[openchrome-devel] drm-openchrome: Branch 'drm-next-4.19' - 2308 commits - arch/alpha/kernel arch/arc/configs arch/arc/include arch/arc/Kconfig arch/arc/kernel arch/arc/Makefile arch/arc/plat-hsdk arch/arm64/include arch/arm64/kernel arch/arm64/Makefile arch/arm64/mm arch/arm/boot arch/arm/kernel arch/arm/mach-omap2 arch/arm/mach-pxa arch/arm/mach-rpc arch/arm/mm arch/ia64/include arch/ia64/kernel arch/ia64/mm arch/mips/ath79 arch/mips/bcm47xx arch/mips/include arch/mips/kernel arch/mips/mm arch/mips/pci arch/nds32/include arch/nds32/Kconfig arch/nds32/kernel arch/nds32/Makefile arch/nds32/mm arch/powerpc/include arch/powerpc/kernel arch/powerpc/kvm arch/powerpc/Makefile arch/powerpc/mm arch/powerpc/net arch/powerpc/xmon arch/s390/Kconfig arch/x86/boot arch/x86/events arch/x86/include arch/x86/Kconfig arch/x86/kernel arch/x86/kvm arch/x86/purgatory arch/x86/um arch/x86/xen block/bio.c block/blk-mq.c block/bsg.c crypto/af_alg.c Documentation/admin-guide/kernel-parameters.txt Documentation/devic e-mapper/writecache.txt Documentation/devicetree/bindings Documentation/driver-api/dma-buf.rst Documentation/fb/fbcon.txt Documentation/gpu/amdgpu.rst Documentation/gpu/drivers.rst Documentation/gpu/drm-client.rst Documentation/gpu/drm-kms-helpers.rst Documentation/gpu/drm-kms.rst Documentation/gpu/drm-mm.rst Documentation/gpu/index.rst Documentation/gpu/kms-properties.csv Documentation/gpu/msm-crash-dump.rst Documentation/gpu/v3d.rst Documentation/kbuild/kbuild.txt Documentation/kbuild/kconfig.txt Documentation/locking/ww-mutex-design.txt Documentation/networking/bonding.txt Documentation/networking/e1000.rst Documentation/networking/e100.rst drivers/acpi/acpica drivers/acpi/ec.c drivers/acpi/nfit drivers/ata/ahci.c drivers/ata/ahci_mvebu.c drivers/ata/Kconfig drivers/ata/libahci.c drivers/ata/libata-core.c drivers/ata/libata-eh.c drivers/ata/libata-scsi.c drivers/ata/sata_fsl.c drivers/ata/sata_nv.c drivers/base/dd.c drivers/block/nbd.c drivers/char/mem.c drivers/char/random.c dri vers/clk/clk-aspeed.c drivers/clk/clk.c drivers/clk/meson drivers/clk/mvebu drivers/clk/qcom drivers/clocksource/arm_arch_timer.c drivers/cpufreq/intel_pstate.c drivers/cpufreq/pcc-cpufreq.c drivers/cpufreq/qcom-cpufreq-kryo.c drivers/dax/device.c drivers/dma-buf/dma-buf.c drivers/dma-buf/dma-fence-array.c drivers/dma-buf/dma-fence.c drivers/dma-buf/reservation.c drivers/dma-buf/sw_sync.c drivers/fpga/altera-cvp.c drivers/gpio/gpiolib-of.c drivers/gpio/gpio-uniphier.c drivers/gpu/drm drivers/gpu/ipu-v3 drivers/hid/hid-core.c drivers/hid/hid-debug.c drivers/hid/i2c-hid drivers/hid/usbhid drivers/hid/wacom_wac.c drivers/i2c/busses drivers/i2c/i2c-core-base.c drivers/infiniband/core drivers/infiniband/hw drivers/input/mouse drivers/input/serio drivers/iommu/intel-iommu.c drivers/md/dm-writecache.c drivers/media/common drivers/misc/cxl drivers/misc/ibmasm drivers/misc/mei drivers/misc/vmw_balloon.c drivers/mmc/core drivers/mmc/host drivers/mtd/spi-nor drivers/net/bonding drivers/net/can drivers/net/dsa drivers/net/ethernet drivers/net/hyperv drivers/net/ieee802154 drivers/net/phy drivers/net/tun.c drivers/net/usb drivers/net/vxlan.c drivers/net/wireless drivers/nvdimm/claim.c drivers/nvme/host drivers/nvmem/core.c drivers/nvme/target drivers/of/base.c drivers/of/of_private.h drivers/of/overlay.c drivers/pci/controller drivers/pci/endpoint drivers/pci/of.c drivers/pci/pci.c drivers/pci/pcie drivers/phy/broadcom drivers/phy/motorola drivers/pinctrl/bcm drivers/pinctrl/mediatek drivers/pinctrl/pinctrl-ingenic.c drivers/pinctrl/sh-pfc drivers/platform/x86 drivers/ptp/ptp_chardev.c drivers/rtc/interface.c drivers/rtc/rtc-mrst.c drivers/scsi/cxlflash drivers/scsi/hpsa.c drivers/scsi/hpsa.h drivers/scsi/qedf drivers/scsi/qedi drivers/scsi/qla2xxx drivers/scsi/scsi_error.c drivers/scsi/sd_zbc.c drivers/soc/imx drivers/staging/android drivers/staging/ks7010 drivers/staging/media drivers/staging/rtl8188eu drivers/staging/rtl8723bs drivers/staging/rtlwifi drivers/staging/spe akup drivers/staging/vboxvideo drivers/tee/tee_shm.c drivers/thunderbolt/domain.c drivers/uio/uio.c drivers/usb/chipidea drivers/usb/class drivers/usb/core drivers/usb/dwc2 drivers/usb/dwc3 drivers/usb/gadget drivers/usb/host drivers/usb/misc drivers/usb/phy drivers/usb/serial drivers/usb/typec drivers/vfio/pci drivers/vfio/vfio_iommu_spapr_tce.c drivers/video/console drivers/video/fbdev fs/aio.c fs/autofs/dev-ioctl.c fs/binfmt_elf.c fs/block_dev.c fs/btrfs/extent_io.c fs/btrfs/ioctl.c fs/btrfs/scrub.c fs/btrfs/volumes.c fs/cachefiles/bind.c fs/cachefiles/namei.c fs/cachefiles/rdwr.c fs/exec.c fs/ext4/balloc.c fs/ext4/ialloc.c fs/ext4/inline.c fs/ext4/inode.c fs/ext4/mmp.c fs/ext4/super.c fs/fat/inode.c fs/fscache/cache.c fs/fscache/cookie.c fs/fscache/object.c fs/fscache/operation.c fs/hugetlbfs/inode.c fs/internal.h fs/proc/task_mmu.c fs/reiserfs/prints.c fs/squashfs/cache.c fs/squashfs/file.c fs/squashfs/fragment.c fs/squashfs/squashfs_fs.h fs/xfs/libxfs include/asm-generic/tlb.h include/drm/drm_atomic.h include/drm/drm_atomic_helper.h include/drm/drm_bridge.h include/drm/drm_client.h include/drm/drm_connector.h include/drm/drm_crtc.h include/drm/drm_debugfs_crc.h include/drm/drm_device.h include/drm/drm_dp_helper.h include/drm/drm_drv.h include/drm/drm_encoder.h include/drm/drm_fb_cma_helper.h include/drm/drm_fb_helper.h include/drm/drm_file.h include/drm/drm_fourcc.h include/drm/drm_mm.h include/drm/drm_mode_config.h include/drm/drm_modeset_helper_vtables.h include/drm/drm_modes.h include/drm/drm_of.h include/drm/drm_panel.h include/drm/drm_pci.h include/drm/drmP.h include/drm/drm_plane.h include/drm/drm_plane_helper.h include/drm/drm_prime.h include/drm/drm_print.h include/drm/drm_property.h include/drm/drm_vma_manager.h include/drm/drm_writeback.h include/drm/gpu_scheduler.h include/drm/i915_drm.h include/drm/i915_pciids.h include/drm/tinydrm include/drm/ttm include/dt-bindings/clock include/linux/ascii85.h include/linux/blk-mq.h include/linux/bpf-cgrou p.h include/linux/bpfilter.h include/linux/console.h include/linux/delayacct.h include/linux/dma-buf.h include/linux/dma-fence.h include/linux/eventfd.h include/linux/filter.h include/linux/fs.h include/linux/fsl include/linux/hid.h include/linux/if_bridge.h include/linux/igmp.h include/linux/intel-iommu.h include/linux/libata.h include/linux/marvell_phy.h include/linux/mlx5 include/linux/mm.h include/linux/pci.h include/linux/ring_buffer.h include/linux/sched include/linux/skbuff.h include/linux/syscalls.h include/linux/uio_driver.h include/linux/ww_mutex.h include/net/cfg80211.h include/net/ip6_fib.h include/net/ip6_route.h include/net/ipv6.h include/net/netfilter include/net/tc_act include/net/tcp.h include/net/xdp_sock.h include/uapi/drm include/uapi/linux include/video/mipi_display.h ipc/sem.c kernel/bpf/btf.c kernel/bpf/devmap.c kernel/bpf/hashtab.c kernel/bpf/sockmap.c kernel/bpf/syscall.c kernel/bpf/verifier.c kernel/fork.c kernel/kthread.c kernel/locking/locktorture.c kerne l/locking/mutex.c kernel/locking/test-ww_mutex.c kernel/memremap.c kernel/printk/printk.c kernel/rseq.c kernel/sched/deadline.c kernel/softirq.c kernel/stop_machine.c kernel/time/tick-common.c kernel/trace/ring_buffer.c kernel/trace/trace.c kernel/trace/trace_events_trigger.c kernel/trace/trace_kprobe.c kernel/trace/trace_output.c lib/iov_iter.c lib/Kconfig.kasan lib/locking-selftest.c lib/rhashtable.c MAINTAINERS Makefile mm/gup.c mm/huge_memory.c mm/memblock.c mm/memcontrol.c mm/mempolicy.c mm/mmap.c mm/nommu.c mm/page_alloc.c mm/rmap.c mm/shmem.c mm/zswap.c net/9p/client.c net/batman-adv/bat_iv_ogm.c net/batman-adv/bat_v.c net/batman-adv/debugfs.c net/batman-adv/debugfs.h net/batman-adv/hard-interface.c net/batman-adv/translation-table.c net/bpf/test_run.c net/caif/caif_dev.c net/core/filter.c net/core/gen_stats.c net/core/page_pool.c net/core/rtnetlink.c net/core/skbuff.c net/core/sock.c net/dns_resolver/dns_key.c net/ieee802154/6lowpan net/ipv4/fib_frontend.c net/ipv4/igmp.c ne t/ipv4/inet_fragment.c net/ipv4/ip_output.c net/ipv4/ip_sockglue.c net/ipv4/netfilter net/ipv4/sysctl_net_ipv4.c net/ipv4/tcp.c net/ipv4/tcp_dctcp.c net/ipv4/tcp_input.c net/ipv4/tcp_ipv4.c net/ipv4/tcp_output.c net/ipv6/addrconf.c net/ipv6/calipso.c net/ipv6/datagram.c net/ipv6/exthdrs.c net/ipv6/icmp.c net/ipv6/ip6_fib.c net/ipv6/ip6_gre.c net/ipv6/ip6_output.c net/ipv6/ipv6_sockglue.c net/ipv6/Kconfig net/ipv6/mcast.c net/ipv6/ndisc.c net/ipv6/netfilter net/ipv6/route.c net/ipv6/seg6_iptunnel.c net/ipv6/tcp_ipv6.c net/mac80211/rx.c net/mac80211/util.c net/netfilter/Kconfig net/netfilter/Makefile net/netfilter/nf_conntrack_core.c net/netfilter/nf_conntrack_proto_dccp.c net/netfilter/nf_tables_api.c net/netfilter/nf_tables_set_core.c net/netfilter/nft_compat.c net/netfilter/nft_immediate.c net/netfilter/nft_lookup.c net/netfilter/nft_set_bitmap.c net/netfilter/nft_set_hash.c net/netfilter/nft_set_rbtree.c net/netfilter/xt_TPROXY.c net/nfc/llcp_commands.c net/nsh/nsh.c net/packet/af _packet.c net/qrtr/qrtr.c net/sched/act_csum.c net/sched/act_tunnel_key.c net/sched/cls_api.c net/sched/sch_fq_codel.c net/sctp/transport.c net/smc/af_smc.c net/smc/smc_clc.c net/smc/smc_close.c net/smc/smc_tx.c net/tipc/discover.c net/tipc/net.c net/tipc/node.c net/tls/tls_sw.c net/wireless/nl80211.c net/wireless/reg.c net/wireless/trace.h net/xdp/xsk.c net/xdp/xsk_queue.h samples/bpf/.gitignore samples/bpf/parse_varlen.c samples/bpf/test_overhead_user.c samples/bpf/trace_event_user.c samples/bpf/xdp2skb_meta.sh samples/bpf/xdpsock_user.c samples/vfio-mdev/mbochs.c scripts/checkpatch.pl scripts/extract-vmlinux scripts/Kbuild.include scripts/Makefile.build scripts/Makefile.clean scripts/Makefile.modbuiltin scripts/Makefile.modinst scripts/Makefile.modpost scripts/Makefile.modsign scripts/tags.sh sound/core/rawmidi.c sound/pci/hda tools/bpf/bpftool tools/build/Build.include tools/build/Makefile tools/objtool/elf.c tools/perf/arch tools/perf/builtin-stat.c tools/perf/jvmti tools/perf/ Makefile.config tools/perf/pmu-events tools/perf/scripts tools/perf/tests tools/perf/util tools/testing/nvdimm tools/testing/selftests tools/usb/ffs-test.c virt/kvm/eventfd.c

Kevin Brace kevinbrace at kemper.freedesktop.org
Wed Aug 15 19:49:02 UTC 2018


 Documentation/admin-guide/kernel-parameters.txt                                    |    5 
 Documentation/device-mapper/writecache.txt                                         |    2 
 Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt                   |    2 
 Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt                         |    6 
 Documentation/devicetree/bindings/display/ilitek,ili9341.txt                       |   27 
 Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt               |    2 
 Documentation/devicetree/bindings/display/msm/dpu.txt                              |  131 
 Documentation/devicetree/bindings/display/msm/dsi.txt                              |   16 
 Documentation/devicetree/bindings/display/panel/auo,g070vvn01.txt                  |   29 
 Documentation/devicetree/bindings/display/panel/boe,hv070wsa-100.txt               |   28 
 Documentation/devicetree/bindings/display/panel/dataimage,scf0700c48ggu18.txt      |    8 
 Documentation/devicetree/bindings/display/panel/dlc,dlc0700yzg-1.txt               |   13 
 Documentation/devicetree/bindings/display/panel/edt,et-series.txt                  |   39 
 Documentation/devicetree/bindings/display/panel/edt,et070080dh6.txt                |   10 
 Documentation/devicetree/bindings/display/panel/edt,etm0700g0dh6.txt               |   10 
 Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.txt                |   20 
 Documentation/devicetree/bindings/display/panel/innolux,g070y2-l01.txt             |   12 
 Documentation/devicetree/bindings/display/panel/innolux,p097pfg.txt                |   24 
 Documentation/devicetree/bindings/display/panel/innolux,tv123wam.txt               |   20 
 Documentation/devicetree/bindings/display/panel/kingdisplay,kd097d04.txt           |   22 
 Documentation/devicetree/bindings/display/panel/newhaven,nhd-4.3-480272ef-atxl.txt |    4 
 Documentation/devicetree/bindings/display/panel/rocktech,rk070er9427.txt           |   25 
 Documentation/devicetree/bindings/display/panel/sharp,lq035q7db03.txt              |   12 
 Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt                      |   64 
 Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt                        |    2 
 Documentation/devicetree/bindings/gpio/nintendo,hollywood-gpio.txt                 |    2 
 Documentation/devicetree/bindings/input/touchscreen/hideep.txt                     |    2 
 Documentation/devicetree/bindings/interrupt-controller/nvidia,tegra20-ictlr.txt    |    2 
 Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.txt           |    2 
 Documentation/devicetree/bindings/mips/brcm/soc.txt                                |    2 
 Documentation/devicetree/bindings/net/fsl-fman.txt                                 |    2 
 Documentation/devicetree/bindings/power/power_domain.txt                           |    2 
 Documentation/devicetree/bindings/regulator/tps65090.txt                           |    2 
 Documentation/devicetree/bindings/reset/st,sti-softreset.txt                       |    2 
 Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.txt                        |    2 
 Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt                       |    2 
 Documentation/devicetree/bindings/sound/qcom,apq8096.txt                           |    2 
 Documentation/devicetree/bindings/usb/rockchip,dwc3.txt                            |    3 
 Documentation/devicetree/bindings/vendor-prefixes.txt                              |    4 
 Documentation/devicetree/bindings/w1/w1-gpio.txt                                   |    2 
 Documentation/driver-api/dma-buf.rst                                               |    6 
 Documentation/fb/fbcon.txt                                                         |    7 
 Documentation/gpu/amdgpu.rst                                                       |  129 
 Documentation/gpu/drivers.rst                                                      |    1 
 Documentation/gpu/drm-client.rst                                                   |   12 
 Documentation/gpu/drm-kms-helpers.rst                                              |   26 
 Documentation/gpu/drm-kms.rst                                                      |   28 
 Documentation/gpu/drm-mm.rst                                                       |   20 
 Documentation/gpu/index.rst                                                        |    1 
 Documentation/gpu/kms-properties.csv                                               |    1 
 Documentation/gpu/msm-crash-dump.rst                                               |   96 
 Documentation/gpu/v3d.rst                                                          |   28 
 Documentation/kbuild/kbuild.txt                                                    |   17 
 Documentation/kbuild/kconfig.txt                                                   |   51 
 Documentation/locking/ww-mutex-design.txt                                          |   65 
 Documentation/networking/bonding.txt                                               |    2 
 Documentation/networking/e100.rst                                                  |   27 
 Documentation/networking/e1000.rst                                                 |  187 
 MAINTAINERS                                                                        |   34 
 Makefile                                                                           |   10 
 arch/alpha/kernel/osf_sys.c                                                        |    5 
 arch/arc/Kconfig                                                                   |    2 
 arch/arc/Makefile                                                                  |   15 
 arch/arc/configs/axs101_defconfig                                                  |    1 
 arch/arc/configs/axs103_defconfig                                                  |    1 
 arch/arc/configs/axs103_smp_defconfig                                              |    1 
 arch/arc/configs/haps_hs_defconfig                                                 |    1 
 arch/arc/configs/haps_hs_smp_defconfig                                             |    1 
 arch/arc/configs/hsdk_defconfig                                                    |    1 
 arch/arc/configs/nsim_700_defconfig                                                |    1 
 arch/arc/configs/nsim_hs_defconfig                                                 |    1 
 arch/arc/configs/nsim_hs_smp_defconfig                                             |    1 
 arch/arc/configs/nsimosci_defconfig                                                |    1 
 arch/arc/configs/nsimosci_hs_defconfig                                             |    1 
 arch/arc/configs/nsimosci_hs_smp_defconfig                                         |    1 
 arch/arc/configs/tb10x_defconfig                                                   |    1 
 arch/arc/include/asm/entry-compact.h                                               |    6 
 arch/arc/include/asm/entry.h                                                       |    3 
 arch/arc/include/asm/mach_desc.h                                                   |    2 
 arch/arc/include/asm/page.h                                                        |    2 
 arch/arc/include/asm/pgtable.h                                                     |    2 
 arch/arc/kernel/irq.c                                                              |    2 
 arch/arc/kernel/process.c                                                          |   47 
 arch/arc/plat-hsdk/Kconfig                                                         |    3 
 arch/arc/plat-hsdk/platform.c                                                      |   62 
 arch/arm/boot/dts/am3517.dtsi                                                      |    5 
 arch/arm/boot/dts/armada-38x.dtsi                                                  |    2 
 arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi                                            |    2 
 arch/arm/boot/dts/omap4-droid4-xt894.dts                                           |    9 
 arch/arm/kernel/head-nommu.S                                                       |    2 
 arch/arm/kernel/process.c                                                          |    1 
 arch/arm/mach-omap2/omap-smp.c                                                     |   41 
 arch/arm/mach-pxa/irq.c                                                            |    4 
 arch/arm/mach-rpc/ecard.c                                                          |    2 
 arch/arm/mm/dma-mapping.c                                                          |   12 
 arch/arm/mm/init.c                                                                 |    9 
 arch/arm64/Makefile                                                                |    6 
 arch/arm64/include/asm/simd.h                                                      |   19 
 arch/arm64/include/asm/tlb.h                                                       |    4 
 arch/arm64/kernel/cpufeature.c                                                     |    4 
 arch/arm64/mm/hugetlbpage.c                                                        |    7 
 arch/arm64/mm/init.c                                                               |    4 
 arch/ia64/include/asm/tlb.h                                                        |    2 
 arch/ia64/kernel/perfmon.c                                                         |    6 
 arch/ia64/mm/init.c                                                                |   14 
 arch/mips/ath79/common.c                                                           |    2 
 arch/mips/bcm47xx/setup.c                                                          |    6 
 arch/mips/include/asm/mipsregs.h                                                   |    3 
 arch/mips/kernel/process.c                                                         |   43 
 arch/mips/kernel/traps.c                                                           |    1 
 arch/mips/mm/ioremap.c                                                             |   37 
 arch/mips/pci/pci.c                                                                |    2 
 arch/nds32/Kconfig                                                                 |   12 
 arch/nds32/Makefile                                                                |    2 
 arch/nds32/include/asm/cacheflush.h                                                |    9 
 arch/nds32/include/asm/futex.h                                                     |    2 
 arch/nds32/kernel/setup.c                                                          |    3 
 arch/nds32/mm/cacheflush.c                                                         |  100 
 arch/powerpc/Makefile                                                              |    1 
 arch/powerpc/include/asm/mmu_context.h                                             |    4 
 arch/powerpc/kernel/idle_book3s.S                                                  |    2 
 arch/powerpc/kvm/book3s_64_vio.c                                                   |    2 
 arch/powerpc/kvm/book3s_64_vio_hv.c                                                |    6 
 arch/powerpc/mm/mmu_context_iommu.c                                                |   37 
 arch/powerpc/net/bpf_jit_comp64.c                                                  |   29 
 arch/powerpc/xmon/xmon.c                                                           |    4 
 arch/s390/Kconfig                                                                  |    2 
 arch/x86/Kconfig                                                                   |    2 
 arch/x86/boot/compressed/eboot.c                                                   |   12 
 arch/x86/events/intel/ds.c                                                         |    8 
 arch/x86/include/asm/apm.h                                                         |    6 
 arch/x86/include/asm/uaccess_64.h                                                  |    7 
 arch/x86/kernel/apm_32.c                                                           |    5 
 arch/x86/kernel/cpu/mcheck/mce.c                                                   |    3 
 arch/x86/kernel/early-quirks.c                                                     |   18 
 arch/x86/kernel/kvmclock.c                                                         |   12 
 arch/x86/kvm/Kconfig                                                               |    2 
 arch/x86/kvm/mmu.c                                                                 |    2 
 arch/x86/kvm/vmx.c                                                                 |   61 
 arch/x86/kvm/x86.c                                                                 |    4 
 arch/x86/purgatory/Makefile                                                        |    2 
 arch/x86/um/mem_32.c                                                               |    2 
 arch/x86/xen/enlighten_pv.c                                                        |   25 
 arch/x86/xen/irq.c                                                                 |    4 
 block/bio.c                                                                        |   54 
 block/blk-mq.c                                                                     |    4 
 block/bsg.c                                                                        |    2 
 crypto/af_alg.c                                                                    |    4 
 drivers/acpi/acpica/hwsleep.c                                                      |   15 
 drivers/acpi/acpica/psloop.c                                                       |   26 
 drivers/acpi/ec.c                                                                  |    2 
 drivers/acpi/nfit/core.c                                                           |   48 
 drivers/acpi/nfit/nfit.h                                                           |    1 
 drivers/ata/Kconfig                                                                |    2 
 drivers/ata/ahci.c                                                                 |   60 
 drivers/ata/ahci_mvebu.c                                                           |    2 
 drivers/ata/libahci.c                                                              |    7 
 drivers/ata/libata-core.c                                                          |    3 
 drivers/ata/libata-eh.c                                                            |   41 
 drivers/ata/libata-scsi.c                                                          |   18 
 drivers/ata/sata_fsl.c                                                             |    9 
 drivers/ata/sata_nv.c                                                              |    3 
 drivers/base/dd.c                                                                  |    8 
 drivers/block/nbd.c                                                                |   96 
 drivers/char/mem.c                                                                 |    1 
 drivers/char/random.c                                                              |   10 
 drivers/clk/clk-aspeed.c                                                           |   59 
 drivers/clk/clk.c                                                                  |    3 
 drivers/clk/meson/clk-audio-divider.c                                              |    2 
 drivers/clk/meson/gxbb.c                                                           |    1 
 drivers/clk/mvebu/armada-37xx-periph.c                                             |   38 
 drivers/clk/qcom/gcc-msm8996.c                                                     |    1 
 drivers/clk/qcom/mmcc-msm8996.c                                                    |    1 
 drivers/clocksource/arm_arch_timer.c                                               |    2 
 drivers/cpufreq/intel_pstate.c                                                     |   17 
 drivers/cpufreq/pcc-cpufreq.c                                                      |    4 
 drivers/cpufreq/qcom-cpufreq-kryo.c                                                |    1 
 drivers/dax/device.c                                                               |   12 
 drivers/dma-buf/dma-buf.c                                                          |   56 
 drivers/dma-buf/dma-fence-array.c                                                  |    1 
 drivers/dma-buf/dma-fence.c                                                        |  167 
 drivers/dma-buf/reservation.c                                                      |    8 
 drivers/dma-buf/sw_sync.c                                                          |    1 
 drivers/fpga/altera-cvp.c                                                          |    6 
 drivers/gpio/gpio-uniphier.c                                                       |    6 
 drivers/gpio/gpiolib-of.c                                                          |    3 
 drivers/gpu/drm/Kconfig                                                            |   21 
 drivers/gpu/drm/Makefile                                                           |    4 
 drivers/gpu/drm/amd/amdgpu/ObjectID.h                                              |    8 
 drivers/gpu/drm/amd/amdgpu/amdgpu.h                                                |  103 
 drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c                                            |   47 
 drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c                                           |   55 
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c                                         |   47 
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h                                         |   10 
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c                                   |    2 
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c                                  |   27 
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c                                  |    9 
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c                                  |    8 
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c                                   |   24 
 drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c                                   |    5 
 drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c                                      |   16 
 drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c                                        |  267 
 drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h                                        |   85 
 drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c                                            |    8 
 drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c                                     |   85 
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c                                             |  259 
 drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c                                            |   33 
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c                                         |  403 
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c                                        |   11 
 drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c                                            |    7 
 drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h                                            |   16 
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c                                            |  266 
 drivers/gpu/drm/amd/amdgpu/amdgpu_encoders.c                                       |    2 
 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c                                             |   16 
 drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c                                          |    1 
 drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c                                           |   14 
 drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h                                           |    2 
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c                                            |   14 
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h                                            |   17 
 drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c                                             |    5 
 drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c                                            |    5 
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c                                            |  202 
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c                                            |   79 
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.h                                            |   74 
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c                                            |   87 
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c                                             |  207 
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c                                         |  418 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.h                                         |   11 
 drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c                                             |  219 
 drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c                                          |  127 
 drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c                                      |   29 
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c                                           |    5 
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h                                           |    7 
 drivers/gpu/drm/amd/amdgpu/amdgpu_test.c                                           |   12 
 drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h                                          |   15 
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c                                            |  185 
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h                                            |    2 
 drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c                                            |  211 
 drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h                                            |   15 
 drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c                                            |   37 
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c                                            |  143 
 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h                                            |    4 
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c                                             |  396 
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h                                             |   17 
 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c                                       |   22 
 drivers/gpu/drm/amd/amdgpu/ci_dpm.c                                                |   40 
 drivers/gpu/drm/amd/amdgpu/cik.c                                                   |   10 
 drivers/gpu/drm/amd/amdgpu/cik_sdma.c                                              |   36 
 drivers/gpu/drm/amd/amdgpu/dce_v10_0.c                                             |   16 
 drivers/gpu/drm/amd/amdgpu/dce_v11_0.c                                             |   16 
 drivers/gpu/drm/amd/amdgpu/dce_v6_0.c                                              |   10 
 drivers/gpu/drm/amd/amdgpu/dce_v8_0.c                                              |   10 
 drivers/gpu/drm/amd/amdgpu/dce_virtual.c                                           |   20 
 drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c                                              |   56 
 drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c                                              |   72 
 drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c                                              |  299 
 drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c                                              |  124 
 drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c                                              |   14 
 drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c                                              |   48 
 drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c                                              |   47 
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c                                              |   17 
 drivers/gpu/drm/amd/amdgpu/kv_dpm.c                                                |   17 
 drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c                                            |    4 
 drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c                                             |   18 
 drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c                                             |   20 
 drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c                                             |   30 
 drivers/gpu/drm/amd/amdgpu/si_dpm.c                                                |   29 
 drivers/gpu/drm/amd/amdgpu/soc15d.h                                                |   23 
 drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c                                              |    3 
 drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c                                              |   42 
 drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c                                              |  126 
 drivers/gpu/drm/amd/amdgpu/vce_v2_0.c                                              |   10 
 drivers/gpu/drm/amd/amdgpu/vce_v3_0.c                                              |   23 
 drivers/gpu/drm/amd/amdgpu/vce_v4_0.c                                              |   18 
 drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c                                              |  467 +
 drivers/gpu/drm/amd/amdgpu/vega10_reg_init.c                                       |    1 
 drivers/gpu/drm/amd/amdgpu/vi.c                                                    |   12 
 drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c                                   |   54 
 drivers/gpu/drm/amd/amdkfd/cik_int.h                                               |    7 
 drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h                                     |  458 -
 drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx8.asm                              |   18 
 drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx9.asm                              |   16 
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c                                           |   69 
 drivers/gpu/drm/amd/amdkfd/kfd_crat.c                                              |   57 
 drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c                                            |    1 
 drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h                                            |   37 
 drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c                                           |   48 
 drivers/gpu/drm/amd/amdkfd/kfd_device.c                                            |  122 
 drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c                              |  283 
 drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h                              |   32 
 drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c                           |    2 
 drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c                                          |    9 
 drivers/gpu/drm/amd/amdkfd/kfd_events.c                                            |  118 
 drivers/gpu/drm/amd/amdkfd/kfd_events.h                                            |    1 
 drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c                                    |   22 
 drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c                                         |    6 
 drivers/gpu/drm/amd/amdkfd/kfd_iommu.c                                             |    2 
 drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c                                      |   18 
 drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h                                      |    2 
 drivers/gpu/drm/amd/amdkfd/kfd_module.c                                            |   16 
 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c                                       |   41 
 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h                                       |    4 
 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c                                   |   29 
 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c                                    |   31 
 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c                                    |   29 
 drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c                                    |   26 
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h                                              |   40 
 drivers/gpu/drm/amd/amdkfd/kfd_process.c                                           |    2 
 drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c                             |   43 
 drivers/gpu/drm/amd/display/Kconfig                                                |   17 
 drivers/gpu/drm/amd/display/TODO                                                   |    8 
 drivers/gpu/drm/amd/display/amdgpu_dm/Makefile                                     |    4 
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c                                  |  104 
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h                                  |    5 
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c                            |   42 
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c                          |  722 +
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.h                          |   18 
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c                          |   49 
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c                        |  104 
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c                           |  562 +
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c                         |  330 
 drivers/gpu/drm/amd/display/dc/Makefile                                            |    2 
 drivers/gpu/drm/amd/display/dc/basics/Makefile                                     |    2 
 drivers/gpu/drm/amd/display/dc/basics/log_helpers.c                                |   69 
 drivers/gpu/drm/amd/display/dc/basics/logger.c                                     |  405 
 drivers/gpu/drm/amd/display/dc/bios/bios_parser.c                                  |  196 
 drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c                                 |  220 
 drivers/gpu/drm/amd/display/dc/bios/command_table.c                                |   18 
 drivers/gpu/drm/amd/display/dc/bios/command_table2.c                               |   46 
 drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c                        |    2 
 drivers/gpu/drm/amd/display/dc/calcs/Makefile                                      |    2 
 drivers/gpu/drm/amd/display/dc/calcs/calcs_logger.h                                |    9 
 drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c                                   |    6 
 drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c                                   |  215 
 drivers/gpu/drm/amd/display/dc/core/dc.c                                           |  110 
 drivers/gpu/drm/amd/display/dc/core/dc_debug.c                                     |   26 
 drivers/gpu/drm/amd/display/dc/core/dc_link.c                                      |  174 
 drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c                                  |  117 
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c                                   |  141 
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c                                  |  462 -
 drivers/gpu/drm/amd/display/dc/core/dc_sink.c                                      |    4 
 drivers/gpu/drm/amd/display/dc/core/dc_stream.c                                    |   25 
 drivers/gpu/drm/amd/display/dc/core/dc_surface.c                                   |   13 
 drivers/gpu/drm/amd/display/dc/dc.h                                                |   62 
 drivers/gpu/drm/amd/display/dc/dc_bios_types.h                                     |    4 
 drivers/gpu/drm/amd/display/dc/dc_ddc_types.h                                      |   61 
 drivers/gpu/drm/amd/display/dc/dc_dp_types.h                                       |    5 
 drivers/gpu/drm/amd/display/dc/dc_helper.c                                         |   51 
 drivers/gpu/drm/amd/display/dc/dc_hw_types.h                                       |   51 
 drivers/gpu/drm/amd/display/dc/dc_link.h                                           |   24 
 drivers/gpu/drm/amd/display/dc/dc_stream.h                                         |   15 
 drivers/gpu/drm/amd/display/dc/dc_types.h                                          |   24 
 drivers/gpu/drm/amd/display/dc/dce/Makefile                                        |    2 
 drivers/gpu/drm/amd/display/dc/dce/dce_aux.c                                       |  937 ++
 drivers/gpu/drm/amd/display/dc/dce/dce_aux.h                                       |  111 
 drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c                              |   16 
 drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h                              |    2 
 drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c                                    |  724 -
 drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h                                    |   89 
 drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c                                      |   44 
 drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h                                     |   12 
 drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c                              |   11 
 drivers/gpu/drm/amd/display/dc/dce/dce_mem_input.c                                 |    6 
 drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c                            |   25 
 drivers/gpu/drm/amd/display/dc/dce/dce_transform.c                                 |    2 
 drivers/gpu/drm/amd/display/dc/dce100/dce100_hw_sequencer.c                        |   45 
 drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c                            |   60 
 drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c                          |    6 
 drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c                        |  427 -
 drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h                        |   13 
 drivers/gpu/drm/amd/display/dc/dce110/dce110_mem_input_v.c                         |    2 
 drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c                            |  102 
 drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c                         |    2 
 drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c                            |  102 
 drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c                        |   10 
 drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c                            |   65 
 drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c                              |   75 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c                                   |   23 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h                                   |   14 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c                              |   19 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c                                |  362 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h                                |    6 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c                                  |   59 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h                                  |   13 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c                          |  518 -
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h                          |    7 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c                          |   21 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h                          |   15 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c                                   |    2 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c                                   |    2 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c                                  |  100 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h                                  |   64 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c                              |  128 
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c                        |   88 
 drivers/gpu/drm/amd/display/dc/dm_helpers.h                                        |   11 
 drivers/gpu/drm/amd/display/dc/dm_pp_smu.h                                         |    6 
 drivers/gpu/drm/amd/display/dc/dm_services.h                                       |    5 
 drivers/gpu/drm/amd/display/dc/dm_services_types.h                                 |    6 
 drivers/gpu/drm/amd/display/dc/dml/Makefile                                        |    3 
 drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c                              |   63 
 drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h                              |    1 
 drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h                          |    6 
 drivers/gpu/drm/amd/display/dc/dml/soc_bounding_box.c                              |   79 
 drivers/gpu/drm/amd/display/dc/gpio/Makefile                                       |    2 
 drivers/gpu/drm/amd/display/dc/gpio/ddc_regs.h                                     |    7 
 drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c                                 |    1 
 drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c                                   |    4 
 drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c                                 |    4 
 drivers/gpu/drm/amd/display/dc/i2caux/Makefile                                     |    2 
 drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.c                                 |   31 
 drivers/gpu/drm/amd/display/dc/i2caux/aux_engine.h                                 |   47 
 drivers/gpu/drm/amd/display/dc/i2caux/dce100/i2caux_dce100.c                       |    1 
 drivers/gpu/drm/amd/display/dc/i2caux/dce110/aux_engine_dce110.c                   |  159 
 drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.c                |   26 
 drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2c_hw_engine_dce110.h                |    8 
 drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2caux_dce110.c                       |   24 
 drivers/gpu/drm/amd/display/dc/i2caux/dce110/i2caux_dce110.h                       |    1 
 drivers/gpu/drm/amd/display/dc/i2caux/dce112/i2caux_dce112.c                       |    1 
 drivers/gpu/drm/amd/display/dc/i2caux/dce120/i2caux_dce120.c                       |    1 
 drivers/gpu/drm/amd/display/dc/i2caux/dcn10/i2caux_dcn10.c                         |    1 
 drivers/gpu/drm/amd/display/dc/i2caux/engine.h                                     |   19 
 drivers/gpu/drm/amd/display/dc/i2caux/i2c_engine.h                                 |    2 
 drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c                                     |    5 
 drivers/gpu/drm/amd/display/dc/inc/core_types.h                                    |   15 
 drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h                                   |   22 
 drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h                                    |    5 
 drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h                                     |    2 
 drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h                                 |  180 
 drivers/gpu/drm/amd/display/dc/inc/hw/display_clock.h                              |   43 
 drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h                                       |    2 
 drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h                                        |    3 
 drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h                                       |    3 
 drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h                                  |    2 
 drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h                           |    3 
 drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h                                  |   20 
 drivers/gpu/drm/amd/display/dc/inc/reg_helper.h                                    |   46 
 drivers/gpu/drm/amd/display/dc/inc/resource.h                                      |    1 
 drivers/gpu/drm/amd/display/dc/irq/Makefile                                        |    2 
 drivers/gpu/drm/amd/display/dc/irq/irq_service.c                                   |    4 
 drivers/gpu/drm/amd/display/dc/os_types.h                                          |    2 
 drivers/gpu/drm/amd/display/include/ddc_service_types.h                            |    3 
 drivers/gpu/drm/amd/display/include/dpcd_defs.h                                    |    3 
 drivers/gpu/drm/amd/display/include/fixed31_32.h                                   |    7 
 drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h                        |    2 
 drivers/gpu/drm/amd/display/include/grph_object_defs.h                             |   46 
 drivers/gpu/drm/amd/display/include/grph_object_id.h                               |   16 
 drivers/gpu/drm/amd/display/include/logger_interface.h                             |  136 
 drivers/gpu/drm/amd/display/include/logger_types.h                                 |   59 
 drivers/gpu/drm/amd/display/modules/color/color_gamma.c                            |  147 
 drivers/gpu/drm/amd/display/modules/color/luts_1d.h                                |   51 
 drivers/gpu/drm/amd/display/modules/stats/stats.c                                  |    4 
 drivers/gpu/drm/amd/include/amd_pcie.h                                             |    2 
 drivers/gpu/drm/amd/include/amd_shared.h                                           |   46 
 drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_1_0_offset.h                          |   20 
 drivers/gpu/drm/amd/include/atomfirmware.h                                         |   15 
 drivers/gpu/drm/amd/include/dm_pp_interface.h                                      |   37 
 drivers/gpu/drm/amd/include/ivsrcid/gfx/irqsrcs_gfx_9_0.h                          |   55 
 drivers/gpu/drm/amd/include/ivsrcid/ivsrcid_vislands30.h                           |   98 
 drivers/gpu/drm/amd/include/ivsrcid/sdma0/irqsrcs_sdma0_4_0.h                      |   50 
 drivers/gpu/drm/amd/include/ivsrcid/sdma1/irqsrcs_sdma1_4_0.h                      |   50 
 drivers/gpu/drm/amd/include/ivsrcid/smuio/irqsrcs_smuio_9_0.h                      |   11 
 drivers/gpu/drm/amd/include/ivsrcid/thm/irqsrcs_thm_9_0.h                          |   33 
 drivers/gpu/drm/amd/include/ivsrcid/uvd/irqsrcs_uvd_7_0.h                          |   34 
 drivers/gpu/drm/amd/include/ivsrcid/vce/irqsrcs_vce_4_0.h                          |   34 
 drivers/gpu/drm/amd/include/ivsrcid/vcn/irqsrcs_vcn_1_0.h                          |   34 
 drivers/gpu/drm/amd/include/ivsrcid/vmc/irqsrcs_vmc_1_0.h                          |   37 
 drivers/gpu/drm/amd/include/kgd_kfd_interface.h                                    |   40 
 drivers/gpu/drm/amd/include/kgd_pp_interface.h                                     |   15 
 drivers/gpu/drm/amd/powerplay/amd_powerplay.c                                      |  109 
 drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c                              |    4 
 drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c                                        |    8 
 drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c                                   |    8 
 drivers/gpu/drm/amd/powerplay/hwmgr/process_pptables_v1_0.c                        |    8 
 drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c                                  |   12 
 drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c                        |   56 
 drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.h                        |    3 
 drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c                                   |  155 
 drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.h                                   |    1 
 drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c                               |   43 
 drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c                                   |   11 
 drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c                                   |   57 
 drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.h                                   |    2 
 drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c                                 |  179 
 drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h                                 |    1 
 drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c                                 | 1133 +-
 drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h                                 |   13 
 drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c                       |    6 
 drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c                               |    8 
 drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h                                |    2 
 drivers/gpu/drm/amd/powerplay/inc/hwmgr.h                                          |   11 
 drivers/gpu/drm/amd/powerplay/inc/smumgr.h                                         |    4 
 drivers/gpu/drm/amd/powerplay/inc/vega12/smu9_driver_if.h                          |   18 
 drivers/gpu/drm/amd/powerplay/smumgr/Makefile                                      |    2 
 drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c                                   |  119 
 drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c                                 |   74 
 drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c                              |   10 
 drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c                            |  108 
 drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c                                |    2 
 drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c                                 |  101 
 drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h                                 |    3 
 drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c                                 |    4 
 drivers/gpu/drm/amd/powerplay/smumgr/smu9_smumgr.c                                 |  150 
 drivers/gpu/drm/amd/powerplay/smumgr/smu9_smumgr.h                                 |   32 
 drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c                                      |    2 
 drivers/gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c                                |   80 
 drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c                               |  168 
 drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.c                               |  220 
 drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.h                               |    1 
 drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c                                |   85 
 drivers/gpu/drm/arc/arcpgu_crtc.c                                                  |    5 
 drivers/gpu/drm/arc/arcpgu_sim.c                                                   |    2 
 drivers/gpu/drm/arm/Makefile                                                       |    1 
 drivers/gpu/drm/arm/hdlcd_crtc.c                                                   |   35 
 drivers/gpu/drm/arm/hdlcd_drv.c                                                    |   76 
 drivers/gpu/drm/arm/hdlcd_drv.h                                                    |    2 
 drivers/gpu/drm/arm/malidp_crtc.c                                                  |   10 
 drivers/gpu/drm/arm/malidp_drv.c                                                   |  187 
 drivers/gpu/drm/arm/malidp_drv.h                                                   |   26 
 drivers/gpu/drm/arm/malidp_hw.c                                                    |  297 
 drivers/gpu/drm/arm/malidp_hw.h                                                    |   40 
 drivers/gpu/drm/arm/malidp_mw.c                                                    |  250 
 drivers/gpu/drm/arm/malidp_mw.h                                                    |   14 
 drivers/gpu/drm/arm/malidp_regs.h                                                  |   24 
 drivers/gpu/drm/armada/Makefile                                                    |    2 
 drivers/gpu/drm/armada/armada_510.c                                                |   24 
 drivers/gpu/drm/armada/armada_crtc.c                                               | 1008 --
 drivers/gpu/drm/armada/armada_crtc.h                                               |   56 
 drivers/gpu/drm/armada/armada_drm.h                                                |   14 
 drivers/gpu/drm/armada/armada_drv.c                                                |   54 
 drivers/gpu/drm/armada/armada_fb.c                                                 |   30 
 drivers/gpu/drm/armada/armada_fb.h                                                 |    6 
 drivers/gpu/drm/armada/armada_fbdev.c                                              |    4 
 drivers/gpu/drm/armada/armada_gem.c                                                |   17 
 drivers/gpu/drm/armada/armada_hw.h                                                 |   15 
 drivers/gpu/drm/armada/armada_overlay.c                                            |  665 -
 drivers/gpu/drm/armada/armada_plane.c                                              |  289 
 drivers/gpu/drm/armada/armada_plane.h                                              |   15 
 drivers/gpu/drm/ast/ast_mode.c                                                     |    6 
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c                                       |    1 
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c                                    |   19 
 drivers/gpu/drm/bochs/bochs_kms.c                                                  |    2 
 drivers/gpu/drm/bridge/Kconfig                                                     |    4 
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c                                       |    4 
 drivers/gpu/drm/bridge/analogix-anx78xx.c                                          |    8 
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c                                 |    6 
 drivers/gpu/drm/bridge/cdns-dsi.c                                                  |    6 
 drivers/gpu/drm/bridge/dumb-vga-dac.c                                              |    4 
 drivers/gpu/drm/bridge/lvds-encoder.c                                              |    4 
 drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c                           |    4 
 drivers/gpu/drm/bridge/nxp-ptn3460.c                                               |    4 
 drivers/gpu/drm/bridge/panel.c                                                     |    2 
 drivers/gpu/drm/bridge/parade-ps8622.c                                             |    2 
 drivers/gpu/drm/bridge/sii902x.c                                                   |    4 
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c                                          |    4 
 drivers/gpu/drm/bridge/tc358767.c                                                  |    4 
 drivers/gpu/drm/bridge/ti-tfp410.c                                                 |    4 
 drivers/gpu/drm/cirrus/cirrus_drv.h                                                |   10 
 drivers/gpu/drm/cirrus/cirrus_fbdev.c                                              |   20 
 drivers/gpu/drm/cirrus/cirrus_main.c                                               |   43 
 drivers/gpu/drm/cirrus/cirrus_mode.c                                               |   14 
 drivers/gpu/drm/drm_atomic.c                                                       |  408 
 drivers/gpu/drm/drm_atomic_helper.c                                                |  114 
 drivers/gpu/drm/drm_client.c                                                       |  406 
 drivers/gpu/drm/drm_connector.c                                                    |  219 
 drivers/gpu/drm/drm_crtc.c                                                         |   53 
 drivers/gpu/drm/drm_crtc_internal.h                                                |   28 
 drivers/gpu/drm/drm_debugfs.c                                                      |   11 
 drivers/gpu/drm/drm_debugfs_crc.c                                                  |    9 
 drivers/gpu/drm/drm_dp_cec.c                                                       |  428 +
 drivers/gpu/drm/drm_dp_helper.c                                                    |   33 
 drivers/gpu/drm/drm_dp_mst_topology.c                                              |    4 
 drivers/gpu/drm/drm_drv.c                                                          |   23 
 drivers/gpu/drm/drm_dumb_buffers.c                                                 |   29 
 drivers/gpu/drm/drm_edid.c                                                         |  279 
 drivers/gpu/drm/drm_fb_cma_helper.c                                                |  355 
 drivers/gpu/drm/drm_fb_helper.c                                                    |  359 
 drivers/gpu/drm/drm_file.c                                                         |  306 
 drivers/gpu/drm/drm_fourcc.c                                                       |   42 
 drivers/gpu/drm/drm_framebuffer.c                                                  |   49 
 drivers/gpu/drm/drm_gem.c                                                          |    9 
 drivers/gpu/drm/drm_gem_framebuffer_helper.c                                       |    2 
 drivers/gpu/drm/drm_global.c                                                       |    2 
 drivers/gpu/drm/drm_internal.h                                                     |    2 
 drivers/gpu/drm/drm_ioctl.c                                                        |   13 
 drivers/gpu/drm/drm_lease.c                                                        |   16 
 drivers/gpu/drm/drm_mipi_dsi.c                                                     |    2 
 drivers/gpu/drm/drm_mm.c                                                           |   91 
 drivers/gpu/drm/drm_mode_config.c                                                  |    5 
 drivers/gpu/drm/drm_mode_object.c                                                  |    3 
 drivers/gpu/drm/drm_modes.c                                                        |   23 
 drivers/gpu/drm/drm_of.c                                                           |   27 
 drivers/gpu/drm/drm_panel.c                                                        |   27 
 drivers/gpu/drm/drm_pci.c                                                          |   58 
 drivers/gpu/drm/drm_plane.c                                                        |  169 
 drivers/gpu/drm/drm_plane_helper.c                                                 |   12 
 drivers/gpu/drm/drm_prime.c                                                        |   34 
 drivers/gpu/drm/drm_print.c                                                        |  111 
 drivers/gpu/drm/drm_probe_helper.c                                                 |   19 
 drivers/gpu/drm/drm_simple_kms_helper.c                                            |    6 
 drivers/gpu/drm/drm_syncobj.c                                                      |    1 
 drivers/gpu/drm/drm_vm.c                                                           |   10 
 drivers/gpu/drm/drm_vma_manager.c                                                  |    1 
 drivers/gpu/drm/drm_writeback.c                                                    |  353 
 drivers/gpu/drm/etnaviv/etnaviv_drv.c                                              |   11 
 drivers/gpu/drm/etnaviv/etnaviv_drv.h                                              |    3 
 drivers/gpu/drm/etnaviv/etnaviv_gem.c                                              |   37 
 drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c                                       |    4 
 drivers/gpu/drm/etnaviv/etnaviv_gpu.c                                              |   10 
 drivers/gpu/drm/etnaviv/etnaviv_gpu.h                                              |    2 
 drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c                                         |    9 
 drivers/gpu/drm/etnaviv/etnaviv_sched.c                                            |   28 
 drivers/gpu/drm/exynos/Makefile                                                    |    2 
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c                                      |    2 
 drivers/gpu/drm/exynos/exynos7_drm_decon.c                                         |    2 
 drivers/gpu/drm/exynos/exynos_dp.c                                                 |    9 
 drivers/gpu/drm/exynos/exynos_drm_core.c                                           |  119 
 drivers/gpu/drm/exynos/exynos_drm_dpi.c                                            |    6 
 drivers/gpu/drm/exynos/exynos_drm_drv.c                                            |   29 
 drivers/gpu/drm/exynos/exynos_drm_drv.h                                            |   47 
 drivers/gpu/drm/exynos/exynos_drm_dsi.c                                            |    7 
 drivers/gpu/drm/exynos/exynos_drm_fb.c                                             |   10 
 drivers/gpu/drm/exynos/exynos_drm_fimd.c                                           |    2 
 drivers/gpu/drm/exynos/exynos_drm_g2d.c                                            |  300 
 drivers/gpu/drm/exynos/exynos_drm_g2d.h                                            |   11 
 drivers/gpu/drm/exynos/exynos_drm_gem.c                                            |   58 
 drivers/gpu/drm/exynos/exynos_drm_gem.h                                            |   24 
 drivers/gpu/drm/exynos/exynos_drm_ipp.c                                            |   10 
 drivers/gpu/drm/exynos/exynos_drm_mic.c                                            |    2 
 drivers/gpu/drm/exynos/exynos_drm_plane.c                                          |    2 
 drivers/gpu/drm/exynos/exynos_drm_vidi.c                                           |    4 
 drivers/gpu/drm/exynos/exynos_hdmi.c                                               |    6 
 drivers/gpu/drm/exynos/exynos_mixer.c                                              |    4 
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c                                          |    7 
 drivers/gpu/drm/gma500/accel_2d.c                                                  |    2 
 drivers/gpu/drm/gma500/cdv_intel_dp.c                                              |    2 
 drivers/gpu/drm/gma500/cdv_intel_hdmi.c                                            |    2 
 drivers/gpu/drm/gma500/framebuffer.c                                               |   62 
 drivers/gpu/drm/gma500/framebuffer.h                                               |    1 
 drivers/gpu/drm/gma500/gem.c                                                       |    2 
 drivers/gpu/drm/gma500/gma_display.c                                               |   20 
 drivers/gpu/drm/gma500/gtt.h                                                       |    2 
 drivers/gpu/drm/gma500/intel_bios.h                                                |   38 
 drivers/gpu/drm/gma500/mdfld_dsi_dpi.c                                             |    2 
 drivers/gpu/drm/gma500/mdfld_intel_display.c                                       |    3 
 drivers/gpu/drm/gma500/oaktrail_crtc.c                                             |    3 
 drivers/gpu/drm/gma500/oaktrail_hdmi.c                                             |    2 
 drivers/gpu/drm/gma500/oaktrail_lvds.c                                             |    2 
 drivers/gpu/drm/gma500/psb_intel_modes.c                                           |    2 
 drivers/gpu/drm/gma500/psb_intel_sdvo.c                                            |   13 
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c                                   |    2 
 drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c                                    |    1 
 drivers/gpu/drm/i2c/tda998x_drv.c                                                  |  387 
 drivers/gpu/drm/i810/i810_dma.c                                                    |    2 
 drivers/gpu/drm/i915/Kconfig.debug                                                 |   12 
 drivers/gpu/drm/i915/Makefile                                                      |    7 
 drivers/gpu/drm/i915/dvo_ch7017.c                                                  |   20 
 drivers/gpu/drm/i915/dvo_ch7xxx.c                                                  |   22 
 drivers/gpu/drm/i915/dvo_ivch.c                                                    |   26 
 drivers/gpu/drm/i915/dvo_ns2501.c                                                  |   44 
 drivers/gpu/drm/i915/dvo_sil164.c                                                  |   10 
 drivers/gpu/drm/i915/dvo_tfp410.c                                                  |   16 
 drivers/gpu/drm/i915/gvt/aperture_gm.c                                             |    2 
 drivers/gpu/drm/i915/gvt/cmd_parser.c                                              |   43 
 drivers/gpu/drm/i915/gvt/display.c                                                 |   62 
 drivers/gpu/drm/i915/gvt/dmabuf.c                                                  |   26 
 drivers/gpu/drm/i915/gvt/edid.c                                                    |   20 
 drivers/gpu/drm/i915/gvt/execlist.h                                                |   13 
 drivers/gpu/drm/i915/gvt/fb_decoder.c                                              |   27 
 drivers/gpu/drm/i915/gvt/firmware.c                                                |    2 
 drivers/gpu/drm/i915/gvt/gtt.c                                                     |  434 -
 drivers/gpu/drm/i915/gvt/gtt.h                                                     |    9 
 drivers/gpu/drm/i915/gvt/gvt.c                                                     |   31 
 drivers/gpu/drm/i915/gvt/gvt.h                                                     |   20 
 drivers/gpu/drm/i915/gvt/handlers.c                                                |  438 -
 drivers/gpu/drm/i915/gvt/hypercall.h                                               |    2 
 drivers/gpu/drm/i915/gvt/interrupt.c                                               |   17 
 drivers/gpu/drm/i915/gvt/kvmgt.c                                                   |  130 
 drivers/gpu/drm/i915/gvt/mmio.c                                                    |   12 
 drivers/gpu/drm/i915/gvt/mmio.h                                                    |   11 
 drivers/gpu/drm/i915/gvt/mmio_context.c                                            |   22 
 drivers/gpu/drm/i915/gvt/mmio_context.h                                            |    2 
 drivers/gpu/drm/i915/gvt/mpt.h                                                     |    7 
 drivers/gpu/drm/i915/gvt/page_track.c                                              |    5 
 drivers/gpu/drm/i915/gvt/sched_policy.c                                            |   36 
 drivers/gpu/drm/i915/gvt/scheduler.c                                               |  208 
 drivers/gpu/drm/i915/gvt/scheduler.h                                               |    1 
 drivers/gpu/drm/i915/gvt/vgpu.c                                                    |   57 
 drivers/gpu/drm/i915/i915_debugfs.c                                                |  374 
 drivers/gpu/drm/i915/i915_drv.c                                                    |  177 
 drivers/gpu/drm/i915/i915_drv.h                                                    |  128 
 drivers/gpu/drm/i915/i915_gem.c                                                    |  593 -
 drivers/gpu/drm/i915/i915_gem.h                                                    |   21 
 drivers/gpu/drm/i915/i915_gem_context.c                                            |  174 
 drivers/gpu/drm/i915/i915_gem_context.h                                            |   28 
 drivers/gpu/drm/i915/i915_gem_dmabuf.c                                             |   11 
 drivers/gpu/drm/i915/i915_gem_evict.c                                              |    3 
 drivers/gpu/drm/i915/i915_gem_execbuffer.c                                         |  115 
 drivers/gpu/drm/i915/i915_gem_gtt.c                                                | 1282 +--
 drivers/gpu/drm/i915/i915_gem_gtt.h                                                |   85 
 drivers/gpu/drm/i915/i915_gem_object.h                                             |   27 
 drivers/gpu/drm/i915/i915_gem_render_state.c                                       |    4 
 drivers/gpu/drm/i915/i915_gem_shrinker.c                                           |   25 
 drivers/gpu/drm/i915/i915_gem_stolen.c                                             |   45 
 drivers/gpu/drm/i915/i915_gem_userptr.c                                            |   18 
 drivers/gpu/drm/i915/i915_gpu_error.c                                              |   92 
 drivers/gpu/drm/i915/i915_gpu_error.h                                              |    4 
 drivers/gpu/drm/i915/i915_irq.c                                                    |  648 +
 drivers/gpu/drm/i915/i915_params.c                                                 |    9 
 drivers/gpu/drm/i915/i915_params.h                                                 |    2 
 drivers/gpu/drm/i915/i915_pci.c                                                    |   20 
 drivers/gpu/drm/i915/i915_perf.c                                                   |  144 
 drivers/gpu/drm/i915/i915_pmu.c                                                    |   67 
 drivers/gpu/drm/i915/i915_pmu.h                                                    |    8 
 drivers/gpu/drm/i915/i915_pvinfo.h                                                 |    6 
 drivers/gpu/drm/i915/i915_reg.h                                                    | 4088 +++++-----
 drivers/gpu/drm/i915/i915_request.c                                                |  100 
 drivers/gpu/drm/i915/i915_request.h                                                |   14 
 drivers/gpu/drm/i915/i915_selftest.h                                               |    2 
 drivers/gpu/drm/i915/i915_timeline.h                                               |    2 
 drivers/gpu/drm/i915/i915_trace.h                                                  |  148 
 drivers/gpu/drm/i915/i915_vgpu.c                                                   |    8 
 drivers/gpu/drm/i915/i915_vgpu.h                                                   |    6 
 drivers/gpu/drm/i915/i915_vma.c                                                    |  385 
 drivers/gpu/drm/i915/i915_vma.h                                                    |   53 
 drivers/gpu/drm/i915/icl_dsi.c                                                     |  127 
 drivers/gpu/drm/i915/intel_acpi.c                                                  |   27 
 drivers/gpu/drm/i915/intel_atomic.c                                                |    7 
 drivers/gpu/drm/i915/intel_atomic_plane.c                                          |   18 
 drivers/gpu/drm/i915/intel_audio.c                                                 |   48 
 drivers/gpu/drm/i915/intel_bios.c                                                  |  129 
 drivers/gpu/drm/i915/intel_breadcrumbs.c                                           |   16 
 drivers/gpu/drm/i915/intel_cdclk.c                                                 |   61 
 drivers/gpu/drm/i915/intel_crt.c                                                   |   55 
 drivers/gpu/drm/i915/intel_ddi.c                                                   |  191 
 drivers/gpu/drm/i915/intel_device_info.c                                           |    2 
 drivers/gpu/drm/i915/intel_device_info.h                                           |    1 
 drivers/gpu/drm/i915/intel_display.c                                               |  803 +
 drivers/gpu/drm/i915/intel_display.h                                               |   26 
 drivers/gpu/drm/i915/intel_dp.c                                                    |  531 -
 drivers/gpu/drm/i915/intel_dp_aux_backlight.c                                      |   12 
 drivers/gpu/drm/i915/intel_dp_link_training.c                                      |   39 
 drivers/gpu/drm/i915/intel_dp_mst.c                                                |   17 
 drivers/gpu/drm/i915/intel_dpll_mgr.c                                              |  205 
 drivers/gpu/drm/i915/intel_dpll_mgr.h                                              |   18 
 drivers/gpu/drm/i915/intel_drv.h                                                   |  102 
 drivers/gpu/drm/i915/intel_dsi.h                                                   |   34 
 drivers/gpu/drm/i915/intel_dsi_vbt.c                                               |    2 
 drivers/gpu/drm/i915/intel_dvo.c                                                   |   15 
 drivers/gpu/drm/i915/intel_engine_cs.c                                             |  288 
 drivers/gpu/drm/i915/intel_fbc.c                                                   |  129 
 drivers/gpu/drm/i915/intel_fbdev.c                                                 |    9 
 drivers/gpu/drm/i915/intel_frontbuffer.c                                           |    2 
 drivers/gpu/drm/i915/intel_guc.c                                                   |  160 
 drivers/gpu/drm/i915/intel_guc.h                                                   |    5 
 drivers/gpu/drm/i915/intel_guc_fwif.h                                              |   20 
 drivers/gpu/drm/i915/intel_guc_log.c                                               |   70 
 drivers/gpu/drm/i915/intel_guc_log.h                                               |   26 
 drivers/gpu/drm/i915/intel_guc_submission.c                                        |  138 
 drivers/gpu/drm/i915/intel_gvt.c                                                   |    5 
 drivers/gpu/drm/i915/intel_hangcheck.c                                             |   17 
 drivers/gpu/drm/i915/intel_hdmi.c                                                  |  140 
 drivers/gpu/drm/i915/intel_hotplug.c                                               |  118 
 drivers/gpu/drm/i915/intel_huc.c                                                   |    8 
 drivers/gpu/drm/i915/intel_huc.h                                                   |    6 
 drivers/gpu/drm/i915/intel_i2c.c                                                   |   84 
 drivers/gpu/drm/i915/intel_lpe_audio.c                                             |    4 
 drivers/gpu/drm/i915/intel_lrc.c                                                   |  979 +-
 drivers/gpu/drm/i915/intel_lrc.h                                                   |    7 
 drivers/gpu/drm/i915/intel_lspcon.c                                                |    2 
 drivers/gpu/drm/i915/intel_lvds.c                                                  |  204 
 drivers/gpu/drm/i915/intel_modes.c                                                 |    2 
 drivers/gpu/drm/i915/intel_opregion.c                                              |   31 
 drivers/gpu/drm/i915/intel_opregion.h                                              |    1 
 drivers/gpu/drm/i915/intel_panel.c                                                 |   28 
 drivers/gpu/drm/i915/intel_pipe_crc.c                                              |  445 -
 drivers/gpu/drm/i915/intel_pm.c                                                    |  109 
 drivers/gpu/drm/i915/intel_psr.c                                                   |  631 -
 drivers/gpu/drm/i915/intel_ringbuffer.c                                            |  405 
 drivers/gpu/drm/i915/intel_ringbuffer.h                                            |  139 
 drivers/gpu/drm/i915/intel_runtime_pm.c                                            |  333 
 drivers/gpu/drm/i915/intel_sdvo.c                                                  |   49 
 drivers/gpu/drm/i915/intel_sprite.c                                                |  311 
 drivers/gpu/drm/i915/intel_tv.c                                                    |   23 
 drivers/gpu/drm/i915/intel_uc.c                                                    |  165 
 drivers/gpu/drm/i915/intel_uncore.c                                                |   28 
 drivers/gpu/drm/i915/intel_uncore.h                                                |   22 
 drivers/gpu/drm/i915/intel_vbt_defs.h                                              |   14 
 drivers/gpu/drm/i915/intel_workarounds.c                                           |  167 
 drivers/gpu/drm/i915/selftests/huge_pages.c                                        |   82 
 drivers/gpu/drm/i915/selftests/i915_gem_coherency.c                                |   47 
 drivers/gpu/drm/i915/selftests/i915_gem_context.c                                  |  301 
 drivers/gpu/drm/i915/selftests/i915_gem_dmabuf.c                                   |    2 
 drivers/gpu/drm/i915/selftests/i915_gem_evict.c                                    |   39 
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c                                      |  174 
 drivers/gpu/drm/i915/selftests/i915_gem_object.c                                   |   62 
 drivers/gpu/drm/i915/selftests/i915_mock_selftests.h                               |    1 
 drivers/gpu/drm/i915/selftests/i915_request.c                                      |   34 
 drivers/gpu/drm/i915/selftests/i915_selftest.c                                     |    2 
 drivers/gpu/drm/i915/selftests/i915_vma.c                                          |   33 
 drivers/gpu/drm/i915/selftests/igt_flush_test.c                                    |   55 
 drivers/gpu/drm/i915/selftests/igt_wedge_me.h                                      |   58 
 drivers/gpu/drm/i915/selftests/intel_breadcrumbs.c                                 |    2 
 drivers/gpu/drm/i915/selftests/intel_guc.c                                         |   10 
 drivers/gpu/drm/i915/selftests/intel_hangcheck.c                                   |  260 
 drivers/gpu/drm/i915/selftests/intel_lrc.c                                         |  133 
 drivers/gpu/drm/i915/selftests/intel_workarounds.c                                 |   24 
 drivers/gpu/drm/i915/selftests/mock_context.c                                      |    7 
 drivers/gpu/drm/i915/selftests/mock_dmabuf.c                                       |   14 
 drivers/gpu/drm/i915/selftests/mock_engine.c                                       |   49 
 drivers/gpu/drm/i915/selftests/mock_gem_device.c                                   |   20 
 drivers/gpu/drm/i915/selftests/mock_gtt.c                                          |   65 
 drivers/gpu/drm/i915/vlv_dsi.c                                                     |  117 
 drivers/gpu/drm/i915/vlv_dsi_pll.c                                                 |   98 
 drivers/gpu/drm/imx/imx-drm-core.c                                                 |   47 
 drivers/gpu/drm/imx/imx-drm.h                                                      |    1 
 drivers/gpu/drm/imx/imx-ldb.c                                                      |   14 
 drivers/gpu/drm/imx/imx-tve.c                                                      |    4 
 drivers/gpu/drm/imx/ipuv3-crtc.c                                                   |    3 
 drivers/gpu/drm/imx/parallel-display.c                                             |    4 
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c                                            |    3 
 drivers/gpu/drm/mediatek/mtk_drm_ddp.c                                             |  235 
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c                                        |   15 
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h                                        |   10 
 drivers/gpu/drm/mediatek/mtk_drm_drv.c                                             |  102 
 drivers/gpu/drm/mediatek/mtk_drm_drv.h                                             |    5 
 drivers/gpu/drm/mediatek/mtk_drm_fb.c                                              |   76 
 drivers/gpu/drm/mediatek/mtk_drm_fb.h                                              |    1 
 drivers/gpu/drm/mediatek/mtk_drm_plane.c                                           |    7 
 drivers/gpu/drm/mediatek/mtk_dsi.c                                                 |    2 
 drivers/gpu/drm/mediatek/mtk_hdmi.c                                                |    4 
 drivers/gpu/drm/meson/meson_dw_hdmi.c                                              |   22 
 drivers/gpu/drm/meson/meson_vclk.c                                                 |  656 -
 drivers/gpu/drm/meson/meson_vclk.h                                                 |    4 
 drivers/gpu/drm/meson/meson_venc.c                                                 |  378 
 drivers/gpu/drm/meson/meson_venc.h                                                 |    3 
 drivers/gpu/drm/meson/meson_venc_cvbs.c                                            |    2 
 drivers/gpu/drm/mgag200/mgag200_mode.c                                             |    4 
 drivers/gpu/drm/msm/Kconfig                                                        |    1 
 drivers/gpu/drm/msm/Makefile                                                       |   31 
 drivers/gpu/drm/msm/adreno/a3xx_gpu.c                                              |   30 
 drivers/gpu/drm/msm/adreno/a4xx_gpu.c                                              |   22 
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c                                              |  242 
 drivers/gpu/drm/msm/adreno/adreno_device.c                                         |   14 
 drivers/gpu/drm/msm/adreno/adreno_gpu.c                                            |  187 
 drivers/gpu/drm/msm/adreno/adreno_gpu.h                                            |   11 
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c                                       |  479 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h                                       |  153 
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c                                      |  637 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h                                      |  133 
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c                                           | 2138 +++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h                                           |  423 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c                                            | 2393 +++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.h                                            |  103 
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c                                        | 2498 ++++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h                                        |  177 
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h                                   |  430 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c                               |  905 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c                               |  922 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c                                        | 1173 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h                                        |   88 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.c                                         |  155 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.h                                         |   53 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c                                     |  511 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h                                     |  804 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog_format.h                              |  168 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c                                         |  323 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h                                         |  139 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c                                         |  540 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h                                         |  218 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c                                  | 1183 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h                                  |  257 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c                                        |  349 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h                                        |  128 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c                                          |  261 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h                                          |  122 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h                                        |  465 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c                                    |  250 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h                                    |  136 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c                                        |  753 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h                                        |  424 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c                                         |  398 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h                                         |  202 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c                                        |  368 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h                                        |  348 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c                                        |  275 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h                                        |  128 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h                                           |   56 
 drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c                                        |  203 
 drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h                                        |   57 
 drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c                                            |   66 
 drivers/gpu/drm/msm/disp/dpu1/dpu_irq.h                                            |   59 
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c                                            | 1345 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h                                            |  290 
 drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c                                           |  245 
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c                                          | 1963 ++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h                                          |  175 
 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c                                   |  249 
 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h                                   |  225 
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c                                             | 1079 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h                                             |  199 
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h                                          | 1007 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c                                           |  384 
 drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h                                           |   94 
 drivers/gpu/drm/msm/disp/dpu1/msm_media_info.h                                     | 1376 +++
 drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c                                          |    3 
 drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c                                           |    2 
 drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c                                  |    4 
 drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c                                |    7 
 drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c                                         |    4 
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c                                          |   52 
 drivers/gpu/drm/msm/disp/mdp5/mdp5_encoder.c                                       |   12 
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c                                           |    2 
 drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c                                          |  154 
 drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c                                         |    6 
 drivers/gpu/drm/msm/dsi/dsi.c                                                      |    3 
 drivers/gpu/drm/msm/dsi/dsi.h                                                      |   23 
 drivers/gpu/drm/msm/dsi/dsi_cfg.c                                                  |   56 
 drivers/gpu/drm/msm/dsi/dsi_cfg.h                                                  |   12 
 drivers/gpu/drm/msm/dsi/dsi_host.c                                                 |  431 -
 drivers/gpu/drm/msm/dsi/dsi_manager.c                                              |  135 
 drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c                                         |    2 
 drivers/gpu/drm/msm/edp/edp_connector.c                                            |    4 
 drivers/gpu/drm/msm/hdmi/hdmi_connector.c                                          |    4 
 drivers/gpu/drm/msm/msm_atomic.c                                                   |    7 
 drivers/gpu/drm/msm/msm_debugfs.c                                                  |   93 
 drivers/gpu/drm/msm/msm_drv.c                                                      |  230 
 drivers/gpu/drm/msm/msm_drv.h                                                      |   97 
 drivers/gpu/drm/msm/msm_fb.c                                                       |   54 
 drivers/gpu/drm/msm/msm_gpu.c                                                      |  145 
 drivers/gpu/drm/msm/msm_gpu.h                                                      |   68 
 drivers/gpu/drm/msm/msm_kms.h                                                      |   29 
 drivers/gpu/drm/nouveau/dispnv04/crtc.c                                            |    2 
 drivers/gpu/drm/nouveau/dispnv04/dac.c                                             |    2 
 drivers/gpu/drm/nouveau/dispnv04/dfp.c                                             |    2 
 drivers/gpu/drm/nouveau/dispnv04/disp.c                                            |    3 
 drivers/gpu/drm/nouveau/dispnv04/tvnv04.c                                          |    2 
 drivers/gpu/drm/nouveau/dispnv04/tvnv17.c                                          |    2 
 drivers/gpu/drm/nouveau/dispnv50/disp.c                                            |   99 
 drivers/gpu/drm/nouveau/dispnv50/wndw.c                                            |    1 
 drivers/gpu/drm/nouveau/include/nvif/object.h                                      |    2 
 drivers/gpu/drm/nouveau/nouveau_abi16.c                                            |    2 
 drivers/gpu/drm/nouveau/nouveau_backlight.c                                        |    6 
 drivers/gpu/drm/nouveau/nouveau_connector.c                                        |   40 
 drivers/gpu/drm/nouveau/nouveau_connector.h                                        |   36 
 drivers/gpu/drm/nouveau/nouveau_debugfs.c                                          |    4 
 drivers/gpu/drm/nouveau/nouveau_display.c                                          |   18 
 drivers/gpu/drm/nouveau/nouveau_drm.c                                              |   24 
 drivers/gpu/drm/nouveau/nouveau_fbcon.c                                            |    2 
 drivers/gpu/drm/nouveau/nouveau_gem.c                                              |   18 
 drivers/gpu/drm/nouveau/nouveau_hwmon.c                                            |   12 
 drivers/gpu/drm/nouveau/nouveau_platform.c                                         |    2 
 drivers/gpu/drm/nouveau/nouveau_ttm.c                                              |    3 
 drivers/gpu/drm/nouveau/nvkm/core/engine.c                                         |    3 
 drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c                                 |   13 
 drivers/gpu/drm/nouveau/nvkm/engine/disp/changf119.c                               |    2 
 drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c                                |    4 
 drivers/gpu/drm/nouveau/nvkm/engine/gr/gv100.c                                     |   21 
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/vpstate.c                                 |   10 
 drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c                                   |   10 
 drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c                                  |   21 
 drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h                                   |    1 
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c                                      |    3 
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp100.c                                     |    9 
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gp102.c                                     |    1 
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h                                      |    2 
 drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r352.c                             |   25 
 drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r367.c                             |   16 
 drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c                                |    2 
 drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp10b.c                                |    2 
 drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c                            |    2 
 drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c                            |    2 
 drivers/gpu/drm/omapdrm/dss/core.c                                                 |    4 
 drivers/gpu/drm/omapdrm/dss/dispc.c                                                |    2 
 drivers/gpu/drm/omapdrm/dss/display.c                                              |    2 
 drivers/gpu/drm/omapdrm/dss/dpi.c                                                  |    2 
 drivers/gpu/drm/omapdrm/dss/dsi.c                                                  |    2 
 drivers/gpu/drm/omapdrm/dss/dss.c                                                  |    2 
 drivers/gpu/drm/omapdrm/dss/dss.h                                                  |    5 
 drivers/gpu/drm/omapdrm/dss/pll.c                                                  |   73 
 drivers/gpu/drm/omapdrm/dss/sdi.c                                                  |    2 
 drivers/gpu/drm/omapdrm/dss/venc.c                                                 |    2 
 drivers/gpu/drm/omapdrm/dss/video-pll.c                                            |    1 
 drivers/gpu/drm/omapdrm/omap_connector.c                                           |    4 
 drivers/gpu/drm/omapdrm/omap_debugfs.c                                             |    9 
 drivers/gpu/drm/omapdrm/omap_drv.c                                                 |    6 
 drivers/gpu/drm/omapdrm/omap_drv.h                                                 |    2 
 drivers/gpu/drm/omapdrm/omap_fb.c                                                  |  109 
 drivers/gpu/drm/omapdrm/omap_fb.h                                                  |    2 
 drivers/gpu/drm/omapdrm/omap_fbdev.c                                               |    8 
 drivers/gpu/drm/omapdrm/omap_gem.c                                                 |  286 
 drivers/gpu/drm/omapdrm/omap_gem.h                                                 |    3 
 drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c                                          |   19 
 drivers/gpu/drm/panel/Kconfig                                                      |    9 
 drivers/gpu/drm/panel/Makefile                                                     |    1 
 drivers/gpu/drm/panel/panel-ilitek-ili9881c.c                                      |  503 +
 drivers/gpu/drm/panel/panel-innolux-p079zca.c                                      |  352 
 drivers/gpu/drm/panel/panel-jdi-lt070me05000.c                                     |    1 
 drivers/gpu/drm/panel/panel-lvds.c                                                 |    1 
 drivers/gpu/drm/panel/panel-orisetech-otm8009a.c                                   |   58 
 drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c                               |    1 
 drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c                                      |    2 
 drivers/gpu/drm/panel/panel-seiko-43wvf1g.c                                        |    1 
 drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c                                    |    1 
 drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c                                    |    1 
 drivers/gpu/drm/panel/panel-simple.c                                               |  298 
 drivers/gpu/drm/panel/panel-sitronix-st7789v.c                                     |    1 
 drivers/gpu/drm/pl111/Makefile                                                     |    1 
 drivers/gpu/drm/pl111/pl111_display.c                                              |   56 
 drivers/gpu/drm/pl111/pl111_drm.h                                                  |    5 
 drivers/gpu/drm/pl111/pl111_drv.c                                                  |   61 
 drivers/gpu/drm/pl111/pl111_nomadik.c                                              |   36 
 drivers/gpu/drm/pl111/pl111_nomadik.h                                              |   18 
 drivers/gpu/drm/qxl/qxl_display.c                                                  |    2 
 drivers/gpu/drm/qxl/qxl_release.c                                                  |    7 
 drivers/gpu/drm/radeon/ci_dpm.c                                                    |   20 
 drivers/gpu/drm/radeon/cik.c                                                       |   22 
 drivers/gpu/drm/radeon/r600_dpm.c                                                  |    4 
 drivers/gpu/drm/radeon/radeon.h                                                    |    4 
 drivers/gpu/drm/radeon/radeon_connectors.c                                         |   94 
 drivers/gpu/drm/radeon/radeon_dp_mst.c                                             |    6 
 drivers/gpu/drm/radeon/radeon_encoders.c                                           |    2 
 drivers/gpu/drm/radeon/radeon_object.c                                             |    7 
 drivers/gpu/drm/radeon/radeon_test.c                                               |    1 
 drivers/gpu/drm/radeon/radeon_ttm.c                                                |    8 
 drivers/gpu/drm/radeon/si.c                                                        |   22 
 drivers/gpu/drm/radeon/si_dpm.c                                                    |   20 
 drivers/gpu/drm/rcar-du/rcar_lvds.c                                                |    6 
 drivers/gpu/drm/rockchip/cdn-dp-core.c                                             |    4 
 drivers/gpu/drm/rockchip/cdn-dp-reg.c                                              |   16 
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c                                             |    4 
 drivers/gpu/drm/rockchip/inno_hdmi.c                                               |    4 
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c                                         |   86 
 drivers/gpu/drm/rockchip/rockchip_drm_fb.h                                         |    3 
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c                                        |   99 
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h                                        |   23 
 drivers/gpu/drm/rockchip/rockchip_lvds.c                                           |    8 
 drivers/gpu/drm/savage/savage_state.c                                              |    2 
 drivers/gpu/drm/scheduler/Makefile                                                 |    1 
 drivers/gpu/drm/scheduler/gpu_scheduler.c                                          |  386 
 drivers/gpu/drm/scheduler/sched_fence.c                                            |   13 
 drivers/gpu/drm/selftests/drm_mm_selftests.h                                       |    2 
 drivers/gpu/drm/selftests/test-drm_mm.c                                            |   71 
 drivers/gpu/drm/shmobile/shmob_drm_crtc.c                                          |    2 
 drivers/gpu/drm/sti/sti_cursor.c                                                   |    2 
 drivers/gpu/drm/sti/sti_drv.c                                                      |    8 
 drivers/gpu/drm/sti/sti_dvo.c                                                      |    6 
 drivers/gpu/drm/sti/sti_gdp.c                                                      |    8 
 drivers/gpu/drm/sti/sti_hda.c                                                      |    2 
 drivers/gpu/drm/sti/sti_hdmi.c                                                     |    4 
 drivers/gpu/drm/sti/sti_hqvdp.c                                                    |    2 
 drivers/gpu/drm/stm/drv.c                                                          |   10 
 drivers/gpu/drm/stm/ltdc.c                                                         |   21 
 drivers/gpu/drm/stm/ltdc.h                                                         |    1 
 drivers/gpu/drm/sun4i/Kconfig                                                      |    7 
 drivers/gpu/drm/sun4i/Makefile                                                     |    1 
 drivers/gpu/drm/sun4i/sun4i_backend.c                                              |   12 
 drivers/gpu/drm/sun4i/sun4i_crtc.c                                                 |    2 
 drivers/gpu/drm/sun4i/sun4i_drv.c                                                  |  127 
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c                                             |    4 
 drivers/gpu/drm/sun4i/sun4i_lvds.c                                                 |    4 
 drivers/gpu/drm/sun4i/sun4i_rgb.c                                                  |    4 
 drivers/gpu/drm/sun4i/sun4i_tcon.c                                                 |   67 
 drivers/gpu/drm/sun4i/sun4i_tv.c                                                   |    2 
 drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c                                             |  117 
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c                                              |   44 
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h                                              |    8 
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c                                             |   54 
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c                                         |   90 
 drivers/gpu/drm/sun4i/sun8i_mixer.c                                                |   81 
 drivers/gpu/drm/sun4i/sun8i_mixer.h                                                |    4 
 drivers/gpu/drm/sun4i/sun8i_tcon_top.c                                             |  274 
 drivers/gpu/drm/sun4i/sun8i_tcon_top.h                                             |   44 
 drivers/gpu/drm/sun4i/sun8i_ui_layer.c                                             |   61 
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c                                             |   61 
 drivers/gpu/drm/tegra/dsi.c                                                        |    5 
 drivers/gpu/drm/tegra/gem.c                                                        |   14 
 drivers/gpu/drm/tegra/hdmi.c                                                       |    2 
 drivers/gpu/drm/tegra/output.c                                                     |    6 
 drivers/gpu/drm/tegra/rgb.c                                                        |    2 
 drivers/gpu/drm/tegra/sor.c                                                        |    2 
 drivers/gpu/drm/tilcdc/tilcdc_drv.c                                                |    2 
 drivers/gpu/drm/tilcdc/tilcdc_external.c                                           |    9 
 drivers/gpu/drm/tilcdc/tilcdc_panel.c                                              |    2 
 drivers/gpu/drm/tilcdc/tilcdc_tfp410.c                                             |    4 
 drivers/gpu/drm/tinydrm/Kconfig                                                    |   11 
 drivers/gpu/drm/tinydrm/Makefile                                                   |    1 
 drivers/gpu/drm/tinydrm/core/tinydrm-core.c                                        |    3 
 drivers/gpu/drm/tinydrm/ili9225.c                                                  |    1 
 drivers/gpu/drm/tinydrm/ili9341.c                                                  |  232 
 drivers/gpu/drm/tinydrm/mi0283qt.c                                                 |    1 
 drivers/gpu/drm/tinydrm/mipi-dbi.c                                                 |    2 
 drivers/gpu/drm/tinydrm/st7586.c                                                   |    1 
 drivers/gpu/drm/tinydrm/st7735r.c                                                  |    1 
 drivers/gpu/drm/ttm/ttm_bo.c                                                       |   17 
 drivers/gpu/drm/ttm/ttm_bo_util.c                                                  |   11 
 drivers/gpu/drm/ttm/ttm_bo_vm.c                                                    |   63 
 drivers/gpu/drm/ttm/ttm_page_alloc.c                                               |   62 
 drivers/gpu/drm/ttm/ttm_page_alloc_dma.c                                           |   59 
 drivers/gpu/drm/ttm/ttm_tt.c                                                       |   25 
 drivers/gpu/drm/udl/udl_connector.c                                                |    4 
 drivers/gpu/drm/udl/udl_dmabuf.c                                                   |   18 
 drivers/gpu/drm/udl/udl_drv.h                                                      |    5 
 drivers/gpu/drm/udl/udl_fb.c                                                       |   23 
 drivers/gpu/drm/udl/udl_gem.c                                                      |   15 
 drivers/gpu/drm/udl/udl_main.c                                                     |   45 
 drivers/gpu/drm/udl/udl_modeset.c                                                  |    7 
 drivers/gpu/drm/udl/udl_transfer.c                                                 |   46 
 drivers/gpu/drm/v3d/v3d_bo.c                                                       |   28 
 drivers/gpu/drm/v3d/v3d_drv.c                                                      |   11 
 drivers/gpu/drm/v3d/v3d_drv.h                                                      |   11 
 drivers/gpu/drm/v3d/v3d_fence.c                                                    |   17 
 drivers/gpu/drm/v3d/v3d_gem.c                                                      |   13 
 drivers/gpu/drm/v3d/v3d_irq.c                                                      |    3 
 drivers/gpu/drm/v3d/v3d_regs.h                                                     |    1 
 drivers/gpu/drm/v3d/v3d_sched.c                                                    |   26 
 drivers/gpu/drm/vc4/Makefile                                                       |    1 
 drivers/gpu/drm/vc4/vc4_bo.c                                                       |    2 
 drivers/gpu/drm/vc4/vc4_crtc.c                                                     |  147 
 drivers/gpu/drm/vc4/vc4_debugfs.c                                                  |    1 
 drivers/gpu/drm/vc4/vc4_drv.c                                                      |    9 
 drivers/gpu/drm/vc4/vc4_drv.h                                                      |   10 
 drivers/gpu/drm/vc4/vc4_dsi.c                                                      |   57 
 drivers/gpu/drm/vc4/vc4_fence.c                                                    |    8 
 drivers/gpu/drm/vc4/vc4_hdmi.c                                                     |    4 
 drivers/gpu/drm/vc4/vc4_kms.c                                                      |   11 
 drivers/gpu/drm/vc4/vc4_plane.c                                                    |   98 
 drivers/gpu/drm/vc4/vc4_regs.h                                                     |    6 
 drivers/gpu/drm/vc4/vc4_txp.c                                                      |  477 +
 drivers/gpu/drm/vc4/vc4_vec.c                                                      |    2 
 drivers/gpu/drm/vgem/vgem_drv.c                                                    |    7 
 drivers/gpu/drm/virtio/virtgpu_display.c                                           |   34 
 drivers/gpu/drm/virtio/virtgpu_drv.h                                               |    1 
 drivers/gpu/drm/virtio/virtgpu_fb.c                                                |    8 
 drivers/gpu/drm/virtio/virtgpu_fence.c                                             |    7 
 drivers/gpu/drm/virtio/virtgpu_plane.c                                             |    4 
 drivers/gpu/drm/vkms/Makefile                                                      |    3 
 drivers/gpu/drm/vkms/vkms_crtc.c                                                   |  130 
 drivers/gpu/drm/vkms/vkms_drv.c                                                    |  156 
 drivers/gpu/drm/vkms/vkms_drv.h                                                    |   78 
 drivers/gpu/drm/vkms/vkms_gem.c                                                    |  179 
 drivers/gpu/drm/vkms/vkms_output.c                                                 |  111 
 drivers/gpu/drm/vkms/vkms_plane.c                                                  |   57 
 drivers/gpu/drm/vmwgfx/Kconfig                                                     |    1 
 drivers/gpu/drm/vmwgfx/Makefile                                                    |    4 
 drivers/gpu/drm/vmwgfx/device_include/svga3d_caps.h                                |    3 
 drivers/gpu/drm/vmwgfx/device_include/svga3d_cmd.h                                 |  233 
 drivers/gpu/drm/vmwgfx/device_include/svga3d_devcaps.h                             |   86 
 drivers/gpu/drm/vmwgfx/device_include/svga3d_dx.h                                  |  300 
 drivers/gpu/drm/vmwgfx/device_include/svga3d_limits.h                              |    7 
 drivers/gpu/drm/vmwgfx/device_include/svga3d_reg.h                                 |    3 
 drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h                         | 1094 +-
 drivers/gpu/drm/vmwgfx/device_include/svga3d_types.h                               |  334 
 drivers/gpu/drm/vmwgfx/device_include/svga_escape.h                                |    3 
 drivers/gpu/drm/vmwgfx/device_include/svga_overlay.h                               |    3 
 drivers/gpu/drm/vmwgfx/device_include/svga_reg.h                                   |  211 
 drivers/gpu/drm/vmwgfx/device_include/svga_types.h                                 |    6 
 drivers/gpu/drm/vmwgfx/device_include/vmware_pack_begin.h                          |   25 
 drivers/gpu/drm/vmwgfx/device_include/vmware_pack_end.h                            |   25 
 drivers/gpu/drm/vmwgfx/vmwgfx_binding.c                                            |    4 
 drivers/gpu/drm/vmwgfx/vmwgfx_binding.h                                            |    4 
 drivers/gpu/drm/vmwgfx/vmwgfx_blit.c                                               |    3 
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.c                                                 | 1123 ++
 drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c                                             |    4 
 drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c                                         |    4 
 drivers/gpu/drm/vmwgfx/vmwgfx_context.c                                            |   18 
 drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c                                            |   18 
 drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c                                             |  376 
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c                                                |   72 
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h                                                |  186 
 drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c                                            |  122 
 drivers/gpu/drm/vmwgfx/vmwgfx_fb.c                                                 |   41 
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c                                              |   42 
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.h                                              |    4 
 drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c                                               |    4 
 drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c                                                |    4 
 drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c                                      |    4 
 drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c                                              |   29 
 drivers/gpu/drm/vmwgfx/vmwgfx_irq.c                                                |    4 
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c                                                |  604 -
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.h                                                |   80 
 drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c                                                |   16 
 drivers/gpu/drm/vmwgfx/vmwgfx_marker.c                                             |    4 
 drivers/gpu/drm/vmwgfx/vmwgfx_mob.c                                                |   10 
 drivers/gpu/drm/vmwgfx/vmwgfx_msg.c                                                |   18 
 drivers/gpu/drm/vmwgfx/vmwgfx_msg.h                                                |   35 
 drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c                                            |   28 
 drivers/gpu/drm/vmwgfx/vmwgfx_prime.c                                              |   18 
 drivers/gpu/drm/vmwgfx/vmwgfx_reg.h                                                |    4 
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c                                           |  709 -
 drivers/gpu/drm/vmwgfx/vmwgfx_resource_priv.h                                      |    4 
 drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c                                               |  146 
 drivers/gpu/drm/vmwgfx/vmwgfx_shader.c                                             |   30 
 drivers/gpu/drm/vmwgfx/vmwgfx_simple_resource.c                                    |    4 
 drivers/gpu/drm/vmwgfx/vmwgfx_so.c                                                 |    4 
 drivers/gpu/drm/vmwgfx/vmwgfx_so.h                                                 |    4 
 drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c                                               |  109 
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c                                            |  553 -
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c                                         |   10 
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c                                           |    4 
 drivers/gpu/drm/vmwgfx/vmwgfx_va.c                                                 |    4 
 drivers/gpu/drm/xen/xen_drm_front.c                                                |    2 
 drivers/gpu/drm/xen/xen_drm_front.h                                                |    4 
 drivers/gpu/drm/xen/xen_drm_front_shbuf.c                                          |    2 
 drivers/gpu/drm/zte/zx_hdmi.c                                                      |    4 
 drivers/gpu/drm/zte/zx_plane.c                                                     |    2 
 drivers/gpu/drm/zte/zx_tvenc.c                                                     |    2 
 drivers/gpu/drm/zte/zx_vga.c                                                       |    4 
 drivers/gpu/ipu-v3/ipu-common.c                                                    |    6 
 drivers/gpu/ipu-v3/ipu-cpmem.c                                                     |   29 
 drivers/gpu/ipu-v3/ipu-csi.c                                                       |   37 
 drivers/gpu/ipu-v3/ipu-image-convert.c                                             |    6 
 drivers/hid/hid-core.c                                                             |    5 
 drivers/hid/hid-debug.c                                                            |    8 
 drivers/hid/i2c-hid/i2c-hid.c                                                      |    2 
 drivers/hid/usbhid/hiddev.c                                                        |   11 
 drivers/hid/wacom_wac.c                                                            |   10 
 drivers/i2c/busses/i2c-cht-wc.c                                                    |    3 
 drivers/i2c/busses/i2c-davinci.c                                                   |    8 
 drivers/i2c/busses/i2c-imx.c                                                       |    5 
 drivers/i2c/busses/i2c-rcar.c                                                      |   54 
 drivers/i2c/busses/i2c-stu300.c                                                    |    2 
 drivers/i2c/busses/i2c-tegra.c                                                     |   17 
 drivers/i2c/i2c-core-base.c                                                        |   11 
 drivers/infiniband/core/uverbs_cmd.c                                               |   28 
 drivers/infiniband/hw/cxgb4/mem.c                                                  |    2 
 drivers/infiniband/hw/hfi1/rc.c                                                    |    2 
 drivers/infiniband/hw/hfi1/uc.c                                                    |    4 
 drivers/infiniband/hw/hfi1/ud.c                                                    |    4 
 drivers/infiniband/hw/hfi1/verbs_txreq.c                                           |    4 
 drivers/infiniband/hw/hfi1/verbs_txreq.h                                           |    4 
 drivers/infiniband/hw/mlx5/srq.c                                                   |   18 
 drivers/input/mouse/elan_i2c_core.c                                                |    2 
 drivers/input/serio/i8042-x86ia64io.h                                              |    7 
 drivers/iommu/intel-iommu.c                                                        |   32 
 drivers/md/dm-writecache.c                                                         |   43 
 drivers/media/common/videobuf2/videobuf2-dma-contig.c                              |    3 
 drivers/media/common/videobuf2/videobuf2-dma-sg.c                                  |    3 
 drivers/media/common/videobuf2/videobuf2-vmalloc.c                                 |    3 
 drivers/misc/cxl/api.c                                                             |    8 
 drivers/misc/ibmasm/ibmasmfs.c                                                     |   27 
 drivers/misc/mei/interrupt.c                                                       |    5 
 drivers/misc/vmw_balloon.c                                                         |    4 
 drivers/mmc/core/slot-gpio.c                                                       |    2 
 drivers/mmc/host/dw_mmc.c                                                          |    7 
 drivers/mmc/host/renesas_sdhi_internal_dmac.c                                      |   15 
 drivers/mmc/host/sdhci-esdhc-imx.c                                                 |   21 
 drivers/mmc/host/sunxi-mmc.c                                                       |    7 
 drivers/mtd/spi-nor/cadence-quadspi.c                                              |    6 
 drivers/net/bonding/bond_options.c                                                 |   23 
 drivers/net/can/m_can/m_can.c                                                      |   18 
 drivers/net/can/mscan/mpc5xxx_can.c                                                |    5 
 drivers/net/can/peak_canfd/peak_pciefd_main.c                                      |   19 
 drivers/net/can/xilinx_can.c                                                       |  392 
 drivers/net/dsa/mv88e6xxx/chip.c                                                   |   21 
 drivers/net/ethernet/3com/Kconfig                                                  |    2 
 drivers/net/ethernet/amd/Kconfig                                                   |    4 
 drivers/net/ethernet/aquantia/atlantic/aq_cfg.h                                    |    2 
 drivers/net/ethernet/aquantia/atlantic/aq_hw.h                                     |    4 
 drivers/net/ethernet/aquantia/atlantic/aq_main.c                                   |   11 
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c                                    |   47 
 drivers/net/ethernet/aquantia/atlantic/aq_nic.h                                    |    2 
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c                          |    2 
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c                          |    4 
 drivers/net/ethernet/atheros/atl1c/atl1c_main.c                                    |    1 
 drivers/net/ethernet/broadcom/bcmsysport.c                                         |    4 
 drivers/net/ethernet/broadcom/bcmsysport.h                                         |    3 
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c                                |   13 
 drivers/net/ethernet/broadcom/bnxt/bnxt.c                                          |   24 
 drivers/net/ethernet/broadcom/bnxt/bnxt.h                                          |    1 
 drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c                                       |   30 
 drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c                                      |    2 
 drivers/net/ethernet/broadcom/tg3.c                                                |   13 
 drivers/net/ethernet/broadcom/tg3.h                                                |    2 
 drivers/net/ethernet/cadence/macb.h                                                |   11 
 drivers/net/ethernet/cadence/macb_main.c                                           |   36 
 drivers/net/ethernet/cavium/Kconfig                                                |   12 
 drivers/net/ethernet/cavium/liquidio/lio_main.c                                    |    5 
 drivers/net/ethernet/cavium/octeon/octeon_mgmt.c                                   |   14 
 drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c                                    |    2 
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.c                                         |   35 
 drivers/net/ethernet/cirrus/Kconfig                                                |    1 
 drivers/net/ethernet/huawei/hinic/hinic_tx.c                                       |    1 
 drivers/net/ethernet/ibm/ibmvnic.c                                                 |   43 
 drivers/net/ethernet/intel/ixgbe/ixgbe_common.c                                    |   12 
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c                                     |    2 
 drivers/net/ethernet/mellanox/mlx4/en_rx.c                                         |    8 
 drivers/net/ethernet/mellanox/mlx4/resource_tracker.c                              |    2 
 drivers/net/ethernet/mellanox/mlx5/core/alloc.c                                    |    2 
 drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c                                  |    7 
 drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c                                 |   17 
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c                                    |    4 
 drivers/net/ethernet/mellanox/mlx5/core/eswitch.c                                  |    2 
 drivers/net/ethernet/mellanox/mlx5/core/fs_core.c                                  |    2 
 drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c                                |   12 
 drivers/net/ethernet/mellanox/mlx5/core/wq.c                                       |   34 
 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c                              |   48 
 drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c                            |    2 
 drivers/net/ethernet/qlogic/qed/qed.h                                              |    1 
 drivers/net/ethernet/qlogic/qed/qed_debug.c                                        |    2 
 drivers/net/ethernet/qlogic/qed/qed_l2.c                                           |   15 
 drivers/net/ethernet/qlogic/qed/qed_l2.h                                           |    2 
 drivers/net/ethernet/qlogic/qed/qed_main.c                                         |    2 
 drivers/net/ethernet/qlogic/qed/qed_mcp.c                                          |   52 
 drivers/net/ethernet/qlogic/qed/qed_sriov.c                                        |    2 
 drivers/net/ethernet/qlogic/qed/qed_vf.c                                           |    4 
 drivers/net/ethernet/qlogic/qed/qed_vf.h                                           |    7 
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c                                  |    2 
 drivers/net/ethernet/qualcomm/qca_spi.c                                            |   21 
 drivers/net/ethernet/realtek/r8169.c                                               |    4 
 drivers/net/ethernet/renesas/ravb_main.c                                           |   93 
 drivers/net/ethernet/renesas/sh_eth.c                                              |   94 
 drivers/net/ethernet/sfc/ef10.c                                                    |   30 
 drivers/net/ethernet/sfc/efx.c                                                     |   17 
 drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c                                  |    2 
 drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c                              |    1 
 drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c                                  |    1 
 drivers/net/hyperv/netvsc.c                                                        |   17 
 drivers/net/hyperv/rndis_filter.c                                                  |    1 
 drivers/net/ieee802154/adf7242.c                                                   |   34 
 drivers/net/ieee802154/at86rf230.c                                                 |   15 
 drivers/net/ieee802154/fakelb.c                                                    |    2 
 drivers/net/ieee802154/mcr20a.c                                                    |    3 
 drivers/net/phy/marvell.c                                                          |   54 
 drivers/net/phy/phy.c                                                              |    2 
 drivers/net/phy/phy_device.c                                                       |    7 
 drivers/net/phy/sfp-bus.c                                                          |   35 
 drivers/net/tun.c                                                                  |    2 
 drivers/net/usb/asix_devices.c                                                     |    4 
 drivers/net/usb/lan78xx.c                                                          |    5 
 drivers/net/usb/qmi_wwan.c                                                         |    3 
 drivers/net/usb/rtl8150.c                                                          |    2 
 drivers/net/usb/smsc75xx.c                                                         |   62 
 drivers/net/vxlan.c                                                                |  126 
 drivers/net/wireless/ath/ath10k/mac.c                                              |   16 
 drivers/net/wireless/ath/ath10k/wmi.h                                              |    1 
 drivers/net/wireless/ath/wcn36xx/testmode.c                                        |    2 
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c                            |    7 
 drivers/net/wireless/marvell/mwifiex/usb.c                                         |    7 
 drivers/net/wireless/mediatek/mt7601u/phy.c                                        |    6 
 drivers/net/wireless/quantenna/qtnfmac/cfg80211.c                                  |    3 
 drivers/net/wireless/realtek/rtlwifi/base.c                                        |   17 
 drivers/net/wireless/realtek/rtlwifi/base.h                                        |    2 
 drivers/net/wireless/realtek/rtlwifi/core.c                                        |    3 
 drivers/net/wireless/realtek/rtlwifi/pci.c                                         |    2 
 drivers/net/wireless/realtek/rtlwifi/ps.c                                          |    4 
 drivers/net/wireless/realtek/rtlwifi/usb.c                                         |    2 
 drivers/nvdimm/claim.c                                                             |    1 
 drivers/nvme/host/core.c                                                           |   63 
 drivers/nvme/host/fabrics.c                                                        |   10 
 drivers/nvme/host/fabrics.h                                                        |    3 
 drivers/nvme/host/fc.c                                                             |    2 
 drivers/nvme/host/pci.c                                                            |   12 
 drivers/nvme/host/rdma.c                                                           |    2 
 drivers/nvme/target/configfs.c                                                     |    9 
 drivers/nvme/target/core.c                                                         |    2 
 drivers/nvme/target/fc.c                                                           |   44 
 drivers/nvme/target/loop.c                                                         |    2 
 drivers/nvmem/core.c                                                               |    4 
 drivers/of/base.c                                                                  |    6 
 drivers/of/of_private.h                                                            |    2 
 drivers/of/overlay.c                                                               |   11 
 drivers/pci/controller/dwc/pcie-designware-host.c                                  |    3 
 drivers/pci/controller/pci-aardvark.c                                              |    2 
 drivers/pci/controller/pci-ftpci100.c                                              |    2 
 drivers/pci/controller/pci-hyperv.c                                                |    8 
 drivers/pci/controller/pci-v3-semi.c                                               |    2 
 drivers/pci/controller/pci-versatile.c                                             |    2 
 drivers/pci/controller/pci-xgene.c                                                 |    2 
 drivers/pci/controller/pcie-mediatek.c                                             |    2 
 drivers/pci/endpoint/pci-epf-core.c                                                |   62 
 drivers/pci/of.c                                                                   |    2 
 drivers/pci/pci.c                                                                  |   40 
 drivers/pci/pcie/err.c                                                             |    2 
 drivers/phy/broadcom/phy-brcm-usb-init.c                                           |    4 
 drivers/phy/motorola/phy-mapphone-mdm6600.c                                        |    4 
 drivers/pinctrl/bcm/pinctrl-nsp-mux.c                                              |    6 
 drivers/pinctrl/mediatek/pinctrl-mt7622.c                                          |   48 
 drivers/pinctrl/pinctrl-ingenic.c                                                  |    2 
 drivers/pinctrl/sh-pfc/pfc-r8a77970.c                                              |   14 
 drivers/platform/x86/dell-laptop.c                                                 |    2 
 drivers/ptp/ptp_chardev.c                                                          |    1 
 drivers/rtc/interface.c                                                            |    8 
 drivers/rtc/rtc-mrst.c                                                             |    4 
 drivers/scsi/cxlflash/main.h                                                       |    4 
 drivers/scsi/cxlflash/ocxl_hw.c                                                    |    5 
 drivers/scsi/hpsa.c                                                                |   25 
 drivers/scsi/hpsa.h                                                                |    1 
 drivers/scsi/qedf/qedf_main.c                                                      |   12 
 drivers/scsi/qedi/qedi_main.c                                                      |   11 
 drivers/scsi/qla2xxx/qla_def.h                                                     |    2 
 drivers/scsi/qla2xxx/qla_gs.c                                                      |   40 
 drivers/scsi/qla2xxx/qla_init.c                                                    |   14 
 drivers/scsi/qla2xxx/qla_os.c                                                      |    4 
 drivers/scsi/scsi_error.c                                                          |   14 
 drivers/scsi/sd_zbc.c                                                              |    5 
 drivers/soc/imx/gpc.c                                                              |   21 
 drivers/staging/android/ion/ion.c                                                  |    6 
 drivers/staging/ks7010/ks_hostif.c                                                 |   12 
 drivers/staging/media/omap4iss/iss_video.c                                         |    3 
 drivers/staging/rtl8188eu/Kconfig                                                  |    1 
 drivers/staging/rtl8188eu/core/rtw_recv.c                                          |  161 
 drivers/staging/rtl8188eu/core/rtw_security.c                                      |   92 
 drivers/staging/rtl8723bs/core/rtw_ap.c                                            |    2 
 drivers/staging/rtlwifi/rtl8822be/hw.c                                             |    2 
 drivers/staging/rtlwifi/wifi.h                                                     |    1 
 drivers/staging/speakup/speakup_soft.c                                             |    6 
 drivers/staging/vboxvideo/vbox_mode.c                                              |    4 
 drivers/tee/tee_shm.c                                                              |    6 
 drivers/thunderbolt/domain.c                                                       |    4 
 drivers/uio/uio.c                                                                  |  139 
 drivers/usb/chipidea/Kconfig                                                       |    9 
 drivers/usb/chipidea/Makefile                                                      |    3 
 drivers/usb/chipidea/ci.h                                                          |    8 
 drivers/usb/chipidea/ulpi.c                                                        |    3 
 drivers/usb/class/cdc-acm.c                                                        |    3 
 drivers/usb/core/hub.c                                                             |    8 
 drivers/usb/core/quirks.c                                                          |    4 
 drivers/usb/dwc2/gadget.c                                                          |    6 
 drivers/usb/dwc2/hcd.c                                                             |   54 
 drivers/usb/dwc2/hcd_intr.c                                                        |    9 
 drivers/usb/dwc3/ep0.c                                                             |    3 
 drivers/usb/gadget/composite.c                                                     |    1 
 drivers/usb/gadget/function/f_fs.c                                                 |    2 
 drivers/usb/gadget/function/f_uac2.c                                               |   24 
 drivers/usb/gadget/function/u_audio.c                                              |   88 
 drivers/usb/gadget/udc/aspeed-vhub/Kconfig                                         |    1 
 drivers/usb/gadget/udc/aspeed-vhub/ep0.c                                           |   11 
 drivers/usb/gadget/udc/aspeed-vhub/epn.c                                           |   14 
 drivers/usb/gadget/udc/aspeed-vhub/vhub.h                                          |   33 
 drivers/usb/gadget/udc/r8a66597-udc.c                                              |    6 
 drivers/usb/host/xhci-dbgcap.c                                                     |   12 
 drivers/usb/host/xhci-mem.c                                                        |    2 
 drivers/usb/host/xhci.c                                                            |    1 
 drivers/usb/misc/yurex.c                                                           |   23 
 drivers/usb/phy/phy-fsl-usb.c                                                      |    4 
 drivers/usb/serial/ch341.c                                                         |    2 
 drivers/usb/serial/cp210x.c                                                        |    1 
 drivers/usb/serial/keyspan_pda.c                                                   |    4 
 drivers/usb/serial/mos7840.c                                                       |    3 
 drivers/usb/typec/tcpm.c                                                           |    7 
 drivers/vfio/pci/vfio_pci.c                                                        |    4 
 drivers/vfio/vfio_iommu_spapr_tce.c                                                |   10 
 drivers/video/console/Kconfig                                                      |   11 
 drivers/video/console/dummycon.c                                                   |   69 
 drivers/video/fbdev/core/fbcon.c                                                   |   83 
 fs/aio.c                                                                           |    5 
 fs/autofs/dev-ioctl.c                                                              |   22 
 fs/binfmt_elf.c                                                                    |    5 
 fs/block_dev.c                                                                     |    9 
 fs/btrfs/extent_io.c                                                               |    7 
 fs/btrfs/ioctl.c                                                                   |    2 
 fs/btrfs/scrub.c                                                                   |   17 
 fs/btrfs/volumes.c                                                                 |    2 
 fs/cachefiles/bind.c                                                               |    3 
 fs/cachefiles/namei.c                                                              |    3 
 fs/cachefiles/rdwr.c                                                               |   17 
 fs/exec.c                                                                          |    7 
 fs/ext4/balloc.c                                                                   |    3 
 fs/ext4/ialloc.c                                                                   |    8 
 fs/ext4/inline.c                                                                   |   19 
 fs/ext4/inode.c                                                                    |   16 
 fs/ext4/mmp.c                                                                      |    7 
 fs/ext4/super.c                                                                    |   15 
 fs/fat/inode.c                                                                     |   20 
 fs/fscache/cache.c                                                                 |    2 
 fs/fscache/cookie.c                                                                |    7 
 fs/fscache/object.c                                                                |    1 
 fs/fscache/operation.c                                                             |    6 
 fs/hugetlbfs/inode.c                                                               |    2 
 fs/internal.h                                                                      |    1 
 fs/proc/task_mmu.c                                                                 |    3 
 fs/reiserfs/prints.c                                                               |  141 
 fs/squashfs/cache.c                                                                |    3 
 fs/squashfs/file.c                                                                 |    8 
 fs/squashfs/fragment.c                                                             |    4 
 fs/squashfs/squashfs_fs.h                                                          |    6 
 fs/xfs/libxfs/xfs_alloc.c                                                          |    5 
 fs/xfs/libxfs/xfs_inode_buf.c                                                      |    6 
 include/asm-generic/tlb.h                                                          |    8 
 include/drm/drmP.h                                                                 |   18 
 include/drm/drm_atomic.h                                                           |   14 
 include/drm/drm_atomic_helper.h                                                    |    1 
 include/drm/drm_bridge.h                                                           |   48 
 include/drm/drm_client.h                                                           |  139 
 include/drm/drm_connector.h                                                        |  279 
 include/drm/drm_crtc.h                                                             |  276 
 include/drm/drm_debugfs_crc.h                                                      |    3 
 include/drm/drm_device.h                                                           |   21 
 include/drm/drm_dp_helper.h                                                        |   56 
 include/drm/drm_drv.h                                                              |   29 
 include/drm/drm_encoder.h                                                          |   16 
 include/drm/drm_fb_cma_helper.h                                                    |    6 
 include/drm/drm_fb_helper.h                                                        |   38 
 include/drm/drm_file.h                                                             |    7 
 include/drm/drm_fourcc.h                                                           |    2 
 include/drm/drm_mm.h                                                               |   34 
 include/drm/drm_mode_config.h                                                      |   36 
 include/drm/drm_modes.h                                                            |    2 
 include/drm/drm_modeset_helper_vtables.h                                           |   17 
 include/drm/drm_of.h                                                               |    8 
 include/drm/drm_panel.h                                                            |    3 
 include/drm/drm_pci.h                                                              |    7 
 include/drm/drm_plane.h                                                            |  197 
 include/drm/drm_plane_helper.h                                                     |    6 
 include/drm/drm_prime.h                                                            |    6 
 include/drm/drm_print.h                                                            |   77 
 include/drm/drm_property.h                                                         |    4 
 include/drm/drm_vma_manager.h                                                      |    1 
 include/drm/drm_writeback.h                                                        |  136 
 include/drm/gpu_scheduler.h                                                        |  174 
 include/drm/i915_drm.h                                                             |    4 
 include/drm/i915_pciids.h                                                          |   37 
 include/drm/tinydrm/tinydrm.h                                                      |   23 
 include/drm/ttm/ttm_bo_api.h                                                       |   25 
 include/drm/ttm/ttm_set_memory.h                                                   |  150 
 include/dt-bindings/clock/sun8i-tcon-top.h                                         |   11 
 include/linux/ascii85.h                                                            |   38 
 include/linux/blk-mq.h                                                             |   14 
 include/linux/bpf-cgroup.h                                                         |    1 
 include/linux/bpfilter.h                                                           |    6 
 include/linux/console.h                                                            |    5 
 include/linux/delayacct.h                                                          |    2 
 include/linux/dma-buf.h                                                            |   21 
 include/linux/dma-fence.h                                                          |   32 
 include/linux/eventfd.h                                                            |    1 
 include/linux/filter.h                                                             |    6 
 include/linux/fs.h                                                                 |    1 
 include/linux/fsl/guts.h                                                           |    1 
 include/linux/hid.h                                                                |    3 
 include/linux/if_bridge.h                                                          |    4 
 include/linux/igmp.h                                                               |    2 
 include/linux/intel-iommu.h                                                        |    1 
 include/linux/libata.h                                                             |   24 
 include/linux/marvell_phy.h                                                        |    2 
 include/linux/mlx5/driver.h                                                        |   18 
 include/linux/mm.h                                                                 |   20 
 include/linux/pci.h                                                                |    5 
 include/linux/ring_buffer.h                                                        |    1 
 include/linux/sched/task.h                                                         |    2 
 include/linux/skbuff.h                                                             |   10 
 include/linux/syscalls.h                                                           |    1 
 include/linux/uio_driver.h                                                         |    2 
 include/linux/ww_mutex.h                                                           |   45 
 include/net/cfg80211.h                                                             |   12 
 include/net/ip6_fib.h                                                              |    5 
 include/net/ip6_route.h                                                            |    6 
 include/net/ipv6.h                                                                 |   13 
 include/net/netfilter/nf_tables.h                                                  |    5 
 include/net/netfilter/nf_tables_core.h                                             |    6 
 include/net/netfilter/nf_tproxy.h                                                  |    4 
 include/net/tc_act/tc_csum.h                                                       |    1 
 include/net/tc_act/tc_tunnel_key.h                                                 |    1 
 include/net/tcp.h                                                                  |   13 
 include/net/xdp_sock.h                                                             |    4 
 include/uapi/drm/amdgpu_drm.h                                                      |   27 
 include/uapi/drm/drm.h                                                             |    9 
 include/uapi/drm/drm_fourcc.h                                                      |  176 
 include/uapi/drm/drm_mode.h                                                        |    8 
 include/uapi/drm/vmwgfx_drm.h                                                      |  166 
 include/uapi/linux/aio_abi.h                                                       |    6 
 include/uapi/linux/btf.h                                                           |    2 
 include/uapi/linux/ethtool.h                                                       |    2 
 include/uapi/linux/kfd_ioctl.h                                                     |   33 
 include/uapi/linux/rseq.h                                                          |  102 
 include/uapi/linux/tcp.h                                                           |    4 
 include/uapi/linux/types_32_64.h                                                   |   50 
 include/video/mipi_display.h                                                       |    3 
 ipc/sem.c                                                                          |    2 
 kernel/bpf/btf.c                                                                   |   46 
 kernel/bpf/devmap.c                                                                |    7 
 kernel/bpf/hashtab.c                                                               |   16 
 kernel/bpf/sockmap.c                                                               |   43 
 kernel/bpf/syscall.c                                                               |    4 
 kernel/bpf/verifier.c                                                              |   11 
 kernel/fork.c                                                                      |   33 
 kernel/kthread.c                                                                   |    8 
 kernel/locking/locktorture.c                                                       |    2 
 kernel/locking/mutex.c                                                             |  345 
 kernel/locking/test-ww_mutex.c                                                     |    2 
 kernel/memremap.c                                                                  |   22 
 kernel/printk/printk.c                                                             |    1 
 kernel/rseq.c                                                                      |   41 
 kernel/sched/deadline.c                                                            |   11 
 kernel/softirq.c                                                                   |   12 
 kernel/stop_machine.c                                                              |    6 
 kernel/time/tick-common.c                                                          |    3 
 kernel/trace/ring_buffer.c                                                         |   16 
 kernel/trace/trace.c                                                               |   14 
 kernel/trace/trace_events_trigger.c                                                |   18 
 kernel/trace/trace_kprobe.c                                                        |   21 
 kernel/trace/trace_output.c                                                        |    5 
 lib/Kconfig.kasan                                                                  |    2 
 lib/iov_iter.c                                                                     |   77 
 lib/locking-selftest.c                                                             |    2 
 lib/rhashtable.c                                                                   |   27 
 mm/gup.c                                                                           |    2 
 mm/huge_memory.c                                                                   |    2 
 mm/memblock.c                                                                      |    6 
 mm/memcontrol.c                                                                    |    2 
 mm/mempolicy.c                                                                     |    1 
 mm/mmap.c                                                                          |   67 
 mm/nommu.c                                                                         |   12 
 mm/page_alloc.c                                                                    |    8 
 mm/rmap.c                                                                          |    8 
 mm/shmem.c                                                                         |    1 
 mm/zswap.c                                                                         |    9 
 net/9p/client.c                                                                    |    3 
 net/batman-adv/bat_iv_ogm.c                                                        |    4 
 net/batman-adv/bat_v.c                                                             |    4 
 net/batman-adv/debugfs.c                                                           |   40 
 net/batman-adv/debugfs.h                                                           |   11 
 net/batman-adv/hard-interface.c                                                    |   37 
 net/batman-adv/translation-table.c                                                 |    7 
 net/bpf/test_run.c                                                                 |   17 
 net/caif/caif_dev.c                                                                |    4 
 net/core/filter.c                                                                  |  149 
 net/core/gen_stats.c                                                               |   16 
 net/core/page_pool.c                                                               |    2 
 net/core/rtnetlink.c                                                               |    9 
 net/core/skbuff.c                                                                  |   11 
 net/core/sock.c                                                                    |    6 
 net/dns_resolver/dns_key.c                                                         |   28 
 net/ieee802154/6lowpan/core.c                                                      |    6 
 net/ipv4/fib_frontend.c                                                            |    1 
 net/ipv4/igmp.c                                                                    |   61 
 net/ipv4/inet_fragment.c                                                           |    2 
 net/ipv4/ip_output.c                                                               |    2 
 net/ipv4/ip_sockglue.c                                                             |   11 
 net/ipv4/netfilter/ip_tables.c                                                     |    1 
 net/ipv4/netfilter/nf_tproxy_ipv4.c                                                |   18 
 net/ipv4/sysctl_net_ipv4.c                                                         |    5 
 net/ipv4/tcp.c                                                                     |   16 
 net/ipv4/tcp_dctcp.c                                                               |   75 
 net/ipv4/tcp_input.c                                                               |   65 
 net/ipv4/tcp_ipv4.c                                                                |   23 
 net/ipv4/tcp_output.c                                                              |   36 
 net/ipv6/Kconfig                                                                   |    1 
 net/ipv6/addrconf.c                                                                |    3 
 net/ipv6/calipso.c                                                                 |    9 
 net/ipv6/datagram.c                                                                |    7 
 net/ipv6/exthdrs.c                                                                 |  111 
 net/ipv6/icmp.c                                                                    |    5 
 net/ipv6/ip6_fib.c                                                                 |  156 
 net/ipv6/ip6_gre.c                                                                 |    3 
 net/ipv6/ip6_output.c                                                              |    2 
 net/ipv6/ipv6_sockglue.c                                                           |   32 
 net/ipv6/mcast.c                                                                   |   67 
 net/ipv6/ndisc.c                                                                   |    2 
 net/ipv6/netfilter/ip6_tables.c                                                    |    1 
 net/ipv6/netfilter/nf_conntrack_reasm.c                                            |    2 
 net/ipv6/netfilter/nf_tproxy_ipv6.c                                                |   18 
 net/ipv6/route.c                                                                   |   51 
 net/ipv6/seg6_iptunnel.c                                                           |    2 
 net/ipv6/tcp_ipv6.c                                                                |    6 
 net/mac80211/rx.c                                                                  |    5 
 net/mac80211/util.c                                                                |    3 
 net/netfilter/Kconfig                                                              |   25 
 net/netfilter/Makefile                                                             |    7 
 net/netfilter/nf_conntrack_core.c                                                  |    2 
 net/netfilter/nf_conntrack_proto_dccp.c                                            |    8 
 net/netfilter/nf_tables_api.c                                                      |  304 
 net/netfilter/nf_tables_set_core.c                                                 |   28 
 net/netfilter/nft_compat.c                                                         |   13 
 net/netfilter/nft_immediate.c                                                      |    3 
 net/netfilter/nft_lookup.c                                                         |   13 
 net/netfilter/nft_set_bitmap.c                                                     |   19 
 net/netfilter/nft_set_hash.c                                                       |   30 
 net/netfilter/nft_set_rbtree.c                                                     |   26 
 net/netfilter/xt_TPROXY.c                                                          |    8 
 net/nfc/llcp_commands.c                                                            |    9 
 net/nsh/nsh.c                                                                      |    2 
 net/packet/af_packet.c                                                             |    2 
 net/qrtr/qrtr.c                                                                    |   13 
 net/sched/act_csum.c                                                               |    6 
 net/sched/act_tunnel_key.c                                                         |    6 
 net/sched/cls_api.c                                                                |    4 
 net/sched/sch_fq_codel.c                                                           |   25 
 net/sctp/transport.c                                                               |    2 
 net/smc/af_smc.c                                                                   |   37 
 net/smc/smc_clc.c                                                                  |    3 
 net/smc/smc_close.c                                                                |    2 
 net/smc/smc_tx.c                                                                   |   12 
 net/tipc/discover.c                                                                |   18 
 net/tipc/net.c                                                                     |   17 
 net/tipc/node.c                                                                    |    7 
 net/tls/tls_sw.c                                                                   |   10 
 net/wireless/nl80211.c                                                             |   25 
 net/wireless/reg.c                                                                 |   28 
 net/wireless/trace.h                                                               |   18 
 net/xdp/xsk.c                                                                      |   30 
 net/xdp/xsk_queue.h                                                                |    9 
 samples/bpf/.gitignore                                                             |   49 
 samples/bpf/parse_varlen.c                                                         |    6 
 samples/bpf/test_overhead_user.c                                                   |   19 
 samples/bpf/trace_event_user.c                                                     |   27 
 samples/bpf/xdp2skb_meta.sh                                                        |    6 
 samples/bpf/xdpsock_user.c                                                         |    2 
 samples/vfio-mdev/mbochs.c                                                         |    4 
 scripts/Kbuild.include                                                             |    2 
 scripts/Makefile.build                                                             |    3 
 scripts/Makefile.clean                                                             |    3 
 scripts/Makefile.modbuiltin                                                        |    4 
 scripts/Makefile.modinst                                                           |    4 
 scripts/Makefile.modpost                                                           |    4 
 scripts/Makefile.modsign                                                           |    3 
 scripts/checkpatch.pl                                                              |    6 
 scripts/extract-vmlinux                                                            |    2 
 scripts/tags.sh                                                                    |    3 
 sound/core/rawmidi.c                                                               |   20 
 sound/pci/hda/patch_ca0132.c                                                       |    3 
 sound/pci/hda/patch_conexant.c                                                     |    1 
 sound/pci/hda/patch_hdmi.c                                                         |   19 
 sound/pci/hda/patch_realtek.c                                                      |    8 
 tools/bpf/bpftool/common.c                                                         |   11 
 tools/build/Build.include                                                          |    6 
 tools/build/Makefile                                                               |    2 
 tools/objtool/elf.c                                                                |    6 
 tools/perf/Makefile.config                                                         |    3 
 tools/perf/arch/x86/util/perf_regs.c                                               |    2 
 tools/perf/builtin-stat.c                                                          |    2 
 tools/perf/jvmti/jvmti_agent.c                                                     |    3 
 tools/perf/pmu-events/Build                                                        |    2 
 tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py                   |   40 
 tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py             |    4 
 tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/SchedGui.py               |    2 
 tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py                   |   11 
 tools/perf/scripts/python/sched-migration.py                                       |   14 
 tools/perf/tests/builtin-test.c                                                    |    2 
 tools/perf/tests/shell/record+probe_libc_inet_pton.sh                              |   37 
 tools/perf/tests/shell/trace+probe_vfs_getname.sh                                  |    2 
 tools/perf/util/llvm-utils.c                                                       |    6 
 tools/perf/util/scripting-engines/trace-event-python.c                             |   37 
 tools/testing/nvdimm/test/nfit.c                                                   |    3 
 tools/testing/selftests/bpf/Makefile                                               |    2 
 tools/testing/selftests/bpf/test_verifier.c                                        |   63 
 tools/testing/selftests/ftrace/test.d/00basic/snapshot.tc                          |   28 
 tools/testing/selftests/net/fib_tests.sh                                           |   41 
 tools/testing/selftests/net/udpgso_bench.sh                                        |    3 
 tools/testing/selftests/rseq/rseq.h                                                |   24 
 tools/usb/ffs-test.c                                                               |   19 
 virt/kvm/eventfd.c                                                                 |   17 
 1741 files changed, 83598 insertions(+), 28510 deletions(-)

New commits:
commit 9217f88c82c7bf9edc8d8c07165c2d14e09f10eb
Merge: b48b001db30c 557ce95051c8
Author: Kevin Brace <kevinbrace at gmx.com>
Date:   Wed Aug 15 12:37:01 2018 -0700

    Merge tag 'drm-next-2018-08-15' of git://anongit.freedesktop.org/drm/drm into drm-next-4.19
    
    drm pull for 4.19-rc1

diff --cc drivers/gpu/drm/Makefile
index 38c07562c650,a6771cef85e2..bc0d346eb26a
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@@ -67,8 -68,9 +68,9 @@@ obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus
  obj-$(CONFIG_DRM_SIS)   += sis/
  obj-$(CONFIG_DRM_SAVAGE)+= savage/
  obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/
 -obj-$(CONFIG_DRM_VIA)	+=via/
 +obj-$(CONFIG_DRM_OPENCHROME) +=openchrome/
  obj-$(CONFIG_DRM_VGEM)	+= vgem/
+ obj-$(CONFIG_DRM_VKMS)	+= vkms/
  obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/
  obj-$(CONFIG_DRM_EXYNOS) +=exynos/
  obj-$(CONFIG_DRM_ROCKCHIP) +=rockchip/
commit 557ce95051c8eff67af48612ab350d8408aa0541
Merge: 8511b7da1869 b045d3af7d1f
Author: Dave Airlie <airlied at redhat.com>
Date:   Fri Aug 10 11:43:02 2018 +1000

    Merge branch 'drm-next-4.19' of git://people.freedesktop.org/~agd5f/linux into drm-next
    
    More fixes for 4.19:
    - Fixes for scheduler
    - Fix for SR-IOV
    - Fixes for display
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    From: Alex Deucher <alexdeucher at gmail.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20180809200052.2777-1-alexander.deucher@amd.com

commit 8511b7da18694491afb50a5cf1515c29a999c7a4
Merge: 4abfe15e2a0a 2d87e6c1b99c
Author: Dave Airlie <airlied at redhat.com>
Date:   Fri Aug 10 11:37:30 2018 +1000

    Merge tag 'imx-drm-fixes-2018-08-03' of git://git.pengutronix.de/git/pza/linux into drm-next
    
    drm/imx: ipu-v3 plane offset and IPU id fixes
    
    - Fix U/V plane offsets for odd vertical offsets. Due to wrong operator
      order, the y offset was not rounded down properly for vertically
      chroma subsampled planar formats.
    - Fix IPU id number for boards that don't have an OF alias for their
      single IPU in the device tree. This is necessary to support imx-media
      on i.MX51 and i.MX53 SoCs.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    From: Philipp Zabel <p.zabel at pengutronix.de>
    Link: https://patchwork.freedesktop.org/patch/msgid/1533552680.4204.14.camel@pengutronix.de

commit 4abfe15e2a0a700eb36587dc3b3b1c29a609e4fb
Merge: 824da016fde1 5c41bb607125
Author: Dave Airlie <airlied at redhat.com>
Date:   Fri Aug 10 10:44:20 2018 +1000

    Merge tag 'imx-drm-next-2018-08-03' of git://git.pengutronix.de/git/pza/linux into drm-next
    
    drm/imx: use suspend/resume helpers, add ipu-v3 V4L2 XRGB32/XBGR32 support
    
    - Convert imx_drm_suspend/resume to use the
      drm_mode_config_helper_suspend/ resume functions.
    - Add support for V4L2_PIX_FMT_XRGB32/XBGR32, corresponding to
      DRM_FORMAT_XRGB8888/BGRX8888, respectively.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    From: Philipp Zabel <p.zabel at pengutronix.de>
    Link: https://patchwork.freedesktop.org/patch/msgid/1533552701.4204.15.camel@pengutronix.de

commit b045d3af7d1f443dd5209a096568e0ce983127e9
Author: Emily Deng <Emily.Deng at amd.com>
Date:   Thu Aug 9 10:03:04 2018 +0800

    drm/amdgpu/sriov: give 8s for recover vram under RUNTIME
    
    Extend the timeout for recovering vram bos from shadows on sr-iov
    to cover the worst case scenario for timeslices and VFs
    
    Under runtime, the wait fence time could be quite long when
    other VFs are in exclusive mode. For example, for 4 VF, every
    VF's exclusive timeout time is set to 3s, then the worst case is
    9s. If the VF number is more than 4,then the worst case time will
    be longer.
    The 8s is the test data, with setting to 8s, it will pass the TDR
    test for 1000 times.
    
    SWDEV-161490
    
    Signed-off-by: Monk Liu <Monk.Liu at amd.com>
    Signed-off-by: Emily Deng <Emily.Deng at amd.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index ec53d8f96d06..3ef34df8937b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -3105,7 +3105,7 @@ static int amdgpu_device_handle_vram_lost(struct amdgpu_device *adev)
 	long tmo;
 
 	if (amdgpu_sriov_runtime(adev))
-		tmo = msecs_to_jiffies(amdgpu_lockup_timeout);
+		tmo = msecs_to_jiffies(8000);
 	else
 		tmo = msecs_to_jiffies(100);
 
commit 275e6fa8ecfd8ec1eb36a865d6dafc64f4bed462
Author: Nayan Deshmukh <nayan26deshmukh at gmail.com>
Date:   Thu Aug 9 15:18:12 2018 +0530

    drm/scheduler: fix param documentation
    
    We no longer have sched parameter so remove its description
    as well
    
    Signed-off-by: Nayan Deshmukh <nayan26deshmukh at gmail.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler.c b/drivers/gpu/drm/scheduler/gpu_scheduler.c
index a70c7f7fd6fe..4fc211e19d6e 100644
--- a/drivers/gpu/drm/scheduler/gpu_scheduler.c
+++ b/drivers/gpu/drm/scheduler/gpu_scheduler.c
@@ -249,7 +249,6 @@ static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
 /**
  * drm_sched_entity_flush - Flush a context entity
  *
- * @sched: scheduler instance
  * @entity: scheduler entity
  * @timeout: time to wait in for Q to become empty in jiffies.
  *
@@ -292,7 +291,6 @@ EXPORT_SYMBOL(drm_sched_entity_flush);
 /**
  * drm_sched_entity_cleanup - Destroy a context entity
  *
- * @sched: scheduler instance
  * @entity: scheduler entity
  *
  * This should be called after @drm_sched_entity_do_release. It goes over the
@@ -356,7 +354,6 @@ EXPORT_SYMBOL(drm_sched_entity_fini);
 /**
  * drm_sched_entity_fini - Destroy a context entity
  *
- * @sched: scheduler instance
  * @entity: scheduler entity
  *
  * Calls drm_sched_entity_do_release() and drm_sched_entity_cleanup()
@@ -719,7 +716,6 @@ EXPORT_SYMBOL(drm_sched_job_recovery);
  * drm_sched_job_init - init a scheduler job
  *
  * @job: scheduler job to init
- * @sched: scheduler instance
  * @entity: scheduler entity to use
  * @owner: job owner for debugging
  *
commit 824da016fde1de98ab92c5b9df1b52433edd1594
Merge: 8dd931f46eea 3237c0dbe21f
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Aug 8 06:26:09 2018 +1000

    Merge tag 'drm-intel-next-fixes-2018-08-06' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
    
    - Fix gvt compilation broken on a silent conflict on fixes vs next merge
    - Fix runtime PM for LPE audio
    - Revert on ICL workaround
    - Interactive RPS mode
    - Fix for PSR sink status report
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    From: Rodrigo Vivi <rodrigo.vivi at intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20180806233034.GA20655@intel.com

commit 8dd931f46eea1a7971a700ec9eb99b879871a059
Merge: 940fbcb73fd2 2ead1be54b22
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Aug 8 06:22:56 2018 +1000

    Merge tag 'drm-misc-next-fixes-2018-08-02' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
    
    Fixes an oops on the DP CEC code and a memory leak on the vkms driver.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    From: Gustavo Padovan <gustavo at padovan.org>
    Link: https://patchwork.freedesktop.org/patch/msgid/20180802111728.GA27945@juma

commit 940fbcb73fd25b517fa10c5a9cc96ca0ce1a2fc4
Merge: 569f0a8694d0 df36b2fb8390
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Aug 8 06:09:08 2018 +1000

    Merge branch 'drm-next-4.19' of git://people.freedesktop.org/~agd5f/linux into drm-next
    
    Fixes for 4.19:
    - Fix UVD 7.2 instance handling
    - Fix UVD 7.2 harvesting
    - GPU scheduler fix for when a process is killed
    - TTM cleanups
    - amdgpu CS bo_list fixes
    - Powerplay fixes for polaris12 and CZ/ST
    - DC fixes for link training certain HMDs
    - DC fix for vega10 blank screen in certain cases
    
    From: Alex Deucher <alexdeucher at gmail.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20180801222906.1016-1-alexander.deucher@amd.com

commit 569f0a8694d0ff13c5d296a594c7d8cec8d6f35f
Merge: a7ccc5a43b82 5b1474655323
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Aug 8 06:07:06 2018 +1000

    Merge branch 'etnaviv/next' of https://git.pengutronix.de/git/lst/linux into drm-next
    
    From: Lucas Stach <l.stach at pengutronix.de>
    "not much to de-stage this time. Changes from Philipp and Souptick to
    use memset32 more and switch the fault handler to the new vm_fault_t
    and two small fixes for issues that can be hit in rare corner cases
    from me."
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/1533563808.2809.7.camel@pengutronix.de

diff --cc drivers/gpu/drm/etnaviv/etnaviv_sched.c
index 3949f18afb35,b267d9c4d91c..69e9b431bf1f
--- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
@@@ -140,15 -140,21 +140,21 @@@ static const struct drm_sched_backend_o
  int etnaviv_sched_push_job(struct drm_sched_entity *sched_entity,
  			   struct etnaviv_gem_submit *submit)
  {
- 	int ret;
+ 	int ret = 0;
+ 
+ 	/*
+ 	 * Hold the fence lock across the whole operation to avoid jobs being
+ 	 * pushed out of order with regard to their sched fence seqnos as
+ 	 * allocated in drm_sched_job_init.
+ 	 */
+ 	mutex_lock(&submit->gpu->fence_lock);
  
 -	ret = drm_sched_job_init(&submit->sched_job, &submit->gpu->sched,
 -				 sched_entity, submit->cmdbuf.ctx);
 +	ret = drm_sched_job_init(&submit->sched_job, sched_entity,
 +				 submit->cmdbuf.ctx);
  	if (ret)
- 		return ret;
+ 		goto out_unlock;
  
  	submit->out_fence = dma_fence_get(&submit->sched_job.s_fence->finished);
- 	mutex_lock(&submit->gpu->fence_idr_lock);
  	submit->out_fence_id = idr_alloc_cyclic(&submit->gpu->fence_idr,
  						submit->out_fence, 0,
  						INT_MAX, GFP_KERNEL);
commit a7ccc5a43b829a96b4c62c0de71fc8c6fbd17b8a
Merge: 253265902121 926a299c42e3
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Aug 8 05:52:15 2018 +1000

    Merge branch 'drm-tda998x-devel' of git://git.armlinux.org.uk/~rmk/linux-arm into drm-next
    
    From: Russell King <rmk at armlinux.org.uk>
    As per the patches posted, discussed and tested by Peter Rosin, this
    converts TDA998x to a bridge driver, while still allowing Armada and
    TI LCDC to continue using it as they always have done.  It also gets
    rid of the private .fill_modes function, and tweaks the TMDS divider
    calculation to be more correct to the available information.
    
    [airlied: fixed two conflicts]
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20180802093421.GA29670@rmk-PC.armlinux.org.uk

diff --cc drivers/gpu/drm/i2c/tda998x_drv.c
index eecdc327b9f8,0df86e928191..a7c39f39793f
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@@ -1243,8 -1222,13 +1222,13 @@@ static int tda998x_connector_get_modes(
  		return 0;
  	}
  
 -	drm_mode_connector_update_edid_property(connector, edid);
 +	drm_connector_update_edid_property(connector, edid);
+ 	cec_notifier_set_phys_addr_from_edid(priv->cec_notify, edid);
+ 
+ 	mutex_lock(&priv->audio_mutex);
  	n = drm_add_edid_modes(connector, edid);
+ 	priv->sink_has_audio = drm_detect_monitor_audio(edid);
+ 	mutex_unlock(&priv->audio_mutex);
  
  	kfree(edid);
  
@@@ -1301,7 -1269,8 +1269,8 @@@ static int tda998x_connector_init(struc
  	if (ret)
  		return ret;
  
- 	drm_connector_attach_encoder(&priv->connector, &priv->encoder);
 -	drm_mode_connector_attach_encoder(&priv->connector,
 -					  priv->bridge.encoder);
++	drm_connector_attach_encoder(&priv->connector,
++				     priv->bridge.encoder);
  
  	return 0;
  }
commit 2532659021213f3604615add95c095a2f3bde748
Merge: 15da09500a70 d664b851eb2b
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Aug 8 05:51:16 2018 +1000

    Merge branch 'for-upstream/hdlcd' of git://linux-arm.org/linux-ld into drm-next
    
    From: Liviu Dudau <Liviu.Dudau at arm.com>
    "I managed to loose track of a few patches for HDLCD while focusing
    on Mali DP and found them again when investigating an issue with
    the way HDLCD behaves on teardown. They can go into drm-next for
    one of the v4.19-rcX if you're not going to do another pull request
    before the merge window."
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20180731170831.GF17455@e110455-lin.cambridge.arm.com

commit 926a299c42e38bbe8bb909eae0146e676b66afe4
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Thu Aug 2 10:27:15 2018 +0100

    drm/i2c: tda998x: correct PLL divider calculation
    
    The serializer PLL divider is a power-of-two divider, so our calculation
    which assumes that it's a numerical divider is incorrect.  Replace it
    with one that results in a power-of-two divider value instead.
    
    Tested with all supported modes with a Samsung S24C750.
    
    Tested-by: Peter Rosin <peda at axentia.se>
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 7313ff835f35..0df86e928191 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1343,6 +1343,7 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge,
 				    struct drm_display_mode *adjusted_mode)
 {
 	struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
+	unsigned long tmds_clock;
 	u16 ref_pix, ref_line, n_pix, n_line;
 	u16 hs_pix_s, hs_pix_e;
 	u16 vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e;
@@ -1413,12 +1414,19 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge,
 			       (mode->vsync_end - mode->vsync_start)/2;
 	}
 
-	div = 148500 / mode->clock;
-	if (div != 0) {
-		div--;
-		if (div > 3)
-			div = 3;
-	}
+	tmds_clock = mode->clock;
+
+	/*
+	 * The divisor is power-of-2. The TDA9983B datasheet gives
+	 * this as ranges of Msample/s, which is 10x the TMDS clock:
+	 *   0 - 800 to 1500 Msample/s
+	 *   1 - 400 to 800 Msample/s
+	 *   2 - 200 to 400 Msample/s
+	 *   3 - as 2 above
+	 */
+	for (div = 0; div < 3; div++)
+		if (80000 >> div <= tmds_clock)
+			break;
 
 	mutex_lock(&priv->audio_mutex);
 
commit a3d335f5de7cdd714737a9f8bdcc7b205b0f8d5e
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Thu Aug 2 10:27:15 2018 +0100

    drm/i2c: tda998x: get rid of private fill_modes function
    
    We can achieve the same effect via the get_modes() method, rather than
    wrapping the fill_modes helper.
    
    Tested-by: Peter Rosin <peda at axentia.se>
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 6308e8ec25df..7313ff835f35 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1106,29 +1106,6 @@ static int tda998x_audio_codec_init(struct tda998x_priv *priv,
 
 /* DRM connector functions */
 
-static int tda998x_connector_fill_modes(struct drm_connector *connector,
-					uint32_t maxX, uint32_t maxY)
-{
-	struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
-	int ret;
-
-	mutex_lock(&priv->audio_mutex);
-	ret = drm_helper_probe_single_connector_modes(connector, maxX, maxY);
-
-	if (connector->edid_blob_ptr) {
-		struct edid *edid = (void *)connector->edid_blob_ptr->data;
-
-		cec_notifier_set_phys_addr_from_edid(priv->cec_notify, edid);
-
-		priv->sink_has_audio = drm_detect_monitor_audio(edid);
-	} else {
-		priv->sink_has_audio = false;
-	}
-	mutex_unlock(&priv->audio_mutex);
-
-	return ret;
-}
-
 static enum drm_connector_status
 tda998x_connector_detect(struct drm_connector *connector, bool force)
 {
@@ -1147,7 +1124,7 @@ static void tda998x_connector_destroy(struct drm_connector *connector)
 static const struct drm_connector_funcs tda998x_connector_funcs = {
 	.dpms = drm_helper_connector_dpms,
 	.reset = drm_atomic_helper_connector_reset,
-	.fill_modes = tda998x_connector_fill_modes,
+	.fill_modes = drm_helper_probe_single_connector_modes,
 	.detect = tda998x_connector_detect,
 	.destroy = tda998x_connector_destroy,
 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
@@ -1246,7 +1223,12 @@ static int tda998x_connector_get_modes(struct drm_connector *connector)
 	}
 
 	drm_mode_connector_update_edid_property(connector, edid);
+	cec_notifier_set_phys_addr_from_edid(priv->cec_notify, edid);
+
+	mutex_lock(&priv->audio_mutex);
 	n = drm_add_edid_modes(connector, edid);
+	priv->sink_has_audio = drm_detect_monitor_audio(edid);
+	mutex_unlock(&priv->audio_mutex);
 
 	kfree(edid);
 
commit b073a70ecd37bc6e7c25a47315cd8d65e7b313fd
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Thu Aug 2 10:27:15 2018 +0100

    drm/i2c: tda998x: move mode_valid() to bridge
    
    Move the mode_valid() implementation to the bridge instead of the
    connector, as we're checking the bridge's capabilities.
    
    Tested-by: Peter Rosin <peda at axentia.se>
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index a7a4307f7fcb..6308e8ec25df 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1253,21 +1253,6 @@ static int tda998x_connector_get_modes(struct drm_connector *connector)
 	return n;
 }
 
-static enum drm_mode_status tda998x_connector_mode_valid(struct drm_connector *connector,
-					struct drm_display_mode *mode)
-{
-	/* TDA19988 dotclock can go up to 165MHz */
-	struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
-
-	if (mode->clock > ((priv->rev == TDA19988) ? 165000 : 150000))
-		return MODE_CLOCK_HIGH;
-	if (mode->htotal >= BIT(13))
-		return MODE_BAD_HVALUE;
-	if (mode->vtotal >= BIT(11))
-		return MODE_BAD_VVALUE;
-	return MODE_OK;
-}
-
 static struct drm_encoder *
 tda998x_connector_best_encoder(struct drm_connector *connector)
 {
@@ -1279,7 +1264,6 @@ tda998x_connector_best_encoder(struct drm_connector *connector)
 static
 const struct drm_connector_helper_funcs tda998x_connector_helper_funcs = {
 	.get_modes = tda998x_connector_get_modes,
-	.mode_valid = tda998x_connector_mode_valid,
 	.best_encoder = tda998x_connector_best_encoder,
 };
 
@@ -1325,6 +1309,21 @@ static void tda998x_bridge_detach(struct drm_bridge *bridge)
 	drm_connector_cleanup(&priv->connector);
 }
 
+static enum drm_mode_status tda998x_bridge_mode_valid(struct drm_bridge *bridge,
+				     const struct drm_display_mode *mode)
+{
+	/* TDA19988 dotclock can go up to 165MHz */
+	struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
+
+	if (mode->clock > ((priv->rev == TDA19988) ? 165000 : 150000))
+		return MODE_CLOCK_HIGH;
+	if (mode->htotal >= BIT(13))
+		return MODE_BAD_HVALUE;
+	if (mode->vtotal >= BIT(11))
+		return MODE_BAD_VVALUE;
+	return MODE_OK;
+}
+
 static void tda998x_bridge_enable(struct drm_bridge *bridge)
 {
 	struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
@@ -1571,6 +1570,7 @@ static void tda998x_bridge_mode_set(struct drm_bridge *bridge,
 static const struct drm_bridge_funcs tda998x_bridge_funcs = {
 	.attach = tda998x_bridge_attach,
 	.detach = tda998x_bridge_detach,
+	.mode_valid = tda998x_bridge_mode_valid,
 	.disable = tda998x_bridge_disable,
 	.mode_set = tda998x_bridge_mode_set,
 	.enable = tda998x_bridge_enable,
commit 5a03f5346fedc8b5f1a8601aa46a0930ba56a7ae
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Thu Aug 2 10:25:19 2018 +0100

    drm/i2c: tda998x: register bridge outside of component helper
    
    Register the bridge outside of the component helper as we have
    drivers that wish to use the tda998x without its encoder.
    
    Tested-by: Peter Rosin <peda at axentia.se>
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index f486d85ac575..a7a4307f7fcb 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1904,18 +1904,8 @@ err_encoder:
 static int tda998x_bind(struct device *dev, struct device *master, void *data)
 {
 	struct drm_device *drm = data;
-	int ret;
-
-	ret = tda998x_create(dev);
-	if (ret)
-		return ret;
 
-	ret = tda998x_encoder_init(dev, drm);
-	if (ret) {
-		tda998x_destroy(dev);
-		return ret;
-	}
-	return 0;
+	return tda998x_encoder_init(dev, drm);
 }
 
 static void tda998x_unbind(struct device *dev, struct device *master,
@@ -1924,7 +1914,6 @@ static void tda998x_unbind(struct device *dev, struct device *master,
 	struct tda998x_priv *priv = dev_get_drvdata(dev);
 
 	drm_encoder_cleanup(&priv->encoder);
-	tda998x_destroy(dev);
 }
 
 static const struct component_ops tda998x_ops = {
@@ -1935,16 +1924,27 @@ static const struct component_ops tda998x_ops = {
 static int
 tda998x_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
+	int ret;
+
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
 		dev_warn(&client->dev, "adapter does not support I2C\n");
 		return -EIO;
 	}
-	return component_add(&client->dev, &tda998x_ops);
+
+	ret = tda998x_create(&client->dev);
+	if (ret)
+		return ret;
+
+	ret = component_add(&client->dev, &tda998x_ops);
+	if (ret)
+		tda998x_destroy(&client->dev);
+	return ret;
 }
 
 static int tda998x_remove(struct i2c_client *client)
 {
 	component_del(&client->dev, &tda998x_ops);
+	tda998x_destroy(&client->dev);
 	return 0;
 }
 
commit 76767fdabadbea7dec2cdd741c0177e4fab3c75a
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Thu Aug 2 10:25:19 2018 +0100

    drm/i2c: tda998x: cleanup from previous changes
    
    Cleanup the code a little from the effects of the previous changes:
    - Move tda998x_destroy() to be above tda998x_create()
    - Use 'dev' directly in tda998x_create() where appropriate.
    
    Tested-by: Peter Rosin <peda at axentia.se>
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 74c2e5e59922..f486d85ac575 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1576,31 +1576,6 @@ static const struct drm_bridge_funcs tda998x_bridge_funcs = {
 	.enable = tda998x_bridge_enable,
 };
 
-static void tda998x_destroy(struct device *dev)
-{
-	struct tda998x_priv *priv = dev_get_drvdata(dev);
-
-	drm_bridge_remove(&priv->bridge);
-
-	/* disable all IRQs and free the IRQ handler */
-	cec_write(priv, REG_CEC_RXSHPDINTENA, 0);
-	reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
-
-	if (priv->audio_pdev)
-		platform_device_unregister(priv->audio_pdev);
-
-	if (priv->hdmi->irq)
-		free_irq(priv->hdmi->irq, priv);
-
-	del_timer_sync(&priv->edid_delay_timer);
-	cancel_work_sync(&priv->detect_work);
-
-	i2c_unregister_device(priv->cec);
-
-	if (priv->cec_notify)
-		cec_notifier_put(priv->cec_notify);
-}
-
 /* I2C driver functions */
 
 static int tda998x_get_audio_ports(struct tda998x_priv *priv,
@@ -1664,6 +1639,31 @@ static void tda998x_set_config(struct tda998x_priv *priv,
 	priv->audio_params = p->audio_params;
 }
 
+static void tda998x_destroy(struct device *dev)
+{
+	struct tda998x_priv *priv = dev_get_drvdata(dev);
+
+	drm_bridge_remove(&priv->bridge);
+
+	/* disable all IRQs and free the IRQ handler */
+	cec_write(priv, REG_CEC_RXSHPDINTENA, 0);
+	reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
+
+	if (priv->audio_pdev)
+		platform_device_unregister(priv->audio_pdev);
+
+	if (priv->hdmi->irq)
+		free_irq(priv->hdmi->irq, priv);
+
+	del_timer_sync(&priv->edid_delay_timer);
+	cancel_work_sync(&priv->detect_work);
+
+	i2c_unregister_device(priv->cec);
+
+	if (priv->cec_notify)
+		cec_notifier_put(priv->cec_notify);
+}
+
 static int tda998x_create(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
@@ -1705,13 +1705,13 @@ static int tda998x_create(struct device *dev)
 	/* read version: */
 	rev_lo = reg_read(priv, REG_VERSION_LSB);
 	if (rev_lo < 0) {
-		dev_err(&client->dev, "failed to read version: %d\n", rev_lo);
+		dev_err(dev, "failed to read version: %d\n", rev_lo);
 		return rev_lo;
 	}
 
 	rev_hi = reg_read(priv, REG_VERSION_MSB);
 	if (rev_hi < 0) {
-		dev_err(&client->dev, "failed to read version: %d\n", rev_hi);
+		dev_err(dev, "failed to read version: %d\n", rev_hi);
 		return rev_hi;
 	}
 
@@ -1722,20 +1722,19 @@ static int tda998x_create(struct device *dev)
 
 	switch (priv->rev) {
 	case TDA9989N2:
-		dev_info(&client->dev, "found TDA9989 n2");
+		dev_info(dev, "found TDA9989 n2");
 		break;
 	case TDA19989:
-		dev_info(&client->dev, "found TDA19989");
+		dev_info(dev, "found TDA19989");
 		break;
 	case TDA19989N2:
-		dev_info(&client->dev, "found TDA19989 n2");
+		dev_info(dev, "found TDA19989 n2");
 		break;
 	case TDA19988:
-		dev_info(&client->dev, "found TDA19988");
+		dev_info(dev, "found TDA19988");
 		break;
 	default:
-		dev_err(&client->dev, "found unsupported device: %04x\n",
-			priv->rev);
+		dev_err(dev, "found unsupported device: %04x\n", priv->rev);
 		return -ENXIO;
 	}
 
@@ -1778,8 +1777,7 @@ static int tda998x_create(struct device *dev)
 					   tda998x_irq_thread, irq_flags,
 					   "tda998x", priv);
 		if (ret) {
-			dev_err(&client->dev,
-				"failed to request IRQ#%u: %d\n",
+			dev_err(dev, "failed to request IRQ#%u: %d\n",
 				client->irq, ret);
 			goto err_irq;
 		}
@@ -1788,13 +1786,13 @@ static int tda998x_create(struct device *dev)
 		cec_write(priv, REG_CEC_RXSHPDINTENA, CEC_RXSHPDLEV_HPD);
 	}
 
-	priv->cec_notify = cec_notifier_get(&client->dev);
+	priv->cec_notify = cec_notifier_get(dev);
 	if (!priv->cec_notify) {
 		ret = -ENOMEM;
 		goto fail;
 	}
 
-	priv->cec_glue.parent = &client->dev;
+	priv->cec_glue.parent = dev;
 	priv->cec_glue.data = priv;
 	priv->cec_glue.init = tda998x_cec_hook_init;
 	priv->cec_glue.exit = tda998x_cec_hook_exit;
@@ -1839,8 +1837,8 @@ static int tda998x_create(struct device *dev)
 
 		if (priv->audio_port[0].format != AFMT_UNUSED)
 			tda998x_audio_codec_init(priv, &client->dev);
-	} else if (client->dev.platform_data) {
-		tda998x_set_config(priv, client->dev.platform_data);
+	} else if (dev->platform_data) {
+		tda998x_set_config(priv, dev->platform_data);
 	}
 
 	priv->bridge.funcs = &tda998x_bridge_funcs;
commit 2143adb04b357e192a9717a42554b1fd65c60fd2
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Thu Aug 2 10:25:19 2018 +0100

    drm/i2c: tda998x: allocate tda998x_priv inside tda998x_create()
    
    Move the tda998x_priv allocation inside tda998x_create() and simplify
    the tda998x_create()'s arguments.  Pass the same to tda998x_destroy().
    
    Tested-by: Peter Rosin <peda at axentia.se>
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 999810d8e3d0..74c2e5e59922 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1576,8 +1576,10 @@ static const struct drm_bridge_funcs tda998x_bridge_funcs = {
 	.enable = tda998x_bridge_enable,
 };
 
-static void tda998x_destroy(struct tda998x_priv *priv)
+static void tda998x_destroy(struct device *dev)
 {
+	struct tda998x_priv *priv = dev_get_drvdata(dev);
+
 	drm_bridge_remove(&priv->bridge);
 
 	/* disable all IRQs and free the IRQ handler */
@@ -1662,13 +1664,21 @@ static void tda998x_set_config(struct tda998x_priv *priv,
 	priv->audio_params = p->audio_params;
 }
 
-static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
+static int tda998x_create(struct device *dev)
 {
+	struct i2c_client *client = to_i2c_client(dev);
 	struct device_node *np = client->dev.of_node;
 	struct i2c_board_info cec_info;
+	struct tda998x_priv *priv;
 	u32 video;
 	int rev_lo, rev_hi, ret;
 
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, priv);
+
 	mutex_init(&priv->mutex);	/* protect the page access */
 	mutex_init(&priv->audio_mutex); /* protect access from audio thread */
 	mutex_init(&priv->edid_mutex);
@@ -1843,7 +1853,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
 	return 0;
 
 fail:
-	tda998x_destroy(priv);
+	tda998x_destroy(dev);
 err_irq:
 	return ret;
 }
@@ -1895,24 +1905,16 @@ err_encoder:
 
 static int tda998x_bind(struct device *dev, struct device *master, void *data)
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct drm_device *drm = data;
-	struct tda998x_priv *priv;
 	int ret;
 
-	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-
-	dev_set_drvdata(dev, priv);
-
-	ret = tda998x_create(client, priv);
+	ret = tda998x_create(dev);
 	if (ret)
 		return ret;
 
 	ret = tda998x_encoder_init(dev, drm);
 	if (ret) {
-		tda998x_destroy(priv);
+		tda998x_destroy(dev);
 		return ret;
 	}
 	return 0;
@@ -1924,7 +1926,7 @@ static void tda998x_unbind(struct device *dev, struct device *master,
 	struct tda998x_priv *priv = dev_get_drvdata(dev);
 
 	drm_encoder_cleanup(&priv->encoder);
-	tda998x_destroy(priv);
+	tda998x_destroy(dev);
 }
 
 static const struct component_ops tda998x_ops = {
commit 30bd8b862f5466fe5aee9a9fcdaea5a4fad83f91
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Thu Aug 2 10:25:19 2018 +0100

    drm/i2c: tda998x: convert to bridge driver
    
    Convert tda998x to a bridge driver with built-in encoder support for
    compatibility with existing component drivers.
    
    Tested-by: Peter Rosin <peda at axentia.se>
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index c35b52a83001..999810d8e3d0 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -69,6 +69,7 @@ struct tda998x_priv {
 	bool edid_delay_active;
 
 	struct drm_encoder encoder;
+	struct drm_bridge bridge;
 	struct drm_connector connector;
 
 	struct tda998x_audio_port audio_port[2];
@@ -79,9 +80,10 @@ struct tda998x_priv {
 
 #define conn_to_tda998x_priv(x) \
 	container_of(x, struct tda998x_priv, connector)
-
 #define enc_to_tda998x_priv(x) \
 	container_of(x, struct tda998x_priv, encoder)
+#define bridge_to_tda998x_priv(x) \
+	container_of(x, struct tda998x_priv, bridge)
 
 /* The TDA9988 series of devices use a paged register scheme.. to simplify
  * things we encode the page # in upper bits of the register #.  To read/
@@ -1271,7 +1273,7 @@ tda998x_connector_best_encoder(struct drm_connector *connector)
 {
 	struct tda998x_priv *priv = conn_to_tda998x_priv(connector);
 
-	return &priv->encoder;
+	return priv->bridge.encoder;
 }
 
 static
@@ -1301,15 +1303,32 @@ static int tda998x_connector_init(struct tda998x_priv *priv,
 	if (ret)
 		return ret;
 
-	drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder);
+	drm_mode_connector_attach_encoder(&priv->connector,
+					  priv->bridge.encoder);
 
 	return 0;
 }
 
-/* DRM encoder functions */
+/* DRM bridge functions */
+
+static int tda998x_bridge_attach(struct drm_bridge *bridge)
+{
+	struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
+
+	return tda998x_connector_init(priv, bridge->dev);
+}
+
+static void tda998x_bridge_detach(struct drm_bridge *bridge)
+{
+	struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
+
+	drm_connector_cleanup(&priv->connector);
+}
 
-static void tda998x_enable(struct tda998x_priv *priv)
+static void tda998x_bridge_enable(struct drm_bridge *bridge)
 {
+	struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
+
 	if (!priv->is_on) {
 		/* enable video ports, audio will be enabled later */
 		reg_write(priv, REG_ENA_VP_0, 0xff);
@@ -1324,8 +1343,10 @@ static void tda998x_enable(struct tda998x_priv *priv)
 	}
 }
 
-static void tda998x_disable(struct tda998x_priv *priv)
+static void tda998x_bridge_disable(struct drm_bridge *bridge)
 {
+	struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
+
 	if (priv->is_on) {
 		/* disable video ports */
 		reg_write(priv, REG_ENA_VP_0, 0x00);
@@ -1336,29 +1357,11 @@ static void tda998x_disable(struct tda998x_priv *priv)
 	}
 }
 
-static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-	struct tda998x_priv *priv = enc_to_tda998x_priv(encoder);
-	bool on;
-
-	/* we only care about on or off: */
-	on = mode == DRM_MODE_DPMS_ON;
-
-	if (on == priv->is_on)
-		return;
-
-	if (on)
-		tda998x_enable(priv);
-	else
-		tda998x_disable(priv);
-}
-
-static void
-tda998x_encoder_mode_set(struct drm_encoder *encoder,
-			 struct drm_display_mode *mode,
-			 struct drm_display_mode *adjusted_mode)
+static void tda998x_bridge_mode_set(struct drm_bridge *bridge,
+				    struct drm_display_mode *mode,
+				    struct drm_display_mode *adjusted_mode)
 {
-	struct tda998x_priv *priv = enc_to_tda998x_priv(encoder);
+	struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge);
 	u16 ref_pix, ref_line, n_pix, n_line;
 	u16 hs_pix_s, hs_pix_e;
 	u16 vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e;
@@ -1565,8 +1568,18 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder,
 	mutex_unlock(&priv->audio_mutex);
 }
 
+static const struct drm_bridge_funcs tda998x_bridge_funcs = {
+	.attach = tda998x_bridge_attach,
+	.detach = tda998x_bridge_detach,
+	.disable = tda998x_bridge_disable,
+	.mode_set = tda998x_bridge_mode_set,
+	.enable = tda998x_bridge_enable,
+};
+
 static void tda998x_destroy(struct tda998x_priv *priv)
 {
+	drm_bridge_remove(&priv->bridge);
+
 	/* disable all IRQs and free the IRQ handler */
 	cec_write(priv, REG_CEC_RXSHPDINTENA, 0);
 	reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
@@ -1659,6 +1672,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
 	mutex_init(&priv->mutex);	/* protect the page access */
 	mutex_init(&priv->audio_mutex); /* protect access from audio thread */
 	mutex_init(&priv->edid_mutex);
+	INIT_LIST_HEAD(&priv->bridge.list);
 	init_waitqueue_head(&priv->edid_delay_waitq);
 	timer_setup(&priv->edid_delay_timer, tda998x_edid_delay_done, 0);
 	INIT_WORK(&priv->detect_work, tda998x_detect_work);
@@ -1819,43 +1833,25 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
 		tda998x_set_config(priv, client->dev.platform_data);
 	}
 
+	priv->bridge.funcs = &tda998x_bridge_funcs;
+#ifdef CONFIG_OF
+	priv->bridge.of_node = dev->of_node;
+#endif
+
+	drm_bridge_add(&priv->bridge);
+
 	return 0;
 
 fail:
-	/* if encoder_init fails, the encoder slave is never registered,
-	 * so cleanup here:
-	 */
-	i2c_unregister_device(priv->cec);
-	if (priv->cec_notify)
-		cec_notifier_put(priv->cec_notify);
-	if (client->irq)
-		free_irq(client->irq, priv);
+	tda998x_destroy(priv);
 err_irq:
 	return ret;
 }
 
-static void tda998x_encoder_prepare(struct drm_encoder *encoder)
-{
-	tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
-}
-
-static void tda998x_encoder_commit(struct drm_encoder *encoder)
-{
-	tda998x_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
-}
-
-static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = {
-	.dpms = tda998x_encoder_dpms,
-	.prepare = tda998x_encoder_prepare,
-	.commit = tda998x_encoder_commit,
-	.mode_set = tda998x_encoder_mode_set,
-};
+/* DRM encoder functions */
 
 static void tda998x_encoder_destroy(struct drm_encoder *encoder)
 {
-	struct tda998x_priv *priv = enc_to_tda998x_priv(encoder);
-
-	tda998x_destroy(priv);
 	drm_encoder_cleanup(encoder);
 }
 
@@ -1863,20 +1859,12 @@ static const struct drm_encoder_funcs tda998x_encoder_funcs = {
 	.destroy = tda998x_encoder_destroy,
 };
 
-static int tda998x_bind(struct device *dev, struct device *master, void *data)
+static int tda998x_encoder_init(struct device *dev, struct drm_device *drm)
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct drm_device *drm = data;
-	struct tda998x_priv *priv;
+	struct tda998x_priv *priv = dev_get_drvdata(dev);
 	u32 crtcs = 0;
 	int ret;
 
-	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-
-	dev_set_drvdata(dev, priv);
-
 	if (dev->of_node)
 		crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
 
@@ -1888,35 +1876,53 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data)
 
 	priv->encoder.possible_crtcs = crtcs;
 
-	ret = tda998x_create(client, priv);
-	if (ret)
-		return ret;
-
-	drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs);
 	ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs,
 			       DRM_MODE_ENCODER_TMDS, NULL);
 	if (ret)
 		goto err_encoder;
 
-	ret = tda998x_connector_init(priv, drm);
+	ret = drm_bridge_attach(&priv->encoder, &priv->bridge, NULL);
 	if (ret)
-		goto err_connector;
+		goto err_bridge;
 
 	return 0;
 
-err_connector:
+err_bridge:
 	drm_encoder_cleanup(&priv->encoder);
 err_encoder:
-	tda998x_destroy(priv);
 	return ret;
 }
 
+static int tda998x_bind(struct device *dev, struct device *master, void *data)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct drm_device *drm = data;
+	struct tda998x_priv *priv;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, priv);
+
+	ret = tda998x_create(client, priv);
+	if (ret)
+		return ret;
+
+	ret = tda998x_encoder_init(dev, drm);
+	if (ret) {
+		tda998x_destroy(priv);
+		return ret;
+	}
+	return 0;
+}
+
 static void tda998x_unbind(struct device *dev, struct device *master,
 			   void *data)
 {
 	struct tda998x_priv *priv = dev_get_drvdata(dev);
 
-	drm_connector_cleanup(&priv->connector);
 	drm_encoder_cleanup(&priv->encoder);
 	tda998x_destroy(priv);
 }
commit 4823e5da2ea9061011242db81334d6ebbd2ed0a5
Author: Lucas Stach <l.stach at pengutronix.de>
Date:   Mon Aug 6 15:12:48 2018 +0200

    drm/scheduler: fix timeout worker setup for out of order job completions
    
    drm_sched_job_finish() is a work item scheduled for each finished job on
    a unbound system workqueue. This means the workers can execute out of order
    with regard to the real hardware job completions.
    
    If this happens queueing a timeout worker for the first job on the ring
    mirror list is wrong, as this may be a job which has already finished
    executing. Fix this by reorganizing the code to always queue the worker
    for the next job on the list, if this job hasn't finished yet. This is
    robust against a potential reordering of the finish workers.
    
    Also move out the timeout worker cancelling, so that we don't need to
    take the job list lock twice. As a small optimization list_del is used
    to remove the job from the ring mirror list, as there is no need to
    reinit the list head in the job we are about to free.
    
    Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
    Reviewed-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler.c b/drivers/gpu/drm/scheduler/gpu_scheduler.c
index 1b733229201e..a70c7f7fd6fe 100644
--- a/drivers/gpu/drm/scheduler/gpu_scheduler.c
+++ b/drivers/gpu/drm/scheduler/gpu_scheduler.c
@@ -552,24 +552,28 @@ static void drm_sched_job_finish(struct work_struct *work)
 						   finish_work);
 	struct drm_gpu_scheduler *sched = s_job->sched;
 
-	/* remove job from ring_mirror_list */
-	spin_lock(&sched->job_list_lock);
-	list_del_init(&s_job->node);
-	if (sched->timeout != MAX_SCHEDULE_TIMEOUT) {
-		struct drm_sched_job *next;
-
-		spin_unlock(&sched->job_list_lock);
-		cancel_delayed_work_sync(&s_job->work_tdr);
-		spin_lock(&sched->job_list_lock);
+	/*
+	 * Canceling the timeout without removing our job from the ring mirror
+	 * list is safe, as we will only end up in this worker if our jobs
+	 * finished fence has been signaled. So even if some another worker
+	 * manages to find this job as the next job in the list, the fence
+	 * signaled check below will prevent the timeout to be restarted.
+	 */
+	cancel_delayed_work_sync(&s_job->work_tdr);
 
-		/* queue TDR for next job */
-		next = list_first_entry_or_null(&sched->ring_mirror_list,
-						struct drm_sched_job, node);
+	spin_lock(&sched->job_list_lock);
+	/* queue TDR for next job */
+	if (sched->timeout != MAX_SCHEDULE_TIMEOUT &&
+	    !list_is_last(&s_job->node, &sched->ring_mirror_list)) {
+		struct drm_sched_job *next = list_next_entry(s_job, node);
 
-		if (next)
+		if (!dma_fence_is_signaled(&next->s_fence->finished))
 			schedule_delayed_work(&next->work_tdr, sched->timeout);
 	}
+	/* remove job from ring_mirror_list */
+	list_del(&s_job->node);
 	spin_unlock(&sched->job_list_lock);
+
 	dma_fence_put(&s_job->s_fence->finished);
 	sched->ops->free_job(s_job);
 }
commit 1e1dbd6fd10031bf46d9e44b6ad423e2ee39e2a7
Author: Hersen Wu <hersenxs.wu at amd.com>
Date:   Fri Jul 27 14:52:37 2018 -0400

    drm/amd/display: display connected to dp-1 does not light up
    
    [why]
    for vega, dp set_panel_mode is
    handled by psp firmware. dal should not program the
    register again.
    
    [how]
    dal does not program panel mode.
    
    Signed-off-by: Hersen Wu <hersenxs.wu at amd.com>
    Reviewed-by: Charlene Liu <Charlene.Liu at amd.com>
    Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 3ecd2d614f41..e2f033d420a0 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -79,6 +79,7 @@ struct dc_caps {
 	bool post_blend_color_processing;
 	bool force_dp_tps4_for_cp2520;
 	bool disable_dp_clk_share;
+	bool psp_setup_panel_mode;
 };
 
 struct dc_dcc_surface_param {
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
index 60e3c6a73d37..752b3d62e793 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
@@ -256,6 +256,11 @@ static void setup_panel_mode(
 	enum dp_panel_mode panel_mode)
 {
 	uint32_t value;
+	struct dc_context *ctx = enc110->base.ctx;
+
+	/* if psp set panel mode, dal should be program it */
+	if (ctx->dc->caps.psp_setup_panel_mode)
+		return;
 
 	ASSERT(REG(DP_DPHY_INTERNAL_CTRL));
 	value = REG_READ(DP_DPHY_INTERNAL_CTRL);
diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
index 61d8e22d23c9..d43f37d99c7d 100644
--- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
@@ -883,6 +883,7 @@ static bool construct(
 	dc->caps.i2c_speed_in_khz = 100;
 	dc->caps.max_cursor_size = 128;
 	dc->caps.dual_link_dvi = true;
+	dc->caps.psp_setup_panel_mode = true;
 
 	dc->debug = debug_defaults;
 
commit 81aca8e75c1b046865fb2badef95a0dcff6f73de
Author: Mikita Lipski <mikita.lipski at amd.com>
Date:   Fri Jul 13 09:07:35 2018 -0400

    drm/amd/display: update clk for various HDMI color depths
    
    [why]
    When programming tonga's connector's backend we didn't take
    in account that HDMI's colour depth might be more than 8bpc
    therefore we need to add a switch statement that would adjust
    the pixel clock accordingly.
    
    [how]
    Add a switch statement updating clock by its appropriate
    coefficient.
    
    Signed-off-by: Mikita Lipski <mikita.lipski at amd.com>
    Reviewed-by: Charlene Liu <Charlene.Liu at amd.com>
    Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
    Cc: stable at vger.kernel.org

diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table.c b/drivers/gpu/drm/amd/display/dc/bios/command_table.c
index 651e1fd4622f..a558bfaa0c46 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table.c
@@ -808,6 +808,24 @@ static enum bp_result transmitter_control_v1_5(
 	 * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
 	 * LVDS mode: usPixelClock = pixel clock
 	 */
+	if  (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A) {
+		switch (cntl->color_depth) {
+		case COLOR_DEPTH_101010:
+			params.usSymClock =
+				cpu_to_le16((le16_to_cpu(params.usSymClock) * 30) / 24);
+			break;
+		case COLOR_DEPTH_121212:
+			params.usSymClock =
+				cpu_to_le16((le16_to_cpu(params.usSymClock) * 36) / 24);
+			break;
+		case COLOR_DEPTH_161616:
+			params.usSymClock =
+				cpu_to_le16((le16_to_cpu(params.usSymClock) * 48) / 24);
+			break;
+		default:
+			break;
+		}
+	}
 
 	if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
 		result = BP_RESULT_OK;
commit 99326ee3624b90d176a8f7e2aa3d15dfaa59c8f1
Author: Dmytro Laktyushkin <Dmytro.Laktyushkin at amd.com>
Date:   Thu Jul 26 12:17:58 2018 -0400

    drm/amd/display: program display clock on cache match
    
    [Why]
    We seem to have an issue where high enough display clock
    will not get set properly during S3 resume if we only
    call vbios once
    
    [How]
    Expand condition of display clock programming to happen
    even when cached display clock matches requested display
    clock
    
    Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin at amd.com>
    Reviewed-by: Tony Cheng <Tony.Cheng at amd.com>
    Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
index f17677971d0f..684da3db7568 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
@@ -625,7 +625,9 @@ static void dcn1_update_clocks(struct dccg *dccg,
 	}
 
 	/* dcn1 dppclk is tied to dispclk */
-	if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) {
+	/* program dispclk on = as a w/a for sleep resume clock ramping issues */
+	if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)
+			|| new_clocks->dispclk_khz == dccg->clks.dispclk_khz) {
 		dcn1_ramp_up_dispclk_with_dpp(dccg, new_clocks);
 		dccg->clks.dispclk_khz = new_clocks->dispclk_khz;
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index f5d8242eb047..cfcc54f2ce65 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -1089,6 +1089,8 @@ static void dcn10_init_hw(struct dc *dc)
 	}
 
 	enable_power_gating_plane(dc->hwseq, true);
+
+	memset(&dc->res_pool->dccg->clks, 0, sizeof(dc->res_pool->dccg->clks));
 }
 
 static void reset_hw_ctx_wrap(
commit fb7b11e1633e50b9a6b3fffe5cd151474aee9802
Author: Nicholas Kazlauskas <nicholas.kazlauskas at amd.com>
Date:   Mon Jul 30 12:27:23 2018 -0400

    drm/amd/display: Add NULL check for enabling dp ss
    
    [Why]
    
    The pointer for integrated_info can be NULL which causes the system to
    do a null pointer deference and hang on boot.
    
    [How]
    
    Add a check to ensure that integrated_info is not null before enabling
    DP ss.
    
    Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas at amd.com>
    Reviewed-by: Sun peng Li <Sunpeng.Li at amd.com>
    Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 016587675da4..a38e7ad36a7e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -1038,7 +1038,9 @@ static bool construct(
 	link->link_index = init_params->link_index;
 
 	link->link_id = bios->funcs->get_connector_id(bios, init_params->connector_index);
-	link->dp_ss_off = !!dc_ctx->dc_bios->integrated_info->dp_ss_control;;
+
+	if (dc_ctx->dc_bios->integrated_info)
+		link->dp_ss_off = !!dc_ctx->dc_bios->integrated_info->dp_ss_control;
 
 	if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
 		dm_error("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d! type %d expected %d\n",
commit ad830e7ab1847f4a014c04496b2581a7497b204f
Author: Dmytro Laktyushkin <Dmytro.Laktyushkin at amd.com>
Date:   Wed Jul 18 15:25:34 2018 -0400

    drm/amd/display: add vbios table check for enabling dp ss
    
    Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin at amd.com>
    Reviewed-by: Eric Bernstein <Eric.Bernstein at amd.com>
    Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 9a6448e2089c..016587675da4 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -1038,6 +1038,7 @@ static bool construct(
 	link->link_index = init_params->link_index;
 
 	link->link_id = bios->funcs->get_connector_id(bios, init_params->connector_index);
+	link->dp_ss_off = !!dc_ctx->dc_bios->integrated_info->dp_ss_control;;
 
 	if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
 		dm_error("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d! type %d expected %d\n",
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 160841da72a7..a7553b6d59c2 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -953,7 +953,10 @@ enum link_training_result dc_link_dp_perform_link_training(
 	 * LINK_SPREAD_05_DOWNSPREAD_30KHZ :
 	 * LINK_SPREAD_DISABLED;
 	 */
-	lt_settings.link_settings.link_spread = LINK_SPREAD_05_DOWNSPREAD_30KHZ;
+	if (link->dp_ss_off)
+		lt_settings.link_settings.link_spread = LINK_SPREAD_DISABLED;
+	else
+		lt_settings.link_settings.link_spread = LINK_SPREAD_05_DOWNSPREAD_30KHZ;
 
 	/* 1. set link rate, lane count and spread*/
 	dpcd_set_link_settings(link, &lt_settings);
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index 22f4ddd219d1..d43cefbc43d3 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -73,6 +73,7 @@ struct dc_link {
 	enum dc_irq_source irq_source_hpd;
 	enum dc_irq_source irq_source_hpd_rx;/* aka DP Short Pulse  */
 	bool is_hpd_filter_disabled;
+	bool dp_ss_off;
 
 	/* caps is the same as reported_link_cap. link_traing use
 	 * reported_link_cap. Will clean up.  TODO
diff --git a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
index 36bbad594267..f312834fef50 100644
--- a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
+++ b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h
@@ -395,6 +395,8 @@ struct integrated_info {
 	struct i2c_reg_info dp3_ext_hdmi_reg_settings[9];
 	unsigned char dp3_ext_hdmi_6g_reg_num;
 	struct i2c_reg_info dp3_ext_hdmi_6g_reg_settings[3];
+	/* V11 */
+	uint32_t dp_ss_control;
 };
 
 /**
commit 3e27e10e2ecee0d3a0083f8ae76354ac9c6ad15c
Author: Mikita Lipski <mikita.lipski at amd.com>
Date:   Thu Jul 12 16:44:05 2018 -0400

    drm/amd/display: Don't share clk source between DP and HDMI
    
    [why]
    Prevent clock source sharing between HDMI and DP connectors.
    DP shouldn't be sharing its ref clock with phy clock,
    which caused an issue of older ASICS booting up with multiple
    diplays plugged in.
    
    [how]
    Add an extra check that would prevent HDMI and DP sharing clk.
    
    Signed-off-by: Mikita Lipski <mikita.lipski at amd.com>
    Reviewed-by: Hersen Wu <hersenxs.wu at amd.com>
    Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
    Cc: stable at vger.kernel.org

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 2e65715f76a1..4ca41d6e3bcf 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -330,6 +330,9 @@ bool resource_are_streams_timing_synchronizable(
 				!= stream2->timing.pix_clk_khz)
 		return false;
 
+	if (stream1->clamping.c_depth != stream2->clamping.c_depth)
+		return false;
+
 	if (stream1->phy_pix_clk != stream2->phy_pix_clk
 			&& (!dc_is_dp_signal(stream1->signal)
 			|| !dc_is_dp_signal(stream2->signal)))
@@ -337,6 +340,20 @@ bool resource_are_streams_timing_synchronizable(
 
 	return true;
 }
+static bool is_dp_and_hdmi_sharable(
+		struct dc_stream_state *stream1,
+		struct dc_stream_state *stream2)
+{
+	if (stream1->ctx->dc->caps.disable_dp_clk_share)
+		return false;
+
+	if (stream1->clamping.c_depth != COLOR_DEPTH_888 ||
+	    stream2->clamping.c_depth != COLOR_DEPTH_888)
+	return false;
+
+	return true;
+
+}
 
 static bool is_sharable_clk_src(
 	const struct pipe_ctx *pipe_with_clk_src,
@@ -348,7 +365,10 @@ static bool is_sharable_clk_src(
 	if (pipe_with_clk_src->stream->signal == SIGNAL_TYPE_VIRTUAL)
 		return false;
 
-	if (dc_is_dp_signal(pipe_with_clk_src->stream->signal))
+	if (dc_is_dp_signal(pipe_with_clk_src->stream->signal) ||
+		(dc_is_dp_signal(pipe->stream->signal) &&
+		!is_dp_and_hdmi_sharable(pipe_with_clk_src->stream,
+				     pipe->stream)))
 		return false;
 
 	if (dc_is_hdmi_signal(pipe_with_clk_src->stream->signal)
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 55bcc3bdc6a3..3ecd2d614f41 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -78,6 +78,7 @@ struct dc_caps {
 	bool dual_link_dvi;
 	bool post_blend_color_processing;
 	bool force_dp_tps4_for_cp2520;
+	bool disable_dp_clk_share;
 };
 
 struct dc_dcc_surface_param {
diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
index fd2bdae4dcec..3f76e6019546 100644
--- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
@@ -919,7 +919,7 @@ static bool construct(
 	dc->caps.i2c_speed_in_khz = 40;
 	dc->caps.max_cursor_size = 128;
 	dc->caps.dual_link_dvi = true;
-
+	dc->caps.disable_dp_clk_share = true;
 	for (i = 0; i < pool->base.pipe_count; i++) {
 		pool->base.timing_generators[i] =
 			dce100_timing_generator_create(
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
index dc9f3e9afc33..604c62969ead 100644
--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
@@ -946,6 +946,7 @@ static bool dce80_construct(
 	}
 
 	dc->caps.max_planes =  pool->base.pipe_count;
+	dc->caps.disable_dp_clk_share = true;
 
 	if (!resource_construct(num_virtual_links, dc, &pool->base,
 			&res_create_funcs))
@@ -1131,6 +1132,7 @@ static bool dce81_construct(
 	}
 
 	dc->caps.max_planes =  pool->base.pipe_count;
+	dc->caps.disable_dp_clk_share = true;
 
 	if (!resource_construct(num_virtual_links, dc, &pool->base,
 			&res_create_funcs))
@@ -1312,6 +1314,7 @@ static bool dce83_construct(
 	}
 
 	dc->caps.max_planes =  pool->base.pipe_count;
+	dc->caps.disable_dp_clk_share = true;
 
 	if (!resource_construct(num_virtual_links, dc, &pool->base,
 			&res_create_funcs))
commit 9315e2399a2cdc236e8d42c1a21fb1071cdad03d
Author: Hersen Wu <hersenxs.wu at amd.com>
Date:   Mon Jul 16 11:21:12 2018 -0400

    drm/amd/display: Fix DP HBR2 Eye Diagram Pattern on Carrizo
    
    [why] dp hbr2 eye diagram pattern for raven asic is not stabled.
    workaround is to use tp4 pattern. But this should not be
    applied to asic before raven.
    
    [how] add new bool varilable in asic caps. for raven asic,
    use the workaround. for carrizo, vega, do not use workaround.
    
    Signed-off-by: Hersen Wu <hersenxs.wu at amd.com>
    Reviewed-by: Harry Wentland <Harry.Wentland at amd.com>
    Acked-by: Leo Li <sunpeng.li at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 58ee9aad13fb..160841da72a7 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -1784,12 +1784,10 @@ static void dp_test_send_link_training(struct dc_link *link)
 	dp_retrain_link_dp_test(link, &link_settings, false);
 }
 
-/* TODO hbr2 compliance eye output is unstable
+/* TODO Raven hbr2 compliance eye output is unstable
  * (toggling on and off) with debugger break
  * This caueses intermittent PHY automation failure
  * Need to look into the root cause */
-static uint8_t force_tps4_for_cp2520 = 1;
-
 static void dp_test_send_phy_test_pattern(struct dc_link *link)
 {
 	union phy_test_pattern dpcd_test_pattern;
@@ -1849,13 +1847,13 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link)
 		break;
 	case PHY_TEST_PATTERN_CP2520_1:
 		/* CP2520 pattern is unstable, temporarily use TPS4 instead */
-		test_pattern = (force_tps4_for_cp2520 == 1) ?
+		test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
 				DP_TEST_PATTERN_TRAINING_PATTERN4 :
 				DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
 		break;
 	case PHY_TEST_PATTERN_CP2520_2:
 		/* CP2520 pattern is unstable, temporarily use TPS4 instead */
-		test_pattern = (force_tps4_for_cp2520 == 1) ?
+		test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
 				DP_TEST_PATTERN_TRAINING_PATTERN4 :
 				DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
 		break;
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index c2d390fba0bf..55bcc3bdc6a3 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -77,6 +77,7 @@ struct dc_caps {
 	bool is_apu;
 	bool dual_link_dvi;
 	bool post_blend_color_processing;
+	bool force_dp_tps4_for_cp2520;
 };
 
 struct dc_dcc_surface_param {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
index 5d169f07d745..6b44ed3697a4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -1127,6 +1127,8 @@ static bool construct(
 	dc->caps.max_slave_planes = 1;
 	dc->caps.is_apu = true;
 	dc->caps.post_blend_color_processing = false;
+	/* Raven DP PHY HBR2 eye diagram pattern is not stable. Use TP4 */
+	dc->caps.force_dp_tps4_for_cp2520 = true;
 
 	if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
 		dc->debug = debug_defaults_drv;
commit 5ae6fe572929587a304471bf4a641361a45152b5
Author: Nicholas Kazlauskas <nicholas.kazlauskas at amd.com>
Date:   Mon Jul 23 14:13:23 2018 -0400

    drm/amd/display: Use calculated disp_clk_khz value for dce110
    
    [Why]
    
    The calculated values for actual disp_clk_khz were ignored when
    notifying pplib of the new display requirements. In order to honor DFS
    bypass clocks from the hardware, the calculated value should be used.
    
    [How]
    
    The return value for set_dispclk is now assigned back into new_clocks
    and correctly carried through into dccg->clks.phyclk_khz. When notifying
    pplib of new display requirements dccg->clks.phyclk_khz is used
    instead of dce.dispclk_khz. The value of dce.dispclk_khz was never
    explicitly set to anything before.
    
    A 15% higher display clock value than calculated is no longer requested
    for dce110 since it now makes use of the calculated value.
    
    Since dce112 makes use of dce110's set_bandwidth but not its
    update_clocks it needs to have the value correctly carried through.
    
    Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas at amd.com>
    Reviewed-by: Harry Wentland <Harry.Wentland at amd.com>
    Reviewed-by: Dmytro Laktyushkin <Dmytro.Laktyushkin at amd.com>
    Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
index 0db8d1da3d0e..f17677971d0f 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
@@ -463,7 +463,7 @@ static void dce12_update_clocks(struct dccg *dccg,
 	if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) {
 		clock_voltage_req.clk_type = DM_PP_CLOCK_TYPE_DISPLAY_CLK;
 		clock_voltage_req.clocks_in_khz = new_clocks->dispclk_khz;
-		dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz);
+		new_clocks->dispclk_khz = dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz);
 		dccg->clks.dispclk_khz = new_clocks->dispclk_khz;
 
 		dm_pp_apply_clock_for_voltage_request(dccg->ctx, &clock_voltage_req);
@@ -661,7 +661,7 @@ static void dce_update_clocks(struct dccg *dccg,
 	}
 
 	if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, dccg->clks.dispclk_khz)) {
-		dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz);
+		new_clocks->dispclk_khz = dccg->funcs->set_dispclk(dccg, new_clocks->dispclk_khz);
 		dccg->clks.dispclk_khz = new_clocks->dispclk_khz;
 	}
 }
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index 1149c413f6d2..1d98e3678b04 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -2530,7 +2530,7 @@ static void pplib_apply_display_requirements(
 	/* TODO: dce11.2*/
 	pp_display_cfg->avail_mclk_switch_time_in_disp_active_us = 0;
 
-	pp_display_cfg->disp_clk_khz = context->bw.dce.dispclk_khz;
+	pp_display_cfg->disp_clk_khz = dc->res_pool->dccg->clks.dispclk_khz;
 
 	dce110_fill_display_configs(context, pp_display_cfg);
 
@@ -2559,7 +2559,7 @@ void dce110_set_bandwidth(
 {
 	struct dc_clocks req_clks;
 
-	req_clks.dispclk_khz = context->bw.dce.dispclk_khz * 115 / 100;
+	req_clks.dispclk_khz = context->bw.dce.dispclk_khz;
 	req_clks.phyclk_khz = get_max_pixel_clock_for_all_paths(dc, context);
 
 	if (decrease_allowed)
commit 78e4405cec6cb0780b27b222685dde33934b38e4
Author: David Francis <David.Francis at amd.com>
Date:   Thu Jul 12 15:46:41 2018 -0400

    drm/amd/display: Implement custom degamma lut on dcn
    
    [Why]
    Custom degamma lut functions are a feature we would
    like to support on compatible hardware
    
    [How]
    In atomic check, convert from array of drm_color_lut to
    dc_transfer_func.  On hardware commit, allow for possibility
    of custom degamma.  Both are based on the equivalent
    regamma pipeline.
    
    Signed-off-by: David Francis <David.Francis at amd.com>
    Reviewed-by: Krunoslav Kovac <Krunoslav.Kovac at amd.com>
    Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index b329393307e5..326f6fb7e0bc 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -231,18 +231,21 @@ void amdgpu_dm_set_ctm(struct dm_crtc_state *crtc)
  * preparation for hardware commit. If no lut is specified by user, we default
  * to SRGB degamma.
  *
- * Currently, we only support degamma bypass, or preprogrammed SRGB degamma.
- * Programmable degamma is not supported, and an attempt to do so will return
- * -EINVAL.
+ * We support degamma bypass, predefined SRGB, and custom degamma
  *
  * RETURNS:
- * 0 on success, -EINVAL if custom degamma curve is given.
+ * 0 on success
+ * -EINVAL if crtc_state has a degamma_lut of invalid size
+ * -ENOMEM if gamma allocation fails
  */
 int amdgpu_dm_set_degamma_lut(struct drm_crtc_state *crtc_state,
 			      struct dc_plane_state *dc_plane_state)
 {
 	struct drm_property_blob *blob = crtc_state->degamma_lut;
 	struct drm_color_lut *lut;
+	uint32_t lut_size;
+	struct dc_gamma *gamma;
+	bool ret;
 
 	if (!blob) {
 		/* Default to SRGB */
@@ -258,11 +261,30 @@ int amdgpu_dm_set_degamma_lut(struct drm_crtc_state *crtc_state,
 		return 0;
 	}
 
-	/* Otherwise, assume SRGB, since programmable degamma is not
-	 * supported.
-	 */
-	dc_plane_state->in_transfer_func->type = TF_TYPE_PREDEFINED;
-	dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
-	return -EINVAL;
+	gamma = dc_create_gamma();
+	if (!gamma)
+		return -ENOMEM;
+
+	lut_size = blob->length / sizeof(struct drm_color_lut);
+	gamma->num_entries = lut_size;
+	if (gamma->num_entries == MAX_COLOR_LUT_ENTRIES)
+		gamma->type = GAMMA_CUSTOM;
+	else {
+		dc_gamma_release(&gamma);
+		return -EINVAL;
+	}
+
+	__drm_lut_to_dc_gamma(lut, gamma, false);
+
+	dc_plane_state->in_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
+	ret = mod_color_calculate_degamma_params(dc_plane_state->in_transfer_func, gamma, true);
+	dc_gamma_release(&gamma);
+	if (!ret) {
+		dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS;
+		DRM_ERROR("Out of memory when calculating degamma params\n");
+		return -ENOMEM;
+	}
+
+	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
index 1d1f2d5ece51..b789cb2b354b 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
@@ -417,6 +417,7 @@ enum {
 	GAMMA_RGB_256_ENTRIES = 256,
 	GAMMA_RGB_FLOAT_1024_ENTRIES = 1024,
 	GAMMA_CS_TFM_1D_ENTRIES = 4096,
+	GAMMA_CUSTOM_ENTRIES = 4096,
 	GAMMA_MAX_ENTRIES = 4096
 };
 
@@ -424,6 +425,7 @@ enum dc_gamma_type {
 	GAMMA_RGB_256 = 1,
 	GAMMA_RGB_FLOAT_1024 = 2,
 	GAMMA_CS_TFM_1D = 3,
+	GAMMA_CUSTOM = 4,
 };
 
 struct dc_csc_transform {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index c87f6e603055..f5d8242eb047 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -1213,8 +1213,11 @@ static bool dcn10_set_input_transfer_func(struct pipe_ctx *pipe_ctx,
 	} else if (tf->type == TF_TYPE_BYPASS) {
 		dpp_base->funcs->dpp_set_degamma(dpp_base, IPP_DEGAMMA_MODE_BYPASS);
 	} else {
-		/*TF_TYPE_DISTRIBUTED_POINTS*/
-		result = false;
+		cm_helper_translate_curve_to_degamma_hw_format(tf,
+					&dpp_base->degamma_params);
+		dpp_base->funcs->dpp_program_degamma_pwl(dpp_base,
+				&dpp_base->degamma_params);
+		result = true;
 	}
 
 	return result;
diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
index ee69c949bfbf..bf29733958c3 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
@@ -997,7 +997,9 @@ static void scale_user_regamma_ramp(struct pwl_float_data *pwl_rgb,
  * norm_y = 4095*regamma_y, and index is just truncating to nearest integer
  * lut1 = lut1D[index], lut2 = lut1D[index+1]
  *
- *adjustedY is then linearly interpolating regamma Y between lut1 and lut2
+ * adjustedY is then linearly interpolating regamma Y between lut1 and lut2
+ *
+ * Custom degamma on Linux uses the same interpolation math, so is handled here
  */
 static void apply_lut_1d(
 		const struct dc_gamma *ramp,
@@ -1018,7 +1020,7 @@ static void apply_lut_1d(
 	struct fixed31_32 delta_lut;
 	struct fixed31_32 delta_index;
 
-	if (ramp->type != GAMMA_CS_TFM_1D)
+	if (ramp->type != GAMMA_CS_TFM_1D && ramp->type != GAMMA_CUSTOM)
 		return; // this is not expected
 
 	for (i = 0; i < num_hw_points; i++) {
@@ -1636,7 +1638,9 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf,
 	map_regamma_hw_to_x_user(ramp, coeff, rgb_user,
 			coordinates_x, axix_x, curve,
 			MAX_HW_POINTS, tf_pts,
-			mapUserRamp);
+			mapUserRamp && ramp->type != GAMMA_CUSTOM);
+	if (ramp->type == GAMMA_CUSTOM)
+		apply_lut_1d(ramp, MAX_HW_POINTS, tf_pts);
 
 	ret = true;
 
commit d90e9a3bf5e747f0e3b0c8bec96d8699493f63ab
Author: David Francis <David.Francis at amd.com>
Date:   Thu Jul 19 15:48:24 2018 -0400

    drm/amd/display: Destroy aux_engines only once
    
    [Why]
    In the dce112 function to destroy the resource pool, engines
    (the aux engines) is destroyed twice.  This has no ill effects
    but is a tad redundant.
    
    [How]
    Remove the redundant call
    
    Signed-off-by: David Francis <David.Francis at amd.com>
    Reviewed-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
index 84a05ff2d674..288129343c77 100644
--- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
@@ -677,9 +677,6 @@ static void destruct(struct dce110_resource_pool *pool)
 			pool->base.timing_generators[i] = NULL;
 		}
 
-		if (pool->base.engines[i] != NULL)
-			dce110_engine_destroy(&pool->base.engines[i]);
-
 	}
 
 	for (i = 0; i < pool->base.stream_enc_count; i++) {
commit 53a53f8687faf492df2644d8c18ff0217fc18730
Author: David Francis <David.Francis at amd.com>
Date:   Wed Jul 18 16:03:30 2018 -0400

    drm/amd/display: Read back max backlight value at boot
    
    [Why]
    If there is no program explicitly setting the backlight
    brightness (for example, during a minimal install of linux), the
    hardware defaults to maximum brightness but the backlight_device
    defaults to 0 value.  Thus, settings displays the wrong brightness
    value.
    
    [How]
    When creating the backlight device, set brightness to max
    
    Signed-off-by: David Francis <David.Francis at amd.com>
    Reviewed-by: Harry Wentland <Harry.Wentland at amd.com>
    Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index dcae658fbc50..34f34823bab5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1340,6 +1340,7 @@ amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm)
 	struct backlight_properties props = { 0 };
 
 	props.max_brightness = AMDGPU_MAX_BL_LEVEL;
+	props.brightness = AMDGPU_MAX_BL_LEVEL;
 	props.type = BACKLIGHT_RAW;
 
 	snprintf(bl_name, sizeof(bl_name), "amdgpu_bl%d",
commit 620a0d27b211aa03d3f99accfdd58b88e6e0504c
Author: David Francis <David.Francis at amd.com>
Date:   Thu Jul 19 11:25:05 2018 -0400

    drm/amd/display: Implement backlight_ops.get_brightness
    
    [Why]
    This hook that is supposed to read the actual backlight value
    is used in a few places throughout the kernel to setup or force
    update on backlight
    
    [How]
    Create a dc function that calls the existing abm function, and
    call that function from amdgpu
    
    Signed-off-by: David Francis <David.Francis at amd.com>
    Reviewed-by: Harry Wentland <Harry.Wentland at amd.com>
    Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index c1631d61336e..dcae658fbc50 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -1320,7 +1320,12 @@ static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)
 
 static int amdgpu_dm_backlight_get_brightness(struct backlight_device *bd)
 {
-	return bd->props.brightness;
+	struct amdgpu_display_manager *dm = bl_get_data(bd);
+	int ret = dc_link_get_backlight_level(dm->backlight_link);
+
+	if (ret == DC_ERROR_UNEXPECTED)
+		return bd->props.brightness;
+	return ret;
 }
 
 static const struct backlight_ops amdgpu_dm_backlight_ops = {
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index ce65b4d5062e..9a6448e2089c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -2026,6 +2026,15 @@ enum dc_status dc_link_validate_mode_timing(
 	return DC_OK;
 }
 
+int dc_link_get_backlight_level(const struct dc_link *link)
+{
+	struct abm *abm = link->ctx->dc->res_pool->abm;
+
+	if (abm == NULL || abm->funcs->get_current_backlight_8_bit == NULL)
+		return DC_ERROR_UNEXPECTED;
+
+	return (int) abm->funcs->get_current_backlight_8_bit(abm);
+}
 
 bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t level,
 		uint32_t frame_ramp, const struct dc_stream_state *stream)
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index 070a56926308..22f4ddd219d1 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -141,6 +141,8 @@ static inline struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_
 bool dc_link_set_backlight_level(const struct dc_link *dc_link, uint32_t level,
 		uint32_t frame_ramp, const struct dc_stream_state *stream);
 
+int dc_link_get_backlight_level(const struct dc_link *dc_link);
+
 bool dc_link_set_abm_disable(const struct dc_link *dc_link);
 
 bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable, bool wait);
commit 0301ccbaf67d3d9aea97156c5eb85233bb5a5178
Author: abdoulaye berthe <abdoulaye.berthe at amd.com>
Date:   Thu Jul 19 15:39:55 2018 -0400

    drm/amd/display: DP Compliance 400.1.1 failure
    
    [Why]
    400.1.1 is failing because we are not performing link training when
    we get an HPD pulse for the same display. This is breaking DP
    compliance
    
    [How]
    Always perform link training after HPD pulse if the detection
    reason is not  DETECT_REASON_HPDRX.
    
    Signed-off-by: abdoulaye berthe <abdoulaye.berthe at amd.com>
    Reviewed-by: Wenjing Liu <Wenjing.Liu at amd.com>
    Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 89d7c1e99168..ce65b4d5062e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -764,39 +764,41 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
 		if ((prev_sink != NULL) && ((edid_status == EDID_THE_SAME) || (edid_status == EDID_OK)))
 			same_edid = is_same_edid(&prev_sink->dc_edid, &sink->dc_edid);
 
-		// If both edid and dpcd are the same, then discard new sink and revert back to original sink
-		if ((same_edid) && (same_dpcd)) {
-			link_disconnect_remap(prev_sink, link);
-			sink = prev_sink;
-			prev_sink = NULL;
-		} else {
-			if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
-					sink_caps.transaction_type ==
-						DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
-				/*
-				 * TODO debug why Dell 2413 doesn't like
-				 *  two link trainings
-				 */
+		if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
+			sink_caps.transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX &&
+			reason != DETECT_REASON_HPDRX) {
+			/*
+			 * TODO debug why Dell 2413 doesn't like
+			 *  two link trainings
+			 */
 
-				/* deal with non-mst cases */
-				for (i = 0; i < LINK_TRAINING_MAX_VERIFY_RETRY; i++) {
-					int fail_count = 0;
+			/* deal with non-mst cases */
+			for (i = 0; i < LINK_TRAINING_MAX_VERIFY_RETRY; i++) {
+				int fail_count = 0;
 
-					dp_verify_link_cap(link,
-							  &link->reported_link_cap,
-							  &fail_count);
+				dp_verify_link_cap(link,
+						  &link->reported_link_cap,
+						  &fail_count);
 
-					if (fail_count == 0)
-						break;
-				}
+				if (fail_count == 0)
+					break;
 			}
 
-			/* HDMI-DVI Dongle */
-			if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A &&
-					!sink->edid_caps.edid_hdmi)
-				sink->sink_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
+		} else {
+			// If edid is the same, then discard new sink and revert back to original sink
+			if (same_edid) {
+				link_disconnect_remap(prev_sink, link);
+				sink = prev_sink;
+				prev_sink = NULL;
+
+			}
 		}
 
+		/* HDMI-DVI Dongle */
+		if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A &&
+				!sink->edid_caps.edid_hdmi)
+			sink->sink_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
+
 		/* Connectivity log: detection */
 		for (i = 0; i < sink->dc_edid.length / EDID_BLOCK_SIZE; i++) {
 			CONN_DATA_DETECT(link,
commit e11d41472a50742c16d53c968e143fb498fa482f
Author: Leo (Sunpeng) Li <sunpeng.li at amd.com>
Date:   Thu Jul 19 08:22:16 2018 -0400

    drm/amd/display: Use requested HDMI aspect ratio
    
    [Why]
    The DRM mode's HDMI picture aspect ratio field was never saved in
    dc_stream's timing struct. This causes us to mistake a new stream to
    have the same timings as the old, even though the user has requested a
    different aspect ratio.
    
    [How]
    Save DRM's aspect ratio field within dc_stream's timing struct.
    
    Bug: https://bugs.freedesktop.org/show_bug.cgi?id=107153
    Signed-off-by: Leo (Sunpeng) Li <sunpeng.li at amd.com>
    Reviewed-by: Mikita Lipski <Mikita.Lipski at amd.com>
    Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
    Cc: stable at vger.kernel.org

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 45e062022461..c1631d61336e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2109,13 +2109,8 @@ convert_color_depth_from_display_info(const struct drm_connector *connector)
 static enum dc_aspect_ratio
 get_aspect_ratio(const struct drm_display_mode *mode_in)
 {
-	int32_t width = mode_in->crtc_hdisplay * 9;
-	int32_t height = mode_in->crtc_vdisplay * 16;
-
-	if ((width - height) < 10 && (width - height) > -10)
-		return ASPECT_RATIO_16_9;
-	else
-		return ASPECT_RATIO_4_3;
+	/* 1-1 mapping, since both enums follow the HDMI spec. */
+	return (enum dc_aspect_ratio) mode_in->picture_aspect_ratio;
 }
 
 static enum dc_color_space
commit 3237c0dbe21f8d2ca2feaa3891aff3619873cd30
Author: Michał Winiarski <michal.winiarski at intel.com>
Date:   Thu Jul 12 17:53:30 2018 +0200

    drm/i915/kvmgt: Fix compilation error
    
    gvt_pin_guest_page extracted some of the gvt_dma_map_page functionality:
    commit 79e542f5af79 ("drm/i915/kvmgt: Support setting dma map for huge pages")
    
    And yet, part of it was reintroduced in:
    commit 39b4cbadb9a9 ("drm/i915/kvmgt: Check the pfn got from vfio_pin_pages")
    
    Causing kvmgt part to no longer build. Let's remove it.
    
    Reported-by: Tomasz Lis <tomasz.lis at intel.com>
    Signed-off-by: Michał Winiarski <michal.winiarski at intel.com>
    Cc: Changbin Du <changbin.du at intel.com>
    Cc: Zhenyu Wang <zhenyuw at linux.intel.com>
    Acked-by: Zhenyu Wang <zhenyuw at linux.intel.com>
    Signed-off-by: Rodrigo Vivi <rodrigo.vivi at intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20180712155330.32055-1-michal.winiarski@intel.com
    (cherry picked from commit 4eaf317a60fbea0555b936035002ca9bd9b9105d)
    Signed-off-by: Rodrigo Vivi <rodrigo.vivi at intel.com>

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 718ab307a500..4d2f53ae9f0f 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -185,12 +185,6 @@ static int gvt_dma_map_page(struct intel_vgpu *vgpu, unsigned long gfn,
 	if (ret)
 		return ret;
 
-	if (!pfn_valid(pfn)) {
-		gvt_vgpu_err("pfn 0x%lx is not mem backed\n", pfn);
-		vfio_unpin_pages(mdev_dev(vgpu->vdev.mdev), &gfn, 1);
-		return -EINVAL;
-	}
-
 	/* Setup DMA mapping. */
 	*dma_addr = dma_map_page(dev, page, 0, size, PCI_DMA_BIDIRECTIONAL);
 	ret = dma_mapping_error(dev, *dma_addr);
commit 75eef0f1ed478284911b8723a5bdb659499a7aac
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Aug 2 15:04:16 2018 +0100

    drm/i915/lpe: Mark LPE audio runtime pm as "no callbacks"
    
    The LPE audio is a child device of i915, it is powered up and down
    alongside the igfx and presents no independent runtime interface. This
    aptly fulfils the description of a "No-Callback" Device, so mark it
    thus.
    
    Fixes: 183c00350ccd ("drm/i915: Fix runtime PM for LPE audio")
    Testcase: igt/pm_rpm/basic-pci-d3-state
    Testcase: igt/pm_rpm/basic-rte
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Takashi Iwai <tiwai at suse.de>
    Cc: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
    Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
    Cc: stable at vger.kernel.org
    Reviewed-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20180802140416.6062-1-chris@chris-wilson.co.uk
    (cherry picked from commit 46e831abe864a6b59fa3de253a681c0f2ee1bf2f)
    Signed-off-by: Rodrigo Vivi <rodrigo.vivi at intel.com>

diff --git a/drivers/gpu/drm/i915/intel_lpe_audio.c b/drivers/gpu/drm/i915/intel_lpe_audio.c
index 6269750e2b54..430732720e65 100644
--- a/drivers/gpu/drm/i915/intel_lpe_audio.c
+++ b/drivers/gpu/drm/i915/intel_lpe_audio.c
@@ -126,9 +126,7 @@ lpe_audio_platdev_create(struct drm_i915_private *dev_priv)
 		return platdev;
 	}
 
-	pm_runtime_forbid(&platdev->dev);
-	pm_runtime_set_active(&platdev->dev);
-	pm_runtime_enable(&platdev->dev);
+	pm_runtime_no_callbacks(&platdev->dev);
 
 	return platdev;
 }
commit 497bfb706844892d07495f2ed5dff977fede5e25
Author: Mika Kuoppala <mika.kuoppala at linux.intel.com>
Date:   Mon Jul 30 15:06:36 2018 +0300

    Revert "drm/i915/icl: WaEnableFloatBlendOptimization"
    
    The register for 0xe420 is unable to hold any value, including
    this bit. The documentation is also mixed between having a
    register bit for toggle and having a state command setup
    for it. Apparently the register toggle is deprecated.
    
    Remove the register toggle as evidence shows it's futile.
    
    The thing remaining is an apology and humble request for
    Mesa folks to resurrect their state setup for this as they
    were on right track from start.
    
    This reverts commit 0bf059f3532bb39c52d917142206a8554fc2f1c5.
    
    Fixes: 0bf059f3532b ("drm/i915/icl: WaEnableFloatBlendOptimization")
    References: HSDES#1406393558
    Cc: Oscar Mateo <oscar.mateo at intel.com>
    Cc: Anuj Phogat <anuj.phogat at gmail.com>
    Cc: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
    Signed-off-by: Mika Kuoppala <mika.kuoppala at linux.intel.com>
    Acked-by: Chris Wilson <chris at chris-wilson.co.uk>
    Link: https://patchwork.freedesktop.org/patch/msgid/20180730120636.26958-1-mika.kuoppala@linux.intel.com
    (cherry picked from commit c358514ba8da9e235876db1628cedd19a35803c6)
    Signed-off-by: Rodrigo Vivi <rodrigo.vivi at intel.com>

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 8af945d8a995..91e7483228e1 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2780,9 +2780,6 @@ enum i915_power_well_id {
 #define   GEN8_4x4_STC_OPTIMIZATION_DISABLE	(1 << 6)
 #define   GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE	(1 << 1)
 
-#define GEN10_CACHE_MODE_SS			_MMIO(0xe420)
-#define   FLOAT_BLEND_OPTIMIZATION_ENABLE	(1 << 4)
-
 #define GEN6_BLITTER_ECOSKPD	_MMIO(0x221d0)
 #define   GEN6_BLITTER_LOCK_SHIFT			16
 #define   GEN6_BLITTER_FBC_NOTIFY			(1 << 3)
diff --git a/drivers/gpu/drm/i915/intel_workarounds.c b/drivers/gpu/drm/i915/intel_workarounds.c
index f8bb32e974f6..4bcdeaf8d98f 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/intel_workarounds.c
@@ -508,9 +508,6 @@ static int icl_ctx_workarounds_init(struct drm_i915_private *dev_priv)
 		WA_SET_BIT_MASKED(GEN11_COMMON_SLICE_CHICKEN3,
 				  GEN11_BLEND_EMB_FIX_DISABLE_IN_RCC);
 
-	/* WaEnableFloatBlendOptimization:icl */
-	WA_SET_BIT_MASKED(GEN10_CACHE_MODE_SS, FLOAT_BLEND_OPTIMIZATION_ENABLE);
-
 	return 0;
 }
 
commit 027063b1606fea6df15c270e5f2a072d1dfa8fef
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jul 31 14:26:29 2018 +0100

    drm/i915: Interactive RPS mode
    
    RPS provides a feedback loop where we use the load during the previous
    evaluation interval to decide whether to up or down clock the GPU
    frequency. Our responsiveness is split into 3 regimes, a high and low
    plateau with the intent to keep the gpu clocked high to cover occasional
    stalls under high load, and low despite occasional glitches under steady
    low load, and inbetween. However, we run into situations like kodi where
    we want to stay at low power (video decoding is done efficiently
    inside the fixed function HW and doesn't need high clocks even for high
    bitrate streams), but just occasionally the pipeline is more complex
    than a video decode and we need a smidgen of extra GPU power to present
    on time. In the high power regime, we sample at sub frame intervals with
    a bias to upclocking, and conversely at low power we sample over a few
    frames worth to provide what we consider to be the right levels of
    responsiveness respectively. At low power, we more or less expect to be
    kicked out to high power at the start of a busy sequence by waitboosting.
    
    Prior to commit e9af4ea2b9e7 ("drm/i915: Avoid waitboosting on the active
    request") whenever we missed the frame or stalled, we would immediate go
    full throttle and upclock the GPU to max. But in commit e9af4ea2b9e7, we
    relaxed the waitboosting to only apply if the pipeline was deep to avoid
    over-committing resources for a near miss. Sadly though, a near miss is
    still a miss, and perceptible as jitter in the frame delivery.
    
    To try and prevent the near miss before having to resort to boosting
    after the fact, we use the pageflip queue as an indication that we are
    in an "interactive" regime and so should sample the load more frequently
    to provide power before the frame misses it vblank. This will make us
    more favorable to providing a small power increase (one or two bins) as
    required rather than going all the way to maximum and then having to
    work back down again. (We still keep the waitboosting mechanism around
    just in case a dramatic change in system load requires urgent uplocking,
    faster than we can provide in a few evaluation intervals.)
    
    v2: Reduce rps_set_interactive to a boolean parameter to avoid the
    confusion of what if they wanted a new power mode after pinning to a
    different mode (which to choose?)
    v3: Only reprogram RPS while the GT is awake, it will be set when we
    wake the GT, and while off warns about being used outside of rpm.
    v4: Fix deferred application of interactive mode
    v5: s/state/interactive/
    v6: Group the mutex with its principle in a substruct
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107111
    Fixes: e9af4ea2b9e7 ("drm/i915: Avoid waitboosting on the active request")
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
    Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
    Cc: Radoslaw Szwichtenberg <radoslaw.szwichtenberg at intel.com>
    Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
    Reviewed-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20180731132629.3381-1-chris@chris-wilson.co.uk
    (cherry picked from commit 60548c554be2830d29d2533dad0ac8133347ee51)
    Signed-off-by: Rodrigo Vivi <rodrigo.vivi at intel.com>

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 59dc0610ea44..f9ce35da4123 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1218,7 +1218,8 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
 			   rpcurup, GT_PM_INTERVAL_TO_US(dev_priv, rpcurup));
 		seq_printf(m, "RP PREV UP: %d (%dus)\n",
 			   rpprevup, GT_PM_INTERVAL_TO_US(dev_priv, rpprevup));
-		seq_printf(m, "Up threshold: %d%%\n", rps->up_threshold);
+		seq_printf(m, "Up threshold: %d%%\n",
+			   rps->power.up_threshold);
 
 		seq_printf(m, "RP CUR DOWN EI: %d (%dus)\n",
 			   rpdownei, GT_PM_INTERVAL_TO_US(dev_priv, rpdownei));
@@ -1226,7 +1227,8 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
 			   rpcurdown, GT_PM_INTERVAL_TO_US(dev_priv, rpcurdown));
 		seq_printf(m, "RP PREV DOWN: %d (%dus)\n",
 			   rpprevdown, GT_PM_INTERVAL_TO_US(dev_priv, rpprevdown));
-		seq_printf(m, "Down threshold: %d%%\n", rps->down_threshold);
+		seq_printf(m, "Down threshold: %d%%\n",
+			   rps->power.down_threshold);
 
 		max_freq = (IS_GEN9_LP(dev_priv) ? rp_state_cap >> 0 :
 			    rp_state_cap >> 16) & 0xff;
@@ -2218,6 +2220,7 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
 	seq_printf(m, "CPU waiting? %d\n", count_irq_waiters(dev_priv));
 	seq_printf(m, "Boosts outstanding? %d\n",
 		   atomic_read(&rps->num_waiters));
+	seq_printf(m, "Interactive? %d\n", READ_ONCE(rps->power.interactive));
 	seq_printf(m, "Frequency requested %d\n",
 		   intel_gpu_freq(dev_priv, rps->cur_freq));
 	seq_printf(m, "  min hard:%d, soft:%d; max soft:%d, hard:%d\n",
@@ -2261,13 +2264,13 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
 		intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 
 		seq_printf(m, "\nRPS Autotuning (current \"%s\" window):\n",
-			   rps_power_to_str(rps->power));
+			   rps_power_to_str(rps->power.mode));
 		seq_printf(m, "  Avg. up: %d%% [above threshold? %d%%]\n",
 			   rpup && rpupei ? 100 * rpup / rpupei : 0,
-			   rps->up_threshold);
+			   rps->power.up_threshold);
 		seq_printf(m, "  Avg. down: %d%% [below threshold? %d%%]\n",
 			   rpdown && rpdownei ? 100 * rpdown / rpdownei : 0,
-			   rps->down_threshold);
+			   rps->power.down_threshold);
 	} else {
 		seq_puts(m, "\nRPS Autotuning inactive\n");
 	}
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0f49f9988dfa..4aca5344863d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -779,11 +779,17 @@ struct intel_rps {
 	u8 rp0_freq;		/* Non-overclocked max frequency. */
 	u16 gpll_ref_freq;	/* vlv/chv GPLL reference frequency */
 
-	u8 up_threshold; /* Current %busy required to uplock */
-	u8 down_threshold; /* Current %busy required to downclock */
-
 	int last_adj;
-	enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
+
+	struct {
+		struct mutex mutex;
+
+		enum { LOW_POWER, BETWEEN, HIGH_POWER } mode;
+		unsigned int interactive;
+
+		u8 up_threshold; /* Current %busy required to uplock */
+		u8 down_threshold; /* Current %busy required to downclock */
+	} power;
 
 	bool enabled;
 	atomic_t num_waiters;
@@ -3422,6 +3428,8 @@ extern void i915_redisable_vga_power_on(struct drm_i915_private *dev_priv);
 extern bool ironlake_set_drps(struct drm_i915_private *dev_priv, u8 val);
 extern void intel_init_pch_refclk(struct drm_i915_private *dev_priv);
 extern int intel_set_rps(struct drm_i915_private *dev_priv, u8 val);
+extern void intel_rps_mark_interactive(struct drm_i915_private *i915,
+				       bool interactive);
 extern bool intel_set_memory_cxsr(struct drm_i915_private *dev_priv,
 				  bool enable);
 
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 5dadefca2ad2..90628a47ae17 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1265,9 +1265,9 @@ static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir)
 		c0 = max(render, media);
 		c0 *= 1000 * 100 << 8; /* to usecs and scale to threshold% */
 
-		if (c0 > time * rps->up_threshold)
+		if (c0 > time * rps->power.up_threshold)
 			events = GEN6_PM_RP_UP_THRESHOLD;
-		else if (c0 < time * rps->down_threshold)
+		else if (c0 < time * rps->power.down_threshold)
 			events = GEN6_PM_RP_DOWN_THRESHOLD;
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 87e4cfbfd096..ed3fa1c8a983 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13104,6 +13104,19 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 		add_rps_boost_after_vblank(new_state->crtc, new_state->fence);
 	}
 
+	/*
+	 * We declare pageflips to be interactive and so merit a small bias
+	 * towards upclocking to deliver the frame on time. By only changing
+	 * the RPS thresholds to sample more regularly and aim for higher
+	 * clocks we can hopefully deliver low power workloads (like kodi)
+	 * that are not quite steady state without resorting to forcing
+	 * maximum clocks following a vblank miss (see do_rps_boost()).
+	 */
+	if (!intel_state->rps_interactive) {
+		intel_rps_mark_interactive(dev_priv, true);
+		intel_state->rps_interactive = true;
+	}
+
 	return 0;
 }
 
@@ -13120,8 +13133,15 @@ void
 intel_cleanup_plane_fb(struct drm_plane *plane,
 		       struct drm_plane_state *old_state)
 {
+	struct intel_atomic_state *intel_state =
+		to_intel_atomic_state(old_state->state);
 	struct drm_i915_private *dev_priv = to_i915(plane->dev);
 
+	if (intel_state->rps_interactive) {
+		intel_rps_mark_interactive(dev_priv, false);
+		intel_state->rps_interactive = false;
+	}
+
 	/* Should only be called after a successful intel_prepare_plane_fb()! */
 	mutex_lock(&dev_priv->drm.struct_mutex);
 	intel_plane_unpin_fb(to_intel_plane_state(old_state));
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c275f91244a6..17af06d8a43e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -484,6 +484,8 @@ struct intel_atomic_state {
 	 */
 	bool skip_intermediate_wm;
 
+	bool rps_interactive;
+
 	/* Gen9+ only */
 	struct skl_ddb_values wm_results;
 
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 7312ecb73415..43ae9de12ba3 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6264,42 +6264,15 @@ static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val)
 	return limits;
 }
 
-static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
+static void rps_set_power(struct drm_i915_private *dev_priv, int new_power)
 {
 	struct intel_rps *rps = &dev_priv->gt_pm.rps;
-	int new_power;
 	u32 threshold_up = 0, threshold_down = 0; /* in % */
 	u32 ei_up = 0, ei_down = 0;
 
-	new_power = rps->power;
-	switch (rps->power) {
-	case LOW_POWER:
-		if (val > rps->efficient_freq + 1 &&
-		    val > rps->cur_freq)
-			new_power = BETWEEN;
-		break;
-
-	case BETWEEN:
-		if (val <= rps->efficient_freq &&
-		    val < rps->cur_freq)
-			new_power = LOW_POWER;
-		else if (val >= rps->rp0_freq &&
-			 val > rps->cur_freq)
-			new_power = HIGH_POWER;
-		break;
+	lockdep_assert_held(&rps->power.mutex);
 
-	case HIGH_POWER:
-		if (val < (rps->rp1_freq + rps->rp0_freq) >> 1 &&
-		    val < rps->cur_freq)
-			new_power = BETWEEN;
-		break;
-	}
-	/* Max/min bins are special */
-	if (val <= rps->min_freq_softlimit)
-		new_power = LOW_POWER;
-	if (val >= rps->max_freq_softlimit)
-		new_power = HIGH_POWER;
-	if (new_power == rps->power)
+	if (new_power == rps->power.mode)
 		return;
 
 	/* Note the units here are not exactly 1us, but 1280ns. */
@@ -6362,12 +6335,71 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
 		   GEN6_RP_DOWN_IDLE_AVG);
 
 skip_hw_write:
-	rps->power = new_power;
-	rps->up_threshold = threshold_up;
-	rps->down_threshold = threshold_down;
+	rps->power.mode = new_power;
+	rps->power.up_threshold = threshold_up;
+	rps->power.down_threshold = threshold_down;
+}
+
+static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
+{
+	struct intel_rps *rps = &dev_priv->gt_pm.rps;
+	int new_power;
+
+	new_power = rps->power.mode;
+	switch (rps->power.mode) {
+	case LOW_POWER:
+		if (val > rps->efficient_freq + 1 &&
+		    val > rps->cur_freq)
+			new_power = BETWEEN;
+		break;
+
+	case BETWEEN:
+		if (val <= rps->efficient_freq &&
+		    val < rps->cur_freq)
+			new_power = LOW_POWER;
+		else if (val >= rps->rp0_freq &&
+			 val > rps->cur_freq)
+			new_power = HIGH_POWER;
+		break;
+
+	case HIGH_POWER:
+		if (val < (rps->rp1_freq + rps->rp0_freq) >> 1 &&
+		    val < rps->cur_freq)
+			new_power = BETWEEN;
+		break;
+	}
+	/* Max/min bins are special */
+	if (val <= rps->min_freq_softlimit)
+		new_power = LOW_POWER;
+	if (val >= rps->max_freq_softlimit)
+		new_power = HIGH_POWER;
+
+	mutex_lock(&rps->power.mutex);
+	if (rps->power.interactive)
+		new_power = HIGH_POWER;
+	rps_set_power(dev_priv, new_power);
+	mutex_unlock(&rps->power.mutex);
 	rps->last_adj = 0;
 }
 
+void intel_rps_mark_interactive(struct drm_i915_private *i915, bool interactive)
+{
+	struct intel_rps *rps = &i915->gt_pm.rps;
+
+	if (INTEL_GEN(i915) < 6)
+		return;
+
+	mutex_lock(&rps->power.mutex);
+	if (interactive) {
+		if (!rps->power.interactive++ && READ_ONCE(i915->gt.awake))
+			rps_set_power(i915, HIGH_POWER);
+	} else {
+		GEM_BUG_ON(!rps->power.interactive);
+		rps->power.interactive--;
+	}
+	mutex_unlock(&rps->power.mutex);
+}
+
 static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val)
 {
 	struct intel_rps *rps = &dev_priv->gt_pm.rps;
@@ -6780,7 +6812,7 @@ static void reset_rps(struct drm_i915_private *dev_priv,
 	u8 freq = rps->cur_freq;
 
 	/* force a reset */
-	rps->power = -1;
+	rps->power.mode = -1;
 	rps->cur_freq = -1;
 
 	if (set(dev_priv, freq))
@@ -9604,6 +9636,7 @@ int intel_freq_opcode(struct drm_i915_private *dev_priv, int val)
 void intel_pm_setup(struct drm_i915_private *dev_priv)
 {
 	mutex_init(&dev_priv->pcu_lock);
+	mutex_init(&dev_priv->gt_pm.rps.power.mutex);
 
 	atomic_set(&dev_priv->gt_pm.rps.num_waiters, 0);
 
commit 656921a51244b72cd1105df61b0af15825bddb72
Author: Rodrigo Vivi <rodrigo.vivi at intel.com>
Date:   Thu Jul 19 17:31:55 2018 -0700

    drm/i915: Fix psr sink status report.
    
    First of all don't try to read dpcd if PSR is not even supported.
    
    But also, if read failed return -EIO instead of reporting via a
    backchannel.
    
    v2: fix dev_priv: At this level m->private is the connector. (CI/DK)
        don't convert dpcd read errors to EIO. (DK)
    
    Fixes: 5b7b30864d1d ("drm/i915/psr: Split sink status into a separate debugfs node")
    Cc: Chris Wilson <chris at chris-wilson.co.uk>
    Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan at intel.com>
    Cc: José Roberto de Souza <jose.souza at intel.com>
    Signed-off-by: Rodrigo Vivi <rodrigo.vivi at intel.com>
    Reviewed-by: Dhinakaran Pandiyan <dhinakaran.pandiyan at intel.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20180720003155.16290-1-rodrigo.vivi@intel.com
    (cherry picked from commit 7a72c78bdd0a1ea1d879610542679cc680398220)
    Signed-off-by: Rodrigo Vivi <rodrigo.vivi at intel.com>

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index b3aefd623557..59dc0610ea44 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2606,13 +2606,22 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data)
 		"sink internal error",
 	};
 	struct drm_connector *connector = m->private;
+	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	struct intel_dp *intel_dp =
 		enc_to_intel_dp(&intel_attached_encoder(connector)->base);
+	int ret;
+
+	if (!CAN_PSR(dev_priv)) {
+		seq_puts(m, "PSR Unsupported\n");
+		return -ENODEV;
+	}
 
 	if (connector->status != connector_status_connected)
 		return -ENODEV;
 
-	if (drm_dp_dpcd_readb(&intel_dp->aux, DP_PSR_STATUS, &val) == 1) {
+	ret = drm_dp_dpcd_readb(&intel_dp->aux, DP_PSR_STATUS, &val);
+
+	if (ret == 1) {
 		const char *str = "unknown";
 
 		val &= DP_PSR_SINK_STATE_MASK;
@@ -2620,7 +2629,7 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data)
 			str = sink_status[val];
 		seq_printf(m, "Sink PSR status: 0x%x [%s]\n", val, str);
 	} else {
-		DRM_ERROR("dpcd read (at %u) failed\n", DP_PSR_STATUS);
+		return ret;
 	}
 
 	return 0;
commit 5b147465532365dc4e2fee8499d6ca1f52dd0d16
Author: Lucas Stach <l.stach at pengutronix.de>
Date:   Mon Jul 23 14:27:23 2018 +0200

    drm/etnaviv: fix crash in GPU suspend when init failed due to buffer placement
    
    When the suballocator was unable to provide a suitable buffer for the MMUv1
    linear window, we roll back the GPU initialization. As the GPU is runtime
    resumed at that point we need to clear the kernel cmdbuf suballoc entry to
    properly skip any attempt to manipulate the cmdbuf when the GPU gets shut
    down in the runtime suspend later on.
    
    Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index 18c2224ba0b8..ab8dfe7f69d6 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -799,6 +799,7 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
 
 free_buffer:
 	etnaviv_cmdbuf_free(&gpu->buffer);
+	gpu->buffer.suballoc = NULL;
 destroy_iommu:
 	etnaviv_iommu_destroy(gpu->mmu);
 	gpu->mmu = NULL;
commit cfad05a24dcb2bf09ba6438e0843c6a0ed90381c
Author: Souptick Joarder <jrdr.linux at gmail.com>
Date:   Tue May 29 19:17:27 2018 +0530

    drm/etnaviv: change return type to vm_fault_t
    
    Use new return type vm_fault_t for fault handler. For
    now, this is just documenting that the function returns
    a VM_FAULT value rather than an errno. Once all instances
    are converted, vm_fault_t will become a distinct type.
    
    Ref- commit 1c8f422059ae ("mm: change return type to vm_fault_t")
    
    Previously vm_insert_page() returns err which driver
    mapped into VM_FAULT_* type. The new function
    vmf_insert_page() will replace this inefficiency by
    returning VM_FAULT_* type.
    
    vmf_error() is the newly introduce inline function
    in 4.17-rc6.
    
    Signed-off-by: Souptick Joarder <jrdr.linux at gmail.com>
    Reviewed-by: Matthew Wilcox <mawilcox at microsoft.com>
    Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
index d36c7bbe66db..8d02d1b7dcf5 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h
@@ -18,6 +18,7 @@
 #include <linux/time64.h>
 #include <linux/types.h>
 #include <linux/sizes.h>
+#include <linux/mm_types.h>
 
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
@@ -53,7 +54,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
 		struct drm_file *file);
 
 int etnaviv_gem_mmap(struct file *filp, struct vm_area_struct *vma);
-int etnaviv_gem_fault(struct vm_fault *vmf);
+vm_fault_t etnaviv_gem_fault(struct vm_fault *vmf);
 int etnaviv_gem_mmap_offset(struct drm_gem_object *obj, u64 *offset);
 struct sg_table *etnaviv_gem_prime_get_sg_table(struct drm_gem_object *obj);
 void *etnaviv_gem_prime_vmap(struct drm_gem_object *obj);
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
index 209ef1274b80..1fa74226db91 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
@@ -169,31 +169,30 @@ int etnaviv_gem_mmap(struct file *filp, struct vm_area_struct *vma)
 	return obj->ops->mmap(obj, vma);
 }
 
-int etnaviv_gem_fault(struct vm_fault *vmf)
+vm_fault_t etnaviv_gem_fault(struct vm_fault *vmf)
 {
 	struct vm_area_struct *vma = vmf->vma;
 	struct drm_gem_object *obj = vma->vm_private_data;
 	struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
 	struct page **pages, *page;
 	pgoff_t pgoff;
-	int ret;
+	int err;
 
 	/*
 	 * Make sure we don't parallel update on a fault, nor move or remove
-	 * something from beneath our feet.  Note that vm_insert_page() is
+	 * something from beneath our feet.  Note that vmf_insert_page() is
 	 * specifically coded to take care of this, so we don't have to.
 	 */
-	ret = mutex_lock_interruptible(&etnaviv_obj->lock);
-	if (ret)
-		goto out;
-
+	err = mutex_lock_interruptible(&etnaviv_obj->lock);
+	if (err)
+		return VM_FAULT_NOPAGE;
 	/* make sure we have pages attached now */
 	pages = etnaviv_gem_get_pages(etnaviv_obj);
 	mutex_unlock(&etnaviv_obj->lock);
 
 	if (IS_ERR(pages)) {
-		ret = PTR_ERR(pages);
-		goto out;
+		err = PTR_ERR(pages);
+		return vmf_error(err);
 	}
 
 	/* We don't use vmf->pgoff since that has the fake offset: */
@@ -204,25 +203,7 @@ int etnaviv_gem_fault(struct vm_fault *vmf)
 	VERB("Inserting %p pfn %lx, pa %lx", (void *)vmf->address,
 	     page_to_pfn(page), page_to_pfn(page) << PAGE_SHIFT);
 
-	ret = vm_insert_page(vma, vmf->address, page);
-
-out:
-	switch (ret) {
-	case -EAGAIN:
-	case 0:
-	case -ERESTARTSYS:
-	case -EINTR:
-	case -EBUSY:
-		/*
-		 * EBUSY is ok: this just means that another thread
-		 * already did the job.
-		 */
-		return VM_FAULT_NOPAGE;
-	case -ENOMEM:
-		return VM_FAULT_OOM;
-	default:
-		return VM_FAULT_SIGBUS;
-	}
+	return vmf_insert_page(vma, vmf->address, page);
 }
 
 int etnaviv_gem_mmap_offset(struct drm_gem_object *obj, u64 *offset)
commit a0780bb1df60f00e4573db7bd53e7039e9eee1cb
Author: Lucas Stach <l.stach at pengutronix.de>
Date:   Fri May 25 16:51:25 2018 +0200

    drm/etnaviv: protect sched job submission with fence mutex
    
    The documentation of drm_sched_job_init and drm_sched_entity_push_job has
    been clarified. Both functions should be called under a shared lock, to
    avoid jobs getting pushed into the scheduler queue in a different order
    than their sched_fence seqnos, which will confuse checks that are looking
    at the seqnos to infer information about completion order.
    
    Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
index 46ecd3e66ac9..983e67f19e45 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
@@ -388,9 +388,9 @@ static void submit_cleanup(struct kref *kref)
 		dma_fence_put(submit->in_fence);
 	if (submit->out_fence) {
 		/* first remove from IDR, so fence can not be found anymore */
-		mutex_lock(&submit->gpu->fence_idr_lock);
+		mutex_lock(&submit->gpu->fence_lock);
 		idr_remove(&submit->gpu->fence_idr, submit->out_fence_id);
-		mutex_unlock(&submit->gpu->fence_idr_lock);
+		mutex_unlock(&submit->gpu->fence_lock);
 		dma_fence_put(submit->out_fence);
 	}
 	kfree(submit->pmrs);
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index 686f6552db48..18c2224ba0b8 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -1733,7 +1733,7 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
 
 	gpu->dev = &pdev->dev;
 	mutex_init(&gpu->lock);
-	mutex_init(&gpu->fence_idr_lock);
+	mutex_init(&gpu->fence_lock);
 
 	/* Map registers: */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
index 90f17ff7888e..9a75a6937268 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
@@ -118,7 +118,7 @@ struct etnaviv_gpu {
 	u32 idle_mask;
 
 	/* Fencing support */
-	struct mutex fence_idr_lock;
+	struct mutex fence_lock;
 	struct idr fence_idr;
 	u32 next_fence;
 	u32 active_fence;
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
index 50d6b88cb7aa..b267d9c4d91c 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
@@ -140,28 +140,38 @@ static const struct drm_sched_backend_ops etnaviv_sched_ops = {
 int etnaviv_sched_push_job(struct drm_sched_entity *sched_entity,
 			   struct etnaviv_gem_submit *submit)
 {
-	int ret;
+	int ret = 0;
+
+	/*
+	 * Hold the fence lock across the whole operation to avoid jobs being
+	 * pushed out of order with regard to their sched fence seqnos as
+	 * allocated in drm_sched_job_init.
+	 */
+	mutex_lock(&submit->gpu->fence_lock);
 
 	ret = drm_sched_job_init(&submit->sched_job, &submit->gpu->sched,
 				 sched_entity, submit->cmdbuf.ctx);
 	if (ret)
-		return ret;
+		goto out_unlock;
 
 	submit->out_fence = dma_fence_get(&submit->sched_job.s_fence->finished);
-	mutex_lock(&submit->gpu->fence_idr_lock);
 	submit->out_fence_id = idr_alloc_cyclic(&submit->gpu->fence_idr,
 						submit->out_fence, 0,
 						INT_MAX, GFP_KERNEL);
-	mutex_unlock(&submit->gpu->fence_idr_lock);
-	if (submit->out_fence_id < 0)
-		return -ENOMEM;
+	if (submit->out_fence_id < 0) {
+		ret = -ENOMEM;
+		goto out_unlock;
+	}
 
 	/* the scheduler holds on to the job now */
 	kref_get(&submit->refcount);
 
 	drm_sched_entity_push_job(&submit->sched_job, sched_entity);
 
-	return 0;
+out_unlock:
+	mutex_unlock(&submit->gpu->fence_lock);
+
+	return ret;
 }
 
 int etnaviv_sched_init(struct etnaviv_gpu *gpu)
commit 6ae9c84ff249f2756086e71405375fd06124cf1f
Author: Philipp Zabel <p.zabel at pengutronix.de>
Date:   Tue May 15 16:09:15 2018 +0200

    drm/etnaviv: mmuv2: use memset32 to init scratch page
    
    Replace the open-coded scratch page initialization loop with memset32
    
    Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
    Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c
index 71fbc1f96cb6..f1c88d8ad5ba 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c
@@ -119,8 +119,7 @@ static size_t etnaviv_iommuv2_unmap(struct etnaviv_iommu_domain *domain,
 
 static int etnaviv_iommuv2_init(struct etnaviv_iommuv2_domain *etnaviv_domain)
 {
-	u32 *p;
-	int ret, i;
+	int ret;
 
 	/* allocate scratch page */
 	etnaviv_domain->base.bad_page_cpu =
@@ -131,9 +130,9 @@ static int etnaviv_iommuv2_init(struct etnaviv_iommuv2_domain *etnaviv_domain)
 		ret = -ENOMEM;
 		goto fail_mem;
 	}
-	p = etnaviv_domain->base.bad_page_cpu;
-	for (i = 0; i < SZ_4K / 4; i++)
-		*p++ = 0xdead55aa;
+
+	memset32(etnaviv_domain->base.bad_page_cpu, 0xdead55aa,
+		 SZ_4K / sizeof(u32));
 
 	etnaviv_domain->pta_cpu = dma_alloc_wc(etnaviv_domain->base.dev,
 					       SZ_4K, &etnaviv_domain->pta_dma,
commit 16196776185cb19bb8c2318ebd1dbbefb5350d6a
Author: Harry Wentland <harry.wentland at amd.com>
Date:   Thu Aug 2 15:32:01 2018 -0400

    drm/amd/display: Only require EDID read for HDMI and DVI
    
    [Why]
    VGA sometimes has trouble retrieving the EDID on very long cables, KVM
    switches, or old displays.
    
    [How]
    Only require EDID read for HDMI and DVI and exempt other types (DP,
    VGA). We currently don't support VGA but if anyone adds support in the
    future this might get overlooked.
    
    Signed-off-by: Harry Wentland <harry.wentland at amd.com>
    Suggested-by: Michel Dänzer <michel at daenzer.net>
    Acked-by: Alex Deucher <alexander.deucher at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 31cebb645fca..89d7c1e99168 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -753,7 +753,8 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
 			 * even if we have no EDID in order to go to
 			 * fail-safe mode
 			 */
-			if (!dc_is_dp_signal(link->connector_signal))
+			if (dc_is_hdmi_signal(link->connector_signal) ||
+			    dc_is_dvi_signal(link->connector_signal))
 				return false;
 		default:
 			break;
commit 01dc285d5cd89b77686d8baef8482c58d7dc3ead
Author: Harry Wentland <harry.wentland at amd.com>
Date:   Wed Aug 1 10:48:23 2018 -0400

    drm/amd/display: Report non-DP display as disconnected without EDID
    
    [Why]
    Some boards seem to have a problem where HPD is high on HDMI even though
    no display is connected. We don't want to report these as connected. DP
    spec still requires us to report DP displays as connected when HPD is
    high but we can't read the EDID in order to go to fail-safe mode.
    
    [How]
    If connector_signal is not DP abort detection if we can't retrieve the
    EDID.
    
    v2: Add Bugzilla and stable
    
    Bugzilla: https://bugs.freedesktop.org/107390
    Bugzilla: https://bugs.freedesktop.org/106846
    Cc: stable at vger.kernel.org
    Signed-off-by: Harry Wentland <harry.wentland at amd.com>
    Acked-by: Alex Deucher <alexander.deucher at amd.com>
    Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 966d2f9c8c99..31cebb645fca 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -744,6 +744,17 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
 			break;
 		case EDID_NO_RESPONSE:
 			DC_LOG_ERROR("No EDID read.\n");
+
+			/*
+			 * Abort detection for non-DP connectors if we have
+			 * no EDID
+			 *
+			 * DP needs to report as connected if HDP is high
+			 * even if we have no EDID in order to go to
+			 * fail-safe mode
+			 */
+			if (!dc_is_dp_signal(link->connector_signal))
+				return false;
 		default:
 			break;
 		}
commit 2d87e6c1b99c402360fdfe19ce4f579ab2f96adf
Author: Philipp Zabel <p.zabel at pengutronix.de>
Date:   Thu Jun 21 21:13:38 2018 +0200

    gpu: ipu-v3: default to id 0 on missing OF alias
    
    This is better than storing -ENODEV in the id number. This fixes SoCs
    with only one IPU that don't specify an IPU alias in the device tree.
    
    Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>

diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c
index 48685cddbad1..c73bd003f845 100644
--- a/drivers/gpu/ipu-v3/ipu-common.c
+++ b/drivers/gpu/ipu-v3/ipu-common.c
@@ -1401,6 +1401,8 @@ static int ipu_probe(struct platform_device *pdev)
 		return -ENODEV;
 
 	ipu->id = of_alias_get_id(np, "ipu");
+	if (ipu->id < 0)
+		ipu->id = 0;
 
 	if (of_device_is_compatible(np, "fsl,imx6qp-ipu") &&
 	    IS_ENABLED(CONFIG_DRM)) {
commit 9f0ba3d92fe63fa72f88238d9dde47a38a7d8f40
Author: Steve Longerbeam <slongerbeam at gmail.com>
Date:   Wed Aug 1 12:12:17 2018 -0700

    gpu: ipu-v3: Fix U/V offset macros for planar 4:2:0
    
    The U and V offset macros for planar 4:2:0 (U_OFFSET, V_OFFSET, and
    UV_OFFSET), are not correct. The height component to the offset was
    calculated as:
    
    (pix->width * y / 4)
    
    But this does not produce correct offsets for odd values of y (luma
    line #). The luma line # must be decimated by two to produce the
    correct U/V line #, so the correct formula is:
    
    (pix->width * (y / 2) / 2)
    
    Signed-off-by: Steve Longerbeam <steve_longerbeam at mentor.com>
    Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>

diff --git a/drivers/gpu/ipu-v3/ipu-cpmem.c b/drivers/gpu/ipu-v3/ipu-cpmem.c
index 9f2d9ec42add..e68e4734f052 100644
--- a/drivers/gpu/ipu-v3/ipu-cpmem.c
+++ b/drivers/gpu/ipu-v3/ipu-cpmem.c
@@ -530,17 +530,17 @@ static const struct ipu_rgb def_bgra_16 = {
 
 #define Y_OFFSET(pix, x, y)	((x) + pix->width * (y))
 #define U_OFFSET(pix, x, y)	((pix->width * pix->height) +		\
-				 (pix->width * (y) / 4) + (x) / 2)
+				 (pix->width * ((y) / 2) / 2) + (x) / 2)
 #define V_OFFSET(pix, x, y)	((pix->width * pix->height) +		\
 				 (pix->width * pix->height / 4) +	\
-				 (pix->width * (y) / 4) + (x) / 2)
+				 (pix->width * ((y) / 2) / 2) + (x) / 2)
 #define U2_OFFSET(pix, x, y)	((pix->width * pix->height) +		\
 				 (pix->width * (y) / 2) + (x) / 2)
 #define V2_OFFSET(pix, x, y)	((pix->width * pix->height) +		\
 				 (pix->width * pix->height / 2) +	\
 				 (pix->width * (y) / 2) + (x) / 2)
 #define UV_OFFSET(pix, x, y)	((pix->width * pix->height) +	\
-				 (pix->width * (y) / 2) + (x))
+				 (pix->width * ((y) / 2)) + (x))
 #define UV2_OFFSET(pix, x, y)	((pix->width * pix->height) +	\
 				 (pix->width * y) + (x))
 
commit 5c41bb6071257ba668a2b8933a8654e69aea1cee
Author: Philipp Zabel <p.zabel at pengutronix.de>
Date:   Thu Aug 2 10:40:33 2018 +0200

    gpu: ipu-v3: add support for XRGB32 and XBGR32 V4L2 pixel formats
    
    These should be used instead of the ill-defined deprecated RGB32 and
    BGR32 V4L2 pixel formats.
    
    Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>

diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c
index 48685cddbad1..66e9405faedc 100644
--- a/drivers/gpu/ipu-v3/ipu-common.c
+++ b/drivers/gpu/ipu-v3/ipu-common.c
@@ -122,6 +122,8 @@ enum ipu_color_space ipu_pixelformat_to_colorspace(u32 pixelformat)
 	case V4L2_PIX_FMT_NV16:
 	case V4L2_PIX_FMT_NV61:
 		return IPUV3_COLORSPACE_YUV;
+	case V4L2_PIX_FMT_XRGB32:
+	case V4L2_PIX_FMT_XBGR32:
 	case V4L2_PIX_FMT_RGB32:
 	case V4L2_PIX_FMT_BGR32:
 	case V4L2_PIX_FMT_RGB24:
@@ -190,6 +192,8 @@ int ipu_stride_to_bytes(u32 pixel_stride, u32 pixelformat)
 		return (24 * pixel_stride) >> 3;
 	case V4L2_PIX_FMT_BGR32:
 	case V4L2_PIX_FMT_RGB32:
+	case V4L2_PIX_FMT_XBGR32:
+	case V4L2_PIX_FMT_XRGB32:
 		return (32 * pixel_stride) >> 3;
 	default:
 		break;
diff --git a/drivers/gpu/ipu-v3/ipu-cpmem.c b/drivers/gpu/ipu-v3/ipu-cpmem.c
index 125721a7f8b6..0f1155ea0fbd 100644
--- a/drivers/gpu/ipu-v3/ipu-cpmem.c
+++ b/drivers/gpu/ipu-v3/ipu-cpmem.c
@@ -188,6 +188,12 @@ static int v4l2_pix_fmt_to_drm_fourcc(u32 pixelformat)
 	case V4L2_PIX_FMT_RGB32:
 		/* R G B A <=> [32:0] A:B:G:R */
 		return DRM_FORMAT_XBGR8888;
+	case V4L2_PIX_FMT_XBGR32:
+		/* B G R X <=> [32:0] X:R:G:B */
+		return DRM_FORMAT_XRGB8888;
+	case V4L2_PIX_FMT_XRGB32:
+		/* X R G B <=> [32:0] B:G:R:X */
+		return DRM_FORMAT_BGRX8888;
 	case V4L2_PIX_FMT_UYVY:
 		return DRM_FORMAT_UYVY;
 	case V4L2_PIX_FMT_YUYV:
@@ -787,6 +793,8 @@ int ipu_cpmem_set_image(struct ipuv3_channel *ch, struct ipu_image *image)
 		break;
 	case V4L2_PIX_FMT_RGB32:
 	case V4L2_PIX_FMT_BGR32:
+	case V4L2_PIX_FMT_XRGB32:
+	case V4L2_PIX_FMT_XBGR32:
 		offset = image->rect.left * 4 +
 			image->rect.top * pix->bytesperline;
 		break;
diff --git a/drivers/gpu/ipu-v3/ipu-image-convert.c b/drivers/gpu/ipu-v3/ipu-image-convert.c
index 524a717ab28e..f4081962784c 100644
--- a/drivers/gpu/ipu-v3/ipu-image-convert.c
+++ b/drivers/gpu/ipu-v3/ipu-image-convert.c
@@ -227,6 +227,12 @@ static const struct ipu_image_pixfmt image_convert_formats[] = {
 		.fourcc	= V4L2_PIX_FMT_BGR32,
 		.bpp    = 32,
 	}, {
+		.fourcc	= V4L2_PIX_FMT_XRGB32,
+		.bpp    = 32,
+	}, {
+		.fourcc	= V4L2_PIX_FMT_XBGR32,
+		.bpp    = 32,
+	}, {
 		.fourcc	= V4L2_PIX_FMT_YUYV,
 		.bpp    = 16,
 		.uv_width_dec = 2,
commit 6c1187aaa2912fad40119140286160cfd9f4ac2f
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Thu Aug 2 10:25:19 2018 +0100

    drm/i2c: tda998x: move tda998x_set_config() into tda998x_create()
    
    Move the non-DT configuration of the TDA998x into tda998x_create()
    so that we do all setup in one place.
    
    Tested-by: Peter Rosin <peda at axentia.se>
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index f9a9fb6b97d0..c35b52a83001 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1630,6 +1630,25 @@ static int tda998x_get_audio_ports(struct tda998x_priv *priv,
 	return 0;
 }
 
+static void tda998x_set_config(struct tda998x_priv *priv,
+			       const struct tda998x_encoder_params *p)
+{
+	priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(p->swap_a) |
+			    (p->mirr_a ? VIP_CNTRL_0_MIRR_A : 0) |
+			    VIP_CNTRL_0_SWAP_B(p->swap_b) |
+			    (p->mirr_b ? VIP_CNTRL_0_MIRR_B : 0);
+	priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(p->swap_c) |
+			    (p->mirr_c ? VIP_CNTRL_1_MIRR_C : 0) |
+			    VIP_CNTRL_1_SWAP_D(p->swap_d) |
+			    (p->mirr_d ? VIP_CNTRL_1_MIRR_D : 0);
+	priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(p->swap_e) |
+			    (p->mirr_e ? VIP_CNTRL_2_MIRR_E : 0) |
+			    VIP_CNTRL_2_SWAP_F(p->swap_f) |
+			    (p->mirr_f ? VIP_CNTRL_2_MIRR_F : 0);
+
+	priv->audio_params = p->audio_params;
+}
+
 static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
 {
 	struct device_node *np = client->dev.of_node;
@@ -1781,23 +1800,24 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv)
 	/* enable EDID read irq: */
 	reg_set(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD);
 
-	if (!np)
-		return 0;		/* non-DT */
+	if (np) {
+		/* get the device tree parameters */
+		ret = of_property_read_u32(np, "video-ports", &video);
+		if (ret == 0) {
+			priv->vip_cntrl_0 = video >> 16;
+			priv->vip_cntrl_1 = video >> 8;
+			priv->vip_cntrl_2 = video;
+		}
 
-	/* get the device tree parameters */
-	ret = of_property_read_u32(np, "video-ports", &video);
-	if (ret == 0) {
-		priv->vip_cntrl_0 = video >> 16;
-		priv->vip_cntrl_1 = video >> 8;
-		priv->vip_cntrl_2 = video;
-	}
+		ret = tda998x_get_audio_ports(priv, np);
+		if (ret)
+			goto fail;
 
-	ret = tda998x_get_audio_ports(priv, np);
-	if (ret)
-		goto fail;
-
-	if (priv->audio_port[0].format != AFMT_UNUSED)
-		tda998x_audio_codec_init(priv, &client->dev);
+		if (priv->audio_port[0].format != AFMT_UNUSED)
+			tda998x_audio_codec_init(priv, &client->dev);
+	} else if (client->dev.platform_data) {
+		tda998x_set_config(priv, client->dev.platform_data);
+	}
 
 	return 0;
 
@@ -1843,28 +1863,8 @@ static const struct drm_encoder_funcs tda998x_encoder_funcs = {
 	.destroy = tda998x_encoder_destroy,
 };
 
-static void tda998x_set_config(struct tda998x_priv *priv,
-			       const struct tda998x_encoder_params *p)
-{
-	priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(p->swap_a) |
-			    (p->mirr_a ? VIP_CNTRL_0_MIRR_A : 0) |
-			    VIP_CNTRL_0_SWAP_B(p->swap_b) |
-			    (p->mirr_b ? VIP_CNTRL_0_MIRR_B : 0);
-	priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(p->swap_c) |
-			    (p->mirr_c ? VIP_CNTRL_1_MIRR_C : 0) |
-			    VIP_CNTRL_1_SWAP_D(p->swap_d) |
-			    (p->mirr_d ? VIP_CNTRL_1_MIRR_D : 0);
-	priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(p->swap_e) |
-			    (p->mirr_e ? VIP_CNTRL_2_MIRR_E : 0) |
-			    VIP_CNTRL_2_SWAP_F(p->swap_f) |
-			    (p->mirr_f ? VIP_CNTRL_2_MIRR_F : 0);
-
-	priv->audio_params = p->audio_params;
-}
-
 static int tda998x_bind(struct device *dev, struct device *master, void *data)
 {
-	struct tda998x_encoder_params *params = dev->platform_data;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct drm_device *drm = data;
 	struct tda998x_priv *priv;
@@ -1892,9 +1892,6 @@ static int tda998x_bind(struct device *dev, struct device *master, void *data)
 	if (ret)
 		return ret;
 
-	if (!dev->of_node && params)
-		tda998x_set_config(priv, params);
-
 	drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs);
 	ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs,
 			       DRM_MODE_ENCODER_TMDS, NULL);
commit 2c6e758332a4fdf0d2b1c76adba10961afdabc8a
Author: Peter Rosin <peda at axentia.se>
Date:   Thu Aug 2 10:25:19 2018 +0100

    drm/i2c: tda998x: split tda998x_encoder_dpms into enable/disable
    
    This fits better with the drm_bridge callbacks for when this
    driver becomes a drm_bridge.
    
    Suggested-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
    Signed-off-by: Peter Rosin <peda at axentia.se>
    [edited by rmk to just split the tda998x_encoder_dpms() function
     and restore the double-disable protection we originally had,
     preserving original behaviour.]
    Tested-by: Peter Rosin <peda at axentia.se>
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index c39f7c36ba24..f9a9fb6b97d0 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -1308,18 +1308,9 @@ static int tda998x_connector_init(struct tda998x_priv *priv,
 
 /* DRM encoder functions */
 
-static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode)
+static void tda998x_enable(struct tda998x_priv *priv)
 {
-	struct tda998x_priv *priv = enc_to_tda998x_priv(encoder);
-	bool on;
-
-	/* we only care about on or off: */
-	on = mode == DRM_MODE_DPMS_ON;
-
-	if (on == priv->is_on)
-		return;
-
-	if (on) {
+	if (!priv->is_on) {
 		/* enable video ports, audio will be enabled later */
 		reg_write(priv, REG_ENA_VP_0, 0xff);
 		reg_write(priv, REG_ENA_VP_1, 0xff);
@@ -1330,7 +1321,12 @@ static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode)
 		reg_write(priv, REG_VIP_CNTRL_2, priv->vip_cntrl_2);
 
 		priv->is_on = true;
-	} else {
+	}
+}
+
+static void tda998x_disable(struct tda998x_priv *priv)
+{
+	if (priv->is_on) {
 		/* disable video ports */
 		reg_write(priv, REG_ENA_VP_0, 0x00);
 		reg_write(priv, REG_ENA_VP_1, 0x00);
@@ -1340,6 +1336,23 @@ static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode)
 	}
 }
 
+static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct tda998x_priv *priv = enc_to_tda998x_priv(encoder);
+	bool on;
+
+	/* we only care about on or off: */
+	on = mode == DRM_MODE_DPMS_ON;
+
+	if (on == priv->is_on)
+		return;
+
+	if (on)
+		tda998x_enable(priv);
+	else
+		tda998x_disable(priv);
+}
+
 static void
 tda998x_encoder_mode_set(struct drm_encoder *encoder,
 			 struct drm_display_mode *mode,
commit b1eb4f844f8c35e252eebfacacc438644d9f9ba8
Author: Peter Rosin <peda at axentia.se>
Date:   Thu Aug 2 10:25:19 2018 +0100

    drm/i2c: tda998x: find the drm_device via the drm_connector
    
    This prepares for being a drm_bridge which will not register the
    encoder. That makes the connector the better choice.
    
    Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
    Signed-off-by: Peter Rosin <peda at axentia.se>
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 0038c976536a..c39f7c36ba24 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -762,7 +762,7 @@ static void tda998x_detect_work(struct work_struct *work)
 {
 	struct tda998x_priv *priv =
 		container_of(work, struct tda998x_priv, detect_work);
-	struct drm_device *dev = priv->encoder.dev;
+	struct drm_device *dev = priv->connector.dev;
 
 	if (dev)
 		drm_kms_helper_hotplug_event(dev);
commit df36b2fb8390d98453fff1aae3927095fe9ff36c
Author: Huang Rui <ray.huang at amd.com>
Date:   Wed Aug 1 13:49:33 2018 +0800

    drm/ttm: clean up non-x86 definitions on ttm_tt
    
    All non-x86 definitions are moved to ttm_set_memory header, so remove it from
    ttm_tt.c.
    
    Reviewed-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Huang Rui <ray.huang at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index a1e543972ca7..e3a0691582ff 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -38,9 +38,7 @@
 #include <drm/drm_cache.h>
 #include <drm/ttm/ttm_bo_driver.h>
 #include <drm/ttm/ttm_page_alloc.h>
-#ifdef CONFIG_X86
-#include <asm/set_memory.h>
-#endif
+#include <drm/ttm/ttm_set_memory.h>
 
 /**
  * Allocates a ttm structure for the given BO.
@@ -115,10 +113,9 @@ static int ttm_sg_tt_alloc_page_directory(struct ttm_dma_tt *ttm)
 	return 0;
 }
 
-#ifdef CONFIG_X86
-static inline int ttm_tt_set_page_caching(struct page *p,
-					  enum ttm_caching_state c_old,
-					  enum ttm_caching_state c_new)
+static int ttm_tt_set_page_caching(struct page *p,
+				   enum ttm_caching_state c_old,
+				   enum ttm_caching_state c_new)
 {
 	int ret = 0;
 
@@ -129,26 +126,18 @@ static inline int ttm_tt_set_page_caching(struct page *p,
 		/* p isn't in the default caching state, set it to
 		 * writeback first to free its current memtype. */
 
-		ret = set_pages_wb(p, 1);
+		ret = ttm_set_pages_wb(p, 1);
 		if (ret)
 			return ret;
 	}
 
 	if (c_new == tt_wc)
-		ret = set_memory_wc((unsigned long) page_address(p), 1);
+		ret = ttm_set_pages_wc(p, 1);
 	else if (c_new == tt_uncached)
-		ret = set_pages_uc(p, 1);
+		ret = ttm_set_pages_uc(p, 1);
 
 	return ret;
 }
-#else /* CONFIG_X86 */
-static inline int ttm_tt_set_page_caching(struct page *p,
-					  enum ttm_caching_state c_old,
-					  enum ttm_caching_state c_new)
-{
-	return 0;
-}
-#endif /* CONFIG_X86 */
 
 /*
  * Change caching policy for the linear kernel map
commit dceb219fc60766006bfe8e53afa62816b94fcb11
Author: Huang Rui <ray.huang at amd.com>
Date:   Wed Aug 1 13:49:32 2018 +0800

    drm/ttm: Add ttm_set_pages_wc and ttm_set_pages_uc helper
    
    These two helpers will be used on set page caching.
    
    Reviewed-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Huang Rui <ray.huang at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/include/drm/ttm/ttm_set_memory.h b/include/drm/ttm/ttm_set_memory.h
index a70723cf208b..7c492b49e38c 100644
--- a/include/drm/ttm/ttm_set_memory.h
+++ b/include/drm/ttm/ttm_set_memory.h
@@ -57,6 +57,18 @@ static inline int ttm_set_pages_wb(struct page *page, int numpages)
 	return set_pages_wb(page, numpages);
 }
 
+static inline int ttm_set_pages_wc(struct page *page, int numpages)
+{
+	unsigned long addr = (unsigned long)page_address(page);
+
+	return set_memory_wc(addr, numpages);
+}
+
+static inline int ttm_set_pages_uc(struct page *page, int numpages)
+{
+	return set_pages_uc(page, numpages);
+}
+
 #else /* for CONFIG_X86 */
 
 #if IS_ENABLED(CONFIG_AGP)
@@ -123,6 +135,16 @@ static inline int ttm_set_pages_wb(struct page *page, int numpages)
 
 #endif /* for CONFIG_AGP */
 
+static inline int ttm_set_pages_wc(struct page *page, int numpages)
+{
+	return 0;
+}
+
+static inline int ttm_set_pages_uc(struct page *page, int numpages)
+{
+	return 0;
+}
+
 #endif /* for CONFIG_X86 */
 
 #endif
commit fe710322b81343601ca1759a9f3d4b694ed72fca
Author: Huang Rui <ray.huang at amd.com>
Date:   Wed Aug 1 13:49:31 2018 +0800

    drm/ttm: fix missed conversion of set_pages_array_uc
    
    This patch fixed the error when do not configure CONFIG_X86, otherwise, below
    error will be encountered.
    
    All errors (new ones prefixed by >>):
    
       drivers/gpu/drm/ttm/ttm_page_alloc_dma.c: In function 'ttm_set_pages_caching':
    >> drivers/gpu/drm/ttm/ttm_page_alloc_dma.c:272:7: error: implicit declaration of function 'set_pages_array_uc'; did you mean
    +'ttm_set_pages_array_uc'? [-Werror=implicit-function-declaration]
          r = set_pages_array_uc(pages, cpages);
              ^~~~~~~~~~~~~~~~~~
              ttm_set_pages_array_uc
       cc1: some warnings being treated as errors
    
    Reported-by: kbuild test robot <lkp at intel.com>
    Reviewed-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Huang Rui <ray.huang at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
index 8304917294a2..507be7ac1165 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
@@ -269,7 +269,7 @@ static int ttm_set_pages_caching(struct dma_pool *pool,
 	int r = 0;
 	/* Set page caching */
 	if (pool->type & IS_UC) {
-		r = set_pages_array_uc(pages, cpages);
+		r = ttm_set_pages_array_uc(pages, cpages);
 		if (r)
 			pr_err("%s: Failed to set %d pages to uc!\n",
 			       pool->dev_name, cpages);
commit 64f2cafc3da77da7b176f2cdc3eb3fdb031c639f
Author: Souptick Joarder <jrdr.linux at gmail.com>
Date:   Wed Aug 1 00:58:33 2018 +0530

    drm/imx: Convert drm_atomic_helper_suspend/resume()
    
    convert drm_atomic_helper_suspend/resume() to use
    drm_mode_config_helper_suspend/resume().
    
    with this conversion, the remaining member of struct
    imx_drm_device, state, will be no more useful and it
    could be removed forever.
    
    Signed-off-by: Souptick Joarder <jrdr.linux at gmail.com>
    Signed-off-by: Ajit Negi <ajitn.linux at gmail.com>
    [p.zabel at pengutronix.de: rebased onto drm-next, updated commit message]
    Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>

diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index f0122afcf2a8..5ea0c82f9957 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -35,11 +35,6 @@
 
 #define MAX_CRTC	4
 
-struct imx_drm_device {
-	struct drm_device			*drm;
-	struct drm_atomic_state			*state;
-};
-
 #if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
 static int legacyfb_depth = 16;
 module_param(legacyfb_depth, int, 0444);
@@ -218,22 +213,12 @@ static int compare_of(struct device *dev, void *data)
 static int imx_drm_bind(struct device *dev)
 {
 	struct drm_device *drm;
-	struct imx_drm_device *imxdrm;
 	int ret;
 
 	drm = drm_dev_alloc(&imx_drm_driver, dev);
 	if (IS_ERR(drm))
 		return PTR_ERR(drm);
 
-	imxdrm = devm_kzalloc(dev, sizeof(*imxdrm), GFP_KERNEL);
-	if (!imxdrm) {
-		ret = -ENOMEM;
-		goto err_put;
-	}
-
-	imxdrm->drm = drm;
-	drm->dev_private = imxdrm;
-
 	/*
 	 * enable drm irq mode.
 	 * - with irq_enabled = true, we can use the vblank feature.
@@ -305,7 +290,6 @@ err_unbind:
 	component_unbind_all(drm->dev, drm);
 err_kms:
 	drm_mode_config_cleanup(drm);
-err_put:
 	drm_dev_put(drm);
 
 	return ret;
@@ -354,37 +338,15 @@ static int imx_drm_platform_remove(struct platform_device *pdev)
 static int imx_drm_suspend(struct device *dev)
 {
 	struct drm_device *drm_dev = dev_get_drvdata(dev);
-	struct imx_drm_device *imxdrm;
-
-	/* The drm_dev is NULL before .load hook is called */
-	if (drm_dev == NULL)
-		return 0;
-
-	drm_kms_helper_poll_disable(drm_dev);
 
-	imxdrm = drm_dev->dev_private;
-	imxdrm->state = drm_atomic_helper_suspend(drm_dev);
-	if (IS_ERR(imxdrm->state)) {
-		drm_kms_helper_poll_enable(drm_dev);
-		return PTR_ERR(imxdrm->state);
-	}
-
-	return 0;
+	return drm_mode_config_helper_suspend(drm_dev);
 }
 
 static int imx_drm_resume(struct device *dev)
 {
 	struct drm_device *drm_dev = dev_get_drvdata(dev);
-	struct imx_drm_device *imx_drm;
 
-	if (drm_dev == NULL)
-		return 0;
-
-	imx_drm = drm_dev->dev_private;
-	drm_atomic_helper_resume(drm_dev, imx_drm->state);
-	drm_kms_helper_poll_enable(drm_dev);
-
-	return 0;
+	return drm_mode_config_helper_resume(drm_dev);
 }
 #endif
 
commit 15da09500a7053612e4ab049ff998e99a77a8df0
Merge: f8f15c34ac94 aa595c00bcf5
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Aug 1 09:02:12 2018 +1000

    Merge branch 'drm-armada-devel' of git://git.armlinux.org.uk/~rmk/linux-arm into drm-next
    
    This set of changes migrates Armada DRM from legacy modeset to atomic
    modeset.  This is everything from the "Transition Armada DRM planes to
    atomic state" and "Finish Armada DRM transition to atomic modeset"
    patch sets as posted on drm-devel, excluding the "Finish Armada DRM DT
    support" series.
    
    These series did not evoke any comments - if there are any, these can
    be addressed via follow up patches.
    
    Developed and tested on Dove Cubox with xf86-video-armada including the
    overlay plane, and also tested with the tools in libdrm.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20180730110543.GA30664@rmk-PC.armlinux.org.uk

commit f8f15c34ac94563eb169ce95e97c200a00c15c35
Merge: caca1ff0de62 a7663a793436
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Aug 1 08:52:15 2018 +1000

    Merge tag 'drm-msm-next-2018-07-30' of git://people.freedesktop.org/~robclark/linux into drm-next
    
    A bit larger this time around, due to introduction of "dpu1" support
    for the display controller in sdm845 and beyond.  This has been on
    list and undergoing refactoring since Feb (going from ~110kloc to
    ~30kloc), and all my review complaints have been addressed, so I'd be
    happy to see this upstream so further feature work can procede on top
    of upstream.
    
    Also includes the gpu coredump support, which should be useful for
    debugging gpu crashes.  And various other misc fixes and such.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGv-8y3zguY0Mj1vh=o+vrv_bJ8AwZ96wBXYPvMeQT2XcA@mail.gmail.com

commit ddf74e79a54070f277ae520722d3bab7f7a6c67a
Author: Gustavo A. R. Silva <gustavo at embeddedor.com>
Date:   Mon Jul 23 11:32:32 2018 -0500

    drm/amdgpu/pm: Fix potential Spectre v1
    
    idx can be indirectly controlled by user-space, hence leading to a
    potential exploitation of the Spectre variant 1 vulnerability.
    
    This issue was detected with the help of Smatch:
    
    drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c:408 amdgpu_set_pp_force_state()
    warn: potential spectre issue 'data.states'
    
    Fix this by sanitizing idx before using it to index data.states
    
    Notice that given that speculation windows are large, the policy is
    to kill the speculation on the first load and not worry if it can be
    completed with a dependent load/store [1].
    
    [1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2
    
    Cc: stable at vger.kernel.org
    Signed-off-by: Gustavo A. R. Silva <gustavo at embeddedor.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index 23fc1d32b937..8f98629fbe59 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -31,7 +31,7 @@
 #include <linux/power_supply.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
-
+#include <linux/nospec.h>
 
 static int amdgpu_debugfs_pm_init(struct amdgpu_device *adev);
 
@@ -403,6 +403,7 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev,
 			count = -EINVAL;
 			goto fail;
 		}
+		idx = array_index_nospec(idx, ARRAY_SIZE(data.states));
 
 		amdgpu_dpm_get_pp_num_states(adev, &data);
 		state = data.states[idx];
commit 7ac7aebe85d3b3b57a58efefcdde2bd5d398550d
Author: Colin Ian King <colin.king at canonical.com>
Date:   Tue Jul 31 11:42:54 2018 +0100

    drm/amd/display: add missing void parameter to dc_create_transfer_func
    
    Add a missing void parameter to function dc_create_transfer_func, fixes
    sparse warning:
    
    warning: non-ANSI function declaration of function 'dc_create_transfer_func'
    
    Signed-off-by: Colin Ian King <colin.king at canonical.com>
    Reviewed-by: Harry Wentland <harry.wentland at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
index 815dfb50089b..8fb3aefd195c 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
@@ -192,7 +192,7 @@ void dc_transfer_func_release(struct dc_transfer_func *tf)
 	kref_put(&tf->refcount, dc_transfer_func_free);
 }
 
-struct dc_transfer_func *dc_create_transfer_func()
+struct dc_transfer_func *dc_create_transfer_func(void)
 {
 	struct dc_transfer_func *tf = kvzalloc(sizeof(*tf), GFP_KERNEL);
 
commit 77605e43701578892e98a39383071f1a8503ff8f
Author: Thomas Zimmermann <tzimmermann at suse.de>
Date:   Tue Jul 31 08:16:59 2018 +0200

    drm/radeon: Replace ttm_bo_unref with ttm_bo_put
    
    The function ttm_bo_put releases a reference to a TTM buffer object. The
    function's name is more aligned to the Linux kernel convention of naming
    ref-counting function _get and _put.
    
    A call to ttm_bo_unref takes the address of the TTM BO object's pointer and
    clears the pointer's value to NULL. This is not necessary in most cases and
    sometimes even worked around by the calling code. A call to ttm_bo_put only
    releases the reference without clearing the pointer.
    
    The current behaviour of cleaning the pointer is kept in the calling code,
    but should be removed if not required in a later patch.
    
    Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
    Reviewed-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index 1a9d4f547024..ba2fd295697f 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -320,9 +320,8 @@ void radeon_bo_unref(struct radeon_bo **bo)
 		return;
 	rdev = (*bo)->rdev;
 	tbo = &((*bo)->tbo);
-	ttm_bo_unref(&tbo);
-	if (tbo == NULL)
-		*bo = NULL;
+	ttm_bo_put(tbo);
+	*bo = NULL;
 }
 
 int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset,
commit 269a8b6e342501fa221a398dd2730b7af7e94a5d
Author: Thomas Zimmermann <tzimmermann at suse.de>
Date:   Tue Jul 31 08:16:58 2018 +0200

    drm/radeon: Replace ttm_bo_reference with ttm_bo_get
    
    The function ttm_bo_get acquires a reference on a TTM buffer object. The
    function's name is more aligned to the Linux kernel convention of naming
    ref-counting function _get and _put.
    
    Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
    Reviewed-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index edbb4cd519fd..1a9d4f547024 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -307,7 +307,7 @@ struct radeon_bo *radeon_bo_ref(struct radeon_bo *bo)
 	if (bo == NULL)
 		return NULL;
 
-	ttm_bo_reference(&bo->tbo);
+	ttm_bo_get(&bo->tbo);
 	return bo;
 }
 
commit fea872b279c8cd9433a3c9bb91949643cf645e07
Author: Thomas Zimmermann <tzimmermann at suse.de>
Date:   Tue Jul 31 09:12:36 2018 +0200

    drm/amdgpu: Replace ttm_bo_unref with ttm_bo_put
    
    The function ttm_bo_put releases a reference to a TTM buffer object. The
    function's name is more aligned to the Linux kernel convention of naming
    ref-counting function _get and _put.
    
    A call to ttm_bo_unref takes the address of the TTM BO object's pointer and
    clears the pointer's value to NULL. This is not necessary in most cases and
    sometimes even worked around by the calling code. A call to ttm_bo_put only
    releases the reference without clearing the pointer.
    
    The current behaviour of cleaning the pointer is kept in the calling code,
    but should be removed if not required in a later patch.
    
    v2:
     * set prefix to drm/amdgpu
    
    Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
    Reviewed-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index f7ac9abf9cc1..b0e14a3d54ef 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -843,9 +843,8 @@ void amdgpu_bo_unref(struct amdgpu_bo **bo)
 		return;
 
 	tbo = &((*bo)->tbo);
-	ttm_bo_unref(&tbo);
-	if (tbo == NULL)
-		*bo = NULL;
+	ttm_bo_put(tbo);
+	*bo = NULL;
 }
 
 /**
commit 71d5ef11273b3dbdb57be7d2940dcee70007ae84
Author: Thomas Zimmermann <tzimmermann at suse.de>
Date:   Tue Jul 31 09:12:35 2018 +0200

    drm/amdgpu: Replace ttm_bo_reference with ttm_bo_get
    
    The function ttm_bo_get acquires a reference on a TTM buffer object. The
    function's name is more aligned to the Linux kernel convention of naming
    ref-counting function _get and _put.
    
    v2:
     * changed prefix to drm/amdgpu
    
    Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
    Reviewed-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 21bfa2d8039e..f7ac9abf9cc1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -825,7 +825,7 @@ struct amdgpu_bo *amdgpu_bo_ref(struct amdgpu_bo *bo)
 	if (bo == NULL)
 		return NULL;
 
-	ttm_bo_reference(&bo->tbo);
+	ttm_bo_get(&bo->tbo);
 	return bo;
 }
 
commit a875f58e237a0009c337dd140e4f92a7cffab7af
Author: Christian König <christian.koenig at amd.com>
Date:   Mon Jul 30 11:40:06 2018 +0200

    drm/scheduler: stop setting rq to NULL
    
    We removed the redundancy of having an extra scheduler field, so we
    can't set the rq to NULL any more or otherwise won't know which
    scheduler to use for the cleanup.
    
    Just remove the entity from the scheduling list instead.
    
    Signed-off-by: Christian König <christian.koenig at amd.com>
    Acked-by: Nayan Deshmukh <nayan26deshmukh at gmail.com>
    Bug: https://bugs.freedesktop.org/show_bug.cgi?id=107367
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler.c b/drivers/gpu/drm/scheduler/gpu_scheduler.c
index f563e4fbb4b6..1b733229201e 100644
--- a/drivers/gpu/drm/scheduler/gpu_scheduler.c
+++ b/drivers/gpu/drm/scheduler/gpu_scheduler.c
@@ -199,21 +199,6 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
 EXPORT_SYMBOL(drm_sched_entity_init);
 
 /**
- * drm_sched_entity_is_initialized - Query if entity is initialized
- *
- * @sched: Pointer to scheduler instance
- * @entity: The pointer to a valid scheduler entity
- *
- * return true if entity is initialized, false otherwise
-*/
-static bool drm_sched_entity_is_initialized(struct drm_gpu_scheduler *sched,
-					    struct drm_sched_entity *entity)
-{
-	return entity->rq != NULL &&
-		entity->rq->sched == sched;
-}
-
-/**
  * drm_sched_entity_is_idle - Check if entity is idle
  *
  * @entity: scheduler entity
@@ -224,7 +209,8 @@ static bool drm_sched_entity_is_idle(struct drm_sched_entity *entity)
 {
 	rmb();
 
-	if (!entity->rq || spsc_queue_peek(&entity->job_queue) == NULL)
+	if (list_empty(&entity->list) ||
+	    spsc_queue_peek(&entity->job_queue) == NULL)
 		return true;
 
 	return false;
@@ -279,8 +265,6 @@ long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout)
 	long ret = timeout;
 
 	sched = entity->rq->sched;
-	if (!drm_sched_entity_is_initialized(sched, entity))
-		return ret;
 	/**
 	 * The client will not queue more IBs during this fini, consume existing
 	 * queued IBs or discard them on SIGKILL
@@ -299,7 +283,7 @@ long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout)
 	last_user = cmpxchg(&entity->last_user, current->group_leader, NULL);
 	if ((!last_user || last_user == current->group_leader) &&
 	    (current->flags & PF_EXITING) && (current->exit_code == SIGKILL))
-		drm_sched_entity_set_rq(entity, NULL);
+		drm_sched_rq_remove_entity(entity->rq, entity);
 
 	return ret;
 }
@@ -320,7 +304,7 @@ void drm_sched_entity_fini(struct drm_sched_entity *entity)
 	struct drm_gpu_scheduler *sched;
 
 	sched = entity->rq->sched;
-	drm_sched_entity_set_rq(entity, NULL);
+	drm_sched_rq_remove_entity(entity->rq, entity);
 
 	/* Consumption of existing IBs wasn't completed. Forcefully
 	 * remove them here.
@@ -416,15 +400,12 @@ void drm_sched_entity_set_rq(struct drm_sched_entity *entity,
 	if (entity->rq == rq)
 		return;
 
-	spin_lock(&entity->rq_lock);
-
-	if (entity->rq)
-		drm_sched_rq_remove_entity(entity->rq, entity);
+	BUG_ON(!rq);
 
+	spin_lock(&entity->rq_lock);
+	drm_sched_rq_remove_entity(entity->rq, entity);
 	entity->rq = rq;
-	if (rq)
-		drm_sched_rq_add_entity(rq, entity);
-
+	drm_sched_rq_add_entity(rq, entity);
 	spin_unlock(&entity->rq_lock);
 }
 EXPORT_SYMBOL(drm_sched_entity_set_rq);
commit 43bce41cf48eb51eab5ad9e0d40ed382a7bb61d7
Author: Christian König <christian.koenig at amd.com>
Date:   Thu Jul 26 13:43:49 2018 +0200

    drm/scheduler: only kill entity if last user is killed v2
    
    Note which task is using the entity and only kill it if the last user of
    the entity is killed. This should prevent problems when entities are leaked to
    child processes.
    
    v2: add missing kernel doc
    
    Signed-off-by: Christian König <christian.koenig at amd.com>
    Reviewed-by: Andrey Grodzovsky <andrey.grodzovsky at amd.com>
    Acked-by: Nayan Deshmukh <nayan26deshmukh at gmail.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler.c b/drivers/gpu/drm/scheduler/gpu_scheduler.c
index 3f2fc5e8242a..f563e4fbb4b6 100644
--- a/drivers/gpu/drm/scheduler/gpu_scheduler.c
+++ b/drivers/gpu/drm/scheduler/gpu_scheduler.c
@@ -275,6 +275,7 @@ static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
 long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout)
 {
 	struct drm_gpu_scheduler *sched;
+	struct task_struct *last_user;
 	long ret = timeout;
 
 	sched = entity->rq->sched;
@@ -295,7 +296,9 @@ long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout)
 
 
 	/* For killed process disable any more IBs enqueue right now */
-	if ((current->flags & PF_EXITING) && (current->exit_code == SIGKILL))
+	last_user = cmpxchg(&entity->last_user, current->group_leader, NULL);
+	if ((!last_user || last_user == current->group_leader) &&
+	    (current->flags & PF_EXITING) && (current->exit_code == SIGKILL))
 		drm_sched_entity_set_rq(entity, NULL);
 
 	return ret;
@@ -541,6 +544,7 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job,
 
 	trace_drm_sched_job(sched_job, entity);
 
+	WRITE_ONCE(entity->last_user, current->group_leader);
 	first = spsc_queue_push(&entity->job_queue, &sched_job->queue_node);
 
 	/* first job wakes up scheduler */
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index 091b9afcd184..21c648b0b2a1 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -66,6 +66,7 @@ enum drm_sched_priority {
  * @guilty: points to ctx's guilty.
  * @fini_status: contains the exit status in case the process was signalled.
  * @last_scheduled: points to the finished fence of the last scheduled job.
+ * @last_user: last group leader pushing a job into the entity.
  *
  * Entities will emit jobs in order to their corresponding hardware
  * ring, and the scheduler will alternate between entities based on
@@ -85,6 +86,7 @@ struct drm_sched_entity {
 	struct dma_fence_cb		cb;
 	atomic_t			*guilty;
 	struct dma_fence                *last_scheduled;
+	struct task_struct		*last_user;
 };
 
 /**
commit 4a102ad4ba0daf886dcf0927ce2a7f6c3b3a615c
Author: Christian König <christian.koenig at amd.com>
Date:   Mon Jul 30 16:44:14 2018 +0200

    drm/amdgpu: create an empty bo_list if no handle is provided
    
    Instead of having extra handling just create an empty bo_list when no
    handle is provided.
    
    Signed-off-by: Christian König <christian.koenig at amd.com>
    Reviewed-by: Chunming  Zhou <david1.zhou at amd.com>
    Reviewed-by: Huang Rui <ray.huang at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 1d7292ab2b62..502b94fb116a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -561,6 +561,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
 				union drm_amdgpu_cs *cs)
 {
 	struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
+	struct amdgpu_vm *vm = &fpriv->vm;
 	struct amdgpu_bo_list_entry *e;
 	struct list_head duplicates;
 	struct amdgpu_bo *gds;
@@ -580,13 +581,17 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
 				       &p->bo_list);
 		if (r)
 			return r;
+	} else if (!p->bo_list) {
+		/* Create a empty bo_list when no handle is provided */
+		r = amdgpu_bo_list_create(p->adev, p->filp, NULL, 0,
+					  &p->bo_list);
+		if (r)
+			return r;
 	}
 
-	if (p->bo_list) {
-		amdgpu_bo_list_get_list(p->bo_list, &p->validated);
-		if (p->bo_list->first_userptr != p->bo_list->num_entries)
-			p->mn = amdgpu_mn_get(p->adev, AMDGPU_MN_TYPE_GFX);
-	}
+	amdgpu_bo_list_get_list(p->bo_list, &p->validated);
+	if (p->bo_list->first_userptr != p->bo_list->num_entries)
+		p->mn = amdgpu_mn_get(p->adev, AMDGPU_MN_TYPE_GFX);
 
 	INIT_LIST_HEAD(&duplicates);
 	amdgpu_vm_get_pd_bo(&fpriv->vm, &p->validated, &p->vm_pd);
@@ -605,10 +610,6 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
 			goto error_free_pages;
 		}
 
-		/* Without a BO list we don't have userptr BOs */
-		if (!p->bo_list)
-			break;
-
 		INIT_LIST_HEAD(&need_pages);
 		amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
 			struct amdgpu_bo *bo = e->robj;
@@ -703,21 +704,12 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
 	amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved,
 				     p->bytes_moved_vis);
 
-	if (p->bo_list) {
-		struct amdgpu_vm *vm = &fpriv->vm;
-		struct amdgpu_bo_list_entry *e;
+	gds = p->bo_list->gds_obj;
+	gws = p->bo_list->gws_obj;
+	oa = p->bo_list->oa_obj;
 
-		gds = p->bo_list->gds_obj;
-		gws = p->bo_list->gws_obj;
-		oa = p->bo_list->oa_obj;
-
-		amdgpu_bo_list_for_each_entry(e, p->bo_list)
-			e->bo_va = amdgpu_vm_bo_find(vm, e->robj);
-	} else {
-		gds = p->adev->gds.gds_gfx_bo;
-		gws = p->adev->gds.gws_gfx_bo;
-		oa = p->adev->gds.oa_gfx_bo;
-	}
+	amdgpu_bo_list_for_each_entry(e, p->bo_list)
+		e->bo_va = amdgpu_vm_bo_find(vm, e->robj);
 
 	if (gds) {
 		p->job->gds_base = amdgpu_bo_gpu_offset(gds);
@@ -745,15 +737,13 @@ error_validate:
 
 error_free_pages:
 
-	if (p->bo_list) {
-		amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
-			if (!e->user_pages)
-				continue;
+	amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
+		if (!e->user_pages)
+			continue;
 
-			release_pages(e->user_pages,
-				      e->robj->tbo.ttm->num_pages);
-			kvfree(e->user_pages);
-		}
+		release_pages(e->user_pages,
+			      e->robj->tbo.ttm->num_pages);
+		kvfree(e->user_pages);
 	}
 
 	return r;
@@ -815,9 +805,10 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error,
 
 static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
 {
-	struct amdgpu_device *adev = p->adev;
 	struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
+	struct amdgpu_device *adev = p->adev;
 	struct amdgpu_vm *vm = &fpriv->vm;
+	struct amdgpu_bo_list_entry *e;
 	struct amdgpu_bo_va *bo_va;
 	struct amdgpu_bo *bo;
 	int r;
@@ -850,31 +841,26 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
 			return r;
 	}
 
-	if (p->bo_list) {
-		struct amdgpu_bo_list_entry *e;
-
-		amdgpu_bo_list_for_each_entry(e, p->bo_list) {
-			struct dma_fence *f;
-
-			/* ignore duplicates */
-			bo = e->robj;
-			if (!bo)
-				continue;
+	amdgpu_bo_list_for_each_entry(e, p->bo_list) {
+		struct dma_fence *f;
 
-			bo_va = e->bo_va;
-			if (bo_va == NULL)
-				continue;
+		/* ignore duplicates */
+		bo = e->robj;
+		if (!bo)
+			continue;
 
-			r = amdgpu_vm_bo_update(adev, bo_va, false);
-			if (r)
-				return r;
+		bo_va = e->bo_va;
+		if (bo_va == NULL)
+			continue;
 
-			f = bo_va->last_pt_update;
-			r = amdgpu_sync_fence(adev, &p->job->sync, f, false);
-			if (r)
-				return r;
-		}
+		r = amdgpu_vm_bo_update(adev, bo_va, false);
+		if (r)
+			return r;
 
+		f = bo_va->last_pt_update;
+		r = amdgpu_sync_fence(adev, &p->job->sync, f, false);
+		if (r)
+			return r;
 	}
 
 	r = amdgpu_vm_handle_moved(adev, vm);
@@ -889,9 +875,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
 	if (r)
 		return r;
 
-	if (amdgpu_vm_debug && p->bo_list) {
-		struct amdgpu_bo_list_entry *e;
-
+	if (amdgpu_vm_debug) {
 		/* Invalidate all BOs to test for userspace bugs */
 		amdgpu_bo_list_for_each_entry(e, p->bo_list) {
 			/* ignore duplicates */
@@ -1217,22 +1201,19 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
 	struct amdgpu_ring *ring = p->ring;
 	struct drm_sched_entity *entity = &p->ctx->rings[ring->idx].entity;
 	enum drm_sched_priority priority;
+	struct amdgpu_bo_list_entry *e;
 	struct amdgpu_job *job;
 	uint64_t seq;
 
 	int r;
 
 	amdgpu_mn_lock(p->mn);
-	if (p->bo_list) {
-		struct amdgpu_bo_list_entry *e;
+	amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
+		struct amdgpu_bo *bo = e->robj;
 
-		amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
-			struct amdgpu_bo *bo = e->robj;
-
-			if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) {
-				amdgpu_mn_unlock(p->mn);
-				return -ERESTARTSYS;
-			}
+		if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) {
+			amdgpu_mn_unlock(p->mn);
+			return -ERESTARTSYS;
 		}
 	}
 
commit 920990cb080a44203bf6c8eb706e79ad23241ad3
Author: Christian König <christian.koenig at amd.com>
Date:   Mon Jul 30 16:16:01 2018 +0200

    drm/amdgpu: allocate the bo_list array after the list
    
    This avoids multiple allocations for the head and the array.
    
    Signed-off-by: Christian König <christian.koenig at amd.com>
    Reviewed-by: Chunming  Zhou <david1.zhou at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
index 096bcf4a6334..d472a2c8399f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
@@ -35,13 +35,15 @@
 #define AMDGPU_BO_LIST_MAX_PRIORITY	32u
 #define AMDGPU_BO_LIST_NUM_BUCKETS	(AMDGPU_BO_LIST_MAX_PRIORITY + 1)
 
-static int amdgpu_bo_list_set(struct amdgpu_device *adev,
-				     struct drm_file *filp,
-				     struct amdgpu_bo_list *list,
-				     struct drm_amdgpu_bo_list_entry *info,
-				     unsigned num_entries);
+static void amdgpu_bo_list_free_rcu(struct rcu_head *rcu)
+{
+	struct amdgpu_bo_list *list = container_of(rcu, struct amdgpu_bo_list,
+						   rhead);
+
+	kvfree(list);
+}
 
-static void amdgpu_bo_list_release_rcu(struct kref *ref)
+static void amdgpu_bo_list_free(struct kref *ref)
 {
 	struct amdgpu_bo_list *list = container_of(ref, struct amdgpu_bo_list,
 						   refcount);
@@ -50,67 +52,36 @@ static void amdgpu_bo_list_release_rcu(struct kref *ref)
 	amdgpu_bo_list_for_each_entry(e, list)
 		amdgpu_bo_unref(&e->robj);
 
-	kvfree(list->array);
-	kfree_rcu(list, rhead);
+	call_rcu(&list->rhead, amdgpu_bo_list_free_rcu);
 }
 
-int amdgpu_bo_list_create(struct amdgpu_device *adev,
-				 struct drm_file *filp,
-				 struct drm_amdgpu_bo_list_entry *info,
-				 unsigned num_entries,
-				 struct amdgpu_bo_list **list_out)
+int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp,
+			  struct drm_amdgpu_bo_list_entry *info,
+			  unsigned num_entries, struct amdgpu_bo_list **result)
 {
+	unsigned last_entry = 0, first_userptr = num_entries;
+	struct amdgpu_bo_list_entry *array;
 	struct amdgpu_bo_list *list;
+	uint64_t total_size = 0;
+	size_t size;
+	unsigned i;
 	int r;
 
+	if (num_entries > SIZE_MAX / sizeof(struct amdgpu_bo_list_entry))
+		return -EINVAL;
 
-	list = kzalloc(sizeof(struct amdgpu_bo_list), GFP_KERNEL);
+	size = sizeof(struct amdgpu_bo_list);
+	size += num_entries * sizeof(struct amdgpu_bo_list_entry);
+	list = kvmalloc(size, GFP_KERNEL);
 	if (!list)
 		return -ENOMEM;
 
-	/* initialize bo list*/
 	kref_init(&list->refcount);
-	r = amdgpu_bo_list_set(adev, filp, list, info, num_entries);
-	if (r) {
-		kfree(list);
-		return r;
-	}
-
-	*list_out = list;
-	return 0;
-}
-
-static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id)
-{
-	struct amdgpu_bo_list *list;
-
-	mutex_lock(&fpriv->bo_list_lock);
-	list = idr_remove(&fpriv->bo_list_handles, id);
-	mutex_unlock(&fpriv->bo_list_lock);
-	if (list)
-		kref_put(&list->refcount, amdgpu_bo_list_release_rcu);
-}
-
-static int amdgpu_bo_list_set(struct amdgpu_device *adev,
-				     struct drm_file *filp,
-				     struct amdgpu_bo_list *list,
-				     struct drm_amdgpu_bo_list_entry *info,
-				     unsigned num_entries)
-{
-	struct amdgpu_bo_list_entry *array;
-	struct amdgpu_bo *gds_obj = adev->gds.gds_gfx_bo;
-	struct amdgpu_bo *gws_obj = adev->gds.gws_gfx_bo;
-	struct amdgpu_bo *oa_obj = adev->gds.oa_gfx_bo;
-
-	unsigned last_entry = 0, first_userptr = num_entries;
-	struct amdgpu_bo_list_entry *e;
-	uint64_t total_size = 0;
-	unsigned i;
-	int r;
+	list->gds_obj = adev->gds.gds_gfx_bo;
+	list->gws_obj = adev->gds.gws_gfx_bo;
+	list->oa_obj = adev->gds.oa_gfx_bo;
 
-	array = kvmalloc_array(num_entries, sizeof(struct amdgpu_bo_list_entry), GFP_KERNEL);
-	if (!array)
-		return -ENOMEM;
+	array = amdgpu_bo_list_array_entry(list, 0);
 	memset(array, 0, num_entries * sizeof(struct amdgpu_bo_list_entry));
 
 	for (i = 0; i < num_entries; ++i) {
@@ -147,36 +118,41 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
 		entry->tv.shared = !entry->robj->prime_shared_count;
 
 		if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GDS)
-			gds_obj = entry->robj;
+			list->gds_obj = entry->robj;
 		if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GWS)
-			gws_obj = entry->robj;
+			list->gws_obj = entry->robj;
 		if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_OA)
-			oa_obj = entry->robj;
+			list->oa_obj = entry->robj;
 
 		total_size += amdgpu_bo_size(entry->robj);
 		trace_amdgpu_bo_list_set(list, entry->robj);
 	}
 
-	amdgpu_bo_list_for_each_entry(e, list)
-		amdgpu_bo_unref(&list->array[i].robj);
-
-	kvfree(list->array);
-
-	list->gds_obj = gds_obj;
-	list->gws_obj = gws_obj;
-	list->oa_obj = oa_obj;
 	list->first_userptr = first_userptr;
-	list->array = array;
 	list->num_entries = num_entries;
 
 	trace_amdgpu_cs_bo_status(list->num_entries, total_size);
+
+	*result = list;
 	return 0;
 
 error_free:
 	while (i--)
 		amdgpu_bo_unref(&array[i].robj);
-	kvfree(array);
+	kvfree(list);
 	return r;
+
+}
+
+static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id)
+{
+	struct amdgpu_bo_list *list;
+
+	mutex_lock(&fpriv->bo_list_lock);
+	list = idr_remove(&fpriv->bo_list_handles, id);
+	mutex_unlock(&fpriv->bo_list_lock);
+	if (list)
+		kref_put(&list->refcount, amdgpu_bo_list_free);
 }
 
 int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
@@ -229,7 +205,7 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
 
 void amdgpu_bo_list_put(struct amdgpu_bo_list *list)
 {
-	kref_put(&list->refcount, amdgpu_bo_list_release_rcu);
+	kref_put(&list->refcount, amdgpu_bo_list_free);
 }
 
 int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
index 3d77abfcd4a6..61b089768e1c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
@@ -48,7 +48,6 @@ struct amdgpu_bo_list {
 	struct amdgpu_bo *oa_obj;
 	unsigned first_userptr;
 	unsigned num_entries;
-	struct amdgpu_bo_list_entry *array;
 };
 
 int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
@@ -65,14 +64,22 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev,
 				 unsigned num_entries,
 				 struct amdgpu_bo_list **list);
 
+static inline struct amdgpu_bo_list_entry *
+amdgpu_bo_list_array_entry(struct amdgpu_bo_list *list, unsigned index)
+{
+	struct amdgpu_bo_list_entry *array = (void *)&list[1];
+
+	return &array[index];
+}
+
 #define amdgpu_bo_list_for_each_entry(e, list) \
-	for (e = &(list)->array[0]; \
-	     e != &(list)->array[(list)->num_entries]; \
+	for (e = amdgpu_bo_list_array_entry(list, 0); \
+	     e != amdgpu_bo_list_array_entry(list, (list)->num_entries); \
 	     ++e)
 
 #define amdgpu_bo_list_for_each_userptr_entry(e, list) \
-	for (e = &(list)->array[(list)->first_userptr]; \
-	     e != &(list)->array[(list)->num_entries]; \
+	for (e = amdgpu_bo_list_array_entry(list, (list)->first_userptr); \
+	     e != amdgpu_bo_list_array_entry(list, (list)->num_entries); \
 	     ++e)
 
 #endif
commit 39f7f69a6054bb9777b47b6afdb5ce2fae30dbee
Author: Christian König <christian.koenig at amd.com>
Date:   Mon Jul 30 15:37:46 2018 +0200

    drm/amdgpu: add bo_list iterators
    
    Add helpers to iterate over all entries in a bo_list.
    
    Signed-off-by: Christian König <christian.koenig at amd.com>
    Reviewed-by: Chunming  Zhou <david1.zhou at amd.com>
    Acked-by: Huang Rui <ray.huang at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
index 5335f1b5459f..096bcf4a6334 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
@@ -43,12 +43,12 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
 
 static void amdgpu_bo_list_release_rcu(struct kref *ref)
 {
-	unsigned i;
 	struct amdgpu_bo_list *list = container_of(ref, struct amdgpu_bo_list,
 						   refcount);
+	struct amdgpu_bo_list_entry *e;
 
-	for (i = 0; i < list->num_entries; ++i)
-		amdgpu_bo_unref(&list->array[i].robj);
+	amdgpu_bo_list_for_each_entry(e, list)
+		amdgpu_bo_unref(&e->robj);
 
 	kvfree(list->array);
 	kfree_rcu(list, rhead);
@@ -103,6 +103,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
 	struct amdgpu_bo *oa_obj = adev->gds.oa_gfx_bo;
 
 	unsigned last_entry = 0, first_userptr = num_entries;
+	struct amdgpu_bo_list_entry *e;
 	uint64_t total_size = 0;
 	unsigned i;
 	int r;
@@ -156,7 +157,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
 		trace_amdgpu_bo_list_set(list, entry->robj);
 	}
 
-	for (i = 0; i < list->num_entries; ++i)
+	amdgpu_bo_list_for_each_entry(e, list)
 		amdgpu_bo_unref(&list->array[i].robj);
 
 	kvfree(list->array);
@@ -201,6 +202,7 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
 	 * concatenated in descending order.
 	 */
 	struct list_head bucket[AMDGPU_BO_LIST_NUM_BUCKETS];
+	struct amdgpu_bo_list_entry *e;
 	unsigned i;
 
 	for (i = 0; i < AMDGPU_BO_LIST_NUM_BUCKETS; i++)
@@ -211,14 +213,13 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
 	 * in the list, the sort mustn't change the ordering of buffers
 	 * with the same priority, i.e. it must be stable.
 	 */
-	for (i = 0; i < list->num_entries; i++) {
-		unsigned priority = list->array[i].priority;
+	amdgpu_bo_list_for_each_entry(e, list) {
+		unsigned priority = e->priority;
 
-		if (!list->array[i].robj->parent)
-			list_add_tail(&list->array[i].tv.head,
-				      &bucket[priority]);
+		if (!e->robj->parent)
+			list_add_tail(&e->tv.head, &bucket[priority]);
 
-		list->array[i].user_pages = NULL;
+		e->user_pages = NULL;
 	}
 
 	/* Connect the sorted buckets in the output list. */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
index 0ce540203db1..3d77abfcd4a6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
@@ -65,4 +65,14 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev,
 				 unsigned num_entries,
 				 struct amdgpu_bo_list **list);
 
+#define amdgpu_bo_list_for_each_entry(e, list) \
+	for (e = &(list)->array[0]; \
+	     e != &(list)->array[(list)->num_entries]; \
+	     ++e)
+
+#define amdgpu_bo_list_for_each_userptr_entry(e, list) \
+	for (e = &(list)->array[(list)->first_userptr]; \
+	     e != &(list)->array[(list)->num_entries]; \
+	     ++e)
+
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index f7154f3ed807..1d7292ab2b62 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -563,10 +563,10 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
 	struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
 	struct amdgpu_bo_list_entry *e;
 	struct list_head duplicates;
-	unsigned i, tries = 10;
 	struct amdgpu_bo *gds;
 	struct amdgpu_bo *gws;
 	struct amdgpu_bo *oa;
+	unsigned tries = 10;
 	int r;
 
 	INIT_LIST_HEAD(&p->validated);
@@ -596,7 +596,6 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
 
 	while (1) {
 		struct list_head need_pages;
-		unsigned i;
 
 		r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true,
 					   &duplicates);
@@ -611,12 +610,8 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
 			break;
 
 		INIT_LIST_HEAD(&need_pages);
-		for (i = p->bo_list->first_userptr;
-		     i < p->bo_list->num_entries; ++i) {
-			struct amdgpu_bo *bo;
-
-			e = &p->bo_list->array[i];
-			bo = e->robj;
+		amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
+			struct amdgpu_bo *bo = e->robj;
 
 			if (amdgpu_ttm_tt_userptr_invalidated(bo->tbo.ttm,
 				 &e->user_invalidated) && e->user_pages) {
@@ -710,16 +705,14 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
 
 	if (p->bo_list) {
 		struct amdgpu_vm *vm = &fpriv->vm;
-		unsigned i;
+		struct amdgpu_bo_list_entry *e;
 
 		gds = p->bo_list->gds_obj;
 		gws = p->bo_list->gws_obj;
 		oa = p->bo_list->oa_obj;
-		for (i = 0; i < p->bo_list->num_entries; i++) {
-			struct amdgpu_bo *bo = p->bo_list->array[i].robj;
 
-			p->bo_list->array[i].bo_va = amdgpu_vm_bo_find(vm, bo);
-		}
+		amdgpu_bo_list_for_each_entry(e, p->bo_list)
+			e->bo_va = amdgpu_vm_bo_find(vm, e->robj);
 	} else {
 		gds = p->adev->gds.gds_gfx_bo;
 		gws = p->adev->gds.gws_gfx_bo;
@@ -753,10 +746,7 @@ error_validate:
 error_free_pages:
 
 	if (p->bo_list) {
-		for (i = p->bo_list->first_userptr;
-		     i < p->bo_list->num_entries; ++i) {
-			e = &p->bo_list->array[i];
-
+		amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
 			if (!e->user_pages)
 				continue;
 
@@ -830,7 +820,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
 	struct amdgpu_vm *vm = &fpriv->vm;
 	struct amdgpu_bo_va *bo_va;
 	struct amdgpu_bo *bo;
-	int i, r;
+	int r;
 
 	r = amdgpu_vm_clear_freed(adev, vm, NULL);
 	if (r)
@@ -861,15 +851,17 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
 	}
 
 	if (p->bo_list) {
-		for (i = 0; i < p->bo_list->num_entries; i++) {
+		struct amdgpu_bo_list_entry *e;
+
+		amdgpu_bo_list_for_each_entry(e, p->bo_list) {
 			struct dma_fence *f;
 
 			/* ignore duplicates */
-			bo = p->bo_list->array[i].robj;
+			bo = e->robj;
 			if (!bo)
 				continue;
 
-			bo_va = p->bo_list->array[i].bo_va;
+			bo_va = e->bo_va;
 			if (bo_va == NULL)
 				continue;
 
@@ -898,14 +890,15 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
 		return r;
 
 	if (amdgpu_vm_debug && p->bo_list) {
+		struct amdgpu_bo_list_entry *e;
+
 		/* Invalidate all BOs to test for userspace bugs */
-		for (i = 0; i < p->bo_list->num_entries; i++) {
+		amdgpu_bo_list_for_each_entry(e, p->bo_list) {
 			/* ignore duplicates */
-			bo = p->bo_list->array[i].robj;
-			if (!bo)
+			if (!e->robj)
 				continue;
 
-			amdgpu_vm_bo_invalidate(adev, bo, false);
+			amdgpu_vm_bo_invalidate(adev, e->robj, false);
 		}
 	}
 
@@ -1225,16 +1218,16 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
 	struct drm_sched_entity *entity = &p->ctx->rings[ring->idx].entity;
 	enum drm_sched_priority priority;
 	struct amdgpu_job *job;
-	unsigned i;
 	uint64_t seq;
 
 	int r;
 
 	amdgpu_mn_lock(p->mn);
 	if (p->bo_list) {
-		for (i = p->bo_list->first_userptr;
-		     i < p->bo_list->num_entries; ++i) {
-			struct amdgpu_bo *bo = p->bo_list->array[i].robj;
+		struct amdgpu_bo_list_entry *e;
+
+		amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
+			struct amdgpu_bo *bo = e->robj;
 
 			if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) {
 				amdgpu_mn_unlock(p->mn);
commit a0f208453b97565dab8c334ff013aa5ab3c66d0c
Author: Christian König <christian.koenig at amd.com>
Date:   Mon Jul 30 14:17:41 2018 +0200

    drm/amdgpu: nuke amdgpu_bo_list_free
    
    The RCU grace period is harmless and avoiding it is not worth the effort
    of doubling the implementation.
    
    Signed-off-by: Christian König <christian.koenig at amd.com>
    Reviewed-by: Chunming  Zhou <david1.zhou at amd.com>
    Reviewed-by: Huang Rui <ray.huang at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
index 556040e45931..5335f1b5459f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
@@ -231,17 +231,6 @@ void amdgpu_bo_list_put(struct amdgpu_bo_list *list)
 	kref_put(&list->refcount, amdgpu_bo_list_release_rcu);
 }
 
-void amdgpu_bo_list_free(struct amdgpu_bo_list *list)
-{
-	unsigned i;
-
-	for (i = 0; i < list->num_entries; ++i)
-		amdgpu_bo_unref(&list->array[i].robj);
-
-	kvfree(list->array);
-	kfree(list);
-}
-
 int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in,
 				      struct drm_amdgpu_bo_list_entry **info_param)
 {
@@ -310,7 +299,7 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
 		r = idr_alloc(&fpriv->bo_list_handles, list, 1, 0, GFP_KERNEL);
 		mutex_unlock(&fpriv->bo_list_lock);
 		if (r < 0) {
-			amdgpu_bo_list_free(list);
+			amdgpu_bo_list_put(list);
 			return r;
 		}
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
index 89195fdcb1ef..0ce540203db1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
@@ -56,7 +56,6 @@ int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
 void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
 			     struct list_head *validated);
 void amdgpu_bo_list_put(struct amdgpu_bo_list *list);
-void amdgpu_bo_list_free(struct amdgpu_bo_list *list);
 int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in,
 				      struct drm_amdgpu_bo_list_entry **info_param);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index dd2132fa2b89..bd98cc5fb97b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -967,7 +967,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
 	amdgpu_bo_unref(&pd);
 
 	idr_for_each_entry(&fpriv->bo_list_handles, list, handle)
-		amdgpu_bo_list_free(list);
+		amdgpu_bo_list_put(list);
 
 	idr_destroy(&fpriv->bo_list_handles);
 	mutex_destroy(&fpriv->bo_list_lock);
commit 81c6dabcc990c341793368db985ee8aca5713b16
Author: Christian König <christian.koenig at amd.com>
Date:   Mon Jul 30 13:46:04 2018 +0200

    drm/amdgpu: always recreate bo_list
    
    The bo_list handle is allocated by OP_CREATE, so in OP_UPDATE here we just
    re-create the bo_list object and replace the handle. This way we don't
    need locking to protect the bo_list because it's always re-created when
    changed.
    
    Signed-off-by: Christian König <christian.koenig at amd.com>
    Reviewed-by: Chunming  Zhou <david1.zhou at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
index 6728448167ba..556040e45931 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
@@ -50,7 +50,6 @@ static void amdgpu_bo_list_release_rcu(struct kref *ref)
 	for (i = 0; i < list->num_entries; ++i)
 		amdgpu_bo_unref(&list->array[i].robj);
 
-	mutex_destroy(&list->lock);
 	kvfree(list->array);
 	kfree_rcu(list, rhead);
 }
@@ -70,7 +69,6 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev,
 		return -ENOMEM;
 
 	/* initialize bo list*/
-	mutex_init(&list->lock);
 	kref_init(&list->refcount);
 	r = amdgpu_bo_list_set(adev, filp, list, info, num_entries);
 	if (r) {
@@ -188,7 +186,6 @@ int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
 
 	if (*result && kref_get_unless_zero(&(*result)->refcount)) {
 		rcu_read_unlock();
-		mutex_lock(&(*result)->lock);
 		return 0;
 	}
 
@@ -231,7 +228,6 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
 
 void amdgpu_bo_list_put(struct amdgpu_bo_list *list)
 {
-	mutex_unlock(&list->lock);
 	kref_put(&list->refcount, amdgpu_bo_list_release_rcu);
 }
 
@@ -242,7 +238,6 @@ void amdgpu_bo_list_free(struct amdgpu_bo_list *list)
 	for (i = 0; i < list->num_entries; ++i)
 		amdgpu_bo_unref(&list->array[i].robj);
 
-	mutex_destroy(&list->lock);
 	kvfree(list->array);
 	kfree(list);
 }
@@ -297,7 +292,7 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
 	union drm_amdgpu_bo_list *args = data;
 	uint32_t handle = args->in.list_handle;
 	struct drm_amdgpu_bo_list_entry *info = NULL;
-	struct amdgpu_bo_list *list;
+	struct amdgpu_bo_list *list, *old;
 	int r;
 
 	r = amdgpu_bo_create_list_entry_array(&args->in, &info);
@@ -328,16 +323,22 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
 		break;
 
 	case AMDGPU_BO_LIST_OP_UPDATE:
-		r = amdgpu_bo_list_get(fpriv, handle, &list);
+		r = amdgpu_bo_list_create(adev, filp, info, args->in.bo_number,
+					  &list);
 		if (r)
 			goto error_free;
 
-		r = amdgpu_bo_list_set(adev, filp, list, info,
-					      args->in.bo_number);
-		amdgpu_bo_list_put(list);
-		if (r)
+		mutex_lock(&fpriv->bo_list_lock);
+		old = idr_replace(&fpriv->bo_list_handles, list, handle);
+		mutex_unlock(&fpriv->bo_list_lock);
+
+		if (IS_ERR(old)) {
+			amdgpu_bo_list_put(list);
+			r = PTR_ERR(old);
 			goto error_free;
+		}
 
+		amdgpu_bo_list_put(old);
 		break;
 
 	default:
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
index 833f846bfdad..89195fdcb1ef 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
@@ -41,7 +41,6 @@ struct amdgpu_bo_list_entry {
 };
 
 struct amdgpu_bo_list {
-	struct mutex lock;
 	struct rcu_head rhead;
 	struct kref refcount;
 	struct amdgpu_bo *gds_obj;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 0295666968da..f7154f3ed807 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -580,9 +580,6 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
 				       &p->bo_list);
 		if (r)
 			return r;
-
-	} else if (p->bo_list) {
-		mutex_lock(&p->bo_list->lock);
 	}
 
 	if (p->bo_list) {
commit 4a8c21a1e9b3c35b21c5a4a4c16a009a193389bd
Author: Christian König <christian.koenig at amd.com>
Date:   Mon Jul 30 13:27:09 2018 +0200

    drm/amdgpu: move bo_list defines to amdgpu_bo_list.h
    
    Further demangle amdgpu.h
    
    Signed-off-by: Christian König <christian.koenig at amd.com>
    Reviewed-by: Chunming  Zhou <david1.zhou at amd.com>
    Acked-by: Huang Rui <ray.huang at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 4d4d6697fbce..447c4c7a36d6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -74,6 +74,7 @@
 #include "amdgpu_gart.h"
 #include "amdgpu_debugfs.h"
 #include "amdgpu_job.h"
+#include "amdgpu_bo_list.h"
 
 /*
  * Modules parameters.
@@ -690,45 +691,6 @@ struct amdgpu_fpriv {
 };
 
 /*
- * residency list
- */
-struct amdgpu_bo_list_entry {
-	struct amdgpu_bo		*robj;
-	struct ttm_validate_buffer	tv;
-	struct amdgpu_bo_va		*bo_va;
-	uint32_t			priority;
-	struct page			**user_pages;
-	int				user_invalidated;
-};
-
-struct amdgpu_bo_list {
-	struct mutex lock;
-	struct rcu_head rhead;
-	struct kref refcount;
-	struct amdgpu_bo *gds_obj;
-	struct amdgpu_bo *gws_obj;
-	struct amdgpu_bo *oa_obj;
-	unsigned first_userptr;
-	unsigned num_entries;
-	struct amdgpu_bo_list_entry *array;
-};
-
-int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
-		       struct amdgpu_bo_list **result);
-void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
-			     struct list_head *validated);
-void amdgpu_bo_list_put(struct amdgpu_bo_list *list);
-void amdgpu_bo_list_free(struct amdgpu_bo_list *list);
-int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in,
-				      struct drm_amdgpu_bo_list_entry **info_param);
-
-int amdgpu_bo_list_create(struct amdgpu_device *adev,
-				 struct drm_file *filp,
-				 struct drm_amdgpu_bo_list_entry *info,
-				 unsigned num_entries,
-				 struct amdgpu_bo_list **list);
-
-/*
  * GFX stuff
  */
 #include "clearstate_defs.h"
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
new file mode 100644
index 000000000000..833f846bfdad
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2018 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef __AMDGPU_BO_LIST_H__
+#define __AMDGPU_BO_LIST_H__
+
+#include <drm/ttm/ttm_execbuf_util.h>
+#include <drm/amdgpu_drm.h>
+
+struct amdgpu_device;
+struct amdgpu_bo;
+struct amdgpu_bo_va;
+struct amdgpu_fpriv;
+
+struct amdgpu_bo_list_entry {
+	struct amdgpu_bo		*robj;
+	struct ttm_validate_buffer	tv;
+	struct amdgpu_bo_va		*bo_va;
+	uint32_t			priority;
+	struct page			**user_pages;
+	int				user_invalidated;
+};
+
+struct amdgpu_bo_list {
+	struct mutex lock;
+	struct rcu_head rhead;
+	struct kref refcount;
+	struct amdgpu_bo *gds_obj;
+	struct amdgpu_bo *gws_obj;
+	struct amdgpu_bo *oa_obj;
+	unsigned first_userptr;
+	unsigned num_entries;
+	struct amdgpu_bo_list_entry *array;
+};
+
+int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
+		       struct amdgpu_bo_list **result);
+void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
+			     struct list_head *validated);
+void amdgpu_bo_list_put(struct amdgpu_bo_list *list);
+void amdgpu_bo_list_free(struct amdgpu_bo_list *list);
+int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in,
+				      struct drm_amdgpu_bo_list_entry **info_param);
+
+int amdgpu_bo_list_create(struct amdgpu_device *adev,
+				 struct drm_file *filp,
+				 struct drm_amdgpu_bo_list_entry *info,
+				 unsigned num_entries,
+				 struct amdgpu_bo_list **list);
+
+#endif
commit 8ab19ea619aeed8ca4a36c124e8edfd9b9491aba
Author: Christian König <christian.koenig at amd.com>
Date:   Fri Jul 27 16:56:34 2018 +0200

    drm/amdgpu: add new amdgpu_vm_bo_trace_cs() function v2
    
    This allows us to trace all VM ranges which should be valid inside a CS.
    
    v2: dump mappings without BO as well
    
    Signed-off-by: Christian König <christian.koenig at amd.com>
    Reviewed-by: Chunming  Zhou <david1.zhou at amd.com>
    Reviewed-and-tested-by: Andrey Grodzovsky <andrey.grodzovsky at amd.com> (v1)
    Reviewed-by: Huang Rui <ray.huang at amd.com> (v1)
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index d41cea78e4aa..0295666968da 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1223,6 +1223,7 @@ static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p)
 static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
 			    union drm_amdgpu_cs *cs)
 {
+	struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
 	struct amdgpu_ring *ring = p->ring;
 	struct drm_sched_entity *entity = &p->ctx->rings[ring->idx].entity;
 	enum drm_sched_priority priority;
@@ -1275,6 +1276,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
 	amdgpu_job_free_resources(job);
 
 	trace_amdgpu_cs_ioctl(job);
+	amdgpu_vm_bo_trace_cs(&fpriv->vm, &p->ticket);
 	priority = job->base.s_priority;
 	drm_sched_entity_push_job(&job->base, entity);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
index 11f262f15200..7206a0025b17 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
@@ -314,6 +314,11 @@ DEFINE_EVENT(amdgpu_vm_mapping, amdgpu_vm_bo_mapping,
 	    TP_ARGS(mapping)
 );
 
+DEFINE_EVENT(amdgpu_vm_mapping, amdgpu_vm_bo_cs,
+	    TP_PROTO(struct amdgpu_bo_va_mapping *mapping),
+	    TP_ARGS(mapping)
+);
+
 TRACE_EVENT(amdgpu_vm_set_ptes,
 	    TP_PROTO(uint64_t pe, uint64_t addr, unsigned count,
 		     uint32_t incr, uint64_t flags),
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 5d7d7900ccab..015613b4f98b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -2344,6 +2344,35 @@ struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm,
 }
 
 /**
+ * amdgpu_vm_bo_trace_cs - trace all reserved mappings
+ *
+ * @vm: the requested vm
+ * @ticket: CS ticket
+ *
+ * Trace all mappings of BOs reserved during a command submission.
+ */
+void amdgpu_vm_bo_trace_cs(struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket)
+{
+	struct amdgpu_bo_va_mapping *mapping;
+
+	if (!trace_amdgpu_vm_bo_cs_enabled())
+		return;
+
+	for (mapping = amdgpu_vm_it_iter_first(&vm->va, 0, U64_MAX); mapping;
+	     mapping = amdgpu_vm_it_iter_next(mapping, 0, U64_MAX)) {
+		if (mapping->bo_va && mapping->bo_va->base.bo) {
+			struct amdgpu_bo *bo;
+
+			bo = mapping->bo_va->base.bo;
+			if (READ_ONCE(bo->tbo.resv->lock.ctx) != ticket)
+				continue;
+		}
+
+		trace_amdgpu_vm_bo_cs(mapping);
+	}
+}
+
+/**
  * amdgpu_vm_bo_rmv - remove a bo to a specific vm
  *
  * @adev: amdgpu_device pointer
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index d416f895233d..67a15d439ac0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -318,6 +318,7 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
 				uint64_t saddr, uint64_t size);
 struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm,
 							 uint64_t addr);
+void amdgpu_vm_bo_trace_cs(struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket);
 void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
 		      struct amdgpu_bo_va *bo_va);
 void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t vm_size,
commit 0cb7c1f03bfb3991120313c5927c1749041ef800
Author: Christian König <christian.koenig at amd.com>
Date:   Mon Jul 30 16:18:54 2018 +0200

    drm/amdgpu: return error if both BOs and bo_list handle is given
    
    Return -EINVAL when both the BOs as well as a list handle is provided in
    the IOCTL.
    
    Signed-off-by: Christian König <christian.koenig at amd.com>
    Reviewed-by: Chunming  Zhou <david1.zhou at amd.com>
    Reviewed-by: Huang Rui <ray.huang at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 8a49c3b97bd4..d41cea78e4aa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -572,14 +572,17 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
 	INIT_LIST_HEAD(&p->validated);
 
 	/* p->bo_list could already be assigned if AMDGPU_CHUNK_ID_BO_HANDLES is present */
-	if (p->bo_list) {
-		mutex_lock(&p->bo_list->lock);
+	if (cs->in.bo_list_handle) {
+		if (p->bo_list)
+			return -EINVAL;
 
-	} else if (cs->in.bo_list_handle) {
 		r = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle,
 				       &p->bo_list);
 		if (r)
 			return r;
+
+	} else if (p->bo_list) {
+		mutex_lock(&p->bo_list->lock);
 	}
 
 	if (p->bo_list) {
commit 275105ce7be37a2cc80eb1b60e6526355f54df94
Author: Christian König <christian.koenig at amd.com>
Date:   Mon Jul 30 15:33:34 2018 +0200

    drm/amdgpu: fix total size calculation
    
    long might only be 32bit in size and we can easily use more than 4GB
    here.
    
    Signed-off-by: Christian König <christian.koenig at amd.com>
    Reviewed-by: Chunming  Zhou <david1.zhou at amd.com>
    Acked-by: Huang Rui <ray.huang at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
index 944868e47119..6728448167ba 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
@@ -105,9 +105,9 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
 	struct amdgpu_bo *oa_obj = adev->gds.oa_gfx_bo;
 
 	unsigned last_entry = 0, first_userptr = num_entries;
+	uint64_t total_size = 0;
 	unsigned i;
 	int r;
-	unsigned long total_size = 0;
 
 	array = kvmalloc_array(num_entries, sizeof(struct amdgpu_bo_list_entry), GFP_KERNEL);
 	if (!array)
commit ba7f47831ebdad141791be53a51049d6771156cd
Author: Masahiro Yamada <yamada.masahiro at socionext.com>
Date:   Fri Jul 6 14:12:11 2018 +0900

    drm/sched: remove unneeded -Iinclude/drm compiler flag
    
    I refactored the include directives under include/drm/ some time ago.
    This flag is unneeded.
    
    Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
    Reviewed-by: Christian König <christian.koenig at amd.com>
    Acked-by: Nayan Deshmukh <nayan26deshmukh at gmail.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/scheduler/Makefile b/drivers/gpu/drm/scheduler/Makefile
index bd0377c0d2ee..7665883f81d4 100644
--- a/drivers/gpu/drm/scheduler/Makefile
+++ b/drivers/gpu/drm/scheduler/Makefile
@@ -20,7 +20,6 @@
 # OTHER DEALINGS IN THE SOFTWARE.
 #
 #
-ccflags-y := -Iinclude/drm
 gpu-sched-y := gpu_scheduler.o sched_fence.o
 
 obj-$(CONFIG_DRM_SCHED) += gpu-sched.o
commit 52c054caf83012fe9fe858ee86d90b4ea2cc3cca
Author: Christian König <christian.koenig at amd.com>
Date:   Fri Jul 27 15:32:04 2018 +0200

    drm/amdgpu: add proper error handling to amdgpu_bo_list_get
    
    Otherwise we silently don't use a BO list when the handle is invalid.
    
    Signed-off-by: Christian König <christian.koenig at amd.com>
    Reviewed-by: Chunming Zhou <david1.zhou at amd.com>
    Reviewed-by: Huang Rui <ray.huang at amd.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 1f6345dda6ea..4d4d6697fbce 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -713,8 +713,8 @@ struct amdgpu_bo_list {
 	struct amdgpu_bo_list_entry *array;
 };
 
-struct amdgpu_bo_list *
-amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id);
+int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
+		       struct amdgpu_bo_list **result);
 void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
 			     struct list_head *validated);
 void amdgpu_bo_list_put(struct amdgpu_bo_list *list);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
index 7679c068c89a..944868e47119 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
@@ -180,27 +180,20 @@ error_free:
 	return r;
 }
 
-struct amdgpu_bo_list *
-amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id)
+int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
+		       struct amdgpu_bo_list **result)
 {
-	struct amdgpu_bo_list *result;
-
 	rcu_read_lock();
-	result = idr_find(&fpriv->bo_list_handles, id);
+	*result = idr_find(&fpriv->bo_list_handles, id);
 
-	if (result) {
-		if (kref_get_unless_zero(&result->refcount)) {
-			rcu_read_unlock();
-			mutex_lock(&result->lock);
-		} else {
-			rcu_read_unlock();
-			result = NULL;
-		}
-	} else {
+	if (*result && kref_get_unless_zero(&(*result)->refcount)) {
 		rcu_read_unlock();
+		mutex_lock(&(*result)->lock);
+		return 0;
 	}
 
-	return result;
+	rcu_read_unlock();
+	return -ENOENT;
 }
 
 void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
@@ -335,9 +328,8 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
 		break;
 
 	case AMDGPU_BO_LIST_OP_UPDATE:
-		r = -ENOENT;
-		list = amdgpu_bo_list_get(fpriv, handle);
-		if (!list)
+		r = amdgpu_bo_list_get(fpriv, handle, &list);
+		if (r)
 			goto error_free;
 
 		r = amdgpu_bo_list_set(adev, filp, list, info,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 533b2e7656c0..8a49c3b97bd4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -572,11 +572,16 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
 	INIT_LIST_HEAD(&p->validated);
 
 	/* p->bo_list could already be assigned if AMDGPU_CHUNK_ID_BO_HANDLES is present */
-	if (!p->bo_list)
-		p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle);
-	else
+	if (p->bo_list) {
 		mutex_lock(&p->bo_list->lock);
 
+	} else if (cs->in.bo_list_handle) {
+		r = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle,
+				       &p->bo_list);
+		if (r)
+			return r;
+	}
+
 	if (p->bo_list) {
 		amdgpu_bo_list_get_list(p->bo_list, &p->validated);
 		if (p->bo_list->first_userptr != p->bo_list->num_entries)
commit ccf9ef0b0d10434dec5046bcfc4e834a7b1830fd
Author: Rex Zhu <rex.zhu at amd.com>
Date:   Wed Jul 25 11:51:46 2018 +0800

    drm/amdgpu: fix a reversed condition
    
    This test was reversed so it would end up leading to vddnb value
    can't be read via hwmon on APU.
    
    Reviewed-by: Evan Quan <evan.quan at amd.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Signed-off-by: Rex Zhu <Rex.Zhu at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
    Cc: stable at vger.kernel.org

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index 15a1192c1ec5..23fc1d32b937 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -1185,7 +1185,7 @@ static ssize_t amdgpu_hwmon_show_vddnb(struct device *dev,
 	int r, size = sizeof(vddnb);
 
 	/* only APUs have vddnb */
-	if  (adev->flags & AMD_IS_APU)
+	if  (!(adev->flags & AMD_IS_APU))
 		return -EINVAL;
 
 	/* Can't get voltage when the card is off */
commit 8a50bb47a863c3cb8950a2e810448c9a82a9d446
Author: Rex Zhu <rex.zhu at amd.com>
Date:   Wed Jul 25 11:45:03 2018 +0800

    drm/amd/pp: Convert voltage unit in mV*4 to mV on CZ/ST
    
    the voltage showed in debugfs and hwmon should be in mV
    
    Reviewed-by: Evan Quan <evan.quan at amd.com>
    Acked-by: Alex Deucher <alexander.deucher at amd.com>
    Signed-off-by: Rex Zhu <Rex.Zhu at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
    Cc: stable at vger.kernel.org

diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c
index 288802f209dd..0adfc5392cd3 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c
@@ -244,6 +244,7 @@ static int smu8_initialize_dpm_defaults(struct pp_hwmgr *hwmgr)
 	return 0;
 }
 
+/* convert form 8bit vid to real voltage in mV*4 */
 static uint32_t smu8_convert_8Bit_index_to_voltage(
 			struct pp_hwmgr *hwmgr, uint16_t voltage)
 {
@@ -1702,13 +1703,13 @@ static int smu8_read_sensor(struct pp_hwmgr *hwmgr, int idx,
 	case AMDGPU_PP_SENSOR_VDDNB:
 		tmp = (cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixSMUSVI_NB_CURRENTVID) &
 			CURRENT_NB_VID_MASK) >> CURRENT_NB_VID__SHIFT;
-		vddnb = smu8_convert_8Bit_index_to_voltage(hwmgr, tmp);
+		vddnb = smu8_convert_8Bit_index_to_voltage(hwmgr, tmp) / 4;
 		*((uint32_t *)value) = vddnb;
 		return 0;
 	case AMDGPU_PP_SENSOR_VDDGFX:
 		tmp = (cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixSMUSVI_GFX_CURRENTVID) &
 			CURRENT_GFX_VID_MASK) >> CURRENT_GFX_VID__SHIFT;
-		vddgfx = smu8_convert_8Bit_index_to_voltage(hwmgr, (u16)tmp);
+		vddgfx = smu8_convert_8Bit_index_to_voltage(hwmgr, (u16)tmp) / 4;
 		*((uint32_t *)value) = vddgfx;
 		return 0;
 	case AMDGPU_PP_SENSOR_UVD_VCLK:
commit 90983631a6486f68c1e95bf30713a179ac0a083f
Author: Rex Zhu <rex.zhu at amd.com>
Date:   Fri Jul 20 18:19:00 2018 +0800

    drm/amd/pp: Delete unused temp variables
    
    Only delete the dead temp variables in Polaris.
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Signed-off-by: Rex Zhu <Rex.Zhu at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
index a4ce199af475..1276f168ff68 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
@@ -1204,7 +1204,6 @@ static int polaris10_populate_smc_acpi_level(struct pp_hwmgr *hwmgr,
 			(struct phm_ppt_v1_information *)(hwmgr->pptable);
 	SMIO_Pattern vol_level;
 	uint32_t mvdd;
-	uint16_t us_mvdd;
 
 	table->ACPILevel.Flags &= ~PPSMC_SWSTATE_FLAG_DC;
 
@@ -1255,16 +1254,11 @@ static int polaris10_populate_smc_acpi_level(struct pp_hwmgr *hwmgr,
 			"in Clock Dependency Table",
 			);
 
-	us_mvdd = 0;
-	if ((SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) ||
-			(data->mclk_dpm_key_disabled))
-		us_mvdd = data->vbios_boot_state.mvdd_bootup_value;
-	else {
-		if (!polaris10_populate_mvdd_value(hwmgr,
+	if (!((SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) ||
+			(data->mclk_dpm_key_disabled)))
+		polaris10_populate_mvdd_value(hwmgr,
 				data->dpm_table.mclk_table.dpm_levels[0].value,
-				&vol_level))
-			us_mvdd = vol_level.Voltage;
-	}
+				&vol_level);
 
 	if (0 == polaris10_populate_mvdd_value(hwmgr, 0, &vol_level))
 		table->MemoryACPILevel.MinMvdd = PP_HOST_TO_SMC_UL(vol_level.Voltage);
@@ -1517,7 +1511,7 @@ static int polaris10_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr)
 	uint32_t ro, efuse, volt_without_cks, volt_with_cks, value, max, min;
 	struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(hwmgr->smu_backend);
 
-	uint8_t i, stretch_amount, stretch_amount2, volt_offset = 0;
+	uint8_t i, stretch_amount, volt_offset = 0;
 	struct phm_ppt_v1_information *table_info =
 			(struct phm_ppt_v1_information *)(hwmgr->pptable);
 	struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table =
@@ -1568,11 +1562,7 @@ static int polaris10_populate_clock_stretcher_data_table(struct pp_hwmgr *hwmgr)
 
 	smu_data->smc_state_table.LdoRefSel = (table_info->cac_dtp_table->ucCKS_LDO_REFSEL != 0) ? table_info->cac_dtp_table->ucCKS_LDO_REFSEL : 6;
 	/* Populate CKS Lookup Table */
-	if (stretch_amount == 1 || stretch_amount == 2 || stretch_amount == 5)
-		stretch_amount2 = 0;
-	else if (stretch_amount == 3 || stretch_amount == 4)
-		stretch_amount2 = 1;
-	else {
+	if (stretch_amount == 0 || stretch_amount > 5) {
 		phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
 				PHM_PlatformCaps_ClockStretcher);
 		PP_ASSERT_WITH_CODE(false,
commit 2d227ec2c11c568910299e8f913bac2dda47397c
Author: Rex Zhu <rex.zhu at amd.com>
Date:   Fri Jul 20 16:26:46 2018 +0800

    drm/amd/pp/Polaris12: Fix a chunk of registers missed to program
    
    DIDTConfig_Polaris12[] table missed a big chunk of data.
    
    Pointed by aidan.fabius <aidan.fabius at coreavi.com>
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Signed-off-by: Rex Zhu <Rex.Zhu at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
    Cc: stable at vger.kernel.org

diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c
index c952845833d7..5e19f5977eb1 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_powertune.c
@@ -403,6 +403,49 @@ static const struct gpu_pt_config_reg DIDTConfig_Polaris12[] = {
 	{   ixDIDT_SQ_CTRL1,                   DIDT_SQ_CTRL1__MAX_POWER_MASK,                      DIDT_SQ_CTRL1__MAX_POWER__SHIFT,                    0xffff,     GPU_CONFIGREG_DIDT_IND },
 
 	{   ixDIDT_SQ_CTRL_OCP,                DIDT_SQ_CTRL_OCP__UNUSED_0_MASK,                    DIDT_SQ_CTRL_OCP__UNUSED_0__SHIFT,                  0x0000,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_CTRL_OCP,                DIDT_SQ_CTRL_OCP__OCP_MAX_POWER_MASK,               DIDT_SQ_CTRL_OCP__OCP_MAX_POWER__SHIFT,             0xffff,     GPU_CONFIGREG_DIDT_IND },
+
+	{   ixDIDT_SQ_CTRL2,                   DIDT_SQ_CTRL2__MAX_POWER_DELTA_MASK,                DIDT_SQ_CTRL2__MAX_POWER_DELTA__SHIFT,              0x3853,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_CTRL2,                   DIDT_SQ_CTRL2__UNUSED_0_MASK,                       DIDT_SQ_CTRL2__UNUSED_0__SHIFT,                     0x0000,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_CTRL2,                   DIDT_SQ_CTRL2__SHORT_TERM_INTERVAL_SIZE_MASK,       DIDT_SQ_CTRL2__SHORT_TERM_INTERVAL_SIZE__SHIFT,     0x005a,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_CTRL2,                   DIDT_SQ_CTRL2__UNUSED_1_MASK,                       DIDT_SQ_CTRL2__UNUSED_1__SHIFT,                     0x0000,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_CTRL2,                   DIDT_SQ_CTRL2__LONG_TERM_INTERVAL_RATIO_MASK,       DIDT_SQ_CTRL2__LONG_TERM_INTERVAL_RATIO__SHIFT,     0x0000,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_CTRL2,                   DIDT_SQ_CTRL2__UNUSED_2_MASK,                       DIDT_SQ_CTRL2__UNUSED_2__SHIFT,                     0x0000,     GPU_CONFIGREG_DIDT_IND },
+
+	{   ixDIDT_SQ_STALL_CTRL,              DIDT_SQ_STALL_CTRL__DIDT_STALL_CTRL_ENABLE_MASK,    DIDT_SQ_STALL_CTRL__DIDT_STALL_CTRL_ENABLE__SHIFT,  0x0001,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_STALL_CTRL,              DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_HI_MASK,       DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_HI__SHIFT,     0x0001,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_STALL_CTRL,              DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_LO_MASK,       DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_LO__SHIFT,     0x0001,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_STALL_CTRL,              DIDT_SQ_STALL_CTRL__DIDT_HI_POWER_THRESHOLD_MASK,   DIDT_SQ_STALL_CTRL__DIDT_HI_POWER_THRESHOLD__SHIFT, 0x0ebb,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_STALL_CTRL,              DIDT_SQ_STALL_CTRL__UNUSED_0_MASK,                  DIDT_SQ_STALL_CTRL__UNUSED_0__SHIFT,                0x0000,     GPU_CONFIGREG_DIDT_IND },
+
+	{   ixDIDT_SQ_TUNING_CTRL,             DIDT_SQ_TUNING_CTRL__DIDT_TUNING_ENABLE_MASK,       DIDT_SQ_TUNING_CTRL__DIDT_TUNING_ENABLE__SHIFT,     0x0001,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_TUNING_CTRL,             DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_HI_MASK,       DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_HI__SHIFT,     0x3853,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_TUNING_CTRL,             DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_LO_MASK,       DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_LO__SHIFT,     0x3153,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_TUNING_CTRL,             DIDT_SQ_TUNING_CTRL__UNUSED_0_MASK,                 DIDT_SQ_TUNING_CTRL__UNUSED_0__SHIFT,               0x0000,     GPU_CONFIGREG_DIDT_IND },
+
+	{   ixDIDT_SQ_CTRL0,                   DIDT_SQ_CTRL0__DIDT_CTRL_EN_MASK,                   DIDT_SQ_CTRL0__DIDT_CTRL_EN__SHIFT,                 0x0001,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_CTRL0,                   DIDT_SQ_CTRL0__USE_REF_CLOCK_MASK,                  DIDT_SQ_CTRL0__USE_REF_CLOCK__SHIFT,                0x0000,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_CTRL0,                   DIDT_SQ_CTRL0__PHASE_OFFSET_MASK,                   DIDT_SQ_CTRL0__PHASE_OFFSET__SHIFT,                 0x0000,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_CTRL0,                   DIDT_SQ_CTRL0__DIDT_CTRL_RST_MASK,                  DIDT_SQ_CTRL0__DIDT_CTRL_RST__SHIFT,                0x0000,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_CTRL0,                   DIDT_SQ_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK,           DIDT_SQ_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT,         0x0000,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_CTRL0,                   DIDT_SQ_CTRL0__DIDT_MAX_STALLS_ALLOWED_HI_MASK,     DIDT_SQ_CTRL0__DIDT_MAX_STALLS_ALLOWED_HI__SHIFT,   0x0010,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_CTRL0,                   DIDT_SQ_CTRL0__DIDT_MAX_STALLS_ALLOWED_LO_MASK,     DIDT_SQ_CTRL0__DIDT_MAX_STALLS_ALLOWED_LO__SHIFT,   0x0010,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_SQ_CTRL0,                   DIDT_SQ_CTRL0__UNUSED_0_MASK,                       DIDT_SQ_CTRL0__UNUSED_0__SHIFT,                     0x0000,     GPU_CONFIGREG_DIDT_IND },
+
+	{   ixDIDT_TD_WEIGHT0_3,               DIDT_TD_WEIGHT0_3__WEIGHT0_MASK,                    DIDT_TD_WEIGHT0_3__WEIGHT0__SHIFT,                  0x000a,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_TD_WEIGHT0_3,               DIDT_TD_WEIGHT0_3__WEIGHT1_MASK,                    DIDT_TD_WEIGHT0_3__WEIGHT1__SHIFT,                  0x0010,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_TD_WEIGHT0_3,               DIDT_TD_WEIGHT0_3__WEIGHT2_MASK,                    DIDT_TD_WEIGHT0_3__WEIGHT2__SHIFT,                  0x0017,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_TD_WEIGHT0_3,               DIDT_TD_WEIGHT0_3__WEIGHT3_MASK,                    DIDT_TD_WEIGHT0_3__WEIGHT3__SHIFT,                  0x002f,     GPU_CONFIGREG_DIDT_IND },
+
+	{   ixDIDT_TD_WEIGHT4_7,               DIDT_TD_WEIGHT4_7__WEIGHT4_MASK,                    DIDT_TD_WEIGHT4_7__WEIGHT4__SHIFT,                  0x0046,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_TD_WEIGHT4_7,               DIDT_TD_WEIGHT4_7__WEIGHT5_MASK,                    DIDT_TD_WEIGHT4_7__WEIGHT5__SHIFT,                  0x005d,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_TD_WEIGHT4_7,               DIDT_TD_WEIGHT4_7__WEIGHT6_MASK,                    DIDT_TD_WEIGHT4_7__WEIGHT6__SHIFT,                  0x0000,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_TD_WEIGHT4_7,               DIDT_TD_WEIGHT4_7__WEIGHT7_MASK,                    DIDT_TD_WEIGHT4_7__WEIGHT7__SHIFT,                  0x0000,     GPU_CONFIGREG_DIDT_IND },
+
+	{   ixDIDT_TD_CTRL1,                   DIDT_TD_CTRL1__MIN_POWER_MASK,                      DIDT_TD_CTRL1__MIN_POWER__SHIFT,                    0x0000,     GPU_CONFIGREG_DIDT_IND },
+	{   ixDIDT_TD_CTRL1,                   DIDT_TD_CTRL1__MAX_POWER_MASK,                      DIDT_TD_CTRL1__MAX_POWER__SHIFT,                    0xffff,     GPU_CONFIGREG_DIDT_IND },
+
+	{   ixDIDT_TD_CTRL_OCP,                DIDT_TD_CTRL_OCP__UNUSED_0_MASK,                    DIDT_TD_CTRL_OCP__UNUSED_0__SHIFT,                  0x0000,     GPU_CONFIGREG_DIDT_IND },
 	{   ixDIDT_TD_CTRL_OCP,                DIDT_TD_CTRL_OCP__OCP_MAX_POWER_MASK,               DIDT_TD_CTRL_OCP__OCP_MAX_POWER__SHIFT,             0x00ff,     GPU_CONFIGREG_DIDT_IND },
 
 	{   ixDIDT_TD_CTRL2,                   DIDT_TD_CTRL2__MAX_POWER_DELTA_MASK,                DIDT_TD_CTRL2__MAX_POWER_DELTA__SHIFT,              0x3fff,     GPU_CONFIGREG_DIDT_IND },
commit d664b851eb2bcdf84a3c063cf59457bb15bc6120
Author: Liviu Dudau <Liviu.Dudau at arm.com>
Date:   Mon Jul 23 12:05:53 2018 +0100

    drm/arm/hdlcd: Reject atomic commits that disable only the plane
    
    The HDLCD engine needs an active plane while the CRTC is active, as
    it will start scanning out data from HDLCD_REG_FB_BASE once it gets
    enabled. Make sure that the only available plane doesn't get disabled
    while the CRTC remains active, as this will scanout invalid data.
    
    Signed-off-by: Liviu Dudau <liviu.dudau at arm.com>

diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index 8978d82159e5..e4d67b70244d 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -229,6 +229,8 @@ static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = {
 static int hdlcd_plane_atomic_check(struct drm_plane *plane,
 				    struct drm_plane_state *state)
 {
+	int i;
+	struct drm_crtc *crtc;
 	struct drm_crtc_state *crtc_state;
 	u32 src_h = state->src_h >> 16;
 
@@ -238,20 +240,17 @@ static int hdlcd_plane_atomic_check(struct drm_plane *plane,
 		return -EINVAL;
 	}
 
-	if (!state->fb || !state->crtc)
-		return 0;
-
-	crtc_state = drm_atomic_get_existing_crtc_state(state->state,
-							state->crtc);
-	if (!crtc_state) {
-		DRM_DEBUG_KMS("Invalid crtc state\n");
-		return -EINVAL;
+	for_each_new_crtc_in_state(state->state, crtc, crtc_state, i) {
+		/* we cannot disable the plane while the CRTC is active */
+		if (!state->fb && crtc_state->active)
+			return -EINVAL;
+		return drm_atomic_helper_check_plane_state(state, crtc_state,
+						DRM_PLANE_HELPER_NO_SCALING,
+						DRM_PLANE_HELPER_NO_SCALING,
+						false, true);
 	}
 
-	return drm_atomic_helper_check_plane_state(state, crtc_state,
-						   DRM_PLANE_HELPER_NO_SCALING,
-						   DRM_PLANE_HELPER_NO_SCALING,
-						   false, true);
+	return 0;
 }
 
 static void hdlcd_plane_atomic_update(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 70fca288313a..0ed1cde98cf8 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -325,6 +325,7 @@ err_fbdev:
 err_vblank:
 	pm_runtime_disable(drm->dev);
 err_pm_active:
+	drm_atomic_helper_shutdown(drm);
 	component_unbind_all(dev, drm);
 err_unload:
 	of_node_put(hdlcd->crtc.port);
@@ -350,16 +351,18 @@ static void hdlcd_drm_unbind(struct device *dev)
 	component_unbind_all(dev, drm);
 	of_node_put(hdlcd->crtc.port);
 	hdlcd->crtc.port = NULL;
-	pm_runtime_get_sync(drm->dev);
+	pm_runtime_get_sync(dev);
+	drm_crtc_vblank_off(&hdlcd->crtc);
 	drm_irq_uninstall(drm);
-	pm_runtime_put_sync(drm->dev);
-	pm_runtime_disable(drm->dev);
-	of_reserved_mem_device_release(drm->dev);
 	drm_atomic_helper_shutdown(drm);
+	pm_runtime_put(dev);
+	if (pm_runtime_enabled(dev))
+		pm_runtime_disable(dev);
+	of_reserved_mem_device_release(dev);
 	drm_mode_config_cleanup(drm);
-	drm_dev_put(drm);
 	drm->dev_private = NULL;
 	dev_set_drvdata(dev, NULL);
+	drm_dev_put(drm);
 }
 
 static const struct component_master_ops hdlcd_master_ops = {
commit 9fd466f54f89fc3a2dc6f86fce2ea0b993ff83bd
Author: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
Date:   Wed Jan 17 23:55:28 2018 +0200

    drm: arm: hdlcd: Use drm_atomic_helper_shutdown() to disable planes on removal
    
    The plane cleanup handler currently calls drm_plane_helper_disable(),
    which is a legacy helper function. Replace it with a call to
    drm_atomic_helper_shutdown() at removal time. The plane .destroy()
    handler now consisting only of a call to drm_plane_cleanup(), replace it
    with direct calls to that function.
    
    Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
    Signed-off-by: Liviu Dudau <liviu.dudau at arm.com>

diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index c36c75bef6d9..8978d82159e5 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -280,16 +280,10 @@ static const struct drm_plane_helper_funcs hdlcd_plane_helper_funcs = {
 	.atomic_update = hdlcd_plane_atomic_update,
 };
 
-static void hdlcd_plane_destroy(struct drm_plane *plane)
-{
-	drm_plane_helper_disable(plane, NULL);
-	drm_plane_cleanup(plane);
-}
-
 static const struct drm_plane_funcs hdlcd_plane_funcs = {
 	.update_plane		= drm_atomic_helper_update_plane,
 	.disable_plane		= drm_atomic_helper_disable_plane,
-	.destroy		= hdlcd_plane_destroy,
+	.destroy		= drm_plane_cleanup,
 	.reset			= drm_atomic_helper_plane_reset,
 	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
 	.atomic_destroy_state	= drm_atomic_helper_plane_destroy_state,
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index fd5b8c44af14..70fca288313a 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -355,6 +355,7 @@ static void hdlcd_drm_unbind(struct device *dev)
 	pm_runtime_put_sync(drm->dev);
 	pm_runtime_disable(drm->dev);
 	of_reserved_mem_device_release(drm->dev);
+	drm_atomic_helper_shutdown(drm);
 	drm_mode_config_cleanup(drm);
 	drm_dev_put(drm);
 	drm->dev_private = NULL;
commit 8df24d57d34cd229e7094cfd1b927b585585202d
Author: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
Date:   Wed Jan 17 23:55:27 2018 +0200

    drm: arm: hdlcd: Don't destroy plane manually in hdlcd_setup_crtc()
    
    The top-level error handler calls drm_mode_config_cleanup() which will
    destroy all planes. There's no need to destroy them manually in lower
    error handlers.
    
    Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
    Signed-off-by: Liviu Dudau <liviu.dudau at arm.com>

diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index f3f08cd6e9ef..c36c75bef6d9 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -334,10 +334,8 @@ int hdlcd_setup_crtc(struct drm_device *drm)
 
 	ret = drm_crtc_init_with_planes(drm, &hdlcd->crtc, primary, NULL,
 					&hdlcd_crtc_funcs, NULL);
-	if (ret) {
-		hdlcd_plane_destroy(primary);
+	if (ret)
 		return ret;
-	}
 
 	drm_crtc_helper_add(&hdlcd->crtc, &hdlcd_crtc_helper_funcs);
 	return 0;
commit 1785dbc412c257879274e8807afd6dfdfe06c47b
Author: Noralf Trønnes <noralf at tronnes.org>
Date:   Fri Dec 8 20:37:35 2017 +0100

    drm/arm/hdlcd: Use drm_fb_cma_fbdev_init/fini()
    
    Use drm_fb_cma_fbdev_init() and drm_fb_cma_fbdev_fini() which relies on
    the fact that drm_device holds a pointer to the drm_fb_helper structure.
    This means that the driver doesn't have to keep track of that.
    Also use the drm_fb_helper functions directly.
    
    Cc: Liviu Dudau <liviu.dudau at arm.com>
    Cc: Brian Starkey <brian.starkey at arm.com>
    Signed-off-by: Noralf Trønnes <noralf at tronnes.org>
    Acked-by: Liviu Dudau <liviu.dudau at arm.com>
    Signed-off-by: Liviu Dudau <liviu.dudau at arm.com>

diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 9800a9e388ef..fd5b8c44af14 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -101,16 +101,9 @@ setup_fail:
 	return ret;
 }
 
-static void hdlcd_fb_output_poll_changed(struct drm_device *drm)
-{
-	struct hdlcd_drm_private *hdlcd = drm->dev_private;
-
-	drm_fbdev_cma_hotplug_event(hdlcd->fbdev);
-}
-
 static const struct drm_mode_config_funcs hdlcd_mode_config_funcs = {
 	.fb_create = drm_gem_fb_create,
-	.output_poll_changed = hdlcd_fb_output_poll_changed,
+	.output_poll_changed = drm_fb_helper_output_poll_changed,
 	.atomic_check = drm_atomic_helper_check,
 	.atomic_commit = drm_atomic_helper_commit,
 };
@@ -125,13 +118,6 @@ static void hdlcd_setup_mode_config(struct drm_device *drm)
 	drm->mode_config.funcs = &hdlcd_mode_config_funcs;
 }
 
-static void hdlcd_lastclose(struct drm_device *drm)
-{
-	struct hdlcd_drm_private *hdlcd = drm->dev_private;
-
-	drm_fbdev_cma_restore_mode(hdlcd->fbdev);
-}
-
 static irqreturn_t hdlcd_irq(int irq, void *arg)
 {
 	struct drm_device *drm = arg;
@@ -247,7 +233,7 @@ static struct drm_driver hdlcd_driver = {
 	.driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM |
 			   DRIVER_MODESET | DRIVER_PRIME |
 			   DRIVER_ATOMIC,
-	.lastclose = hdlcd_lastclose,
+	.lastclose = drm_fb_helper_lastclose,
 	.irq_handler = hdlcd_irq,
 	.irq_preinstall = hdlcd_irq_preinstall,
 	.irq_postinstall = hdlcd_irq_postinstall,
@@ -322,14 +308,9 @@ static int hdlcd_drm_bind(struct device *dev)
 	drm_mode_config_reset(drm);
 	drm_kms_helper_poll_init(drm);
 
-	hdlcd->fbdev = drm_fbdev_cma_init(drm, 32,
-					  drm->mode_config.num_connector);
-
-	if (IS_ERR(hdlcd->fbdev)) {
-		ret = PTR_ERR(hdlcd->fbdev);
-		hdlcd->fbdev = NULL;
+	ret = drm_fb_cma_fbdev_init(drm, 32, 0);
+	if (ret)
 		goto err_fbdev;
-	}
 
 	ret = drm_dev_register(drm, 0);
 	if (ret)
@@ -338,10 +319,7 @@ static int hdlcd_drm_bind(struct device *dev)
 	return 0;
 
 err_register:
-	if (hdlcd->fbdev) {
-		drm_fbdev_cma_fini(hdlcd->fbdev);
-		hdlcd->fbdev = NULL;
-	}
+	drm_fb_cma_fbdev_fini(drm);
 err_fbdev:
 	drm_kms_helper_poll_fini(drm);
 err_vblank:
@@ -367,10 +345,7 @@ static void hdlcd_drm_unbind(struct device *dev)
 	struct hdlcd_drm_private *hdlcd = drm->dev_private;
 
 	drm_dev_unregister(drm);
-	if (hdlcd->fbdev) {
-		drm_fbdev_cma_fini(hdlcd->fbdev);
-		hdlcd->fbdev = NULL;
-	}
+	drm_fb_cma_fbdev_fini(drm);
 	drm_kms_helper_poll_fini(drm);
 	component_unbind_all(dev, drm);
 	of_node_put(hdlcd->crtc.port);
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.h b/drivers/gpu/drm/arm/hdlcd_drv.h
index 58d75d7e1b20..fd438d177b64 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.h
+++ b/drivers/gpu/drm/arm/hdlcd_drv.h
@@ -9,7 +9,6 @@
 struct hdlcd_drm_private {
 	void __iomem			*mmio;
 	struct clk			*clk;
-	struct drm_fbdev_cma		*fbdev;
 	struct drm_crtc			crtc;
 	struct drm_plane		*plane;
 #ifdef CONFIG_DEBUG_FS
commit 5c7e5a22c126e4d7839e6bdcc05b3c4dfa945a72
Author: Noralf Trønnes <noralf at tronnes.org>
Date:   Fri Dec 8 20:37:34 2017 +0100

    drm/arm/hdlcd: Use drm_mode_config_helper_suspend/resume()
    
    Replace driver's code with the generic helpers that do the same thing
    including the NULL check.
    
    Cc: Liviu Dudau <liviu.dudau at arm.com>
    Cc: Brian Starkey <brian.starkey at arm.com>
    Signed-off-by: Noralf Trønnes <noralf at tronnes.org>
    Signed-off-by: Liviu Dudau <liviu.dudau at arm.com>

diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index feaa8bc3d7b7..9800a9e388ef 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -27,6 +27,7 @@
 #include <drm/drm_fb_cma_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_modeset_helper.h>
 #include <drm/drm_of.h>
 
 #include "hdlcd_drv.h"
@@ -427,35 +428,15 @@ MODULE_DEVICE_TABLE(of, hdlcd_of_match);
 static int __maybe_unused hdlcd_pm_suspend(struct device *dev)
 {
 	struct drm_device *drm = dev_get_drvdata(dev);
-	struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL;
 
-	if (!hdlcd)
-		return 0;
-
-	drm_kms_helper_poll_disable(drm);
-	drm_fbdev_cma_set_suspend_unlocked(hdlcd->fbdev, 1);
-
-	hdlcd->state = drm_atomic_helper_suspend(drm);
-	if (IS_ERR(hdlcd->state)) {
-		drm_fbdev_cma_set_suspend_unlocked(hdlcd->fbdev, 0);
-		drm_kms_helper_poll_enable(drm);
-		return PTR_ERR(hdlcd->state);
-	}
-
-	return 0;
+	return drm_mode_config_helper_suspend(drm);
 }
 
 static int __maybe_unused hdlcd_pm_resume(struct device *dev)
 {
 	struct drm_device *drm = dev_get_drvdata(dev);
-	struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL;
-
-	if (!hdlcd)
-		return 0;
 
-	drm_atomic_helper_resume(drm, hdlcd->state);
-	drm_fbdev_cma_set_suspend_unlocked(hdlcd->fbdev, 0);
-	drm_kms_helper_poll_enable(drm);
+	drm_mode_config_helper_resume(drm);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.h b/drivers/gpu/drm/arm/hdlcd_drv.h
index 56f34dfff640..58d75d7e1b20 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.h
+++ b/drivers/gpu/drm/arm/hdlcd_drv.h
@@ -12,7 +12,6 @@ struct hdlcd_drm_private {
 	struct drm_fbdev_cma		*fbdev;
 	struct drm_crtc			crtc;
 	struct drm_plane		*plane;
-	struct drm_atomic_state		*state;
 #ifdef CONFIG_DEBUG_FS
 	atomic_t buffer_underrun_count;
 	atomic_t bus_error_count;
commit caca1ff0de6212682f6000db53388800046db887
Merge: 3fce46182793 90991209837a
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Jul 31 08:24:02 2018 +1000

    Merge branch 'drm-udl-next' of git://people.freedesktop.org/~airlied/linux into drm-next
    
    A set of cleanups and fixes for Mikulas for using udl on arm boards.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/CAPM=9twQNgrmfe0=Okq1NTgWHRQXy+AzeDy8A0p_-y856p4vtA@mail.gmail.com

commit 90991209837ab619555a46a97a88dead7a960d2d
Author: Mikulas Patocka <mpatocka at redhat.com>
Date:   Sun Jun 3 16:41:03 2018 +0200

    udl-kms: dont spam the syslog with debug messages
    
    The udl kms driver writes messages to the syslog whenever some application
    opens or closes /dev/fb0 and whenever the user switches between the
    Xserver and the console.
    
    This patch changes the priority of these messages to debug.
    
    Signed-off-by: Mikulas Patocka <mpatocka at redhat.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
index 8746eeeec44d..dbb62f6eb48a 100644
--- a/drivers/gpu/drm/udl/udl_fb.c
+++ b/drivers/gpu/drm/udl/udl_fb.c
@@ -178,7 +178,7 @@ static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
 	pos = (unsigned long)info->fix.smem_start + offset;
 
-	pr_notice("mmap() framebuffer addr:%lu size:%lu\n",
+	pr_debug("mmap() framebuffer addr:%lu size:%lu\n",
 		  pos, size);
 
 	/* We don't want the framebuffer to be mapped encrypted */
@@ -236,7 +236,7 @@ static int udl_fb_open(struct fb_info *info, int user)
 	}
 #endif
 
-	pr_notice("open /dev/fb%d user=%d fb_info=%p count=%d\n",
+	pr_debug("open /dev/fb%d user=%d fb_info=%p count=%d\n",
 		  info->node, user, info, ufbdev->fb_count);
 
 	return 0;
@@ -261,7 +261,7 @@ static int udl_fb_release(struct fb_info *info, int user)
 	}
 #endif
 
-	pr_warn("released /dev/fb%d user=%d count=%d\n",
+	pr_debug("released /dev/fb%d user=%d count=%d\n",
 		info->node, user, ufbdev->fb_count);
 
 	return 0;
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
index 98c6a58bcb07..7e37765cf5ac 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -243,7 +243,7 @@ static int udl_crtc_write_mode_to_hw(struct drm_crtc *crtc)
 
 	memcpy(buf, udl->mode_buf, udl->mode_buf_len);
 	retval = udl_submit_urb(dev, urb, udl->mode_buf_len);
-	DRM_INFO("write mode info %d\n", udl->mode_buf_len);
+	DRM_DEBUG("write mode info %d\n", udl->mode_buf_len);
 	return retval;
 }
 
commit c2f53119b410047e5d97de2a5ec74157d2e58986
Author: Mikulas Patocka <mpatocka at redhat.com>
Date:   Sun Jun 3 16:41:02 2018 +0200

    udl-kms: use spin_lock_irq instead of spin_lock_irqsave
    
    spin_lock_irqsave and spin_unlock_irqrestore is inteded to be called from
    a context where it is unknown if interrupts are enabled or disabled (such
    as interrupt handlers). From a process context, we should call
    spin_lock_irq and spin_unlock_irq, that avoids the costly pushf and popf
    instructions.
    
    Signed-off-by: Mikulas Patocka <mpatocka at redhat.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index 7e9ad926926a..f455f095a146 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -170,7 +170,6 @@ static void udl_free_urb_list(struct drm_device *dev)
 	struct list_head *node;
 	struct urb_node *unode;
 	struct urb *urb;
-	unsigned long flags;
 
 	DRM_DEBUG("Waiting for completes and freeing all render urbs\n");
 
@@ -178,12 +177,12 @@ static void udl_free_urb_list(struct drm_device *dev)
 	while (count--) {
 		down(&udl->urbs.limit_sem);
 
-		spin_lock_irqsave(&udl->urbs.lock, flags);
+		spin_lock_irq(&udl->urbs.lock);
 
 		node = udl->urbs.list.next; /* have reserved one with sem */
 		list_del_init(node);
 
-		spin_unlock_irqrestore(&udl->urbs.lock, flags);
+		spin_unlock_irq(&udl->urbs.lock);
 
 		unode = list_entry(node, struct urb_node, entry);
 		urb = unode->urb;
@@ -268,7 +267,6 @@ struct urb *udl_get_urb(struct drm_device *dev)
 	struct list_head *entry;
 	struct urb_node *unode;
 	struct urb *urb = NULL;
-	unsigned long flags;
 
 	/* Wait for an in-flight buffer to complete and get re-queued */
 	ret = down_timeout(&udl->urbs.limit_sem, GET_URB_TIMEOUT);
@@ -279,14 +277,14 @@ struct urb *udl_get_urb(struct drm_device *dev)
 		goto error;
 	}
 
-	spin_lock_irqsave(&udl->urbs.lock, flags);
+	spin_lock_irq(&udl->urbs.lock);
 
 	BUG_ON(list_empty(&udl->urbs.list)); /* reserved one with limit_sem */
 	entry = udl->urbs.list.next;
 	list_del_init(entry);
 	udl->urbs.available--;
 
-	spin_unlock_irqrestore(&udl->urbs.lock, flags);
+	spin_unlock_irq(&udl->urbs.lock);
 
 	unode = list_entry(entry, struct urb_node, entry);
 	urb = unode->urb;
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
index 5bcae7649795..98c6a58bcb07 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -366,7 +366,6 @@ static int udl_crtc_page_flip(struct drm_crtc *crtc,
 {
 	struct udl_framebuffer *ufb = to_udl_fb(fb);
 	struct drm_device *dev = crtc->dev;
-	unsigned long flags;
 
 	struct drm_framebuffer *old_fb = crtc->primary->fb;
 	if (old_fb) {
@@ -377,10 +376,10 @@ static int udl_crtc_page_flip(struct drm_crtc *crtc,
 
 	udl_handle_damage(ufb, 0, 0, fb->width, fb->height);
 
-	spin_lock_irqsave(&dev->event_lock, flags);
+	spin_lock_irq(&dev->event_lock);
 	if (event)
 		drm_crtc_send_vblank_event(crtc, event);
-	spin_unlock_irqrestore(&dev->event_lock, flags);
+	spin_unlock_irq(&dev->event_lock);
 	crtc->primary->fb = fb;
 
 	return 0;
commit 58cba7c222e8c87bb6b61fcba21d1536145221b0
Author: Mikulas Patocka <mpatocka at redhat.com>
Date:   Sun Jun 3 16:41:01 2018 +0200

    udl-kms: avoid prefetch
    
    Modern processors can detect linear memory accesses and prefetch data
    automatically, so there's no need to use prefetch.
    
    Signed-off-by: Mikulas Patocka <mpatocka at redhat.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c
index f3331d33547a..ce87661e544f 100644
--- a/drivers/gpu/drm/udl/udl_transfer.c
+++ b/drivers/gpu/drm/udl/udl_transfer.c
@@ -13,7 +13,6 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/fb.h>
-#include <linux/prefetch.h>
 #include <asm/unaligned.h>
 
 #include <drm/drmP.h>
@@ -51,9 +50,6 @@ static int udl_trim_hline(const u8 *bback, const u8 **bfront, int *width_bytes)
 	int start = width;
 	int end = width;
 
-	prefetch((void *) front);
-	prefetch((void *) back);
-
 	for (j = 0; j < width; j++) {
 		if (back[j] != front[j]) {
 			start = j;
@@ -140,8 +136,6 @@ static void udl_compress_hline16(
 		const u8 *cmd_pixel_start, *cmd_pixel_end = NULL;
 		uint16_t pixel_val16;
 
-		prefetchw((void *) cmd); /* pull in one cache line at least */
-
 		*cmd++ = 0xaf;
 		*cmd++ = 0x6b;
 		*cmd++ = (uint8_t) ((dev_addr >> 16) & 0xFF);
@@ -158,7 +152,6 @@ static void udl_compress_hline16(
 					(unsigned long)(pixel_end - pixel) >> log_bpp,
 					(unsigned long)(cmd_buffer_end - 1 - cmd) / 2) << log_bpp);
 
-		prefetch_range((void *) pixel, cmd_pixel_end - pixel);
 		pixel_val16 = get_pixel_val16(pixel, log_bpp);
 
 		while (pixel < cmd_pixel_end) {
commit 91ba11fb7d7ca0a3bbe8a512e65e666e2ec1e889
Author: Mikulas Patocka <mpatocka at redhat.com>
Date:   Sun Jun 3 16:41:00 2018 +0200

    udl-kms: avoid division
    
    Division is slow, so it shouldn't be done by the pixel generating code.
    The driver supports only 2 or 4 bytes per pixel, so we can replace
    division with a shift.
    
    Signed-off-by: Mikulas Patocka <mpatocka at redhat.com>
    Cc: stable at vger.kernel.org
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
index 55c0cc309198..7588a9eb0ee0 100644
--- a/drivers/gpu/drm/udl/udl_drv.h
+++ b/drivers/gpu/drm/udl/udl_drv.h
@@ -112,7 +112,7 @@ udl_fb_user_fb_create(struct drm_device *dev,
 		      struct drm_file *file,
 		      const struct drm_mode_fb_cmd2 *mode_cmd);
 
-int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
+int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr,
 		     const char *front, char **urb_buf_ptr,
 		     u32 byte_offset, u32 device_byte_offset, u32 byte_width,
 		     int *ident_ptr, int *sent_ptr);
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
index c3f5867dac91..8746eeeec44d 100644
--- a/drivers/gpu/drm/udl/udl_fb.c
+++ b/drivers/gpu/drm/udl/udl_fb.c
@@ -90,7 +90,10 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
 	int bytes_identical = 0;
 	struct urb *urb;
 	int aligned_x;
-	int bpp = fb->base.format->cpp[0];
+	int log_bpp;
+
+	BUG_ON(!is_power_of_2(fb->base.format->cpp[0]));
+	log_bpp = __ffs(fb->base.format->cpp[0]);
 
 	if (!fb->active_16)
 		return 0;
@@ -125,12 +128,12 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
 
 	for (i = y; i < y + height ; i++) {
 		const int line_offset = fb->base.pitches[0] * i;
-		const int byte_offset = line_offset + (x * bpp);
-		const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp);
-		if (udl_render_hline(dev, bpp, &urb,
+		const int byte_offset = line_offset + (x << log_bpp);
+		const int dev_byte_offset = (fb->base.width * i + x) << log_bpp;
+		if (udl_render_hline(dev, log_bpp, &urb,
 				     (char *) fb->obj->vmapping,
 				     &cmd, byte_offset, dev_byte_offset,
-				     width * bpp,
+				     width << log_bpp,
 				     &bytes_identical, &bytes_sent))
 			goto error;
 	}
@@ -149,7 +152,7 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
 error:
 	atomic_add(bytes_sent, &udl->bytes_sent);
 	atomic_add(bytes_identical, &udl->bytes_identical);
-	atomic_add(width*height*bpp, &udl->bytes_rendered);
+	atomic_add((width * height) << log_bpp, &udl->bytes_rendered);
 	end_cycles = get_cycles();
 	atomic_add(((unsigned int) ((end_cycles - start_cycles)
 		    >> 10)), /* Kcycles */
diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c
index b992644c17e6..f3331d33547a 100644
--- a/drivers/gpu/drm/udl/udl_transfer.c
+++ b/drivers/gpu/drm/udl/udl_transfer.c
@@ -83,12 +83,12 @@ static inline u16 pixel32_to_be16(const uint32_t pixel)
 		((pixel >> 8) & 0xf800));
 }
 
-static inline u16 get_pixel_val16(const uint8_t *pixel, int bpp)
+static inline u16 get_pixel_val16(const uint8_t *pixel, int log_bpp)
 {
-	u16 pixel_val16 = 0;
-	if (bpp == 2)
+	u16 pixel_val16;
+	if (log_bpp == 1)
 		pixel_val16 = *(const uint16_t *)pixel;
-	else if (bpp == 4)
+	else
 		pixel_val16 = pixel32_to_be16(*(const uint32_t *)pixel);
 	return pixel_val16;
 }
@@ -125,8 +125,9 @@ static void udl_compress_hline16(
 	const u8 *const pixel_end,
 	uint32_t *device_address_ptr,
 	uint8_t **command_buffer_ptr,
-	const uint8_t *const cmd_buffer_end, int bpp)
+	const uint8_t *const cmd_buffer_end, int log_bpp)
 {
+	const int bpp = 1 << log_bpp;
 	const u8 *pixel = *pixel_start_ptr;
 	uint32_t dev_addr  = *device_address_ptr;
 	uint8_t *cmd = *command_buffer_ptr;
@@ -153,12 +154,12 @@ static void udl_compress_hline16(
 		raw_pixels_count_byte = cmd++; /*  we'll know this later */
 		raw_pixel_start = pixel;
 
-		cmd_pixel_end = pixel + min3(MAX_CMD_PIXELS + 1UL,
-					(unsigned long)(pixel_end - pixel) / bpp,
-					(unsigned long)(cmd_buffer_end - 1 - cmd) / 2) * bpp;
+		cmd_pixel_end = pixel + (min3(MAX_CMD_PIXELS + 1UL,
+					(unsigned long)(pixel_end - pixel) >> log_bpp,
+					(unsigned long)(cmd_buffer_end - 1 - cmd) / 2) << log_bpp);
 
 		prefetch_range((void *) pixel, cmd_pixel_end - pixel);
-		pixel_val16 = get_pixel_val16(pixel, bpp);
+		pixel_val16 = get_pixel_val16(pixel, log_bpp);
 
 		while (pixel < cmd_pixel_end) {
 			const u8 *const start = pixel;
@@ -170,7 +171,7 @@ static void udl_compress_hline16(
 			pixel += bpp;
 
 			while (pixel < cmd_pixel_end) {
-				pixel_val16 = get_pixel_val16(pixel, bpp);
+				pixel_val16 = get_pixel_val16(pixel, log_bpp);
 				if (pixel_val16 != repeating_pixel_val16)
 					break;
 				pixel += bpp;
@@ -179,10 +180,10 @@ static void udl_compress_hline16(
 			if (unlikely(pixel > start + bpp)) {
 				/* go back and fill in raw pixel count */
 				*raw_pixels_count_byte = (((start -
-						raw_pixel_start) / bpp) + 1) & 0xFF;
+						raw_pixel_start) >> log_bpp) + 1) & 0xFF;
 
 				/* immediately after raw data is repeat byte */
-				*cmd++ = (((pixel - start) / bpp) - 1) & 0xFF;
+				*cmd++ = (((pixel - start) >> log_bpp) - 1) & 0xFF;
 
 				/* Then start another raw pixel span */
 				raw_pixel_start = pixel;
@@ -192,14 +193,14 @@ static void udl_compress_hline16(
 
 		if (pixel > raw_pixel_start) {
 			/* finalize last RAW span */
-			*raw_pixels_count_byte = ((pixel-raw_pixel_start) / bpp) & 0xFF;
+			*raw_pixels_count_byte = ((pixel - raw_pixel_start) >> log_bpp) & 0xFF;
 		} else {
 			/* undo unused byte */
 			cmd--;
 		}
 
-		*cmd_pixels_count_byte = ((pixel - cmd_pixel_start) / bpp) & 0xFF;
-		dev_addr += ((pixel - cmd_pixel_start) / bpp) * 2;
+		*cmd_pixels_count_byte = ((pixel - cmd_pixel_start) >> log_bpp) & 0xFF;
+		dev_addr += ((pixel - cmd_pixel_start) >> log_bpp) * 2;
 	}
 
 	if (cmd_buffer_end <= MIN_RLX_CMD_BYTES + cmd) {
@@ -222,19 +223,19 @@ static void udl_compress_hline16(
  * (that we can only write to, slowly, and can never read), and (optionally)
  * our shadow copy that tracks what's been sent to that hardware buffer.
  */
-int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
+int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr,
 		     const char *front, char **urb_buf_ptr,
 		     u32 byte_offset, u32 device_byte_offset,
 		     u32 byte_width,
 		     int *ident_ptr, int *sent_ptr)
 {
 	const u8 *line_start, *line_end, *next_pixel;
-	u32 base16 = 0 + (device_byte_offset / bpp) * 2;
+	u32 base16 = 0 + (device_byte_offset >> log_bpp) * 2;
 	struct urb *urb = *urb_ptr;
 	u8 *cmd = *urb_buf_ptr;
 	u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length;
 
-	BUG_ON(!(bpp == 2 || bpp == 4));
+	BUG_ON(!(log_bpp == 1 || log_bpp == 2));
 
 	line_start = (u8 *) (front + byte_offset);
 	next_pixel = line_start;
@@ -244,7 +245,7 @@ int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
 
 		udl_compress_hline16(&next_pixel,
 			     line_end, &base16,
-			     (u8 **) &cmd, (u8 *) cmd_end, bpp);
+			     (u8 **) &cmd, (u8 *) cmd_end, log_bpp);
 
 		if (cmd >= cmd_end) {
 			int len = cmd - (u8 *) urb->transfer_buffer;
commit 09a00abe3a9941c2715ca83eb88172cd2f54d8fd
Author: Mikulas Patocka <mpatocka at redhat.com>
Date:   Sun Jun 3 16:40:57 2018 +0200

    udl-kms: fix crash due to uninitialized memory
    
    We must use kzalloc when allocating the fb_deferred_io structure.
    Otherwise, the field first_io is undefined and it causes a crash.
    
    Signed-off-by: Mikulas Patocka <mpatocka at redhat.com>
    Cc: stable at vger.kernel.org
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
index d5583190f3e4..c3f5867dac91 100644
--- a/drivers/gpu/drm/udl/udl_fb.c
+++ b/drivers/gpu/drm/udl/udl_fb.c
@@ -221,7 +221,7 @@ static int udl_fb_open(struct fb_info *info, int user)
 
 		struct fb_deferred_io *fbdefio;
 
-		fbdefio = kmalloc(sizeof(struct fb_deferred_io), GFP_KERNEL);
+		fbdefio = kzalloc(sizeof(struct fb_deferred_io), GFP_KERNEL);
 
 		if (fbdefio) {
 			fbdefio->delay = DL_DEFIO_WRITE_DELAY;
commit 542bb9788a1f485eb1a2229178f665d8ea166156
Author: Mikulas Patocka <mpatocka at redhat.com>
Date:   Sun Jun 3 16:40:56 2018 +0200

    udl-kms: handle allocation failure
    
    Allocations larger than PAGE_ALLOC_COSTLY_ORDER are unreliable and they
    may fail anytime. This patch fixes the udl kms driver so that when a large
    alloactions fails, it tries to do multiple smaller allocations.
    
    Signed-off-by: Mikulas Patocka <mpatocka at redhat.com>
    Cc: stable at vger.kernel.org
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index 1239decd46ff..7e9ad926926a 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -200,17 +200,22 @@ static void udl_free_urb_list(struct drm_device *dev)
 static int udl_alloc_urb_list(struct drm_device *dev, int count, size_t size)
 {
 	struct udl_device *udl = dev->dev_private;
-	int i = 0;
 	struct urb *urb;
 	struct urb_node *unode;
 	char *buf;
+	size_t wanted_size = count * size;
 
 	spin_lock_init(&udl->urbs.lock);
 
+retry:
 	udl->urbs.size = size;
 	INIT_LIST_HEAD(&udl->urbs.list);
 
-	while (i < count) {
+	sema_init(&udl->urbs.limit_sem, 0);
+	udl->urbs.count = 0;
+	udl->urbs.available = 0;
+
+	while (udl->urbs.count * size < wanted_size) {
 		unode = kzalloc(sizeof(struct urb_node), GFP_KERNEL);
 		if (!unode)
 			break;
@@ -226,11 +231,16 @@ static int udl_alloc_urb_list(struct drm_device *dev, int count, size_t size)
 		}
 		unode->urb = urb;
 
-		buf = usb_alloc_coherent(udl->udev, MAX_TRANSFER, GFP_KERNEL,
+		buf = usb_alloc_coherent(udl->udev, size, GFP_KERNEL,
 					 &urb->transfer_dma);
 		if (!buf) {
 			kfree(unode);
 			usb_free_urb(urb);
+			if (size > PAGE_SIZE) {
+				size /= 2;
+				udl_free_urb_list(dev);
+				goto retry;
+			}
 			break;
 		}
 
@@ -241,16 +251,14 @@ static int udl_alloc_urb_list(struct drm_device *dev, int count, size_t size)
 
 		list_add_tail(&unode->entry, &udl->urbs.list);
 
-		i++;
+		up(&udl->urbs.limit_sem);
+		udl->urbs.count++;
+		udl->urbs.available++;
 	}
 
-	sema_init(&udl->urbs.limit_sem, i);
-	udl->urbs.count = i;
-	udl->urbs.available = i;
-
-	DRM_DEBUG("allocated %d %d byte urbs\n", i, (int) size);
+	DRM_DEBUG("allocated %d %d byte urbs\n", udl->urbs.count, (int) size);
 
-	return i;
+	return udl->urbs.count;
 }
 
 struct urb *udl_get_urb(struct drm_device *dev)
commit 8456b99c16d193c4c3b7df305cf431e027f0189c
Author: Mikulas Patocka <mpatocka at redhat.com>
Date:   Sun Jun 3 16:40:55 2018 +0200

    udl-kms: change down_interruptible to down
    
    If we leave urbs around, it causes not only leak, but also memory
    corruption. This patch fixes the function udl_free_urb_list, so that it
    always waits for all urbs that are in progress.
    
    Signed-off-by: Mikulas Patocka <mpatocka at redhat.com>
    Cc: stable at vger.kernel.org
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index d518de8f496b..1239decd46ff 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -170,18 +170,13 @@ static void udl_free_urb_list(struct drm_device *dev)
 	struct list_head *node;
 	struct urb_node *unode;
 	struct urb *urb;
-	int ret;
 	unsigned long flags;
 
 	DRM_DEBUG("Waiting for completes and freeing all render urbs\n");
 
 	/* keep waiting and freeing, until we've got 'em all */
 	while (count--) {
-
-		/* Getting interrupted means a leak, but ok at shutdown*/
-		ret = down_interruptible(&udl->urbs.limit_sem);
-		if (ret)
-			break;
+		down(&udl->urbs.limit_sem);
 
 		spin_lock_irqsave(&udl->urbs.lock, flags);
 
commit a7663a79343658f9362dc0655f1a06723c7014e3
Author: Jeykumar Sankaran <jsanka at codeaurora.org>
Date:   Fri Jul 20 16:43:09 2018 -0400

    dt-bindings: msm/disp: Add bindings for Snapdragon 845 DPU
    
    Adds bindings for Snapdragon 845 display processing unit
    
    Changes in v2:
    - Use SoC specific compatibles for mdss and dpu (Rob Herring)
    - Use assigned-clocks to set initial clock frequency (Rob Herring)
    
    Changes in v3 (all suggested by Rob Herring):
    - Rename mdss_phys to mdss
    - Correct description for clocks/assigned-clocks
    - Rename mdp_phys to mdp
    - Rename vbif_phys to vbif
    - Remove redundant interrupt-parent from mdss_mdp
    - Fully specify 'ranges' and use relative reg address in mdss_mdp
    
    Cc: Rob Herring <robh+dt at kernel.org>
    Signed-off-by: Jeykumar Sankaran <jsanka at codeaurora.org>
    Signed-off-by: Rajesh Yadav <ryadav at codeaurora.org>
    Signed-off-by: Sean Paul <seanpaul at chromium.org>
    Reviewed-by: Rob Herring <robh at kernel.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/Documentation/devicetree/bindings/display/msm/dpu.txt b/Documentation/devicetree/bindings/display/msm/dpu.txt
new file mode 100644
index 000000000000..ad2e8830324e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/msm/dpu.txt
@@ -0,0 +1,131 @@
+Qualcomm Technologies, Inc. DPU KMS
+
+Description:
+
+Device tree bindings for MSM Mobile Display Subsytem(MDSS) that encapsulates
+sub-blocks like DPU display controller, DSI and DP interfaces etc.
+The DPU display controller is found in SDM845 SoC.
+
+MDSS:
+Required properties:
+- compatible: "qcom,sdm845-mdss"
+- reg: physical base address and length of contoller's registers.
+- reg-names: register region names. The following region is required:
+  * "mdss"
+- power-domains: a power domain consumer specifier according to
+  Documentation/devicetree/bindings/power/power_domain.txt
+- clocks: list of clock specifiers for clocks needed by the device.
+- clock-names: device clock names, must be in same order as clocks property.
+  The following clocks are required:
+  * "iface"
+  * "bus"
+  * "core"
+- interrupts: interrupt signal from MDSS.
+- interrupt-controller: identifies the node as an interrupt controller.
+- #interrupt-cells: specifies the number of cells needed to encode an interrupt
+  source, should be 1.
+- iommus: phandle of iommu device node.
+- #address-cells: number of address cells for the MDSS children. Should be 1.
+- #size-cells: Should be 1.
+- ranges: parent bus address space is the same as the child bus address space.
+
+Optional properties:
+- assigned-clocks: list of clock specifiers for clocks needing rate assignment
+- assigned-clock-rates: list of clock frequencies sorted in the same order as
+  the assigned-clocks property.
+
+MDP:
+Required properties:
+- compatible: "qcom,sdm845-dpu"
+- reg: physical base address and length of controller's registers.
+- reg-names : register region names. The following region is required:
+  * "mdp"
+  * "vbif"
+- clocks: list of clock specifiers for clocks needed by the device.
+- clock-names: device clock names, must be in same order as clocks property.
+  The following clocks are required.
+  * "bus"
+  * "iface"
+  * "core"
+  * "vsync"
+- interrupts: interrupt line from DPU to MDSS.
+- ports: contains the list of output ports from DPU device. These ports connect
+  to interfaces that are external to the DPU hardware, such as DSI, DP etc.
+
+  Each output port contains an endpoint that describes how it is connected to an
+  external interface. These are described by the standard properties documented
+  here:
+	Documentation/devicetree/bindings/graph.txt
+	Documentation/devicetree/bindings/media/video-interfaces.txt
+
+	Port 0 -> DPU_INTF1 (DSI1)
+	Port 1 -> DPU_INTF2 (DSI2)
+
+Optional properties:
+- assigned-clocks: list of clock specifiers for clocks needing rate assignment
+- assigned-clock-rates: list of clock frequencies sorted in the same order as
+  the assigned-clocks property.
+
+Example:
+
+	mdss: mdss at ae00000 {
+		compatible = "qcom,sdm845-mdss";
+		reg = <0xae00000 0x1000>;
+		reg-names = "mdss";
+
+		power-domains = <&clock_dispcc 0>;
+
+		clocks = <&gcc GCC_DISP_AHB_CLK>, <&gcc GCC_DISP_AXI_CLK>,
+			 <&clock_dispcc DISP_CC_MDSS_MDP_CLK>;
+		clock-names = "iface", "bus", "core";
+
+		assigned-clocks = <&clock_dispcc DISP_CC_MDSS_MDP_CLK>;
+		assigned-clock-rates = <300000000>;
+
+		interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+
+		iommus = <&apps_iommu 0>;
+
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0 0xae00000 0xb2008>;
+
+		mdss_mdp: mdp at ae01000 {
+			compatible = "qcom,sdm845-dpu";
+			reg = <0 0x1000 0x8f000>, <0 0xb0000 0x2008>;
+			reg-names = "mdp", "vbif";
+
+			clocks = <&clock_dispcc DISP_CC_MDSS_AHB_CLK>,
+				 <&clock_dispcc DISP_CC_MDSS_AXI_CLK>,
+				 <&clock_dispcc DISP_CC_MDSS_MDP_CLK>,
+				 <&clock_dispcc DISP_CC_MDSS_VSYNC_CLK>;
+			clock-names = "iface", "bus", "core", "vsync";
+
+			assigned-clocks = <&clock_dispcc DISP_CC_MDSS_MDP_CLK>,
+					  <&clock_dispcc DISP_CC_MDSS_VSYNC_CLK>;
+			assigned-clock-rates = <0 0 300000000 19200000>;
+
+			interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+					dpu_intf1_out: endpoint {
+						remote-endpoint = <&dsi0_in>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+					dpu_intf2_out: endpoint {
+						remote-endpoint = <&dsi1_in>;
+					};
+				};
+			};
+		};
+	};
commit 6b0a180ede4884ea5cdd30ca939ddf43ef11cdac
Author: Jeykumar Sankaran <jsanka at codeaurora.org>
Date:   Fri Jul 20 16:42:52 2018 -0400

    dt-bindings: msm/dsi: Add mdp transfer time to msm dsi binding
    
    Adds mdp transfer time to msm dsi binding
    
    Changes in v3:
    - Added Rob's R-b
    
    Reviewed-by: Rob Herring <robh at kernel.org>
    Signed-off-by: Jeykumar Sankaran <jsanka at codeaurora.org>
    Signed-off-by: Rajesh Yadav <ryadav at codeaurora.org>
    Signed-off-by: Sean Paul <seanpaul at chromium.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/Documentation/devicetree/bindings/display/msm/dsi.txt b/Documentation/devicetree/bindings/display/msm/dsi.txt
index 518e9cdf0d4b..d22237a88eae 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi.txt
+++ b/Documentation/devicetree/bindings/display/msm/dsi.txt
@@ -121,6 +121,20 @@ Required properties:
 Optional properties:
 - qcom,dsi-phy-regulator-ldo-mode: Boolean value indicating if the LDO mode PHY
   regulator is wanted.
+- qcom,mdss-mdp-transfer-time-us:	Specifies the dsi transfer time for command mode
+					panels in microseconds. Driver uses this number to adjust
+					the clock rate according to the expected transfer time.
+					Increasing this value would slow down the mdp processing
+					and can result in slower performance.
+					Decreasing this value can speed up the mdp processing,
+					but this can also impact power consumption.
+					As a rule this time should not be higher than the time
+					that would be expected with the processing at the
+					dsi link rate since anyways this would be the maximum
+					transfer time that could be achieved.
+					If ping pong split is enabled, this time should not be higher
+					than two times the dsi link rate time.
+					If the property is not specified, then the default value is 14000 us.
 
 [1] Documentation/devicetree/bindings/clock/clock-bindings.txt
 [2] Documentation/devicetree/bindings/graph.txt
@@ -171,6 +185,8 @@ Example:
 		qcom,master-dsi;
 		qcom,sync-dual-dsi;
 
+		qcom,mdss-mdp-transfer-time-us = <12000>;
+
 		pinctrl-names = "default", "sleep";
 		pinctrl-0 = <&dsi_active>;
 		pinctrl-1 = <&dsi_suspend>;
commit fba33cae6aa3eaa3627a603d62d4652f12308b8d
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Thu Jul 26 14:30:14 2018 -0600

    drm/msm/disp/dpu: Mark a handful of functions as static
    
    Mark a number of static functions that are only unsed in the file
    that defines them and remove the prototypes from the headers where
    needed.
    
    Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 5c0051af5e98..0bd3eda93e22 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -264,6 +264,9 @@ void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc,
 				DPU_ENCODER_FRAME_EVENT_ERROR);
 }
 
+static int dpu_encoder_helper_wait_event_timeout(int32_t drm_id,
+		int32_t hw_id, struct dpu_encoder_wait_info *info);
+
 int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
 		enum dpu_intr_idx intr_idx,
 		struct dpu_encoder_wait_info *wait_info)
@@ -467,7 +470,7 @@ void dpu_encoder_get_hw_resources(struct drm_encoder *drm_enc,
 	}
 }
 
-void dpu_encoder_destroy(struct drm_encoder *drm_enc)
+static void dpu_encoder_destroy(struct drm_encoder *drm_enc)
 {
 	struct dpu_encoder_virt *dpu_enc = NULL;
 	int i = 0;
@@ -1516,7 +1519,7 @@ void dpu_encoder_helper_trigger_start(struct dpu_encoder_phys *phys_enc)
 	}
 }
 
-int dpu_encoder_helper_wait_event_timeout(
+static int dpu_encoder_helper_wait_event_timeout(
 		int32_t drm_id,
 		int32_t hw_id,
 		struct dpu_encoder_wait_info *info)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
index 204e538b0b74..60f809fc7c13 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -159,12 +159,6 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc,
 		struct msm_display_info *disp_info);
 
 /**
- * dpu_encoder_destroy - destroy previously initialized virtual encoder
- * @drm_enc:    Pointer to previously created drm encoder structure
- */
-void dpu_encoder_destroy(struct drm_encoder *drm_enc);
-
-/**
  * dpu_encoder_prepare_commit - prepare encoder at the very beginning of an
  *	atomic commit, before any registers are written
  * @drm_enc:    Pointer to previously created drm encoder structure
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index dacec1c8eeeb..c7df8aad6613 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -356,20 +356,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
 void dpu_encoder_helper_trigger_start(struct dpu_encoder_phys *phys_enc);
 
 /**
- * dpu_encoder_helper_wait_event_timeout - wait for event with timeout
- *	taking into account that jiffies may jump between reads leading to
- *	incorrectly detected timeouts. Prevent failure in this scenario by
- *	making sure that elapsed time during wait is valid.
- * @drm_id: drm object id for logging
- * @hw_id: hw instance id for logging
- * @info: wait info structure
- */
-int dpu_encoder_helper_wait_event_timeout(
-		int32_t drm_id,
-		int32_t hw_id,
-		struct dpu_encoder_wait_info *info);
-
-/**
  * dpu_encoder_helper_hw_reset - issue ctl hw reset
  *	This helper function may be optionally specified by physical
  *	encoders if they require ctl hw reset. If state is currently
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index e6d02c6947b4..3084675ed425 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -349,7 +349,7 @@ end:
 	return ret;
 }
 
-void dpu_encoder_phys_cmd_irq_control(struct dpu_encoder_phys *phys_enc,
+static void dpu_encoder_phys_cmd_irq_control(struct dpu_encoder_phys *phys_enc,
 		bool enable)
 {
 	struct dpu_encoder_phys_cmd *cmd_enc;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
index 0cb00612f96f..bfcd165e96df 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
@@ -846,7 +846,7 @@ static int _dpu_format_get_plane_sizes_linear(
 	return 0;
 }
 
-int dpu_format_get_plane_sizes(
+static int dpu_format_get_plane_sizes(
 		const struct dpu_format *fmt,
 		const uint32_t w,
 		const uint32_t h,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h
index b3a6592f1a8a..a54451d8d011 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h
@@ -55,23 +55,6 @@ uint32_t dpu_populate_formats(
 		uint32_t pixel_formats_max);
 
 /**
- * dpu_format_get_plane_sizes - calculate size and layout of given buffer format
- * @fmt:             pointer to dpu_format
- * @w:               width of the buffer
- * @h:               height of the buffer
- * @layout:          layout of the buffer
- * @pitches:         array of size [DPU_MAX_PLANES] to populate
- *		     pitch for each plane
- *
- * Return: size of the buffer
- */
-int dpu_format_get_plane_sizes(
-		const struct dpu_format *fmt,
-		const uint32_t w,
-		const uint32_t h,
-		struct dpu_hw_fmt_layout *layout,
-		const uint32_t *pitches);
-
  * dpu_format_check_modified_format - validate format and buffers for
  *                   dpu non-standard, i.e. modified format
  * @kms:             kms driver
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 1793cfd29a07..44ee06398b1d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -449,7 +449,7 @@ static struct dpu_perf_cfg sdm845_perf_data = {
  * sdm845_cfg_init(): populate sdm845 dpu sub-blocks reg offsets
  * and instance counts.
  */
-void sdm845_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
+static void sdm845_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
 {
 	*dpu_cfg = (struct dpu_mdss_cfg){
 		.caps = &sdm845_dpu_caps,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c
index da6f0609be5f..554874ba0c3b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c
@@ -217,7 +217,7 @@ static int dpu_hw_cdm_setup_cdwn(struct dpu_hw_cdm *ctx,
 	return 0;
 }
 
-int dpu_hw_cdm_enable(struct dpu_hw_cdm *ctx,
+static int dpu_hw_cdm_enable(struct dpu_hw_cdm *ctx,
 		struct dpu_hw_cdm_cfg *cdm)
 {
 	struct dpu_hw_blk_reg_map *c = &ctx->hw;
@@ -249,7 +249,7 @@ int dpu_hw_cdm_enable(struct dpu_hw_cdm *ctx,
 	return 0;
 }
 
-void dpu_hw_cdm_disable(struct dpu_hw_cdm *ctx)
+static void dpu_hw_cdm_disable(struct dpu_hw_cdm *ctx)
 {
 	struct cdm_output_cfg cdm_cfg = { 0 };
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
index 42fc72cf48dd..db2798e862fc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
@@ -275,7 +275,7 @@ static void dpu_hw_get_safe_status(struct dpu_hw_mdp *mdp,
 	status->sspp[SSPP_CURSOR1] = (value >> 26) & 0x1;
 }
 
-void dpu_hw_reset_ubwc(struct dpu_hw_mdp *mdp, struct dpu_mdss_cfg *m)
+static void dpu_hw_reset_ubwc(struct dpu_hw_mdp *mdp, struct dpu_mdss_cfg *m)
 {
 	struct dpu_hw_blk_reg_map c;
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 1c0838801e78..7dd6bd2d6d37 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -819,7 +819,7 @@ static int dpu_kms_pm_resume(struct device *dev)
 	return 0;
 }
 
-void _dpu_kms_set_encoder_mode(struct msm_kms *kms,
+static void _dpu_kms_set_encoder_mode(struct msm_kms *kms,
 				 struct drm_encoder *encoder,
 				 bool cmd_mode)
 {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
index 6dfc26698a09..9e533b86682c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
@@ -115,7 +115,7 @@ static int _dpu_mdss_irq_domain_add(struct dpu_mdss *dpu_mdss)
 	return 0;
 }
 
-int _dpu_mdss_irq_domain_fini(struct dpu_mdss *dpu_mdss)
+static int _dpu_mdss_irq_domain_fini(struct dpu_mdss *dpu_mdss)
 {
 	if (dpu_mdss->irq_controller.domain) {
 		irq_domain_remove(dpu_mdss->irq_controller.domain);
commit f2c9a924c1acf42f692f2b5ac77531eea69460a3
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Thu Jul 26 14:30:13 2018 -0600

    drm/msm/disp/dpu: Remove unused functions from dpu_formats.c
    
    Remove dpu_format_get_block_size, dpu_format_get_framebuffer_size,
    dpu_set_scaler_v2 and dpu_copy_formats they are unused and unneeded.
    
    Signed-off-by: Jordan Crouse <jcrouse at codeauorora.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
index 8189539b0620..0cb00612f96f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
@@ -869,47 +869,6 @@ int dpu_format_get_plane_sizes(
 	return _dpu_format_get_plane_sizes_linear(fmt, w, h, layout, pitches);
 }
 
-int dpu_format_get_block_size(const struct dpu_format *fmt,
-		uint32_t *w, uint32_t *h)
-{
-	if (!fmt || !w || !h) {
-		DRM_ERROR("invalid pointer\n");
-		return -EINVAL;
-	}
-
-	/* TP10 is 96x96 and all others are 128x128 */
-	if (DPU_FORMAT_IS_YUV(fmt) && DPU_FORMAT_IS_DX(fmt) &&
-			(fmt->num_planes == 2) && fmt->unpack_tight)
-		*w = *h = 96;
-	else
-		*w = *h = 128;
-
-	return 0;
-}
-
-uint32_t dpu_format_get_framebuffer_size(
-		const uint32_t format,
-		const uint32_t width,
-		const uint32_t height,
-		const uint32_t *pitches,
-		const uint64_t modifiers)
-{
-	const struct dpu_format *fmt;
-	struct dpu_hw_fmt_layout layout;
-
-	fmt = dpu_get_dpu_format_ext(format, modifiers);
-	if (!fmt)
-		return 0;
-
-	if (!pitches)
-		return -EINVAL;
-
-	if (dpu_format_get_plane_sizes(fmt, width, height, &layout, pitches))
-		layout.total_size = 0;
-
-	return layout.total_size;
-}
-
 static int _dpu_format_populate_addrs_ubwc(
 		struct msm_gem_address_space *aspace,
 		struct drm_framebuffer *fb,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h
index b55bfd13e296..b3a6592f1a8a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.h
@@ -72,19 +72,6 @@ int dpu_format_get_plane_sizes(
 		struct dpu_hw_fmt_layout *layout,
 		const uint32_t *pitches);
 
-/**
- * dpu_format_get_block_size - get block size of given format when
- *	operating in block mode
- * @fmt:             pointer to dpu_format
- * @w:               pointer to width of the block
- * @h:               pointer to height of the block
- *
- * Return: 0 if success; error oode otherwise
- */
-int dpu_format_get_block_size(const struct dpu_format *fmt,
-		uint32_t *w, uint32_t *h);
-
-/**
  * dpu_format_check_modified_format - validate format and buffers for
  *                   dpu non-standard, i.e. modified format
  * @kms:             kms driver
@@ -115,22 +102,4 @@ int dpu_format_populate_layout(
 		struct drm_framebuffer *fb,
 		struct dpu_hw_fmt_layout *fmtl);
 
-/**
- * dpu_format_get_framebuffer_size - get framebuffer memory size
- * @format:            DRM pixel format
- * @width:             pixel width
- * @height:            pixel height
- * @pitches:           array of size [DPU_MAX_PLANES] to populate
- *		       pitch for each plane
- * @modifiers:         drm modifier
- *
- * Return: memory size required for frame buffer
- */
-uint32_t dpu_format_get_framebuffer_size(
-		const uint32_t format,
-		const uint32_t width,
-		const uint32_t height,
-		const uint32_t *pitches,
-		const uint64_t modifiers);
-
 #endif /*_DPU_FORMATS_H */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
index 1ba571e94b32..4cabae480a7b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
@@ -92,59 +92,6 @@ u32 *dpu_hw_util_get_log_mask_ptr(void)
 	return &dpu_hw_util_log_mask;
 }
 
-void dpu_set_scaler_v2(struct dpu_hw_scaler3_cfg *cfg,
-		const struct dpu_drm_scaler_v2 *scale_v2)
-{
-	int i;
-
-	cfg->enable = scale_v2->enable;
-	cfg->dir_en = scale_v2->dir_en;
-
-	for (i = 0; i < DPU_MAX_PLANES; i++) {
-		cfg->init_phase_x[i] = scale_v2->init_phase_x[i];
-		cfg->phase_step_x[i] = scale_v2->phase_step_x[i];
-		cfg->init_phase_y[i] = scale_v2->init_phase_y[i];
-		cfg->phase_step_y[i] = scale_v2->phase_step_y[i];
-
-		cfg->preload_x[i] = scale_v2->preload_x[i];
-		cfg->preload_y[i] = scale_v2->preload_y[i];
-		cfg->src_width[i] = scale_v2->src_width[i];
-		cfg->src_height[i] = scale_v2->src_height[i];
-	}
-
-	cfg->dst_width = scale_v2->dst_width;
-	cfg->dst_height = scale_v2->dst_height;
-
-	cfg->y_rgb_filter_cfg = scale_v2->y_rgb_filter_cfg;
-	cfg->uv_filter_cfg = scale_v2->uv_filter_cfg;
-	cfg->alpha_filter_cfg = scale_v2->alpha_filter_cfg;
-	cfg->blend_cfg = scale_v2->blend_cfg;
-
-	cfg->lut_flag = scale_v2->lut_flag;
-	cfg->dir_lut_idx = scale_v2->dir_lut_idx;
-	cfg->y_rgb_cir_lut_idx = scale_v2->y_rgb_cir_lut_idx;
-	cfg->uv_cir_lut_idx = scale_v2->uv_cir_lut_idx;
-	cfg->y_rgb_sep_lut_idx = scale_v2->y_rgb_sep_lut_idx;
-	cfg->uv_sep_lut_idx = scale_v2->uv_sep_lut_idx;
-
-	cfg->de.enable = scale_v2->de.enable;
-	cfg->de.sharpen_level1 = scale_v2->de.sharpen_level1;
-	cfg->de.sharpen_level2 = scale_v2->de.sharpen_level2;
-	cfg->de.clip = scale_v2->de.clip;
-	cfg->de.limit = scale_v2->de.limit;
-	cfg->de.thr_quiet = scale_v2->de.thr_quiet;
-	cfg->de.thr_dieout = scale_v2->de.thr_dieout;
-	cfg->de.thr_low = scale_v2->de.thr_low;
-	cfg->de.thr_high = scale_v2->de.thr_high;
-	cfg->de.prec_shift = scale_v2->de.prec_shift;
-
-	for (i = 0; i < DPU_MAX_DE_CURVES; i++) {
-		cfg->de.adjust_a[i] = scale_v2->de.adjust_a[i];
-		cfg->de.adjust_b[i] = scale_v2->de.adjust_b[i];
-		cfg->de.adjust_c[i] = scale_v2->de.adjust_c[i];
-	}
-}
-
 static void _dpu_hw_setup_scaler3_lut(struct dpu_hw_blk_reg_map *c,
 		struct dpu_hw_scaler3_cfg *scaler3_cfg, u32 offset)
 {
@@ -419,34 +366,3 @@ void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c,
 	DPU_REG_WRITE(c, csc_reg_off + 0x3c, data->csc_post_bv[1]);
 	DPU_REG_WRITE(c, csc_reg_off + 0x40, data->csc_post_bv[2]);
 }
-
-/**
- * _dpu_copy_formats   - copy formats from src_list to dst_list
- * @dst_list:          pointer to destination list where to copy formats
- * @dst_list_size:     size of destination list
- * @dst_list_pos:      starting position on the list where to copy formats
- * @src_list:          pointer to source list where to copy formats from
- * @src_list_size:     size of source list
- * Return: number of elements populated
- */
-uint32_t dpu_copy_formats(
-		struct dpu_format_extended *dst_list,
-		uint32_t dst_list_size,
-		uint32_t dst_list_pos,
-		const struct dpu_format_extended *src_list,
-		uint32_t src_list_size)
-{
-	uint32_t cur_pos, i;
-
-	if (!dst_list || !src_list || (dst_list_pos >= (dst_list_size - 1)))
-		return 0;
-
-	for (i = 0, cur_pos = dst_list_pos;
-		(cur_pos < (dst_list_size - 1)) && (i < src_list_size)
-		&& src_list[i].fourcc_format; ++i, ++cur_pos)
-		dst_list[cur_pos] = src_list[i];
-
-	dst_list[cur_pos].fourcc_format = 0;
-
-	return i;
-}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
index 42f1b228d342..1240f505ca53 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
@@ -333,9 +333,6 @@ int dpu_reg_read(struct dpu_hw_blk_reg_map *c, u32 reg_off);
 
 void *dpu_hw_util_get_dir(void);
 
-void dpu_set_scaler_v2(struct dpu_hw_scaler3_cfg *cfg,
-		const struct dpu_drm_scaler_v2 *scale_v2);
-
 void dpu_hw_setup_scaler3(struct dpu_hw_blk_reg_map *c,
 		struct dpu_hw_scaler3_cfg *scaler3_cfg,
 		u32 scaler_offset, u32 scaler_version,
@@ -348,11 +345,4 @@ void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map  *c,
 		u32 csc_reg_off,
 		struct dpu_csc_cfg *data, bool csc10);
 
-uint32_t dpu_copy_formats(
-		struct dpu_format_extended *dst_list,
-		uint32_t dst_list_size,
-		uint32_t dst_list_pos,
-		const struct dpu_format_extended *src_list,
-		uint32_t src_list_size);
-
 #endif /* _DPU_HW_UTIL_H */
commit d9c7440dad0d85b29325d89956411e2c57e7d17a
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Thu Jul 26 14:30:12 2018 -0600

    drm/msm/disp/dpu: Remove dpu_kms_utils
    
    None of the functions in dpu_kms_utils.c seem to be used so
    remove them all.
    
    Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 1639ea8c0d13..7c773e003663 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -68,7 +68,6 @@ msm-y := \
 	disp/dpu1/dpu_io_util.o \
 	disp/dpu1/dpu_irq.o \
 	disp/dpu1/dpu_kms.o \
-	disp/dpu1/dpu_kms_utils.o \
 	disp/dpu1/dpu_mdss.o \
 	disp/dpu1/dpu_plane.o \
 	disp/dpu1/dpu_power_handle.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 407c1ed27fe6..66d466628e2b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -271,118 +271,6 @@ void *dpu_debugfs_get_root(struct dpu_kms *dpu_kms);
 #define DPU_KMS_INFO_MAX_SIZE	4096
 
 /**
- * struct dpu_kms_info - connector information structure container
- * @data: Array of information character data
- * @len: Current length of information data
- * @staged_len: Temporary data buffer length, commit to
- *              len using dpu_kms_info_stop
- * @start: Whether or not a partial data entry was just started
- */
-struct dpu_kms_info {
-	char data[DPU_KMS_INFO_MAX_SIZE];
-	uint32_t len;
-	uint32_t staged_len;
-	bool start;
-};
-
-/**
- * DPU_KMS_INFO_DATA - Macro for accessing dpu_kms_info data bytes
- * @S: Pointer to dpu_kms_info structure
- * Returns: Pointer to byte data
- */
-#define DPU_KMS_INFO_DATA(S)    ((S) ? ((struct dpu_kms_info *)(S))->data : 0)
-
-/**
- * DPU_KMS_INFO_DATALEN - Macro for accessing dpu_kms_info data length
- *			it adds an extra character length to count null.
- * @S: Pointer to dpu_kms_info structure
- * Returns: Size of available byte data
- */
-#define DPU_KMS_INFO_DATALEN(S) ((S) ? ((struct dpu_kms_info *)(S))->len + 1 \
-							: 0)
-
-/**
- * dpu_kms_info_reset - reset dpu_kms_info structure
- * @info: Pointer to dpu_kms_info structure
- */
-void dpu_kms_info_reset(struct dpu_kms_info *info);
-
-/**
- * dpu_kms_info_add_keyint - add integer value to 'dpu_kms_info'
- * @info: Pointer to dpu_kms_info structure
- * @key: Pointer to key string
- * @value: Signed 64-bit integer value
- */
-void dpu_kms_info_add_keyint(struct dpu_kms_info *info,
-		const char *key,
-		int64_t value);
-
-/**
- * dpu_kms_info_add_keystr - add string value to 'dpu_kms_info'
- * @info: Pointer to dpu_kms_info structure
- * @key: Pointer to key string
- * @value: Pointer to string value
- */
-void dpu_kms_info_add_keystr(struct dpu_kms_info *info,
-		const char *key,
-		const char *value);
-
-/**
- * dpu_kms_info_start - begin adding key to 'dpu_kms_info'
- * Usage:
- *      dpu_kms_info_start(key)
- *      dpu_kms_info_append(val_1)
- *      ...
- *      dpu_kms_info_append(val_n)
- *      dpu_kms_info_stop
- * @info: Pointer to dpu_kms_info structure
- * @key: Pointer to key string
- */
-void dpu_kms_info_start(struct dpu_kms_info *info,
-		const char *key);
-
-/**
- * dpu_kms_info_append - append value string to 'dpu_kms_info'
- * Usage:
- *      dpu_kms_info_start(key)
- *      dpu_kms_info_append(val_1)
- *      ...
- *      dpu_kms_info_append(val_n)
- *      dpu_kms_info_stop
- * @info: Pointer to dpu_kms_info structure
- * @str: Pointer to partial value string
- */
-void dpu_kms_info_append(struct dpu_kms_info *info,
-		const char *str);
-
-/**
- * dpu_kms_info_append_format - append format code string to 'dpu_kms_info'
- * Usage:
- *      dpu_kms_info_start(key)
- *      dpu_kms_info_append_format(fourcc, modifier)
- *      ...
- *      dpu_kms_info_stop
- * @info: Pointer to dpu_kms_info structure
- * @pixel_format: FOURCC format code
- * @modifier: 64-bit drm format modifier
- */
-void dpu_kms_info_append_format(struct dpu_kms_info *info,
-		uint32_t pixel_format,
-		uint64_t modifier);
-
-/**
- * dpu_kms_info_stop - finish adding key to 'dpu_kms_info'
- * Usage:
- *      dpu_kms_info_start(key)
- *      dpu_kms_info_append(val_1)
- *      ...
- *      dpu_kms_info_append(val_n)
- *      dpu_kms_info_stop
- * @info: Pointer to dpu_kms_info structure
- */
-void dpu_kms_info_stop(struct dpu_kms_info *info);
-
-/**
  * Vblank enable/disable functions
  */
 int dpu_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms_utils.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms_utils.c
deleted file mode 100644
index a80b3da5a9fe..000000000000
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms_utils.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#define pr_fmt(fmt)	"dpu-kms_utils:[%s] " fmt, __func__
-
-#include "dpu_kms.h"
-
-void dpu_kms_info_reset(struct dpu_kms_info *info)
-{
-	if (info) {
-		info->len = 0;
-		info->staged_len = 0;
-	}
-}
-
-void dpu_kms_info_add_keyint(struct dpu_kms_info *info,
-		const char *key,
-		int64_t value)
-{
-	uint32_t len;
-
-	if (info && key) {
-		len = snprintf(info->data + info->len,
-				DPU_KMS_INFO_MAX_SIZE - info->len,
-				"%s=%lld\n",
-				key,
-				value);
-
-		/* check if snprintf truncated the string */
-		if ((info->len + len) < DPU_KMS_INFO_MAX_SIZE)
-			info->len += len;
-	}
-}
-
-void dpu_kms_info_add_keystr(struct dpu_kms_info *info,
-		const char *key,
-		const char *value)
-{
-	uint32_t len;
-
-	if (info && key && value) {
-		len = snprintf(info->data + info->len,
-				DPU_KMS_INFO_MAX_SIZE - info->len,
-				"%s=%s\n",
-				key,
-				value);
-
-		/* check if snprintf truncated the string */
-		if ((info->len + len) < DPU_KMS_INFO_MAX_SIZE)
-			info->len += len;
-	}
-}
-
-void dpu_kms_info_start(struct dpu_kms_info *info,
-		const char *key)
-{
-	uint32_t len;
-
-	if (info && key) {
-		len = snprintf(info->data + info->len,
-				DPU_KMS_INFO_MAX_SIZE - info->len,
-				"%s=",
-				key);
-
-		info->start = true;
-
-		/* check if snprintf truncated the string */
-		if ((info->len + len) < DPU_KMS_INFO_MAX_SIZE)
-			info->staged_len = info->len + len;
-	}
-}
-
-void dpu_kms_info_append(struct dpu_kms_info *info,
-		const char *str)
-{
-	uint32_t len;
-
-	if (info) {
-		len = snprintf(info->data + info->staged_len,
-				DPU_KMS_INFO_MAX_SIZE - info->staged_len,
-				"%s",
-				str);
-
-		/* check if snprintf truncated the string */
-		if ((info->staged_len + len) < DPU_KMS_INFO_MAX_SIZE) {
-			info->staged_len += len;
-			info->start = false;
-		}
-	}
-}
-
-void dpu_kms_info_append_format(struct dpu_kms_info *info,
-		uint32_t pixel_format,
-		uint64_t modifier)
-{
-	uint32_t len;
-
-	if (!info)
-		return;
-
-	if (modifier) {
-		len = snprintf(info->data + info->staged_len,
-				DPU_KMS_INFO_MAX_SIZE - info->staged_len,
-				info->start ?
-				"%c%c%c%c/%llX/%llX" : " %c%c%c%c/%llX/%llX",
-				(pixel_format >> 0) & 0xFF,
-				(pixel_format >> 8) & 0xFF,
-				(pixel_format >> 16) & 0xFF,
-				(pixel_format >> 24) & 0xFF,
-				(modifier >> 56) & 0xFF,
-				modifier & ((1ULL << 56) - 1));
-	} else {
-		len = snprintf(info->data + info->staged_len,
-				DPU_KMS_INFO_MAX_SIZE - info->staged_len,
-				info->start ?
-				"%c%c%c%c" : " %c%c%c%c",
-				(pixel_format >> 0) & 0xFF,
-				(pixel_format >> 8) & 0xFF,
-				(pixel_format >> 16) & 0xFF,
-				(pixel_format >> 24) & 0xFF);
-	}
-
-	/* check if snprintf truncated the string */
-	if ((info->staged_len + len) < DPU_KMS_INFO_MAX_SIZE) {
-		info->staged_len += len;
-		info->start = false;
-	}
-}
-
-void dpu_kms_info_stop(struct dpu_kms_info *info)
-{
-	uint32_t len;
-
-	if (info) {
-		/* insert final delimiter */
-		len = snprintf(info->data + info->staged_len,
-				DPU_KMS_INFO_MAX_SIZE - info->staged_len,
-				"\n");
-
-		/* check if snprintf truncated the string */
-		if ((info->staged_len + len) < DPU_KMS_INFO_MAX_SIZE)
-			info->len = info->staged_len + len;
-	}
-}
commit c17aeda0b01cbcb8e334665fefa64a5148ecd18f
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Thu Jul 26 14:30:11 2018 -0600

    drm/msm/disp/dpu: Remove unused code from drm_crtc.c
    
    Remove a chunk of unused code from drm_crtc.c, namely
    dpu_crtc_res_add, dpu_crtc_res_get, dpu_crtc_res_put
    and associated static functions.
    
    Also zap dpu_crtc_event_queue(), helper functions
    and members.
    
    Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 7ac0e0dda866..80cbf75bc2ff 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -280,289 +280,6 @@ static void _dpu_crtc_rp_reset(struct dpu_crtc_respool *rp,
 	mutex_unlock(rp_lock);
 }
 
-/**
- * _dpu_crtc_rp_add_no_lock - add given resource to resource pool without lock
- * @rp: Pointer to original resource pool
- * @type: Resource type
- * @tag: Search tag for given resource
- * @val: Resource handle
- * @ops: Resource callback operations
- * return: 0 if success; error code otherwise
- */
-static int _dpu_crtc_rp_add_no_lock(struct dpu_crtc_respool *rp, u32 type,
-		u64 tag, void *val, struct dpu_crtc_res_ops *ops)
-{
-	struct dpu_crtc_res *res;
-	struct drm_crtc *crtc;
-
-	if (!rp || !ops) {
-		DPU_ERROR("invalid resource pool/ops\n");
-		return -EINVAL;
-	}
-
-	crtc = _dpu_crtc_rp_to_crtc(rp);
-	if (!crtc) {
-		DPU_ERROR("invalid crtc\n");
-		return -EINVAL;
-	}
-
-	list_for_each_entry(res, &rp->res_list, list) {
-		if (res->type != type || res->tag != tag)
-			continue;
-		DPU_ERROR("crtc%d.%u already exist res:0x%x/0x%llx/%pK/%d\n",
-				crtc->base.id, rp->sequence_id,
-				res->type, res->tag, res->val,
-				atomic_read(&res->refcount));
-		return -EEXIST;
-	}
-	res = kzalloc(sizeof(struct dpu_crtc_res), GFP_KERNEL);
-	if (!res)
-		return -ENOMEM;
-	INIT_LIST_HEAD(&res->list);
-	atomic_set(&res->refcount, 1);
-	res->type = type;
-	res->tag = tag;
-	res->val = val;
-	res->ops = *ops;
-	list_add_tail(&res->list, &rp->res_list);
-	DPU_DEBUG("crtc%d.%u added res:0x%x/0x%llx\n",
-			crtc->base.id, rp->sequence_id, type, tag);
-	return 0;
-}
-
-/**
- * _dpu_crtc_rp_add - add given resource to resource pool
- * @rp: Pointer to original resource pool
- * @type: Resource type
- * @tag: Search tag for given resource
- * @val: Resource handle
- * @ops: Resource callback operations
- * return: 0 if success; error code otherwise
- */
-static int _dpu_crtc_rp_add(struct dpu_crtc_respool *rp, u32 type, u64 tag,
-		void *val, struct dpu_crtc_res_ops *ops)
-{
-	int rc;
-
-	if (!rp) {
-		DPU_ERROR("invalid resource pool\n");
-		return -EINVAL;
-	}
-
-	mutex_lock(rp->rp_lock);
-	rc = _dpu_crtc_rp_add_no_lock(rp, type, tag, val, ops);
-	mutex_unlock(rp->rp_lock);
-	return rc;
-}
-
-/**
- * _dpu_crtc_rp_get - lookup the resource from given resource pool and obtain
- *	if available; otherwise, obtain resource from global pool
- * @rp: Pointer to original resource pool
- * @type: Resource type
- * @tag:  Search tag for given resource
- * return: Resource handle if success; pointer error or null otherwise
- */
-static void *_dpu_crtc_rp_get(struct dpu_crtc_respool *rp, u32 type, u64 tag)
-{
-	struct dpu_crtc_respool *old_rp;
-	struct dpu_crtc_res *res;
-	void *val = NULL;
-	int rc;
-	struct drm_crtc *crtc;
-
-	if (!rp) {
-		DPU_ERROR("invalid resource pool\n");
-		return NULL;
-	}
-
-	crtc = _dpu_crtc_rp_to_crtc(rp);
-	if (!crtc) {
-		DPU_ERROR("invalid crtc\n");
-		return NULL;
-	}
-
-	mutex_lock(rp->rp_lock);
-	list_for_each_entry(res, &rp->res_list, list) {
-		if (res->type != type || res->tag != tag)
-			continue;
-		DPU_DEBUG("crtc%d.%u found res:0x%x/0x%llx/%pK/%d\n",
-				crtc->base.id, rp->sequence_id,
-				res->type, res->tag, res->val,
-				atomic_read(&res->refcount));
-		atomic_inc(&res->refcount);
-		res->flags &= ~DPU_CRTC_RES_FLAG_FREE;
-		mutex_unlock(rp->rp_lock);
-		return res->val;
-	}
-	list_for_each_entry(res, &rp->res_list, list) {
-		if (res->type != type || !(res->flags & DPU_CRTC_RES_FLAG_FREE))
-			continue;
-		DPU_DEBUG("crtc%d.%u retag res:0x%x/0x%llx/%pK/%d\n",
-				crtc->base.id, rp->sequence_id,
-				res->type, res->tag, res->val,
-				atomic_read(&res->refcount));
-		atomic_inc(&res->refcount);
-		res->tag = tag;
-		res->flags &= ~DPU_CRTC_RES_FLAG_FREE;
-		mutex_unlock(rp->rp_lock);
-		return res->val;
-	}
-	/* not in this rp, try to grab from global pool */
-	if (rp->ops.get)
-		val = rp->ops.get(NULL, type, -1);
-	if (!IS_ERR_OR_NULL(val))
-		goto add_res;
-	/*
-	 * Search older resource pools for hw blk with matching type,
-	 * necessary when resource is being used by this object,
-	 * but in previous states not yet cleaned up.
-	 *
-	 * This enables searching of all resources currently owned
-	 * by this crtc even though the resource might not be used
-	 * in the current atomic state. This allows those resources
-	 * to be re-acquired by the new atomic state immediately
-	 * without waiting for the resources to be fully released.
-	 */
-	else if (IS_ERR_OR_NULL(val) && (type < DPU_HW_BLK_MAX)) {
-		list_for_each_entry(old_rp, rp->rp_head, rp_list) {
-			if (old_rp == rp)
-				continue;
-
-			list_for_each_entry(res, &old_rp->res_list, list) {
-				if (res->type != type)
-					continue;
-				DRM_DEBUG_KMS("crtc%d.%u found res:0x%x//%pK/ "
-					      "in crtc%d.%d\n",
-					      crtc->base.id, rp->sequence_id,
-					      res->type, res->val,
-					      crtc->base.id,
-					      old_rp->sequence_id);
-				if (res->ops.get)
-					res->ops.get(res->val, 0, -1);
-				val = res->val;
-				break;
-			}
-
-			if (!IS_ERR_OR_NULL(val))
-				break;
-		}
-	}
-	if (IS_ERR_OR_NULL(val)) {
-		DPU_DEBUG("crtc%d.%u failed to get res:0x%x//\n",
-				crtc->base.id, rp->sequence_id, type);
-		mutex_unlock(rp->rp_lock);
-		return NULL;
-	}
-add_res:
-	rc = _dpu_crtc_rp_add_no_lock(rp, type, tag, val, &rp->ops);
-	if (rc) {
-		DPU_ERROR("crtc%d.%u failed to add res:0x%x/0x%llx\n",
-				crtc->base.id, rp->sequence_id, type, tag);
-		if (rp->ops.put)
-			rp->ops.put(val);
-		val = NULL;
-	}
-	mutex_unlock(rp->rp_lock);
-	return val;
-}
-
-/**
- * _dpu_crtc_rp_put - return given resource to resource pool
- * @rp: Pointer to original resource pool
- * @type: Resource type
- * @tag: Search tag for given resource
- * return: None
- */
-static void _dpu_crtc_rp_put(struct dpu_crtc_respool *rp, u32 type, u64 tag)
-{
-	struct dpu_crtc_res *res, *next;
-	struct drm_crtc *crtc;
-
-	if (!rp) {
-		DPU_ERROR("invalid resource pool\n");
-		return;
-	}
-
-	crtc = _dpu_crtc_rp_to_crtc(rp);
-	if (!crtc) {
-		DPU_ERROR("invalid crtc\n");
-		return;
-	}
-
-	mutex_lock(rp->rp_lock);
-	list_for_each_entry_safe(res, next, &rp->res_list, list) {
-		if (res->type != type || res->tag != tag)
-			continue;
-		DPU_DEBUG("crtc%d.%u found res:0x%x/0x%llx/%pK/%d\n",
-				crtc->base.id, rp->sequence_id,
-				res->type, res->tag, res->val,
-				atomic_read(&res->refcount));
-		if (res->flags & DPU_CRTC_RES_FLAG_FREE)
-			DPU_ERROR(
-				"crtc%d.%u already free res:0x%x/0x%llx/%pK/%d\n",
-					crtc->base.id, rp->sequence_id,
-					res->type, res->tag, res->val,
-					atomic_read(&res->refcount));
-		else if (atomic_dec_return(&res->refcount) == 0)
-			res->flags |= DPU_CRTC_RES_FLAG_FREE;
-
-		mutex_unlock(rp->rp_lock);
-		return;
-	}
-	DPU_ERROR("crtc%d.%u not found res:0x%x/0x%llx\n",
-			crtc->base.id, rp->sequence_id, type, tag);
-	mutex_unlock(rp->rp_lock);
-}
-
-int dpu_crtc_res_add(struct drm_crtc_state *state, u32 type, u64 tag,
-		void *val, struct dpu_crtc_res_ops *ops)
-{
-	struct dpu_crtc_respool *rp;
-
-	if (!state) {
-		DPU_ERROR("invalid parameters\n");
-		return -EINVAL;
-	}
-
-	rp = &to_dpu_crtc_state(state)->rp;
-	return _dpu_crtc_rp_add(rp, type, tag, val, ops);
-}
-
-void *dpu_crtc_res_get(struct drm_crtc_state *state, u32 type, u64 tag)
-{
-	struct dpu_crtc_respool *rp;
-	void *val;
-
-	if (!state) {
-		DPU_ERROR("invalid parameters\n");
-		return NULL;
-	}
-
-	rp = &to_dpu_crtc_state(state)->rp;
-	val = _dpu_crtc_rp_get(rp, type, tag);
-	if (IS_ERR(val)) {
-		DPU_ERROR("failed to get res type:0x%x:0x%llx\n",
-				type, tag);
-		return NULL;
-	}
-
-	return val;
-}
-
-void dpu_crtc_res_put(struct drm_crtc_state *state, u32 type, u64 tag)
-{
-	struct dpu_crtc_respool *rp;
-
-	if (!state) {
-		DPU_ERROR("invalid parameters\n");
-		return;
-	}
-
-	rp = &to_dpu_crtc_state(state)->rp;
-	_dpu_crtc_rp_put(rp, type, tag);
-}
-
 static void dpu_crtc_destroy(struct drm_crtc *crtc)
 {
 	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
@@ -2364,97 +2081,6 @@ static const struct drm_crtc_helper_funcs dpu_crtc_helper_funcs = {
 	.atomic_flush = dpu_crtc_atomic_flush,
 };
 
-static void _dpu_crtc_event_cb(struct kthread_work *work)
-{
-	struct dpu_crtc_event *event;
-	struct dpu_crtc *dpu_crtc;
-	unsigned long irq_flags;
-
-	if (!work) {
-		DPU_ERROR("invalid work item\n");
-		return;
-	}
-
-	event = container_of(work, struct dpu_crtc_event, kt_work);
-
-	/* set dpu_crtc to NULL for static work structures */
-	dpu_crtc = event->dpu_crtc;
-	if (!dpu_crtc)
-		return;
-
-	if (event->cb_func)
-		event->cb_func(&dpu_crtc->base, event->usr);
-
-	spin_lock_irqsave(&dpu_crtc->event_lock, irq_flags);
-	list_add_tail(&event->list, &dpu_crtc->event_free_list);
-	spin_unlock_irqrestore(&dpu_crtc->event_lock, irq_flags);
-}
-
-int dpu_crtc_event_queue(struct drm_crtc *crtc,
-		void (*func)(struct drm_crtc *crtc, void *usr), void *usr)
-{
-	unsigned long irq_flags;
-	struct dpu_crtc *dpu_crtc;
-	struct msm_drm_private *priv;
-	struct dpu_crtc_event *event = NULL;
-	u32 crtc_id;
-
-	if (!crtc || !crtc->dev || !crtc->dev->dev_private || !func) {
-		DPU_ERROR("invalid parameters\n");
-		return -EINVAL;
-	}
-	dpu_crtc = to_dpu_crtc(crtc);
-	priv = crtc->dev->dev_private;
-	crtc_id = drm_crtc_index(crtc);
-
-	/*
-	 * Obtain an event struct from the private cache. This event
-	 * queue may be called from ISR contexts, so use a private
-	 * cache to avoid calling any memory allocation functions.
-	 */
-	spin_lock_irqsave(&dpu_crtc->event_lock, irq_flags);
-	if (!list_empty(&dpu_crtc->event_free_list)) {
-		event = list_first_entry(&dpu_crtc->event_free_list,
-				struct dpu_crtc_event, list);
-		list_del_init(&event->list);
-	}
-	spin_unlock_irqrestore(&dpu_crtc->event_lock, irq_flags);
-
-	if (!event)
-		return -ENOMEM;
-
-	/* populate event node */
-	event->dpu_crtc = dpu_crtc;
-	event->cb_func = func;
-	event->usr = usr;
-
-	/* queue new event request */
-	kthread_init_work(&event->kt_work, _dpu_crtc_event_cb);
-	kthread_queue_work(&priv->event_thread[crtc_id].worker,
-			&event->kt_work);
-
-	return 0;
-}
-
-static int _dpu_crtc_init_events(struct dpu_crtc *dpu_crtc)
-{
-	int i, rc = 0;
-
-	if (!dpu_crtc) {
-		DPU_ERROR("invalid crtc\n");
-		return -EINVAL;
-	}
-
-	spin_lock_init(&dpu_crtc->event_lock);
-
-	INIT_LIST_HEAD(&dpu_crtc->event_free_list);
-	for (i = 0; i < DPU_CRTC_MAX_EVENT_COUNT; ++i)
-		list_add_tail(&dpu_crtc->event_cache[i].list,
-				&dpu_crtc->event_free_list);
-
-	return rc;
-}
-
 /* initialize crtc */
 struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane)
 {
@@ -2462,7 +2088,7 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane)
 	struct dpu_crtc *dpu_crtc = NULL;
 	struct msm_drm_private *priv = NULL;
 	struct dpu_kms *kms = NULL;
-	int i, rc;
+	int i;
 
 	priv = dev->dev_private;
 	kms = to_dpu_kms(priv->kms);
@@ -2503,12 +2129,7 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane)
 	snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", crtc->base.id);
 
 	/* initialize event handling */
-	rc = _dpu_crtc_init_events(dpu_crtc);
-	if (rc) {
-		drm_crtc_cleanup(crtc);
-		kfree(dpu_crtc);
-		return ERR_PTR(rc);
-	}
+	spin_lock_init(&dpu_crtc->event_lock);
 
 	dpu_crtc->phandle = &kms->phandle;
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 4a97ba16735f..e87109e608e9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -112,23 +112,6 @@ struct dpu_crtc_frame_event {
 	u32 event;
 };
 
-/**
- * struct dpu_crtc_event - event callback tracking structure
- * @list:     Linked list tracking node
- * @kt_work:  Kthread worker structure
- * @dpu_crtc: Pointer to associated dpu_crtc structure
- * @cb_func:  Pointer to callback function
- * @usr:      Pointer to user data to be provided to the callback
- */
-struct dpu_crtc_event {
-	struct list_head list;
-	struct kthread_work kt_work;
-	void *dpu_crtc;
-
-	void (*cb_func)(struct drm_crtc *crtc, void *usr);
-	void *usr;
-};
-
 /*
  * Maximum number of free event structures to cache
  */
@@ -172,8 +155,6 @@ struct dpu_crtc_event {
  * @frame_done_comp    : for frame_event_done synchronization
  * @event_thread  : Pointer to event handler thread
  * @event_worker  : Event worker queue
- * @event_cache   : Local cache of event worker structures
- * @event_free_list : List of available event structures
  * @event_lock    : Spinlock around event handling code
  * @misr_enable   : boolean entry indicates misr enable/disable status.
  * @misr_frame_count  : misr frame count provided by client
@@ -224,8 +205,6 @@ struct dpu_crtc {
 	struct completion frame_done_comp;
 
 	/* for handling internal event thread */
-	struct dpu_crtc_event event_cache[DPU_CRTC_MAX_EVENT_COUNT];
-	struct list_head event_free_list;
 	spinlock_t event_lock;
 	bool misr_enable;
 	u32 misr_frame_count;
@@ -441,44 +420,4 @@ static inline bool dpu_crtc_is_enabled(struct drm_crtc *crtc)
 	return crtc ? crtc->enabled : false;
 }
 
-/**
- * dpu_crtc_event_queue - request event callback
- * @crtc: Pointer to drm crtc structure
- * @func: Pointer to callback function
- * @usr: Pointer to user data to be passed to callback
- * Returns: Zero on success
- */
-int dpu_crtc_event_queue(struct drm_crtc *crtc,
-		void (*func)(struct drm_crtc *crtc, void *usr), void *usr);
-
-/**
- * dpu_crtc_res_add - add given resource to resource pool in crtc state
- * @state: Pointer to drm crtc state
- * @type: Resource type
- * @tag: Search tag for given resource
- * @val: Resource handle
- * @ops: Resource callback operations
- * return: 0 if success; error code otherwise
- */
-int dpu_crtc_res_add(struct drm_crtc_state *state, u32 type, u64 tag,
-		void *val, struct dpu_crtc_res_ops *ops);
-
-/**
- * dpu_crtc_res_get - get given resource from resource pool in crtc state
- * @state: Pointer to drm crtc state
- * @type: Resource type
- * @tag: Search tag for given resource
- * return: Resource handle if success; pointer error or null otherwise
- */
-void *dpu_crtc_res_get(struct drm_crtc_state *state, u32 type, u64 tag);
-
-/**
- * dpu_crtc_res_put - return given resource to resource pool in crtc state
- * @state: Pointer to drm crtc state
- * @type: Resource type
- * @tag: Search tag for given resource
- * return: None
- */
-void dpu_crtc_res_put(struct drm_crtc_state *state, u32 type, u64 tag);
-
 #endif /* _DPU_CRTC_H_ */
commit 2c7b48e7267adb0b79a0785563eaa69a35632155
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Thu Jul 26 14:30:10 2018 -0600

    drm/msm/disp/dpu: Remove unused code from drm_encoder.c
    
    Remove dpu_encoder_check_mode and dpu_encoder_helper_hw_release
    frmo drm_encoder.c as they appear to be unused.
    
    Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 27775feed32b..5c0051af5e98 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1627,22 +1627,6 @@ static void _dpu_encoder_kickoff_phys(struct dpu_encoder_virt *dpu_enc)
 	spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags);
 }
 
-bool dpu_encoder_check_mode(struct drm_encoder *drm_enc, u32 mode)
-{
-	struct dpu_encoder_virt *dpu_enc;
-	struct msm_display_info *disp_info;
-
-	if (!drm_enc) {
-		DPU_ERROR("invalid encoder\n");
-		return false;
-	}
-
-	dpu_enc = to_dpu_encoder_virt(drm_enc);
-	disp_info = &dpu_enc->disp_info;
-
-	return (disp_info->capabilities & mode);
-}
-
 void dpu_encoder_trigger_kickoff_pending(struct drm_encoder *drm_enc)
 {
 	struct dpu_encoder_virt *dpu_enc;
@@ -1903,70 +1887,6 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc)
 	DPU_ATRACE_END("encoder_kickoff");
 }
 
-int dpu_encoder_helper_hw_release(struct dpu_encoder_phys *phys_enc,
-		struct drm_framebuffer *fb)
-{
-	struct drm_encoder *drm_enc;
-	struct dpu_hw_mixer_cfg mixer;
-	struct dpu_rm_hw_iter lm_iter;
-	bool lm_valid = false;
-
-	if (!phys_enc || !phys_enc->parent) {
-		DPU_ERROR("invalid encoder\n");
-		return -EINVAL;
-	}
-
-	drm_enc = phys_enc->parent;
-	memset(&mixer, 0, sizeof(mixer));
-
-	/* reset associated CTL/LMs */
-	if (phys_enc->hw_ctl->ops.clear_pending_flush)
-		phys_enc->hw_ctl->ops.clear_pending_flush(phys_enc->hw_ctl);
-	if (phys_enc->hw_ctl->ops.clear_all_blendstages)
-		phys_enc->hw_ctl->ops.clear_all_blendstages(phys_enc->hw_ctl);
-
-	dpu_rm_init_hw_iter(&lm_iter, drm_enc->base.id, DPU_HW_BLK_LM);
-	while (dpu_rm_get_hw(&phys_enc->dpu_kms->rm, &lm_iter)) {
-		struct dpu_hw_mixer *hw_lm = (struct dpu_hw_mixer *)lm_iter.hw;
-
-		if (!hw_lm)
-			continue;
-
-		/* need to flush LM to remove it */
-		if (phys_enc->hw_ctl->ops.get_bitmask_mixer &&
-				phys_enc->hw_ctl->ops.update_pending_flush)
-			phys_enc->hw_ctl->ops.update_pending_flush(
-					phys_enc->hw_ctl,
-					phys_enc->hw_ctl->ops.get_bitmask_mixer(
-					phys_enc->hw_ctl, hw_lm->idx));
-
-		if (fb) {
-			/* assume a single LM if targeting a frame buffer */
-			if (lm_valid)
-				continue;
-
-			mixer.out_height = fb->height;
-			mixer.out_width = fb->width;
-
-			if (hw_lm->ops.setup_mixer_out)
-				hw_lm->ops.setup_mixer_out(hw_lm, &mixer);
-		}
-
-		lm_valid = true;
-
-		/* only enable border color on LM */
-		if (phys_enc->hw_ctl->ops.setup_blendstage)
-			phys_enc->hw_ctl->ops.setup_blendstage(
-					phys_enc->hw_ctl, hw_lm->idx, NULL);
-	}
-
-	if (!lm_valid) {
-		DPU_DEBUG_ENC(to_dpu_encoder_virt(drm_enc), "lm not found\n");
-		return -EFAULT;
-	}
-	return 0;
-}
-
 void dpu_encoder_prepare_commit(struct drm_encoder *drm_enc)
 {
 	struct dpu_encoder_virt *dpu_enc;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
index ce92901ed227..204e538b0b74 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -140,14 +140,6 @@ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder);
 void dpu_encoder_virt_restore(struct drm_encoder *encoder);
 
 /**
- * dpu_encoder_check_mode - check if given mode is supported or not
- * @drm_enc: Pointer to drm encoder object
- * @mode: Mode to be checked
- * @Return: true if it is cmd mode
- */
-bool dpu_encoder_check_mode(struct drm_encoder *drm_enc, u32 mode);
-
-/**
  * dpu_encoder_init - initialize virtual encoder object
  * @dev:        Pointer to drm device structure
  * @disp_info:  Pointer to display information structure
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index 8505edddcc81..dacec1c8eeeb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -403,15 +403,6 @@ void dpu_encoder_helper_split_config(
 		enum dpu_intf interface);
 
 /**
- * dpu_encoder_helper_hw_release - prepare for h/w reset during disable
- * @phys_enc: Pointer to physical encoder structure
- * @fb: Optional fb for specifying new mixer output resolution, may be NULL
- * Return: Zero on success
- */
-int dpu_encoder_helper_hw_release(struct dpu_encoder_phys *phys_enc,
-		struct drm_framebuffer *fb);
-
-/**
  * dpu_encoder_helper_report_irq_timeout - utility to report error that irq has
  *	timed out, including reporting frame error event to crtc and debug dump
  * @phys_enc: Pointer to physical encoder structure
commit aff24cd1f531b0dd55e46f6a8f76cf44117f0a24
Author: Gustavo A. R. Silva <gustavo at embeddedor.com>
Date:   Mon Jul 23 13:46:55 2018 -0500

    drm/msm: Replace PTR_RET with PTR_ERR_OR_ZERO
    
    PTR_RET is deprecated, use PTR_ERR_OR_ZERO instead.
    
    Signed-off-by: Gustavo A. R. Silva <gustavo at embeddedor.com>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c
index c1d7eac4fa25..790d39f816dc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c
@@ -35,7 +35,7 @@ int msm_dss_get_clk(struct device *dev, struct dss_clk *clk_arry, int num_clk)
 
 	for (i = 0; i < num_clk; i++) {
 		clk_arry[i].clk = clk_get(dev, clk_arry[i].clk_name);
-		rc = PTR_RET(clk_arry[i].clk);
+		rc = PTR_ERR_OR_ZERO(clk_arry[i].clk);
 		if (rc) {
 			DEV_ERR("%pS->%s: '%s' get failed. rc=%d\n",
 				__builtin_return_address(0), __func__,
commit 78918cd0eee346c43e2d9dc553fadfacad6cb488
Author: Arnd Bergmann <arnd at arndb.de>
Date:   Tue Jul 24 17:35:37 2018 +0200

    drm/msm: mark PM functions as __maybe_unused
    
    The suspend/resume functions are not referenced when power
    management is disabled:
    
    drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c:1288:12: error: 'dpu_runtime_resume' defined but not used [-Werror=unused-function]
    drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c:1261:12: error: 'dpu_runtime_suspend' defined but not used [-Werror=unused-function]
    
    This marks them as __maybe_unused to let the compiler
    drop the functions without complaining.
    
    Fixes: 591225291ca2 ("drm/msm: Add SDM845 DPU support")
    Signed-off-by: Arnd Bergmann <arnd at arndb.de>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 8d4678d29cc7..1c0838801e78 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1258,7 +1258,7 @@ static int dpu_dev_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static int dpu_runtime_suspend(struct device *dev)
+static int __maybe_unused dpu_runtime_suspend(struct device *dev)
 {
 	int rc = -1;
 	struct platform_device *pdev = to_platform_device(dev);
@@ -1285,7 +1285,7 @@ exit:
 	return rc;
 }
 
-static int dpu_runtime_resume(struct device *dev)
+static int __maybe_unused dpu_runtime_resume(struct device *dev)
 {
 	int rc = -1;
 	struct platform_device *pdev = to_platform_device(dev);
commit f4b0f66daf77ac79807711310597e4c102f72bd8
Author: zhong jiang <zhongjiang at huawei.com>
Date:   Tue Jul 24 19:51:59 2018 +0800

    drm/msm/dpu: fix mismatch in function argument.
    
    Fix the sparse error. the dpu_rm_init declaration is not consistent
    with the implement.
    
    Signed-off-by: zhong jiang <zhongjiang at huawei.com>
    [robclark un-typo'd subject line]
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index ef3f67bedaa0..ffd1841a6067 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -105,7 +105,7 @@ struct dpu_rm_hw_iter {
  */
 int dpu_rm_init(struct dpu_rm *rm,
 		struct dpu_mdss_cfg *cat,
-		void *mmio,
+		void __iomem *mmio,
 		struct drm_device *dev);
 
 /**
commit 3530a17f4dc8f1f667fee14c16f229162daa79bb
Author: Arnd Bergmann <arnd at arndb.de>
Date:   Thu Jul 26 14:39:25 2018 +0200

    drm/msm/gpu: avoid deprecated do_gettimeofday
    
    All users of do_gettimeofday() have been removed, but this one recently
    crept in, along with an incorrect printing of the microseconds portion.
    
    This converts it to using ktime_get_real_timespec64() as a direct
    replacement, and adds the leading zeroes. I considered using monotonic
    times (ktime_get()) instead, but as this timestamp appears to only
    be used for humans rather than compared with other timestamps, the
    real time domain is probably good enough.
    
    Fixes: e43b045e2c82 ("drm/msm/gpu: Capture the state of the GPU")
    Signed-off-by: Arnd Bergmann <arnd at arndb.de>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 08d3c618b7de..38ac50b73829 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -376,7 +376,7 @@ int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state)
 
 	kref_init(&state->ref);
 
-	do_gettimeofday(&state->time);
+	ktime_get_real_ts64(&state->time);
 
 	for (i = 0; i < gpu->nr_rings; i++) {
 		int size = 0, j;
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 3cf8e8d29812..f388944c93e2 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -297,8 +297,8 @@ static ssize_t msm_gpu_devcoredump_read(char *buffer, loff_t offset,
 	drm_printf(&p, "---\n");
 	drm_printf(&p, "kernel: " UTS_RELEASE "\n");
 	drm_printf(&p, "module: " KBUILD_MODNAME "\n");
-	drm_printf(&p, "time: %ld.%ld\n",
-		state->time.tv_sec, state->time.tv_usec);
+	drm_printf(&p, "time: %lld.%09ld\n",
+		state->time.tv_sec, state->time.tv_nsec);
 	if (state->comm)
 		drm_printf(&p, "comm: %s\n", state->comm);
 	if (state->cmd)
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 57380ef8d1f7..1c6105bc55c7 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -189,7 +189,7 @@ struct msm_gpu_state_bo {
 
 struct msm_gpu_state {
 	struct kref ref;
-	struct timeval time;
+	struct timespec64 time;
 
 	struct {
 		u64 iova;
commit a6bcddbc2ee1b2797fce016775b9e3faf17a4d0e
Author: Sean Paul <seanpaul at chromium.org>
Date:   Wed Jul 25 16:34:45 2018 -0400

    drm/msm: dsi: Handle dual-channel for 6G as well
    
    This fixes up a collision between introducing dual-channel support and
    the dsi refactors. This patch applies the same dual-channel
    considerations and pclk calculations to both v2 and 6G, with a bit of
    abstracting for good measure.
    
    Signed-off-by: Sean Paul <seanpaul at chromium.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 319501dcc083..96fb5f635314 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -664,11 +664,9 @@ void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host)
 	clk_disable_unprepare(msm_host->byte_clk);
 }
 
-int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_dual_dsi)
+static u32 dsi_get_pclk_rate(struct msm_dsi_host *msm_host, bool is_dual_dsi)
 {
 	struct drm_display_mode *mode = msm_host->mode;
-	u8 lanes = msm_host->lanes;
-	u32 bpp = dsi_get_bpp(msm_host->format);
 	u32 pclk_rate;
 
 	pclk_rate = mode->clock * 1000;
@@ -676,61 +674,61 @@ int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_dual_dsi)
 	/*
 	 * For dual DSI mode, the current DRM mode has the complete width of the
 	 * panel. Since, the complete panel is driven by two DSI controllers,
-	 * theclock rates have to be split between the two dsi controllers.
+	 * the clock rates have to be split between the two dsi controllers.
 	 * Adjust the byte and pixel clock rates for each dsi host accordingly.
 	 */
 	if (is_dual_dsi)
 		pclk_rate /= 2;
 
-	if (lanes > 0) {
-		msm_host->byte_clk_rate = (pclk_rate * bpp) / (8 * lanes);
-	} else {
+	return pclk_rate;
+}
+
+static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_dual_dsi)
+{
+	u8 lanes = msm_host->lanes;
+	u32 bpp = dsi_get_bpp(msm_host->format);
+	u32 pclk_rate = dsi_get_pclk_rate(msm_host, is_dual_dsi);
+	u64 pclk_bpp = (u64)pclk_rate * bpp;
+
+	if (lanes == 0) {
 		pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__);
-		msm_host->byte_clk_rate = (pclk_rate * bpp) / 8;
+		lanes = 1;
 	}
 
-	DBG("pclk=%d, bclk=%d", pclk_rate, msm_host->byte_clk_rate);
+	do_div(pclk_bpp, (8 * lanes));
 
-	msm_host->esc_clk_rate = clk_get_rate(msm_host->esc_clk);
+	msm_host->pixel_clk_rate = pclk_rate;
+	msm_host->byte_clk_rate = pclk_bpp;
+
+	DBG("pclk=%d, bclk=%d", msm_host->pixel_clk_rate,
+				msm_host->byte_clk_rate);
+
+}
+
+int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_dual_dsi)
+{
+	if (!msm_host->mode) {
+		pr_err("%s: mode not set\n", __func__);
+		return -EINVAL;
+	}
 
+	dsi_calc_pclk(msm_host, is_dual_dsi);
+	msm_host->esc_clk_rate = clk_get_rate(msm_host->esc_clk);
 	return 0;
 }
 
 int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_dual_dsi)
 {
-	struct drm_display_mode *mode = msm_host->mode;
-	u8 lanes = msm_host->lanes;
 	u32 bpp = dsi_get_bpp(msm_host->format);
-	u32 pclk_rate;
 	u64 pclk_bpp;
 	unsigned int esc_mhz, esc_div;
 	unsigned long byte_mhz;
 
-	pclk_rate = mode->clock * 1000;
-
-	/*
-	 * For dual DSI mode, the current DRM mode has the complete width of the
-	 * panel. Since, the complete panel is driven by two DSI controllers,
-	 * theclock rates have to be split between the two dsi controllers.
-	 * Adjust the byte and pixel clock rates for each dsi host accordingly.
-	 */
-	if (is_dual_dsi)
-		pclk_rate /= 2;
-
-	pclk_bpp = pclk_rate * bpp;
-	if (lanes > 0) {
-		do_div(pclk_bpp, (8 * lanes));
-	} else {
-		pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__);
-		do_div(pclk_bpp, 8);
-	}
-	msm_host->pixel_clk_rate = pclk_rate;
-	msm_host->byte_clk_rate = pclk_bpp;
-
-	DBG("pclk=%d, bclk=%d", msm_host->pixel_clk_rate,
-				msm_host->byte_clk_rate);
+	dsi_calc_pclk(msm_host, is_dual_dsi);
 
-	msm_host->src_clk_rate = (pclk_rate * bpp) / 8;
+	pclk_bpp = (u64)dsi_get_pclk_rate(msm_host, is_dual_dsi) * bpp;
+	do_div(pclk_bpp, 8);
+	msm_host->src_clk_rate = pclk_bpp;
 
 	/*
 	 * esc clock is byte clock followed by a 4 bit divider,
commit 41a8e8865a82b4fd4ff62b43b7c6d3bc5831f93d
Author: Sean Paul <seanpaul at chromium.org>
Date:   Wed Jul 25 16:34:44 2018 -0400

    drm/msm: dpu: Use clock-names instead of assigned-clock-names
    
    In these cases, we want to enumerate _all_ clocks, not just the ones
    that are assigned a rate.
    
    Signed-off-by: Sean Paul <seanpaul at chromium.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c
index 8d907faa7496..c1d7eac4fa25 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c
@@ -147,8 +147,7 @@ int msm_dss_parse_clock(struct platform_device *pdev,
 		return -EINVAL;
 
 	mp->num_clk = 0;
-	num_clk = of_property_count_strings(pdev->dev.of_node,
-					    "assigned-clock-names");
+	num_clk = of_property_count_strings(pdev->dev.of_node, "clock-names");
 	if (num_clk <= 0) {
 		pr_debug("clocks are not defined\n");
 		return 0;
@@ -162,7 +161,7 @@ int msm_dss_parse_clock(struct platform_device *pdev,
 
 	for (i = 0; i < num_clk; i++) {
 		rc = of_property_read_string_index(pdev->dev.of_node,
-						   "assigned-clock-names", i,
+						   "clock-names", i,
 						   &clock_name);
 		if (rc) {
 			dev_err(&pdev->dev, "Failed to get clock name for %d\n",
commit 2c1f748d00e0617799c5bdbe9daf3a6a887b1b84
Author: Sean Paul <seanpaul at chromium.org>
Date:   Wed Jul 25 16:34:43 2018 -0400

    drm/msm: dpu: Use 'vsync' instead of 'vsync_clk' in cmdmode encoder
    
    Should work with the legacy handling in of, but we shouldn't rely on
    that.
    
    Signed-off-by: Sean Paul <seanpaul at chromium.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index 035a5fbe1435..e6d02c6947b4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -424,7 +424,7 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
 	 * vsync_count is ratio of MDP VSYNC clock frequency to LCD panel
 	 * frequency divided by the no. of rows (lines) in the LCDpanel.
 	 */
-	vsync_hz = dpu_kms_get_clk_rate(dpu_kms, "vsync_clk");
+	vsync_hz = dpu_kms_get_clk_rate(dpu_kms, "vsync");
 	if (vsync_hz <= 0) {
 		DPU_DEBUG_CMDENC(cmd_enc, "invalid - vsync_hz %u\n",
 				 vsync_hz);
commit cdb95931dea32981545e34a3b1dfc9e172425d95
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Tue Jul 24 10:33:31 2018 -0600

    drm/msm/gpu: Add the buffer objects from the submit to the crash dump
    
    For hangs, dump copy out the contents of the buffer objects attached to the
    guilty submission and print them in the crash dump report.
    
    Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/Documentation/gpu/msm-crash-dump.rst b/Documentation/gpu/msm-crash-dump.rst
index 7943f43f70d6..757cd257e0d8 100644
--- a/Documentation/gpu/msm-crash-dump.rst
+++ b/Documentation/gpu/msm-crash-dump.rst
@@ -66,6 +66,20 @@ ringbuffer
 		The contents of the ring encoded as ascii85.  Only the used
 		portions of the ring will be printed.
 
+bo
+	List of buffers from the hanging submission if available.
+	Each buffer object will have a uinque iova.
+
+	iova
+		GPU address of the buffer object.
+
+	size
+		Allocated size of the buffer object.
+
+	data
+		The contents of the buffer object encoded with ascii85.  Only
+		Trailing zeros at the end of the buffer will be skipped.
+
 registers
 	Set of registers values. Each entry is on its own line enclosed
 	by brackets { }.
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index cd418dab7a62..08d3c618b7de 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -437,6 +437,10 @@ void adreno_gpu_state_destroy(struct msm_gpu_state *state)
 	for (i = 0; i < ARRAY_SIZE(state->ring); i++)
 		kfree(state->ring[i].data);
 
+	for (i = 0; state->bos && i < state->nr_bos; i++)
+		kvfree(state->bos[i].data);
+
+	kfree(state->bos);
 	kfree(state->comm);
 	kfree(state->cmd);
 	kfree(state->registers);
@@ -460,6 +464,39 @@ int adreno_gpu_state_put(struct msm_gpu_state *state)
 }
 
 #if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
+
+static void adreno_show_object(struct drm_printer *p, u32 *ptr, int len)
+{
+	char out[ASCII85_BUFSZ];
+	long l, datalen, i;
+
+	if (!ptr || !len)
+		return;
+
+	/*
+	 * Only dump the non-zero part of the buffer - rarely will any data
+	 * completely fill the entire allocated size of the buffer
+	 */
+	for (datalen = 0, i = 0; i < len >> 2; i++) {
+		if (ptr[i])
+			datalen = (i << 2) + 1;
+	}
+
+	/* Skip printing the object if it is empty */
+	if (datalen == 0)
+		return;
+
+	l = ascii85_encode_len(datalen);
+
+	drm_puts(p, "    data: !!ascii85 |\n");
+	drm_puts(p, "     ");
+
+	for (i = 0; i < l; i++)
+		drm_puts(p, ascii85_encode(ptr[i], out));
+
+	drm_puts(p, "\n");
+}
+
 void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
 		struct drm_printer *p)
 {
@@ -487,19 +524,20 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
 		drm_printf(p, "    wptr: %d\n", state->ring[i].wptr);
 		drm_printf(p, "    size: %d\n", MSM_GPU_RINGBUFFER_SZ);
 
-		if (state->ring[i].data && state->ring[i].data_size) {
-			u32 *ptr = (u32 *) state->ring[i].data;
-			char out[ASCII85_BUFSZ];
-			long len = ascii85_encode_len(state->ring[i].data_size);
-			int j;
+		adreno_show_object(p, state->ring[i].data,
+			state->ring[i].data_size);
+	}
 
-			drm_printf(p, "    data: !!ascii85 |\n");
-			drm_printf(p, "     ");
+	if (state->bos) {
+		drm_puts(p, "bos:\n");
 
-			for (j = 0; j < len; j++)
-				drm_printf(p, ascii85_encode(ptr[j], out));
+		for (i = 0; i < state->nr_bos; i++) {
+			drm_printf(p, "  - iova: 0x%016llx\n",
+				state->bos[i].iova);
+			drm_printf(p, "    size: %zd\n", state->bos[i].size);
 
-			drm_printf(p, "\n");
+			adreno_show_object(p, state->bos[i].data,
+				state->bos[i].size);
 		}
 	}
 
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 5f39549d9a8b..3cf8e8d29812 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -318,8 +318,39 @@ static void msm_gpu_devcoredump_free(void *data)
 	msm_gpu_crashstate_put(gpu);
 }
 
-static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, char *comm,
-		char *cmd)
+static void msm_gpu_crashstate_get_bo(struct msm_gpu_state *state,
+		struct msm_gem_object *obj, u64 iova, u32 flags)
+{
+	struct msm_gpu_state_bo *state_bo = &state->bos[state->nr_bos];
+
+	/* Don't record write only objects */
+
+	state_bo->size = obj->base.size;
+	state_bo->iova = iova;
+
+	/* Only store the data for buffer objects marked for read */
+	if ((flags & MSM_SUBMIT_BO_READ)) {
+		void *ptr;
+
+		state_bo->data = kvmalloc(obj->base.size, GFP_KERNEL);
+		if (!state_bo->data)
+			return;
+
+		ptr = msm_gem_get_vaddr_active(&obj->base);
+		if (IS_ERR(ptr)) {
+			kvfree(state_bo->data);
+			return;
+		}
+
+		memcpy(state_bo->data, ptr, obj->base.size);
+		msm_gem_put_vaddr(&obj->base);
+	}
+
+	state->nr_bos++;
+}
+
+static void msm_gpu_crashstate_capture(struct msm_gpu *gpu,
+		struct msm_gem_submit *submit, char *comm, char *cmd)
 {
 	struct msm_gpu_state *state;
 
@@ -335,6 +366,17 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, char *comm,
 	state->comm = kstrdup(comm, GFP_KERNEL);
 	state->cmd = kstrdup(cmd, GFP_KERNEL);
 
+	if (submit) {
+		int i;
+
+		state->bos = kcalloc(submit->nr_bos,
+			sizeof(struct msm_gpu_state_bo), GFP_KERNEL);
+
+		for (i = 0; state->bos && i < submit->nr_bos; i++)
+			msm_gpu_crashstate_get_bo(state, submit->bos[i].obj,
+				submit->bos[i].iova, submit->bos[i].flags);
+	}
+
 	/* Set the active crash state to be dumped on failure */
 	gpu->crashstate = state;
 
@@ -434,7 +476,7 @@ static void recover_worker(struct work_struct *work)
 
 	/* Record the crash state */
 	pm_runtime_get_sync(&gpu->pdev->dev);
-	msm_gpu_crashstate_capture(gpu, comm, cmd);
+	msm_gpu_crashstate_capture(gpu, submit, comm, cmd);
 	pm_runtime_put_sync(&gpu->pdev->dev);
 
 	kfree(cmd);
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 878090b57e90..57380ef8d1f7 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -181,6 +181,12 @@ struct msm_gpu_submitqueue {
 	struct kref ref;
 };
 
+struct msm_gpu_state_bo {
+	u64 iova;
+	size_t size;
+	void *data;
+};
+
 struct msm_gpu_state {
 	struct kref ref;
 	struct timeval time;
@@ -202,6 +208,9 @@ struct msm_gpu_state {
 
 	char *comm;
 	char *cmd;
+
+	int nr_bos;
+	struct msm_gpu_state_bo *bos;
 };
 
 static inline void gpu_write(struct msm_gpu *gpu, u32 reg, u32 data)
commit 50f8d21863b9b774b198e631d2b14878f6a54b5b
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Tue Jul 24 10:33:30 2018 -0600

    drm/msm/adreno: Add a5xx specific registers for the GPU state
    
    HLSQ, SP and TP registers are only accessible from a special
    aperture and to make matters worse the aperture is blocked from
    the CPU on targets that can support secure rendering. Luckily the
    GPU hardware has its own purpose built register dumper that can
    access the registers from the aperture. Add a5xx specific code
    to program the crashdumper and retrieve the wayward registers
    and dump them for the crash state.
    
    Also, remove a block of registers the regular CPU accessible
    list that aren't useful for debug which helps reduce the size
    of the crash state file by a goodly amount.
    
    Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/Documentation/gpu/msm-crash-dump.rst b/Documentation/gpu/msm-crash-dump.rst
index 35e87004e006..7943f43f70d6 100644
--- a/Documentation/gpu/msm-crash-dump.rst
+++ b/Documentation/gpu/msm-crash-dump.rst
@@ -76,3 +76,7 @@ registers
 
 	value
 		Hexadecimal value of the register.
+
+registers-hlsq
+		(5xx only) Register values from the HLSQ aperture.
+		Same format as the register section.
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index fc502e412132..669c2d4b070d 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -421,10 +421,12 @@ static void a3xx_dump(struct msm_gpu *gpu)
 
 static struct msm_gpu_state *a3xx_gpu_state_get(struct msm_gpu *gpu)
 {
-	struct msm_gpu_state *state = adreno_gpu_state_get(gpu);
+	struct msm_gpu_state *state = kzalloc(sizeof(*state), GFP_KERNEL);
 
-	if (IS_ERR(state))
-		return state;
+	if (!state)
+		return ERR_PTR(-ENOMEM);
+
+	adreno_gpu_state_get(gpu, state);
 
 	state->rbbm_status = gpu_read(gpu, REG_A3XX_RBBM_STATUS);
 
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
index 8129cf037db1..7c4e6dc1ed59 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
@@ -457,10 +457,12 @@ static const unsigned int a4xx_registers[] = {
 
 static struct msm_gpu_state *a4xx_gpu_state_get(struct msm_gpu *gpu)
 {
-	struct msm_gpu_state *state = adreno_gpu_state_get(gpu);
+	struct msm_gpu_state *state = kzalloc(sizeof(*state), GFP_KERNEL);
 
-	if (IS_ERR(state))
-		return state;
+	if (!state)
+		return ERR_PTR(-ENOMEM);
+
+	adreno_gpu_state_get(gpu, state);
 
 	state->rbbm_status = gpu_read(gpu, REG_A4XX_RBBM_STATUS);
 
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 16074fa6bf1e..bd84f71d27d8 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -19,6 +19,7 @@
 #include <linux/soc/qcom/mdt_loader.h>
 #include <linux/pm_opp.h>
 #include <linux/nvmem-consumer.h>
+#include <linux/iopoll.h>
 #include "msm_gem.h"
 #include "msm_mmu.h"
 #include "a5xx_gpu.h"
@@ -1123,8 +1124,9 @@ static const u32 a5xx_registers[] = {
 	0xE800, 0xE806, 0xE810, 0xE89A, 0xE8A0, 0xE8A4, 0xE8AA, 0xE8EB,
 	0xE900, 0xE905, 0xEB80, 0xEB8F, 0xEBB0, 0xEBB0, 0xEC00, 0xEC05,
 	0xEC08, 0xECE9, 0xECF0, 0xECF0, 0xEA80, 0xEA80, 0xEA82, 0xEAA3,
-	0xEAA5, 0xEAC2, 0xA800, 0xA8FF, 0xAC60, 0xAC60, 0xB000, 0xB97F,
-	0xB9A0, 0xB9BF, ~0
+	0xEAA5, 0xEAC2, 0xA800, 0xA800, 0xA820, 0xA828, 0xA840, 0xA87D,
+	0XA880, 0xA88D, 0xA890, 0xA8A3, 0xA8D0, 0xA8D8, 0xA8E0, 0xA8F5,
+	0xAC60, 0xAC60, ~0,
 };
 
 static void a5xx_dump(struct msm_gpu *gpu)
@@ -1195,25 +1197,233 @@ static int a5xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
 	return 0;
 }
 
+struct a5xx_crashdumper {
+	void *ptr;
+	struct drm_gem_object *bo;
+	u64 iova;
+};
+
+struct a5xx_gpu_state {
+	struct msm_gpu_state base;
+	u32 *hlsqregs;
+};
+
+#define gpu_poll_timeout(gpu, addr, val, cond, interval, timeout) \
+	readl_poll_timeout((gpu)->mmio + ((addr) << 2), val, cond, \
+		interval, timeout)
+
+static int a5xx_crashdumper_init(struct msm_gpu *gpu,
+		struct a5xx_crashdumper *dumper)
+{
+	dumper->ptr = msm_gem_kernel_new_locked(gpu->dev,
+		SZ_1M, MSM_BO_UNCACHED, gpu->aspace,
+		&dumper->bo, &dumper->iova);
+
+	if (IS_ERR(dumper->ptr))
+		return PTR_ERR(dumper->ptr);
+
+	return 0;
+}
+
+static void a5xx_crashdumper_free(struct msm_gpu *gpu,
+		struct a5xx_crashdumper *dumper)
+{
+	msm_gem_put_iova(dumper->bo, gpu->aspace);
+	msm_gem_put_vaddr(dumper->bo);
+
+	drm_gem_object_unreference(dumper->bo);
+}
+
+static int a5xx_crashdumper_run(struct msm_gpu *gpu,
+		struct a5xx_crashdumper *dumper)
+{
+	u32 val;
+
+	if (IS_ERR_OR_NULL(dumper->ptr))
+		return -EINVAL;
+
+	gpu_write64(gpu, REG_A5XX_CP_CRASH_SCRIPT_BASE_LO,
+		REG_A5XX_CP_CRASH_SCRIPT_BASE_HI, dumper->iova);
+
+	gpu_write(gpu, REG_A5XX_CP_CRASH_DUMP_CNTL, 1);
+
+	return gpu_poll_timeout(gpu, REG_A5XX_CP_CRASH_DUMP_CNTL, val,
+		val & 0x04, 100, 10000);
+}
+
+/*
+ * These are a list of the registers that need to be read through the HLSQ
+ * aperture through the crashdumper.  These are not nominally accessible from
+ * the CPU on a secure platform.
+ */
+static const struct {
+	u32 type;
+	u32 regoffset;
+	u32 count;
+} a5xx_hlsq_aperture_regs[] = {
+	{ 0x35, 0xe00, 0x32 },   /* HSLQ non-context */
+	{ 0x31, 0x2080, 0x1 },   /* HLSQ 2D context 0 */
+	{ 0x33, 0x2480, 0x1 },   /* HLSQ 2D context 1 */
+	{ 0x32, 0xe780, 0x62 },  /* HLSQ 3D context 0 */
+	{ 0x34, 0xef80, 0x62 },  /* HLSQ 3D context 1 */
+	{ 0x3f, 0x0ec0, 0x40 },  /* SP non-context */
+	{ 0x3d, 0x2040, 0x1 },   /* SP 2D context 0 */
+	{ 0x3b, 0x2440, 0x1 },   /* SP 2D context 1 */
+	{ 0x3e, 0xe580, 0x170 }, /* SP 3D context 0 */
+	{ 0x3c, 0xed80, 0x170 }, /* SP 3D context 1 */
+	{ 0x3a, 0x0f00, 0x1c },  /* TP non-context */
+	{ 0x38, 0x2000, 0xa },   /* TP 2D context 0 */
+	{ 0x36, 0x2400, 0xa },   /* TP 2D context 1 */
+	{ 0x39, 0xe700, 0x80 },  /* TP 3D context 0 */
+	{ 0x37, 0xef00, 0x80 },  /* TP 3D context 1 */
+};
+
+static void a5xx_gpu_state_get_hlsq_regs(struct msm_gpu *gpu,
+		struct a5xx_gpu_state *a5xx_state)
+{
+	struct a5xx_crashdumper dumper = { 0 };
+	u32 offset, count = 0;
+	u64 *ptr;
+	int i;
+
+	if (a5xx_crashdumper_init(gpu, &dumper))
+		return;
+
+	/* The script will be written at offset 0 */
+	ptr = dumper.ptr;
+
+	/* Start writing the data at offset 256k */
+	offset = dumper.iova + (256 * SZ_1K);
+
+	/* Count how many additional registers to get from the HLSQ aperture */
+	for (i = 0; i < ARRAY_SIZE(a5xx_hlsq_aperture_regs); i++)
+		count += a5xx_hlsq_aperture_regs[i].count;
+
+	a5xx_state->hlsqregs = kcalloc(count, sizeof(u32), GFP_KERNEL);
+	if (!a5xx_state->hlsqregs)
+		return;
+
+	/* Build the crashdump script */
+	for (i = 0; i < ARRAY_SIZE(a5xx_hlsq_aperture_regs); i++) {
+		u32 type = a5xx_hlsq_aperture_regs[i].type;
+		u32 c = a5xx_hlsq_aperture_regs[i].count;
+
+		/* Write the register to select the desired bank */
+		*ptr++ = ((u64) type << 8);
+		*ptr++ = (((u64) REG_A5XX_HLSQ_DBG_READ_SEL) << 44) |
+			(1 << 21) | 1;
+
+		*ptr++ = offset;
+		*ptr++ = (((u64) REG_A5XX_HLSQ_DBG_AHB_READ_APERTURE) << 44)
+			| c;
+
+		offset += c * sizeof(u32);
+	}
+
+	/* Write two zeros to close off the script */
+	*ptr++ = 0;
+	*ptr++ = 0;
+
+	if (a5xx_crashdumper_run(gpu, &dumper)) {
+		kfree(a5xx_state->hlsqregs);
+		a5xx_crashdumper_free(gpu, &dumper);
+		return;
+	}
+
+	/* Copy the data from the crashdumper to the state */
+	memcpy(a5xx_state->hlsqregs, dumper.ptr + (256 * SZ_1K),
+		count * sizeof(u32));
+
+	a5xx_crashdumper_free(gpu, &dumper);
+}
+
 static struct msm_gpu_state *a5xx_gpu_state_get(struct msm_gpu *gpu)
 {
-	struct msm_gpu_state *state;
+	struct a5xx_gpu_state *a5xx_state = kzalloc(sizeof(*a5xx_state),
+			GFP_KERNEL);
 
-	/*
-	 * Temporarily disable hardware clock gating before going into
-	 * adreno_show to avoid issues while reading the registers
-	 */
+	if (!a5xx_state)
+		return ERR_PTR(-ENOMEM);
+
+	/* Temporarily disable hardware clock gating before reading the hw */
 	a5xx_set_hwcg(gpu, false);
 
-	state = adreno_gpu_state_get(gpu);
+	/* First get the generic state from the adreno core */
+	adreno_gpu_state_get(gpu, &(a5xx_state->base));
+
+	a5xx_state->base.rbbm_status = gpu_read(gpu, REG_A5XX_RBBM_STATUS);
 
-	if (!IS_ERR(state))
-		state->rbbm_status = gpu_read(gpu, REG_A5XX_RBBM_STATUS);
+	/* Get the HLSQ regs with the help of the crashdumper */
+	a5xx_gpu_state_get_hlsq_regs(gpu, a5xx_state);
 
 	a5xx_set_hwcg(gpu, true);
 
-	return state;
+	return &a5xx_state->base;
+}
+
+static void a5xx_gpu_state_destroy(struct kref *kref)
+{
+	struct msm_gpu_state *state = container_of(kref,
+		struct msm_gpu_state, ref);
+	struct a5xx_gpu_state *a5xx_state = container_of(state,
+		struct a5xx_gpu_state, base);
+
+	kfree(a5xx_state->hlsqregs);
+
+	adreno_gpu_state_destroy(state);
+	kfree(a5xx_state);
+}
+
+int a5xx_gpu_state_put(struct msm_gpu_state *state)
+{
+	if (IS_ERR_OR_NULL(state))
+		return 1;
+
+	return kref_put(&state->ref, a5xx_gpu_state_destroy);
+}
+
+
+#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
+void a5xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
+		struct drm_printer *p)
+{
+	int i, j;
+	u32 pos = 0;
+	struct a5xx_gpu_state *a5xx_state = container_of(state,
+		struct a5xx_gpu_state, base);
+
+	if (IS_ERR_OR_NULL(state))
+		return;
+
+	adreno_show(gpu, state, p);
+
+	/* Dump the additional a5xx HLSQ registers */
+	if (!a5xx_state->hlsqregs)
+		return;
+
+	drm_printf(p, "registers-hlsq:\n");
+
+	for (i = 0; i < ARRAY_SIZE(a5xx_hlsq_aperture_regs); i++) {
+		u32 o = a5xx_hlsq_aperture_regs[i].regoffset;
+		u32 c = a5xx_hlsq_aperture_regs[i].count;
+
+		for (j = 0; j < c; j++, pos++, o++) {
+			/*
+			 * To keep the crashdump simple we pull the entire range
+			 * for each register type but not all of the registers
+			 * in the range are valid. Fortunately invalid registers
+			 * stick out like a sore thumb with a value of
+			 * 0xdeadbeef
+			 */
+			if (a5xx_state->hlsqregs[pos] == 0xdeadbeef)
+				continue;
+
+			drm_printf(p, "  - { offset: 0x%04x, value: 0x%08x }\n",
+				o << 2, a5xx_state->hlsqregs[pos]);
+		}
+	}
 }
+#endif
 
 static struct msm_ringbuffer *a5xx_active_ring(struct msm_gpu *gpu)
 {
@@ -1244,14 +1454,14 @@ static const struct adreno_gpu_funcs funcs = {
 		.irq = a5xx_irq,
 		.destroy = a5xx_destroy,
 #if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
-		.show = adreno_show,
+		.show = a5xx_show,
 #endif
 #if defined(CONFIG_DEBUG_FS)
 		.debugfs_init = a5xx_debugfs_init,
 #endif
 		.gpu_busy = a5xx_gpu_busy,
 		.gpu_state_get = a5xx_gpu_state_get,
-		.gpu_state_put = adreno_gpu_state_put,
+		.gpu_state_put = a5xx_gpu_state_put,
 	},
 	.get_timestamp = a5xx_get_timestamp,
 };
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 808d4fc9c4a1..cd418dab7a62 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -369,16 +369,11 @@ bool adreno_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
 	return false;
 }
 
-struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu)
+int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state)
 {
 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
-	struct msm_gpu_state *state;
 	int i, count = 0;
 
-	state = kzalloc(sizeof(*state), GFP_KERNEL);
-	if (!state)
-		return ERR_PTR(-ENOMEM);
-
 	kref_init(&state->ref);
 
 	do_gettimeofday(&state->time);
@@ -432,14 +427,12 @@ struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu)
 		state->nr_registers = count;
 	}
 
-	return state;
+	return 0;
 }
 
-static void adreno_gpu_state_destroy(struct kref *kref)
+void adreno_gpu_state_destroy(struct msm_gpu_state *state)
 {
 	int i;
-	struct msm_gpu_state *state = container_of(kref,
-		struct msm_gpu_state, ref);
 
 	for (i = 0; i < ARRAY_SIZE(state->ring); i++)
 		kfree(state->ring[i].data);
@@ -447,6 +440,14 @@ static void adreno_gpu_state_destroy(struct kref *kref)
 	kfree(state->comm);
 	kfree(state->cmd);
 	kfree(state->registers);
+}
+
+static void adreno_gpu_state_kref_destroy(struct kref *kref)
+{
+	struct msm_gpu_state *state = container_of(kref,
+		struct msm_gpu_state, ref);
+
+	adreno_gpu_state_destroy(state);
 	kfree(state);
 }
 
@@ -455,7 +456,7 @@ int adreno_gpu_state_put(struct msm_gpu_state *state)
 	if (IS_ERR_OR_NULL(state))
 		return 1;
 
-	return kref_put(&state->ref, adreno_gpu_state_destroy);
+	return kref_put(&state->ref, adreno_gpu_state_kref_destroy);
 }
 
 #if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index 4a868aaf1a70..4406776597fd 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -230,7 +230,9 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
 void adreno_gpu_cleanup(struct adreno_gpu *gpu);
 
 
-struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu);
+void adreno_gpu_state_destroy(struct msm_gpu_state *state);
+
+int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state);
 int adreno_gpu_state_put(struct msm_gpu_state *state);
 
 /* ringbuffer helpers (the parts that are adreno specific) */
commit 43a56687d15db09f3cf7b9d53b182bdef86c17c0
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Tue Jul 24 10:33:29 2018 -0600

    drm/msm/adreno: Add ringbuffer data to the GPU state
    
    Add the contents of each ringbuffer to the GPU state and dump the
    data in the crash file encoded with ascii85. To save space only
    the used portions of the ringbuffer are dumped.
    
    Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/Documentation/gpu/msm-crash-dump.rst b/Documentation/gpu/msm-crash-dump.rst
index 75ab1d541c03..35e87004e006 100644
--- a/Documentation/gpu/msm-crash-dump.rst
+++ b/Documentation/gpu/msm-crash-dump.rst
@@ -59,6 +59,13 @@ ringbuffer
 	wptr
 		The current write pointer (wptr) for the ringbuffer.
 
+	size
+		Maximum size of the ringbuffer programmed in the hardware.
+
+	data
+		The contents of the ring encoded as ascii85.  Only the used
+		portions of the ring will be printed.
+
 registers
 	Set of registers values. Each entry is on its own line enclosed
 	by brackets { }.
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index c7a998d9dc85..808d4fc9c4a1 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -17,6 +17,7 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/ascii85.h>
 #include <linux/pm_opp.h>
 #include "adreno_gpu.h"
 #include "msm_gem.h"
@@ -383,11 +384,29 @@ struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu)
 	do_gettimeofday(&state->time);
 
 	for (i = 0; i < gpu->nr_rings; i++) {
+		int size = 0, j;
+
 		state->ring[i].fence = gpu->rb[i]->memptrs->fence;
 		state->ring[i].iova = gpu->rb[i]->iova;
 		state->ring[i].seqno = gpu->rb[i]->seqno;
 		state->ring[i].rptr = get_rptr(adreno_gpu, gpu->rb[i]);
 		state->ring[i].wptr = get_wptr(gpu->rb[i]);
+
+		/* Copy at least 'wptr' dwords of the data */
+		size = state->ring[i].wptr;
+
+		/* After wptr find the last non zero dword to save space */
+		for (j = state->ring[i].wptr; j < MSM_GPU_RINGBUFFER_SZ >> 2; j++)
+			if (gpu->rb[i]->start[j])
+				size = j + 1;
+
+		if (size) {
+			state->ring[i].data = kmalloc(size << 2, GFP_KERNEL);
+			if (state->ring[i].data) {
+				memcpy(state->ring[i].data, gpu->rb[i]->start, size << 2);
+				state->ring[i].data_size = size << 2;
+			}
+		}
 	}
 
 	/* Count the number of registers */
@@ -418,9 +437,13 @@ struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu)
 
 static void adreno_gpu_state_destroy(struct kref *kref)
 {
+	int i;
 	struct msm_gpu_state *state = container_of(kref,
 		struct msm_gpu_state, ref);
 
+	for (i = 0; i < ARRAY_SIZE(state->ring); i++)
+		kfree(state->ring[i].data);
+
 	kfree(state->comm);
 	kfree(state->cmd);
 	kfree(state->registers);
@@ -461,6 +484,22 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
 		drm_printf(p, "    retired-fence: %d\n", state->ring[i].fence);
 		drm_printf(p, "    rptr: %d\n", state->ring[i].rptr);
 		drm_printf(p, "    wptr: %d\n", state->ring[i].wptr);
+		drm_printf(p, "    size: %d\n", MSM_GPU_RINGBUFFER_SZ);
+
+		if (state->ring[i].data && state->ring[i].data_size) {
+			u32 *ptr = (u32 *) state->ring[i].data;
+			char out[ASCII85_BUFSZ];
+			long len = ascii85_encode_len(state->ring[i].data_size);
+			int j;
+
+			drm_printf(p, "    data: !!ascii85 |\n");
+			drm_printf(p, "     ");
+
+			for (j = 0; j < len; j++)
+				drm_printf(p, ascii85_encode(ptr[j], out));
+
+			drm_printf(p, "\n");
+		}
 	}
 
 	drm_puts(p, "registers:\n");
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index b1cb44922441..878090b57e90 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -191,6 +191,8 @@ struct msm_gpu_state {
 		u32 seqno;
 		u32 rptr;
 		u32 wptr;
+		void *data;
+		int data_size;
 	} ring[MSM_GPU_MAX_RINGS];
 
 	int nr_registers;
commit bcf1d9fa5d03c1e86733411b5dc3a76ba7d75e6e
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Tue Jul 24 10:33:28 2018 -0600

    drm/msm/adreno: Convert the show/crash file format
    
    Convert the format of the 'show' debugfs file and the crash
    dump to a  format resembling YAML. This should be easier to
    parse and be more flexible for future changes and expansions.
    
    v2: Use a standard .rst for the msm crashdump documentation
    
    Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/Documentation/gpu/msm-crash-dump.rst b/Documentation/gpu/msm-crash-dump.rst
new file mode 100644
index 000000000000..75ab1d541c03
--- /dev/null
+++ b/Documentation/gpu/msm-crash-dump.rst
@@ -0,0 +1,71 @@
+=====================
+MSM Crash Dump Format
+=====================
+
+Following a GPU hang the MSM driver outputs debugging information via
+/sys/kernel/dri/X/show or via devcoredump (/sys/class/devcoredump/dcdX/data).
+This document describes how the output is formatted.
+
+Each entry is in the form key: value. Sections headers will not have a value
+and all the contents of a section will be indented two spaces from the header.
+Each section might have multiple array entries the start of which is designated
+by a (-).
+
+Mappings
+--------
+
+kernel
+	The kernel version that generated the dump (UTS_RELEASE).
+
+module
+	The module that generated the crashdump.
+
+time
+	The kernel time at crash formated as seconds.microseconds.
+
+comm
+	Comm string for the binary that generated the fault.
+
+cmdline
+	Command line for the binary that generated the fault.
+
+revision
+	ID of the GPU that generated the crash formatted as
+	core.major.minor.patchlevel separated by dots.
+
+rbbm-status
+	The current value of RBBM_STATUS which shows what top level GPU
+	components are in use at the time of crash.
+
+ringbuffer
+	Section containing the contents of each ringbuffer. Each ringbuffer is
+	identified with an id number.
+
+	id
+		Ringbuffer ID (0 based index).  Each ringbuffer in the section
+		will have its own unique id.
+	iova
+		GPU address of the ringbuffer.
+
+	last-fence
+		The last fence that was issued on the ringbuffer
+
+	retired-fence
+		The last fence retired on the ringbuffer.
+
+	rptr
+		The current read pointer (rptr) for the ringbuffer.
+
+	wptr
+		The current write pointer (wptr) for the ringbuffer.
+
+registers
+	Set of registers values. Each entry is on its own line enclosed
+	by brackets { }.
+
+	offset
+		Byte offset of the register from the start of the
+		GPU memory region.
+
+	value
+		Hexadecimal value of the register.
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index c72e3afc43a8..c7a998d9dc85 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -445,23 +445,28 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
 	if (IS_ERR_OR_NULL(state))
 		return;
 
-	drm_printf(p, "status:   %08x\n", state->rbbm_status);
 	drm_printf(p, "revision: %d (%d.%d.%d.%d)\n",
 			adreno_gpu->info->revn, adreno_gpu->rev.core,
 			adreno_gpu->rev.major, adreno_gpu->rev.minor,
 			adreno_gpu->rev.patchid);
 
-	for (i = 0; i < gpu->nr_rings; i++) {
-		drm_printf(p, "rb %d: fence:    %d/%d\n", i,
-			state->ring[i].fence, state->ring[i].seqno);
+	drm_printf(p, "rbbm-status: 0x%08x\n", state->rbbm_status);
+
+	drm_puts(p, "ringbuffer:\n");
 
-		drm_printf(p, "      rptr:     %d\n", state->ring[i].rptr);
-		drm_printf(p, "rb wptr:  %d\n", state->ring[i].wptr);
+	for (i = 0; i < gpu->nr_rings; i++) {
+		drm_printf(p, "  - id: %d\n", i);
+		drm_printf(p, "    iova: 0x%016llx\n", state->ring[i].iova);
+		drm_printf(p, "    last-fence: %d\n", state->ring[i].seqno);
+		drm_printf(p, "    retired-fence: %d\n", state->ring[i].fence);
+		drm_printf(p, "    rptr: %d\n", state->ring[i].rptr);
+		drm_printf(p, "    wptr: %d\n", state->ring[i].wptr);
 	}
 
-	drm_printf(p, "IO:region %s 00000000 00020000\n", gpu->name);
+	drm_puts(p, "registers:\n");
+
 	for (i = 0; i < state->nr_registers; i++) {
-		drm_printf(p, "IO:R %08x %08x\n",
+		drm_printf(p, "  - { offset: 0x%04x, value: 0x%08x }\n",
 			state->registers[i * 2] << 2,
 			state->registers[(i * 2) + 1]);
 	}
commit c0fec7f562ec76404ef0f074a89113a703587f3d
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Tue Jul 24 10:33:27 2018 -0600

    drm/msm/gpu: Capture the GPU state on a GPU hang
    
    Capture the GPU state on a GPU hang and store it for later playback
    via the devcoredump facility. Only one crash state is stored at a
    time on the assumption that the first hang is usually the most
    interesting. The existing crash state can be cleared after capturing
    it and then a new one will be captured on the next hang.
    
    Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 38cbde971b48..843a9d40c05e 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -12,6 +12,7 @@ config DRM_MSM
 	select SHMEM
 	select TMPFS
 	select QCOM_SCM
+	select WANT_DEV_COREDUMP
 	select SND_SOC_HDMI_CODEC if SND_SOC
 	select SYNC_FILE
 	select PM_OPP
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index 4cffec2b6adc..fc502e412132 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -454,7 +454,7 @@ static const struct adreno_gpu_funcs funcs = {
 		.active_ring = adreno_active_ring,
 		.irq = a3xx_irq,
 		.destroy = a3xx_destroy,
-#ifdef CONFIG_DEBUG_FS
+#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
 		.show = adreno_show,
 #endif
 		.gpu_state_get = a3xx_gpu_state_get,
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
index 95f08c22e8d7..8129cf037db1 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
@@ -540,7 +540,7 @@ static const struct adreno_gpu_funcs funcs = {
 		.active_ring = adreno_active_ring,
 		.irq = a4xx_irq,
 		.destroy = a4xx_destroy,
-#ifdef CONFIG_DEBUG_FS
+#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
 		.show = adreno_show,
 #endif
 		.gpu_state_get = a4xx_gpu_state_get,
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 5f1aab3c1cb1..16074fa6bf1e 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -1243,8 +1243,10 @@ static const struct adreno_gpu_funcs funcs = {
 		.active_ring = a5xx_active_ring,
 		.irq = a5xx_irq,
 		.destroy = a5xx_destroy,
-#ifdef CONFIG_DEBUG_FS
+#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
 		.show = adreno_show,
+#endif
+#if defined(CONFIG_DEBUG_FS)
 		.debugfs_init = a5xx_debugfs_init,
 #endif
 		.gpu_busy = a5xx_gpu_busy,
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 42828253ede5..c72e3afc43a8 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -378,6 +378,8 @@ struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu)
 	if (!state)
 		return ERR_PTR(-ENOMEM);
 
+	kref_init(&state->ref);
+
 	do_gettimeofday(&state->time);
 
 	for (i = 0; i < gpu->nr_rings; i++) {
@@ -414,18 +416,28 @@ struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu)
 	return state;
 }
 
-void adreno_gpu_state_put(struct msm_gpu_state *state)
+static void adreno_gpu_state_destroy(struct kref *kref)
 {
-	if (IS_ERR_OR_NULL(state))
-		return;
+	struct msm_gpu_state *state = container_of(kref,
+		struct msm_gpu_state, ref);
 
+	kfree(state->comm);
+	kfree(state->cmd);
 	kfree(state->registers);
 	kfree(state);
 }
 
-#ifdef CONFIG_DEBUG_FS
+int adreno_gpu_state_put(struct msm_gpu_state *state)
+{
+	if (IS_ERR_OR_NULL(state))
+		return 1;
+
+	return kref_put(&state->ref, adreno_gpu_state_destroy);
+}
+
+#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
 void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
-		struct seq_file *m)
+		struct drm_printer *p)
 {
 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
 	int i;
@@ -433,23 +445,23 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
 	if (IS_ERR_OR_NULL(state))
 		return;
 
-	seq_printf(m, "status:   %08x\n", state->rbbm_status);
-	seq_printf(m, "revision: %d (%d.%d.%d.%d)\n",
+	drm_printf(p, "status:   %08x\n", state->rbbm_status);
+	drm_printf(p, "revision: %d (%d.%d.%d.%d)\n",
 			adreno_gpu->info->revn, adreno_gpu->rev.core,
 			adreno_gpu->rev.major, adreno_gpu->rev.minor,
 			adreno_gpu->rev.patchid);
 
 	for (i = 0; i < gpu->nr_rings; i++) {
-		seq_printf(m, "rb %d: fence:    %d/%d\n", i,
+		drm_printf(p, "rb %d: fence:    %d/%d\n", i,
 			state->ring[i].fence, state->ring[i].seqno);
 
-		seq_printf(m, "      rptr:     %d\n", state->ring[i].rptr);
-		seq_printf(m, "rb wptr:  %d\n", state->ring[i].wptr);
+		drm_printf(p, "      rptr:     %d\n", state->ring[i].rptr);
+		drm_printf(p, "rb wptr:  %d\n", state->ring[i].wptr);
 	}
 
-	seq_printf(m, "IO:region %s 00000000 00020000\n", gpu->name);
+	drm_printf(p, "IO:region %s 00000000 00020000\n", gpu->name);
 	for (i = 0; i < state->nr_registers; i++) {
-		seq_printf(m, "IO:R %08x %08x\n",
+		drm_printf(p, "IO:R %08x %08x\n",
 			state->registers[i * 2] << 2,
 			state->registers[(i * 2) + 1]);
 	}
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index 90b6b59252af..4a868aaf1a70 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -215,9 +215,9 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
 		struct msm_file_private *ctx);
 void adreno_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
 bool adreno_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
-#ifdef CONFIG_DEBUG_FS
+#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
 void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
-		struct seq_file *m);
+		struct drm_printer *p);
 #endif
 void adreno_dump_info(struct msm_gpu *gpu);
 void adreno_dump(struct msm_gpu *gpu);
@@ -231,7 +231,7 @@ void adreno_gpu_cleanup(struct adreno_gpu *gpu);
 
 
 struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu);
-void adreno_gpu_state_put(struct msm_gpu_state *state);
+int adreno_gpu_state_put(struct msm_gpu_state *state);
 
 /* ringbuffer helpers (the parts that are adreno specific) */
 
diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c
index c3da12179888..f0da0d3c8a80 100644
--- a/drivers/gpu/drm/msm/msm_debugfs.c
+++ b/drivers/gpu/drm/msm/msm_debugfs.c
@@ -29,6 +29,7 @@ struct msm_gpu_show_priv {
 
 static int msm_gpu_show(struct seq_file *m, void *arg)
 {
+	struct drm_printer p = drm_seq_file_printer(m);
 	struct msm_gpu_show_priv *show_priv = m->private;
 	struct msm_drm_private *priv = show_priv->dev->dev_private;
 	struct msm_gpu *gpu = priv->gpu;
@@ -38,8 +39,8 @@ static int msm_gpu_show(struct seq_file *m, void *arg)
 	if (ret)
 		return ret;
 
-	seq_printf(m, "%s Status:\n", gpu->name);
-	gpu->funcs->show(gpu, show_priv->state, m);
+	drm_printf(&p, "%s Status:\n", gpu->name);
+	gpu->funcs->show(gpu, show_priv->state, &p);
 
 	mutex_unlock(&show_priv->dev->struct_mutex);
 
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 03ba8872cc99..5f39549d9a8b 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -20,10 +20,11 @@
 #include "msm_mmu.h"
 #include "msm_fence.h"
 
+#include <generated/utsrelease.h>
 #include <linux/string_helpers.h>
 #include <linux/pm_opp.h>
 #include <linux/devfreq.h>
-
+#include <linux/devcoredump.h>
 
 /*
  * Power Management:
@@ -273,6 +274,81 @@ int msm_gpu_hw_init(struct msm_gpu *gpu)
 	return ret;
 }
 
+#ifdef CONFIG_DEV_COREDUMP
+static ssize_t msm_gpu_devcoredump_read(char *buffer, loff_t offset,
+		size_t count, void *data, size_t datalen)
+{
+	struct msm_gpu *gpu = data;
+	struct drm_print_iterator iter;
+	struct drm_printer p;
+	struct msm_gpu_state *state;
+
+	state = msm_gpu_crashstate_get(gpu);
+	if (!state)
+		return 0;
+
+	iter.data = buffer;
+	iter.offset = 0;
+	iter.start = offset;
+	iter.remain = count;
+
+	p = drm_coredump_printer(&iter);
+
+	drm_printf(&p, "---\n");
+	drm_printf(&p, "kernel: " UTS_RELEASE "\n");
+	drm_printf(&p, "module: " KBUILD_MODNAME "\n");
+	drm_printf(&p, "time: %ld.%ld\n",
+		state->time.tv_sec, state->time.tv_usec);
+	if (state->comm)
+		drm_printf(&p, "comm: %s\n", state->comm);
+	if (state->cmd)
+		drm_printf(&p, "cmdline: %s\n", state->cmd);
+
+	gpu->funcs->show(gpu, state, &p);
+
+	msm_gpu_crashstate_put(gpu);
+
+	return count - iter.remain;
+}
+
+static void msm_gpu_devcoredump_free(void *data)
+{
+	struct msm_gpu *gpu = data;
+
+	msm_gpu_crashstate_put(gpu);
+}
+
+static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, char *comm,
+		char *cmd)
+{
+	struct msm_gpu_state *state;
+
+	/* Only save one crash state at a time */
+	if (gpu->crashstate)
+		return;
+
+	state = gpu->funcs->gpu_state_get(gpu);
+	if (IS_ERR_OR_NULL(state))
+		return;
+
+	/* Fill in the additional crash state information */
+	state->comm = kstrdup(comm, GFP_KERNEL);
+	state->cmd = kstrdup(cmd, GFP_KERNEL);
+
+	/* Set the active crash state to be dumped on failure */
+	gpu->crashstate = state;
+
+	/* FIXME: Release the crashstate if this errors out? */
+	dev_coredumpm(gpu->dev->dev, THIS_MODULE, gpu, 0, GFP_KERNEL,
+		msm_gpu_devcoredump_read, msm_gpu_devcoredump_free);
+}
+#else
+static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, char *comm,
+		char *cmd)
+{
+}
+#endif
+
 /*
  * Hangcheck detection for locked gpu:
  */
@@ -356,6 +432,11 @@ static void recover_worker(struct work_struct *work)
 			msm_rd_dump_submit(priv->hangrd, submit, NULL);
 	}
 
+	/* Record the crash state */
+	pm_runtime_get_sync(&gpu->pdev->dev);
+	msm_gpu_crashstate_capture(gpu, comm, cmd);
+	pm_runtime_put_sync(&gpu->pdev->dev);
+
 	kfree(cmd);
 	kfree(comm);
 
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index d204eca8518e..b1cb44922441 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -66,13 +66,13 @@ struct msm_gpu_funcs {
 #ifdef CONFIG_DEBUG_FS
 	/* show GPU status in debugfs: */
 	void (*show)(struct msm_gpu *gpu, struct msm_gpu_state *state,
-			struct seq_file *m);
+			struct drm_printer *p);
 	/* for generation specific debugfs: */
 	int (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor);
 #endif
 	int (*gpu_busy)(struct msm_gpu *gpu, uint64_t *value);
 	struct msm_gpu_state *(*gpu_state_get)(struct msm_gpu *gpu);
-	void (*gpu_state_put)(struct msm_gpu_state *state);
+	int (*gpu_state_put)(struct msm_gpu_state *state);
 };
 
 struct msm_gpu {
@@ -133,6 +133,8 @@ struct msm_gpu {
 		u64 busy_cycles;
 		ktime_t time;
 	} devfreq;
+
+	struct msm_gpu_state *crashstate;
 };
 
 /* It turns out that all targets use the same ringbuffer size */
@@ -180,6 +182,7 @@ struct msm_gpu_submitqueue {
 };
 
 struct msm_gpu_state {
+	struct kref ref;
 	struct timeval time;
 
 	struct {
@@ -194,6 +197,9 @@ struct msm_gpu_state {
 	u32 *registers;
 
 	u32 rbbm_status;
+
+	char *comm;
+	char *cmd;
 };
 
 static inline void gpu_write(struct msm_gpu *gpu, u32 reg, u32 data)
@@ -275,4 +281,32 @@ static inline void msm_submitqueue_put(struct msm_gpu_submitqueue *queue)
 		kref_put(&queue->ref, msm_submitqueue_destroy);
 }
 
+static inline struct msm_gpu_state *msm_gpu_crashstate_get(struct msm_gpu *gpu)
+{
+	struct msm_gpu_state *state = NULL;
+
+	mutex_lock(&gpu->dev->struct_mutex);
+
+	if (gpu->crashstate) {
+		kref_get(&gpu->crashstate->ref);
+		state = gpu->crashstate;
+	}
+
+	mutex_unlock(&gpu->dev->struct_mutex);
+
+	return state;
+}
+
+static inline void msm_gpu_crashstate_put(struct msm_gpu *gpu)
+{
+	mutex_lock(&gpu->dev->struct_mutex);
+
+	if (gpu->crashstate) {
+		if (gpu->funcs->gpu_state_put(gpu->crashstate))
+			gpu->crashstate = NULL;
+	}
+
+	mutex_unlock(&gpu->dev->struct_mutex);
+}
+
 #endif /* __MSM_GPU_H__ */
commit 65a3c2748e882da03102369edb6991e1dd88456e
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Tue Jul 24 10:33:26 2018 -0600

    drm/msm/gpu: Rearrange the code that collects the task during a hang
    
    Do a bit of cleanup to prepare for upcoming changes to pass the
    hanging task comm and cmdline to the crash dump function.
    
    v2: Use GFP_ATOMIC while holding the rcu lock per Chris Wilson
    
    Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 1c09acfb4028..03ba8872cc99 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -314,6 +314,7 @@ static void recover_worker(struct work_struct *work)
 	struct msm_drm_private *priv = dev->dev_private;
 	struct msm_gem_submit *submit;
 	struct msm_ringbuffer *cur_ring = gpu->funcs->active_ring(gpu);
+	char *comm = NULL, *cmd = NULL;
 	int i;
 
 	mutex_lock(&dev->struct_mutex);
@@ -327,7 +328,7 @@ static void recover_worker(struct work_struct *work)
 		rcu_read_lock();
 		task = pid_task(submit->pid, PIDTYPE_PID);
 		if (task) {
-			char *cmd;
+			comm = kstrdup(task->comm, GFP_ATOMIC);
 
 			/*
 			 * So slightly annoying, in other paths like
@@ -340,22 +341,23 @@ static void recover_worker(struct work_struct *work)
 			 * about the submit going away.
 			 */
 			mutex_unlock(&dev->struct_mutex);
-			cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL);
+			cmd = kstrdup_quotable_cmdline(task, GFP_ATOMIC);
 			mutex_lock(&dev->struct_mutex);
+		}
+		rcu_read_unlock();
 
+		if (comm && cmd) {
 			dev_err(dev->dev, "%s: offending task: %s (%s)\n",
-				gpu->name, task->comm, cmd);
+				gpu->name, comm, cmd);
 
 			msm_rd_dump_submit(priv->hangrd, submit,
-				"offending task: %s (%s)", task->comm, cmd);
-
-			kfree(cmd);
-		} else {
+				"offending task: %s (%s)", comm, cmd);
+		} else
 			msm_rd_dump_submit(priv->hangrd, submit, NULL);
-		}
-		rcu_read_unlock();
 	}
 
+	kfree(cmd);
+	kfree(comm);
 
 	/*
 	 * Update all the rings with the latest and greatest fence.. this
commit 4f776f4511c7f7b6576dfc38c609b168b9188d72
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Tue Jul 24 10:33:25 2018 -0600

    drm/msm/gpu: Convert the GPU show function to use the GPU state
    
    Convert the existing GPU show function to use the GPU state to
    dump the information rather than reading it directly from the hardware.
    This will require an additional step to capture the state before
    dumping it for the existing nodes but it will greatly facilitate reusing
    the same code for dumping a previously captured state from a GPU hang.
    
    Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index b707b5bca9ab..4cffec2b6adc 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -411,15 +411,6 @@ static const unsigned int a3xx_registers[] = {
 	~0   /* sentinel */
 };
 
-#ifdef CONFIG_DEBUG_FS
-static void a3xx_show(struct msm_gpu *gpu, struct seq_file *m)
-{
-	seq_printf(m, "status:   %08x\n",
-			gpu_read(gpu, REG_A3XX_RBBM_STATUS));
-	adreno_show(gpu, m);
-}
-#endif
-
 /* would be nice to not have to duplicate the _show() stuff with printk(): */
 static void a3xx_dump(struct msm_gpu *gpu)
 {
@@ -464,7 +455,7 @@ static const struct adreno_gpu_funcs funcs = {
 		.irq = a3xx_irq,
 		.destroy = a3xx_destroy,
 #ifdef CONFIG_DEBUG_FS
-		.show = a3xx_show,
+		.show = adreno_show,
 #endif
 		.gpu_state_get = a3xx_gpu_state_get,
 		.gpu_state_put = adreno_gpu_state_put,
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
index 17e97ebc1077..95f08c22e8d7 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
@@ -455,16 +455,6 @@ static const unsigned int a4xx_registers[] = {
 	~0 /* sentinel */
 };
 
-#ifdef CONFIG_DEBUG_FS
-static void a4xx_show(struct msm_gpu *gpu, struct seq_file *m)
-{
-	seq_printf(m, "status:   %08x\n",
-			gpu_read(gpu, REG_A4XX_RBBM_STATUS));
-	adreno_show(gpu, m);
-
-}
-#endif
-
 static struct msm_gpu_state *a4xx_gpu_state_get(struct msm_gpu *gpu)
 {
 	struct msm_gpu_state *state = adreno_gpu_state_get(gpu);
@@ -551,7 +541,7 @@ static const struct adreno_gpu_funcs funcs = {
 		.irq = a4xx_irq,
 		.destroy = a4xx_destroy,
 #ifdef CONFIG_DEBUG_FS
-		.show = a4xx_show,
+		.show = adreno_show,
 #endif
 		.gpu_state_get = a4xx_gpu_state_get,
 		.gpu_state_put = adreno_gpu_state_put,
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 9e85e4f7016d..5f1aab3c1cb1 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -1215,22 +1215,6 @@ static struct msm_gpu_state *a5xx_gpu_state_get(struct msm_gpu *gpu)
 	return state;
 }
 
-#ifdef CONFIG_DEBUG_FS
-static void a5xx_show(struct msm_gpu *gpu, struct seq_file *m)
-{
-	seq_printf(m, "status:   %08x\n",
-			gpu_read(gpu, REG_A5XX_RBBM_STATUS));
-
-	/*
-	 * Temporarily disable hardware clock gating before going into
-	 * adreno_show to avoid issues while reading the registers
-	 */
-	a5xx_set_hwcg(gpu, false);
-	adreno_show(gpu, m);
-	a5xx_set_hwcg(gpu, true);
-}
-#endif
-
 static struct msm_ringbuffer *a5xx_active_ring(struct msm_gpu *gpu)
 {
 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
@@ -1260,7 +1244,7 @@ static const struct adreno_gpu_funcs funcs = {
 		.irq = a5xx_irq,
 		.destroy = a5xx_destroy,
 #ifdef CONFIG_DEBUG_FS
-		.show = a5xx_show,
+		.show = adreno_show,
 		.debugfs_init = a5xx_debugfs_init,
 #endif
 		.gpu_busy = a5xx_gpu_busy,
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 4286a539f40a..42828253ede5 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -424,38 +424,34 @@ void adreno_gpu_state_put(struct msm_gpu_state *state)
 }
 
 #ifdef CONFIG_DEBUG_FS
-void adreno_show(struct msm_gpu *gpu, struct seq_file *m)
+void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
+		struct seq_file *m)
 {
 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
 	int i;
 
+	if (IS_ERR_OR_NULL(state))
+		return;
+
+	seq_printf(m, "status:   %08x\n", state->rbbm_status);
 	seq_printf(m, "revision: %d (%d.%d.%d.%d)\n",
 			adreno_gpu->info->revn, adreno_gpu->rev.core,
 			adreno_gpu->rev.major, adreno_gpu->rev.minor,
 			adreno_gpu->rev.patchid);
 
 	for (i = 0; i < gpu->nr_rings; i++) {
-		struct msm_ringbuffer *ring = gpu->rb[i];
-
 		seq_printf(m, "rb %d: fence:    %d/%d\n", i,
-			ring->memptrs->fence, ring->seqno);
+			state->ring[i].fence, state->ring[i].seqno);
 
-		seq_printf(m, "      rptr:     %d\n",
-			get_rptr(adreno_gpu, ring));
-		seq_printf(m, "rb wptr:  %d\n", get_wptr(ring));
+		seq_printf(m, "      rptr:     %d\n", state->ring[i].rptr);
+		seq_printf(m, "rb wptr:  %d\n", state->ring[i].wptr);
 	}
 
-	/* dump these out in a form that can be parsed by demsm: */
 	seq_printf(m, "IO:region %s 00000000 00020000\n", gpu->name);
-	for (i = 0; adreno_gpu->registers[i] != ~0; i += 2) {
-		uint32_t start = adreno_gpu->registers[i];
-		uint32_t end   = adreno_gpu->registers[i+1];
-		uint32_t addr;
-
-		for (addr = start; addr <= end; addr++) {
-			uint32_t val = gpu_read(gpu, addr);
-			seq_printf(m, "IO:R %08x %08x\n", addr<<2, val);
-		}
+	for (i = 0; i < state->nr_registers; i++) {
+		seq_printf(m, "IO:R %08x %08x\n",
+			state->registers[i * 2] << 2,
+			state->registers[(i * 2) + 1]);
 	}
 }
 #endif
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index 734e31a9631f..90b6b59252af 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -216,7 +216,8 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
 void adreno_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
 bool adreno_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
 #ifdef CONFIG_DEBUG_FS
-void adreno_show(struct msm_gpu *gpu, struct seq_file *m);
+void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
+		struct seq_file *m);
 #endif
 void adreno_dump_info(struct msm_gpu *gpu);
 void adreno_dump(struct msm_gpu *gpu);
diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c
index 1ff3fda245d1..c3da12179888 100644
--- a/drivers/gpu/drm/msm/msm_debugfs.c
+++ b/drivers/gpu/drm/msm/msm_debugfs.c
@@ -16,26 +16,100 @@
  */
 
 #ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
 #include "msm_drv.h"
 #include "msm_gpu.h"
 #include "msm_kms.h"
 #include "msm_debugfs.h"
 
-static int msm_gpu_show(struct drm_device *dev, struct seq_file *m)
+struct msm_gpu_show_priv {
+	struct msm_gpu_state *state;
+	struct drm_device *dev;
+};
+
+static int msm_gpu_show(struct seq_file *m, void *arg)
+{
+	struct msm_gpu_show_priv *show_priv = m->private;
+	struct msm_drm_private *priv = show_priv->dev->dev_private;
+	struct msm_gpu *gpu = priv->gpu;
+	int ret;
+
+	ret = mutex_lock_interruptible(&show_priv->dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	seq_printf(m, "%s Status:\n", gpu->name);
+	gpu->funcs->show(gpu, show_priv->state, m);
+
+	mutex_unlock(&show_priv->dev->struct_mutex);
+
+	return 0;
+}
+
+static int msm_gpu_release(struct inode *inode, struct file *file)
+{
+	struct seq_file *m = file->private_data;
+	struct msm_gpu_show_priv *show_priv = m->private;
+	struct msm_drm_private *priv = show_priv->dev->dev_private;
+	struct msm_gpu *gpu = priv->gpu;
+	int ret;
+
+	ret = mutex_lock_interruptible(&show_priv->dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	gpu->funcs->gpu_state_put(show_priv->state);
+	mutex_unlock(&show_priv->dev->struct_mutex);
+
+	kfree(show_priv);
+
+	return single_release(inode, file);
+}
+
+static int msm_gpu_open(struct inode *inode, struct file *file)
 {
+	struct drm_device *dev = inode->i_private;
 	struct msm_drm_private *priv = dev->dev_private;
 	struct msm_gpu *gpu = priv->gpu;
+	struct msm_gpu_show_priv *show_priv;
+	int ret;
 
-	if (gpu) {
-		seq_printf(m, "%s Status:\n", gpu->name);
-		pm_runtime_get_sync(&gpu->pdev->dev);
-		gpu->funcs->show(gpu, m);
-		pm_runtime_put_sync(&gpu->pdev->dev);
+	if (!gpu)
+		return -ENODEV;
+
+	show_priv = kmalloc(sizeof(*show_priv), GFP_KERNEL);
+	if (!show_priv)
+		return -ENOMEM;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+
+	pm_runtime_get_sync(&gpu->pdev->dev);
+	show_priv->state = gpu->funcs->gpu_state_get(gpu);
+	pm_runtime_put_sync(&gpu->pdev->dev);
+
+	mutex_unlock(&dev->struct_mutex);
+
+	if (IS_ERR(show_priv->state)) {
+		ret = PTR_ERR(show_priv->state);
+		kfree(show_priv);
+		return ret;
 	}
 
-	return 0;
+	show_priv->dev = dev;
+
+	return single_open(file, msm_gpu_show, show_priv);
 }
 
+static const struct file_operations msm_gpu_fops = {
+	.owner = THIS_MODULE,
+	.open = msm_gpu_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = msm_gpu_release,
+};
+
 static int msm_gem_show(struct drm_device *dev, struct seq_file *m)
 {
 	struct msm_drm_private *priv = dev->dev_private;
@@ -105,7 +179,6 @@ static int show_locked(struct seq_file *m, void *arg)
 }
 
 static struct drm_info_list msm_debugfs_list[] = {
-		{"gpu", show_locked, 0, msm_gpu_show},
 		{"gem", show_locked, 0, msm_gem_show},
 		{ "mm", show_locked, 0, msm_mm_show },
 		{ "fb", show_locked, 0, msm_fb_show },
@@ -158,6 +231,9 @@ int msm_debugfs_init(struct drm_minor *minor)
 		return ret;
 	}
 
+	debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root,
+		dev, &msm_gpu_fops);
+
 	if (priv->kms->funcs->debugfs_init) {
 		ret = priv->kms->funcs->debugfs_init(priv->kms, minor);
 		if (ret)
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index de71cc04ecf3..d204eca8518e 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -65,7 +65,8 @@ struct msm_gpu_funcs {
 	void (*destroy)(struct msm_gpu *gpu);
 #ifdef CONFIG_DEBUG_FS
 	/* show GPU status in debugfs: */
-	void (*show)(struct msm_gpu *gpu, struct seq_file *m);
+	void (*show)(struct msm_gpu *gpu, struct msm_gpu_state *state,
+			struct seq_file *m);
 	/* for generation specific debugfs: */
 	int (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor);
 #endif
commit e00e473d9817e03cddbaf181a491c42ae8373482
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Tue Jul 24 10:33:24 2018 -0600

    drm/msm/gpu: Capture the state of the GPU
    
    Add the infrastructure to capture the current state of the GPU and
    store it in memory so that it can be dumped later.
    
    For now grab the same basic ringbuffer information and registers
    that are provided by the debugfs 'gpu' node but obviously this should
    be extended to capture a much larger set of GPU information.
    
    Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index 3ebbeb3a9b68..b707b5bca9ab 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -427,6 +427,19 @@ static void a3xx_dump(struct msm_gpu *gpu)
 			gpu_read(gpu, REG_A3XX_RBBM_STATUS));
 	adreno_dump(gpu);
 }
+
+static struct msm_gpu_state *a3xx_gpu_state_get(struct msm_gpu *gpu)
+{
+	struct msm_gpu_state *state = adreno_gpu_state_get(gpu);
+
+	if (IS_ERR(state))
+		return state;
+
+	state->rbbm_status = gpu_read(gpu, REG_A3XX_RBBM_STATUS);
+
+	return state;
+}
+
 /* Register offset defines for A3XX */
 static const unsigned int a3xx_register_offsets[REG_ADRENO_REGISTER_MAX] = {
 	REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_AXXX_CP_RB_BASE),
@@ -453,6 +466,8 @@ static const struct adreno_gpu_funcs funcs = {
 #ifdef CONFIG_DEBUG_FS
 		.show = a3xx_show,
 #endif
+		.gpu_state_get = a3xx_gpu_state_get,
+		.gpu_state_put = adreno_gpu_state_put,
 	},
 };
 
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
index 16d3d596638e..17e97ebc1077 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
@@ -465,6 +465,18 @@ static void a4xx_show(struct msm_gpu *gpu, struct seq_file *m)
 }
 #endif
 
+static struct msm_gpu_state *a4xx_gpu_state_get(struct msm_gpu *gpu)
+{
+	struct msm_gpu_state *state = adreno_gpu_state_get(gpu);
+
+	if (IS_ERR(state))
+		return state;
+
+	state->rbbm_status = gpu_read(gpu, REG_A4XX_RBBM_STATUS);
+
+	return state;
+}
+
 /* Register offset defines for A4XX, in order of enum adreno_regs */
 static const unsigned int a4xx_register_offsets[REG_ADRENO_REGISTER_MAX] = {
 	REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_A4XX_CP_RB_BASE),
@@ -541,6 +553,8 @@ static const struct adreno_gpu_funcs funcs = {
 #ifdef CONFIG_DEBUG_FS
 		.show = a4xx_show,
 #endif
+		.gpu_state_get = a4xx_gpu_state_get,
+		.gpu_state_put = adreno_gpu_state_put,
 	},
 	.get_timestamp = a4xx_get_timestamp,
 };
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index d39400e5bc42..9e85e4f7016d 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -1195,6 +1195,26 @@ static int a5xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
 	return 0;
 }
 
+static struct msm_gpu_state *a5xx_gpu_state_get(struct msm_gpu *gpu)
+{
+	struct msm_gpu_state *state;
+
+	/*
+	 * Temporarily disable hardware clock gating before going into
+	 * adreno_show to avoid issues while reading the registers
+	 */
+	a5xx_set_hwcg(gpu, false);
+
+	state = adreno_gpu_state_get(gpu);
+
+	if (!IS_ERR(state))
+		state->rbbm_status = gpu_read(gpu, REG_A5XX_RBBM_STATUS);
+
+	a5xx_set_hwcg(gpu, true);
+
+	return state;
+}
+
 #ifdef CONFIG_DEBUG_FS
 static void a5xx_show(struct msm_gpu *gpu, struct seq_file *m)
 {
@@ -1244,6 +1264,8 @@ static const struct adreno_gpu_funcs funcs = {
 		.debugfs_init = a5xx_debugfs_init,
 #endif
 		.gpu_busy = a5xx_gpu_busy,
+		.gpu_state_get = a5xx_gpu_state_get,
+		.gpu_state_put = adreno_gpu_state_put,
 	},
 	.get_timestamp = a5xx_get_timestamp,
 };
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index bcbf9f2a29f9..4286a539f40a 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -368,6 +368,61 @@ bool adreno_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
 	return false;
 }
 
+struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct msm_gpu_state *state;
+	int i, count = 0;
+
+	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return ERR_PTR(-ENOMEM);
+
+	do_gettimeofday(&state->time);
+
+	for (i = 0; i < gpu->nr_rings; i++) {
+		state->ring[i].fence = gpu->rb[i]->memptrs->fence;
+		state->ring[i].iova = gpu->rb[i]->iova;
+		state->ring[i].seqno = gpu->rb[i]->seqno;
+		state->ring[i].rptr = get_rptr(adreno_gpu, gpu->rb[i]);
+		state->ring[i].wptr = get_wptr(gpu->rb[i]);
+	}
+
+	/* Count the number of registers */
+	for (i = 0; adreno_gpu->registers[i] != ~0; i += 2)
+		count += adreno_gpu->registers[i + 1] -
+			adreno_gpu->registers[i] + 1;
+
+	state->registers = kcalloc(count * 2, sizeof(u32), GFP_KERNEL);
+	if (state->registers) {
+		int pos = 0;
+
+		for (i = 0; adreno_gpu->registers[i] != ~0; i += 2) {
+			u32 start = adreno_gpu->registers[i];
+			u32 end   = adreno_gpu->registers[i + 1];
+			u32 addr;
+
+			for (addr = start; addr <= end; addr++) {
+				state->registers[pos++] = addr;
+				state->registers[pos++] = gpu_read(gpu, addr);
+			}
+		}
+
+		state->nr_registers = count;
+	}
+
+	return state;
+}
+
+void adreno_gpu_state_put(struct msm_gpu_state *state)
+{
+	if (IS_ERR_OR_NULL(state))
+		return;
+
+	kfree(state->registers);
+	kfree(state);
+}
+
 #ifdef CONFIG_DEBUG_FS
 void adreno_show(struct msm_gpu *gpu, struct seq_file *m)
 {
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index bc9ec27e9ed8..734e31a9631f 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -229,6 +229,9 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
 void adreno_gpu_cleanup(struct adreno_gpu *gpu);
 
 
+struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu);
+void adreno_gpu_state_put(struct msm_gpu_state *state);
+
 /* ringbuffer helpers (the parts that are adreno specific) */
 
 static inline void
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index b8241179175a..de71cc04ecf3 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -27,6 +27,7 @@
 
 struct msm_gem_submit;
 struct msm_gpu_perfcntr;
+struct msm_gpu_state;
 
 struct msm_gpu_config {
 	const char *ioname;
@@ -69,6 +70,8 @@ struct msm_gpu_funcs {
 	int (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor);
 #endif
 	int (*gpu_busy)(struct msm_gpu *gpu, uint64_t *value);
+	struct msm_gpu_state *(*gpu_state_get)(struct msm_gpu *gpu);
+	void (*gpu_state_put)(struct msm_gpu_state *state);
 };
 
 struct msm_gpu {
@@ -175,6 +178,23 @@ struct msm_gpu_submitqueue {
 	struct kref ref;
 };
 
+struct msm_gpu_state {
+	struct timeval time;
+
+	struct {
+		u64 iova;
+		u32 fence;
+		u32 seqno;
+		u32 rptr;
+		u32 wptr;
+	} ring[MSM_GPU_MAX_RINGS];
+
+	int nr_registers;
+	u32 *registers;
+
+	u32 rbbm_status;
+};
+
 static inline void gpu_write(struct msm_gpu *gpu, u32 reg, u32 data)
 {
 	msm_writel(data, gpu->mmio + (reg << 2));
commit 5dc634bdbfd6dd9bdf98bce0d6f64878e1d47b1f
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Tue Jul 24 10:33:23 2018 -0600

    drm: Add puts callback for the coredump printer
    
    Add a puts function for the coredump printer to bypass printf()
    for constant strings for a speed boost. Reorganize the
    coredump printf callback to share as much code as possible.
    
    v2: Try to reuse code between print and puts as suggested by
        Chris Wilson
    
    Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 45d787611723..0e7fc3e7dfb4 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -30,7 +30,7 @@
 #include <drm/drmP.h>
 #include <drm/drm_print.h>
 
-void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)
+void __drm_puts_coredump(struct drm_printer *p, const char *str)
 {
 	struct drm_print_iterator *iterator = p->arg;
 	ssize_t len;
@@ -38,26 +38,16 @@ void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)
 	if (!iterator->remain)
 		return;
 
-	/* Figure out how big the string will be */
-	len = snprintf(NULL, 0, "%pV", vaf);
-
 	if (iterator->offset < iterator->start) {
-		char *buf;
 		ssize_t copy;
 
+		len = strlen(str);
+
 		if (iterator->offset + len <= iterator->start) {
 			iterator->offset += len;
 			return;
 		}
 
-		/* Print the string into a temporary buffer */
-		buf = kmalloc(len + 1,
-			GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
-		if (!buf)
-			return;
-
-		snprintf(buf, len + 1, "%pV", vaf);
-
 		copy = len - (iterator->start - iterator->offset);
 
 		if (copy > iterator->remain)
@@ -65,42 +55,66 @@ void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)
 
 		/* Copy out the bit of the string that we need */
 		memcpy(iterator->data,
-			buf + (iterator->start - iterator->offset), copy);
+			str + (iterator->start - iterator->offset), copy);
 
 		iterator->offset = iterator->start + copy;
 		iterator->remain -= copy;
-
-		kfree(buf);
 	} else {
-		char *buf;
 		ssize_t pos = iterator->offset - iterator->start;
 
-		if (len < iterator->remain) {
-			snprintf(((char *) iterator->data) + pos,
-				iterator->remain, "%pV", vaf);
+		len = min_t(ssize_t, strlen(str), iterator->remain);
 
-			iterator->offset += len;
-			iterator->remain -= len;
+		memcpy(iterator->data + pos, str, len);
 
-			return;
-		}
+		iterator->offset += len;
+		iterator->remain -= len;
+	}
+}
+EXPORT_SYMBOL(__drm_puts_coredump);
 
-		/* Print the string into a temporary buffer */
-		buf = kmalloc(len + 1,
-			GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
-		if (!buf)
-			return;
+void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)
+{
+	struct drm_print_iterator *iterator = p->arg;
+	size_t len;
+	char *buf;
+
+	if (!iterator->remain)
+		return;
+
+	/* Figure out how big the string will be */
+	len = snprintf(NULL, 0, "%pV", vaf);
+
+	/* This is the easiest path, we've already advanced beyond the offset */
+	if (iterator->offset + len <= iterator->start) {
+		iterator->offset += len;
+		return;
+	}
 
-		snprintf(buf, len + 1, "%pV", vaf);
+	/* Then check if we can directly copy into the target buffer */
+	if ((iterator->offset >= iterator->start) && (len < iterator->remain)) {
+		ssize_t pos = iterator->offset - iterator->start;
 
-		/* Copy out the remaining bits */
-		memcpy(iterator->data + pos, buf, iterator->remain);
+		snprintf(((char *) iterator->data) + pos,
+			iterator->remain, "%pV", vaf);
 
-		iterator->offset += iterator->remain;
-		iterator->remain = 0;
+		iterator->offset += len;
+		iterator->remain -= len;
 
-		kfree(buf);
+		return;
 	}
+
+	/*
+	 * Finally, hit the slow path and make a temporary string to copy over
+	 * using _drm_puts_coredump
+	 */
+	buf = kmalloc(len + 1, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
+	if (!buf)
+		return;
+
+	snprintf(buf, len + 1, "%pV", vaf);
+	__drm_puts_coredump(p, (const char *) buf);
+
+	kfree(buf);
 }
 EXPORT_SYMBOL(__drm_printfn_coredump);
 
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index b1432969b627..f3e6eed3e79c 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -75,6 +75,7 @@ struct drm_printer {
 };
 
 void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf);
+void __drm_puts_coredump(struct drm_printer *p, const char *str);
 void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf);
 void __drm_puts_seq_file(struct drm_printer *p, const char *str);
 void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf);
@@ -163,6 +164,7 @@ drm_coredump_printer(struct drm_print_iterator *iter)
 {
 	struct drm_printer p = {
 		.printfn = __drm_printfn_coredump,
+		.puts = __drm_puts_coredump,
 		.arg = iter,
 	};
 
commit 4538d7324507fed892a18b79ad72c8501b6e7027
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Tue Jul 24 10:33:22 2018 -0600

    drm: Add a -puts() function for the seq_file printer
    
    Add a puts() function to use seq_puts() to help speed up
    up print time for constant strings.
    
    Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
    Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 01d4e5583b5d..45d787611723 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -104,6 +104,12 @@ void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)
 }
 EXPORT_SYMBOL(__drm_printfn_coredump);
 
+void __drm_puts_seq_file(struct drm_printer *p, const char *str)
+{
+	seq_puts(p->arg, str);
+}
+EXPORT_SYMBOL(__drm_puts_seq_file);
+
 void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf)
 {
 	seq_printf(p->arg, "%pV", vaf);
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index f2f42bb87ef2..b1432969b627 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -76,6 +76,7 @@ struct drm_printer {
 
 void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf);
 void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf);
+void __drm_puts_seq_file(struct drm_printer *p, const char *str);
 void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf);
 void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf);
 
@@ -182,6 +183,7 @@ static inline struct drm_printer drm_seq_file_printer(struct seq_file *f)
 {
 	struct drm_printer p = {
 		.printfn = __drm_printfn_seq_file,
+		.puts = __drm_puts_seq_file,
 		.arg = f,
 	};
 	return p;
commit 63f4cc015b66dd265c2fd6e7c94be1b9a3b72267
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Tue Jul 24 10:33:21 2018 -0600

    drm: Add drm_puts() to complement drm_printf()
    
    Add drm_puts() for a much faster path to print constant strings
    into a drm_printer object with memcpy and friends. This can
    have seconds off of really large outputs such as GPU dumps.
    
    If the drm_printer object supports a custom puts function then
    use that otherwise fall back to the slower legacy printf call.
    
    v2: Add documentation for drm_puts() per Daniel Vetter
    
    Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
    Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
    [robclark fix minor htmldocs warning]
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 03d1f98e5ac7..01d4e5583b5d 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -123,6 +123,23 @@ void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf)
 EXPORT_SYMBOL(__drm_printfn_debug);
 
 /**
+ * drm_puts - print a const string to a &drm_printer stream
+ * @p: the &drm printer
+ * @str: const string
+ *
+ * Allow &drm_printer types that have a constant string
+ * option to use it.
+ */
+void drm_puts(struct drm_printer *p, const char *str)
+{
+	if (p->puts)
+		p->puts(p, str);
+	else
+		drm_printf(p, "%s", str);
+}
+EXPORT_SYMBOL(drm_puts);
+
+/**
  * drm_printf - print to a &drm_printer stream
  * @p: the &drm_printer
  * @f: format string
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index e7570f93a21f..f2f42bb87ef2 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -69,6 +69,7 @@
 struct drm_printer {
 	/* private: */
 	void (*printfn)(struct drm_printer *p, struct va_format *vaf);
+	void (*puts)(struct drm_printer *p, const char *str);
 	void *arg;
 	const char *prefix;
 };
@@ -80,6 +81,7 @@ void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf);
 
 __printf(2, 3)
 void drm_printf(struct drm_printer *p, const char *f, ...);
+void drm_puts(struct drm_printer *p, const char *str);
 
 __printf(2, 0)
 /**
commit cfc57a18a3c5dc95d06db80bddd30015162c57d2
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Tue Jul 24 10:33:20 2018 -0600

    drm: drm_printer: Add printer for devcoredump
    
    Add a drm printer suitable for use with the read callback for
    devcoredump or other suitable buffer based output format that
    isn't otherwise covered by seq_file.
    
    v2: Add improved documentation per Daniel Vetter
    
    Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index b25f98f33f6c..03d1f98e5ac7 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -30,6 +30,80 @@
 #include <drm/drmP.h>
 #include <drm/drm_print.h>
 
+void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf)
+{
+	struct drm_print_iterator *iterator = p->arg;
+	ssize_t len;
+
+	if (!iterator->remain)
+		return;
+
+	/* Figure out how big the string will be */
+	len = snprintf(NULL, 0, "%pV", vaf);
+
+	if (iterator->offset < iterator->start) {
+		char *buf;
+		ssize_t copy;
+
+		if (iterator->offset + len <= iterator->start) {
+			iterator->offset += len;
+			return;
+		}
+
+		/* Print the string into a temporary buffer */
+		buf = kmalloc(len + 1,
+			GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
+		if (!buf)
+			return;
+
+		snprintf(buf, len + 1, "%pV", vaf);
+
+		copy = len - (iterator->start - iterator->offset);
+
+		if (copy > iterator->remain)
+			copy = iterator->remain;
+
+		/* Copy out the bit of the string that we need */
+		memcpy(iterator->data,
+			buf + (iterator->start - iterator->offset), copy);
+
+		iterator->offset = iterator->start + copy;
+		iterator->remain -= copy;
+
+		kfree(buf);
+	} else {
+		char *buf;
+		ssize_t pos = iterator->offset - iterator->start;
+
+		if (len < iterator->remain) {
+			snprintf(((char *) iterator->data) + pos,
+				iterator->remain, "%pV", vaf);
+
+			iterator->offset += len;
+			iterator->remain -= len;
+
+			return;
+		}
+
+		/* Print the string into a temporary buffer */
+		buf = kmalloc(len + 1,
+			GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
+		if (!buf)
+			return;
+
+		snprintf(buf, len + 1, "%pV", vaf);
+
+		/* Copy out the remaining bits */
+		memcpy(iterator->data + pos, buf, iterator->remain);
+
+		iterator->offset += iterator->remain;
+		iterator->remain = 0;
+
+		kfree(buf);
+	}
+}
+EXPORT_SYMBOL(__drm_printfn_coredump);
+
 void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf)
 {
 	seq_printf(p->arg, "%pV", vaf);
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 767c90b654c5..e7570f93a21f 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -73,6 +73,7 @@ struct drm_printer {
 	const char *prefix;
 };
 
+void __drm_printfn_coredump(struct drm_printer *p, struct va_format *vaf);
 void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf);
 void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf);
 void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf);
@@ -105,6 +106,70 @@ drm_vprintf(struct drm_printer *p, const char *fmt, va_list *va)
 	drm_printf((printer), "%.*s" fmt, (indent), "\t\t\t\t\tX", ##__VA_ARGS__)
 
 /**
+ * struct drm_print_iterator - local struct used with drm_printer_coredump
+ * @data: Pointer to the devcoredump output buffer
+ * @start: The offset within the buffer to start writing
+ * @remain: The number of bytes to write for this iteration
+ */
+struct drm_print_iterator {
+	void *data;
+	ssize_t start;
+	ssize_t remain;
+	/* private: */
+	ssize_t offset;
+};
+
+/**
+ * drm_coredump_printer - construct a &drm_printer that can output to a buffer
+ * from the read function for devcoredump
+ * @iter: A pointer to a struct drm_print_iterator for the read instance
+ *
+ * This wrapper extends drm_printf() to work with a dev_coredumpm() callback
+ * function. The passed in drm_print_iterator struct contains the buffer
+ * pointer, size and offset as passed in from devcoredump.
+ *
+ * For example::
+ *
+ *	void coredump_read(char *buffer, loff_t offset, size_t count,
+ *		void *data, size_t datalen)
+ *	{
+ *		struct drm_print_iterator iter;
+ *		struct drm_printer p;
+ *
+ *		iter.data = buffer;
+ *		iter.start = offset;
+ *		iter.remain = count;
+ *
+ *		p = drm_coredump_printer(&iter);
+ *
+ *		drm_printf(p, "foo=%d\n", foo);
+ *	}
+ *
+ *	void makecoredump(...)
+ *	{
+ *		...
+ *		dev_coredumpm(dev, THIS_MODULE, data, 0, GFP_KERNEL,
+ *			coredump_read, ...)
+ *	}
+ *
+ * RETURNS:
+ * The &drm_printer object
+ */
+static inline struct drm_printer
+drm_coredump_printer(struct drm_print_iterator *iter)
+{
+	struct drm_printer p = {
+		.printfn = __drm_printfn_coredump,
+		.arg = iter,
+	};
+
+	/* Set the internal offset of the iterator to zero */
+	iter->offset = 0;
+
+	return p;
+}
+
+/**
  * drm_seq_file_printer - construct a &drm_printer that outputs to &seq_file
  * @f:  the &struct seq_file to output to
  *
commit 489cae632fc04927e8ef36ac8d8847193a41df3b
Author: Jordan Crouse <jcrouse at codeaurora.org>
Date:   Tue Jul 24 10:33:19 2018 -0600

    include: Move ascii85 functions from i915 to linux/ascii85.h
    
    The i915 DRM driver very cleverly used ascii85 encoding for their
    GPU state file. Move the encode functions to a general header file to
    support other drivers that might be interested in the same
    functionality.
    
    v4: Make the return value const char * as suggested by Chris Wilson
    v3: Fix error_puts -> err_puts pointed out by the 01.org bot
    v2: Update API to be cleaner for the caller as suggested by Chris Wilson
    
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
    Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
    Signed-off-by: Rob Clark <robdclark at gmail.com>

diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 8c81cf3aa182..f7f2aa71d8d9 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -31,6 +31,7 @@
 #include <linux/stop_machine.h>
 #include <linux/zlib.h>
 #include <drm/drm_print.h>
+#include <linux/ascii85.h>
 
 #include "i915_gpu_error.h"
 #include "i915_drv.h"
@@ -517,35 +518,12 @@ void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...)
 	va_end(args);
 }
 
-static int
-ascii85_encode_len(int len)
-{
-	return DIV_ROUND_UP(len, 4);
-}
-
-static bool
-ascii85_encode(u32 in, char *out)
-{
-	int i;
-
-	if (in == 0)
-		return false;
-
-	out[5] = '\0';
-	for (i = 5; i--; ) {
-		out[i] = '!' + in % 85;
-		in /= 85;
-	}
-
-	return true;
-}
-
 static void print_error_obj(struct drm_i915_error_state_buf *m,
 			    struct intel_engine_cs *engine,
 			    const char *name,
 			    struct drm_i915_error_object *obj)
 {
-	char out[6];
+	char out[ASCII85_BUFSZ];
 	int page;
 
 	if (!obj)
@@ -567,12 +545,8 @@ static void print_error_obj(struct drm_i915_error_state_buf *m,
 			len -= obj->unused;
 		len = ascii85_encode_len(len);
 
-		for (i = 0; i < len; i++) {
-			if (ascii85_encode(obj->pages[page][i], out))
-				err_puts(m, out);
-			else
-				err_puts(m, "z");
-		}
+		for (i = 0; i < len; i++)
+			err_puts(m, ascii85_encode(obj->pages[page][i], out));
 	}
 	err_puts(m, "\n");
 }
diff --git a/include/linux/ascii85.h b/include/linux/ascii85.h
new file mode 100644
index 000000000000..4cc40201273e
--- /dev/null
+++ b/include/linux/ascii85.h
@@ -0,0 +1,38 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2008 Intel Corporation
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _ASCII85_H_
+#define _ASCII85_H_
+
+#include <linux/kernel.h>
+
+#define ASCII85_BUFSZ 6
+
+static inline long
+ascii85_encode_len(long len)
+{
+	return DIV_ROUND_UP(len, 4);
+}
+
+static inline const char *
+ascii85_encode(u32 in, char *out)
+{
+	int i;
+
+	if (in == 0)
+		return "z";
+
+	out[5] = '\0';
+	for (i = 5; i--; ) {
+		out[i] = '!' + in % 85;
+		in /= 85;
+	}
+
+	return out;
+}
+
+#endif
commit aa595c00bcf5b6f2f394a98217f82c9402952ea9
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:53:06 2018 +0100

    drm/armada: remove obsolete fb unreferencing kfifo and workqueue
    
    Remove the obsolete fb unreferencing system that is no longer used
    since we've transitioned to atomic modeset.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h
index 9658be917ea1..f09083ff15d3 100644
--- a/drivers/gpu/drm/armada/armada_drm.h
+++ b/drivers/gpu/drm/armada/armada_drm.h
@@ -55,8 +55,6 @@ extern const struct armada_variant armada510_ops;
 
 struct armada_private {
 	struct drm_device	drm;
-	struct work_struct	fb_unref_work;
-	DECLARE_KFIFO(fb_unref, struct drm_framebuffer *, 8);
 	struct drm_fb_helper	*fbdev;
 	struct armada_crtc	*dcrtc[2];
 	struct drm_mm		linear; /* protected by linear_lock */
@@ -75,11 +73,6 @@ struct armada_private {
 #endif
 };
 
-void __armada_drm_queue_unref_work(struct drm_device *,
-	struct drm_framebuffer *);
-void armada_drm_queue_unref_work(struct drm_device *,
-	struct drm_framebuffer *);
-
 int armada_fbdev_init(struct drm_device *);
 void armada_fbdev_fini(struct drm_device *);
 
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 20661bd9001e..fa31589b4fc0 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -21,36 +21,6 @@
 #include <drm/armada_drm.h>
 #include "armada_ioctlP.h"
 
-static void armada_drm_unref_work(struct work_struct *work)
-{
-	struct armada_private *priv =
-		container_of(work, struct armada_private, fb_unref_work);
-	struct drm_framebuffer *fb;
-
-	while (kfifo_get(&priv->fb_unref, &fb))
-		drm_framebuffer_put(fb);
-}
-
-/* Must be called with dev->event_lock held */
-void __armada_drm_queue_unref_work(struct drm_device *dev,
-	struct drm_framebuffer *fb)
-{
-	struct armada_private *priv = dev->dev_private;
-
-	WARN_ON(!kfifo_put(&priv->fb_unref, fb));
-	schedule_work(&priv->fb_unref_work);
-}
-
-void armada_drm_queue_unref_work(struct drm_device *dev,
-	struct drm_framebuffer *fb)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&dev->event_lock, flags);
-	__armada_drm_queue_unref_work(dev, fb);
-	spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
 static struct drm_ioctl_desc armada_ioctls[] = {
 	DRM_IOCTL_DEF_DRV(ARMADA_GEM_CREATE, armada_gem_create_ioctl,0),
 	DRM_IOCTL_DEF_DRV(ARMADA_GEM_MMAP, armada_gem_mmap_ioctl, 0),
@@ -134,9 +104,6 @@ static int armada_drm_bind(struct device *dev)
 
 	dev_set_drvdata(dev, &priv->drm);
 
-	INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work);
-	INIT_KFIFO(priv->fb_unref);
-
 	/* Mode setting support */
 	drm_mode_config_init(&priv->drm);
 	priv->drm.mode_config.min_width = 320;
@@ -190,7 +157,6 @@ static int armada_drm_bind(struct device *dev)
  err_kms:
 	drm_mode_config_cleanup(&priv->drm);
 	drm_mm_takedown(&priv->linear);
-	flush_work(&priv->fb_unref_work);
 	drm_dev_put(&priv->drm);
 	return ret;
 }
@@ -209,7 +175,6 @@ static void armada_drm_unbind(struct device *dev)
 
 	drm_mode_config_cleanup(&priv->drm);
 	drm_mm_takedown(&priv->linear);
-	flush_work(&priv->fb_unref_work);
 
 	drm_dev_put(&priv->drm);
 }
commit 82c702cb0c041a9a1c69f489d1517235a633fc77
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:53:06 2018 +0100

    drm/armada: remove unnecessary armada_plane structure
    
    We no longer require a private armada_plane structure, so eliminate
    it, and use the drm_plane structure directly.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index bb1e13b4516b..da9360688b55 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -723,7 +723,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 {
 	struct armada_private *priv = drm->dev_private;
 	struct armada_crtc *dcrtc;
-	struct armada_plane *primary;
+	struct drm_plane *primary;
 	void __iomem *base;
 	int ret;
 
@@ -793,7 +793,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 		goto err_crtc;
 	}
 
-	ret = drm_crtc_init_with_planes(drm, &dcrtc->crtc, &primary->base, NULL,
+	ret = drm_crtc_init_with_planes(drm, &dcrtc->crtc, primary, NULL,
 					&armada_crtc_funcs, NULL);
 	if (ret)
 		goto err_crtc_init;
@@ -803,7 +803,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 	return armada_overlay_plane_create(drm, 1 << dcrtc->num);
 
 err_crtc_init:
-	primary->base.funcs->destroy(&primary->base);
+	primary->funcs->destroy(primary);
 err_crtc:
 	kfree(dcrtc);
 
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index b95ea13d0705..7ebd337b60af 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -32,15 +32,8 @@ struct armada_regs {
 	armada_reg_queue_mod(_r, _i, 0, 0, ~0)
 
 struct armada_crtc;
-struct armada_plane;
 struct armada_variant;
 
-struct armada_plane {
-	struct drm_plane	base;
-	wait_queue_head_t	frame_wait;
-};
-#define drm_to_armada_plane(p) container_of(p, struct armada_plane, base)
-
 struct armada_crtc {
 	struct drm_crtc		crtc;
 	const struct armada_variant *variant;
diff --git a/drivers/gpu/drm/armada/armada_plane.c b/drivers/gpu/drm/armada/armada_plane.c
index bed2dca83a37..9f36423dd394 100644
--- a/drivers/gpu/drm/armada/armada_plane.c
+++ b/drivers/gpu/drm/armada/armada_plane.c
@@ -271,25 +271,14 @@ static const struct drm_plane_funcs armada_primary_plane_funcs = {
 	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 };
 
-int armada_drm_plane_init(struct armada_plane *plane)
-{
-	init_waitqueue_head(&plane->frame_wait);
-	return 0;
-}
-
 int armada_drm_primary_plane_init(struct drm_device *drm,
-	struct armada_plane *primary)
+	struct drm_plane *primary)
 {
 	int ret;
 
-	ret = armada_drm_plane_init(primary);
-	if (ret)
-		return ret;
-
-	drm_plane_helper_add(&primary->base,
-			     &armada_primary_plane_helper_funcs);
+	drm_plane_helper_add(primary, &armada_primary_plane_helper_funcs);
 
-	ret = drm_universal_plane_init(drm, &primary->base, 0,
+	ret = drm_universal_plane_init(drm, primary, 0,
 				       &armada_primary_plane_funcs,
 				       armada_primary_formats,
 				       ARRAY_SIZE(armada_primary_formats),
diff --git a/drivers/gpu/drm/armada/armada_plane.h b/drivers/gpu/drm/armada/armada_plane.h
index 1bd8430992e0..ff4281ba7fad 100644
--- a/drivers/gpu/drm/armada/armada_plane.h
+++ b/drivers/gpu/drm/armada/armada_plane.h
@@ -9,8 +9,7 @@ void armada_drm_plane_cleanup_fb(struct drm_plane *plane,
 	struct drm_plane_state *old_state);
 int armada_drm_plane_atomic_check(struct drm_plane *plane,
 	struct drm_plane_state *state);
-int armada_drm_plane_init(struct armada_plane *plane);
 int armada_drm_primary_plane_init(struct drm_device *drm,
-	struct armada_plane *primary);
+	struct drm_plane *primary);
 
 #endif
commit d701278ada5115c40cd4d58ce0fb1169479c0bf6
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:53:06 2018 +0100

    drm/armada: remove unnecessary armada_ovl_plane structure
    
    We no longer need a private plane structure, so get rid of it.  Use the
    drm_plane structure directly.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index ec2043b6f61f..eb7dfb65ef47 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -25,12 +25,6 @@
 #define DEFAULT_SATURATION	0x4000
 #define DEFAULT_ENCODING	DRM_COLOR_YCBCR_BT601
 
-struct armada_ovl_plane {
-	struct armada_plane base;
-};
-#define drm_to_armada_ovl_plane(p) \
-	container_of(p, struct armada_ovl_plane, base.base)
-
 struct armada_overlay_state {
 	struct drm_plane_state base;
 	u32 colorkey_yr;
@@ -301,11 +295,8 @@ fail:
 
 static void armada_ovl_plane_destroy(struct drm_plane *plane)
 {
-	struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
-
 	drm_plane_cleanup(plane);
-
-	kfree(dplane);
+	kfree(plane);
 }
 
 static void armada_overlay_reset(struct drm_plane *plane)
@@ -550,38 +541,31 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 {
 	struct armada_private *priv = dev->dev_private;
 	struct drm_mode_object *mobj;
-	struct armada_ovl_plane *dplane;
+	struct drm_plane *overlay;
 	int ret;
 
 	ret = armada_overlay_create_properties(dev);
 	if (ret)
 		return ret;
 
-	dplane = kzalloc(sizeof(*dplane), GFP_KERNEL);
-	if (!dplane)
+	overlay = kzalloc(sizeof(*overlay), GFP_KERNEL);
+	if (!overlay)
 		return -ENOMEM;
 
-	ret = armada_drm_plane_init(&dplane->base);
-	if (ret) {
-		kfree(dplane);
-		return ret;
-	}
-
-	drm_plane_helper_add(&dplane->base.base,
-			     &armada_overlay_plane_helper_funcs);
+	drm_plane_helper_add(overlay, &armada_overlay_plane_helper_funcs);
 
-	ret = drm_universal_plane_init(dev, &dplane->base.base, crtcs,
+	ret = drm_universal_plane_init(dev, overlay, crtcs,
 				       &armada_ovl_plane_funcs,
 				       armada_ovl_formats,
 				       ARRAY_SIZE(armada_ovl_formats),
 				       NULL,
 				       DRM_PLANE_TYPE_OVERLAY, NULL);
 	if (ret) {
-		kfree(dplane);
+		kfree(overlay);
 		return ret;
 	}
 
-	mobj = &dplane->base.base.base;
+	mobj = &overlay->base;
 	drm_object_attach_property(mobj, priv->colorkey_prop,
 				   0x0101fe);
 	drm_object_attach_property(mobj, priv->colorkey_min_prop,
@@ -601,7 +585,7 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 	drm_object_attach_property(mobj, priv->saturation_prop,
 				   DEFAULT_SATURATION);
 
-	ret = drm_plane_create_color_properties(&dplane->base.base,
+	ret = drm_plane_create_color_properties(overlay,
 						BIT(DRM_COLOR_YCBCR_BT601) |
 						BIT(DRM_COLOR_YCBCR_BT709),
 						BIT(DRM_COLOR_YCBCR_LIMITED_RANGE),
commit dae2155bb07bb2063ce604049e9aa4e862b6db0a
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:53:06 2018 +0100

    drm/armada: update primary framebuffer parameters on mode change
    
    The framebuffer base address and toggling mode needs to be updated
    when the interlaced flag for mode changes is updated.  Arrange to
    reprogram these parameters when only the mode has changed.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_plane.c b/drivers/gpu/drm/armada/armada_plane.c
index 39c9ba3ee57e..bed2dca83a37 100644
--- a/drivers/gpu/drm/armada/armada_plane.c
+++ b/drivers/gpu/drm/armada/armada_plane.c
@@ -184,11 +184,13 @@ static void armada_drm_primary_plane_atomic_update(struct drm_plane *plane,
 		armada_reg_queue_set(regs, idx, val, LCD_SPU_GZM_HPXL_VLN);
 	if (old_state->src.x1 != state->src.x1 ||
 	    old_state->src.y1 != state->src.y1 ||
-	    old_state->fb != state->fb) {
+	    old_state->fb != state->fb ||
+	    state->crtc->state->mode_changed) {
 		idx += armada_drm_crtc_calc_fb(state, regs + idx,
 					       dcrtc->interlaced);
 	}
-	if (old_state->fb != state->fb) {
+	if (old_state->fb != state->fb ||
+	    state->crtc->state->mode_changed) {
 		cfg = CFG_GRA_FMT(drm_fb_to_armada_fb(state->fb)->fmt) |
 		      CFG_GRA_MOD(drm_fb_to_armada_fb(state->fb)->mod);
 		if (drm_fb_to_armada_fb(state->fb)->fmt > CFG_420)
commit 3cb13ac97bdfda5b301609256e3e0b59bc94f10a
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:53:06 2018 +0100

    drm/armada: update planes after the dumb frame is complete
    
    Write out the plane updates after the dumb frame has completed, but
    just before the blank period.  This allows all the plane updates to
    be performed in a flicker-free non-tearing manner.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index ebcb99316c94..bb1e13b4516b 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -197,21 +197,27 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 		writel_relaxed(val, base + LCD_SPU_ADV_REG);
 	}
 
-	if (stat & DUMB_FRAMEDONE && dcrtc->cursor_update) {
-		writel_relaxed(dcrtc->cursor_hw_pos,
-			       base + LCD_SPU_HWC_OVSA_HPXL_VLN);
-		writel_relaxed(dcrtc->cursor_hw_sz,
-			       base + LCD_SPU_HWC_HPXL_VLN);
-		armada_updatel(CFG_HWC_ENA,
-			       CFG_HWC_ENA | CFG_HWC_1BITMOD | CFG_HWC_1BITENA,
-			       base + LCD_SPU_DMA_CTRL0);
-		dcrtc->cursor_update = false;
+	if (stat & dcrtc->irq_ena & DUMB_FRAMEDONE) {
+		if (dcrtc->update_pending) {
+			armada_drm_crtc_update_regs(dcrtc, dcrtc->regs);
+			dcrtc->update_pending = false;
+		}
+		if (dcrtc->cursor_update) {
+			writel_relaxed(dcrtc->cursor_hw_pos,
+				       base + LCD_SPU_HWC_OVSA_HPXL_VLN);
+			writel_relaxed(dcrtc->cursor_hw_sz,
+				       base + LCD_SPU_HWC_HPXL_VLN);
+			armada_updatel(CFG_HWC_ENA,
+				       CFG_HWC_ENA | CFG_HWC_1BITMOD |
+				       CFG_HWC_1BITENA,
+				       base + LCD_SPU_DMA_CTRL0);
+			dcrtc->cursor_update = false;
+		}
 		armada_drm_crtc_disable_irq(dcrtc, DUMB_FRAMEDONE_ENA);
 	}
-
 	spin_unlock(&dcrtc->irq_lock);
 
-	if (stat & VSYNC_IRQ) {
+	if (stat & VSYNC_IRQ && !dcrtc->update_pending) {
 		event = xchg(&dcrtc->event, NULL);
 		if (event) {
 			spin_lock(&dcrtc->crtc.dev->event_lock);
@@ -360,22 +366,26 @@ static void armada_drm_crtc_atomic_flush(struct drm_crtc *crtc,
 					 struct drm_crtc_state *old_crtc_state)
 {
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
-	unsigned long flags;
 
 	DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
 
 	armada_reg_queue_end(dcrtc->regs, dcrtc->regs_idx);
 
-	spin_lock_irqsave(&dcrtc->irq_lock, flags);
-	armada_drm_crtc_update_regs(dcrtc, dcrtc->regs);
-	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
-
 	/*
 	 * If we aren't doing a full modeset, then we need to queue
 	 * the event here.
 	 */
-	if (!drm_atomic_crtc_needs_modeset(crtc->state))
+	if (!drm_atomic_crtc_needs_modeset(crtc->state)) {
+		dcrtc->update_pending = true;
 		armada_drm_crtc_queue_state_event(crtc);
+		spin_lock_irq(&dcrtc->irq_lock);
+		armada_drm_crtc_enable_irq(dcrtc, DUMB_FRAMEDONE_ENA);
+		spin_unlock_irq(&dcrtc->irq_lock);
+	} else {
+		spin_lock_irq(&dcrtc->irq_lock);
+		armada_drm_crtc_update_regs(dcrtc, dcrtc->regs);
+		spin_unlock_irq(&dcrtc->irq_lock);
+	}
 }
 
 static void armada_drm_crtc_atomic_disable(struct drm_crtc *crtc,
@@ -532,7 +542,6 @@ static int armada_drm_crtc_cursor_update(struct armada_crtc *dcrtc, bool reload)
 
 	if (!dcrtc->cursor_obj || !h || !w) {
 		spin_lock_irq(&dcrtc->irq_lock);
-		armada_drm_crtc_disable_irq(dcrtc, DUMB_FRAMEDONE_ENA);
 		dcrtc->cursor_update = false;
 		armada_updatel(0, CFG_HWC_ENA, dcrtc->base + LCD_SPU_DMA_CTRL0);
 		spin_unlock_irq(&dcrtc->irq_lock);
@@ -556,7 +565,6 @@ static int armada_drm_crtc_cursor_update(struct armada_crtc *dcrtc, bool reload)
 
 	if (dcrtc->cursor_hw_sz != (h << 16 | w)) {
 		spin_lock_irq(&dcrtc->irq_lock);
-		armada_drm_crtc_disable_irq(dcrtc, DUMB_FRAMEDONE_ENA);
 		dcrtc->cursor_update = false;
 		armada_updatel(0, CFG_HWC_ENA, dcrtc->base + LCD_SPU_DMA_CTRL0);
 		spin_unlock_irq(&dcrtc->irq_lock);
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 5b607d45f469..b95ea13d0705 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -70,6 +70,7 @@ struct armada_crtc {
 	spinlock_t		irq_lock;
 	uint32_t		irq_ena;
 
+	bool			update_pending;
 	struct drm_pending_vblank_event *event;
 	struct armada_regs	atomic_regs[32];
 	struct armada_regs	*regs;
commit b1ec9ed6aa985be432f9ba29696029dc6779258e
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:53:06 2018 +0100

    drm/armada: switch overlay plane to atomic modeset
    
    Switch the overlay plane away from the transitional helpers and legacy
    methods, and use atomic helpers instead to implement the legacy
    set_plane ioctl methods.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index a25094bbeb2c..ebcb99316c94 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -117,80 +117,6 @@ static void armada_drm_crtc_update(struct armada_crtc *dcrtc, bool enable)
 		       dcrtc->base + LCD_SPU_DUMB_CTRL);
 }
 
-static void armada_drm_plane_work_call(struct armada_crtc *dcrtc,
-	struct armada_plane_work *work,
-	void (*fn)(struct armada_crtc *, struct armada_plane_work *))
-{
-	struct armada_plane *dplane = drm_to_armada_plane(work->plane);
-	struct drm_pending_vblank_event *event;
-	struct drm_framebuffer *fb;
-
-	if (fn)
-		fn(dcrtc, work);
-	drm_crtc_vblank_put(&dcrtc->crtc);
-
-	event = work->event;
-	fb = work->old_fb;
-	if (event || fb) {
-		struct drm_device *dev = dcrtc->crtc.dev;
-		unsigned long flags;
-
-		spin_lock_irqsave(&dev->event_lock, flags);
-		if (event)
-			drm_crtc_send_vblank_event(&dcrtc->crtc, event);
-		if (fb)
-			__armada_drm_queue_unref_work(dev, fb);
-		spin_unlock_irqrestore(&dev->event_lock, flags);
-	}
-
-	if (work->need_kfree)
-		kfree(work);
-
-	wake_up(&dplane->frame_wait);
-}
-
-static void armada_drm_plane_work_run(struct armada_crtc *dcrtc,
-	struct drm_plane *plane)
-{
-	struct armada_plane *dplane = drm_to_armada_plane(plane);
-	struct armada_plane_work *work = xchg(&dplane->work, NULL);
-
-	/* Handle any pending frame work. */
-	if (work)
-		armada_drm_plane_work_call(dcrtc, work, work->fn);
-}
-
-int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
-	struct armada_plane_work *work)
-{
-	struct armada_plane *plane = drm_to_armada_plane(work->plane);
-	int ret;
-
-	ret = drm_crtc_vblank_get(&dcrtc->crtc);
-	if (ret)
-		return ret;
-
-	ret = cmpxchg(&plane->work, NULL, work) ? -EBUSY : 0;
-	if (ret)
-		drm_crtc_vblank_put(&dcrtc->crtc);
-
-	return ret;
-}
-
-int armada_drm_plane_work_wait(struct armada_plane *plane, long timeout)
-{
-	return wait_event_timeout(plane->frame_wait, !plane->work, timeout);
-}
-
-void armada_drm_plane_work_cancel(struct armada_crtc *dcrtc,
-	struct armada_plane *dplane)
-{
-	struct armada_plane_work *work = xchg(&dplane->work, NULL);
-
-	if (work)
-		armada_drm_plane_work_call(dcrtc, work, work->cancel);
-}
-
 static void armada_drm_crtc_queue_state_event(struct drm_crtc *crtc)
 {
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
@@ -247,7 +173,6 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 {
 	struct drm_pending_vblank_event *event;
 	void __iomem *base = dcrtc->base;
-	struct drm_plane *ovl_plane;
 
 	if (stat & DMA_FF_UNDERFLOW)
 		DRM_ERROR("video underflow on crtc %u\n", dcrtc->num);
@@ -257,10 +182,6 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 	if (stat & VSYNC_IRQ)
 		drm_crtc_handle_vblank(&dcrtc->crtc);
 
-	ovl_plane = dcrtc->plane;
-	if (ovl_plane)
-		armada_drm_plane_work_run(dcrtc, ovl_plane);
-
 	spin_lock(&dcrtc->irq_lock);
 	if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) {
 		int i = stat & GRA_FRAME_IRQ0 ? 0 : 1;
@@ -462,19 +383,9 @@ static void armada_drm_crtc_atomic_disable(struct drm_crtc *crtc,
 {
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
 	struct drm_pending_vblank_event *event;
-	struct drm_plane *plane;
 
 	DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
 
-	/*
-	 * For transition only - we must wait for completion of our
-	 * untransitioned paths before changing anything.
-	 */
-	plane = dcrtc->plane;
-	if (plane)
-		WARN_ON(!armada_drm_plane_work_wait(drm_to_armada_plane(plane),
-						    HZ));
-
 	drm_crtc_vblank_off(crtc);
 	armada_drm_crtc_update(dcrtc, false);
 
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index afc9266bc1e2..5b607d45f469 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -35,29 +35,12 @@ struct armada_crtc;
 struct armada_plane;
 struct armada_variant;
 
-struct armada_plane_work {
-	void (*fn)(struct armada_crtc *, struct armada_plane_work *);
-	void (*cancel)(struct armada_crtc *, struct armada_plane_work *);
-	bool need_kfree;
-	struct drm_plane *plane;
-	struct drm_framebuffer *old_fb;
-	struct drm_pending_vblank_event *event;
-	struct armada_regs regs[24];
-};
-
 struct armada_plane {
 	struct drm_plane	base;
 	wait_queue_head_t	frame_wait;
-	struct armada_plane_work *work;
 };
 #define drm_to_armada_plane(p) container_of(p, struct armada_plane, base)
 
-int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
-	struct armada_plane_work *work);
-int armada_drm_plane_work_wait(struct armada_plane *plane, long timeout);
-void armada_drm_plane_work_cancel(struct armada_crtc *dcrtc,
-	struct armada_plane *plane);
-
 struct armada_crtc {
 	struct drm_crtc		crtc;
 	const struct armada_variant *variant;
@@ -73,8 +56,6 @@ struct armada_crtc {
 	bool			interlaced;
 	bool			cursor_update;
 
-	struct drm_plane	*plane;
-
 	struct armada_gem_object	*cursor_obj;
 	int			cursor_x;
 	int			cursor_y;
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 7de8b6bd7847..ec2043b6f61f 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -27,9 +27,6 @@
 
 struct armada_ovl_plane {
 	struct armada_plane base;
-	struct armada_plane_work works[2];
-	bool next_work;
-	bool wait_vblank;
 };
 #define drm_to_armada_ovl_plane(p) \
 	container_of(p, struct armada_ovl_plane, base.base)
@@ -74,18 +71,6 @@ static inline u32 armada_csc(struct drm_plane_state *state)
 }
 
 /* === Plane support === */
-static void armada_ovl_plane_work(struct armada_crtc *dcrtc,
-	struct armada_plane_work *work)
-{
-	unsigned long flags;
-
-	trace_armada_ovl_plane_work(&dcrtc->crtc, work->plane);
-
-	spin_lock_irqsave(&dcrtc->irq_lock, flags);
-	armada_drm_crtc_update_regs(dcrtc, work->regs);
-	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
-}
-
 static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
 	struct drm_plane_state *old_state)
 {
@@ -109,8 +94,6 @@ static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
 	dcrtc = drm_to_armada_crtc(state->crtc);
 	regs = dcrtc->regs + dcrtc->regs_idx;
 
-	drm_to_armada_ovl_plane(plane)->wait_vblank = false;
-
 	idx = 0;
 	if (!old_state->visible && state->visible)
 		armada_reg_queue_mod(regs, idx,
@@ -173,8 +156,6 @@ static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
 				       CFG_SWAPYU | CFG_YUV2RGB) |
 			   CFG_DMA_FTOGGLE | CFG_DMA_TSTMODE |
 			   CFG_DMA_ENA;
-
-		drm_to_armada_ovl_plane(plane)->wait_vblank = true;
 	} else if (old_state->visible != state->visible) {
 		cfg = state->visible ? CFG_DMA_ENA : 0;
 		cfg_mask = CFG_DMA_ENA;
@@ -262,9 +243,6 @@ static void armada_drm_overlay_plane_atomic_disable(struct drm_plane *plane,
 			     LCD_SPU_SRAM_PARA1);
 
 	dcrtc->regs_idx += idx;
-
-	if (dcrtc->plane == plane)
-		dcrtc->plane = NULL;
 }
 
 static const struct drm_plane_helper_funcs armada_overlay_plane_helper_funcs = {
@@ -275,108 +253,50 @@ static const struct drm_plane_helper_funcs armada_overlay_plane_helper_funcs = {
 	.atomic_disable	= armada_drm_overlay_plane_atomic_disable,
 };
 
-static int armada_overlay_commit(struct drm_plane *plane,
-	struct drm_plane_state *state)
-{
-	struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
-	const struct drm_plane_helper_funcs *plane_funcs;
-	struct armada_crtc *dcrtc = drm_to_armada_crtc(state->crtc);
-	struct armada_plane_work *work;
-	int ret;
-
-	plane_funcs = plane->helper_private;
-	ret = plane_funcs->atomic_check(plane, state);
-	if (ret)
-		goto put_state;
-
-	work = &dplane->works[dplane->next_work];
-
-	if (plane->state->fb != state->fb) {
-		/*
-		 * Take a reference on the new framebuffer - we want to
-		 * hold on to it while the hardware is displaying it.
-		 */
-		drm_framebuffer_reference(state->fb);
-
-		work->old_fb = plane->state->fb;
-	} else {
-		work->old_fb = NULL;
-	}
-
-	/* Point of no return */
-	swap(plane->state, state);
-
-	/* No CRTC, can't update */
-	if (!plane->state->crtc)
-		goto put_state;
-
-	dcrtc->regs_idx = 0;
-	dcrtc->regs = work->regs;
-
-	plane_funcs->atomic_update(plane, state);
-
-	/* If nothing was updated, short-circuit */
-	if (dcrtc->regs_idx == 0)
-		goto put_state;
-
-	armada_reg_queue_end(dcrtc->regs, dcrtc->regs_idx);
-
-	/* Wait for pending work to complete */
-	if (armada_drm_plane_work_wait(&dplane->base, HZ / 25) == 0)
-		armada_drm_plane_work_cancel(dcrtc, &dplane->base);
-
-	/* Just updating the position/size? */
-	if (!dplane->wait_vblank) {
-		armada_ovl_plane_work(dcrtc, work);
-		goto put_state;
-	}
-
-	dcrtc->plane = plane;
-
-	/* Queue it for update on the next interrupt if we are enabled */
-	ret = armada_drm_plane_work_queue(dcrtc, work);
-	if (ret) {
-		DRM_ERROR("failed to queue plane work: %d\n", ret);
-		ret = 0;
-	}
-
-	dplane->next_work = !dplane->next_work;
-
-put_state:
-	plane->funcs->atomic_destroy_state(plane, state);
-	return ret;
-}
-
 static int
-armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
+armada_overlay_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
 	struct drm_framebuffer *fb,
 	int crtc_x, int crtc_y, unsigned crtc_w, unsigned crtc_h,
 	uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h,
 	struct drm_modeset_acquire_ctx *ctx)
 {
-	struct drm_plane_state *state;
+	struct drm_atomic_state *state;
+	struct drm_plane_state *plane_state;
+	int ret = 0;
 
 	trace_armada_ovl_plane_update(plane, crtc, fb,
 				 crtc_x, crtc_y, crtc_w, crtc_h,
 				 src_x, src_y, src_w, src_h);
 
-	/* Construct new state for the overlay plane */
-	state = plane->funcs->atomic_duplicate_state(plane);
+	state = drm_atomic_state_alloc(plane->dev);
 	if (!state)
 		return -ENOMEM;
 
-	state->crtc = crtc;
-	drm_atomic_set_fb_for_plane(state, fb);
-	state->crtc_x = crtc_x;
-	state->crtc_y = crtc_y;
-	state->crtc_h = crtc_h;
-	state->crtc_w = crtc_w;
-	state->src_x = src_x;
-	state->src_y = src_y;
-	state->src_h = src_h;
-	state->src_w = src_w;
-
-	return armada_overlay_commit(plane, state);
+	state->acquire_ctx = ctx;
+	plane_state = drm_atomic_get_plane_state(state, plane);
+	if (IS_ERR(plane_state)) {
+		ret = PTR_ERR(plane_state);
+		goto fail;
+	}
+
+	ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
+	if (ret != 0)
+		goto fail;
+
+	drm_atomic_set_fb_for_plane(plane_state, fb);
+	plane_state->crtc_x = crtc_x;
+	plane_state->crtc_y = crtc_y;
+	plane_state->crtc_h = crtc_h;
+	plane_state->crtc_w = crtc_w;
+	plane_state->src_x = src_x;
+	plane_state->src_y = src_y;
+	plane_state->src_h = src_h;
+	plane_state->src_w = src_w;
+
+	ret = drm_atomic_nonblocking_commit(state);
+fail:
+	drm_atomic_state_put(state);
+	return ret;
 }
 
 static void armada_ovl_plane_destroy(struct drm_plane *plane)
@@ -388,25 +308,6 @@ static void armada_ovl_plane_destroy(struct drm_plane *plane)
 	kfree(dplane);
 }
 
-static int armada_ovl_plane_set_property(struct drm_plane *plane,
-	struct drm_property *property, uint64_t val)
-{
-	struct drm_plane_state *state;
-	int ret;
-
-	state = plane->funcs->atomic_duplicate_state(plane);
-	if (!state)
-		return -ENOMEM;
-
-	ret = plane->funcs->atomic_set_property(plane, state, property, val);
-	if (ret) {
-		plane->funcs->atomic_destroy_state(plane, state);
-		return ret;
-	}
-
-	return armada_overlay_commit(plane, state);
-}
-
 static void armada_overlay_reset(struct drm_plane *plane)
 {
 	struct armada_overlay_state *state;
@@ -510,9 +411,6 @@ static int armada_overlay_set_property(struct drm_plane *plane,
 		drm_to_overlay_state(state)->contrast = val;
 	} else if (property == priv->saturation_prop) {
 		drm_to_overlay_state(state)->saturation = val;
-	} else if (property == plane->color_encoding_property) {
-		/* transitional only */
-		state->color_encoding = val;
 	} else {
 		return -EINVAL;
 	}
@@ -572,10 +470,9 @@ static int armada_overlay_get_property(struct drm_plane *plane,
 }
 
 static const struct drm_plane_funcs armada_ovl_plane_funcs = {
-	.update_plane	= armada_ovl_plane_update,
-	.disable_plane	= drm_plane_helper_disable,
+	.update_plane	= armada_overlay_plane_update,
+	.disable_plane	= drm_atomic_helper_disable_plane,
 	.destroy	= armada_ovl_plane_destroy,
-	.set_property	= armada_ovl_plane_set_property,
 	.reset		= armada_overlay_reset,
 	.atomic_duplicate_state = armada_overlay_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -670,11 +567,6 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 		return ret;
 	}
 
-	dplane->works[0].plane = &dplane->base.base;
-	dplane->works[0].fn = armada_ovl_plane_work;
-	dplane->works[1].plane = &dplane->base.base;
-	dplane->works[1].fn = armada_ovl_plane_work;
-
 	drm_plane_helper_add(&dplane->base.base,
 			     &armada_overlay_plane_helper_funcs);
 
commit 13c94d5349c9c0756131e7bf2e703ab36ea55c73
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:53:06 2018 +0100

    drm/armada: switch primary plane to atomic modeset
    
    Switch the primary plane away from the transitional helpers, and
    use the atomic helpers instead to implement the legacy set_plane
    ioctl call for this plane.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 0cef40ad3a06..a25094bbeb2c 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -191,34 +191,6 @@ void armada_drm_plane_work_cancel(struct armada_crtc *dcrtc,
 		armada_drm_plane_work_call(dcrtc, work, work->cancel);
 }
 
-static void armada_drm_crtc_complete_frame_work(struct armada_crtc *dcrtc,
-	struct armada_plane_work *work)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&dcrtc->irq_lock, flags);
-	armada_drm_crtc_update_regs(dcrtc, work->regs);
-	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
-}
-
-static struct armada_plane_work *
-armada_drm_crtc_alloc_plane_work(struct drm_plane *plane)
-{
-	struct armada_plane_work *work;
-	int i = 0;
-
-	work = kzalloc(sizeof(*work), GFP_KERNEL);
-	if (!work)
-		return NULL;
-
-	work->plane = plane;
-	work->fn = armada_drm_crtc_complete_frame_work;
-	work->need_kfree = true;
-	armada_reg_queue_end(work->regs, i);
-
-	return work;
-}
-
 static void armada_drm_crtc_queue_state_event(struct drm_crtc *crtc)
 {
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
@@ -318,9 +290,6 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 
 	spin_unlock(&dcrtc->irq_lock);
 
-	if (stat & GRA_FRAME_IRQ)
-		armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary);
-
 	if (stat & VSYNC_IRQ) {
 		event = xchg(&dcrtc->event, NULL);
 		if (event) {
@@ -459,15 +428,9 @@ static void armada_drm_crtc_atomic_begin(struct drm_crtc *crtc,
 					 struct drm_crtc_state *old_crtc_state)
 {
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
-	struct armada_plane *dplane;
 
 	DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
 
-	/* Wait 100ms for any plane works to complete */
-	dplane = drm_to_armada_plane(crtc->primary);
-	if (WARN_ON(armada_drm_plane_work_wait(dplane, HZ / 10) == 0))
-		armada_drm_plane_work_cancel(dcrtc, dplane);
-
 	dcrtc->regs_idx = 0;
 	dcrtc->regs = dcrtc->atomic_regs;
 }
@@ -511,8 +474,6 @@ static void armada_drm_crtc_atomic_disable(struct drm_crtc *crtc,
 	if (plane)
 		WARN_ON(!armada_drm_plane_work_wait(drm_to_armada_plane(plane),
 						    HZ));
-	armada_drm_plane_work_wait(drm_to_armada_plane(dcrtc->crtc.primary),
-				   MAX_SCHEDULE_TIMEOUT);
 
 	drm_crtc_vblank_off(crtc);
 	armada_drm_crtc_update(dcrtc, false);
@@ -802,81 +763,6 @@ static void armada_drm_crtc_destroy(struct drm_crtc *crtc)
 	kfree(dcrtc);
 }
 
-/*
- * The mode_config lock is held here, to prevent races between this
- * and a mode_set.
- */
-static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
-	struct drm_framebuffer *fb, struct drm_pending_vblank_event *event,
-	uint32_t page_flip_flags, struct drm_modeset_acquire_ctx *ctx)
-{
-	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
-	struct drm_plane *plane = crtc->primary;
-	const struct drm_plane_helper_funcs *plane_funcs;
-	struct drm_plane_state *state;
-	struct armada_plane_work *work;
-	int ret;
-
-	/* Construct new state for the primary plane */
-	state = drm_atomic_helper_plane_duplicate_state(plane);
-	if (!state)
-		return -ENOMEM;
-
-	drm_atomic_set_fb_for_plane(state, fb);
-
-	work = armada_drm_crtc_alloc_plane_work(plane);
-	if (!work) {
-		ret = -ENOMEM;
-		goto put_state;
-	}
-
-	/* Make sure we can get vblank interrupts */
-	ret = drm_crtc_vblank_get(crtc);
-	if (ret)
-		goto put_work;
-
-	/*
-	 * If we have another work pending, we can't process this flip.
-	 * The modeset locks protect us from another user queuing a work
-	 * while we're setting up.
-	 */
-	if (drm_to_armada_plane(plane)->work) {
-		ret = -EBUSY;
-		goto put_vblank;
-	}
-
-	work->event = event;
-	work->old_fb = plane->state->fb;
-
-	/*
-	 * Hold a ref on the new fb while it's being displayed by the
-	 * hardware. The old fb refcount will be released in the worker.
-	 */
-	drm_framebuffer_get(state->fb);
-
-	/* Point of no return */
-	swap(plane->state, state);
-
-	dcrtc->regs_idx = 0;
-	dcrtc->regs = work->regs;
-
-	plane_funcs = plane->helper_private;
-	plane_funcs->atomic_update(plane, state);
-	armada_reg_queue_end(dcrtc->regs, dcrtc->regs_idx);
-
-	/* Queue the work - this should never fail */
-	WARN_ON(armada_drm_plane_work_queue(dcrtc, work));
-	work = NULL;
-
-put_vblank:
-	drm_crtc_vblank_put(crtc);
-put_work:
-	kfree(work);
-put_state:
-	drm_atomic_helper_plane_destroy_state(plane, state);
-	return ret;
-}
-
 /* These are called under the vbl_lock. */
 static int armada_drm_crtc_enable_vblank(struct drm_crtc *crtc)
 {
@@ -905,7 +791,7 @@ static const struct drm_crtc_funcs armada_crtc_funcs = {
 	.cursor_move	= armada_drm_crtc_cursor_move,
 	.destroy	= armada_drm_crtc_destroy,
 	.set_config	= drm_atomic_helper_set_config,
-	.page_flip	= armada_drm_crtc_page_flip,
+	.page_flip	= drm_atomic_helper_page_flip,
 	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 	.enable_vblank	= armada_drm_crtc_enable_vblank,
diff --git a/drivers/gpu/drm/armada/armada_plane.c b/drivers/gpu/drm/armada/armada_plane.c
index 1320fec4c386..39c9ba3ee57e 100644
--- a/drivers/gpu/drm/armada/armada_plane.c
+++ b/drivers/gpu/drm/armada/armada_plane.c
@@ -261,8 +261,8 @@ static const struct drm_plane_helper_funcs armada_primary_plane_helper_funcs = {
 };
 
 static const struct drm_plane_funcs armada_primary_plane_funcs = {
-	.update_plane	= drm_plane_helper_update,
-	.disable_plane	= drm_plane_helper_disable,
+	.update_plane	= drm_atomic_helper_update_plane,
+	.disable_plane	= drm_atomic_helper_disable_plane,
 	.destroy	= drm_primary_helper_destroy,
 	.reset		= drm_atomic_helper_plane_reset,
 	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
commit 6d2f864fdff5c73cb37069cd17b0f897d7995b62
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:53:06 2018 +0100

    drm/armada: switch legacy modeset to atomic modeset
    
    Switch the legacy set_config() method to use the atomic modeset
    helper, which allows us to get rid of the legacy dpms, prepare,
    commit, mode_set, mode_set_base and disable helper methods.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 375a20757561..0cef40ad3a06 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -92,8 +92,6 @@ armada_drm_crtc_update_regs(struct armada_crtc *dcrtc, struct armada_regs *regs)
 	}
 }
 
-#define dpms_blanked(dpms)	((dpms) != DRM_MODE_DPMS_ON)
-
 static void armada_drm_crtc_update(struct armada_crtc *dcrtc, bool enable)
 {
 	uint32_t dumb_ctrl;
@@ -221,16 +219,6 @@ armada_drm_crtc_alloc_plane_work(struct drm_plane *plane)
 	return work;
 }
 
-static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
-{
-	/*
-	 * Tell the DRM core that vblank IRQs aren't going to happen for
-	 * a while.  This cleans up any pending vblank events for us.
-	 */
-	drm_crtc_vblank_off(&dcrtc->crtc);
-	armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary);
-}
-
 static void armada_drm_crtc_queue_state_event(struct drm_crtc *crtc)
 {
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
@@ -245,71 +233,6 @@ static void armada_drm_crtc_queue_state_event(struct drm_crtc *crtc)
 }
 
 /* The mode_config.mutex will be held for this call */
-static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms)
-{
-	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
-
-	if (dpms_blanked(dcrtc->dpms) != dpms_blanked(dpms)) {
-		if (dpms_blanked(dpms))
-			armada_drm_vblank_off(dcrtc);
-		else if (dcrtc->variant->enable)
-			dcrtc->variant->enable(dcrtc, &crtc->hwmode);
-		dcrtc->dpms = dpms;
-		armada_drm_crtc_update(dcrtc, !dpms_blanked(dcrtc->dpms));
-		if (!dpms_blanked(dpms))
-			drm_crtc_vblank_on(&dcrtc->crtc);
-		else if (dcrtc->variant->disable)
-			dcrtc->variant->disable(dcrtc);
-	} else if (dcrtc->dpms != dpms) {
-		dcrtc->dpms = dpms;
-	}
-}
-
-/*
- * Prepare for a mode set.  Turn off overlay to ensure that we don't end
- * up with the overlay size being bigger than the active screen size.
- * We rely upon X refreshing this state after the mode set has completed.
- *
- * The mode_config.mutex will be held for this call
- */
-static void armada_drm_crtc_prepare(struct drm_crtc *crtc)
-{
-	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
-	struct drm_plane *plane;
-
-	/*
-	 * If we have an overlay plane associated with this CRTC, disable it
-	 * before the modeset to avoid its coordinates being outside the new
-	 * mode parameters.  For transitional atomic modeset, we only wait.
-	 */
-	plane = dcrtc->plane;
-	if (plane) {
-		WARN_ON(!armada_drm_plane_work_wait(drm_to_armada_plane(plane),
-						    HZ));
-	}
-
-	/* Wait for pending flips to complete */
-	armada_drm_plane_work_wait(drm_to_armada_plane(dcrtc->crtc.primary),
-				   MAX_SCHEDULE_TIMEOUT);
-
-	drm_crtc_vblank_off(crtc);
-
-	armada_updatel(0, CFG_DUMB_ENA, dcrtc->base + LCD_SPU_DUMB_CTRL);
-}
-
-/* The mode_config.mutex will be held for this call */
-static void armada_drm_crtc_commit(struct drm_crtc *crtc)
-{
-	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
-
-	dcrtc->dpms = DRM_MODE_DPMS_ON;
-	armada_drm_crtc_update(dcrtc, true);
-	drm_crtc_vblank_on(crtc);
-
-	armada_drm_crtc_queue_state_event(crtc);
-}
-
-/* The mode_config.mutex will be held for this call */
 static bool armada_drm_crtc_mode_fixup(struct drm_crtc *crtc,
 	const struct drm_display_mode *mode, struct drm_display_mode *adj)
 {
@@ -532,15 +455,6 @@ static void armada_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
 	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
 }
 
-/* The mode_config.mutex will be held for this call */
-static void armada_drm_crtc_disable(struct drm_crtc *crtc)
-{
-	armada_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
-
-	/* Disable our primary plane when we disable the CRTC. */
-	crtc->primary->funcs->disable_plane(crtc->primary, NULL);
-}
-
 static void armada_drm_crtc_atomic_begin(struct drm_crtc *crtc,
 					 struct drm_crtc_state *old_crtc_state)
 {
@@ -600,7 +514,6 @@ static void armada_drm_crtc_atomic_disable(struct drm_crtc *crtc,
 	armada_drm_plane_work_wait(drm_to_armada_plane(dcrtc->crtc.primary),
 				   MAX_SCHEDULE_TIMEOUT);
 
-	dcrtc->dpms = DRM_MODE_DPMS_OFF;
 	drm_crtc_vblank_off(crtc);
 	armada_drm_crtc_update(dcrtc, false);
 
@@ -633,7 +546,6 @@ static void armada_drm_crtc_atomic_enable(struct drm_crtc *crtc,
 
 	DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
 
-	dcrtc->dpms = DRM_MODE_DPMS_ON;
 	if (!old_state->active) {
 		/*
 		 * This modeset is enabling the CRTC after it having
@@ -650,14 +562,8 @@ static void armada_drm_crtc_atomic_enable(struct drm_crtc *crtc,
 }
 
 static const struct drm_crtc_helper_funcs armada_crtc_helper_funcs = {
-	.dpms		= armada_drm_crtc_dpms,
-	.prepare	= armada_drm_crtc_prepare,
-	.commit		= armada_drm_crtc_commit,
 	.mode_fixup	= armada_drm_crtc_mode_fixup,
-	.mode_set	= drm_helper_crtc_mode_set,
 	.mode_set_nofb	= armada_drm_crtc_mode_set_nofb,
-	.mode_set_base	= drm_helper_crtc_mode_set_base,
-	.disable	= armada_drm_crtc_disable,
 	.atomic_begin	= armada_drm_crtc_atomic_begin,
 	.atomic_flush	= armada_drm_crtc_atomic_flush,
 	.atomic_disable	= armada_drm_crtc_atomic_disable,
@@ -962,13 +868,6 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
 	WARN_ON(armada_drm_plane_work_queue(dcrtc, work));
 	work = NULL;
 
-	/*
-	 * Finally, if the display is blanked, we won't receive an
-	 * interrupt, so complete it now.
-	 */
-	if (dpms_blanked(dcrtc->dpms))
-		armada_drm_plane_work_run(dcrtc, plane);
-
 put_vblank:
 	drm_crtc_vblank_put(crtc);
 put_work:
@@ -1005,7 +904,7 @@ static const struct drm_crtc_funcs armada_crtc_funcs = {
 	.cursor_set	= armada_drm_crtc_cursor_set,
 	.cursor_move	= armada_drm_crtc_cursor_move,
 	.destroy	= armada_drm_crtc_destroy,
-	.set_config	= drm_crtc_helper_set_config,
+	.set_config	= drm_atomic_helper_set_config,
 	.page_flip	= armada_drm_crtc_page_flip,
 	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 8b1de877cb02..afc9266bc1e2 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -83,7 +83,6 @@ struct armada_crtc {
 	uint32_t		cursor_w;
 	uint32_t		cursor_h;
 
-	int			dpms;
 	uint32_t		cfg_dumb_ctrl;
 	uint32_t		spu_iopad_ctrl;
 
commit 6bd02908836ed00aa7fcdc759d490029137c2b30
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:53:06 2018 +0100

    drm/armada: enable atomic modeset support
    
    Enable atomic modeset helpers, and internal DRM use of atomic modeset
    with armada-drm.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index e93097d3aa06..375a20757561 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -278,13 +278,12 @@ static void armada_drm_crtc_prepare(struct drm_crtc *crtc)
 	struct drm_plane *plane;
 
 	/*
-	 * If we have an overlay plane associated with this CRTC, disable
-	 * it before the modeset to avoid its coordinates being outside
-	 * the new mode parameters.
+	 * If we have an overlay plane associated with this CRTC, disable it
+	 * before the modeset to avoid its coordinates being outside the new
+	 * mode parameters.  For transitional atomic modeset, we only wait.
 	 */
 	plane = dcrtc->plane;
 	if (plane) {
-		drm_plane_force_disable(plane);
 		WARN_ON(!armada_drm_plane_work_wait(drm_to_armada_plane(plane),
 						    HZ));
 	}
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 7517f23bb9cd..20661bd9001e 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -9,6 +9,7 @@
 #include <linux/component.h>
 #include <linux/module.h>
 #include <linux/of_graph.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_of.h>
@@ -73,7 +74,7 @@ static struct drm_driver armada_drm_driver = {
 	.desc			= "Armada SoC DRM",
 	.date			= "20120730",
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET |
-				  DRIVER_PRIME,
+				  DRIVER_PRIME | DRIVER_ATOMIC,
 	.ioctls			= armada_ioctls,
 	.fops			= &armada_drm_fops,
 };
@@ -81,6 +82,8 @@ static struct drm_driver armada_drm_driver = {
 static const struct drm_mode_config_funcs armada_drm_mode_config_funcs = {
 	.fb_create		= armada_fb_create,
 	.output_poll_changed	= drm_fb_helper_output_poll_changed,
+	.atomic_check		= drm_atomic_helper_check,
+	.atomic_commit		= drm_atomic_helper_commit,
 };
 
 static int armada_drm_bind(struct device *dev)
commit 34e25ed60ae2cdf91b953dd3772ae48a6bffbd4c
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: implement atomic_enable()/atomic_disable() methods
    
    Implement the atomic_enable()/atomic_disable() methods used by the
    atomic modeset helpers.  atomic_disable() will need some transitional
    code during conversion to ensure proper ordering is maintained.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 554135062d93..e93097d3aa06 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -581,6 +581,75 @@ static void armada_drm_crtc_atomic_flush(struct drm_crtc *crtc,
 		armada_drm_crtc_queue_state_event(crtc);
 }
 
+static void armada_drm_crtc_atomic_disable(struct drm_crtc *crtc,
+					   struct drm_crtc_state *old_state)
+{
+	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
+	struct drm_pending_vblank_event *event;
+	struct drm_plane *plane;
+
+	DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
+
+	/*
+	 * For transition only - we must wait for completion of our
+	 * untransitioned paths before changing anything.
+	 */
+	plane = dcrtc->plane;
+	if (plane)
+		WARN_ON(!armada_drm_plane_work_wait(drm_to_armada_plane(plane),
+						    HZ));
+	armada_drm_plane_work_wait(drm_to_armada_plane(dcrtc->crtc.primary),
+				   MAX_SCHEDULE_TIMEOUT);
+
+	dcrtc->dpms = DRM_MODE_DPMS_OFF;
+	drm_crtc_vblank_off(crtc);
+	armada_drm_crtc_update(dcrtc, false);
+
+	if (!crtc->state->active) {
+		/*
+		 * This modeset will be leaving the CRTC disabled, so
+		 * call the backend to disable upstream clocks etc.
+		 */
+		if (dcrtc->variant->disable)
+			dcrtc->variant->disable(dcrtc);
+
+		/*
+		 * We will not receive any further vblank events.
+		 * Send the flip_done event manually.
+		 */
+		event = crtc->state->event;
+		crtc->state->event = NULL;
+		if (event) {
+			spin_lock_irq(&crtc->dev->event_lock);
+			drm_crtc_send_vblank_event(crtc, event);
+			spin_unlock_irq(&crtc->dev->event_lock);
+		}
+	}
+}
+
+static void armada_drm_crtc_atomic_enable(struct drm_crtc *crtc,
+					  struct drm_crtc_state *old_state)
+{
+	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
+
+	DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
+
+	dcrtc->dpms = DRM_MODE_DPMS_ON;
+	if (!old_state->active) {
+		/*
+		 * This modeset is enabling the CRTC after it having
+		 * been disabled.  Reverse the call to ->disable in
+		 * the atomic_disable().
+		 */
+		if (dcrtc->variant->enable)
+			dcrtc->variant->enable(dcrtc, &crtc->state->adjusted_mode);
+	}
+	armada_drm_crtc_update(dcrtc, true);
+	drm_crtc_vblank_on(crtc);
+
+	armada_drm_crtc_queue_state_event(crtc);
+}
+
 static const struct drm_crtc_helper_funcs armada_crtc_helper_funcs = {
 	.dpms		= armada_drm_crtc_dpms,
 	.prepare	= armada_drm_crtc_prepare,
@@ -592,6 +661,8 @@ static const struct drm_crtc_helper_funcs armada_crtc_helper_funcs = {
 	.disable	= armada_drm_crtc_disable,
 	.atomic_begin	= armada_drm_crtc_atomic_begin,
 	.atomic_flush	= armada_drm_crtc_atomic_flush,
+	.atomic_disable	= armada_drm_crtc_atomic_disable,
+	.atomic_enable	= armada_drm_crtc_atomic_enable,
 };
 
 static void armada_load_cursor_argb(void __iomem *base, uint32_t *pix,
commit a0f75d2468fe4510bb8d0d6c4e1a5fd5e262e7b5
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: unhook dpms state from armada_drm_crtc_update()
    
    Explicitly pass in the desired enable/disable state into
    armada_drm_crtc_update() rather than having it use the DPMS state
    stored in our crtc structure.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 5d8fdcda27ee..554135062d93 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -94,13 +94,13 @@ armada_drm_crtc_update_regs(struct armada_crtc *dcrtc, struct armada_regs *regs)
 
 #define dpms_blanked(dpms)	((dpms) != DRM_MODE_DPMS_ON)
 
-static void armada_drm_crtc_update(struct armada_crtc *dcrtc)
+static void armada_drm_crtc_update(struct armada_crtc *dcrtc, bool enable)
 {
 	uint32_t dumb_ctrl;
 
 	dumb_ctrl = dcrtc->cfg_dumb_ctrl;
 
-	if (!dpms_blanked(dcrtc->dpms))
+	if (enable)
 		dumb_ctrl |= CFG_DUMB_ENA;
 
 	/*
@@ -109,8 +109,7 @@ static void armada_drm_crtc_update(struct armada_crtc *dcrtc)
 	 * force LCD_D[23:0] to output blank color, overriding the GPIO or
 	 * SPI usage.  So leave it as-is unless in DUMB24_RGB888_0 mode.
 	 */
-	if (dpms_blanked(dcrtc->dpms) &&
-	    (dumb_ctrl & DUMB_MASK) == DUMB24_RGB888_0) {
+	if (!enable && (dumb_ctrl & DUMB_MASK) == DUMB24_RGB888_0) {
 		dumb_ctrl &= ~DUMB_MASK;
 		dumb_ctrl |= DUMB_BLANK;
 	}
@@ -256,7 +255,7 @@ static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms)
 		else if (dcrtc->variant->enable)
 			dcrtc->variant->enable(dcrtc, &crtc->hwmode);
 		dcrtc->dpms = dpms;
-		armada_drm_crtc_update(dcrtc);
+		armada_drm_crtc_update(dcrtc, !dpms_blanked(dcrtc->dpms));
 		if (!dpms_blanked(dpms))
 			drm_crtc_vblank_on(&dcrtc->crtc);
 		else if (dcrtc->variant->disable)
@@ -305,7 +304,7 @@ static void armada_drm_crtc_commit(struct drm_crtc *crtc)
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
 
 	dcrtc->dpms = DRM_MODE_DPMS_ON;
-	armada_drm_crtc_update(dcrtc);
+	armada_drm_crtc_update(dcrtc, true);
 	drm_crtc_vblank_on(crtc);
 
 	armada_drm_crtc_queue_state_event(crtc);
commit a0fbb35ecde52aa5abf5975d117d29e3b30f7b91
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: push responsibility for clock management to backend
    
    Push responsibility for managing the clock during DPMS down into the
    variant backend, rather than the CRTC layer having knowledge of its
    state.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_510.c b/drivers/gpu/drm/armada/armada_510.c
index 9a4fbb6a24b8..2f7c048c5361 100644
--- a/drivers/gpu/drm/armada/armada_510.c
+++ b/drivers/gpu/drm/armada/armada_510.c
@@ -79,8 +79,27 @@ static int armada510_crtc_compute_clock(struct armada_crtc *dcrtc,
 	return 0;
 }
 
+static void armada510_crtc_disable(struct armada_crtc *dcrtc)
+{
+	if (!IS_ERR(dcrtc->clk)) {
+		clk_disable_unprepare(dcrtc->clk);
+		dcrtc->clk = ERR_PTR(-EINVAL);
+	}
+}
+
+static void armada510_crtc_enable(struct armada_crtc *dcrtc,
+	const struct drm_display_mode *mode)
+{
+	if (IS_ERR(dcrtc->clk)) {
+		dcrtc->clk = dcrtc->extclk[0];
+		WARN_ON(clk_prepare_enable(dcrtc->clk));
+	}
+}
+
 const struct armada_variant armada510_ops = {
 	.has_spu_adv_reg = true,
 	.init = armada510_crtc_init,
 	.compute_clock = armada510_crtc_compute_clock,
+	.disable = armada510_crtc_disable,
+	.enable = armada510_crtc_enable,
 };
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index a0c67ec892cf..5d8fdcda27ee 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -253,14 +253,14 @@ static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms)
 	if (dpms_blanked(dcrtc->dpms) != dpms_blanked(dpms)) {
 		if (dpms_blanked(dpms))
 			armada_drm_vblank_off(dcrtc);
-		else if (!IS_ERR(dcrtc->clk))
-			WARN_ON(clk_prepare_enable(dcrtc->clk));
+		else if (dcrtc->variant->enable)
+			dcrtc->variant->enable(dcrtc, &crtc->hwmode);
 		dcrtc->dpms = dpms;
 		armada_drm_crtc_update(dcrtc);
 		if (!dpms_blanked(dpms))
 			drm_crtc_vblank_on(&dcrtc->crtc);
-		else if (!IS_ERR(dcrtc->clk))
-			clk_disable_unprepare(dcrtc->clk);
+		else if (dcrtc->variant->disable)
+			dcrtc->variant->disable(dcrtc);
 	} else if (dcrtc->dpms != dpms) {
 		dcrtc->dpms = dpms;
 	}
@@ -462,13 +462,6 @@ static void armada_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
 		      adj->type, adj->flags);
 	DRM_DEBUG_KMS("lm %d rm %d tm %d bm %d\n", lm, rm, tm, bm);
 
-	/*
-	 * If we are blanked, we would have disabled the clock.  Re-enable
-	 * it so that compute_clock() does the right thing.
-	 */
-	if (!IS_ERR(dcrtc->clk) && dpms_blanked(dcrtc->dpms))
-		WARN_ON(clk_prepare_enable(dcrtc->clk));
-
 	/* Now compute the divider for real */
 	dcrtc->variant->compute_clock(dcrtc, adj, &sclk);
 
@@ -824,8 +817,8 @@ static void armada_drm_crtc_destroy(struct drm_crtc *crtc)
 	priv->dcrtc[dcrtc->num] = NULL;
 	drm_crtc_cleanup(&dcrtc->crtc);
 
-	if (!IS_ERR(dcrtc->clk))
-		clk_disable_unprepare(dcrtc->clk);
+	if (dcrtc->variant->disable)
+		dcrtc->variant->disable(dcrtc);
 
 	writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ENA);
 
diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h
index a6f919b0084c..9658be917ea1 100644
--- a/drivers/gpu/drm/armada/armada_drm.h
+++ b/drivers/gpu/drm/armada/armada_drm.h
@@ -46,6 +46,8 @@ struct armada_variant {
 	int (*compute_clock)(struct armada_crtc *,
 			     const struct drm_display_mode *,
 			     uint32_t *);
+	void (*disable)(struct armada_crtc *);
+	void (*enable)(struct armada_crtc *, const struct drm_display_mode *);
 };
 
 /* Variant ops */
commit dbb4ca8acae100b21946a9c6439af51bd606595e
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: handle atomic modeset crtc events
    
    Prepare handling for atomic modeset CRTC events.  Currently, using the
    transition helpers, CRTC events do not exist, but once we switch to
    proper atomic modeset, they have to be handled.
    
    We queue an event for the next vblank in two places:
    - armada_drm_crtc_atomic_flush() provided we aren't doing an
      atomic modeset.
    - armada_drm_crtc_commit() if we are committing a modeset.
    
    This ensures that the event is sent at the correct time (after all
    updates have been written to the hardware and after the following
    vblank.)
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 80d34a4b7d41..a0c67ec892cf 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -232,6 +232,19 @@ static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
 	armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary);
 }
 
+static void armada_drm_crtc_queue_state_event(struct drm_crtc *crtc)
+{
+	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
+	struct drm_pending_vblank_event *event;
+
+	/* If we have an event, we need vblank events enabled */
+	event = xchg(&crtc->state->event, NULL);
+	if (event) {
+		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+		dcrtc->event = event;
+	}
+}
+
 /* The mode_config.mutex will be held for this call */
 static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms)
 {
@@ -294,6 +307,8 @@ static void armada_drm_crtc_commit(struct drm_crtc *crtc)
 	dcrtc->dpms = DRM_MODE_DPMS_ON;
 	armada_drm_crtc_update(dcrtc);
 	drm_crtc_vblank_on(crtc);
+
+	armada_drm_crtc_queue_state_event(crtc);
 }
 
 /* The mode_config.mutex will be held for this call */
@@ -337,6 +352,7 @@ static void armada_drm_crtc_enable_irq(struct armada_crtc *dcrtc, u32 mask)
 
 static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 {
+	struct drm_pending_vblank_event *event;
 	void __iomem *base = dcrtc->base;
 	struct drm_plane *ovl_plane;
 
@@ -383,6 +399,16 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 
 	if (stat & GRA_FRAME_IRQ)
 		armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary);
+
+	if (stat & VSYNC_IRQ) {
+		event = xchg(&dcrtc->event, NULL);
+		if (event) {
+			spin_lock(&dcrtc->crtc.dev->event_lock);
+			drm_crtc_send_vblank_event(&dcrtc->crtc, event);
+			spin_unlock(&dcrtc->crtc.dev->event_lock);
+			drm_crtc_vblank_put(&dcrtc->crtc);
+		}
+	}
 }
 
 static irqreturn_t armada_drm_irq(int irq, void *arg)
@@ -554,6 +580,13 @@ static void armada_drm_crtc_atomic_flush(struct drm_crtc *crtc,
 	spin_lock_irqsave(&dcrtc->irq_lock, flags);
 	armada_drm_crtc_update_regs(dcrtc, dcrtc->regs);
 	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
+
+	/*
+	 * If we aren't doing a full modeset, then we need to queue
+	 * the event here.
+	 */
+	if (!drm_atomic_crtc_needs_modeset(crtc->state))
+		armada_drm_crtc_queue_state_event(crtc);
 }
 
 static const struct drm_crtc_helper_funcs armada_crtc_helper_funcs = {
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 775c01c52982..8b1de877cb02 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -90,6 +90,7 @@ struct armada_crtc {
 	spinlock_t		irq_lock;
 	uint32_t		irq_ena;
 
+	struct drm_pending_vblank_event *event;
 	struct armada_regs	atomic_regs[32];
 	struct armada_regs	*regs;
 	unsigned int		regs_idx;
commit 4e4b3563ac006e47761341682de80528e2cf30ab
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: clean up SPU_ADV_REG
    
    Rather than writing all bits of SPU_ADV_REG on modeset, only write
    what we need to change, and initialise the register in the variant
    initialisation.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_510.c b/drivers/gpu/drm/armada/armada_510.c
index 41a784f5a5e6..9a4fbb6a24b8 100644
--- a/drivers/gpu/drm/armada/armada_510.c
+++ b/drivers/gpu/drm/armada/armada_510.c
@@ -27,6 +27,10 @@ static int armada510_crtc_init(struct armada_crtc *dcrtc, struct device *dev)
 	/* Lower the watermark so to eliminate jitter at higher bandwidths */
 	armada_updatel(0x20, (1 << 11) | 0xff, dcrtc->base + LCD_CFG_RDREG4F);
 
+	/* Initialise SPU register */
+	writel_relaxed(ADV_HWC32ENABLE | ADV_HWC32ARGB | ADV_HWC32BLEND,
+		       dcrtc->base + LCD_SPU_ADV_REG);
+
 	return 0;
 }
 
@@ -77,7 +81,6 @@ static int armada510_crtc_compute_clock(struct armada_crtc *dcrtc,
 
 const struct armada_variant armada510_ops = {
 	.has_spu_adv_reg = true,
-	.spu_adv_reg = ADV_HWC32ENABLE | ADV_HWC32ARGB | ADV_HWC32BLEND,
 	.init = armada510_crtc_init,
 	.compute_clock = armada510_crtc_compute_clock,
 };
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 9ad966caf08c..80d34a4b7d41 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -463,17 +463,15 @@ static void armada_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
 				    adj->crtc_htotal;
 	dcrtc->v[1].spu_v_porch = tm << 16 | bm;
 	val = adj->crtc_hsync_start;
-	dcrtc->v[1].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN |
-		dcrtc->variant->spu_adv_reg;
+	dcrtc->v[1].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN;
 
 	if (interlaced) {
 		/* Odd interlaced frame */
+		val -= adj->crtc_htotal / 2;
+		dcrtc->v[0].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN;
 		dcrtc->v[0].spu_v_h_total = dcrtc->v[1].spu_v_h_total +
 						(1 << 16);
 		dcrtc->v[0].spu_v_porch = dcrtc->v[1].spu_v_porch + 1;
-		val = adj->crtc_hsync_start - adj->crtc_htotal / 2;
-		dcrtc->v[0].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN |
-			dcrtc->variant->spu_adv_reg;
 	} else {
 		dcrtc->v[0] = dcrtc->v[1];
 	}
@@ -486,11 +484,10 @@ static void armada_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
 	armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_h_total,
 			   LCD_SPUT_V_H_TOTAL);
 
-	if (dcrtc->variant->has_spu_adv_reg) {
+	if (dcrtc->variant->has_spu_adv_reg)
 		armada_reg_queue_mod(regs, i, dcrtc->v[0].spu_adv_reg,
 				     ADV_VSYNC_L_OFF | ADV_VSYNC_H_OFF |
 				     ADV_VSYNCOFFEN, LCD_SPU_ADV_REG);
-	}
 
 	val = adj->flags & DRM_MODE_FLAG_NVSYNC ? CFG_VSYNC_INV : 0;
 	armada_reg_queue_mod(regs, i, val, CFG_VSYNC_INV, LCD_SPU_DMA_CTRL1);
diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h
index 64f1c8836078..a6f919b0084c 100644
--- a/drivers/gpu/drm/armada/armada_drm.h
+++ b/drivers/gpu/drm/armada/armada_drm.h
@@ -42,7 +42,6 @@ struct armada_private;
 
 struct armada_variant {
 	bool has_spu_adv_reg;
-	uint32_t spu_adv_reg;
 	int (*init)(struct armada_crtc *, struct device *);
 	int (*compute_clock)(struct armada_crtc *,
 			     const struct drm_display_mode *,
commit a61c3922f6293ab5d58f64e2312981cc646c2fd8
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: update debug in armada_drm_crtc_mode_set_nofb()
    
    Update debug to use KMS level, and print the mode using the standard
    format for mode lines, but print the adjusted CRTC parameters as
    that's what we will be programming for.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 3cae6587b079..9ad966caf08c 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -426,16 +426,15 @@ static void armada_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
 	bm = adj->crtc_vsync_start - adj->crtc_vdisplay;
 	tm = adj->crtc_vtotal - adj->crtc_vsync_end;
 
-	DRM_DEBUG_DRIVER("H: %d %d %d %d lm %d rm %d\n",
-		adj->crtc_hdisplay,
-		adj->crtc_hsync_start,
-		adj->crtc_hsync_end,
-		adj->crtc_htotal, lm, rm);
-	DRM_DEBUG_DRIVER("V: %d %d %d %d tm %d bm %d\n",
-		adj->crtc_vdisplay,
-		adj->crtc_vsync_start,
-		adj->crtc_vsync_end,
-		adj->crtc_vtotal, tm, bm);
+	DRM_DEBUG_KMS("[CRTC:%d:%s] mode " DRM_MODE_FMT "\n",
+		      crtc->base.id, crtc->name,
+		      adj->base.id, adj->name, adj->vrefresh, adj->clock,
+		      adj->crtc_hdisplay, adj->crtc_hsync_start,
+		      adj->crtc_hsync_end, adj->crtc_htotal,
+		      adj->crtc_vdisplay, adj->crtc_vsync_start,
+		      adj->crtc_vsync_end, adj->crtc_vtotal,
+		      adj->type, adj->flags);
+	DRM_DEBUG_KMS("lm %d rm %d tm %d bm %d\n", lm, rm, tm, bm);
 
 	/*
 	 * If we are blanked, we would have disabled the clock.  Re-enable
commit 155b8290f7635b31faa57ca38cb5ddfe78111c2d
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: move sync signal polarity to mode_set_nofb() method
    
    For atomic modeset, we need to set the sync signal polarities from the
    CRTC state structure rather than the legacy mode structure stored in
    CRTC.  In any case, we should update this from our mode_set_nofb()
    method, rather than the commit() method.  Move it there, and ensure
    that armada_drm_crtc_update() will not overwrite these bits.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 35b2df0fc21c..3cae6587b079 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -115,25 +115,9 @@ static void armada_drm_crtc_update(struct armada_crtc *dcrtc)
 		dumb_ctrl |= DUMB_BLANK;
 	}
 
-	/*
-	 * The documentation doesn't indicate what the normal state of
-	 * the sync signals are.  Sebastian Hesselbart kindly probed
-	 * these signals on his board to determine their state.
-	 *
-	 * The non-inverted state of the sync signals is active high.
-	 * Setting these bits makes the appropriate signal active low.
-	 */
-	if (dcrtc->crtc.mode.flags & DRM_MODE_FLAG_NCSYNC)
-		dumb_ctrl |= CFG_INV_CSYNC;
-	if (dcrtc->crtc.mode.flags & DRM_MODE_FLAG_NHSYNC)
-		dumb_ctrl |= CFG_INV_HSYNC;
-	if (dcrtc->crtc.mode.flags & DRM_MODE_FLAG_NVSYNC)
-		dumb_ctrl |= CFG_INV_VSYNC;
-
-	if (dcrtc->dumb_ctrl != dumb_ctrl) {
-		dcrtc->dumb_ctrl = dumb_ctrl;
-		writel_relaxed(dumb_ctrl, dcrtc->base + LCD_SPU_DUMB_CTRL);
-	}
+	armada_updatel(dumb_ctrl,
+		       ~(CFG_INV_CSYNC | CFG_INV_HSYNC | CFG_INV_VSYNC),
+		       dcrtc->base + LCD_SPU_DUMB_CTRL);
 }
 
 static void armada_drm_plane_work_call(struct armada_crtc *dcrtc,
@@ -280,7 +264,6 @@ static void armada_drm_crtc_prepare(struct drm_crtc *crtc)
 {
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
 	struct drm_plane *plane;
-	u32 val;
 
 	/*
 	 * If we have an overlay plane associated with this CRTC, disable
@@ -300,11 +283,7 @@ static void armada_drm_crtc_prepare(struct drm_crtc *crtc)
 
 	drm_crtc_vblank_off(crtc);
 
-	val = dcrtc->dumb_ctrl & ~CFG_DUMB_ENA;
-	if (val != dcrtc->dumb_ctrl) {
-		dcrtc->dumb_ctrl = val;
-		writel_relaxed(val, dcrtc->base + LCD_SPU_DUMB_CTRL);
-	}
+	armada_updatel(0, CFG_DUMB_ENA, dcrtc->base + LCD_SPU_DUMB_CTRL);
 }
 
 /* The mode_config.mutex will be held for this call */
@@ -516,6 +495,24 @@ static void armada_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
 
 	val = adj->flags & DRM_MODE_FLAG_NVSYNC ? CFG_VSYNC_INV : 0;
 	armada_reg_queue_mod(regs, i, val, CFG_VSYNC_INV, LCD_SPU_DMA_CTRL1);
+
+	/*
+	 * The documentation doesn't indicate what the normal state of
+	 * the sync signals are.  Sebastian Hesselbart kindly probed
+	 * these signals on his board to determine their state.
+	 *
+	 * The non-inverted state of the sync signals is active high.
+	 * Setting these bits makes the appropriate signal active low.
+	 */
+	val = 0;
+	if (adj->flags & DRM_MODE_FLAG_NCSYNC)
+		val |= CFG_INV_CSYNC;
+	if (adj->flags & DRM_MODE_FLAG_NHSYNC)
+		val |= CFG_INV_HSYNC;
+	if (adj->flags & DRM_MODE_FLAG_NVSYNC)
+		val |= CFG_INV_VSYNC;
+	armada_reg_queue_mod(regs, i, val, CFG_INV_CSYNC | CFG_INV_HSYNC |
+			     CFG_INV_VSYNC, LCD_SPU_DUMB_CTRL);
 	armada_reg_queue_end(regs, i);
 
 	armada_drm_crtc_update_regs(dcrtc, regs);
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 21338f7c3d7d..775c01c52982 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -85,7 +85,6 @@ struct armada_crtc {
 
 	int			dpms;
 	uint32_t		cfg_dumb_ctrl;
-	uint32_t		dumb_ctrl;
 	uint32_t		spu_iopad_ctrl;
 
 	spinlock_t		irq_lock;
commit b5bae71a79d712681bdf48ee029f1953697924f7
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: push interlace calculation into armada_drm_plane_calc()
    
    Push the interlaced frame calculation down into armada_drm_plane_calc()
    which needs to apply the same correction for both the overlay and
    primary planes.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index f36f6fb919e7..7de8b6bd7847 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -131,21 +131,21 @@ static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
 	    old_state->fb != state->fb) {
 		const struct drm_format_info *format;
 		u16 src_x, pitches[3];
-		u32 addrs[3];
+		u32 addrs[2][3];
 
-		armada_drm_plane_calc(state, addrs, pitches);
+		armada_drm_plane_calc(state, addrs, pitches, false);
 
-		armada_reg_queue_set(regs, idx, addrs[0],
+		armada_reg_queue_set(regs, idx, addrs[0][0],
 				     LCD_SPU_DMA_START_ADDR_Y0);
-		armada_reg_queue_set(regs, idx, addrs[1],
+		armada_reg_queue_set(regs, idx, addrs[0][1],
 				     LCD_SPU_DMA_START_ADDR_U0);
-		armada_reg_queue_set(regs, idx, addrs[2],
+		armada_reg_queue_set(regs, idx, addrs[0][2],
 				     LCD_SPU_DMA_START_ADDR_V0);
-		armada_reg_queue_set(regs, idx, addrs[0],
+		armada_reg_queue_set(regs, idx, addrs[1][0],
 				     LCD_SPU_DMA_START_ADDR_Y1);
-		armada_reg_queue_set(regs, idx, addrs[1],
+		armada_reg_queue_set(regs, idx, addrs[1][1],
 				     LCD_SPU_DMA_START_ADDR_U1);
-		armada_reg_queue_set(regs, idx, addrs[2],
+		armada_reg_queue_set(regs, idx, addrs[1][2],
 				     LCD_SPU_DMA_START_ADDR_V1);
 
 		val = pitches[0] << 16 | pitches[0];
diff --git a/drivers/gpu/drm/armada/armada_plane.c b/drivers/gpu/drm/armada/armada_plane.c
index 3c9414c56aca..1320fec4c386 100644
--- a/drivers/gpu/drm/armada/armada_plane.c
+++ b/drivers/gpu/drm/armada/armada_plane.c
@@ -35,8 +35,8 @@ static const uint32_t armada_primary_formats[] = {
 	DRM_FORMAT_BGR565,
 };
 
-void armada_drm_plane_calc(struct drm_plane_state *state, u32 addrs[3],
-	u16 pitches[3])
+void armada_drm_plane_calc(struct drm_plane_state *state, u32 addrs[2][3],
+	u16 pitches[3], bool interlaced)
 {
 	struct drm_framebuffer *fb = state->fb;
 	const struct drm_format_info *format = fb->format;
@@ -52,43 +52,45 @@ void armada_drm_plane_calc(struct drm_plane_state *state, u32 addrs[3],
 	if (num_planes > 3)
 		num_planes = 3;
 
-	addrs[0] = addr + fb->offsets[0] + y * fb->pitches[0] +
-		   x * format->cpp[0];
+	addrs[0][0] = addr + fb->offsets[0] + y * fb->pitches[0] +
+		      x * format->cpp[0];
 	pitches[0] = fb->pitches[0];
 
 	y /= format->vsub;
 	x /= format->hsub;
 
 	for (i = 1; i < num_planes; i++) {
-		addrs[i] = addr + fb->offsets[i] + y * fb->pitches[i] +
-			     x * format->cpp[i];
+		addrs[0][i] = addr + fb->offsets[i] + y * fb->pitches[i] +
+			      x * format->cpp[i];
 		pitches[i] = fb->pitches[i];
 	}
 	for (; i < 3; i++) {
-		addrs[i] = 0;
+		addrs[0][i] = 0;
 		pitches[i] = 0;
 	}
+	if (interlaced) {
+		for (i = 0; i < 3; i++) {
+			addrs[1][i] = addrs[0][i] + pitches[i];
+			pitches[i] *= 2;
+		}
+	} else {
+		for (i = 0; i < 3; i++)
+			addrs[1][i] = addrs[0][i];
+	}
 }
 
 static unsigned armada_drm_crtc_calc_fb(struct drm_plane_state *state,
 	struct armada_regs *regs, bool interlaced)
 {
 	u16 pitches[3];
-	u32 addrs[3], addr_odd, addr_even;
+	u32 addrs[2][3];
 	unsigned i = 0;
 
-	armada_drm_plane_calc(state, addrs, pitches);
-
-	addr_odd = addr_even = addrs[0];
-
-	if (interlaced) {
-		addr_even += pitches[0];
-		pitches[0] *= 2;
-	}
+	armada_drm_plane_calc(state, addrs, pitches, interlaced);
 
 	/* write offset, base, and pitch */
-	armada_reg_queue_set(regs, i, addr_odd, LCD_CFG_GRA_START_ADDR0);
-	armada_reg_queue_set(regs, i, addr_even, LCD_CFG_GRA_START_ADDR1);
+	armada_reg_queue_set(regs, i, addrs[0][0], LCD_CFG_GRA_START_ADDR0);
+	armada_reg_queue_set(regs, i, addrs[1][0], LCD_CFG_GRA_START_ADDR1);
 	armada_reg_queue_mod(regs, i, pitches[0], 0xffff, LCD_CFG_GRA_PITCH);
 
 	return i;
diff --git a/drivers/gpu/drm/armada/armada_plane.h b/drivers/gpu/drm/armada/armada_plane.h
index 98280beaaa44..1bd8430992e0 100644
--- a/drivers/gpu/drm/armada/armada_plane.h
+++ b/drivers/gpu/drm/armada/armada_plane.h
@@ -1,8 +1,8 @@
 #ifndef ARMADA_PLANE_H
 #define ARMADA_PLANE_H
 
-void armada_drm_plane_calc(struct drm_plane_state *state, u32 addrs[3],
-	u16 pitches[3]);
+void armada_drm_plane_calc(struct drm_plane_state *state, u32 addrs[2][3],
+	u16 pitches[3], bool interlaced);
 int armada_drm_plane_prepare_fb(struct drm_plane *plane,
 	struct drm_plane_state *state);
 void armada_drm_plane_cleanup_fb(struct drm_plane *plane,
commit 4aafe00e2f6bb43656d690b6241f80bb8c236168
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: provide pitches from armada_drm_plane_calc_addrs()
    
    Provide the framebuffer pitches from armada_drm_plane_calc_addrs() as
    well as the base addresses for each plane.  Since this is now about
    more than just addresses, rename to armada_drm_plane_calc().
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index e8c3bcc09d5c..f36f6fb919e7 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -130,10 +130,10 @@ static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
 	    old_state->src.y1 != state->src.y1 ||
 	    old_state->fb != state->fb) {
 		const struct drm_format_info *format;
-		u16 src_x;
+		u16 src_x, pitches[3];
 		u32 addrs[3];
 
-		armada_drm_plane_calc_addrs(state, addrs);
+		armada_drm_plane_calc(state, addrs, pitches);
 
 		armada_reg_queue_set(regs, idx, addrs[0],
 				     LCD_SPU_DMA_START_ADDR_Y0);
@@ -148,9 +148,9 @@ static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
 		armada_reg_queue_set(regs, idx, addrs[2],
 				     LCD_SPU_DMA_START_ADDR_V1);
 
-		val = state->fb->pitches[0] << 16 | state->fb->pitches[0];
+		val = pitches[0] << 16 | pitches[0];
 		armada_reg_queue_set(regs, idx, val, LCD_SPU_DMA_PITCH_YC);
-		val = state->fb->pitches[1] << 16 | state->fb->pitches[2];
+		val = pitches[1] << 16 | pitches[2];
 		armada_reg_queue_set(regs, idx, val, LCD_SPU_DMA_PITCH_UV);
 
 		cfg = CFG_DMA_FMT(drm_fb_to_armada_fb(state->fb)->fmt) |
diff --git a/drivers/gpu/drm/armada/armada_plane.c b/drivers/gpu/drm/armada/armada_plane.c
index c426c92c79d9..3c9414c56aca 100644
--- a/drivers/gpu/drm/armada/armada_plane.c
+++ b/drivers/gpu/drm/armada/armada_plane.c
@@ -35,7 +35,8 @@ static const uint32_t armada_primary_formats[] = {
 	DRM_FORMAT_BGR565,
 };
 
-void armada_drm_plane_calc_addrs(struct drm_plane_state *state, u32 addrs[3])
+void armada_drm_plane_calc(struct drm_plane_state *state, u32 addrs[3],
+	u16 pitches[3])
 {
 	struct drm_framebuffer *fb = state->fb;
 	const struct drm_format_info *format = fb->format;
@@ -53,37 +54,42 @@ void armada_drm_plane_calc_addrs(struct drm_plane_state *state, u32 addrs[3])
 
 	addrs[0] = addr + fb->offsets[0] + y * fb->pitches[0] +
 		   x * format->cpp[0];
+	pitches[0] = fb->pitches[0];
 
 	y /= format->vsub;
 	x /= format->hsub;
 
-	for (i = 1; i < num_planes; i++)
+	for (i = 1; i < num_planes; i++) {
 		addrs[i] = addr + fb->offsets[i] + y * fb->pitches[i] +
 			     x * format->cpp[i];
-	for (; i < 3; i++)
+		pitches[i] = fb->pitches[i];
+	}
+	for (; i < 3; i++) {
 		addrs[i] = 0;
+		pitches[i] = 0;
+	}
 }
 
 static unsigned armada_drm_crtc_calc_fb(struct drm_plane_state *state,
 	struct armada_regs *regs, bool interlaced)
 {
-	unsigned pitch = state->fb->pitches[0];
+	u16 pitches[3];
 	u32 addrs[3], addr_odd, addr_even;
 	unsigned i = 0;
 
-	armada_drm_plane_calc_addrs(state, addrs);
+	armada_drm_plane_calc(state, addrs, pitches);
 
 	addr_odd = addr_even = addrs[0];
 
 	if (interlaced) {
-		addr_even += pitch;
-		pitch *= 2;
+		addr_even += pitches[0];
+		pitches[0] *= 2;
 	}
 
 	/* write offset, base, and pitch */
 	armada_reg_queue_set(regs, i, addr_odd, LCD_CFG_GRA_START_ADDR0);
 	armada_reg_queue_set(regs, i, addr_even, LCD_CFG_GRA_START_ADDR1);
-	armada_reg_queue_mod(regs, i, pitch, 0xffff, LCD_CFG_GRA_PITCH);
+	armada_reg_queue_mod(regs, i, pitches[0], 0xffff, LCD_CFG_GRA_PITCH);
 
 	return i;
 }
diff --git a/drivers/gpu/drm/armada/armada_plane.h b/drivers/gpu/drm/armada/armada_plane.h
index 999a0bd3e512..98280beaaa44 100644
--- a/drivers/gpu/drm/armada/armada_plane.h
+++ b/drivers/gpu/drm/armada/armada_plane.h
@@ -1,7 +1,8 @@
 #ifndef ARMADA_PLANE_H
 #define ARMADA_PLANE_H
 
-void armada_drm_plane_calc_addrs(struct drm_plane_state *state, u32 addrs[3]);
+void armada_drm_plane_calc(struct drm_plane_state *state, u32 addrs[3],
+	u16 pitches[3]);
 int armada_drm_plane_prepare_fb(struct drm_plane *plane,
 	struct drm_plane_state *state);
 void armada_drm_plane_cleanup_fb(struct drm_plane *plane,
commit b4df3ba0d76823cb5e548505de104837d89aa5a9
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: pass plane state into armada_drm_plane_calc_addrs()
    
    armada_drm_plane_calc_addrs() gets all its information from the plane
    state, so it makes sense to pass the plane state pointer down into this
    function, rather than extracting the information in identical ways,
    sometimes a couple of layers up.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index bc1b5b860141..e8c3bcc09d5c 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -130,11 +130,10 @@ static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
 	    old_state->src.y1 != state->src.y1 ||
 	    old_state->fb != state->fb) {
 		const struct drm_format_info *format;
-		u16 src_x = state->src.x1 >> 16;
-		u16 src_y = state->src.y1 >> 16;
+		u16 src_x;
 		u32 addrs[3];
 
-		armada_drm_plane_calc_addrs(addrs, state->fb, src_x, src_y);
+		armada_drm_plane_calc_addrs(state, addrs);
 
 		armada_reg_queue_set(regs, idx, addrs[0],
 				     LCD_SPU_DMA_START_ADDR_Y0);
@@ -166,6 +165,7 @@ static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
 		 * the UV swap.
 		 */
 		format = state->fb->format;
+		src_x = state->src.x1 >> 16;
 		if (format->num_planes == 1 && src_x & (format->hsub - 1))
 			cfg ^= CFG_DMA_MOD(CFG_SWAPUV);
 		cfg_mask = CFG_CBSH_ENA | CFG_DMAFORMAT |
diff --git a/drivers/gpu/drm/armada/armada_plane.c b/drivers/gpu/drm/armada/armada_plane.c
index 1cb6a605bda9..c426c92c79d9 100644
--- a/drivers/gpu/drm/armada/armada_plane.c
+++ b/drivers/gpu/drm/armada/armada_plane.c
@@ -35,14 +35,19 @@ static const uint32_t armada_primary_formats[] = {
 	DRM_FORMAT_BGR565,
 };
 
-void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb,
-	int x, int y)
+void armada_drm_plane_calc_addrs(struct drm_plane_state *state, u32 addrs[3])
 {
+	struct drm_framebuffer *fb = state->fb;
 	const struct drm_format_info *format = fb->format;
 	unsigned int num_planes = format->num_planes;
+	unsigned int x = state->src.x1 >> 16;
+	unsigned int y = state->src.y1 >> 16;
 	u32 addr = drm_fb_obj(fb)->dev_addr;
 	int i;
 
+	DRM_DEBUG_KMS("pitch %u x %d y %d bpp %d\n",
+		      fb->pitches[0], x, y, format->cpp[0] * 8);
+
 	if (num_planes > 3)
 		num_planes = 3;
 
@@ -59,17 +64,14 @@ void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb,
 		addrs[i] = 0;
 }
 
-static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb,
-	int x, int y, struct armada_regs *regs, bool interlaced)
+static unsigned armada_drm_crtc_calc_fb(struct drm_plane_state *state,
+	struct armada_regs *regs, bool interlaced)
 {
-	unsigned pitch = fb->pitches[0];
+	unsigned pitch = state->fb->pitches[0];
 	u32 addrs[3], addr_odd, addr_even;
 	unsigned i = 0;
 
-	DRM_DEBUG_DRIVER("pitch %u x %d y %d bpp %d\n",
-		pitch, x, y, fb->format->cpp[0] * 8);
-
-	armada_drm_plane_calc_addrs(addrs, fb, x, y);
+	armada_drm_plane_calc_addrs(state, addrs);
 
 	addr_odd = addr_even = addrs[0];
 
@@ -175,10 +177,7 @@ static void armada_drm_primary_plane_atomic_update(struct drm_plane *plane,
 	if (old_state->src.x1 != state->src.x1 ||
 	    old_state->src.y1 != state->src.y1 ||
 	    old_state->fb != state->fb) {
-		idx += armada_drm_crtc_calc_fb(state->fb,
-					       state->src.x1 >> 16,
-					       state->src.y1 >> 16,
-					       regs + idx,
+		idx += armada_drm_crtc_calc_fb(state, regs + idx,
 					       dcrtc->interlaced);
 	}
 	if (old_state->fb != state->fb) {
diff --git a/drivers/gpu/drm/armada/armada_plane.h b/drivers/gpu/drm/armada/armada_plane.h
index 3c8316003907..999a0bd3e512 100644
--- a/drivers/gpu/drm/armada/armada_plane.h
+++ b/drivers/gpu/drm/armada/armada_plane.h
@@ -1,8 +1,7 @@
 #ifndef ARMADA_PLANE_H
 #define ARMADA_PLANE_H
 
-void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb,
-	int x, int y);
+void armada_drm_plane_calc_addrs(struct drm_plane_state *state, u32 addrs[3]);
 int armada_drm_plane_prepare_fb(struct drm_plane *plane,
 	struct drm_plane_state *state);
 void armada_drm_plane_cleanup_fb(struct drm_plane *plane,
commit 3382a6b999415d1f78cee3f483957651d7e1f8a4
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: move armada_drm_mode_config_funcs to armada_drv.c
    
    Move the armada_drm_mode_config_funcs to armada_drv.c, since this now
    has less to do with FBs than it does with general mode configuration.
    In doing so, we need to make armada_fb_create() visible to armada_drv.c,
    which reveals a function name clash with armada_fbdev.c.  Rename the
    version in armada_fbdev.c.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h
index 28087e4b9b81..64f1c8836078 100644
--- a/drivers/gpu/drm/armada/armada_drm.h
+++ b/drivers/gpu/drm/armada/armada_drm.h
@@ -79,8 +79,6 @@ void __armada_drm_queue_unref_work(struct drm_device *,
 void armada_drm_queue_unref_work(struct drm_device *,
 	struct drm_framebuffer *);
 
-extern const struct drm_mode_config_funcs armada_drm_mode_config_funcs;
-
 int armada_fbdev_init(struct drm_device *);
 void armada_fbdev_fini(struct drm_device *);
 
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index e47b995b4ce6..7517f23bb9cd 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -15,6 +15,7 @@
 #include "armada_crtc.h"
 #include "armada_drm.h"
 #include "armada_gem.h"
+#include "armada_fb.h"
 #include "armada_hw.h"
 #include <drm/armada_drm.h>
 #include "armada_ioctlP.h"
@@ -77,6 +78,11 @@ static struct drm_driver armada_drm_driver = {
 	.fops			= &armada_drm_fops,
 };
 
+static const struct drm_mode_config_funcs armada_drm_mode_config_funcs = {
+	.fb_create		= armada_fb_create,
+	.output_poll_changed	= drm_fb_helper_output_poll_changed,
+};
+
 static int armada_drm_bind(struct device *dev)
 {
 	struct armada_private *priv;
diff --git a/drivers/gpu/drm/armada/armada_fb.c b/drivers/gpu/drm/armada/armada_fb.c
index edd15126bde9..6bd638a54579 100644
--- a/drivers/gpu/drm/armada/armada_fb.c
+++ b/drivers/gpu/drm/armada/armada_fb.c
@@ -84,7 +84,7 @@ struct armada_framebuffer *armada_framebuffer_create(struct drm_device *dev,
 	return dfb;
 }
 
-static struct drm_framebuffer *armada_fb_create(struct drm_device *dev,
+struct drm_framebuffer *armada_fb_create(struct drm_device *dev,
 	struct drm_file *dfile, const struct drm_mode_fb_cmd2 *mode)
 {
 	struct armada_gem_object *obj;
@@ -138,8 +138,3 @@ static struct drm_framebuffer *armada_fb_create(struct drm_device *dev,
 	DRM_ERROR("failed to initialize framebuffer: %d\n", ret);
 	return ERR_PTR(ret);
 }
-
-const struct drm_mode_config_funcs armada_drm_mode_config_funcs = {
-	.fb_create		= armada_fb_create,
-	.output_poll_changed	= drm_fb_helper_output_poll_changed,
-};
diff --git a/drivers/gpu/drm/armada/armada_fb.h b/drivers/gpu/drm/armada/armada_fb.h
index 5c130ff5da77..476daad0a36a 100644
--- a/drivers/gpu/drm/armada/armada_fb.h
+++ b/drivers/gpu/drm/armada/armada_fb.h
@@ -19,5 +19,6 @@ struct armada_framebuffer {
 
 struct armada_framebuffer *armada_framebuffer_create(struct drm_device *,
 	const struct drm_mode_fb_cmd2 *, struct armada_gem_object *);
-
+struct drm_framebuffer *armada_fb_create(struct drm_device *dev,
+	struct drm_file *dfile, const struct drm_mode_fb_cmd2 *mode);
 #endif
diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c
index 2a59db0994b2..8d23700848df 100644
--- a/drivers/gpu/drm/armada/armada_fbdev.c
+++ b/drivers/gpu/drm/armada/armada_fbdev.c
@@ -24,7 +24,7 @@ static /*const*/ struct fb_ops armada_fb_ops = {
 	.fb_imageblit	= drm_fb_helper_cfb_imageblit,
 };
 
-static int armada_fb_create(struct drm_fb_helper *fbh,
+static int armada_fbdev_create(struct drm_fb_helper *fbh,
 	struct drm_fb_helper_surface_size *sizes)
 {
 	struct drm_device *dev = fbh->dev;
@@ -108,7 +108,7 @@ static int armada_fb_probe(struct drm_fb_helper *fbh,
 	int ret = 0;
 
 	if (!fbh->fb) {
-		ret = armada_fb_create(fbh, sizes);
+		ret = armada_fbdev_create(fbh, sizes);
 		if (ret == 0)
 			ret = 1;
 	}
commit c29277d4e56388e805acc3ba428c9cff7df99fa7
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: add plane colorspace properties
    
    Use the DRM standard plane properties for specifying the YUV
    colour encoding parameter.  Our colour range is fixed at limited
    range.
    
    Since we are transitioning to atomic modeset, we need to explicitly
    add handling of these properties to our atomic_set_property() method,
    but once the transition is complete, these will be removed.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 7f75df4f8390..bc1b5b860141 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -23,6 +23,7 @@
 #define DEFAULT_BRIGHTNESS	0
 #define DEFAULT_CONTRAST	0x4000
 #define DEFAULT_SATURATION	0x4000
+#define DEFAULT_ENCODING	DRM_COLOR_YCBCR_BT601
 
 struct armada_ovl_plane {
 	struct armada_plane base;
@@ -59,6 +60,19 @@ static inline u32 armada_spu_saturation(struct drm_plane_state *state)
 	return drm_to_overlay_state(state)->saturation << 16;
 }
 
+static inline u32 armada_csc(struct drm_plane_state *state)
+{
+	/*
+	 * The CFG_CSC_RGB_* settings control the output of the colour space
+	 * converter, setting the range of output values it produces.  Since
+	 * we will be blending with the full-range graphics, we need to
+	 * produce full-range RGB output from the conversion.
+	 */
+	return CFG_CSC_RGB_COMPUTER |
+	       (state->color_encoding == DRM_COLOR_YCBCR_BT709 ?
+			CFG_CSC_YUV_CCIR709 : CFG_CSC_YUV_CCIR601);
+}
+
 /* === Plane support === */
 static void armada_ovl_plane_work(struct armada_crtc *dcrtc,
 	struct armada_plane_work *work)
@@ -189,6 +203,11 @@ static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
 		armada_reg_queue_set(regs, idx, val, LCD_SPU_SATURATION);
 	if (!old_state->visible && state->visible)
 		armada_reg_queue_set(regs, idx, 0x00002000, LCD_SPU_CBSH_HUE);
+	val = armada_csc(state);
+	if ((!old_state->visible && state->visible) ||
+	    armada_csc(old_state) != val)
+		armada_reg_queue_mod(regs, idx, val, CFG_CSC_MASK,
+				     LCD_SPU_IOPAD_CONTROL);
 	val = drm_to_overlay_state(state)->colorkey_yr;
 	if ((!old_state->visible && state->visible) ||
 	    drm_to_overlay_state(old_state)->colorkey_yr != val)
@@ -399,6 +418,8 @@ static void armada_overlay_reset(struct drm_plane *plane)
 	state = kzalloc(sizeof(*state), GFP_KERNEL);
 	if (state) {
 		state->base.plane = plane;
+		state->base.color_encoding = DEFAULT_ENCODING;
+		state->base.color_range = DRM_COLOR_YCBCR_LIMITED_RANGE;
 		state->base.rotation = DRM_MODE_ROTATE_0;
 		state->colorkey_yr = 0xfefefe00;
 		state->colorkey_ug = 0x01010100;
@@ -489,6 +510,9 @@ static int armada_overlay_set_property(struct drm_plane *plane,
 		drm_to_overlay_state(state)->contrast = val;
 	} else if (property == priv->saturation_prop) {
 		drm_to_overlay_state(state)->saturation = val;
+	} else if (property == plane->color_encoding_property) {
+		/* transitional only */
+		state->color_encoding = val;
 	} else {
 		return -EINVAL;
 	}
@@ -685,5 +709,12 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 	drm_object_attach_property(mobj, priv->saturation_prop,
 				   DEFAULT_SATURATION);
 
-	return 0;
+	ret = drm_plane_create_color_properties(&dplane->base.base,
+						BIT(DRM_COLOR_YCBCR_BT601) |
+						BIT(DRM_COLOR_YCBCR_BT709),
+						BIT(DRM_COLOR_YCBCR_LIMITED_RANGE),
+						DEFAULT_ENCODING,
+						DRM_COLOR_YCBCR_LIMITED_RANGE);
+
+	return ret;
 }
commit 240cf2b58eb0bdd3c59387ca0cfbd5657708b996
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: remove crtc YUV colourspace properties
    
    Remove the unused CRTC colourspace properties - userspace does not make
    use of these.  In any case, these are not a property of the CRTC, since
    they demonstrably only affect the video (overlay) plane, irrespective
    of the format of the graphics (primary) plane.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index b9b0a508793d..35b2df0fc21c 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -23,14 +23,6 @@
 #include "armada_plane.h"
 #include "armada_trace.h"
 
-enum csc_mode {
-	CSC_AUTO = 0,
-	CSC_YUV_CCIR601 = 1,
-	CSC_YUV_CCIR709 = 2,
-	CSC_RGB_COMPUTER = 1,
-	CSC_RGB_STUDIO = 2,
-};
-
 /*
  * A note about interlacing.  Let's consider HDMI 1920x1080i.
  * The timing parameters we have from X are:
@@ -438,42 +430,6 @@ static irqreturn_t armada_drm_irq(int irq, void *arg)
 	return IRQ_NONE;
 }
 
-static uint32_t armada_drm_crtc_calculate_csc(struct armada_crtc *dcrtc)
-{
-	struct drm_display_mode *adj = &dcrtc->crtc.mode;
-	uint32_t val = 0;
-
-	if (dcrtc->csc_yuv_mode == CSC_YUV_CCIR709)
-		val |= CFG_CSC_YUV_CCIR709;
-	if (dcrtc->csc_rgb_mode == CSC_RGB_STUDIO)
-		val |= CFG_CSC_RGB_STUDIO;
-
-	/*
-	 * In auto mode, set the colorimetry, based upon the HDMI spec.
-	 * 1280x720p, 1920x1080p and 1920x1080i use ITU709, others use
-	 * ITU601.  It may be more appropriate to set this depending on
-	 * the source - but what if the graphic frame is YUV and the
-	 * video frame is RGB?
-	 */
-	if ((adj->hdisplay == 1280 && adj->vdisplay == 720 &&
-	     !(adj->flags & DRM_MODE_FLAG_INTERLACE)) ||
-	    (adj->hdisplay == 1920 && adj->vdisplay == 1080)) {
-		if (dcrtc->csc_yuv_mode == CSC_AUTO)
-			val |= CFG_CSC_YUV_CCIR709;
-	}
-
-	/*
-	 * We assume we're connected to a TV-like device, so the YUV->RGB
-	 * conversion should produce a limited range.  We should set this
-	 * depending on the connectors attached to this CRTC, and what
-	 * kind of device they report being connected.
-	 */
-	if (dcrtc->csc_rgb_mode == CSC_AUTO)
-		val |= CFG_CSC_RGB_STUDIO;
-
-	return val;
-}
-
 /* The mode_config.mutex will be held for this call */
 static void armada_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
@@ -560,9 +516,6 @@ static void armada_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
 
 	val = adj->flags & DRM_MODE_FLAG_NVSYNC ? CFG_VSYNC_INV : 0;
 	armada_reg_queue_mod(regs, i, val, CFG_VSYNC_INV, LCD_SPU_DMA_CTRL1);
-
-	val = dcrtc->spu_iopad_ctrl | armada_drm_crtc_calculate_csc(dcrtc);
-	armada_reg_queue_set(regs, i, val, LCD_SPU_IOPAD_CONTROL);
 	armada_reg_queue_end(regs, i);
 
 	armada_drm_crtc_update_regs(dcrtc, regs);
@@ -937,33 +890,6 @@ put_state:
 	return ret;
 }
 
-static int
-armada_drm_crtc_set_property(struct drm_crtc *crtc,
-	struct drm_property *property, uint64_t val)
-{
-	struct armada_private *priv = crtc->dev->dev_private;
-	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
-	bool update_csc = false;
-
-	if (property == priv->csc_yuv_prop) {
-		dcrtc->csc_yuv_mode = val;
-		update_csc = true;
-	} else if (property == priv->csc_rgb_prop) {
-		dcrtc->csc_rgb_mode = val;
-		update_csc = true;
-	}
-
-	if (update_csc) {
-		uint32_t val;
-
-		val = dcrtc->spu_iopad_ctrl |
-		      armada_drm_crtc_calculate_csc(dcrtc);
-		writel_relaxed(val, dcrtc->base + LCD_SPU_IOPAD_CONTROL);
-	}
-
-	return 0;
-}
-
 /* These are called under the vbl_lock. */
 static int armada_drm_crtc_enable_vblank(struct drm_crtc *crtc)
 {
@@ -993,45 +919,12 @@ static const struct drm_crtc_funcs armada_crtc_funcs = {
 	.destroy	= armada_drm_crtc_destroy,
 	.set_config	= drm_crtc_helper_set_config,
 	.page_flip	= armada_drm_crtc_page_flip,
-	.set_property	= armada_drm_crtc_set_property,
 	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 	.enable_vblank	= armada_drm_crtc_enable_vblank,
 	.disable_vblank	= armada_drm_crtc_disable_vblank,
 };
 
-static const struct drm_prop_enum_list armada_drm_csc_yuv_enum_list[] = {
-	{ CSC_AUTO,        "Auto" },
-	{ CSC_YUV_CCIR601, "CCIR601" },
-	{ CSC_YUV_CCIR709, "CCIR709" },
-};
-
-static const struct drm_prop_enum_list armada_drm_csc_rgb_enum_list[] = {
-	{ CSC_AUTO,         "Auto" },
-	{ CSC_RGB_COMPUTER, "Computer system" },
-	{ CSC_RGB_STUDIO,   "Studio" },
-};
-
-static int armada_drm_crtc_create_properties(struct drm_device *dev)
-{
-	struct armada_private *priv = dev->dev_private;
-
-	if (priv->csc_yuv_prop)
-		return 0;
-
-	priv->csc_yuv_prop = drm_property_create_enum(dev, 0,
-				"CSC_YUV", armada_drm_csc_yuv_enum_list,
-				ARRAY_SIZE(armada_drm_csc_yuv_enum_list));
-	priv->csc_rgb_prop = drm_property_create_enum(dev, 0,
-				"CSC_RGB", armada_drm_csc_rgb_enum_list,
-				ARRAY_SIZE(armada_drm_csc_rgb_enum_list));
-
-	if (!priv->csc_yuv_prop || !priv->csc_rgb_prop)
-		return -ENOMEM;
-
-	return 0;
-}
-
 static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 	struct resource *res, int irq, const struct armada_variant *variant,
 	struct device_node *port)
@@ -1042,10 +935,6 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 	void __iomem *base;
 	int ret;
 
-	ret = armada_drm_crtc_create_properties(drm);
-	if (ret)
-		return ret;
-
 	base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(base))
 		return PTR_ERR(base);
@@ -1063,8 +952,6 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 	dcrtc->base = base;
 	dcrtc->num = drm->mode_config.num_crtc;
 	dcrtc->clk = ERR_PTR(-EINVAL);
-	dcrtc->csc_yuv_mode = CSC_AUTO;
-	dcrtc->csc_rgb_mode = CSC_AUTO;
 	dcrtc->cfg_dumb_ctrl = DUMB24_RGB888_0;
 	dcrtc->spu_iopad_ctrl = CFG_VSCALE_LN_EN | CFG_IOPAD_DUMB24;
 	spin_lock_init(&dcrtc->irq_lock);
@@ -1121,11 +1008,6 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 
 	drm_crtc_helper_add(&dcrtc->crtc, &armada_crtc_helper_funcs);
 
-	drm_object_attach_property(&dcrtc->crtc.base, priv->csc_yuv_prop,
-				   dcrtc->csc_yuv_mode);
-	drm_object_attach_property(&dcrtc->crtc.base, priv->csc_rgb_prop,
-				   dcrtc->csc_rgb_mode);
-
 	return armada_overlay_plane_create(drm, 1 << dcrtc->num);
 
 err_crtc_init:
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index c27435a8776a..21338f7c3d7d 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -72,8 +72,6 @@ struct armada_crtc {
 	} v[2];
 	bool			interlaced;
 	bool			cursor_update;
-	uint8_t			csc_yuv_mode;
-	uint8_t			csc_rgb_mode;
 
 	struct drm_plane	*plane;
 
diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h
index cc4c557c9f66..28087e4b9b81 100644
--- a/drivers/gpu/drm/armada/armada_drm.h
+++ b/drivers/gpu/drm/armada/armada_drm.h
@@ -60,8 +60,6 @@ struct armada_private {
 	struct armada_crtc	*dcrtc[2];
 	struct drm_mm		linear; /* protected by linear_lock */
 	struct mutex		linear_lock;
-	struct drm_property	*csc_yuv_prop;
-	struct drm_property	*csc_rgb_prop;
 	struct drm_property	*colorkey_prop;
 	struct drm_property	*colorkey_min_prop;
 	struct drm_property	*colorkey_max_prop;
commit c96103b6c49ff9a8710e580da72c0f116d24a76c
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: move colorkey properties into overlay plane state
    
    Move the overlay plane colorkey properties into the plane state,
    keeping the existing driver behaviour to avoid breaking userspace.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index ec3ce28f162e..7f75df4f8390 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -24,29 +24,22 @@
 #define DEFAULT_CONTRAST	0x4000
 #define DEFAULT_SATURATION	0x4000
 
-struct armada_ovl_plane_properties {
-	uint32_t colorkey_yr;
-	uint32_t colorkey_ug;
-	uint32_t colorkey_vb;
-#define K2R(val) (((val) >> 0) & 0xff)
-#define K2G(val) (((val) >> 8) & 0xff)
-#define K2B(val) (((val) >> 16) & 0xff)
-	uint32_t colorkey_mode;
-	uint32_t colorkey_enable;
-};
-
 struct armada_ovl_plane {
 	struct armada_plane base;
 	struct armada_plane_work works[2];
 	bool next_work;
 	bool wait_vblank;
-	struct armada_ovl_plane_properties prop;
 };
 #define drm_to_armada_ovl_plane(p) \
 	container_of(p, struct armada_ovl_plane, base.base)
 
 struct armada_overlay_state {
 	struct drm_plane_state base;
+	u32 colorkey_yr;
+	u32 colorkey_ug;
+	u32 colorkey_vb;
+	u32 colorkey_mode;
+	u32 colorkey_enable;
 	s16 brightness;
 	u16 contrast;
 	u16 saturation;
@@ -66,25 +59,6 @@ static inline u32 armada_spu_saturation(struct drm_plane_state *state)
 	return drm_to_overlay_state(state)->saturation << 16;
 }
 
-static void
-armada_ovl_update_attr(struct armada_ovl_plane_properties *prop,
-	struct armada_crtc *dcrtc)
-{
-	writel_relaxed(prop->colorkey_yr, dcrtc->base + LCD_SPU_COLORKEY_Y);
-	writel_relaxed(prop->colorkey_ug, dcrtc->base + LCD_SPU_COLORKEY_U);
-	writel_relaxed(prop->colorkey_vb, dcrtc->base + LCD_SPU_COLORKEY_V);
-
-	spin_lock_irq(&dcrtc->irq_lock);
-	armada_updatel(prop->colorkey_mode,
-		       CFG_CKMODE_MASK | CFG_ALPHAM_MASK | CFG_ALPHA_MASK,
-		       dcrtc->base + LCD_SPU_DMA_CTRL1);
-	if (dcrtc->variant->has_spu_adv_reg)
-		armada_updatel(prop->colorkey_enable,
-			       ADV_GRACOLORKEY | ADV_VIDCOLORKEY,
-			       dcrtc->base + LCD_SPU_ADV_REG);
-	spin_unlock_irq(&dcrtc->irq_lock);
-}
-
 /* === Plane support === */
 static void armada_ovl_plane_work(struct armada_crtc *dcrtc,
 	struct armada_plane_work *work)
@@ -215,6 +189,30 @@ static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
 		armada_reg_queue_set(regs, idx, val, LCD_SPU_SATURATION);
 	if (!old_state->visible && state->visible)
 		armada_reg_queue_set(regs, idx, 0x00002000, LCD_SPU_CBSH_HUE);
+	val = drm_to_overlay_state(state)->colorkey_yr;
+	if ((!old_state->visible && state->visible) ||
+	    drm_to_overlay_state(old_state)->colorkey_yr != val)
+		armada_reg_queue_set(regs, idx, val, LCD_SPU_COLORKEY_Y);
+	val = drm_to_overlay_state(state)->colorkey_ug;
+	if ((!old_state->visible && state->visible) ||
+	    drm_to_overlay_state(old_state)->colorkey_ug != val)
+		armada_reg_queue_set(regs, idx, val, LCD_SPU_COLORKEY_U);
+	val = drm_to_overlay_state(state)->colorkey_vb;
+	if ((!old_state->visible && state->visible) ||
+	    drm_to_overlay_state(old_state)->colorkey_vb != val)
+		armada_reg_queue_set(regs, idx, val, LCD_SPU_COLORKEY_V);
+	val = drm_to_overlay_state(state)->colorkey_mode;
+	if ((!old_state->visible && state->visible) ||
+	    drm_to_overlay_state(old_state)->colorkey_mode != val)
+		armada_reg_queue_mod(regs, idx, val, CFG_CKMODE_MASK |
+				     CFG_ALPHAM_MASK | CFG_ALPHA_MASK,
+				     LCD_SPU_DMA_CTRL1);
+	val = drm_to_overlay_state(state)->colorkey_enable;
+	if (((!old_state->visible && state->visible) ||
+	     drm_to_overlay_state(old_state)->colorkey_enable != val) &&
+	    dcrtc->variant->has_spu_adv_reg)
+		armada_reg_queue_mod(regs, idx, val, ADV_GRACOLORKEY |
+				     ADV_VIDCOLORKEY, LCD_SPU_ADV_REG);
 
 	dcrtc->regs_idx += idx;
 }
@@ -314,10 +312,7 @@ static int armada_overlay_commit(struct drm_plane *plane,
 		goto put_state;
 	}
 
-	if (!dcrtc->plane) {
-		dcrtc->plane = plane;
-		armada_ovl_update_attr(&dplane->prop, dcrtc);
-	}
+	dcrtc->plane = plane;
 
 	/* Queue it for update on the next interrupt if we are enabled */
 	ret = armada_drm_plane_work_queue(dcrtc, work);
@@ -377,85 +372,20 @@ static void armada_ovl_plane_destroy(struct drm_plane *plane)
 static int armada_ovl_plane_set_property(struct drm_plane *plane,
 	struct drm_property *property, uint64_t val)
 {
-	struct armada_private *priv = plane->dev->dev_private;
-	struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
-	bool update_attr = false;
+	struct drm_plane_state *state;
+	int ret;
 
-	if (property == priv->colorkey_prop) {
-#define CCC(v) ((v) << 24 | (v) << 16 | (v) << 8)
-		dplane->prop.colorkey_yr = CCC(K2R(val));
-		dplane->prop.colorkey_ug = CCC(K2G(val));
-		dplane->prop.colorkey_vb = CCC(K2B(val));
-#undef CCC
-		update_attr = true;
-	} else if (property == priv->colorkey_min_prop) {
-		dplane->prop.colorkey_yr &= ~0x00ff0000;
-		dplane->prop.colorkey_yr |= K2R(val) << 16;
-		dplane->prop.colorkey_ug &= ~0x00ff0000;
-		dplane->prop.colorkey_ug |= K2G(val) << 16;
-		dplane->prop.colorkey_vb &= ~0x00ff0000;
-		dplane->prop.colorkey_vb |= K2B(val) << 16;
-		update_attr = true;
-	} else if (property == priv->colorkey_max_prop) {
-		dplane->prop.colorkey_yr &= ~0xff000000;
-		dplane->prop.colorkey_yr |= K2R(val) << 24;
-		dplane->prop.colorkey_ug &= ~0xff000000;
-		dplane->prop.colorkey_ug |= K2G(val) << 24;
-		dplane->prop.colorkey_vb &= ~0xff000000;
-		dplane->prop.colorkey_vb |= K2B(val) << 24;
-		update_attr = true;
-	} else if (property == priv->colorkey_val_prop) {
-		dplane->prop.colorkey_yr &= ~0x0000ff00;
-		dplane->prop.colorkey_yr |= K2R(val) << 8;
-		dplane->prop.colorkey_ug &= ~0x0000ff00;
-		dplane->prop.colorkey_ug |= K2G(val) << 8;
-		dplane->prop.colorkey_vb &= ~0x0000ff00;
-		dplane->prop.colorkey_vb |= K2B(val) << 8;
-		update_attr = true;
-	} else if (property == priv->colorkey_alpha_prop) {
-		dplane->prop.colorkey_yr &= ~0x000000ff;
-		dplane->prop.colorkey_yr |= K2R(val);
-		dplane->prop.colorkey_ug &= ~0x000000ff;
-		dplane->prop.colorkey_ug |= K2G(val);
-		dplane->prop.colorkey_vb &= ~0x000000ff;
-		dplane->prop.colorkey_vb |= K2B(val);
-		update_attr = true;
-	} else if (property == priv->colorkey_mode_prop) {
-		if (val == CKMODE_DISABLE) {
-			dplane->prop.colorkey_mode =
-				CFG_CKMODE(CKMODE_DISABLE) |
-				CFG_ALPHAM_CFG | CFG_ALPHA(255);
-			dplane->prop.colorkey_enable = 0;
-		} else {
-			dplane->prop.colorkey_mode =
-				CFG_CKMODE(val) |
-				CFG_ALPHAM_GRA | CFG_ALPHA(0);
-			dplane->prop.colorkey_enable = ADV_GRACOLORKEY;
-		}
-		update_attr = true;
-	} else {
-		struct drm_plane_state *state;
-		int ret;
-
-		state = plane->funcs->atomic_duplicate_state(plane);
-		if (!state)
-			return -ENOMEM;
-
-		ret = plane->funcs->atomic_set_property(plane, state, property,
-							val);
-		if (ret) {
-			plane->funcs->atomic_destroy_state(plane, state);
-			return ret;
-		}
+	state = plane->funcs->atomic_duplicate_state(plane);
+	if (!state)
+		return -ENOMEM;
 
-		return armada_overlay_commit(plane, state);
+	ret = plane->funcs->atomic_set_property(plane, state, property, val);
+	if (ret) {
+		plane->funcs->atomic_destroy_state(plane, state);
+		return ret;
 	}
 
-	if (update_attr && dplane->base.base.crtc)
-		armada_ovl_update_attr(&dplane->prop,
-				       drm_to_armada_crtc(dplane->base.base.crtc));
-
-	return 0;
+	return armada_overlay_commit(plane, state);
 }
 
 static void armada_overlay_reset(struct drm_plane *plane)
@@ -470,6 +400,12 @@ static void armada_overlay_reset(struct drm_plane *plane)
 	if (state) {
 		state->base.plane = plane;
 		state->base.rotation = DRM_MODE_ROTATE_0;
+		state->colorkey_yr = 0xfefefe00;
+		state->colorkey_ug = 0x01010100;
+		state->colorkey_vb = 0x01010100;
+		state->colorkey_mode = CFG_CKMODE(CKMODE_RGB) |
+				       CFG_ALPHAM_GRA | CFG_ALPHA(0);
+		state->colorkey_enable = ADV_GRACOLORKEY;
 		state->brightness = DEFAULT_BRIGHTNESS;
 		state->contrast = DEFAULT_CONTRAST;
 		state->saturation = DEFAULT_SATURATION;
@@ -497,7 +433,57 @@ static int armada_overlay_set_property(struct drm_plane *plane,
 {
 	struct armada_private *priv = plane->dev->dev_private;
 
-	if (property == priv->brightness_prop) {
+#define K2R(val) (((val) >> 0) & 0xff)
+#define K2G(val) (((val) >> 8) & 0xff)
+#define K2B(val) (((val) >> 16) & 0xff)
+	if (property == priv->colorkey_prop) {
+#define CCC(v) ((v) << 24 | (v) << 16 | (v) << 8)
+		drm_to_overlay_state(state)->colorkey_yr = CCC(K2R(val));
+		drm_to_overlay_state(state)->colorkey_ug = CCC(K2G(val));
+		drm_to_overlay_state(state)->colorkey_vb = CCC(K2B(val));
+#undef CCC
+	} else if (property == priv->colorkey_min_prop) {
+		drm_to_overlay_state(state)->colorkey_yr &= ~0x00ff0000;
+		drm_to_overlay_state(state)->colorkey_yr |= K2R(val) << 16;
+		drm_to_overlay_state(state)->colorkey_ug &= ~0x00ff0000;
+		drm_to_overlay_state(state)->colorkey_ug |= K2G(val) << 16;
+		drm_to_overlay_state(state)->colorkey_vb &= ~0x00ff0000;
+		drm_to_overlay_state(state)->colorkey_vb |= K2B(val) << 16;
+	} else if (property == priv->colorkey_max_prop) {
+		drm_to_overlay_state(state)->colorkey_yr &= ~0xff000000;
+		drm_to_overlay_state(state)->colorkey_yr |= K2R(val) << 24;
+		drm_to_overlay_state(state)->colorkey_ug &= ~0xff000000;
+		drm_to_overlay_state(state)->colorkey_ug |= K2G(val) << 24;
+		drm_to_overlay_state(state)->colorkey_vb &= ~0xff000000;
+		drm_to_overlay_state(state)->colorkey_vb |= K2B(val) << 24;
+	} else if (property == priv->colorkey_val_prop) {
+		drm_to_overlay_state(state)->colorkey_yr &= ~0x0000ff00;
+		drm_to_overlay_state(state)->colorkey_yr |= K2R(val) << 8;
+		drm_to_overlay_state(state)->colorkey_ug &= ~0x0000ff00;
+		drm_to_overlay_state(state)->colorkey_ug |= K2G(val) << 8;
+		drm_to_overlay_state(state)->colorkey_vb &= ~0x0000ff00;
+		drm_to_overlay_state(state)->colorkey_vb |= K2B(val) << 8;
+	} else if (property == priv->colorkey_alpha_prop) {
+		drm_to_overlay_state(state)->colorkey_yr &= ~0x000000ff;
+		drm_to_overlay_state(state)->colorkey_yr |= K2R(val);
+		drm_to_overlay_state(state)->colorkey_ug &= ~0x000000ff;
+		drm_to_overlay_state(state)->colorkey_ug |= K2G(val);
+		drm_to_overlay_state(state)->colorkey_vb &= ~0x000000ff;
+		drm_to_overlay_state(state)->colorkey_vb |= K2B(val);
+	} else if (property == priv->colorkey_mode_prop) {
+		if (val == CKMODE_DISABLE) {
+			drm_to_overlay_state(state)->colorkey_mode =
+				CFG_CKMODE(CKMODE_DISABLE) |
+				CFG_ALPHAM_CFG | CFG_ALPHA(255);
+			drm_to_overlay_state(state)->colorkey_enable = 0;
+		} else {
+			drm_to_overlay_state(state)->colorkey_mode =
+				CFG_CKMODE(val) |
+				CFG_ALPHAM_GRA | CFG_ALPHA(0);
+			drm_to_overlay_state(state)->colorkey_enable =
+				ADV_GRACOLORKEY;
+		}
+	} else if (property == priv->brightness_prop) {
 		drm_to_overlay_state(state)->brightness = val - 256;
 	} else if (property == priv->contrast_prop) {
 		drm_to_overlay_state(state)->contrast = val;
@@ -515,7 +501,41 @@ static int armada_overlay_get_property(struct drm_plane *plane,
 {
 	struct armada_private *priv = plane->dev->dev_private;
 
-	if (property == priv->brightness_prop) {
+#define C2K(c,s)	(((c) >> (s)) & 0xff)
+#define R2BGR(r,g,b,s)	(C2K(r,s) << 0 | C2K(g,s) << 8 | C2K(b,s) << 16)
+	if (property == priv->colorkey_prop) {
+		/* Do best-efforts here for this property */
+		*val = R2BGR(drm_to_overlay_state(state)->colorkey_yr,
+			     drm_to_overlay_state(state)->colorkey_ug,
+			     drm_to_overlay_state(state)->colorkey_vb, 16);
+		/* If min != max, or min != val, error out */
+		if (*val != R2BGR(drm_to_overlay_state(state)->colorkey_yr,
+				  drm_to_overlay_state(state)->colorkey_ug,
+				  drm_to_overlay_state(state)->colorkey_vb, 24) ||
+		    *val != R2BGR(drm_to_overlay_state(state)->colorkey_yr,
+				  drm_to_overlay_state(state)->colorkey_ug,
+				  drm_to_overlay_state(state)->colorkey_vb, 8))
+			return -EINVAL;
+	} else if (property == priv->colorkey_min_prop) {
+		*val = R2BGR(drm_to_overlay_state(state)->colorkey_yr,
+			     drm_to_overlay_state(state)->colorkey_ug,
+			     drm_to_overlay_state(state)->colorkey_vb, 16);
+	} else if (property == priv->colorkey_max_prop) {
+		*val = R2BGR(drm_to_overlay_state(state)->colorkey_yr,
+			     drm_to_overlay_state(state)->colorkey_ug,
+			     drm_to_overlay_state(state)->colorkey_vb, 24);
+	} else if (property == priv->colorkey_val_prop) {
+		*val = R2BGR(drm_to_overlay_state(state)->colorkey_yr,
+			     drm_to_overlay_state(state)->colorkey_ug,
+			     drm_to_overlay_state(state)->colorkey_vb, 8);
+	} else if (property == priv->colorkey_alpha_prop) {
+		*val = R2BGR(drm_to_overlay_state(state)->colorkey_yr,
+			     drm_to_overlay_state(state)->colorkey_ug,
+			     drm_to_overlay_state(state)->colorkey_vb, 0);
+	} else if (property == priv->colorkey_mode_prop) {
+		*val = (drm_to_overlay_state(state)->colorkey_mode &
+			CFG_CKMODE_MASK) >> ffs(CFG_CKMODE_MASK);
+	} else if (property == priv->brightness_prop) {
 		*val = drm_to_overlay_state(state)->brightness + 256;
 	} else if (property == priv->contrast_prop) {
 		*val = drm_to_overlay_state(state)->contrast;
@@ -645,13 +665,6 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 		return ret;
 	}
 
-	dplane->prop.colorkey_yr = 0xfefefe00;
-	dplane->prop.colorkey_ug = 0x01010100;
-	dplane->prop.colorkey_vb = 0x01010100;
-	dplane->prop.colorkey_mode = CFG_CKMODE(CKMODE_RGB) |
-				     CFG_ALPHAM_GRA | CFG_ALPHA(0);
-	dplane->prop.colorkey_enable = ADV_GRACOLORKEY;
-
 	mobj = &dplane->base.base.base;
 	drm_object_attach_property(mobj, priv->colorkey_prop,
 				   0x0101fe);
commit 61ba252705a6d5b8dd71bd2ccc544d33cb2af623
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: move CBSH properties into overlay plane state
    
    Move the contrast, brightness, and saturation properties to the overlay
    plane state structure, and call our overlay commit function to update
    the hardware via the planes atomic_update() method.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 73ddd7d61eb4..c27435a8776a 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -42,7 +42,7 @@ struct armada_plane_work {
 	struct drm_plane *plane;
 	struct drm_framebuffer *old_fb;
 	struct drm_pending_vblank_event *event;
-	struct armada_regs regs[14];
+	struct armada_regs regs[24];
 };
 
 struct armada_plane {
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 40868e485ae8..ec3ce28f162e 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -20,6 +20,10 @@
 #include "armada_plane.h"
 #include "armada_trace.h"
 
+#define DEFAULT_BRIGHTNESS	0
+#define DEFAULT_CONTRAST	0x4000
+#define DEFAULT_SATURATION	0x4000
+
 struct armada_ovl_plane_properties {
 	uint32_t colorkey_yr;
 	uint32_t colorkey_ug;
@@ -27,9 +31,6 @@ struct armada_ovl_plane_properties {
 #define K2R(val) (((val) >> 0) & 0xff)
 #define K2G(val) (((val) >> 8) & 0xff)
 #define K2B(val) (((val) >> 16) & 0xff)
-	int16_t  brightness;
-	uint16_t contrast;
-	uint16_t saturation;
 	uint32_t colorkey_mode;
 	uint32_t colorkey_enable;
 };
@@ -44,6 +45,26 @@ struct armada_ovl_plane {
 #define drm_to_armada_ovl_plane(p) \
 	container_of(p, struct armada_ovl_plane, base.base)
 
+struct armada_overlay_state {
+	struct drm_plane_state base;
+	s16 brightness;
+	u16 contrast;
+	u16 saturation;
+};
+#define drm_to_overlay_state(s) \
+	container_of(s, struct armada_overlay_state, base)
+
+static inline u32 armada_spu_contrast(struct drm_plane_state *state)
+{
+	return drm_to_overlay_state(state)->brightness << 16 |
+	       drm_to_overlay_state(state)->contrast;
+}
+
+static inline u32 armada_spu_saturation(struct drm_plane_state *state)
+{
+	/* Docs say 15:0, but it seems to actually be 31:16 on Armada 510 */
+	return drm_to_overlay_state(state)->saturation << 16;
+}
 
 static void
 armada_ovl_update_attr(struct armada_ovl_plane_properties *prop,
@@ -53,13 +74,6 @@ armada_ovl_update_attr(struct armada_ovl_plane_properties *prop,
 	writel_relaxed(prop->colorkey_ug, dcrtc->base + LCD_SPU_COLORKEY_U);
 	writel_relaxed(prop->colorkey_vb, dcrtc->base + LCD_SPU_COLORKEY_V);
 
-	writel_relaxed(prop->brightness << 16 | prop->contrast,
-		       dcrtc->base + LCD_SPU_CONTRAST);
-	/* Docs say 15:0, but it seems to actually be 31:16 on Armada 510 */
-	writel_relaxed(prop->saturation << 16,
-		       dcrtc->base + LCD_SPU_SATURATION);
-	writel_relaxed(0x00002000, dcrtc->base + LCD_SPU_CBSH_HUE);
-
 	spin_lock_irq(&dcrtc->irq_lock);
 	armada_updatel(prop->colorkey_mode,
 		       CFG_CKMODE_MASK | CFG_ALPHAM_MASK | CFG_ALPHA_MASK,
@@ -191,6 +205,17 @@ static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
 		armada_reg_queue_mod(regs, idx, cfg, cfg_mask,
 				     LCD_SPU_DMA_CTRL0);
 
+	val = armada_spu_contrast(state);
+	if ((!old_state->visible && state->visible) ||
+	    armada_spu_contrast(old_state) != val)
+		armada_reg_queue_set(regs, idx, val, LCD_SPU_CONTRAST);
+	val = armada_spu_saturation(state);
+	if ((!old_state->visible && state->visible) ||
+	    armada_spu_saturation(old_state) != val)
+		armada_reg_queue_set(regs, idx, val, LCD_SPU_SATURATION);
+	if (!old_state->visible && state->visible)
+		armada_reg_queue_set(regs, idx, 0x00002000, LCD_SPU_CBSH_HUE);
+
 	dcrtc->regs_idx += idx;
 }
 
@@ -264,6 +289,10 @@ static int armada_overlay_commit(struct drm_plane *plane,
 	/* Point of no return */
 	swap(plane->state, state);
 
+	/* No CRTC, can't update */
+	if (!plane->state->crtc)
+		goto put_state;
+
 	dcrtc->regs_idx = 0;
 	dcrtc->regs = work->regs;
 
@@ -300,7 +329,7 @@ static int armada_overlay_commit(struct drm_plane *plane,
 	dplane->next_work = !dplane->next_work;
 
 put_state:
-	drm_atomic_helper_plane_destroy_state(plane, state);
+	plane->funcs->atomic_destroy_state(plane, state);
 	return ret;
 }
 
@@ -318,7 +347,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
 				 src_x, src_y, src_w, src_h);
 
 	/* Construct new state for the overlay plane */
-	state = drm_atomic_helper_plane_duplicate_state(plane);
+	state = plane->funcs->atomic_duplicate_state(plane);
 	if (!state)
 		return -ENOMEM;
 
@@ -404,15 +433,22 @@ static int armada_ovl_plane_set_property(struct drm_plane *plane,
 			dplane->prop.colorkey_enable = ADV_GRACOLORKEY;
 		}
 		update_attr = true;
-	} else if (property == priv->brightness_prop) {
-		dplane->prop.brightness = val - 256;
-		update_attr = true;
-	} else if (property == priv->contrast_prop) {
-		dplane->prop.contrast = val;
-		update_attr = true;
-	} else if (property == priv->saturation_prop) {
-		dplane->prop.saturation = val;
-		update_attr = true;
+	} else {
+		struct drm_plane_state *state;
+		int ret;
+
+		state = plane->funcs->atomic_duplicate_state(plane);
+		if (!state)
+			return -ENOMEM;
+
+		ret = plane->funcs->atomic_set_property(plane, state, property,
+							val);
+		if (ret) {
+			plane->funcs->atomic_destroy_state(plane, state);
+			return ret;
+		}
+
+		return armada_overlay_commit(plane, state);
 	}
 
 	if (update_attr && dplane->base.base.crtc)
@@ -422,12 +458,85 @@ static int armada_ovl_plane_set_property(struct drm_plane *plane,
 	return 0;
 }
 
+static void armada_overlay_reset(struct drm_plane *plane)
+{
+	struct armada_overlay_state *state;
+
+	if (plane->state)
+		__drm_atomic_helper_plane_destroy_state(plane->state);
+	kfree(plane->state);
+
+	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	if (state) {
+		state->base.plane = plane;
+		state->base.rotation = DRM_MODE_ROTATE_0;
+		state->brightness = DEFAULT_BRIGHTNESS;
+		state->contrast = DEFAULT_CONTRAST;
+		state->saturation = DEFAULT_SATURATION;
+	}
+	plane->state = &state->base;
+}
+
+struct drm_plane_state *
+armada_overlay_duplicate_state(struct drm_plane *plane)
+{
+	struct armada_overlay_state *state;
+
+	if (WARN_ON(!plane->state))
+		return NULL;
+
+	state = kmemdup(plane->state, sizeof(*state), GFP_KERNEL);
+	if (state)
+		__drm_atomic_helper_plane_duplicate_state(plane, &state->base);
+	return &state->base;
+}
+
+static int armada_overlay_set_property(struct drm_plane *plane,
+	struct drm_plane_state *state, struct drm_property *property,
+	uint64_t val)
+{
+	struct armada_private *priv = plane->dev->dev_private;
+
+	if (property == priv->brightness_prop) {
+		drm_to_overlay_state(state)->brightness = val - 256;
+	} else if (property == priv->contrast_prop) {
+		drm_to_overlay_state(state)->contrast = val;
+	} else if (property == priv->saturation_prop) {
+		drm_to_overlay_state(state)->saturation = val;
+	} else {
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int armada_overlay_get_property(struct drm_plane *plane,
+	const struct drm_plane_state *state, struct drm_property *property,
+	uint64_t *val)
+{
+	struct armada_private *priv = plane->dev->dev_private;
+
+	if (property == priv->brightness_prop) {
+		*val = drm_to_overlay_state(state)->brightness + 256;
+	} else if (property == priv->contrast_prop) {
+		*val = drm_to_overlay_state(state)->contrast;
+	} else if (property == priv->saturation_prop) {
+		*val = drm_to_overlay_state(state)->saturation;
+	} else {
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static const struct drm_plane_funcs armada_ovl_plane_funcs = {
 	.update_plane	= armada_ovl_plane_update,
 	.disable_plane	= drm_plane_helper_disable,
 	.destroy	= armada_ovl_plane_destroy,
 	.set_property	= armada_ovl_plane_set_property,
-	.reset		= drm_atomic_helper_plane_reset,
+	.reset		= armada_overlay_reset,
+	.atomic_duplicate_state = armada_overlay_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+	.atomic_set_property = armada_overlay_set_property,
+	.atomic_get_property = armada_overlay_get_property,
 };
 
 static const uint32_t armada_ovl_formats[] = {
@@ -542,9 +651,6 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 	dplane->prop.colorkey_mode = CFG_CKMODE(CKMODE_RGB) |
 				     CFG_ALPHAM_GRA | CFG_ALPHA(0);
 	dplane->prop.colorkey_enable = ADV_GRACOLORKEY;
-	dplane->prop.brightness = 0;
-	dplane->prop.contrast = 0x4000;
-	dplane->prop.saturation = 0x4000;
 
 	mobj = &dplane->base.base.base;
 	drm_object_attach_property(mobj, priv->colorkey_prop,
@@ -559,11 +665,12 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 				   0x000000);
 	drm_object_attach_property(mobj, priv->colorkey_mode_prop,
 				   CKMODE_RGB);
-	drm_object_attach_property(mobj, priv->brightness_prop, 256);
+	drm_object_attach_property(mobj, priv->brightness_prop,
+				   256 + DEFAULT_BRIGHTNESS);
 	drm_object_attach_property(mobj, priv->contrast_prop,
-				   dplane->prop.contrast);
+				   DEFAULT_CONTRAST);
 	drm_object_attach_property(mobj, priv->saturation_prop,
-				   dplane->prop.saturation);
+				   DEFAULT_SATURATION);
 
 	return 0;
 }
commit 63b93c0834a0cb7d537b30f8e815a9f63d0da37f
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: move plane works to overlay
    
    Only overlay makes use of these now, so move these to the overlay code.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 2672c5cc0e45..73ddd7d61eb4 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -48,8 +48,6 @@ struct armada_plane_work {
 struct armada_plane {
 	struct drm_plane	base;
 	wait_queue_head_t	frame_wait;
-	bool			next_work;
-	struct armada_plane_work works[2];
 	struct armada_plane_work *work;
 };
 #define drm_to_armada_plane(p) container_of(p, struct armada_plane, base)
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 214b2171a8f4..40868e485ae8 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -36,6 +36,8 @@ struct armada_ovl_plane_properties {
 
 struct armada_ovl_plane {
 	struct armada_plane base;
+	struct armada_plane_work works[2];
+	bool next_work;
 	bool wait_vblank;
 	struct armada_ovl_plane_properties prop;
 };
@@ -245,7 +247,7 @@ static int armada_overlay_commit(struct drm_plane *plane,
 	if (ret)
 		goto put_state;
 
-	work = &dplane->base.works[dplane->base.next_work];
+	work = &dplane->works[dplane->next_work];
 
 	if (plane->state->fb != state->fb) {
 		/*
@@ -295,7 +297,7 @@ static int armada_overlay_commit(struct drm_plane *plane,
 		ret = 0;
 	}
 
-	dplane->base.next_work = !dplane->base.next_work;
+	dplane->next_work = !dplane->next_work;
 
 put_state:
 	drm_atomic_helper_plane_destroy_state(plane, state);
@@ -515,8 +517,10 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 		return ret;
 	}
 
-	dplane->base.works[0].fn = armada_ovl_plane_work;
-	dplane->base.works[1].fn = armada_ovl_plane_work;
+	dplane->works[0].plane = &dplane->base.base;
+	dplane->works[0].fn = armada_ovl_plane_work;
+	dplane->works[1].plane = &dplane->base.base;
+	dplane->works[1].fn = armada_ovl_plane_work;
 
 	drm_plane_helper_add(&dplane->base.base,
 			     &armada_overlay_plane_helper_funcs);
diff --git a/drivers/gpu/drm/armada/armada_plane.c b/drivers/gpu/drm/armada/armada_plane.c
index 9d1eec1dc720..1cb6a605bda9 100644
--- a/drivers/gpu/drm/armada/armada_plane.c
+++ b/drivers/gpu/drm/armada/armada_plane.c
@@ -264,13 +264,7 @@ static const struct drm_plane_funcs armada_primary_plane_funcs = {
 
 int armada_drm_plane_init(struct armada_plane *plane)
 {
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(plane->works); i++)
-		plane->works[i].plane = &plane->base;
-
 	init_waitqueue_head(&plane->frame_wait);
-
 	return 0;
 }
 
commit d40af7b1ae23da718ba916fcd07f5b064efff921
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: move primary plane to separate file
    
    Split out the primary plane support; this is now entirely separate from
    the CRTC support.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/Makefile b/drivers/gpu/drm/armada/Makefile
index ecf25cf9f9f5..9bc3c3213724 100644
--- a/drivers/gpu/drm/armada/Makefile
+++ b/drivers/gpu/drm/armada/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 armada-y	:= armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \
-		   armada_gem.o armada_overlay.o armada_trace.o
+		   armada_gem.o armada_overlay.o armada_plane.o armada_trace.o
 armada-y	+= armada_510.o
 armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o
 
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 14339d5bed14..b9b0a508793d 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -20,6 +20,7 @@
 #include "armada_fb.h"
 #include "armada_gem.h"
 #include "armada_hw.h"
+#include "armada_plane.h"
 #include "armada_trace.h"
 
 enum csc_mode {
@@ -30,23 +31,6 @@ enum csc_mode {
 	CSC_RGB_STUDIO = 2,
 };
 
-static const uint32_t armada_primary_formats[] = {
-	DRM_FORMAT_UYVY,
-	DRM_FORMAT_YUYV,
-	DRM_FORMAT_VYUY,
-	DRM_FORMAT_YVYU,
-	DRM_FORMAT_ARGB8888,
-	DRM_FORMAT_ABGR8888,
-	DRM_FORMAT_XRGB8888,
-	DRM_FORMAT_XBGR8888,
-	DRM_FORMAT_RGB888,
-	DRM_FORMAT_BGR888,
-	DRM_FORMAT_ARGB1555,
-	DRM_FORMAT_ABGR1555,
-	DRM_FORMAT_RGB565,
-	DRM_FORMAT_BGR565,
-};
-
 /*
  * A note about interlacing.  Let's consider HDMI 1920x1080i.
  * The timing parameters we have from X are:
@@ -160,57 +144,6 @@ static void armada_drm_crtc_update(struct armada_crtc *dcrtc)
 	}
 }
 
-void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb,
-	int x, int y)
-{
-	const struct drm_format_info *format = fb->format;
-	unsigned int num_planes = format->num_planes;
-	u32 addr = drm_fb_obj(fb)->dev_addr;
-	int i;
-
-	if (num_planes > 3)
-		num_planes = 3;
-
-	addrs[0] = addr + fb->offsets[0] + y * fb->pitches[0] +
-		   x * format->cpp[0];
-
-	y /= format->vsub;
-	x /= format->hsub;
-
-	for (i = 1; i < num_planes; i++)
-		addrs[i] = addr + fb->offsets[i] + y * fb->pitches[i] +
-			     x * format->cpp[i];
-	for (; i < 3; i++)
-		addrs[i] = 0;
-}
-
-static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb,
-	int x, int y, struct armada_regs *regs, bool interlaced)
-{
-	unsigned pitch = fb->pitches[0];
-	u32 addrs[3], addr_odd, addr_even;
-	unsigned i = 0;
-
-	DRM_DEBUG_DRIVER("pitch %u x %d y %d bpp %d\n",
-		pitch, x, y, fb->format->cpp[0] * 8);
-
-	armada_drm_plane_calc_addrs(addrs, fb, x, y);
-
-	addr_odd = addr_even = addrs[0];
-
-	if (interlaced) {
-		addr_even += pitch;
-		pitch *= 2;
-	}
-
-	/* write offset, base, and pitch */
-	armada_reg_queue_set(regs, i, addr_odd, LCD_CFG_GRA_START_ADDR0);
-	armada_reg_queue_set(regs, i, addr_even, LCD_CFG_GRA_START_ADDR1);
-	armada_reg_queue_mod(regs, i, pitch, 0xffff, LCD_CFG_GRA_PITCH);
-
-	return i;
-}
-
 static void armada_drm_plane_work_call(struct armada_crtc *dcrtc,
 	struct armada_plane_work *work,
 	void (*fn)(struct armada_crtc *, struct armada_plane_work *))
@@ -1067,194 +1000,6 @@ static const struct drm_crtc_funcs armada_crtc_funcs = {
 	.disable_vblank	= armada_drm_crtc_disable_vblank,
 };
 
-int armada_drm_plane_prepare_fb(struct drm_plane *plane,
-	struct drm_plane_state *state)
-{
-	DRM_DEBUG_KMS("[PLANE:%d:%s] [FB:%d]\n",
-		plane->base.id, plane->name,
-		state->fb ? state->fb->base.id : 0);
-
-	/*
-	 * Take a reference on the new framebuffer - we want to
-	 * hold on to it while the hardware is displaying it.
-	 */
-	if (state->fb)
-		drm_framebuffer_get(state->fb);
-	return 0;
-}
-
-void armada_drm_plane_cleanup_fb(struct drm_plane *plane,
-	struct drm_plane_state *old_state)
-{
-	DRM_DEBUG_KMS("[PLANE:%d:%s] [FB:%d]\n",
-		plane->base.id, plane->name,
-		old_state->fb ? old_state->fb->base.id : 0);
-
-	if (old_state->fb)
-		drm_framebuffer_put(old_state->fb);
-}
-
-int armada_drm_plane_atomic_check(struct drm_plane *plane,
-	struct drm_plane_state *state)
-{
-	if (state->fb && !WARN_ON(!state->crtc)) {
-		struct drm_crtc *crtc = state->crtc;
-		struct drm_crtc_state *crtc_state;
-
-		if (state->state)
-			crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc);
-		else
-			crtc_state = crtc->state;
-		return drm_atomic_helper_check_plane_state(state, crtc_state,
-							   0, INT_MAX,
-							   true, false);
-	} else {
-		state->visible = false;
-	}
-	return 0;
-}
-
-static void armada_drm_primary_plane_atomic_update(struct drm_plane *plane,
-	struct drm_plane_state *old_state)
-{
-	struct drm_plane_state *state = plane->state;
-	struct armada_crtc *dcrtc;
-	struct armada_regs *regs;
-	u32 cfg, cfg_mask, val;
-	unsigned int idx;
-
-	DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name);
-
-	if (!state->fb || WARN_ON(!state->crtc))
-		return;
-
-	DRM_DEBUG_KMS("[PLANE:%d:%s] is on [CRTC:%d:%s] with [FB:%d] visible %u->%u\n",
-		plane->base.id, plane->name,
-		state->crtc->base.id, state->crtc->name,
-		state->fb->base.id,
-		old_state->visible, state->visible);
-
-	dcrtc = drm_to_armada_crtc(state->crtc);
-	regs = dcrtc->regs + dcrtc->regs_idx;
-
-	idx = 0;
-	if (!old_state->visible && state->visible) {
-		val = CFG_PDWN64x66;
-		if (drm_fb_to_armada_fb(state->fb)->fmt > CFG_420)
-			val |= CFG_PDWN256x24;
-		armada_reg_queue_mod(regs, idx, 0, val, LCD_SPU_SRAM_PARA1);
-	}
-	val = armada_rect_hw_fp(&state->src);
-	if (armada_rect_hw_fp(&old_state->src) != val)
-		armada_reg_queue_set(regs, idx, val, LCD_SPU_GRA_HPXL_VLN);
-	val = armada_rect_yx(&state->dst);
-	if (armada_rect_yx(&old_state->dst) != val)
-		armada_reg_queue_set(regs, idx, val, LCD_SPU_GRA_OVSA_HPXL_VLN);
-	val = armada_rect_hw(&state->dst);
-	if (armada_rect_hw(&old_state->dst) != val)
-		armada_reg_queue_set(regs, idx, val, LCD_SPU_GZM_HPXL_VLN);
-	if (old_state->src.x1 != state->src.x1 ||
-	    old_state->src.y1 != state->src.y1 ||
-	    old_state->fb != state->fb) {
-		idx += armada_drm_crtc_calc_fb(state->fb,
-					       state->src.x1 >> 16,
-					       state->src.y1 >> 16,
-					       regs + idx,
-					       dcrtc->interlaced);
-	}
-	if (old_state->fb != state->fb) {
-		cfg = CFG_GRA_FMT(drm_fb_to_armada_fb(state->fb)->fmt) |
-		      CFG_GRA_MOD(drm_fb_to_armada_fb(state->fb)->mod);
-		if (drm_fb_to_armada_fb(state->fb)->fmt > CFG_420)
-			cfg |= CFG_PALETTE_ENA;
-		if (state->visible)
-			cfg |= CFG_GRA_ENA;
-		if (dcrtc->interlaced)
-			cfg |= CFG_GRA_FTOGGLE;
-		cfg_mask = CFG_GRAFORMAT |
-			   CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV |
-				       CFG_SWAPYU | CFG_YUV2RGB) |
-			   CFG_PALETTE_ENA | CFG_GRA_FTOGGLE |
-			   CFG_GRA_ENA;
-	} else if (old_state->visible != state->visible) {
-		cfg = state->visible ? CFG_GRA_ENA : 0;
-		cfg_mask = CFG_GRA_ENA;
-	} else {
-		cfg = cfg_mask = 0;
-	}
-	if (drm_rect_width(&old_state->src) != drm_rect_width(&state->src) ||
-	    drm_rect_width(&old_state->dst) != drm_rect_width(&state->dst)) {
-		cfg_mask |= CFG_GRA_HSMOOTH;
-		if (drm_rect_width(&state->src) >> 16 !=
-		    drm_rect_width(&state->dst))
-			cfg |= CFG_GRA_HSMOOTH;
-	}
-
-	if (cfg_mask)
-		armada_reg_queue_mod(regs, idx, cfg, cfg_mask,
-				     LCD_SPU_DMA_CTRL0);
-
-	dcrtc->regs_idx += idx;
-}
-
-static void armada_drm_primary_plane_atomic_disable(struct drm_plane *plane,
-	struct drm_plane_state *old_state)
-{
-	struct armada_crtc *dcrtc;
-	struct armada_regs *regs;
-	unsigned int idx = 0;
-
-	DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name);
-
-	if (!old_state->crtc)
-		return;
-
-	DRM_DEBUG_KMS("[PLANE:%d:%s] was on [CRTC:%d:%s] with [FB:%d]\n",
-		plane->base.id, plane->name,
-		old_state->crtc->base.id, old_state->crtc->name,
-		old_state->fb->base.id);
-
-	dcrtc = drm_to_armada_crtc(old_state->crtc);
-	regs = dcrtc->regs + dcrtc->regs_idx;
-
-	/* Disable plane and power down most RAMs and FIFOs */
-	armada_reg_queue_mod(regs, idx, 0, CFG_GRA_ENA, LCD_SPU_DMA_CTRL0);
-	armada_reg_queue_mod(regs, idx, CFG_PDWN256x32 | CFG_PDWN256x24 |
-			     CFG_PDWN256x8 | CFG_PDWN32x32 | CFG_PDWN64x66,
-			     0, LCD_SPU_SRAM_PARA1);
-
-	dcrtc->regs_idx += idx;
-}
-
-static const struct drm_plane_helper_funcs armada_primary_plane_helper_funcs = {
-	.prepare_fb	= armada_drm_plane_prepare_fb,
-	.cleanup_fb	= armada_drm_plane_cleanup_fb,
-	.atomic_check	= armada_drm_plane_atomic_check,
-	.atomic_update	= armada_drm_primary_plane_atomic_update,
-	.atomic_disable	= armada_drm_primary_plane_atomic_disable,
-};
-
-static const struct drm_plane_funcs armada_primary_plane_funcs = {
-	.update_plane	= drm_plane_helper_update,
-	.disable_plane	= drm_plane_helper_disable,
-	.destroy	= drm_primary_helper_destroy,
-	.reset		= drm_atomic_helper_plane_reset,
-	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
-	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
-};
-
-int armada_drm_plane_init(struct armada_plane *plane)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(plane->works); i++)
-		plane->works[i].plane = &plane->base;
-
-	init_waitqueue_head(&plane->frame_wait);
-
-	return 0;
-}
-
 static const struct drm_prop_enum_list armada_drm_csc_yuv_enum_list[] = {
 	{ CSC_AUTO,        "Auto" },
 	{ CSC_YUV_CCIR601, "CCIR601" },
@@ -1363,21 +1108,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 		goto err_crtc;
 	}
 
-	ret = armada_drm_plane_init(primary);
-	if (ret) {
-		kfree(primary);
-		goto err_crtc;
-	}
-
-	drm_plane_helper_add(&primary->base,
-			     &armada_primary_plane_helper_funcs);
-
-	ret = drm_universal_plane_init(drm, &primary->base, 0,
-				       &armada_primary_plane_funcs,
-				       armada_primary_formats,
-				       ARRAY_SIZE(armada_primary_formats),
-				       NULL,
-				       DRM_PLANE_TYPE_PRIMARY, NULL);
+	ret = armada_drm_primary_plane_init(drm, primary);
 	if (ret) {
 		kfree(primary);
 		goto err_crtc;
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 79ac0db047c9..2672c5cc0e45 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -54,21 +54,11 @@ struct armada_plane {
 };
 #define drm_to_armada_plane(p) container_of(p, struct armada_plane, base)
 
-int armada_drm_plane_init(struct armada_plane *plane);
 int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
 	struct armada_plane_work *work);
 int armada_drm_plane_work_wait(struct armada_plane *plane, long timeout);
 void armada_drm_plane_work_cancel(struct armada_crtc *dcrtc,
 	struct armada_plane *plane);
-void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb,
-	int x, int y);
-
-int armada_drm_plane_prepare_fb(struct drm_plane *plane,
-	struct drm_plane_state *state);
-void armada_drm_plane_cleanup_fb(struct drm_plane *plane,
-	struct drm_plane_state *old_state);
-int armada_drm_plane_atomic_check(struct drm_plane *plane,
-	struct drm_plane_state *state);
 
 struct armada_crtc {
 	struct drm_crtc		crtc;
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index aa2a12aec3cc..214b2171a8f4 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -10,13 +10,14 @@
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_plane_helper.h>
+#include <drm/armada_drm.h>
 #include "armada_crtc.h"
 #include "armada_drm.h"
 #include "armada_fb.h"
 #include "armada_gem.h"
 #include "armada_hw.h"
-#include <drm/armada_drm.h>
 #include "armada_ioctlP.h"
+#include "armada_plane.h"
 #include "armada_trace.h"
 
 struct armada_ovl_plane_properties {
diff --git a/drivers/gpu/drm/armada/armada_plane.c b/drivers/gpu/drm/armada/armada_plane.c
new file mode 100644
index 000000000000..9d1eec1dc720
--- /dev/null
+++ b/drivers/gpu/drm/armada/armada_plane.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2012 Russell King
+ *  Rewritten from the dovefb driver, and Armada510 manuals.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_plane_helper.h>
+#include "armada_crtc.h"
+#include "armada_drm.h"
+#include "armada_fb.h"
+#include "armada_gem.h"
+#include "armada_hw.h"
+#include "armada_plane.h"
+#include "armada_trace.h"
+
+static const uint32_t armada_primary_formats[] = {
+	DRM_FORMAT_UYVY,
+	DRM_FORMAT_YUYV,
+	DRM_FORMAT_VYUY,
+	DRM_FORMAT_YVYU,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_RGB888,
+	DRM_FORMAT_BGR888,
+	DRM_FORMAT_ARGB1555,
+	DRM_FORMAT_ABGR1555,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_BGR565,
+};
+
+void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb,
+	int x, int y)
+{
+	const struct drm_format_info *format = fb->format;
+	unsigned int num_planes = format->num_planes;
+	u32 addr = drm_fb_obj(fb)->dev_addr;
+	int i;
+
+	if (num_planes > 3)
+		num_planes = 3;
+
+	addrs[0] = addr + fb->offsets[0] + y * fb->pitches[0] +
+		   x * format->cpp[0];
+
+	y /= format->vsub;
+	x /= format->hsub;
+
+	for (i = 1; i < num_planes; i++)
+		addrs[i] = addr + fb->offsets[i] + y * fb->pitches[i] +
+			     x * format->cpp[i];
+	for (; i < 3; i++)
+		addrs[i] = 0;
+}
+
+static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb,
+	int x, int y, struct armada_regs *regs, bool interlaced)
+{
+	unsigned pitch = fb->pitches[0];
+	u32 addrs[3], addr_odd, addr_even;
+	unsigned i = 0;
+
+	DRM_DEBUG_DRIVER("pitch %u x %d y %d bpp %d\n",
+		pitch, x, y, fb->format->cpp[0] * 8);
+
+	armada_drm_plane_calc_addrs(addrs, fb, x, y);
+
+	addr_odd = addr_even = addrs[0];
+
+	if (interlaced) {
+		addr_even += pitch;
+		pitch *= 2;
+	}
+
+	/* write offset, base, and pitch */
+	armada_reg_queue_set(regs, i, addr_odd, LCD_CFG_GRA_START_ADDR0);
+	armada_reg_queue_set(regs, i, addr_even, LCD_CFG_GRA_START_ADDR1);
+	armada_reg_queue_mod(regs, i, pitch, 0xffff, LCD_CFG_GRA_PITCH);
+
+	return i;
+}
+
+int armada_drm_plane_prepare_fb(struct drm_plane *plane,
+	struct drm_plane_state *state)
+{
+	DRM_DEBUG_KMS("[PLANE:%d:%s] [FB:%d]\n",
+		plane->base.id, plane->name,
+		state->fb ? state->fb->base.id : 0);
+
+	/*
+	 * Take a reference on the new framebuffer - we want to
+	 * hold on to it while the hardware is displaying it.
+	 */
+	if (state->fb)
+		drm_framebuffer_get(state->fb);
+	return 0;
+}
+
+void armada_drm_plane_cleanup_fb(struct drm_plane *plane,
+	struct drm_plane_state *old_state)
+{
+	DRM_DEBUG_KMS("[PLANE:%d:%s] [FB:%d]\n",
+		plane->base.id, plane->name,
+		old_state->fb ? old_state->fb->base.id : 0);
+
+	if (old_state->fb)
+		drm_framebuffer_put(old_state->fb);
+}
+
+int armada_drm_plane_atomic_check(struct drm_plane *plane,
+	struct drm_plane_state *state)
+{
+	if (state->fb && !WARN_ON(!state->crtc)) {
+		struct drm_crtc *crtc = state->crtc;
+		struct drm_crtc_state *crtc_state;
+
+		if (state->state)
+			crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc);
+		else
+			crtc_state = crtc->state;
+		return drm_atomic_helper_check_plane_state(state, crtc_state,
+							   0, INT_MAX,
+							   true, false);
+	} else {
+		state->visible = false;
+	}
+	return 0;
+}
+
+static void armada_drm_primary_plane_atomic_update(struct drm_plane *plane,
+	struct drm_plane_state *old_state)
+{
+	struct drm_plane_state *state = plane->state;
+	struct armada_crtc *dcrtc;
+	struct armada_regs *regs;
+	u32 cfg, cfg_mask, val;
+	unsigned int idx;
+
+	DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name);
+
+	if (!state->fb || WARN_ON(!state->crtc))
+		return;
+
+	DRM_DEBUG_KMS("[PLANE:%d:%s] is on [CRTC:%d:%s] with [FB:%d] visible %u->%u\n",
+		plane->base.id, plane->name,
+		state->crtc->base.id, state->crtc->name,
+		state->fb->base.id,
+		old_state->visible, state->visible);
+
+	dcrtc = drm_to_armada_crtc(state->crtc);
+	regs = dcrtc->regs + dcrtc->regs_idx;
+
+	idx = 0;
+	if (!old_state->visible && state->visible) {
+		val = CFG_PDWN64x66;
+		if (drm_fb_to_armada_fb(state->fb)->fmt > CFG_420)
+			val |= CFG_PDWN256x24;
+		armada_reg_queue_mod(regs, idx, 0, val, LCD_SPU_SRAM_PARA1);
+	}
+	val = armada_rect_hw_fp(&state->src);
+	if (armada_rect_hw_fp(&old_state->src) != val)
+		armada_reg_queue_set(regs, idx, val, LCD_SPU_GRA_HPXL_VLN);
+	val = armada_rect_yx(&state->dst);
+	if (armada_rect_yx(&old_state->dst) != val)
+		armada_reg_queue_set(regs, idx, val, LCD_SPU_GRA_OVSA_HPXL_VLN);
+	val = armada_rect_hw(&state->dst);
+	if (armada_rect_hw(&old_state->dst) != val)
+		armada_reg_queue_set(regs, idx, val, LCD_SPU_GZM_HPXL_VLN);
+	if (old_state->src.x1 != state->src.x1 ||
+	    old_state->src.y1 != state->src.y1 ||
+	    old_state->fb != state->fb) {
+		idx += armada_drm_crtc_calc_fb(state->fb,
+					       state->src.x1 >> 16,
+					       state->src.y1 >> 16,
+					       regs + idx,
+					       dcrtc->interlaced);
+	}
+	if (old_state->fb != state->fb) {
+		cfg = CFG_GRA_FMT(drm_fb_to_armada_fb(state->fb)->fmt) |
+		      CFG_GRA_MOD(drm_fb_to_armada_fb(state->fb)->mod);
+		if (drm_fb_to_armada_fb(state->fb)->fmt > CFG_420)
+			cfg |= CFG_PALETTE_ENA;
+		if (state->visible)
+			cfg |= CFG_GRA_ENA;
+		if (dcrtc->interlaced)
+			cfg |= CFG_GRA_FTOGGLE;
+		cfg_mask = CFG_GRAFORMAT |
+			   CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV |
+				       CFG_SWAPYU | CFG_YUV2RGB) |
+			   CFG_PALETTE_ENA | CFG_GRA_FTOGGLE |
+			   CFG_GRA_ENA;
+	} else if (old_state->visible != state->visible) {
+		cfg = state->visible ? CFG_GRA_ENA : 0;
+		cfg_mask = CFG_GRA_ENA;
+	} else {
+		cfg = cfg_mask = 0;
+	}
+	if (drm_rect_width(&old_state->src) != drm_rect_width(&state->src) ||
+	    drm_rect_width(&old_state->dst) != drm_rect_width(&state->dst)) {
+		cfg_mask |= CFG_GRA_HSMOOTH;
+		if (drm_rect_width(&state->src) >> 16 !=
+		    drm_rect_width(&state->dst))
+			cfg |= CFG_GRA_HSMOOTH;
+	}
+
+	if (cfg_mask)
+		armada_reg_queue_mod(regs, idx, cfg, cfg_mask,
+				     LCD_SPU_DMA_CTRL0);
+
+	dcrtc->regs_idx += idx;
+}
+
+static void armada_drm_primary_plane_atomic_disable(struct drm_plane *plane,
+	struct drm_plane_state *old_state)
+{
+	struct armada_crtc *dcrtc;
+	struct armada_regs *regs;
+	unsigned int idx = 0;
+
+	DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name);
+
+	if (!old_state->crtc)
+		return;
+
+	DRM_DEBUG_KMS("[PLANE:%d:%s] was on [CRTC:%d:%s] with [FB:%d]\n",
+		plane->base.id, plane->name,
+		old_state->crtc->base.id, old_state->crtc->name,
+		old_state->fb->base.id);
+
+	dcrtc = drm_to_armada_crtc(old_state->crtc);
+	regs = dcrtc->regs + dcrtc->regs_idx;
+
+	/* Disable plane and power down most RAMs and FIFOs */
+	armada_reg_queue_mod(regs, idx, 0, CFG_GRA_ENA, LCD_SPU_DMA_CTRL0);
+	armada_reg_queue_mod(regs, idx, CFG_PDWN256x32 | CFG_PDWN256x24 |
+			     CFG_PDWN256x8 | CFG_PDWN32x32 | CFG_PDWN64x66,
+			     0, LCD_SPU_SRAM_PARA1);
+
+	dcrtc->regs_idx += idx;
+}
+
+static const struct drm_plane_helper_funcs armada_primary_plane_helper_funcs = {
+	.prepare_fb	= armada_drm_plane_prepare_fb,
+	.cleanup_fb	= armada_drm_plane_cleanup_fb,
+	.atomic_check	= armada_drm_plane_atomic_check,
+	.atomic_update	= armada_drm_primary_plane_atomic_update,
+	.atomic_disable	= armada_drm_primary_plane_atomic_disable,
+};
+
+static const struct drm_plane_funcs armada_primary_plane_funcs = {
+	.update_plane	= drm_plane_helper_update,
+	.disable_plane	= drm_plane_helper_disable,
+	.destroy	= drm_primary_helper_destroy,
+	.reset		= drm_atomic_helper_plane_reset,
+	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+};
+
+int armada_drm_plane_init(struct armada_plane *plane)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(plane->works); i++)
+		plane->works[i].plane = &plane->base;
+
+	init_waitqueue_head(&plane->frame_wait);
+
+	return 0;
+}
+
+int armada_drm_primary_plane_init(struct drm_device *drm,
+	struct armada_plane *primary)
+{
+	int ret;
+
+	ret = armada_drm_plane_init(primary);
+	if (ret)
+		return ret;
+
+	drm_plane_helper_add(&primary->base,
+			     &armada_primary_plane_helper_funcs);
+
+	ret = drm_universal_plane_init(drm, &primary->base, 0,
+				       &armada_primary_plane_funcs,
+				       armada_primary_formats,
+				       ARRAY_SIZE(armada_primary_formats),
+				       NULL,
+				       DRM_PLANE_TYPE_PRIMARY, NULL);
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/armada/armada_plane.h b/drivers/gpu/drm/armada/armada_plane.h
new file mode 100644
index 000000000000..3c8316003907
--- /dev/null
+++ b/drivers/gpu/drm/armada/armada_plane.h
@@ -0,0 +1,16 @@
+#ifndef ARMADA_PLANE_H
+#define ARMADA_PLANE_H
+
+void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb,
+	int x, int y);
+int armada_drm_plane_prepare_fb(struct drm_plane *plane,
+	struct drm_plane_state *state);
+void armada_drm_plane_cleanup_fb(struct drm_plane *plane,
+	struct drm_plane_state *old_state);
+int armada_drm_plane_atomic_check(struct drm_plane *plane,
+	struct drm_plane_state *state);
+int armada_drm_plane_init(struct armada_plane *plane);
+int armada_drm_primary_plane_init(struct drm_device *drm,
+	struct armada_plane *primary);
+
+#endif
commit 3acea7b9b62c282ea3d4d0cd156ca8e35dfa8a8c
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: use old_state for update tracking in atomic_update()
    
    Rather than tracking the register state, we can now check the previous
    state and decide which registers need updating from that since the old
    plane state indicates the previous state which was programmed into the
    hardware.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 056673911818..14339d5bed14 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -1114,64 +1114,14 @@ int armada_drm_plane_atomic_check(struct drm_plane *plane,
 	return 0;
 }
 
-static unsigned int armada_drm_primary_update_state(
-	struct drm_plane_state *state, struct armada_regs *regs)
-{
-	struct armada_plane *dplane = drm_to_armada_plane(state->plane);
-	struct armada_crtc *dcrtc = drm_to_armada_crtc(state->crtc);
-	struct armada_framebuffer *dfb = drm_fb_to_armada_fb(state->fb);
-	bool was_disabled;
-	unsigned int idx = 0;
-	u32 val;
-
-	val = CFG_GRA_FMT(dfb->fmt) | CFG_GRA_MOD(dfb->mod);
-	if (dfb->fmt > CFG_420)
-		val |= CFG_PALETTE_ENA;
-	if (state->visible)
-		val |= CFG_GRA_ENA;
-	if (drm_rect_width(&state->src) >> 16 != drm_rect_width(&state->dst))
-		val |= CFG_GRA_HSMOOTH;
-	if (dcrtc->interlaced)
-		val |= CFG_GRA_FTOGGLE;
-
-	was_disabled = !(dplane->state.ctrl0 & CFG_GRA_ENA);
-	if (was_disabled)
-		armada_reg_queue_mod(regs, idx,
-				     0, CFG_PDWN64x66, LCD_SPU_SRAM_PARA1);
-
-	dplane->state.ctrl0 = val;
-	dplane->state.src_hw = armada_rect_hw_fp(&state->src);
-	dplane->state.dst_hw = armada_rect_hw(&state->dst);
-	dplane->state.dst_yx = armada_rect_yx(&state->dst);
-
-	idx += armada_drm_crtc_calc_fb(&dfb->fb, state->src.x1 >> 16,
-				       state->src.y1 >> 16, regs + idx,
-				       dcrtc->interlaced);
-	armada_reg_queue_set(regs, idx, dplane->state.dst_yx,
-			     LCD_SPU_GRA_OVSA_HPXL_VLN);
-	armada_reg_queue_set(regs, idx, dplane->state.src_hw,
-			     LCD_SPU_GRA_HPXL_VLN);
-	armada_reg_queue_set(regs, idx, dplane->state.dst_hw,
-			     LCD_SPU_GZM_HPXL_VLN);
-	armada_reg_queue_mod(regs, idx, dplane->state.ctrl0, CFG_GRAFORMAT |
-			     CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV |
-					 CFG_SWAPYU | CFG_YUV2RGB) |
-			     CFG_PALETTE_ENA | CFG_GRA_FTOGGLE |
-			     CFG_GRA_HSMOOTH | CFG_GRA_ENA,
-			     LCD_SPU_DMA_CTRL0);
-
-	dplane->state.vsync_update = !was_disabled;
-	dplane->state.changed = true;
-
-	return idx;
-}
-
 static void armada_drm_primary_plane_atomic_update(struct drm_plane *plane,
 	struct drm_plane_state *old_state)
 {
 	struct drm_plane_state *state = plane->state;
 	struct armada_crtc *dcrtc;
 	struct armada_regs *regs;
+	u32 cfg, cfg_mask, val;
+	unsigned int idx;
 
 	DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name);
 
@@ -1187,13 +1137,69 @@ static void armada_drm_primary_plane_atomic_update(struct drm_plane *plane,
 	dcrtc = drm_to_armada_crtc(state->crtc);
 	regs = dcrtc->regs + dcrtc->regs_idx;
 
-	dcrtc->regs_idx += armada_drm_primary_update_state(state, regs);
+	idx = 0;
+	if (!old_state->visible && state->visible) {
+		val = CFG_PDWN64x66;
+		if (drm_fb_to_armada_fb(state->fb)->fmt > CFG_420)
+			val |= CFG_PDWN256x24;
+		armada_reg_queue_mod(regs, idx, 0, val, LCD_SPU_SRAM_PARA1);
+	}
+	val = armada_rect_hw_fp(&state->src);
+	if (armada_rect_hw_fp(&old_state->src) != val)
+		armada_reg_queue_set(regs, idx, val, LCD_SPU_GRA_HPXL_VLN);
+	val = armada_rect_yx(&state->dst);
+	if (armada_rect_yx(&old_state->dst) != val)
+		armada_reg_queue_set(regs, idx, val, LCD_SPU_GRA_OVSA_HPXL_VLN);
+	val = armada_rect_hw(&state->dst);
+	if (armada_rect_hw(&old_state->dst) != val)
+		armada_reg_queue_set(regs, idx, val, LCD_SPU_GZM_HPXL_VLN);
+	if (old_state->src.x1 != state->src.x1 ||
+	    old_state->src.y1 != state->src.y1 ||
+	    old_state->fb != state->fb) {
+		idx += armada_drm_crtc_calc_fb(state->fb,
+					       state->src.x1 >> 16,
+					       state->src.y1 >> 16,
+					       regs + idx,
+					       dcrtc->interlaced);
+	}
+	if (old_state->fb != state->fb) {
+		cfg = CFG_GRA_FMT(drm_fb_to_armada_fb(state->fb)->fmt) |
+		      CFG_GRA_MOD(drm_fb_to_armada_fb(state->fb)->mod);
+		if (drm_fb_to_armada_fb(state->fb)->fmt > CFG_420)
+			cfg |= CFG_PALETTE_ENA;
+		if (state->visible)
+			cfg |= CFG_GRA_ENA;
+		if (dcrtc->interlaced)
+			cfg |= CFG_GRA_FTOGGLE;
+		cfg_mask = CFG_GRAFORMAT |
+			   CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV |
+				       CFG_SWAPYU | CFG_YUV2RGB) |
+			   CFG_PALETTE_ENA | CFG_GRA_FTOGGLE |
+			   CFG_GRA_ENA;
+	} else if (old_state->visible != state->visible) {
+		cfg = state->visible ? CFG_GRA_ENA : 0;
+		cfg_mask = CFG_GRA_ENA;
+	} else {
+		cfg = cfg_mask = 0;
+	}
+	if (drm_rect_width(&old_state->src) != drm_rect_width(&state->src) ||
+	    drm_rect_width(&old_state->dst) != drm_rect_width(&state->dst)) {
+		cfg_mask |= CFG_GRA_HSMOOTH;
+		if (drm_rect_width(&state->src) >> 16 !=
+		    drm_rect_width(&state->dst))
+			cfg |= CFG_GRA_HSMOOTH;
+	}
+
+	if (cfg_mask)
+		armada_reg_queue_mod(regs, idx, cfg, cfg_mask,
+				     LCD_SPU_DMA_CTRL0);
+
+	dcrtc->regs_idx += idx;
 }
 
 static void armada_drm_primary_plane_atomic_disable(struct drm_plane *plane,
 	struct drm_plane_state *old_state)
 {
-	struct armada_plane *dplane = drm_to_armada_plane(plane);
 	struct armada_crtc *dcrtc;
 	struct armada_regs *regs;
 	unsigned int idx = 0;
@@ -1208,8 +1214,6 @@ static void armada_drm_primary_plane_atomic_disable(struct drm_plane *plane,
 		old_state->crtc->base.id, old_state->crtc->name,
 		old_state->fb->base.id);
 
-	dplane->state.ctrl0 &= ~CFG_GRA_ENA;
-
 	dcrtc = drm_to_armada_crtc(old_state->crtc);
 	regs = dcrtc->regs + dcrtc->regs_idx;
 
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 4da56a171b13..79ac0db047c9 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -45,24 +45,12 @@ struct armada_plane_work {
 	struct armada_regs regs[14];
 };
 
-struct armada_plane_state {
-	u16 src_x;
-	u16 src_y;
-	u32 src_hw;
-	u32 dst_hw;
-	u32 dst_yx;
-	u32 ctrl0;
-	bool changed;
-	bool vsync_update;
-};
-
 struct armada_plane {
 	struct drm_plane	base;
 	wait_queue_head_t	frame_wait;
 	bool			next_work;
 	struct armada_plane_work works[2];
 	struct armada_plane_work *work;
-	struct armada_plane_state state;
 };
 #define drm_to_armada_plane(p) container_of(p, struct armada_plane, base)
 
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index be9de5d85f9f..aa2a12aec3cc 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -35,6 +35,7 @@ struct armada_ovl_plane_properties {
 
 struct armada_ovl_plane {
 	struct armada_plane base;
+	bool wait_vblank;
 	struct armada_ovl_plane_properties prop;
 };
 #define drm_to_armada_ovl_plane(p) \
@@ -80,52 +81,55 @@ static void armada_ovl_plane_work(struct armada_crtc *dcrtc,
 	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
 }
 
-static unsigned int armada_ovl_plane_update_state(struct drm_plane_state *state,
-	struct armada_regs *regs)
+static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
+	struct drm_plane_state *old_state)
 {
-	struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(state->plane);
-	struct armada_framebuffer *dfb = drm_fb_to_armada_fb(state->fb);
-	const struct drm_format_info *format;
-	unsigned int idx = 0;
-	bool fb_changed;
-	u32 val, ctrl0;
-	u16 src_x, src_y;
-
-	ctrl0 = CFG_DMA_FMT(dfb->fmt) | CFG_DMA_MOD(dfb->mod) | CFG_CBSH_ENA;
-	if (state->visible)
-		ctrl0 |= CFG_DMA_ENA;
-	if (drm_rect_width(&state->src) >> 16 != drm_rect_width(&state->dst))
-		ctrl0 |= CFG_DMA_HSMOOTH;
-
-	/*
-	 * Shifting a YUV packed format image by one pixel causes the U/V
-	 * planes to swap.  Compensate for it by also toggling the UV swap.
-	 */
-	format = dfb->fb.format;
-	if (format->num_planes == 1 && state->src.x1 >> 16 & (format->hsub - 1))
-		ctrl0 ^= CFG_DMA_MOD(CFG_SWAPUV);
-
-	if (~dplane->base.state.ctrl0 & ctrl0 & CFG_DMA_ENA) {
-		/* Power up the Y/U/V FIFOs on ENA 0->1 transitions */
-		armada_reg_queue_mod(regs, idx,
-				     0, CFG_PDWN16x66 | CFG_PDWN32x66,
-				     LCD_SPU_SRAM_PARA1);
-	}
+	struct drm_plane_state *state = plane->state;
+	struct armada_crtc *dcrtc;
+	struct armada_regs *regs;
+	unsigned int idx;
+	u32 cfg, cfg_mask, val;
 
-	fb_changed = dplane->base.base.fb != &dfb->fb ||
-		     dplane->base.state.src_x != state->src.x1 >> 16 ||
-	             dplane->base.state.src_y != state->src.y1 >> 16;
+	DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name);
 
-	dplane->base.state.vsync_update = fb_changed;
+	if (!state->fb || WARN_ON(!state->crtc))
+		return;
 
+	DRM_DEBUG_KMS("[PLANE:%d:%s] is on [CRTC:%d:%s] with [FB:%d] visible %u->%u\n",
+		plane->base.id, plane->name,
+		state->crtc->base.id, state->crtc->name,
+		state->fb->base.id,
+		old_state->visible, state->visible);
+
+	dcrtc = drm_to_armada_crtc(state->crtc);
+	regs = dcrtc->regs + dcrtc->regs_idx;
+
+	drm_to_armada_ovl_plane(plane)->wait_vblank = false;
+
+	idx = 0;
+	if (!old_state->visible && state->visible)
+		armada_reg_queue_mod(regs, idx,
+				     0, CFG_PDWN16x66 | CFG_PDWN32x66,
+				     LCD_SPU_SRAM_PARA1);
+	val = armada_rect_hw_fp(&state->src);
+	if (armada_rect_hw_fp(&old_state->src) != val)
+		armada_reg_queue_set(regs, idx, val, LCD_SPU_DMA_HPXL_VLN);
+	val = armada_rect_yx(&state->dst);
+	if (armada_rect_yx(&old_state->dst) != val)
+		armada_reg_queue_set(regs, idx, val, LCD_SPU_DMA_OVSA_HPXL_VLN);
+	val = armada_rect_hw(&state->dst);
+	if (armada_rect_hw(&old_state->dst) != val)
+		armada_reg_queue_set(regs, idx, val, LCD_SPU_DZM_HPXL_VLN);
 	/* FIXME: overlay on an interlaced display */
-	if (fb_changed) {
+	if (old_state->src.x1 != state->src.x1 ||
+	    old_state->src.y1 != state->src.y1 ||
+	    old_state->fb != state->fb) {
+		const struct drm_format_info *format;
+		u16 src_x = state->src.x1 >> 16;
+		u16 src_y = state->src.y1 >> 16;
 		u32 addrs[3];
 
-		dplane->base.state.src_y = src_y = state->src.y1 >> 16;
-		dplane->base.state.src_x = src_x = state->src.x1 >> 16;
-
-		armada_drm_plane_calc_addrs(addrs, &dfb->fb, src_x, src_y);
+		armada_drm_plane_calc_addrs(addrs, state->fb, src_x, src_y);
 
 		armada_reg_queue_set(regs, idx, addrs[0],
 				     LCD_SPU_DMA_START_ADDR_Y0);
@@ -140,79 +144,56 @@ static unsigned int armada_ovl_plane_update_state(struct drm_plane_state *state,
 		armada_reg_queue_set(regs, idx, addrs[2],
 				     LCD_SPU_DMA_START_ADDR_V1);
 
-		val = dfb->fb.pitches[0] << 16 | dfb->fb.pitches[0];
-		armada_reg_queue_set(regs, idx, val,
-				     LCD_SPU_DMA_PITCH_YC);
-		val = dfb->fb.pitches[1] << 16 | dfb->fb.pitches[2];
-		armada_reg_queue_set(regs, idx, val,
-				     LCD_SPU_DMA_PITCH_UV);
-	}
-
-	val = armada_rect_hw_fp(&state->src);
-	if (dplane->base.state.src_hw != val) {
-		dplane->base.state.src_hw = val;
-		armada_reg_queue_set(regs, idx, val,
-				     LCD_SPU_DMA_HPXL_VLN);
-	}
+		val = state->fb->pitches[0] << 16 | state->fb->pitches[0];
+		armada_reg_queue_set(regs, idx, val, LCD_SPU_DMA_PITCH_YC);
+		val = state->fb->pitches[1] << 16 | state->fb->pitches[2];
+		armada_reg_queue_set(regs, idx, val, LCD_SPU_DMA_PITCH_UV);
 
-	val = armada_rect_hw(&state->dst);
-	if (dplane->base.state.dst_hw != val) {
-		dplane->base.state.dst_hw = val;
-		armada_reg_queue_set(regs, idx, val,
-				     LCD_SPU_DZM_HPXL_VLN);
-	}
+		cfg = CFG_DMA_FMT(drm_fb_to_armada_fb(state->fb)->fmt) |
+		      CFG_DMA_MOD(drm_fb_to_armada_fb(state->fb)->mod) |
+		      CFG_CBSH_ENA;
+		if (state->visible)
+			cfg |= CFG_DMA_ENA;
 
-	val = armada_rect_yx(&state->dst);
-	if (dplane->base.state.dst_yx != val) {
-		dplane->base.state.dst_yx = val;
-		armada_reg_queue_set(regs, idx, val,
-				     LCD_SPU_DMA_OVSA_HPXL_VLN);
+		/*
+		 * Shifting a YUV packed format image by one pixel causes the
+		 * U/V planes to swap.  Compensate for it by also toggling
+		 * the UV swap.
+		 */
+		format = state->fb->format;
+		if (format->num_planes == 1 && src_x & (format->hsub - 1))
+			cfg ^= CFG_DMA_MOD(CFG_SWAPUV);
+		cfg_mask = CFG_CBSH_ENA | CFG_DMAFORMAT |
+			   CFG_DMA_MOD(CFG_SWAPRB | CFG_SWAPUV |
+				       CFG_SWAPYU | CFG_YUV2RGB) |
+			   CFG_DMA_FTOGGLE | CFG_DMA_TSTMODE |
+			   CFG_DMA_ENA;
+
+		drm_to_armada_ovl_plane(plane)->wait_vblank = true;
+	} else if (old_state->visible != state->visible) {
+		cfg = state->visible ? CFG_DMA_ENA : 0;
+		cfg_mask = CFG_DMA_ENA;
+	} else {
+		cfg = cfg_mask = 0;
 	}
-
-	if (dplane->base.state.ctrl0 != ctrl0) {
-		dplane->base.state.ctrl0 = ctrl0;
-		armada_reg_queue_mod(regs, idx, ctrl0,
-			CFG_CBSH_ENA | CFG_DMAFORMAT | CFG_DMA_FTOGGLE |
-			CFG_DMA_HSMOOTH | CFG_DMA_TSTMODE |
-			CFG_DMA_MOD(CFG_SWAPRB | CFG_SWAPUV | CFG_SWAPYU |
-			CFG_YUV2RGB) | CFG_DMA_ENA,
-			LCD_SPU_DMA_CTRL0);
-		dplane->base.state.vsync_update = true;
+	if (drm_rect_width(&old_state->src) != drm_rect_width(&state->src) ||
+	    drm_rect_width(&old_state->dst) != drm_rect_width(&state->dst)) {
+		cfg_mask |= CFG_DMA_HSMOOTH;
+		if (drm_rect_width(&state->src) >> 16 !=
+		    drm_rect_width(&state->dst))
+			cfg |= CFG_DMA_HSMOOTH;
 	}
 
-	dplane->base.state.changed = idx != 0;
-
-	return idx;
-}
-
-static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
-	struct drm_plane_state *old_state)
-{
-	struct drm_plane_state *state = plane->state;
-	struct armada_crtc *dcrtc;
-	struct armada_regs *regs;
+	if (cfg_mask)
+		armada_reg_queue_mod(regs, idx, cfg, cfg_mask,
+				     LCD_SPU_DMA_CTRL0);
 
-	DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name);
-
-	if (!state->fb || WARN_ON(!state->crtc))
-		return;
-
-	DRM_DEBUG_KMS("[PLANE:%d:%s] is on [CRTC:%d:%s] with [FB:%d] visible %u->%u\n",
-		plane->base.id, plane->name,
-		state->crtc->base.id, state->crtc->name,
-		state->fb->base.id,
-		old_state->visible, state->visible);
-
-	dcrtc = drm_to_armada_crtc(state->crtc);
-	regs = dcrtc->regs + dcrtc->regs_idx;
-
-	dcrtc->regs_idx += armada_ovl_plane_update_state(state, regs);
+	dcrtc->regs_idx += idx;
 }
 
 static void armada_drm_overlay_plane_atomic_disable(struct drm_plane *plane,
 	struct drm_plane_state *old_state)
 {
-	struct armada_plane *dplane = drm_to_armada_plane(plane);
 	struct armada_crtc *dcrtc;
 	struct armada_regs *regs;
 	unsigned int idx = 0;
@@ -227,8 +208,6 @@ static void armada_drm_overlay_plane_atomic_disable(struct drm_plane *plane,
 		old_state->crtc->base.id, old_state->crtc->name,
 		old_state->fb->base.id);
 
-	dplane->state.ctrl0 &= ~CFG_DMA_ENA;
-
 	dcrtc = drm_to_armada_crtc(old_state->crtc);
 	regs = dcrtc->regs + dcrtc->regs_idx;
 
@@ -288,7 +267,7 @@ static int armada_overlay_commit(struct drm_plane *plane,
 	plane_funcs->atomic_update(plane, state);
 
 	/* If nothing was updated, short-circuit */
-	if (!dplane->base.state.changed)
+	if (dcrtc->regs_idx == 0)
 		goto put_state;
 
 	armada_reg_queue_end(dcrtc->regs, dcrtc->regs_idx);
@@ -298,7 +277,7 @@ static int armada_overlay_commit(struct drm_plane *plane,
 		armada_drm_plane_work_cancel(dcrtc, &dplane->base);
 
 	/* Just updating the position/size? */
-	if (!dplane->base.state.vsync_update) {
+	if (!dplane->wait_vblank) {
 		armada_ovl_plane_work(dcrtc, work);
 		goto put_state;
 	}
commit 9c41467c9aa5b3916ff559b8c2b3725d6290e5ec
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: remove temporary crtc state
    
    Now that we have the CRTC using the atomic modeset transitional helper,
    there is no need to build a temporary crtc state anymore - we can use
    the CRTC atomic state directly.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 5bb097b75b44..056673911818 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -1099,13 +1099,13 @@ int armada_drm_plane_atomic_check(struct drm_plane *plane,
 {
 	if (state->fb && !WARN_ON(!state->crtc)) {
 		struct drm_crtc *crtc = state->crtc;
-		struct drm_crtc_state crtc_state = {
-			.crtc = crtc,
-			.enable = crtc->enabled,
-			.mode = crtc->mode,
-		};
+		struct drm_crtc_state *crtc_state;
 
-		return drm_atomic_helper_check_plane_state(state, &crtc_state,
+		if (state->state)
+			crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc);
+		else
+			crtc_state = crtc->state;
+		return drm_atomic_helper_check_plane_state(state, crtc_state,
 							   0, INT_MAX,
 							   true, false);
 	} else {
commit 47dc413b0025e96eaa43bdd808233763e4080a10
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: convert overlay plane to atomic state
    
    The overlay plane support updates asynchronously to the request, but the
    drm_plane_helper_update() transitional helper waits for a vblank event
    before releasing the framebuffer.  Using the transitional helper would
    make the call block, which would introduce a performance regression.
    
    Convert the overlay plane update to use the atomic state structures and
    methods for the plane, but implement our own legacy update method
    rather than the transitional helper.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 50b34f5fc97b..5bb097b75b44 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -295,19 +295,6 @@ static void armada_drm_crtc_complete_frame_work(struct armada_crtc *dcrtc,
 	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
 }
 
-static void armada_drm_crtc_complete_disable_work(struct armada_crtc *dcrtc,
-	struct armada_plane_work *work)
-{
-	unsigned long flags;
-
-	if (dcrtc->plane == work->plane)
-		dcrtc->plane = NULL;
-
-	spin_lock_irqsave(&dcrtc->irq_lock, flags);
-	armada_drm_crtc_update_regs(dcrtc, work->regs);
-	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
-}
-
 static struct armada_plane_work *
 armada_drm_crtc_alloc_plane_work(struct drm_plane *plane)
 {
@@ -1080,7 +1067,7 @@ static const struct drm_crtc_funcs armada_crtc_funcs = {
 	.disable_vblank	= armada_drm_crtc_disable_vblank,
 };
 
-static int armada_drm_plane_prepare_fb(struct drm_plane *plane,
+int armada_drm_plane_prepare_fb(struct drm_plane *plane,
 	struct drm_plane_state *state)
 {
 	DRM_DEBUG_KMS("[PLANE:%d:%s] [FB:%d]\n",
@@ -1096,7 +1083,7 @@ static int armada_drm_plane_prepare_fb(struct drm_plane *plane,
 	return 0;
 }
 
-static void armada_drm_plane_cleanup_fb(struct drm_plane *plane,
+void armada_drm_plane_cleanup_fb(struct drm_plane *plane,
 	struct drm_plane_state *old_state)
 {
 	DRM_DEBUG_KMS("[PLANE:%d:%s] [FB:%d]\n",
@@ -1107,7 +1094,7 @@ static void armada_drm_plane_cleanup_fb(struct drm_plane *plane,
 		drm_framebuffer_put(old_state->fb);
 }
 
-static int armada_drm_plane_atomic_check(struct drm_plane *plane,
+int armada_drm_plane_atomic_check(struct drm_plane *plane,
 	struct drm_plane_state *state)
 {
 	if (state->fb && !WARN_ON(!state->crtc)) {
@@ -1243,66 +1230,6 @@ static const struct drm_plane_helper_funcs armada_primary_plane_helper_funcs = {
 	.atomic_disable	= armada_drm_primary_plane_atomic_disable,
 };
 
-int armada_drm_plane_disable(struct drm_plane *plane,
-			     struct drm_modeset_acquire_ctx *ctx)
-{
-	struct armada_plane *dplane = drm_to_armada_plane(plane);
-	struct armada_crtc *dcrtc;
-	struct armada_plane_work *work;
-	unsigned int idx = 0;
-	u32 sram_para1, enable_mask;
-
-	if (!plane->crtc)
-		return 0;
-
-	/*
-	 * Arrange to power down most RAMs and FIFOs if this is the primary
-	 * plane, otherwise just the YUV FIFOs for the overlay plane.
-	 */
-	if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
-		sram_para1 = CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 |
-			     CFG_PDWN32x32 | CFG_PDWN64x66;
-		enable_mask = CFG_GRA_ENA;
-	} else {
-		sram_para1 = CFG_PDWN16x66 | CFG_PDWN32x66;
-		enable_mask = CFG_DMA_ENA;
-	}
-
-	dplane->state.ctrl0 &= ~enable_mask;
-
-	dcrtc = drm_to_armada_crtc(plane->crtc);
-
-	/*
-	 * Try to disable the plane and drop our ref on the framebuffer
-	 * at the next frame update. If we fail for any reason, disable
-	 * the plane immediately.
-	 */
-	work = &dplane->works[dplane->next_work];
-	work->fn = armada_drm_crtc_complete_disable_work;
-	work->cancel = armada_drm_crtc_complete_disable_work;
-	work->old_fb = plane->fb;
-
-	armada_reg_queue_mod(work->regs, idx,
-			     0, enable_mask, LCD_SPU_DMA_CTRL0);
-	armada_reg_queue_mod(work->regs, idx,
-			     sram_para1, 0, LCD_SPU_SRAM_PARA1);
-	armada_reg_queue_end(work->regs, idx);
-
-	/* Wait for any preceding work to complete, but don't wedge */
-	if (WARN_ON(!armada_drm_plane_work_wait(dplane, HZ)))
-		armada_drm_plane_work_cancel(dcrtc, dplane);
-
-	if (armada_drm_plane_work_queue(dcrtc, work)) {
-		work->fn(dcrtc, work);
-		if (work->old_fb)
-			drm_framebuffer_unreference(work->old_fb);
-	}
-
-	dplane->next_work = !dplane->next_work;
-
-	return 0;
-}
-
 static const struct drm_plane_funcs armada_primary_plane_funcs = {
 	.update_plane	= drm_plane_helper_update,
 	.disable_plane	= drm_plane_helper_disable,
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 3253947e0d41..4da56a171b13 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -75,6 +75,13 @@ void armada_drm_plane_work_cancel(struct armada_crtc *dcrtc,
 void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb,
 	int x, int y);
 
+int armada_drm_plane_prepare_fb(struct drm_plane *plane,
+	struct drm_plane_state *state);
+void armada_drm_plane_cleanup_fb(struct drm_plane *plane,
+	struct drm_plane_state *old_state);
+int armada_drm_plane_atomic_check(struct drm_plane *plane,
+	struct drm_plane_state *state);
+
 struct armada_crtc {
 	struct drm_crtc		crtc;
 	const struct armada_variant *variant;
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 2347811ccf1b..be9de5d85f9f 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -7,7 +7,9 @@
  * published by the Free Software Foundation.
  */
 #include <drm/drmP.h>
+#include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
+#include <drm/drm_plane_helper.h>
 #include "armada_crtc.h"
 #include "armada_drm.h"
 #include "armada_fb.h"
@@ -78,7 +80,7 @@ static void armada_ovl_plane_work(struct armada_crtc *dcrtc,
 	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
 }
 
-static void armada_ovl_plane_update_state(struct drm_plane_state *state,
+static unsigned int armada_ovl_plane_update_state(struct drm_plane_state *state,
 	struct armada_regs *regs)
 {
 	struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(state->plane);
@@ -180,67 +182,116 @@ static void armada_ovl_plane_update_state(struct drm_plane_state *state,
 
 	dplane->base.state.changed = idx != 0;
 
-	armada_reg_queue_end(regs, idx);
+	return idx;
 }
 
-static int
-armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
-	struct drm_framebuffer *fb,
-	int crtc_x, int crtc_y, unsigned crtc_w, unsigned crtc_h,
-	uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h,
-	struct drm_modeset_acquire_ctx *ctx)
+static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
+	struct drm_plane_state *old_state)
+{
+	struct drm_plane_state *state = plane->state;
+	struct armada_crtc *dcrtc;
+	struct armada_regs *regs;
+
+	DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name);
+
+	if (!state->fb || WARN_ON(!state->crtc))
+		return;
+
+	DRM_DEBUG_KMS("[PLANE:%d:%s] is on [CRTC:%d:%s] with [FB:%d] visible %u->%u\n",
+		plane->base.id, plane->name,
+		state->crtc->base.id, state->crtc->name,
+		state->fb->base.id,
+		old_state->visible, state->visible);
+
+	dcrtc = drm_to_armada_crtc(state->crtc);
+	regs = dcrtc->regs + dcrtc->regs_idx;
+
+	dcrtc->regs_idx += armada_ovl_plane_update_state(state, regs);
+}
+
+static void armada_drm_overlay_plane_atomic_disable(struct drm_plane *plane,
+	struct drm_plane_state *old_state)
+{
+	struct armada_plane *dplane = drm_to_armada_plane(plane);
+	struct armada_crtc *dcrtc;
+	struct armada_regs *regs;
+	unsigned int idx = 0;
+
+	DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name);
+
+	if (!old_state->crtc)
+		return;
+
+	DRM_DEBUG_KMS("[PLANE:%d:%s] was on [CRTC:%d:%s] with [FB:%d]\n",
+		plane->base.id, plane->name,
+		old_state->crtc->base.id, old_state->crtc->name,
+		old_state->fb->base.id);
+
+	dplane->state.ctrl0 &= ~CFG_DMA_ENA;
+
+	dcrtc = drm_to_armada_crtc(old_state->crtc);
+	regs = dcrtc->regs + dcrtc->regs_idx;
+
+	/* Disable plane and power down the YUV FIFOs */
+	armada_reg_queue_mod(regs, idx, 0, CFG_DMA_ENA, LCD_SPU_DMA_CTRL0);
+	armada_reg_queue_mod(regs, idx, CFG_PDWN16x66 | CFG_PDWN32x66, 0,
+			     LCD_SPU_SRAM_PARA1);
+
+	dcrtc->regs_idx += idx;
+
+	if (dcrtc->plane == plane)
+		dcrtc->plane = NULL;
+}
+
+static const struct drm_plane_helper_funcs armada_overlay_plane_helper_funcs = {
+	.prepare_fb	= armada_drm_plane_prepare_fb,
+	.cleanup_fb	= armada_drm_plane_cleanup_fb,
+	.atomic_check	= armada_drm_plane_atomic_check,
+	.atomic_update	= armada_drm_overlay_plane_atomic_update,
+	.atomic_disable	= armada_drm_overlay_plane_atomic_disable,
+};
+
+static int armada_overlay_commit(struct drm_plane *plane,
+	struct drm_plane_state *state)
 {
 	struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
-	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
+	const struct drm_plane_helper_funcs *plane_funcs;
+	struct armada_crtc *dcrtc = drm_to_armada_crtc(state->crtc);
 	struct armada_plane_work *work;
-	struct drm_plane_state state = {
-		.plane = plane,
-		.crtc = crtc,
-		.fb = fb,
-		.src_x = src_x,
-		.src_y = src_y,
-		.src_w = src_w,
-		.src_h = src_h,
-		.crtc_x = crtc_x,
-		.crtc_y = crtc_y,
-		.crtc_w = crtc_w,
-		.crtc_h = crtc_h,
-		.rotation = DRM_MODE_ROTATE_0,
-	};
-	struct drm_crtc_state crtc_state = {
-		.crtc = crtc,
-		.enable = crtc->enabled,
-		.mode = crtc->mode,
-	};
 	int ret;
 
-	trace_armada_ovl_plane_update(plane, crtc, fb,
-				 crtc_x, crtc_y, crtc_w, crtc_h,
-				 src_x, src_y, src_w, src_h);
-
-	ret = drm_atomic_helper_check_plane_state(&state, &crtc_state, 0,
-						  INT_MAX, true, false);
+	plane_funcs = plane->helper_private;
+	ret = plane_funcs->atomic_check(plane, state);
 	if (ret)
-		return ret;
+		goto put_state;
 
 	work = &dplane->base.works[dplane->base.next_work];
 
-	if (plane->fb != fb) {
+	if (plane->state->fb != state->fb) {
 		/*
 		 * Take a reference on the new framebuffer - we want to
 		 * hold on to it while the hardware is displaying it.
 		 */
-		drm_framebuffer_reference(fb);
+		drm_framebuffer_reference(state->fb);
 
-		work->old_fb = plane->fb;
+		work->old_fb = plane->state->fb;
 	} else {
 		work->old_fb = NULL;
 	}
 
-	armada_ovl_plane_update_state(&state, work->regs);
+	/* Point of no return */
+	swap(plane->state, state);
+
+	dcrtc->regs_idx = 0;
+	dcrtc->regs = work->regs;
 
+	plane_funcs->atomic_update(plane, state);
+
+	/* If nothing was updated, short-circuit */
 	if (!dplane->base.state.changed)
-		return 0;
+		goto put_state;
+
+	armada_reg_queue_end(dcrtc->regs, dcrtc->regs_idx);
 
 	/* Wait for pending work to complete */
 	if (armada_drm_plane_work_wait(&dplane->base, HZ / 25) == 0)
@@ -249,7 +300,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
 	/* Just updating the position/size? */
 	if (!dplane->base.state.vsync_update) {
 		armada_ovl_plane_work(dcrtc, work);
-		return 0;
+		goto put_state;
 	}
 
 	if (!dcrtc->plane) {
@@ -259,12 +310,48 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
 
 	/* Queue it for update on the next interrupt if we are enabled */
 	ret = armada_drm_plane_work_queue(dcrtc, work);
-	if (ret)
+	if (ret) {
 		DRM_ERROR("failed to queue plane work: %d\n", ret);
+		ret = 0;
+	}
 
 	dplane->base.next_work = !dplane->base.next_work;
 
-	return 0;
+put_state:
+	drm_atomic_helper_plane_destroy_state(plane, state);
+	return ret;
+}
+
+static int
+armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
+	struct drm_framebuffer *fb,
+	int crtc_x, int crtc_y, unsigned crtc_w, unsigned crtc_h,
+	uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h,
+	struct drm_modeset_acquire_ctx *ctx)
+{
+	struct drm_plane_state *state;
+
+	trace_armada_ovl_plane_update(plane, crtc, fb,
+				 crtc_x, crtc_y, crtc_w, crtc_h,
+				 src_x, src_y, src_w, src_h);
+
+	/* Construct new state for the overlay plane */
+	state = drm_atomic_helper_plane_duplicate_state(plane);
+	if (!state)
+		return -ENOMEM;
+
+	state->crtc = crtc;
+	drm_atomic_set_fb_for_plane(state, fb);
+	state->crtc_x = crtc_x;
+	state->crtc_y = crtc_y;
+	state->crtc_h = crtc_h;
+	state->crtc_w = crtc_w;
+	state->src_x = src_x;
+	state->src_y = src_y;
+	state->src_h = src_h;
+	state->src_w = src_w;
+
+	return armada_overlay_commit(plane, state);
 }
 
 static void armada_ovl_plane_destroy(struct drm_plane *plane)
@@ -355,9 +442,10 @@ static int armada_ovl_plane_set_property(struct drm_plane *plane,
 
 static const struct drm_plane_funcs armada_ovl_plane_funcs = {
 	.update_plane	= armada_ovl_plane_update,
-	.disable_plane	= armada_drm_plane_disable,
+	.disable_plane	= drm_plane_helper_disable,
 	.destroy	= armada_ovl_plane_destroy,
 	.set_property	= armada_ovl_plane_set_property,
+	.reset		= drm_atomic_helper_plane_reset,
 };
 
 static const uint32_t armada_ovl_formats[] = {
@@ -450,6 +538,9 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 	dplane->base.works[0].fn = armada_ovl_plane_work;
 	dplane->base.works[1].fn = armada_ovl_plane_work;
 
+	drm_plane_helper_add(&dplane->base.base,
+			     &armada_overlay_plane_helper_funcs);
+
 	ret = drm_universal_plane_init(dev, &dplane->base.base, crtcs,
 				       &armada_ovl_plane_funcs,
 				       armada_ovl_formats,
commit de503ddff86ed31cde5ec5ea74ec7bf60d3fecc5
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: convert page_flip to use primary plane atomic_update()
    
    page_flip requests happen asynchronously, so we can't wait on the
    vblank event before returning to userspace, as the transitional plane
    update helper would do.  Craft our own implementation that keeps the
    asynchronous behaviour of this request, while making use of the atomic
    infrastructure for the primary plane update.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 523e0e8c6962..50b34f5fc97b 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -11,6 +11,7 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_plane_helper.h>
 #include <drm/drm_atomic_helper.h>
@@ -939,53 +940,81 @@ static void armada_drm_crtc_destroy(struct drm_crtc *crtc)
  * and a mode_set.
  */
 static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
-	struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, uint32_t page_flip_flags,
-	struct drm_modeset_acquire_ctx *ctx)
+	struct drm_framebuffer *fb, struct drm_pending_vblank_event *event,
+	uint32_t page_flip_flags, struct drm_modeset_acquire_ctx *ctx)
 {
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
+	struct drm_plane *plane = crtc->primary;
+	const struct drm_plane_helper_funcs *plane_funcs;
+	struct drm_plane_state *state;
 	struct armada_plane_work *work;
-	unsigned i;
 	int ret;
 
-	work = armada_drm_crtc_alloc_plane_work(dcrtc->crtc.primary);
-	if (!work)
+	/* Construct new state for the primary plane */
+	state = drm_atomic_helper_plane_duplicate_state(plane);
+	if (!state)
 		return -ENOMEM;
 
-	work->event = event;
-	work->old_fb = dcrtc->crtc.primary->fb;
+	drm_atomic_set_fb_for_plane(state, fb);
 
-	i = armada_drm_crtc_calc_fb(fb, crtc->x, crtc->y, work->regs,
-				    dcrtc->interlaced);
-	armada_reg_queue_end(work->regs, i);
+	work = armada_drm_crtc_alloc_plane_work(plane);
+	if (!work) {
+		ret = -ENOMEM;
+		goto put_state;
+	}
+
+	/* Make sure we can get vblank interrupts */
+	ret = drm_crtc_vblank_get(crtc);
+	if (ret)
+		goto put_work;
 
 	/*
-	 * Ensure that we hold a reference on the new framebuffer.
-	 * This has to match the behaviour in mode_set.
+	 * If we have another work pending, we can't process this flip.
+	 * The modeset locks protect us from another user queuing a work
+	 * while we're setting up.
 	 */
-	drm_framebuffer_get(fb);
-
-	ret = armada_drm_plane_work_queue(dcrtc, work);
-	if (ret) {
-		/* Undo our reference above */
-		drm_framebuffer_put(fb);
-		kfree(work);
-		return ret;
+	if (drm_to_armada_plane(plane)->work) {
+		ret = -EBUSY;
+		goto put_vblank;
 	}
 
+	work->event = event;
+	work->old_fb = plane->state->fb;
+
 	/*
-	 * We are in transition to atomic modeset: update the atomic modeset
-	 * state with the new framebuffer to keep the state consistent.
+	 * Hold a ref on the new fb while it's being displayed by the
+	 * hardware. The old fb refcount will be released in the worker.
 	 */
-	drm_framebuffer_assign(&dcrtc->crtc.primary->state->fb, fb);
+	drm_framebuffer_get(state->fb);
+
+	/* Point of no return */
+	swap(plane->state, state);
+
+	dcrtc->regs_idx = 0;
+	dcrtc->regs = work->regs;
+
+	plane_funcs = plane->helper_private;
+	plane_funcs->atomic_update(plane, state);
+	armada_reg_queue_end(dcrtc->regs, dcrtc->regs_idx);
+
+	/* Queue the work - this should never fail */
+	WARN_ON(armada_drm_plane_work_queue(dcrtc, work));
+	work = NULL;
 
 	/*
 	 * Finally, if the display is blanked, we won't receive an
 	 * interrupt, so complete it now.
 	 */
 	if (dpms_blanked(dcrtc->dpms))
-		armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary);
-
-	return 0;
+		armada_drm_plane_work_run(dcrtc, plane);
+
+put_vblank:
+	drm_crtc_vblank_put(crtc);
+put_work:
+	kfree(work);
+put_state:
+	drm_atomic_helper_plane_destroy_state(plane, state);
+	return ret;
 }
 
 static int
commit c36045e17a0e9206078a3254385bf9258e32d5b8
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: convert primary plane to atomic state
    
    Convert the primary plane as a whole to use its atomic state and the
    transitional helpers.  The CRTC is also switched to use the transitional
    helpers for mode_set() and mode_set_base().
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 735abdab9754..523e0e8c6962 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -325,38 +325,6 @@ armada_drm_crtc_alloc_plane_work(struct drm_plane *plane)
 	return work;
 }
 
-static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc,
-	struct drm_framebuffer *fb, bool force)
-{
-	struct armada_plane_work *work;
-
-	if (!fb)
-		return;
-
-	if (force) {
-		/* Display is disabled, so just drop the old fb */
-		drm_framebuffer_put(fb);
-		return;
-	}
-
-	work = armada_drm_crtc_alloc_plane_work(dcrtc->crtc.primary);
-	if (work) {
-		work->old_fb = fb;
-
-		if (armada_drm_plane_work_queue(dcrtc, work) == 0)
-			return;
-
-		kfree(work);
-	}
-
-	/*
-	 * Oops - just drop the reference immediately and hope for
-	 * the best.  The worst that will happen is the buffer gets
-	 * reused before it has finished being displayed.
-	 */
-	drm_framebuffer_put(fb);
-}
-
 static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
 {
 	/*
@@ -434,9 +402,6 @@ static void armada_drm_crtc_commit(struct drm_crtc *crtc)
 	dcrtc->dpms = DRM_MODE_DPMS_ON;
 	armada_drm_crtc_update(dcrtc);
 	drm_crtc_vblank_on(crtc);
-
-	if (dcrtc->old_modeset_fb)
-		armada_drm_crtc_finish_fb(dcrtc, dcrtc->old_modeset_fb, false);
 }
 
 /* The mode_config.mutex will be held for this call */
@@ -588,27 +553,16 @@ static uint32_t armada_drm_crtc_calculate_csc(struct armada_crtc *dcrtc)
 	return val;
 }
 
-static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
-	struct drm_framebuffer *old_fb);
-
 /* The mode_config.mutex will be held for this call */
-static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
-	struct drm_display_mode *mode, struct drm_display_mode *adj,
-	int x, int y, struct drm_framebuffer *old_fb)
+static void armada_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
+	struct drm_display_mode *adj = &crtc->state->adjusted_mode;
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
 	struct armada_regs regs[17];
 	uint32_t lm, rm, tm, bm, val, sclk;
 	unsigned long flags;
 	unsigned i;
-	bool interlaced;
-
-	/* Take a reference on the old fb for armada_drm_crtc_commit() */
-	if (old_fb)
-		drm_framebuffer_get(old_fb);
-	dcrtc->old_modeset_fb = old_fb;
-
-	interlaced = !!(adj->flags & DRM_MODE_FLAG_INTERLACE);
+	bool interlaced = !!(adj->flags & DRM_MODE_FLAG_INTERLACE);
 
 	i = 0;
 	rm = adj->crtc_hsync_start - adj->crtc_hdisplay;
@@ -692,35 +646,6 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
 
 	armada_drm_crtc_update_regs(dcrtc, regs);
 	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
-
-	return armada_drm_crtc_mode_set_base(crtc, x, y, old_fb);
-}
-
-static int armada_drm_do_primary_update(struct drm_plane *plane,
-	struct drm_plane_state *state, struct drm_framebuffer *old_fb);
-
-/* The mode_config.mutex will be held for this call */
-static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
-	struct drm_framebuffer *old_fb)
-{
-	struct drm_plane_state state = {
-		.plane = crtc->primary,
-		.crtc = crtc,
-		.fb = crtc->primary->fb,
-		.crtc_x = 0,
-		.crtc_y = 0,
-		.crtc_w = crtc->mode.hdisplay,
-		.crtc_h = crtc->mode.vdisplay,
-		.src_x = x << 16,
-		.src_y = y << 16,
-		.src_w = crtc->mode.hdisplay << 16,
-		.src_h = crtc->mode.vdisplay << 16,
-		.rotation = DRM_MODE_ROTATE_0,
-	};
-
-	armada_drm_do_primary_update(crtc->primary, &state, old_fb);
-
-	return 0;
 }
 
 /* The mode_config.mutex will be held for this call */
@@ -732,14 +657,49 @@ static void armada_drm_crtc_disable(struct drm_crtc *crtc)
 	crtc->primary->funcs->disable_plane(crtc->primary, NULL);
 }
 
+static void armada_drm_crtc_atomic_begin(struct drm_crtc *crtc,
+					 struct drm_crtc_state *old_crtc_state)
+{
+	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
+	struct armada_plane *dplane;
+
+	DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
+
+	/* Wait 100ms for any plane works to complete */
+	dplane = drm_to_armada_plane(crtc->primary);
+	if (WARN_ON(armada_drm_plane_work_wait(dplane, HZ / 10) == 0))
+		armada_drm_plane_work_cancel(dcrtc, dplane);
+
+	dcrtc->regs_idx = 0;
+	dcrtc->regs = dcrtc->atomic_regs;
+}
+
+static void armada_drm_crtc_atomic_flush(struct drm_crtc *crtc,
+					 struct drm_crtc_state *old_crtc_state)
+{
+	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
+	unsigned long flags;
+
+	DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
+
+	armada_reg_queue_end(dcrtc->regs, dcrtc->regs_idx);
+
+	spin_lock_irqsave(&dcrtc->irq_lock, flags);
+	armada_drm_crtc_update_regs(dcrtc, dcrtc->regs);
+	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
+}
+
 static const struct drm_crtc_helper_funcs armada_crtc_helper_funcs = {
 	.dpms		= armada_drm_crtc_dpms,
 	.prepare	= armada_drm_crtc_prepare,
 	.commit		= armada_drm_crtc_commit,
 	.mode_fixup	= armada_drm_crtc_mode_fixup,
-	.mode_set	= armada_drm_crtc_mode_set,
-	.mode_set_base	= armada_drm_crtc_mode_set_base,
+	.mode_set	= drm_helper_crtc_mode_set,
+	.mode_set_nofb	= armada_drm_crtc_mode_set_nofb,
+	.mode_set_base	= drm_helper_crtc_mode_set_base,
 	.disable	= armada_drm_crtc_disable,
+	.atomic_begin	= armada_drm_crtc_atomic_begin,
+	.atomic_flush	= armada_drm_crtc_atomic_flush,
 };
 
 static void armada_load_cursor_argb(void __iomem *base, uint32_t *pix,
@@ -1013,6 +973,12 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
 	}
 
 	/*
+	 * We are in transition to atomic modeset: update the atomic modeset
+	 * state with the new framebuffer to keep the state consistent.
+	 */
+	drm_framebuffer_assign(&dcrtc->crtc.primary->state->fb, fb);
+
+	/*
 	 * Finally, if the display is blanked, we won't receive an
 	 * interrupt, so complete it now.
 	 */
@@ -1072,16 +1038,66 @@ static void armada_drm_crtc_disable_vblank(struct drm_crtc *crtc)
 }
 
 static const struct drm_crtc_funcs armada_crtc_funcs = {
+	.reset		= drm_atomic_helper_crtc_reset,
 	.cursor_set	= armada_drm_crtc_cursor_set,
 	.cursor_move	= armada_drm_crtc_cursor_move,
 	.destroy	= armada_drm_crtc_destroy,
 	.set_config	= drm_crtc_helper_set_config,
 	.page_flip	= armada_drm_crtc_page_flip,
 	.set_property	= armada_drm_crtc_set_property,
+	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 	.enable_vblank	= armada_drm_crtc_enable_vblank,
 	.disable_vblank	= armada_drm_crtc_disable_vblank,
 };
 
+static int armada_drm_plane_prepare_fb(struct drm_plane *plane,
+	struct drm_plane_state *state)
+{
+	DRM_DEBUG_KMS("[PLANE:%d:%s] [FB:%d]\n",
+		plane->base.id, plane->name,
+		state->fb ? state->fb->base.id : 0);
+
+	/*
+	 * Take a reference on the new framebuffer - we want to
+	 * hold on to it while the hardware is displaying it.
+	 */
+	if (state->fb)
+		drm_framebuffer_get(state->fb);
+	return 0;
+}
+
+static void armada_drm_plane_cleanup_fb(struct drm_plane *plane,
+	struct drm_plane_state *old_state)
+{
+	DRM_DEBUG_KMS("[PLANE:%d:%s] [FB:%d]\n",
+		plane->base.id, plane->name,
+		old_state->fb ? old_state->fb->base.id : 0);
+
+	if (old_state->fb)
+		drm_framebuffer_put(old_state->fb);
+}
+
+static int armada_drm_plane_atomic_check(struct drm_plane *plane,
+	struct drm_plane_state *state)
+{
+	if (state->fb && !WARN_ON(!state->crtc)) {
+		struct drm_crtc *crtc = state->crtc;
+		struct drm_crtc_state crtc_state = {
+			.crtc = crtc,
+			.enable = crtc->enabled,
+			.mode = crtc->mode,
+		};
+
+		return drm_atomic_helper_check_plane_state(state, &crtc_state,
+							   0, INT_MAX,
+							   true, false);
+	} else {
+		state->visible = false;
+	}
+	return 0;
+}
+
 static unsigned int armada_drm_primary_update_state(
 	struct drm_plane_state *state, struct armada_regs *regs)
 {
@@ -1134,94 +1150,70 @@ static unsigned int armada_drm_primary_update_state(
 	return idx;
 }
 
-static int armada_drm_do_primary_update(struct drm_plane *plane,
-	struct drm_plane_state *state, struct drm_framebuffer *old_fb)
+static void armada_drm_primary_plane_atomic_update(struct drm_plane *plane,
+	struct drm_plane_state *old_state)
 {
-	struct armada_plane *dplane = drm_to_armada_plane(plane);
-	struct armada_crtc *dcrtc = drm_to_armada_crtc(state->crtc);
-	struct armada_plane_work *work;
-	struct drm_crtc_state crtc_state = {
-		.crtc = state->crtc,
-		.enable = state->crtc->enabled,
-		.mode = state->crtc->mode,
-	};
-	unsigned int idx;
-	int ret;
+	struct drm_plane_state *state = plane->state;
+	struct armada_crtc *dcrtc;
+	struct armada_regs *regs;
 
-	ret = drm_atomic_helper_check_plane_state(state, &crtc_state, 0,
-						  INT_MAX, true, false);
-	if (ret)
-		return ret;
+	DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name);
 
-	work = &dplane->works[dplane->next_work];
-	work->fn = armada_drm_crtc_complete_frame_work;
+	if (!state->fb || WARN_ON(!state->crtc))
+		return;
 
-	if (old_fb != state->fb) {
-		/*
-		 * Take a reference on the new framebuffer - we want to
-		 * hold on to it while the hardware is displaying it.
-		 */
-		drm_framebuffer_reference(state->fb);
+	DRM_DEBUG_KMS("[PLANE:%d:%s] is on [CRTC:%d:%s] with [FB:%d] visible %u->%u\n",
+		plane->base.id, plane->name,
+		state->crtc->base.id, state->crtc->name,
+		state->fb->base.id,
+		old_state->visible, state->visible);
 
-		work->old_fb = old_fb;
-	} else {
-		work->old_fb = NULL;
-	}
+	dcrtc = drm_to_armada_crtc(state->crtc);
+	regs = dcrtc->regs + dcrtc->regs_idx;
 
-	idx = armada_drm_primary_update_state(state, work->regs);
-	armada_reg_queue_end(work->regs, idx);
+	dcrtc->regs_idx += armada_drm_primary_update_state(state, regs);
+}
 
-	if (!dplane->state.changed)
-		return 0;
+static void armada_drm_primary_plane_atomic_disable(struct drm_plane *plane,
+	struct drm_plane_state *old_state)
+{
+	struct armada_plane *dplane = drm_to_armada_plane(plane);
+	struct armada_crtc *dcrtc;
+	struct armada_regs *regs;
+	unsigned int idx = 0;
 
-	/* Wait for pending work to complete */
-	if (armada_drm_plane_work_wait(dplane, HZ / 10) == 0)
-		armada_drm_plane_work_cancel(dcrtc, dplane);
+	DRM_DEBUG_KMS("[PLANE:%d:%s]\n", plane->base.id, plane->name);
 
-	if (!dplane->state.vsync_update) {
-		work->fn(dcrtc, work);
-		if (work->old_fb)
-			drm_framebuffer_unreference(work->old_fb);
-		return 0;
-	}
+	if (!old_state->crtc)
+		return;
 
-	/* Queue it for update on the next interrupt if we are enabled */
-	ret = armada_drm_plane_work_queue(dcrtc, work);
-	if (ret) {
-		work->fn(dcrtc, work);
-		if (work->old_fb)
-			drm_framebuffer_unreference(work->old_fb);
-	}
+	DRM_DEBUG_KMS("[PLANE:%d:%s] was on [CRTC:%d:%s] with [FB:%d]\n",
+		plane->base.id, plane->name,
+		old_state->crtc->base.id, old_state->crtc->name,
+		old_state->fb->base.id);
 
-	dplane->next_work = !dplane->next_work;
+	dplane->state.ctrl0 &= ~CFG_GRA_ENA;
 
-	return 0;
-}
+	dcrtc = drm_to_armada_crtc(old_state->crtc);
+	regs = dcrtc->regs + dcrtc->regs_idx;
 
-static int armada_drm_primary_update(struct drm_plane *plane,
-	struct drm_crtc *crtc, struct drm_framebuffer *fb,
-	int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h,
-	uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h,
-	struct drm_modeset_acquire_ctx *ctx)
-{
-	struct drm_plane_state state = {
-		.plane = plane,
-		.crtc = crtc,
-		.fb = fb,
-		.src_x = src_x,
-		.src_y = src_y,
-		.src_w = src_w,
-		.src_h = src_h,
-		.crtc_x = crtc_x,
-		.crtc_y = crtc_y,
-		.crtc_w = crtc_w,
-		.crtc_h = crtc_h,
-		.rotation = DRM_MODE_ROTATE_0,
-	};
-
-	return armada_drm_do_primary_update(plane, &state, plane->fb);
+	/* Disable plane and power down most RAMs and FIFOs */
+	armada_reg_queue_mod(regs, idx, 0, CFG_GRA_ENA, LCD_SPU_DMA_CTRL0);
+	armada_reg_queue_mod(regs, idx, CFG_PDWN256x32 | CFG_PDWN256x24 |
+			     CFG_PDWN256x8 | CFG_PDWN32x32 | CFG_PDWN64x66,
+			     0, LCD_SPU_SRAM_PARA1);
+
+	dcrtc->regs_idx += idx;
 }
 
+static const struct drm_plane_helper_funcs armada_primary_plane_helper_funcs = {
+	.prepare_fb	= armada_drm_plane_prepare_fb,
+	.cleanup_fb	= armada_drm_plane_cleanup_fb,
+	.atomic_check	= armada_drm_plane_atomic_check,
+	.atomic_update	= armada_drm_primary_plane_atomic_update,
+	.atomic_disable	= armada_drm_primary_plane_atomic_disable,
+};
+
 int armada_drm_plane_disable(struct drm_plane *plane,
 			     struct drm_modeset_acquire_ctx *ctx)
 {
@@ -1283,9 +1275,12 @@ int armada_drm_plane_disable(struct drm_plane *plane,
 }
 
 static const struct drm_plane_funcs armada_primary_plane_funcs = {
-	.update_plane	= armada_drm_primary_update,
-	.disable_plane	= armada_drm_plane_disable,
+	.update_plane	= drm_plane_helper_update,
+	.disable_plane	= drm_plane_helper_disable,
 	.destroy	= drm_primary_helper_destroy,
+	.reset		= drm_atomic_helper_plane_reset,
+	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 };
 
 int armada_drm_plane_init(struct armada_plane *plane)
@@ -1414,6 +1409,9 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 		goto err_crtc;
 	}
 
+	drm_plane_helper_add(&primary->base,
+			     &armada_primary_plane_helper_funcs);
+
 	ret = drm_universal_plane_init(drm, &primary->base, 0,
 				       &armada_primary_plane_funcs,
 				       armada_primary_formats,
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 8edcfd1fa75f..3253947e0d41 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -93,7 +93,6 @@ struct armada_crtc {
 	uint8_t			csc_rgb_mode;
 
 	struct drm_plane	*plane;
-	struct drm_framebuffer	*old_modeset_fb;
 
 	struct armada_gem_object	*cursor_obj;
 	int			cursor_x;
@@ -110,14 +109,15 @@ struct armada_crtc {
 
 	spinlock_t		irq_lock;
 	uint32_t		irq_ena;
+
+	struct armada_regs	atomic_regs[32];
+	struct armada_regs	*regs;
+	unsigned int		regs_idx;
 };
 #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
 
 void armada_drm_crtc_update_regs(struct armada_crtc *, struct armada_regs *);
 
-int armada_drm_plane_disable(struct drm_plane *plane,
-			     struct drm_modeset_acquire_ctx *ctx);
-
 extern struct platform_driver armada_lcd_platform_driver;
 
 #endif
commit 80c63aee8143d83743a9df6d09309d3d15b20680
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: reset all atomic state during driver initialisation
    
    Reset the atomic state of any converted components during driver
    initialisation to ensure that we have the atomic state initialised for
    any component converted to atomic modeset.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index d1705d298a39..e47b995b4ce6 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -155,6 +155,8 @@ static int armada_drm_bind(struct device *dev)
 
 	priv->drm.irq_enabled = true;
 
+	drm_mode_config_reset(&priv->drm);
+
 	ret = armada_fbdev_init(&priv->drm);
 	if (ret)
 		goto err_comp;
commit ecf25d2380313139a2cc5f07e7ac2d910054b478
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: merge armada_drm_gra_plane_regs() into only caller
    
    armada_drm_gra_plane_regs() is now only ever called from within
    armada_drm_primary_update_state(), so merge it into this function.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 6dd54f1d3ac9..735abdab9754 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -588,31 +588,6 @@ static uint32_t armada_drm_crtc_calculate_csc(struct armada_crtc *dcrtc)
 	return val;
 }
 
-static void armada_drm_gra_plane_regs(struct armada_regs *regs,
-	struct drm_framebuffer *fb, struct armada_plane_state *state,
-	int x, int y, bool interlaced)
-{
-	unsigned int i;
-	u32 ctrl0;
-
-	i = armada_drm_crtc_calc_fb(fb, x, y, regs, interlaced);
-	armada_reg_queue_set(regs, i, state->dst_yx, LCD_SPU_GRA_OVSA_HPXL_VLN);
-	armada_reg_queue_set(regs, i, state->src_hw, LCD_SPU_GRA_HPXL_VLN);
-	armada_reg_queue_set(regs, i, state->dst_hw, LCD_SPU_GZM_HPXL_VLN);
-
-	ctrl0 = state->ctrl0;
-	if (interlaced)
-		ctrl0 |= CFG_GRA_FTOGGLE;
-
-	armada_reg_queue_mod(regs, i, ctrl0, CFG_GRAFORMAT |
-			     CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV |
-					 CFG_SWAPYU | CFG_YUV2RGB) |
-			     CFG_PALETTE_ENA | CFG_GRA_FTOGGLE |
-			     CFG_GRA_HSMOOTH | CFG_GRA_ENA,
-			     LCD_SPU_DMA_CTRL0);
-	armada_reg_queue_end(regs, i);
-}
-
 static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 	struct drm_framebuffer *old_fb);
 
@@ -1107,8 +1082,8 @@ static const struct drm_crtc_funcs armada_crtc_funcs = {
 	.disable_vblank	= armada_drm_crtc_disable_vblank,
 };
 
-static void armada_drm_primary_update_state(struct drm_plane_state *state,
-	struct armada_regs *regs)
+static unsigned int armada_drm_primary_update_state(
+	struct drm_plane_state *state, struct armada_regs *regs)
 {
 	struct armada_plane *dplane = drm_to_armada_plane(state->plane);
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(state->crtc);
@@ -1124,6 +1099,8 @@ static void armada_drm_primary_update_state(struct drm_plane_state *state,
 		val |= CFG_GRA_ENA;
 	if (drm_rect_width(&state->src) >> 16 != drm_rect_width(&state->dst))
 		val |= CFG_GRA_HSMOOTH;
+	if (dcrtc->interlaced)
+		val |= CFG_GRA_FTOGGLE;
 
 	was_disabled = !(dplane->state.ctrl0 & CFG_GRA_ENA);
 	if (was_disabled)
@@ -1135,12 +1112,26 @@ static void armada_drm_primary_update_state(struct drm_plane_state *state,
 	dplane->state.dst_hw = armada_rect_hw(&state->dst);
 	dplane->state.dst_yx = armada_rect_yx(&state->dst);
 
-	armada_drm_gra_plane_regs(regs + idx, &dfb->fb, &dplane->state,
-				  state->src.x1 >> 16, state->src.y1 >> 16,
-				  dcrtc->interlaced);
+	idx += armada_drm_crtc_calc_fb(&dfb->fb, state->src.x1 >> 16,
+				       state->src.y1 >> 16, regs + idx,
+				       dcrtc->interlaced);
+	armada_reg_queue_set(regs, idx, dplane->state.dst_yx,
+			     LCD_SPU_GRA_OVSA_HPXL_VLN);
+	armada_reg_queue_set(regs, idx, dplane->state.src_hw,
+			     LCD_SPU_GRA_HPXL_VLN);
+	armada_reg_queue_set(regs, idx, dplane->state.dst_hw,
+			     LCD_SPU_GZM_HPXL_VLN);
+	armada_reg_queue_mod(regs, idx, dplane->state.ctrl0, CFG_GRAFORMAT |
+			     CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV |
+					 CFG_SWAPYU | CFG_YUV2RGB) |
+			     CFG_PALETTE_ENA | CFG_GRA_FTOGGLE |
+			     CFG_GRA_HSMOOTH | CFG_GRA_ENA,
+			     LCD_SPU_DMA_CTRL0);
 
 	dplane->state.vsync_update = !was_disabled;
 	dplane->state.changed = true;
+
+	return idx;
 }
 
 static int armada_drm_do_primary_update(struct drm_plane *plane,
@@ -1154,6 +1145,7 @@ static int armada_drm_do_primary_update(struct drm_plane *plane,
 		.enable = state->crtc->enabled,
 		.mode = state->crtc->mode,
 	};
+	unsigned int idx;
 	int ret;
 
 	ret = drm_atomic_helper_check_plane_state(state, &crtc_state, 0,
@@ -1176,7 +1168,8 @@ static int armada_drm_do_primary_update(struct drm_plane *plane,
 		work->old_fb = NULL;
 	}
 
-	armada_drm_primary_update_state(state, work->regs);
+	idx = armada_drm_primary_update_state(state, work->regs);
+	armada_reg_queue_end(work->regs, idx);
 
 	if (!dplane->state.changed)
 		return 0;
commit cfd1b63af78bfce8161e5f65a1d799a9c33b52c6
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: use core of primary update_plane for mode set
    
    Use the core of the update_plane method to configure the primary plane
    within mode_set() rather than duplicating this code.  This moves us
    closer to the same code structure that the atomic modeset transitional
    helpers will use.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 683b2cec3d55..6dd54f1d3ac9 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -613,17 +613,8 @@ static void armada_drm_gra_plane_regs(struct armada_regs *regs,
 	armada_reg_queue_end(regs, i);
 }
 
-static void armada_drm_primary_set(struct drm_crtc *crtc,
-	struct drm_plane *plane, int x, int y)
-{
-	struct armada_plane_state *state = &drm_to_armada_plane(plane)->state;
-	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
-	struct armada_regs regs[8];
-	bool interlaced = dcrtc->interlaced;
-
-	armada_drm_gra_plane_regs(regs, plane->fb, state, x, y, interlaced);
-	armada_drm_crtc_update_regs(dcrtc, regs);
-}
+static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+	struct drm_framebuffer *old_fb);
 
 /* The mode_config.mutex will be held for this call */
 static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
@@ -637,24 +628,13 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
 	unsigned i;
 	bool interlaced;
 
-	drm_framebuffer_get(crtc->primary->fb);
+	/* Take a reference on the old fb for armada_drm_crtc_commit() */
+	if (old_fb)
+		drm_framebuffer_get(old_fb);
 	dcrtc->old_modeset_fb = old_fb;
 
 	interlaced = !!(adj->flags & DRM_MODE_FLAG_INTERLACE);
 
-	val = CFG_GRA_ENA;
-	val |= CFG_GRA_FMT(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt);
-	val |= CFG_GRA_MOD(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->mod);
-
-	if (drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt > CFG_420)
-		val |= CFG_PALETTE_ENA;
-
-	drm_to_armada_plane(crtc->primary)->state.ctrl0 = val;
-	drm_to_armada_plane(crtc->primary)->state.src_hw =
-	drm_to_armada_plane(crtc->primary)->state.dst_hw =
-		adj->crtc_vdisplay << 16 | adj->crtc_hdisplay;
-	drm_to_armada_plane(crtc->primary)->state.dst_yx = 0;
-
 	i = 0;
 	rm = adj->crtc_hsync_start - adj->crtc_hdisplay;
 	lm = adj->crtc_htotal - adj->crtc_hsync_end;
@@ -694,9 +674,6 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
 
 	spin_lock_irqsave(&dcrtc->irq_lock, flags);
 
-	/* Ensure graphic fifo is enabled */
-	armada_reg_queue_mod(regs, i, 0, CFG_PDWN64x66, LCD_SPU_SRAM_PARA1);
-
 	/* Even interlaced/progressive frame */
 	dcrtc->v[1].spu_v_h_total = adj->crtc_vtotal << 16 |
 				    adj->crtc_htotal;
@@ -739,37 +716,34 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
 	armada_reg_queue_end(regs, i);
 
 	armada_drm_crtc_update_regs(dcrtc, regs);
-
-	armada_drm_primary_set(crtc, crtc->primary, x, y);
 	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
 
-	return 0;
+	return armada_drm_crtc_mode_set_base(crtc, x, y, old_fb);
 }
 
+static int armada_drm_do_primary_update(struct drm_plane *plane,
+	struct drm_plane_state *state, struct drm_framebuffer *old_fb);
+
 /* The mode_config.mutex will be held for this call */
 static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 	struct drm_framebuffer *old_fb)
 {
-	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
-	struct armada_regs regs[4];
-	unsigned i;
-
-	i = armada_drm_crtc_calc_fb(crtc->primary->fb, crtc->x, crtc->y, regs,
-				    dcrtc->interlaced);
-	armada_reg_queue_end(regs, i);
-
-	/* Wait for pending flips to complete */
-	armada_drm_plane_work_wait(drm_to_armada_plane(dcrtc->crtc.primary),
-				   MAX_SCHEDULE_TIMEOUT);
-
-	/* Take a reference to the new fb as we're using it */
-	drm_framebuffer_get(crtc->primary->fb);
-
-	/* Update the base in the CRTC */
-	armada_drm_crtc_update_regs(dcrtc, regs);
+	struct drm_plane_state state = {
+		.plane = crtc->primary,
+		.crtc = crtc,
+		.fb = crtc->primary->fb,
+		.crtc_x = 0,
+		.crtc_y = 0,
+		.crtc_w = crtc->mode.hdisplay,
+		.crtc_h = crtc->mode.vdisplay,
+		.src_x = x << 16,
+		.src_y = y << 16,
+		.src_w = crtc->mode.hdisplay << 16,
+		.src_h = crtc->mode.vdisplay << 16,
+		.rotation = DRM_MODE_ROTATE_0,
+	};
 
-	/* Drop our previously held reference */
-	armada_drm_crtc_finish_fb(dcrtc, old_fb, dpms_blanked(dcrtc->dpms));
+	armada_drm_do_primary_update(crtc->primary, &state, old_fb);
 
 	return 0;
 }
@@ -1169,37 +1143,20 @@ static void armada_drm_primary_update_state(struct drm_plane_state *state,
 	dplane->state.changed = true;
 }
 
-static int armada_drm_primary_update(struct drm_plane *plane,
-	struct drm_crtc *crtc, struct drm_framebuffer *fb,
-	int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h,
-	uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h,
-	struct drm_modeset_acquire_ctx *ctx)
+static int armada_drm_do_primary_update(struct drm_plane *plane,
+	struct drm_plane_state *state, struct drm_framebuffer *old_fb)
 {
 	struct armada_plane *dplane = drm_to_armada_plane(plane);
-	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
+	struct armada_crtc *dcrtc = drm_to_armada_crtc(state->crtc);
 	struct armada_plane_work *work;
-	struct drm_plane_state state = {
-		.plane = plane,
-		.crtc = crtc,
-		.fb = fb,
-		.src_x = src_x,
-		.src_y = src_y,
-		.src_w = src_w,
-		.src_h = src_h,
-		.crtc_x = crtc_x,
-		.crtc_y = crtc_y,
-		.crtc_w = crtc_w,
-		.crtc_h = crtc_h,
-		.rotation = DRM_MODE_ROTATE_0,
-	};
 	struct drm_crtc_state crtc_state = {
-		.crtc = crtc,
-		.enable = crtc->enabled,
-		.mode = crtc->mode,
+		.crtc = state->crtc,
+		.enable = state->crtc->enabled,
+		.mode = state->crtc->mode,
 	};
 	int ret;
 
-	ret = drm_atomic_helper_check_plane_state(&state, &crtc_state, 0,
+	ret = drm_atomic_helper_check_plane_state(state, &crtc_state, 0,
 						  INT_MAX, true, false);
 	if (ret)
 		return ret;
@@ -1207,19 +1164,19 @@ static int armada_drm_primary_update(struct drm_plane *plane,
 	work = &dplane->works[dplane->next_work];
 	work->fn = armada_drm_crtc_complete_frame_work;
 
-	if (plane->fb != fb) {
+	if (old_fb != state->fb) {
 		/*
 		 * Take a reference on the new framebuffer - we want to
 		 * hold on to it while the hardware is displaying it.
 		 */
-		drm_framebuffer_reference(fb);
+		drm_framebuffer_reference(state->fb);
 
-		work->old_fb = plane->fb;
+		work->old_fb = old_fb;
 	} else {
 		work->old_fb = NULL;
 	}
 
-	armada_drm_primary_update_state(&state, work->regs);
+	armada_drm_primary_update_state(state, work->regs);
 
 	if (!dplane->state.changed)
 		return 0;
@@ -1248,6 +1205,30 @@ static int armada_drm_primary_update(struct drm_plane *plane,
 	return 0;
 }
 
+static int armada_drm_primary_update(struct drm_plane *plane,
+	struct drm_crtc *crtc, struct drm_framebuffer *fb,
+	int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h,
+	uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h,
+	struct drm_modeset_acquire_ctx *ctx)
+{
+	struct drm_plane_state state = {
+		.plane = plane,
+		.crtc = crtc,
+		.fb = fb,
+		.src_x = src_x,
+		.src_y = src_y,
+		.src_w = src_w,
+		.src_h = src_h,
+		.crtc_x = crtc_x,
+		.crtc_y = crtc_y,
+		.crtc_w = crtc_w,
+		.crtc_h = crtc_h,
+		.rotation = DRM_MODE_ROTATE_0,
+	};
+
+	return armada_drm_do_primary_update(plane, &state, plane->fb);
+}
+
 int armada_drm_plane_disable(struct drm_plane *plane,
 			     struct drm_modeset_acquire_ctx *ctx)
 {
commit f9a13bb3baf6009225e91f2b9748ed27f2db9c2c
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: move mode set vblank handling and disable/enable
    
    Move the mode set vblank handling and controller enable/disable to the
    prepare() and commit() callbacks.  This will be needed when we move to
    mode_set_nofb() as we should not enable the controller without the
    plane coordinates and location having been properly updated.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 205d5dc7ba81..683b2cec3d55 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -399,6 +399,7 @@ static void armada_drm_crtc_prepare(struct drm_crtc *crtc)
 {
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
 	struct drm_plane *plane;
+	u32 val;
 
 	/*
 	 * If we have an overlay plane associated with this CRTC, disable
@@ -411,6 +412,18 @@ static void armada_drm_crtc_prepare(struct drm_crtc *crtc)
 		WARN_ON(!armada_drm_plane_work_wait(drm_to_armada_plane(plane),
 						    HZ));
 	}
+
+	/* Wait for pending flips to complete */
+	armada_drm_plane_work_wait(drm_to_armada_plane(dcrtc->crtc.primary),
+				   MAX_SCHEDULE_TIMEOUT);
+
+	drm_crtc_vblank_off(crtc);
+
+	val = dcrtc->dumb_ctrl & ~CFG_DUMB_ENA;
+	if (val != dcrtc->dumb_ctrl) {
+		dcrtc->dumb_ctrl = val;
+		writel_relaxed(val, dcrtc->base + LCD_SPU_DUMB_CTRL);
+	}
 }
 
 /* The mode_config.mutex will be held for this call */
@@ -418,10 +431,12 @@ static void armada_drm_crtc_commit(struct drm_crtc *crtc)
 {
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
 
-	if (dcrtc->dpms != DRM_MODE_DPMS_ON) {
-		dcrtc->dpms = DRM_MODE_DPMS_ON;
-		armada_drm_crtc_update(dcrtc);
-	}
+	dcrtc->dpms = DRM_MODE_DPMS_ON;
+	armada_drm_crtc_update(dcrtc);
+	drm_crtc_vblank_on(crtc);
+
+	if (dcrtc->old_modeset_fb)
+		armada_drm_crtc_finish_fb(dcrtc, dcrtc->old_modeset_fb, false);
 }
 
 /* The mode_config.mutex will be held for this call */
@@ -623,6 +638,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
 	bool interlaced;
 
 	drm_framebuffer_get(crtc->primary->fb);
+	dcrtc->old_modeset_fb = old_fb;
 
 	interlaced = !!(adj->flags & DRM_MODE_FLAG_INTERLACE);
 
@@ -656,18 +672,6 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
 		adj->crtc_vsync_end,
 		adj->crtc_vtotal, tm, bm);
 
-	/* Wait for pending flips to complete */
-	armada_drm_plane_work_wait(drm_to_armada_plane(dcrtc->crtc.primary),
-				   MAX_SCHEDULE_TIMEOUT);
-
-	drm_crtc_vblank_off(crtc);
-
-	val = dcrtc->dumb_ctrl & ~CFG_DUMB_ENA;
-	if (val != dcrtc->dumb_ctrl) {
-		dcrtc->dumb_ctrl = val;
-		writel_relaxed(val, dcrtc->base + LCD_SPU_DUMB_CTRL);
-	}
-
 	/*
 	 * If we are blanked, we would have disabled the clock.  Re-enable
 	 * it so that compute_clock() does the right thing.
@@ -739,11 +743,6 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
 	armada_drm_primary_set(crtc, crtc->primary, x, y);
 	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
 
-	armada_drm_crtc_update(dcrtc);
-
-	drm_crtc_vblank_on(crtc);
-	armada_drm_crtc_finish_fb(dcrtc, old_fb, dpms_blanked(dcrtc->dpms));
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 445829b8877a..8edcfd1fa75f 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -93,6 +93,7 @@ struct armada_crtc {
 	uint8_t			csc_rgb_mode;
 
 	struct drm_plane	*plane;
+	struct drm_framebuffer	*old_modeset_fb;
 
 	struct armada_gem_object	*cursor_obj;
 	int			cursor_x;
commit 0239520e0290e7d5f186f7fb7f7ce307c478a439
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: add rectangle helpers
    
    Add helpers to convert rectangle width/height and x/y to register
    values.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 78bb3d51417b..205d5dc7ba81 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -1158,11 +1158,9 @@ static void armada_drm_primary_update_state(struct drm_plane_state *state,
 				     0, CFG_PDWN64x66, LCD_SPU_SRAM_PARA1);
 
 	dplane->state.ctrl0 = val;
-	dplane->state.src_hw = (drm_rect_height(&state->src) & 0xffff0000) |
-				drm_rect_width(&state->src) >> 16;
-	dplane->state.dst_hw = drm_rect_height(&state->dst) << 16 |
-			       drm_rect_width(&state->dst);
-	dplane->state.dst_yx = state->dst.y1 << 16 | state->dst.x1;
+	dplane->state.src_hw = armada_rect_hw_fp(&state->src);
+	dplane->state.dst_hw = armada_rect_hw(&state->dst);
+	dplane->state.dst_yx = armada_rect_yx(&state->dst);
 
 	armada_drm_gra_plane_regs(regs + idx, &dfb->fb, &dplane->state,
 				  state->src.x1 >> 16, state->src.y1 >> 16,
diff --git a/drivers/gpu/drm/armada/armada_hw.h b/drivers/gpu/drm/armada/armada_hw.h
index 345dc4d0851e..277580b36758 100644
--- a/drivers/gpu/drm/armada/armada_hw.h
+++ b/drivers/gpu/drm/armada/armada_hw.h
@@ -316,4 +316,19 @@ enum {
 	PWRDN_IRQ_LEVEL		= 1 << 0,
 };
 
+static inline u32 armada_rect_hw_fp(struct drm_rect *r)
+{
+	return (drm_rect_height(r) & 0xffff0000) | drm_rect_width(r) >> 16;
+}
+
+static inline u32 armada_rect_hw(struct drm_rect *r)
+{
+	return drm_rect_height(r) << 16 | (drm_rect_width(r) & 0x0000ffff);
+}
+
+static inline u32 armada_rect_yx(struct drm_rect *r)
+{
+	return (r)->y1 << 16 | ((r)->x1 & 0x0000ffff);
+}
+
 #endif
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index afa7ded3ae31..2347811ccf1b 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -146,22 +146,21 @@ static void armada_ovl_plane_update_state(struct drm_plane_state *state,
 				     LCD_SPU_DMA_PITCH_UV);
 	}
 
-	val = (drm_rect_height(&state->src) & 0xffff0000) |
-	       drm_rect_width(&state->src) >> 16;
+	val = armada_rect_hw_fp(&state->src);
 	if (dplane->base.state.src_hw != val) {
 		dplane->base.state.src_hw = val;
 		armada_reg_queue_set(regs, idx, val,
 				     LCD_SPU_DMA_HPXL_VLN);
 	}
 
-	val = drm_rect_height(&state->dst) << 16 | drm_rect_width(&state->dst);
+	val = armada_rect_hw(&state->dst);
 	if (dplane->base.state.dst_hw != val) {
 		dplane->base.state.dst_hw = val;
 		armada_reg_queue_set(regs, idx, val,
 				     LCD_SPU_DZM_HPXL_VLN);
 	}
 
-	val = state->dst.y1 << 16 | state->dst.x1;
+	val = armada_rect_yx(&state->dst);
 	if (dplane->base.state.dst_yx != val) {
 		dplane->base.state.dst_yx = val;
 		armada_reg_queue_set(regs, idx, val,
commit 1729f56010a960f182a36e09ce8d6504fa637d76
Author: Russell King <rmk+kernel at armlinux.org.uk>
Date:   Mon Jul 30 11:52:34 2018 +0100

    drm/armada: clean up armada_drm_crtc_page_flip()
    
    drm_mode_page_flip_ioctl() already takes care of checking the
    framebuffer format, and also assigns primary->fb after a successful
    call to this handler.  These are both redundant, and can be removed.
    
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 42a40daff132..78bb3d51417b 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -1039,10 +1039,6 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
 	unsigned i;
 	int ret;
 
-	/* We don't support changing the pixel format */
-	if (fb->format != crtc->primary->fb->format)
-		return -EINVAL;
-
 	work = armada_drm_crtc_alloc_plane_work(dcrtc->crtc.primary);
 	if (!work)
 		return -ENOMEM;
@@ -1069,14 +1065,6 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
 	}
 
 	/*
-	 * Don't take a reference on the new framebuffer;
-	 * drm_mode_page_flip_ioctl() has already grabbed a reference and
-	 * will _not_ drop that reference on successful return from this
-	 * function.  Simply mark this new framebuffer as the current one.
-	 */
-	dcrtc->crtc.primary->fb = fb;
-
-	/*
 	 * Finally, if the display is blanked, we won't receive an
 	 * interrupt, so complete it now.
 	 */
commit 7794ec7774066eb12af67a0a756bddd66f2d50f8
Author: Souptick Joarder <jrdr.linux at gmail.com>
Date:   Mon Jul 30 11:52:31 2018 +0100

    drm/armada: Adding new typedef vm_fault_t
    
    Use new return type vm_fault_t for fault handler in struct
    vm_operations_struct. For now, this is just documenting that the
    function returns a VM_FAULT value rather than an errno. Once all
    instances are converted, vm_fault_t will become a distinct type.
    
    commit 1c8f422059ae ("mm: change return type to vm_fault_t")
    
    Previously vm_insert_pfn() returns err which driver mapped into
    VM_FAULT_* type. The new function vmf_insert_pfn() will replace this
    inefficiency by returning VM_FAULT_* type.
    
    Signed-off-by: Souptick Joarder <jrdr.linux at gmail.com>
    Reviewed-by: Matthew Wilcox <mawilcox at microsoft.com>
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index 3fb37c75c065..892c1d9304bb 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -13,25 +13,14 @@
 #include <drm/armada_drm.h>
 #include "armada_ioctlP.h"
 
-static int armada_gem_vm_fault(struct vm_fault *vmf)
+static vm_fault_t armada_gem_vm_fault(struct vm_fault *vmf)
 {
 	struct drm_gem_object *gobj = vmf->vma->vm_private_data;
 	struct armada_gem_object *obj = drm_to_armada_gem(gobj);
 	unsigned long pfn = obj->phys_addr >> PAGE_SHIFT;
-	int ret;
 
 	pfn += (vmf->address - vmf->vma->vm_start) >> PAGE_SHIFT;
-	ret = vm_insert_pfn(vmf->vma, vmf->address, pfn);
-
-	switch (ret) {
-	case 0:
-	case -EBUSY:
-		return VM_FAULT_NOPAGE;
-	case -ENOMEM:
-		return VM_FAULT_OOM;
-	default:
-		return VM_FAULT_SIGBUS;
-	}
+	return vmf_insert_pfn(vmf->vma, vmf->address, pfn);
 }
 
 const struct vm_operations_struct armada_gem_vm_ops = {
commit 830aadceae20c08704562f0b83fdd0f0062d06c6
Author: Thomas Zimmermann <tdz at users.sourceforge.net>
Date:   Mon Jul 30 11:52:31 2018 +0100

    drm/armada: Replace drm_dev_unref with drm_dev_put
    
    This patch unifies the naming of DRM functions for reference counting
    of struct drm_device. The resulting code is more aligned with the rest
    of the Linux kernel interfaces.
    
    Signed-off-by: Thomas Zimmermann <tdz at users.sourceforge.net>
    Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>

diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 4b11b6b52f1d..d1705d298a39 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -109,7 +109,7 @@ static int armada_drm_bind(struct device *dev)
 
 	/*
 	 * The drm_device structure must be at the start of
-	 * armada_private for drm_dev_unref() to work correctly.
+	 * armada_private for drm_dev_put() to work correctly.
 	 */
 	BUILD_BUG_ON(offsetof(struct armada_private, drm) != 0);
 
@@ -180,7 +180,7 @@ static int armada_drm_bind(struct device *dev)
 	drm_mode_config_cleanup(&priv->drm);
 	drm_mm_takedown(&priv->linear);
 	flush_work(&priv->fb_unref_work);
-	drm_dev_unref(&priv->drm);
+	drm_dev_put(&priv->drm);
 	return ret;
 }
 
@@ -200,7 +200,7 @@ static void armada_drm_unbind(struct device *dev)
 	drm_mm_takedown(&priv->linear);
 	flush_work(&priv->fb_unref_work);
 
-	drm_dev_unref(&priv->drm);
+	drm_dev_put(&priv->drm);
 }
 
 static int compare_of(struct device *dev, void *data)
commit 3fce4618279373efc59a91adb16c11da46cd69e5
Merge: ecd7963f7cf9 acb1872577b3
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Jul 30 10:39:22 2018 +1000

    BackMerge v4.18-rc7 into drm-next
    
    rmk requested this for armada and I think we've had a few
    conflicts build up.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>

diff --cc drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c
index 9f0a217603ad,5a2e952c5bea..516795342dd2
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_services.c
@@@ -74,4 -80,327 +74,3 @@@ bool dm_read_persistent_data(struct dc_
  
  /**** power component interfaces ****/
  
 -bool dm_pp_apply_display_requirements(
 -		const struct dc_context *ctx,
 -		const struct dm_pp_display_configuration *pp_display_cfg)
 -{
 -	struct amdgpu_device *adev = ctx->driver_context;
 -
 -	if (adev->pm.dpm_enabled) {
 -
 -		memset(&adev->pm.pm_display_cfg, 0,
 -				sizeof(adev->pm.pm_display_cfg));
 -
 -		adev->pm.pm_display_cfg.cpu_cc6_disable =
 -			pp_display_cfg->cpu_cc6_disable;
 -
 -		adev->pm.pm_display_cfg.cpu_pstate_disable =
 -			pp_display_cfg->cpu_pstate_disable;
 -
 -		adev->pm.pm_display_cfg.cpu_pstate_separation_time =
 -			pp_display_cfg->cpu_pstate_separation_time;
 -
 -		adev->pm.pm_display_cfg.nb_pstate_switch_disable =
 -			pp_display_cfg->nb_pstate_switch_disable;
 -
 -		adev->pm.pm_display_cfg.num_display =
 -				pp_display_cfg->display_count;
 -		adev->pm.pm_display_cfg.num_path_including_non_display =
 -				pp_display_cfg->display_count;
 -
 -		adev->pm.pm_display_cfg.min_core_set_clock =
 -				pp_display_cfg->min_engine_clock_khz/10;
 -		adev->pm.pm_display_cfg.min_core_set_clock_in_sr =
 -				pp_display_cfg->min_engine_clock_deep_sleep_khz/10;
 -		adev->pm.pm_display_cfg.min_mem_set_clock =
 -				pp_display_cfg->min_memory_clock_khz/10;
 -
 -		adev->pm.pm_display_cfg.multi_monitor_in_sync =
 -				pp_display_cfg->all_displays_in_sync;
 -		adev->pm.pm_display_cfg.min_vblank_time =
 -				pp_display_cfg->avail_mclk_switch_time_us;
 -
 -		adev->pm.pm_display_cfg.display_clk =
 -				pp_display_cfg->disp_clk_khz/10;
 -
 -		adev->pm.pm_display_cfg.dce_tolerable_mclk_in_active_latency =
 -				pp_display_cfg->avail_mclk_switch_time_in_disp_active_us;
 -
 -		adev->pm.pm_display_cfg.crtc_index = pp_display_cfg->crtc_index;
 -		adev->pm.pm_display_cfg.line_time_in_us =
 -				pp_display_cfg->line_time_in_us;
 -
 -		adev->pm.pm_display_cfg.vrefresh = pp_display_cfg->disp_configs[0].v_refresh;
 -		adev->pm.pm_display_cfg.crossfire_display_index = -1;
 -		adev->pm.pm_display_cfg.min_bus_bandwidth = 0;
 -
 -		/* TODO: complete implementation of
 -		 * pp_display_configuration_change().
 -		 * Follow example of:
 -		 * PHM_StoreDALConfigurationData - powerplay\hwmgr\hardwaremanager.c
 -		 * PP_IRI_DisplayConfigurationChange - powerplay\eventmgr\iri.c */
 -		if (adev->powerplay.pp_funcs->display_configuration_change)
 -			adev->powerplay.pp_funcs->display_configuration_change(
 -				adev->powerplay.pp_handle,
 -				&adev->pm.pm_display_cfg);
 -
 -		/* TODO: replace by a separate call to 'apply display cfg'? */
 -		amdgpu_pm_compute_clocks(adev);
 -	}
 -
 -	return true;
 -}
 -
 -static void get_default_clock_levels(
 -		enum dm_pp_clock_type clk_type,
 -		struct dm_pp_clock_levels *clks)
 -{
 -	uint32_t disp_clks_in_khz[6] = {
 -			300000, 400000, 496560, 626090, 685720, 757900 };
 -	uint32_t sclks_in_khz[6] = {
 -			300000, 360000, 423530, 514290, 626090, 720000 };
 -	uint32_t mclks_in_khz[2] = { 333000, 800000 };
 -
 -	switch (clk_type) {
 -	case DM_PP_CLOCK_TYPE_DISPLAY_CLK:
 -		clks->num_levels = 6;
 -		memmove(clks->clocks_in_khz, disp_clks_in_khz,
 -				sizeof(disp_clks_in_khz));
 -		break;
 -	case DM_PP_CLOCK_TYPE_ENGINE_CLK:
 -		clks->num_levels = 6;
 -		memmove(clks->clocks_in_khz, sclks_in_khz,
 -				sizeof(sclks_in_khz));
 -		break;
 -	case DM_PP_CLOCK_TYPE_MEMORY_CLK:
 -		clks->num_levels = 2;
 -		memmove(clks->clocks_in_khz, mclks_in_khz,
 -				sizeof(mclks_in_khz));
 -		break;
 -	default:
 -		clks->num_levels = 0;
 -		break;
 -	}
 -}
 -
 -static enum amd_pp_clock_type dc_to_pp_clock_type(
 -		enum dm_pp_clock_type dm_pp_clk_type)
 -{
 -	enum amd_pp_clock_type amd_pp_clk_type = 0;
 -
 -	switch (dm_pp_clk_type) {
 -	case DM_PP_CLOCK_TYPE_DISPLAY_CLK:
 -		amd_pp_clk_type = amd_pp_disp_clock;
 -		break;
 -	case DM_PP_CLOCK_TYPE_ENGINE_CLK:
 -		amd_pp_clk_type = amd_pp_sys_clock;
 -		break;
 -	case DM_PP_CLOCK_TYPE_MEMORY_CLK:
 -		amd_pp_clk_type = amd_pp_mem_clock;
 -		break;
 -	default:
 -		DRM_ERROR("DM_PPLIB: invalid clock type: %d!\n",
 -				dm_pp_clk_type);
 -		break;
 -	}
 -
 -	return amd_pp_clk_type;
 -}
 -
 -static void pp_to_dc_clock_levels(
 -		const struct amd_pp_clocks *pp_clks,
 -		struct dm_pp_clock_levels *dc_clks,
 -		enum dm_pp_clock_type dc_clk_type)
 -{
 -	uint32_t i;
 -
 -	if (pp_clks->count > DM_PP_MAX_CLOCK_LEVELS) {
 -		DRM_INFO("DM_PPLIB: Warning: %s clock: number of levels %d exceeds maximum of %d!\n",
 -				DC_DECODE_PP_CLOCK_TYPE(dc_clk_type),
 -				pp_clks->count,
 -				DM_PP_MAX_CLOCK_LEVELS);
 -
 -		dc_clks->num_levels = DM_PP_MAX_CLOCK_LEVELS;
 -	} else
 -		dc_clks->num_levels = pp_clks->count;
 -
 -	DRM_INFO("DM_PPLIB: values for %s clock\n",
 -			DC_DECODE_PP_CLOCK_TYPE(dc_clk_type));
 -
 -	for (i = 0; i < dc_clks->num_levels; i++) {
 -		DRM_INFO("DM_PPLIB:\t %d\n", pp_clks->clock[i]);
 -		/* translate 10kHz to kHz */
 -		dc_clks->clocks_in_khz[i] = pp_clks->clock[i] * 10;
 -	}
 -}
 -
 -static void pp_to_dc_clock_levels_with_latency(
 -		const struct pp_clock_levels_with_latency *pp_clks,
 -		struct dm_pp_clock_levels_with_latency *clk_level_info,
 -		enum dm_pp_clock_type dc_clk_type)
 -{
 -	uint32_t i;
 -
 -	if (pp_clks->num_levels > DM_PP_MAX_CLOCK_LEVELS) {
 -		DRM_INFO("DM_PPLIB: Warning: %s clock: number of levels %d exceeds maximum of %d!\n",
 -				DC_DECODE_PP_CLOCK_TYPE(dc_clk_type),
 -				pp_clks->num_levels,
 -				DM_PP_MAX_CLOCK_LEVELS);
 -
 -		clk_level_info->num_levels = DM_PP_MAX_CLOCK_LEVELS;
 -	} else
 -		clk_level_info->num_levels = pp_clks->num_levels;
 -
 -	DRM_DEBUG("DM_PPLIB: values for %s clock\n",
 -			DC_DECODE_PP_CLOCK_TYPE(dc_clk_type));
 -
 -	for (i = 0; i < clk_level_info->num_levels; i++) {
 -		DRM_DEBUG("DM_PPLIB:\t %d in 10kHz\n", pp_clks->data[i].clocks_in_khz);
 -		/* translate 10kHz to kHz */
 -		clk_level_info->data[i].clocks_in_khz = pp_clks->data[i].clocks_in_khz * 10;
 -		clk_level_info->data[i].latency_in_us = pp_clks->data[i].latency_in_us;
 -	}
 -}
 -
 -bool dm_pp_get_clock_levels_by_type(
 -		const struct dc_context *ctx,
 -		enum dm_pp_clock_type clk_type,
 -		struct dm_pp_clock_levels *dc_clks)
 -{
 -	struct amdgpu_device *adev = ctx->driver_context;
 -	void *pp_handle = adev->powerplay.pp_handle;
 -	struct amd_pp_clocks pp_clks = { 0 };
 -	struct amd_pp_simple_clock_info validation_clks = { 0 };
 -	uint32_t i;
 -
 -	if (adev->powerplay.pp_funcs->get_clock_by_type) {
 -		if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle,
 -			dc_to_pp_clock_type(clk_type), &pp_clks)) {
 -		/* Error in pplib. Provide default values. */
 -			get_default_clock_levels(clk_type, dc_clks);
 -			return true;
 -		}
 -	}
 -
 -	pp_to_dc_clock_levels(&pp_clks, dc_clks, clk_type);
 -
 -	if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks) {
 -		if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks(
 -						pp_handle, &validation_clks)) {
 -			/* Error in pplib. Provide default values. */
 -			DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n");
 -			validation_clks.engine_max_clock = 72000;
 -			validation_clks.memory_max_clock = 80000;
 -			validation_clks.level = 0;
 -		}
 -	}
 -
 -	DRM_INFO("DM_PPLIB: Validation clocks:\n");
 -	DRM_INFO("DM_PPLIB:    engine_max_clock: %d\n",
 -			validation_clks.engine_max_clock);
 -	DRM_INFO("DM_PPLIB:    memory_max_clock: %d\n",
 -			validation_clks.memory_max_clock);
 -	DRM_INFO("DM_PPLIB:    level           : %d\n",
 -			validation_clks.level);
 -
 -	/* Translate 10 kHz to kHz. */
 -	validation_clks.engine_max_clock *= 10;
 -	validation_clks.memory_max_clock *= 10;
 -
 -	/* Determine the highest non-boosted level from the Validation Clocks */
 -	if (clk_type == DM_PP_CLOCK_TYPE_ENGINE_CLK) {
 -		for (i = 0; i < dc_clks->num_levels; i++) {
 -			if (dc_clks->clocks_in_khz[i] > validation_clks.engine_max_clock) {
 -				/* This clock is higher the validation clock.
 -				 * Than means the previous one is the highest
 -				 * non-boosted one. */
 -				DRM_INFO("DM_PPLIB: reducing engine clock level from %d to %d\n",
 -						dc_clks->num_levels, i);
 -				dc_clks->num_levels = i > 0 ? i : 1;
 -				break;
 -			}
 -		}
 -	} else if (clk_type == DM_PP_CLOCK_TYPE_MEMORY_CLK) {
 -		for (i = 0; i < dc_clks->num_levels; i++) {
 -			if (dc_clks->clocks_in_khz[i] > validation_clks.memory_max_clock) {
 -				DRM_INFO("DM_PPLIB: reducing memory clock level from %d to %d\n",
 -						dc_clks->num_levels, i);
 -				dc_clks->num_levels = i > 0 ? i : 1;
 -				break;
 -			}
 -		}
 -	}
 -
 -	return true;
 -}
 -
 -bool dm_pp_get_clock_levels_by_type_with_latency(
 -	const struct dc_context *ctx,
 -	enum dm_pp_clock_type clk_type,
 -	struct dm_pp_clock_levels_with_latency *clk_level_info)
 -{
 -	struct amdgpu_device *adev = ctx->driver_context;
 -	void *pp_handle = adev->powerplay.pp_handle;
 -	struct pp_clock_levels_with_latency pp_clks = { 0 };
 -	const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
 -
 -	if (!pp_funcs || !pp_funcs->get_clock_by_type_with_latency)
 -		return false;
 -
 -	if (pp_funcs->get_clock_by_type_with_latency(pp_handle,
 -						     dc_to_pp_clock_type(clk_type),
 -						     &pp_clks))
 -		return false;
 -
 -	pp_to_dc_clock_levels_with_latency(&pp_clks, clk_level_info, clk_type);
 -
 -	return true;
 -}
 -
 -bool dm_pp_get_clock_levels_by_type_with_voltage(
 -	const struct dc_context *ctx,
 -	enum dm_pp_clock_type clk_type,
 -	struct dm_pp_clock_levels_with_voltage *clk_level_info)
 -{
 -	/* TODO: to be implemented */
 -	return false;
 -}
 -
 -bool dm_pp_notify_wm_clock_changes(
 -	const struct dc_context *ctx,
 -	struct dm_pp_wm_sets_with_clock_ranges *wm_with_clock_ranges)
 -{
 -	/* TODO: to be implemented */
 -	return false;
 -}
 -
 -bool dm_pp_apply_power_level_change_request(
 -	const struct dc_context *ctx,
 -	struct dm_pp_power_level_change_request *level_change_req)
 -{
 -	/* TODO: to be implemented */
 -	return false;
 -}
 -
 -bool dm_pp_apply_clock_for_voltage_request(
 -	const struct dc_context *ctx,
 -	struct dm_pp_clock_for_voltage_req *clock_for_voltage_req)
 -{
 -	/* TODO: to be implemented */
 -	return false;
 -}
 -
 -bool dm_pp_get_static_clocks(
 -	const struct dc_context *ctx,
 -	struct dm_pp_static_clock_info *static_clk_info)
 -{
 -	/* TODO: to be implemented */
 -	return false;
 -}
 -
 -void dm_pp_get_funcs_rv(
 -		struct dc_context *ctx,
 -		struct pp_smu_funcs_rv *funcs)
 -{}
--
 -/**** end of power component interfaces ****/
diff --cc drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c
index f4f366b26fd1,29914700ee82..cb3a5b1737c8
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_processpptables.c
@@@ -224,8 -224,14 +224,10 @@@ static int append_vbios_pptable(struct 
  	ppsmc_pptable->AcgGfxclkSpreadPercent = smc_dpm_table.acggfxclkspreadpercent;
  	ppsmc_pptable->AcgGfxclkSpreadFreq = smc_dpm_table.acggfxclkspreadfreq;
  
 -	/* 0xFFFF will disable the ACG feature */
 -	if (!(hwmgr->feature_mask & PP_ACG_MASK)) {
 -		ppsmc_pptable->AcgThresholdFreqHigh = 0xFFFF;
 -		ppsmc_pptable->AcgThresholdFreqLow = 0xFFFF;
 -	}
 +	ppsmc_pptable->Vr2_I2C_address = smc_dpm_table.Vr2_I2C_address;
  
+ 	ppsmc_pptable->Vr2_I2C_address = smc_dpm_table.Vr2_I2C_address;
+ 
  	return 0;
  }
  
commit ecd7963f7cf967009882fd56eaee1e87a229bea2
Merge: 6d52aacd92c6 b5aa3f4aef72
Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Jul 30 10:23:40 2018 +1000

    Merge tag 'drm-amdkfd-next-2018-07-28' of git://people.freedesktop.org/~gabbayo/linux into drm-next
    
    This is amdkfd pull for 4.19. The major changes are:
    
    - Add Raven support. Raven refers to Ryzen APUs with integrated GFXv9 GPU.
    - Integrate GPU reset support
    
    In addition, there are a couple of small fixes and improvements, such as:
    
    - Better handling and reporting to user of VM faults
    - Fix race upon context restore
    - Allow the user to use specific Compute Units
    - Basic power management
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20180728122306.GA5235@ogabbay-vm

commit acb1872577b346bd15ab3a3f8dff780d6cca4b70
Author: Linus Torvalds <torvalds at linux-foundation.org>
Date:   Sun Jul 29 14:44:52 2018 -0700

    Linux 4.18-rc7

diff --git a/Makefile b/Makefile
index 67d9d20f8564..85f3481a56d6 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 4
 PATCHLEVEL = 18
 SUBLEVEL = 0
-EXTRAVERSION = -rc6
+EXTRAVERSION = -rc7
 NAME = Merciless Moray
 
 # *DOCUMENTATION*
commit 3cfb6772d4cf3875d199f5a5a547cadaef7c1382
Merge: 01cfb7937a9a 501228470077
Author: Linus Torvalds <torvalds at linux-foundation.org>
Date:   Sun Jul 29 13:13:45 2018 -0700

    Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
    
    Pull ext4 fixes from Ted Ts'o:
     "Some miscellaneous ext4 fixes for 4.18; one fix is for a regression
      introduced in 4.18-rc4.
    
      Sorry for the late-breaking pull. I was originally going to wait for
      the next merge window, but Eric Whitney found a regression introduced
      in 4.18-rc4, so I decided to push out the regression plus the other
      fixes now. (The other commits have been baking in linux-next since
      early July)"
    
    * tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
      ext4: fix check to prevent initializing reserved inodes
      ext4: check for allocation block validity with block group locked
      ext4: fix inline data updates with checksums enabled
      ext4: clear mmp sequence number when remounting read-only
      ext4: fix false negatives *and* false positives in ext4_check_descriptors()

commit 01cfb7937a9af2abb1136c7e89fbf3fd92952956
Author: Linus Torvalds <torvalds at linux-foundation.org>
Date:   Sun Jul 29 12:44:46 2018 -0700

    squashfs: be more careful about metadata corruption
    
    Anatoly Trosinenko reports that a corrupted squashfs image can cause a
    kernel oops.  It turns out that squashfs can end up being confused about
    negative fragment lengths.
    
    The regular squashfs_read_data() does check for negative lengths, but
    squashfs_read_metadata() did not, and the fragment size code just
    blindly trusted the on-disk value.  Fix both the fragment parsing and
    the metadata reading code.
    
    Reported-by: Anatoly Trosinenko <anatoly.trosinenko at gmail.com>
    Cc: Al Viro <viro at zeniv.linux.org.uk>
    Cc: Phillip Lougher <phillip at squashfs.org.uk>
    Cc: stable at kernel.org
    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>

diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c
index 23813c078cc9..0839efa720b3 100644
--- a/fs/squashfs/cache.c
+++ b/fs/squashfs/cache.c
@@ -350,6 +350,9 @@ int squashfs_read_metadata(struct super_block *sb, void *buffer,
 
 	TRACE("Entered squashfs_read_metadata [%llx:%x]\n", *block, *offset);
 
+	if (unlikely(length < 0))
+		return -EIO;
+
 	while (length) {
 		entry = squashfs_cache_get(sb, msblk->block_cache, *block, 0);
 		if (entry->error) {
diff --git a/fs/squashfs/file.c b/fs/squashfs/file.c
index 13d80947bf9e..fcff2e0487fe 100644
--- a/fs/squashfs/file.c
+++ b/fs/squashfs/file.c
@@ -194,7 +194,11 @@ static long long read_indexes(struct super_block *sb, int n,
 		}
 
 		for (i = 0; i < blocks; i++) {
-			int size = le32_to_cpu(blist[i]);
+			int size = squashfs_block_size(blist[i]);
+			if (size < 0) {
+				err = size;
+				goto failure;
+			}
 			block += SQUASHFS_COMPRESSED_SIZE_BLOCK(size);
 		}
 		n -= blocks;
@@ -367,7 +371,7 @@ static int read_blocklist(struct inode *inode, int index, u64 *block)
 			sizeof(size));
 	if (res < 0)
 		return res;
-	return le32_to_cpu(size);
+	return squashfs_block_size(size);
 }
 
 /* Copy data into page cache  */
diff --git a/fs/squashfs/fragment.c b/fs/squashfs/fragment.c
index 0ed6edbc5c71..86ad9a4b8c36 100644
--- a/fs/squashfs/fragment.c
+++ b/fs/squashfs/fragment.c
@@ -61,9 +61,7 @@ int squashfs_frag_lookup(struct super_block *sb, unsigned int fragment,
 		return size;
 
 	*fragment_block = le64_to_cpu(fragment_entry.start_block);
-	size = le32_to_cpu(fragment_entry.size);
-
-	return size;
+	return squashfs_block_size(fragment_entry.size);
 }
 
 
diff --git a/fs/squashfs/squashfs_fs.h b/fs/squashfs/squashfs_fs.h
index 24d12fd14177..4e6853f084d0 100644
--- a/fs/squashfs/squashfs_fs.h
+++ b/fs/squashfs/squashfs_fs.h
@@ -129,6 +129,12 @@
 
 #define SQUASHFS_COMPRESSED_BLOCK(B)	(!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK))
 
+static inline int squashfs_block_size(__le32 raw)
+{
+	u32 size = le32_to_cpu(raw);
+	return (size >> 25) ? -EIO : size;
+}
+
 /*
  * Inode number ops.  Inodes consist of a compressed block number, and an
  * uncompressed offset within that block
commit 5012284700775a4e6e3fbe7eac4c543c4874b559
Author: Theodore Ts'o <tytso at mit.edu>
Date:   Sat Jul 28 08:12:04 2018 -0400

    ext4: fix check to prevent initializing reserved inodes
    
    Commit 8844618d8aa7: "ext4: only look at the bg_flags field if it is
    valid" will complain if block group zero does not have the
    EXT4_BG_INODE_ZEROED flag set.  Unfortunately, this is not correct,
    since a freshly created file system has this flag cleared.  It gets
    almost immediately after the file system is mounted read-write --- but
    the following somewhat unlikely sequence will end up triggering a
    false positive report of a corrupted file system:
    
       mkfs.ext4 /dev/vdc
       mount -o ro /dev/vdc /vdc
       mount -o remount,rw /dev/vdc
    
    Instead, when initializing the inode table for block group zero, test
    to make sure that itable_unused count is not too large, since that is
    the case that will result in some or all of the reserved inodes
    getting cleared.
    
    This fixes the failures reported by Eric Whiteney when running
    generic/230 and generic/231 in the the nojournal test case.
    
    Fixes: 8844618d8aa7 ("ext4: only look at the bg_flags field if it is valid")
    Reported-by: Eric Whitney <enwlinux at gmail.com>
    Signed-off-by: Theodore Ts'o <tytso at mit.edu>

diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index e9d8e2667ab5..f336cbc6e932 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -1388,7 +1388,10 @@ int ext4_init_inode_table(struct super_block *sb, ext4_group_t group,
 			    ext4_itable_unused_count(sb, gdp)),
 			    sbi->s_inodes_per_block);
 
-	if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group)) {
+	if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group) ||
+	    ((group == 0) && ((EXT4_INODES_PER_GROUP(sb) -
+			       ext4_itable_unused_count(sb, gdp)) <
+			      EXT4_FIRST_INO(sb)))) {
 		ext4_error(sb, "Something is wrong with group %u: "
 			   "used itable blocks: %d; "
 			   "itable unused count: %u",
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 680526e9ee96..b7f7922061be 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3141,14 +3141,8 @@ static ext4_group_t ext4_has_uninit_itable(struct super_block *sb)
 		if (!gdp)
 			continue;
 
-		if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED))
-			continue;
-		if (group != 0)
+		if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED)))
 			break;
-		ext4_error(sb, "Inode table for bg 0 marked as "
-			   "needing zeroing");
-		if (sb_rdonly(sb))
-			return ngroups;
 	}
 
 	return group;
commit a26fb01c2879ed7026e6cbd78bb701912d249eef
Merge: 2ffb57dfa793 81e69df38e29
Author: Linus Torvalds <torvalds at linux-foundation.org>
Date:   Sat Jul 28 19:40:06 2018 -0700

    Merge tag 'random_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random
    
    Pull random fixes from Ted Ts'o:
     "In reaction to the fixes to address CVE-2018-1108, some Linux
      distributions that have certain systemd versions in some cases
      combined with patches to libcrypt for FIPS/FEDRAMP compliance, have
      led to boot-time stalls for some hardware.
    
      The reaction by some distros and Linux sysadmins has been to install
      packages that try to do complicated things with the CPU and hope that
      leads to randomness.
    
      To mitigate this, if RDRAND is available, mix it into entropy provided
      by userspace. It won't hurt, and it will probably help"
    
    * tag 'random_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random:
      random: mix rdrand with entropy sent in from userspace

commit 2ffb57dfa793ca2932c524a1e91d403b28bd84b9
Merge: 7648c44680de bbfbf04c2d4e
Author: Linus Torvalds <torvalds at linux-foundation.org>
Date:   Sat Jul 28 15:43:14 2018 -0700

    Merge tag 'gpio-v4.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio
    
    Pull GPIO fixes from Linus Walleij:
     "Just a smallish OF fix and a driver fix:
    
       - OF flag fix for special regulator flags
    
       - fix up the Uniphier IRQ callback"
    
    * tag 'gpio-v4.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio:
      gpio: uniphier: set legitimate irq trigger type in .to_irq hook
      gpio: of: Handle fixed regulator flags properly

commit 7648c44680de90a0b656a55813fed5f6621512c5
Merge: dd63bf22fccd d5ea019f8a38
Author: Linus Torvalds <torvalds at linux-foundation.org>
Date:   Sat Jul 28 12:32:28 2018 -0700

    Merge tag 'mips_fixes_4.18_5' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
    
    Pull MIPS fix from Paul Burton:
     "Here's one more MIPS fix, reverting an errata workaround that was
      merged for v4.18-rc2 but has since been found to cause system hangs on
      some BCM4718A1-based systems by the OpenWRT project"
    
    * tag 'mips_fixes_4.18_5' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux:
      Revert "MIPS: BCM47XX: Enable 74K Core ExternalSync for PCIe erratum"

commit 2ead1be54b22ccdc93d3030172993e363128f1b4
Author: Rodrigo Siqueira <rodrigosiqueiramelo at gmail.com>
Date:   Wed Jul 18 21:40:45 2018 -0300

    drm/vkms: Fix connector leak at the module removal
    
    Currently, vkms shows an error message if the following steps occur: (1)
    load vkms, (2) perform any specific operation in the vkms (e.g., run an
    IGT test), and (3) unload the module. The following error message
    emerges:
    
    [drm:drm_mode_config_cleanup [drm]] *ERROR* connector Virtual-1 leaked!
    
    This commit fixes this error by calling drm_atomic_helper_shutdown()
    before drm_mode_config_cleanup, which turns off the whole display
    pipeline and remove a reference related to any connector.
    
    Signed-off-by: Rodrigo Siqueira <rodrigosiqueiramelo at gmail.com>
    Signed-off-by: Gustavo Padovan <gustavo.padovan at collabora.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20180719004045.hzepp565x5lfco3c@smtp.gmail.com

diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index 37aa2ef33b21..6e728b825259 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -44,6 +44,7 @@ static void vkms_release(struct drm_device *dev)
 	struct vkms_device *vkms = container_of(dev, struct vkms_device, drm);
 
 	platform_device_unregister(vkms->platform);
+	drm_atomic_helper_shutdown(&vkms->drm);
 	drm_mode_config_cleanup(&vkms->drm);
 	drm_dev_fini(&vkms->drm);
 }
commit ea5569ecd6b81232eb536017b627c417befc1acb
Author: Hans Verkuil <hverkuil at xs4all.nl>
Date:   Tue Jul 24 21:20:28 2018 +0200

    drm_dp_cec.c: fix formatting typo: %pdH -> %phD
    
    This caused a kernel oops since %pdH interpreted the pointer
    as a struct file.
    
    Signed-off-by: Hans Verkuil <hans.verkuil at cisco.com>
    Signed-off-by: Gustavo Padovan <gustavo.padovan at collabora.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/f3720ddf-ec0f-cd22-46b6-720a5e2098f2@xs4all.nl

diff --git a/drivers/gpu/drm/drm_dp_cec.c b/drivers/gpu/drm/drm_dp_cec.c
index ddb1c5adebb9..988513346e9c 100644
--- a/drivers/gpu/drm/drm_dp_cec.c
+++ b/drivers/gpu/drm/drm_dp_cec.c
@@ -157,7 +157,7 @@ static void drm_dp_cec_adap_status(struct cec_adapter *adap,
 
 	if (drm_dp_read_desc(aux, &desc, true))
 		return;
-	seq_printf(file, "OUI: %*pdH\n",
+	seq_printf(file, "OUI: %*phD\n",
 		   (int)sizeof(id->oui), id->oui);
 	seq_printf(file, "ID: %*pE\n",
 		   (int)strnlen(id->device_id, sizeof(id->device_id)),
commit dd63bf22fccd68913e3088c5ed5de3bf406a7546
Merge: eb181a814c98 d2d0ad2aec4a
Author: Linus Torvalds <torvalds at linux-foundation.org>
Date:   Sat Jul 28 10:04:40 2018 -0700

    Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
    
    Pull i2c fixes from Wolfram Sang:
     "Some driver bugfixes"
    
    * 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
      i2c: imx: use open drain for recovery GPIO
      i2c: rcar: handle RXDMA HW behaviour on Gen3
      i2c: imx: Fix reinit_completion() use
      i2c: davinci: Avoid zero value of CLKH

commit 2e603d0429a4e7cba93a4bc4fcdbdf830adaa472
Author: Huang Rui <ray.huang at amd.com>
Date:   Thu Jul 26 14:08:03 2018 +0800

    drm/amdgpu: clean up the superfluous space and align the comment text for amdgpu_ttm
    
    This patch cleans up spaces and align the text to refine the comment for
    amdgpu_ttm.
    
    Signed-off-by: Huang Rui <ray.huang at amd.com>
    Reviewed-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index c1ae528c7b0e..fcf421263fd9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -92,11 +92,9 @@ static void amdgpu_ttm_mem_global_release(struct drm_global_reference *ref)
 }
 
 /**
- * amdgpu_ttm_global_init - Initialize global TTM memory reference
- * 							structures.
+ * amdgpu_ttm_global_init - Initialize global TTM memory reference structures.
  *
- * @adev:  	AMDGPU device for which the global structures need to be
- *			registered.
+ * @adev: AMDGPU device for which the global structures need to be registered.
  *
  * This is called as part of the AMDGPU ttm init from amdgpu_ttm_init()
  * during bring up.
@@ -162,13 +160,12 @@ static int amdgpu_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags)
 }
 
 /**
- * amdgpu_init_mem_type - 	Initialize a memory manager for a specific
- * 							type of memory request.
+ * amdgpu_init_mem_type - Initialize a memory manager for a specific type of
+ * memory request.
  *
- * @bdev:	The TTM BO device object (contains a reference to
- * 			amdgpu_device)
- * @type:	The type of memory requested
- * @man:
+ * @bdev: The TTM BO device object (contains a reference to amdgpu_device)
+ * @type: The type of memory requested
+ * @man: The memory type manager for each domain
  *
  * This is called by ttm_bo_init_mm() when a buffer object is being
  * initialized.
@@ -292,8 +289,8 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
 /**
  * amdgpu_verify_access - Verify access for a mmap call
  *
- * @bo:		The buffer object to map
- * @filp:	The file pointer from the process performing the mmap
+ * @bo:	The buffer object to map
+ * @filp: The file pointer from the process performing the mmap
  *
  * This is called by ttm_bo_mmap() to verify whether a process
  * has the right to mmap a BO to their process space.
@@ -318,11 +315,10 @@ static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp)
 /**
  * amdgpu_move_null - Register memory for a buffer object
  *
- * @bo:			The bo to assign the memory to
- * @new_mem:	The memory to be assigned.
+ * @bo: The bo to assign the memory to
+ * @new_mem: The memory to be assigned.
  *
- * Assign the memory from new_mem to the memory of the buffer object
- * bo.
+ * Assign the memory from new_mem to the memory of the buffer object bo.
  */
 static void amdgpu_move_null(struct ttm_buffer_object *bo,
 			     struct ttm_mem_reg *new_mem)
@@ -335,8 +331,12 @@ static void amdgpu_move_null(struct ttm_buffer_object *bo,
 }
 
 /**
- * amdgpu_mm_node_addr -	Compute the GPU relative offset of a GTT
- * 							buffer.
+ * amdgpu_mm_node_addr - Compute the GPU relative offset of a GTT buffer.
+ *
+ * @bo: The bo to assign the memory to.
+ * @mm_node: Memory manager node for drm allocator.
+ * @mem: The region where the bo resides.
+ *
  */
 static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo,
 				    struct drm_mm_node *mm_node,
@@ -352,10 +352,12 @@ static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo,
 }
 
 /**
- * amdgpu_find_mm_node -	Helper function finds the drm_mm_node
- *  						corresponding to @offset. It also modifies
- * 							the offset to be within the drm_mm_node
- * 							returned
+ * amdgpu_find_mm_node - Helper function finds the drm_mm_node corresponding to
+ * @offset. It also modifies the offset to be within the drm_mm_node returned
+ *
+ * @mem: The region where the bo resides.
+ * @offset: The offset that drm_mm_node is used for finding.
+ *
  */
 static struct drm_mm_node *amdgpu_find_mm_node(struct ttm_mem_reg *mem,
 					       unsigned long *offset)
@@ -497,8 +499,8 @@ error:
 /**
  * amdgpu_move_blit - Copy an entire buffer to another buffer
  *
- * This is a helper called by amdgpu_bo_move() and
- * amdgpu_move_vram_ram() to help move buffers to and from VRAM.
+ * This is a helper called by amdgpu_bo_move() and amdgpu_move_vram_ram() to
+ * help move buffers to and from VRAM.
  */
 static int amdgpu_move_blit(struct ttm_buffer_object *bo,
 			    bool evict, bool no_wait_gpu,
@@ -794,8 +796,8 @@ struct amdgpu_ttm_tt {
 };
 
 /**
- * amdgpu_ttm_tt_get_user_pages - 	Pin pages of memory pointed to
- * 									by a USERPTR pointer to memory
+ * amdgpu_ttm_tt_get_user_pages - Pin pages of memory pointed to by a USERPTR
+ * pointer to memory
  *
  * Called by amdgpu_gem_userptr_ioctl() and amdgpu_cs_parser_bos().
  * This provides a wrapper around the get_user_pages() call to provide
@@ -818,8 +820,10 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
 	down_read(&mm->mmap_sem);
 
 	if (gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) {
-		/* check that we only use anonymous memory
-		   to prevent problems with writeback */
+		/*
+		 * check that we only use anonymous memory to prevent problems
+		 * with writeback
+		 */
 		unsigned long end = gtt->userptr + ttm->num_pages * PAGE_SIZE;
 		struct vm_area_struct *vma;
 
@@ -870,10 +874,9 @@ release_pages:
 }
 
 /**
- * amdgpu_ttm_tt_set_user_pages - 	Copy pages in, putting old pages
- * 									as necessary.
+ * amdgpu_ttm_tt_set_user_pages - Copy pages in, putting old pages as necessary.
  *
- * Called by amdgpu_cs_list_validate().  This creates the page list
+ * Called by amdgpu_cs_list_validate(). This creates the page list
  * that backs user memory and will ultimately be mapped into the device
  * address space.
  */
@@ -915,8 +918,7 @@ void amdgpu_ttm_tt_mark_user_pages(struct ttm_tt *ttm)
 }
 
 /**
- * amdgpu_ttm_tt_pin_userptr - 	prepare the sg table with the
- * 								user pages
+ * amdgpu_ttm_tt_pin_userptr - 	prepare the sg table with the user pages
  *
  * Called by amdgpu_ttm_backend_bind()
  **/
@@ -1295,8 +1297,8 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm)
 }
 
 /**
- * amdgpu_ttm_tt_set_userptr -	Initialize userptr GTT ttm_tt
- * 								for the current task
+ * amdgpu_ttm_tt_set_userptr - Initialize userptr GTT ttm_tt for the current
+ * task
  *
  * @ttm: The ttm_tt object to bind this userptr object to
  * @addr:  The address in the current tasks VM space to use
@@ -1346,9 +1348,8 @@ struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm)
 }
 
 /**
- * amdgpu_ttm_tt_affect_userptr -	Determine if a ttm_tt object lays
- * 									inside an address range for the
- * 									current task.
+ * amdgpu_ttm_tt_affect_userptr - Determine if a ttm_tt object lays inside an
+ * address range for the current task.
  *
  */
 bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
@@ -1386,8 +1387,7 @@ bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
 }
 
 /**
- * amdgpu_ttm_tt_userptr_invalidated -	Has the ttm_tt object been
- * 										invalidated?
+ * amdgpu_ttm_tt_userptr_invalidated - Has the ttm_tt object been invalidated?
  */
 bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm,
 				       int *last_invalidated)
@@ -1400,10 +1400,8 @@ bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm,
 }
 
 /**
- * amdgpu_ttm_tt_userptr_needs_pages -	Have the pages backing this
- * 										ttm_tt object been invalidated
- * 										since the last time they've
- * 										been set?
+ * amdgpu_ttm_tt_userptr_needs_pages - Have the pages backing this ttm_tt object
+ * been invalidated since the last time they've been set?
  */
 bool amdgpu_ttm_tt_userptr_needs_pages(struct ttm_tt *ttm)
 {
@@ -1459,13 +1457,12 @@ uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
 }
 
 /**
- * amdgpu_ttm_bo_eviction_valuable -	Check to see if we can evict
- * 										a buffer object.
+ * amdgpu_ttm_bo_eviction_valuable - Check to see if we can evict a buffer
+ * object.
  *
- * Return true if eviction is sensible.  Called by
- * ttm_mem_evict_first() on behalf of ttm_bo_mem_force_space()
- * which tries to evict buffer objects until it can find space
- * for a new object and by ttm_bo_force_list_clean() which is
+ * Return true if eviction is sensible. Called by ttm_mem_evict_first() on
+ * behalf of ttm_bo_mem_force_space() which tries to evict buffer objects until
+ * it can find space for a new object and by ttm_bo_force_list_clean() which is
  * used to clean out a memory space.
  */
 static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
@@ -1515,8 +1512,7 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
 }
 
 /**
- * amdgpu_ttm_access_memory -	Read or Write memory that backs a
- * 								buffer object.
+ * amdgpu_ttm_access_memory - Read or Write memory that backs a buffer object.
  *
  * @bo:  The buffer object to read/write
  * @offset:  Offset into buffer object
@@ -1704,8 +1700,8 @@ error_create:
 	return r;
 }
 /**
- * amdgpu_ttm_init -	Init the memory management (ttm) as well as
- * 						various gtt/vram related fields.
+ * amdgpu_ttm_init - Init the memory management (ttm) as well as various
+ * gtt/vram related fields.
  *
  * This initializes all of the memory space pools that the TTM layer
  * will need such as the GTT space (system memory mapped to the device),
@@ -1856,8 +1852,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
 }
 
 /**
- * amdgpu_ttm_late_init -	Handle any late initialization for
- * 							amdgpu_ttm
+ * amdgpu_ttm_late_init - Handle any late initialization for amdgpu_ttm
  */
 void amdgpu_ttm_late_init(struct amdgpu_device *adev)
 {
commit 204029e1979959ea6150c2a5c3e961800f52d0d4
Author: Junwei Zhang <Jerry.Zhang at amd.com>
Date:   Thu Jul 26 18:00:13 2018 +0800

    drm/amdgpu: correct evict flag for bo move
    
    pass the evict flag instead of hard code
    
    Signed-off-by: Junwei Zhang <Jerry.Zhang at amd.com>
    Reviewed-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 8c4358e36c87..c1ae528c7b0e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -580,7 +580,7 @@ static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, bool evict,
 	}
 
 	/* blit VRAM to GTT */
-	r = amdgpu_move_blit(bo, true, ctx->no_wait_gpu, &tmp_mem, old_mem);
+	r = amdgpu_move_blit(bo, evict, ctx->no_wait_gpu, &tmp_mem, old_mem);
 	if (unlikely(r)) {
 		goto out_cleanup;
 	}
@@ -632,7 +632,7 @@ static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo, bool evict,
 	}
 
 	/* copy to VRAM */
-	r = amdgpu_move_blit(bo, true, ctx->no_wait_gpu, new_mem, old_mem);
+	r = amdgpu_move_blit(bo, evict, ctx->no_wait_gpu, new_mem, old_mem);
 	if (unlikely(r)) {
 		goto out_cleanup;
 	}
commit 610b399f1ff269e4b9ec85cfdffb06f9befd0c41
Author: Bas Nieuwenhuizen <basni at chromium.org>
Date:   Wed Jul 25 22:29:50 2018 +0200

    drm/ttm: Merge hugepage attr changes in ttm_dma_page_put. (v2)
    
    Every set_pages_array_wb call resulted in cross-core
    interrupts and TLB flushes. Merge more of them for
    less overhead.
    
    This reduces the time needed to free a 1.6 GiB GTT WC
    buffer as part of Vulkan CTS from  ~2 sec to < 0.25 sec.
    (Allocation still takes more than 2 sec though)
    
    (v2): use set_pages_wb instead of set_memory_wb.
    
    Signed-off-by: Bas Nieuwenhuizen <basni at chromium.org>
    Signed-off-by: Huang Rui <ray.huang at amd.com>
    Reviewed-by: Christian König <christian.koenig at amd.com>
    Reviewed-by: Huang Rui <ray.huang at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
index f31148ad981c..8304917294a2 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
@@ -349,17 +349,14 @@ static void ttm_pool_update_free_locked(struct dma_pool *pool,
 static void ttm_dma_page_put(struct dma_pool *pool, struct dma_page *d_page)
 {
 	struct page *page = d_page->p;
-	unsigned i, num_pages;
+	unsigned num_pages;
 
 	/* Don't set WB on WB page pool. */
 	if (!(pool->type & IS_CACHED)) {
 		num_pages = pool->size / PAGE_SIZE;
-		for (i = 0; i < num_pages; ++i, ++page) {
-			if (ttm_set_pages_array_wb(&page, 1)) {
-				pr_err("%s: Failed to set %d pages to wb!\n",
-				       pool->dev_name, 1);
-			}
-		}
+		if (ttm_set_pages_wb(page, num_pages))
+			pr_err("%s: Failed to set %d pages to wb!\n",
+			       pool->dev_name, num_pages);
 	}
 
 	list_del(&d_page->page_list);
commit d55f9b87428f4732472ec7e9ccb7b4135751996c
Author: Huang Rui <ray.huang at amd.com>
Date:   Thu Jul 26 16:49:36 2018 +0800

    drm/ttm: clean up non-x86 definitions on ttm_page_alloc
    
    All non-x86 definitions are moved to ttm_set_memory header, so remove it from
    ttm_page_alloc.c.
    
    Suggested-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Huang Rui <ray.huang at amd.com>
    Reviewed-by: Bas Nieuwenhuizen <basni at chromium.org>
    Reviewed-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
index 6e2d1300b457..f841accc2c00 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
@@ -47,13 +47,7 @@
 
 #include <drm/ttm/ttm_bo_driver.h>
 #include <drm/ttm/ttm_page_alloc.h>
-
-#if IS_ENABLED(CONFIG_AGP)
-#include <asm/agp.h>
-#endif
-#ifdef CONFIG_X86
-#include <asm/set_memory.h>
-#endif
+#include <drm/ttm/ttm_set_memory.h>
 
 #define NUM_PAGES_TO_ALLOC		(PAGE_SIZE/sizeof(struct page *))
 #define SMALL_ALLOCATION		16
@@ -222,52 +216,6 @@ static struct kobj_type ttm_pool_kobj_type = {
 
 static struct ttm_pool_manager *_manager;
 
-#ifndef CONFIG_X86
-static int set_pages_wb(struct page *page, int numpages)
-{
-#if IS_ENABLED(CONFIG_AGP)
-	int i;
-
-	for (i = 0; i < numpages; i++)
-		unmap_page_from_agp(page++);
-#endif
-	return 0;
-}
-
-static int set_pages_array_wb(struct page **pages, int addrinarray)
-{
-#if IS_ENABLED(CONFIG_AGP)
-	int i;
-
-	for (i = 0; i < addrinarray; i++)
-		unmap_page_from_agp(pages[i]);
-#endif
-	return 0;
-}
-
-static int set_pages_array_wc(struct page **pages, int addrinarray)
-{
-#if IS_ENABLED(CONFIG_AGP)
-	int i;
-
-	for (i = 0; i < addrinarray; i++)
-		map_page_into_agp(pages[i]);
-#endif
-	return 0;
-}
-
-static int set_pages_array_uc(struct page **pages, int addrinarray)
-{
-#if IS_ENABLED(CONFIG_AGP)
-	int i;
-
-	for (i = 0; i < addrinarray; i++)
-		map_page_into_agp(pages[i]);
-#endif
-	return 0;
-}
-#endif
-
 /**
  * Select the right pool or requested caching state and ttm flags. */
 static struct ttm_page_pool *ttm_get_pool(int flags, bool huge,
@@ -302,13 +250,13 @@ static void ttm_pages_put(struct page *pages[], unsigned npages,
 	unsigned int i, pages_nr = (1 << order);
 
 	if (order == 0) {
-		if (set_pages_array_wb(pages, npages))
+		if (ttm_set_pages_array_wb(pages, npages))
 			pr_err("Failed to set %d pages to wb!\n", npages);
 	}
 
 	for (i = 0; i < npages; ++i) {
 		if (order > 0) {
-			if (set_pages_wb(pages[i], pages_nr))
+			if (ttm_set_pages_wb(pages[i], pages_nr))
 				pr_err("Failed to set %d pages to wb!\n", pages_nr);
 		}
 		__free_pages(pages[i], order);
@@ -498,12 +446,12 @@ static int ttm_set_pages_caching(struct page **pages,
 	/* Set page caching */
 	switch (cstate) {
 	case tt_uncached:
-		r = set_pages_array_uc(pages, cpages);
+		r = ttm_set_pages_array_uc(pages, cpages);
 		if (r)
 			pr_err("Failed to set %d pages to uc!\n", cpages);
 		break;
 	case tt_wc:
-		r = set_pages_array_wc(pages, cpages);
+		r = ttm_set_pages_array_wc(pages, cpages);
 		if (r)
 			pr_err("Failed to set %d pages to wc!\n", cpages);
 		break;
commit c7bb1e57e20a7f43b52df183d1a5a1aa936acc2d
Author: Huang Rui <ray.huang at amd.com>
Date:   Thu Jul 26 16:48:54 2018 +0800

    drm/ttm: clean up non-x86 definitions on ttm_page_alloc_dma
    
    All non-x86 definitions are moved to ttm_set_memory header, so remove it from
    ttm_page_alloc_dma.c.
    
    Suggested-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Huang Rui <ray.huang at amd.com>
    Reviewed-by: Bas Nieuwenhuizen <basni at chromium.org>
    Reviewed-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
index 3f14c1cc0789..f31148ad981c 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
@@ -50,12 +50,7 @@
 #include <linux/kthread.h>
 #include <drm/ttm/ttm_bo_driver.h>
 #include <drm/ttm/ttm_page_alloc.h>
-#if IS_ENABLED(CONFIG_AGP)
-#include <asm/agp.h>
-#endif
-#ifdef CONFIG_X86
-#include <asm/set_memory.h>
-#endif
+#include <drm/ttm/ttm_set_memory.h>
 
 #define NUM_PAGES_TO_ALLOC		(PAGE_SIZE/sizeof(struct page *))
 #define SMALL_ALLOCATION		4
@@ -268,41 +263,6 @@ static struct kobj_type ttm_pool_kobj_type = {
 	.default_attrs = ttm_pool_attrs,
 };
 
-#ifndef CONFIG_X86
-static int set_pages_array_wb(struct page **pages, int addrinarray)
-{
-#if IS_ENABLED(CONFIG_AGP)
-	int i;
-
-	for (i = 0; i < addrinarray; i++)
-		unmap_page_from_agp(pages[i]);
-#endif
-	return 0;
-}
-
-static int set_pages_array_wc(struct page **pages, int addrinarray)
-{
-#if IS_ENABLED(CONFIG_AGP)
-	int i;
-
-	for (i = 0; i < addrinarray; i++)
-		map_page_into_agp(pages[i]);
-#endif
-	return 0;
-}
-
-static int set_pages_array_uc(struct page **pages, int addrinarray)
-{
-#if IS_ENABLED(CONFIG_AGP)
-	int i;
-
-	for (i = 0; i < addrinarray; i++)
-		map_page_into_agp(pages[i]);
-#endif
-	return 0;
-}
-#endif /* for !CONFIG_X86 */
-
 static int ttm_set_pages_caching(struct dma_pool *pool,
 				 struct page **pages, unsigned cpages)
 {
@@ -315,7 +275,7 @@ static int ttm_set_pages_caching(struct dma_pool *pool,
 			       pool->dev_name, cpages);
 	}
 	if (pool->type & IS_WC) {
-		r = set_pages_array_wc(pages, cpages);
+		r = ttm_set_pages_array_wc(pages, cpages);
 		if (r)
 			pr_err("%s: Failed to set %d pages to wc!\n",
 			       pool->dev_name, cpages);
@@ -395,7 +355,7 @@ static void ttm_dma_page_put(struct dma_pool *pool, struct dma_page *d_page)
 	if (!(pool->type & IS_CACHED)) {
 		num_pages = pool->size / PAGE_SIZE;
 		for (i = 0; i < num_pages; ++i, ++page) {
-			if (set_pages_array_wb(&page, 1)) {
+			if (ttm_set_pages_array_wb(&page, 1)) {
 				pr_err("%s: Failed to set %d pages to wb!\n",
 				       pool->dev_name, 1);
 			}
@@ -420,7 +380,7 @@ static void ttm_dma_pages_put(struct dma_pool *pool, struct list_head *d_pages,
 
 	/* Don't set WB on WB page pool. */
 	if (npages && !(pool->type & IS_CACHED) &&
-	    set_pages_array_wb(pages, npages))
+	    ttm_set_pages_array_wb(pages, npages))
 		pr_err("%s: Failed to set %d pages to wb!\n",
 		       pool->dev_name, npages);
 
commit 2ac305b7c8d7f93a6ef0018391e9865ea4ac0d65
Author: Huang Rui <ray.huang at amd.com>
Date:   Thu Jul 26 16:32:08 2018 +0800

    drm/ttm: add ttm_set_memory header (v2)
    
    This patch moves all non-x86 abstraction to the ttm_set_memory header.
    It is to make function calling more clearly.
    
    (v2): add ttm_ prefix.
    
    Suggested-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Huang Rui <ray.huang at amd.com>
    Reviewed-by: Bas Nieuwenhuizen <basni at chromium.org>
    Reviewed-by: Christian König <christian.koenig at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/include/drm/ttm/ttm_set_memory.h b/include/drm/ttm/ttm_set_memory.h
new file mode 100644
index 000000000000..a70723cf208b
--- /dev/null
+++ b/include/drm/ttm/ttm_set_memory.h
@@ -0,0 +1,128 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2018 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Huang Rui <ray.huang at amd.com>
+ */
+
+#ifndef TTM_SET_MEMORY
+#define TTM_SET_MEMORY
+
+#include <linux/mm.h>
+
+#ifdef CONFIG_X86
+
+#include <asm/set_memory.h>
+
+static inline int ttm_set_pages_array_wb(struct page **pages, int addrinarray)
+{
+	return set_pages_array_wb(pages, addrinarray);
+}
+
+static inline int ttm_set_pages_array_wc(struct page **pages, int addrinarray)
+{
+	return set_pages_array_wc(pages, addrinarray);
+}
+
+static inline int ttm_set_pages_array_uc(struct page **pages, int addrinarray)
+{
+	return set_pages_array_uc(pages, addrinarray);
+}
+
+static inline int ttm_set_pages_wb(struct page *page, int numpages)
+{
+	return set_pages_wb(page, numpages);
+}
+
+#else /* for CONFIG_X86 */
+
+#if IS_ENABLED(CONFIG_AGP)
+
+#include <asm/agp.h>
+
+static inline int ttm_set_pages_array_wb(struct page **pages, int addrinarray)
+{
+	int i;
+
+	for (i = 0; i < addrinarray; i++)
+		unmap_page_from_agp(pages[i]);
+	return 0;
+}
+
+static inline int ttm_set_pages_array_wc(struct page **pages, int addrinarray)
+{
+	int i;
+
+	for (i = 0; i < addrinarray; i++)
+		map_page_into_agp(pages[i]);
+	return 0;
+}
+
+static inline int ttm_set_pages_array_uc(struct page **pages, int addrinarray)
+{
+	int i;
+
+	for (i = 0; i < addrinarray; i++)
+		map_page_into_agp(pages[i]);
+	return 0;
+}
+
+static inline int ttm_set_pages_wb(struct page *page, int numpages)
+{
+	int i;
+
+	for (i = 0; i < numpages; i++)
+		unmap_page_from_agp(page++);
+	return 0;
+}
+
+#else /* for CONFIG_AGP */
+
+static inline int ttm_set_pages_array_wb(struct page **pages, int addrinarray)
+{
+	return 0;
+}
+
+static inline int ttm_set_pages_array_wc(struct page **pages, int addrinarray)
+{
+	return 0;
+}
+
+static inline int ttm_set_pages_array_uc(struct page **pages, int addrinarray)
+{
+	return 0;
+}
+
+static inline int ttm_set_pages_wb(struct page *page, int numpages)
+{
+	return 0;
+}
+
+#endif /* for CONFIG_AGP */
+
+#endif /* for CONFIG_X86 */
+
+#endif
commit eb181a814c98255b32d30b383baca00e6ebec72e
Merge: 864af0d40cdc 5151842b9d87
Author: Linus Torvalds <torvalds at linux-foundation.org>
Date:   Fri Jul 27 12:51:00 2018 -0700

    Merge tag 'for-linus-20180727' of git://git.kernel.dk/linux-block
    
    Pull block fixes from Jens Axboe:
     "Bigger than usual at this time, mostly due to the O_DIRECT corruption
      issue and the fact that I was on vacation last week. This contains:
    
       - NVMe pull request with two fixes for the FC code, and two target
         fixes (Christoph)
    
       - a DIF bio reset iteration fix (Greg Edwards)
    
       - two nbd reply and requeue fixes (Josef)
    
       - SCSI timeout fixup (Keith)
    
       - a small series that fixes an issue with bio_iov_iter_get_pages(),
         which ended up causing corruption for larger sized O_DIRECT writes
         that ended up racing with buffered writes (Martin Wilck)"
    
    * tag 'for-linus-20180727' of git://git.kernel.dk/linux-block:
      block: reset bi_iter.bi_done after splitting bio
      block: bio_iov_iter_get_pages: pin more pages for multi-segment IOs
      blkdev: __blkdev_direct_IO_simple: fix leak in error case
      block: bio_iov_iter_get_pages: fix size of last iovec
      nvmet: only check for filebacking on -ENOTBLK
      nvmet: fixup crash on NULL device path
      scsi: set timed out out mq requests to complete
      blk-mq: export setting request completion state
      nvme: if_ready checks to fail io to deleting controller
      nvmet-fc: fix target sgl list on large transfers
      nbd: handle unexpected replies better
      nbd: don't requeue the same request twice.

commit 864af0d40cdc82b705e3ca79cf2a57be900954b1
Merge: 1a3d8691fd2a d97e5e6160c0
Author: Linus Torvalds <torvalds at linux-foundation.org>
Date:   Fri Jul 27 10:30:47 2018 -0700

    Merge branch 'akpm' (patches from Andrew)
    
    Merge misc fixes from Andrew Morton:
     "11 fixes"
    
    * emailed patches from Andrew Morton <akpm at linux-foundation.org>:
      kvm, mm: account shadow page tables to kmemcg
      zswap: re-check zswap_is_full() after do zswap_shrink()
      include/linux/eventfd.h: include linux/errno.h
      mm: fix vma_is_anonymous() false-positives
      mm: use vma_init() to initialize VMAs on stack and data segments
      mm: introduce vma_init()
      mm: fix exports that inadvertently make put_page() EXPORT_SYMBOL_GPL
      ipc/sem.c: prevent queue.status tearing in semop
      mm: disallow mappings that conflict for devm_memremap_pages()
      kasan: only select SLUB_DEBUG with SYSFS=y
      delayacct: fix crash in delayacct_blkio_end() after delayacct init failure

commit 1a3d8691fd2ae95f5443b2d57f91f28f6ff4700d
Merge: 6284c99cf12f bd91b56cb3b2
Author: Linus Torvalds <torvalds at linux-foundation.org>
Date:   Fri Jul 27 10:28:51 2018 -0700

    Merge tag 'pci-v4.18-fixes-4' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
    
    Pull PCI fix from Bjorn Helgaas:
     "Fix a use-after-free error in fatal error recovery (Thomas Tai)"
    
    * tag 'pci-v4.18-fixes-4' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci:
      PCI/AER: Work around use-after-free in pcie_do_fatal_recovery()

commit 6284c99cf12f1f01d8c931ba4226b0cfbc0c37db
Merge: 3c9fdefe516f 7b0eb6b41a08
Author: Linus Torvalds <torvalds at linux-foundation.org>
Date:   Fri Jul 27 10:26:02 2018 -0700

    Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
    
    Pull arm64 fixes from Will Deacon:
     "Inevitably, after saying that I hoped we would be done on the fixes
      front, a couple of issues have cropped up over the last week. Next
      time I'll stay schtum.
    
      We've fixed an over-eager BUILD_BUG_ON() which Arnd ran into with
      arndconfig, as well as ensuring that KPTI really is disabled on
      Thunder-X1, where the cure is worse than the disease (this regressed
      when we reworked the heterogeneous CPU feature checking).
    
      Summary:
    
       - Fix disabling of kpti on Thunder-X machines
    
       - Fix premature BUILD_BUG_ON() found with randconfig"
    
    * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
      arm64: fix vmemmap BUILD_BUG_ON() triggering on !vmemmap setups
      arm64: Check for errata before evaluating cpu features

commit d5ea019f8a381f88545bb26993b62ec24a2796b7
Author: Rafał Miłecki <rafal at milecki.pl>
Date:   Fri Jul 27 13:13:39 2018 +0200

    Revert "MIPS: BCM47XX: Enable 74K Core ExternalSync for PCIe erratum"
    
    This reverts commit 2a027b47dba6 ("MIPS: BCM47XX: Enable 74K Core
    ExternalSync for PCIe erratum").
    
    Enabling ExternalSync caused a regression for BCM4718A1 (used e.g. in
    Netgear E3000 and ASUS RT-N16): it simply hangs during PCIe
    initialization. It's likely that BCM4717A1 is also affected.
    
    I didn't notice that earlier as the only BCM47XX devices with PCIe I
    own are:
    1) BCM4706 with 2 x 14e4:4331
    2) BCM4706 with 14e4:4360 and 14e4:4331
    it appears that BCM4706 is unaffected.
    
    While BCM5300X-ES300-RDS.pdf seems to document that erratum and its
    workarounds (according to quotes provided by Tokunori) it seems not even
    Broadcom follows them.
    
    According to the provided info Broadcom should define CONF7_ES in their
    SDK's mipsinc.h and implement workaround in the si_mips_init(). Checking
    both didn't reveal such code. It *could* mean Broadcom also had some
    problems with the given workaround.
    
    Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
    Signed-off-by: Paul Burton <paul.burton at mips.com>
    Reported-by: Michael Marley <michael at michaelmarley.com>
    Patchwork: https://patchwork.linux-mips.org/patch/20032/
    URL: https://bugs.openwrt.org/index.php?do=details&task_id=1688
    Cc: Tokunori Ikegami <ikegami at allied-telesis.co.jp>
    Cc: Hauke Mehrtens <hauke at hauke-m.de>
    Cc: Chris Packham <chris.packham at alliedtelesis.co.nz>
    Cc: James Hogan <jhogan at kernel.org>
    Cc: Ralf Baechle <ralf at linux-mips.org>
    Cc: linux-mips at linux-mips.org

diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index 8c9cbf13d32a..6054d49e608e 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -212,12 +212,6 @@ static int __init bcm47xx_cpu_fixes(void)
 		 */
 		if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706)
 			cpu_wait = NULL;
-
-		/*
-		 * BCM47XX Erratum "R10: PCIe Transactions Periodically Fail"
-		 * Enable ExternalSync for sync instruction to take effect
-		 */
-		set_c0_config7(MIPS_CONF7_ES);
 		break;
 #endif
 	}
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 0bc270806ec5..ae461d91cd1f 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -681,8 +681,6 @@
 #define MIPS_CONF7_WII		(_ULCAST_(1) << 31)
 
 #define MIPS_CONF7_RPS		(_ULCAST_(1) << 2)
-/* ExternalSync */
-#define MIPS_CONF7_ES		(_ULCAST_(1) << 8)
 
 #define MIPS_CONF7_IAR		(_ULCAST_(1) << 10)
 #define MIPS_CONF7_AR		(_ULCAST_(1) << 16)
@@ -2767,7 +2765,6 @@ __BUILD_SET_C0(status)
 __BUILD_SET_C0(cause)
 __BUILD_SET_C0(config)
 __BUILD_SET_C0(config5)
-__BUILD_SET_C0(config7)
 __BUILD_SET_C0(intcontrol)
 __BUILD_SET_C0(intctl)
 __BUILD_SET_C0(srsmap)
commit 3c9fdefe516f350469ac105943fb1bc22e3e8196
Merge: 49b1622bdb0b 050d2a5533af
Author: Linus Torvalds <torvalds at linux-foundation.org>
Date:   Fri Jul 27 10:03:08 2018 -0700

    Merge tag 'drm-fixes-2018-07-27' of git://anongit.freedesktop.org/drm/drm
    
    Pull drm fixes from Dave Airlie:
     "Not much happening this week which is good: two imx display fixes and
      one i915 quirk addition"
    
    * tag 'drm-fixes-2018-07-27' of git://anongit.freedesktop.org/drm/drm:
      drm/i915/glk: Add Quirk for GLK NUC HDMI port issues.
      gpu: ipu-csi: Check for field type alternate
      drm/imx: imx-ldb: check if channel is enabled before printing warning
      drm/imx: imx-ldb: disable LDB on driver bind

commit 49b1622bdb0be9b1cb20d36c64a635bcc5981c4b
Merge: 3ebb6fb03dad 384cf4285b34
Author: Linus Torvalds <torvalds at linux-foundation.org>
Date:   Fri Jul 27 09:53:45 2018 -0700

    Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
    
    Pull input fixes from Dmitry Torokhov:
    
     - a couple of new device IDs added to Elan i2c touchpad controller
       driver
    
     - another entry in i8042 reset quirk list
    
    * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
      Input: i8042 - add Lenovo LaVie Z to the i8042 reset list
      Input: elan_i2c - add another ACPI ID for Lenovo Ideapad 330-15AST
      MAINTAINERS: Add file patterns for serio device tree bindings
      Input: elan_i2c - add ACPI ID for lenovo ideapad 330

commit 3ebb6fb03dad87cfd74d5bcd31b9dbcf3c82c89c
Merge: f636d300cdd6 3e536e222f29
Author: Linus Torvalds <torvalds at linux-foundation.org>
Date:   Fri Jul 27 09:50:33 2018 -0700

    Merge tag 'trace-v4.18-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
    
    Pull tracing fixes from Steven Rostedt:
     "Various fixes to the tracing infrastructure:
    
       - Fix double free when the reg() call fails in
         event_trigger_callback()
    
       - Fix anomoly of snapshot causing tracing_on flag to change
    
       - Add selftest to test snapshot and tracing_on affecting each other
    
       - Fix setting of tracepoint flag on error that prevents probes from
         being deleted.
    
       - Fix another possible double free that is similar to
         event_trigger_callback()
    
       - Quiet a gcc warning of a false positive unused variable
    
       - Fix crash of partial exposed task->comm to trace events"
    
    * tag 'trace-v4.18-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
      kthread, tracing: Don't expose half-written comm when creating kthreads
      tracing: Quiet gcc warning about maybe unused link variable
      tracing: Fix possible double free in event_enable_trigger_func()
      tracing/kprobes: Fix trace_probe flags on enable_trace_kprobe() failure
      selftests/ftrace: Add snapshot and tracing_on test case
      ring_buffer: tracing: Inherit the tracing setting to next ring buffer
      tracing: Fix double free of event_trigger_data

commit f636d300cdd6c5ff30662feb2149640eee85679a
Merge: cd3f77d74ac3 d4a34e165557
Author: Linus Torvalds <torvalds at linux-foundation.org>
Date:   Fri Jul 27 09:25:09 2018 -0700

    Merge tag 'xfs-4.18-fixes-4' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
    
    Pull xfs fixes from Darrick Wong:
    
     - Fix some uninitialized variable errors
    
     - Fix an incorrect check in metadata verifiers
    
    * tag 'xfs-4.18-fixes-4' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
      xfs: properly handle free inodes in extent hint validators
      xfs: Initialize variables in xfs_alloc_get_rec before using them

commit 5151842b9d8732d4cbfa8400b40bff894f501b2f
Author: Greg Edwards <gedwards at ddn.com>
Date:   Thu Jul 26 14:39:37 2018 -0400

    block: reset bi_iter.bi_done after splitting bio
    
    After the bio has been updated to represent the remaining sectors, reset
    bi_done so bio_rewind_iter() does not rewind further than it should.
    
    This resolves a bio_integrity_process() failure on reads where the
    original request was split.
    
    Fixes: 63573e359d05 ("bio-integrity: Restore original iterator on verify stage")
    Signed-off-by: Greg Edwards <gedwards at ddn.com>
    Signed-off-by: Jens Axboe <axboe at kernel.dk>

diff --git a/block/bio.c b/block/bio.c
index dc07a427e782..05d81912870b 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1893,6 +1893,7 @@ struct bio *bio_split(struct bio *bio, int sectors,
 		bio_integrity_trim(split);
 
 	bio_advance(bio, split->bi_iter.bi_size);
+	bio->bi_iter.bi_done = 0;
 
 	if (bio_flagged(bio, BIO_TRACE_COMPLETION))
 		bio_set_flag(split, BIO_TRACE_COMPLETION);
commit f1e582ebfd703ea01dc4caf4d339b7c84ec3ff29
Author: Alex Deucher <alexander.deucher at amd.com>
Date:   Wed Jul 25 15:11:34 2018 -0500

    drm/amdgpu: implement harvesting support for UVD 7.2 (v3)
    
    Properly handle cases where one or more instance of the IP
    block may be harvested.
    
    v2: make sure ip_num_rings is initialized amdgpu_queue_mgr.c
    v3: rebase on Christian's UVD changes, drop unused var
    
    Reviewed-by: James Zhu <James.Zhu at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index c7dce14fd47d..dd2132fa2b89 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -286,7 +286,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
 	struct drm_crtc *crtc;
 	uint32_t ui32 = 0;
 	uint64_t ui64 = 0;
-	int i, found;
+	int i, j, found;
 	int ui32_size = sizeof(ui32);
 
 	if (!info->return_size || !info->return_pointer)
@@ -348,7 +348,11 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
 			break;
 		case AMDGPU_HW_IP_UVD:
 			type = AMD_IP_BLOCK_TYPE_UVD;
-			ring_mask |= adev->uvd.inst[0].ring.ready;
+			for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
+				if (adev->uvd.harvest_config & (1 << i))
+					continue;
+				ring_mask |= adev->uvd.inst[i].ring.ready;
+			}
 			ib_start_alignment = 64;
 			ib_size_alignment = 64;
 			break;
@@ -361,9 +365,12 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
 			break;
 		case AMDGPU_HW_IP_UVD_ENC:
 			type = AMD_IP_BLOCK_TYPE_UVD;
-			for (i = 0; i < adev->uvd.num_enc_rings; i++)
-				ring_mask |=
-					adev->uvd.inst[0].ring_enc[i].ready << i;
+			for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
+				if (adev->uvd.harvest_config & (1 << i))
+					continue;
+				for (j = 0; j < adev->uvd.num_enc_rings; j++)
+					ring_mask |= adev->uvd.inst[i].ring_enc[j].ready << j;
+			}
 			ib_start_alignment = 64;
 			ib_size_alignment = 64;
 			break;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c
index d8357290ad09..a172bba32b45 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_queue_mgr.c
@@ -214,7 +214,7 @@ int amdgpu_queue_mgr_map(struct amdgpu_device *adev,
 			 u32 hw_ip, u32 instance, u32 ring,
 			 struct amdgpu_ring **out_ring)
 {
-	int r, ip_num_rings;
+	int i, r, ip_num_rings = 0;
 	struct amdgpu_queue_mapper *mapper = &mgr->mapper[hw_ip];
 
 	if (!adev || !mgr || !out_ring)
@@ -243,14 +243,21 @@ int amdgpu_queue_mgr_map(struct amdgpu_device *adev,
 		ip_num_rings = adev->sdma.num_instances;
 		break;
 	case AMDGPU_HW_IP_UVD:
-		ip_num_rings = adev->uvd.num_uvd_inst;
+		for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
+			if (!(adev->uvd.harvest_config & (1 << i)))
+				ip_num_rings++;
+		}
 		break;
 	case AMDGPU_HW_IP_VCE:
 		ip_num_rings = adev->vce.num_rings;
 		break;
 	case AMDGPU_HW_IP_UVD_ENC:
+		for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
+			if (!(adev->uvd.harvest_config & (1 << i)))
+				ip_num_rings++;
+		}
 		ip_num_rings =
-			adev->uvd.num_enc_rings * adev->uvd.num_uvd_inst;
+			adev->uvd.num_enc_rings * ip_num_rings;
 		break;
 	case AMDGPU_HW_IP_VCN_DEC:
 		ip_num_rings = 1;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index fca86d71fafc..632fa5980ff4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -255,7 +255,8 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
 		bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
 
 	for (j = 0; j < adev->uvd.num_uvd_inst; j++) {
-
+		if (adev->uvd.harvest_config & (1 << j))
+			continue;
 		r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE,
 					    AMDGPU_GEM_DOMAIN_VRAM, &adev->uvd.inst[j].vcpu_bo,
 					    &adev->uvd.inst[j].gpu_addr, &adev->uvd.inst[j].cpu_addr);
@@ -308,6 +309,8 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev)
 	drm_sched_entity_destroy(&adev->uvd.entity);
 
 	for (j = 0; j < adev->uvd.num_uvd_inst; ++j) {
+		if (adev->uvd.harvest_config & (1 << j))
+			continue;
 		kfree(adev->uvd.inst[j].saved_bo);
 
 		amdgpu_bo_free_kernel(&adev->uvd.inst[j].vcpu_bo,
@@ -343,6 +346,8 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev)
 	}
 
 	for (j = 0; j < adev->uvd.num_uvd_inst; ++j) {
+		if (adev->uvd.harvest_config & (1 << j))
+			continue;
 		if (adev->uvd.inst[j].vcpu_bo == NULL)
 			continue;
 
@@ -365,6 +370,8 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
 	int i;
 
 	for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
+		if (adev->uvd.harvest_config & (1 << i))
+			continue;
 		if (adev->uvd.inst[i].vcpu_bo == NULL)
 			return -EINVAL;
 
@@ -1159,6 +1166,8 @@ static void amdgpu_uvd_idle_work_handler(struct work_struct *work)
 	unsigned fences = 0, i, j;
 
 	for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
+		if (adev->uvd.harvest_config & (1 << i))
+			continue;
 		fences += amdgpu_fence_count_emitted(&adev->uvd.inst[i].ring);
 		for (j = 0; j < adev->uvd.num_enc_rings; ++j) {
 			fences += amdgpu_fence_count_emitted(&adev->uvd.inst[i].ring_enc[j]);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h
index 66872286ab12..33c5f806f925 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h
@@ -48,6 +48,9 @@ struct amdgpu_uvd_inst {
 	uint32_t                srbm_soft_reset;
 };
 
+#define AMDGPU_UVD_HARVEST_UVD0 (1 << 0)
+#define AMDGPU_UVD_HARVEST_UVD1 (1 << 1)
+
 struct amdgpu_uvd {
 	const struct firmware	*fw;	/* UVD firmware */
 	unsigned		fw_version;
@@ -61,6 +64,7 @@ struct amdgpu_uvd {
 	atomic_t		handles[AMDGPU_MAX_UVD_HANDLES];
 	struct drm_sched_entity entity;
 	struct delayed_work	idle_work;
+	unsigned		harvest_config;
 };
 
 int amdgpu_uvd_sw_init(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
index d74c1b242667..5fab3560a71d 100644
--- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
@@ -41,6 +41,12 @@
 #include "mmhub/mmhub_1_0_sh_mask.h"
 #include "ivsrcid/uvd/irqsrcs_uvd_7_0.h"
 
+#define mmUVD_PG0_CC_UVD_HARVESTING                                                                    0x00c7
+#define mmUVD_PG0_CC_UVD_HARVESTING_BASE_IDX                                                           1
+//UVD_PG0_CC_UVD_HARVESTING
+#define UVD_PG0_CC_UVD_HARVESTING__UVD_DISABLE__SHIFT                                                         0x1
+#define UVD_PG0_CC_UVD_HARVESTING__UVD_DISABLE_MASK                                                           0x00000002L
+
 #define UVD7_MAX_HW_INSTANCES_VEGA20			2
 
 static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev);
@@ -370,10 +376,25 @@ error:
 static int uvd_v7_0_early_init(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-	if (adev->asic_type == CHIP_VEGA20)
+
+	if (adev->asic_type == CHIP_VEGA20) {
+		u32 harvest;
+		int i;
+
 		adev->uvd.num_uvd_inst = UVD7_MAX_HW_INSTANCES_VEGA20;
-	else
+		for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
+			harvest = RREG32_SOC15(UVD, i, mmUVD_PG0_CC_UVD_HARVESTING);
+			if (harvest & UVD_PG0_CC_UVD_HARVESTING__UVD_DISABLE_MASK) {
+				adev->uvd.harvest_config |= 1 << i;
+			}
+		}
+		if (adev->uvd.harvest_config == (AMDGPU_UVD_HARVEST_UVD0 |
+						 AMDGPU_UVD_HARVEST_UVD1))
+			/* both instances are harvested, disable the block */
+			return -ENOENT;
+	} else {
 		adev->uvd.num_uvd_inst = 1;
+	}
 
 	if (amdgpu_sriov_vf(adev))
 		adev->uvd.num_enc_rings = 1;
@@ -393,6 +414,8 @@ static int uvd_v7_0_sw_init(void *handle)
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
 	for (j = 0; j < adev->uvd.num_uvd_inst; j++) {
+		if (adev->uvd.harvest_config & (1 << j))
+			continue;
 		/* UVD TRAP */
 		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_uvds[j], UVD_7_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->uvd.inst[j].irq);
 		if (r)
@@ -425,6 +448,8 @@ static int uvd_v7_0_sw_init(void *handle)
 		return r;
 
 	for (j = 0; j < adev->uvd.num_uvd_inst; j++) {
+		if (adev->uvd.harvest_config & (1 << j))
+			continue;
 		if (!amdgpu_sriov_vf(adev)) {
 			ring = &adev->uvd.inst[j].ring;
 			sprintf(ring->name, "uvd<%d>", j);
@@ -472,6 +497,8 @@ static int uvd_v7_0_sw_fini(void *handle)
 		return r;
 
 	for (j = 0; j < adev->uvd.num_uvd_inst; ++j) {
+		if (adev->uvd.harvest_config & (1 << j))
+			continue;
 		for (i = 0; i < adev->uvd.num_enc_rings; ++i)
 			amdgpu_ring_fini(&adev->uvd.inst[j].ring_enc[i]);
 	}
@@ -500,6 +527,8 @@ static int uvd_v7_0_hw_init(void *handle)
 		goto done;
 
 	for (j = 0; j < adev->uvd.num_uvd_inst; ++j) {
+		if (adev->uvd.harvest_config & (1 << j))
+			continue;
 		ring = &adev->uvd.inst[j].ring;
 
 		if (!amdgpu_sriov_vf(adev)) {
@@ -579,8 +608,11 @@ static int uvd_v7_0_hw_fini(void *handle)
 		DRM_DEBUG("For SRIOV client, shouldn't do anything.\n");
 	}
 
-	for (i = 0; i < adev->uvd.num_uvd_inst; ++i)
+	for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
+		if (adev->uvd.harvest_config & (1 << i))
+			continue;
 		adev->uvd.inst[i].ring.ready = false;
+	}
 
 	return 0;
 }
@@ -623,6 +655,8 @@ static void uvd_v7_0_mc_resume(struct amdgpu_device *adev)
 	int i;
 
 	for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
+		if (adev->uvd.harvest_config & (1 << i))
+			continue;
 		if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
 			WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
 				lower_32_bits(adev->firmware.ucode[AMDGPU_UCODE_ID_UVD].mc_addr));
@@ -695,6 +729,8 @@ static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev,
 	WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_RESP, 0);
 
 	for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
+		if (adev->uvd.harvest_config & (1 << i))
+			continue;
 		WDOORBELL32(adev->uvd.inst[i].ring_enc[0].doorbell_index, 0);
 		adev->wb.wb[adev->uvd.inst[i].ring_enc[0].wptr_offs] = 0;
 		adev->uvd.inst[i].ring_enc[0].wptr = 0;
@@ -751,6 +787,8 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev)
 		init_table += header->uvd_table_offset;
 
 		for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
+			if (adev->uvd.harvest_config & (1 << i))
+				continue;
 			ring = &adev->uvd.inst[i].ring;
 			ring->wptr = 0;
 			size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4);
@@ -890,6 +928,8 @@ static int uvd_v7_0_start(struct amdgpu_device *adev)
 	int i, j, k, r;
 
 	for (k = 0; k < adev->uvd.num_uvd_inst; ++k) {
+		if (adev->uvd.harvest_config & (1 << k))
+			continue;
 		/* disable DPG */
 		WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_POWER_STATUS), 0,
 				~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
@@ -902,6 +942,8 @@ static int uvd_v7_0_start(struct amdgpu_device *adev)
 	uvd_v7_0_mc_resume(adev);
 
 	for (k = 0; k < adev->uvd.num_uvd_inst; ++k) {
+		if (adev->uvd.harvest_config & (1 << k))
+			continue;
 		ring = &adev->uvd.inst[k].ring;
 		/* disable clock gating */
 		WREG32_P(SOC15_REG_OFFSET(UVD, k, mmUVD_CGC_CTRL), 0,
@@ -1069,6 +1111,8 @@ static void uvd_v7_0_stop(struct amdgpu_device *adev)
 	uint8_t i = 0;
 
 	for (i = 0; i < adev->uvd.num_uvd_inst; ++i) {
+		if (adev->uvd.harvest_config & (1 << i))
+			continue;
 		/* force RBC into idle state */
 		WREG32_SOC15(UVD, i, mmUVD_RBC_RB_CNTL, 0x11010101);
 
@@ -1785,6 +1829,8 @@ static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev)
 	int i;
 
 	for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
+		if (adev->uvd.harvest_config & (1 << i))
+			continue;
 		adev->uvd.inst[i].ring.funcs = &uvd_v7_0_ring_vm_funcs;
 		adev->uvd.inst[i].ring.me = i;
 		DRM_INFO("UVD(%d) is enabled in VM mode\n", i);
@@ -1796,6 +1842,8 @@ static void uvd_v7_0_set_enc_ring_funcs(struct amdgpu_device *adev)
 	int i, j;
 
 	for (j = 0; j < adev->uvd.num_uvd_inst; j++) {
+		if (adev->uvd.harvest_config & (1 << j))
+			continue;
 		for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
 			adev->uvd.inst[j].ring_enc[i].funcs = &uvd_v7_0_enc_ring_vm_funcs;
 			adev->uvd.inst[j].ring_enc[i].me = j;
@@ -1815,6 +1863,8 @@ static void uvd_v7_0_set_irq_funcs(struct amdgpu_device *adev)
 	int i;
 
 	for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
+		if (adev->uvd.harvest_config & (1 << i))
+			continue;
 		adev->uvd.inst[i].irq.num_types = adev->uvd.num_enc_rings + 1;
 		adev->uvd.inst[i].irq.funcs = &uvd_v7_0_irq_funcs;
 	}
commit d04cc604a66b07eff8fce824fb6c0fdc0875d2e3
Author: Harry Wentland <harry.wentland at amd.com>
Date:   Wed Jul 25 09:45:47 2018 -0400

    drm/amd: Add missing fields in atom_integrated_system_info_v1_11
    
    This structure needs to align with structure in atomfirmware table.
    Update it.
    
    Signed-off-by: Harry Wentland <harry.wentland at amd.com>
    Acked-by: Alex Deucher <alexander.deucher at amd.com>
    Reviewed-by: Dmytro Laktyushkin <dmytro.laktyushkin at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
index 33b4de4ad66e..4bc118df3bc4 100644
--- a/drivers/gpu/drm/amd/include/atomfirmware.h
+++ b/drivers/gpu/drm/amd/include/atomfirmware.h
@@ -1074,7 +1074,7 @@ struct atom_integrated_system_info_v1_11
   uint16_t  dpphy_override;                   // bit vector, enum of atom_sysinfo_dpphy_override_def
   uint16_t  lvds_misc;                        // enum of atom_sys_info_lvds_misc_def
   uint16_t  backlight_pwm_hz;                 // pwm frequency in hz
-  uint8_t   memorytype;                       // enum of atom_sys_mem_type
+  uint8_t   memorytype;                       // enum of atom_dmi_t17_mem_type_def, APU memory type indication.
   uint8_t   umachannelnumber;                 // number of memory channels
   uint8_t   pwr_on_digon_to_de;               /* all pwr sequence numbers below are in uint of 4ms */
   uint8_t   pwr_on_de_to_vary_bl;
@@ -1084,18 +1084,25 @@ struct atom_integrated_system_info_v1_11
   uint8_t   pwr_on_vary_bl_to_blon;
   uint8_t   pwr_down_bloff_to_vary_bloff;
   uint8_t   min_allowed_bl_level;
+  uint8_t   htc_hyst_limit;
+  uint8_t   htc_tmp_limit;
+  uint8_t   reserved1;
+  uint8_t   reserved2;
   struct atom_external_display_connection_info extdispconninfo;
   struct atom_14nm_dpphy_dvihdmi_tuningset dvi_tuningset;
   struct atom_14nm_dpphy_dvihdmi_tuningset hdmi_tuningset;
   struct atom_14nm_dpphy_dvihdmi_tuningset hdmi6g_tuningset;
-  struct atom_14nm_dpphy_dp_tuningset dp_tuningset;
-  struct atom_14nm_dpphy_dp_tuningset dp_hbr3_tuningset;
+  struct atom_14nm_dpphy_dp_tuningset dp_tuningset;        // rbr 1.62G dp tuning set
+  struct atom_14nm_dpphy_dp_tuningset dp_hbr3_tuningset;   // HBR3 dp tuning set
   struct atom_camera_data  camera_info;
   struct atom_hdmi_retimer_redriver_set dp0_retimer_set;   //for DP0
   struct atom_hdmi_retimer_redriver_set dp1_retimer_set;   //for DP1
   struct atom_hdmi_retimer_redriver_set dp2_retimer_set;   //for DP2
   struct atom_hdmi_retimer_redriver_set dp3_retimer_set;   //for DP3
-  uint32_t  reserved[108];
+  struct atom_14nm_dpphy_dp_tuningset dp_hbr_tuningset;    //hbr 2.7G dp tuning set
+  struct atom_14nm_dpphy_dp_tuningset dp_hbr2_tuningset;   //hbr2 5.4G dp turnig set
+  struct atom_14nm_dpphy_dp_tuningset edp_tuningset;       //edp tuning set
+  uint32_t  reserved[66];
 };
 
 
commit 116f451c90a94de6203757c117278b99a837d3b5
Author: Harry Wentland <harry.wentland at amd.com>
Date:   Mon Jul 9 17:26:34 2018 -0400

    drm/amd/display: DC 3.1.59
    
    Signed-off-by: Harry Wentland <harry.wentland at amd.com>
    Reviewed-by: Aric Cyr <Aric.Cyr at amd.com>
    Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 7515c0dcbdd2..c2d390fba0bf 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -38,7 +38,7 @@
 #include "inc/compressor.h"
 #include "dml/display_mode_lib.h"
 
-#define DC_VER "3.1.58"
+#define DC_VER "3.1.59"
 
 #define MAX_SURFACES 3
 #define MAX_STREAMS 6
commit 9907704174e0ad4ed02766fac4049971e583323d
Author: Anthony Koo <Anthony.Koo at amd.com>
Date:   Tue Jul 17 09:43:44 2018 -0400

    drm/amd/display: Prevent PSR from being enabled if initialization fails
    
    [Why]
    PSR_SET command is sent to the microcontroller in order to initialize
    parameters needed for PSR feature, such as telling the microcontroller
    which pipe is driving the PSR supported panel. When this command is
    skipped or fails, the microcontroller may program the wrong thing if
    driver tries to enable PSR.
    
    [How]
    If PSR_SET fails, do not set psr_enable flag to indicate the feature is
    not yet initialized.
    
    Signed-off-by: Anthony Koo <Anthony.Koo at amd.com>
    Reviewed-by: Aric Cyr <Aric.Cyr at amd.com>
    Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
index 062a46543887..ca7989e4932b 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
@@ -150,7 +150,7 @@ static void dce_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)
 	}
 }
 
-static void dce_dmcu_setup_psr(struct dmcu *dmcu,
+static bool dce_dmcu_setup_psr(struct dmcu *dmcu,
 		struct dc_link *link,
 		struct psr_context *psr_context)
 {
@@ -261,6 +261,8 @@ static void dce_dmcu_setup_psr(struct dmcu *dmcu,
 
 	/* notifyDMCUMsg */
 	REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
+
+	return true;
 }
 
 static bool dce_is_dmcu_initialized(struct dmcu *dmcu)
@@ -545,24 +547,25 @@ static void dcn10_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)
 	 *  least a few frames. Should never hit the max retry assert below.
 	 */
 	if (wait == true) {
-	for (retryCount = 0; retryCount <= 1000; retryCount++) {
-		dcn10_get_dmcu_psr_state(dmcu, &psr_state);
-		if (enable) {
-			if (psr_state != 0)
-				break;
-		} else {
-			if (psr_state == 0)
-				break;
+		for (retryCount = 0; retryCount <= 1000; retryCount++) {
+			dcn10_get_dmcu_psr_state(dmcu, &psr_state);
+			if (enable) {
+				if (psr_state != 0)
+					break;
+			} else {
+				if (psr_state == 0)
+					break;
+			}
+			udelay(500);
 		}
-		udelay(500);
-	}
 
-	/* assert if max retry hit */
-	ASSERT(retryCount <= 1000);
+		/* assert if max retry hit */
+		if (retryCount >= 1000)
+			ASSERT(0);
 	}
 }
 
-static void dcn10_dmcu_setup_psr(struct dmcu *dmcu,
+static bool dcn10_dmcu_setup_psr(struct dmcu *dmcu,
 		struct dc_link *link,
 		struct psr_context *psr_context)
 {
@@ -577,7 +580,7 @@ static void dcn10_dmcu_setup_psr(struct dmcu *dmcu,
 
 	/* If microcontroller is not running, do nothing */
 	if (dmcu->dmcu_state != DMCU_RUNNING)
-		return;
+		return false;
 
 	link->link_enc->funcs->psr_program_dp_dphy_fast_training(link->link_enc,
 			psr_context->psrExitLinkTrainingRequired);
@@ -677,6 +680,11 @@ static void dcn10_dmcu_setup_psr(struct dmcu *dmcu,
 
 	/* notifyDMCUMsg */
 	REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
+
+	/* waitDMCUReadyForCmd */
+	REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 1, 10000);
+
+	return true;
 }
 
 static void dcn10_psr_wait_loop(
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
index de60f940030d..4550747fb61c 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h
@@ -48,7 +48,7 @@ struct dmcu_funcs {
 			const char *src,
 			unsigned int bytes);
 	void (*set_psr_enable)(struct dmcu *dmcu, bool enable, bool wait);
-	void (*setup_psr)(struct dmcu *dmcu,
+	bool (*setup_psr)(struct dmcu *dmcu,
 			struct dc_link *link,
 			struct psr_context *psr_context);
 	void (*get_psr_state)(struct dmcu *dmcu, uint32_t *psr_state);
commit f358b39d187500717b4bc8633cef45d87eff0a3e
Author: Jerry (Fangzhi) Zuo <Jerry.Zuo at amd.com>
Date:   Tue Jul 17 11:53:54 2018 -0400

    drm/amd/display: Fix Vega10 black screen after mode change
    
    [Why]
    The sequence is slightly changed when bring .set_bandwidth out
    from the end of programming backend to the end of programming
    surface. Vega10 doesn't like to get clocks updated if
    stream_count is zero in the current context (Atomic Reset).
    
    [How]
    Do not update clocks if no stream is showing up in the context.
    
    Fixes 1b2b130192 "dc: Remove 300Mhz minimum disp clk limit."
    
    Signed-off-by: Jerry (Fangzhi) Zuo <Jerry.Zuo at amd.com>
    Reviewed-by: Tony Cheng <Tony.Cheng at amd.com>
    Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index 33a14e163f88..1149c413f6d2 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -2552,7 +2552,7 @@ static void pplib_apply_display_requirements(
 	dc->prev_display_config = *pp_display_cfg;
 }
 
-static void dce110_set_bandwidth(
+void dce110_set_bandwidth(
 		struct dc *dc,
 		struct dc_state *context,
 		bool decrease_allowed)
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
index d6db3dbd9015..e4c5db75c4c6 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h
@@ -68,6 +68,11 @@ void dce110_fill_display_configs(
 	const struct dc_state *context,
 	struct dm_pp_display_configuration *pp_display_cfg);
 
+void dce110_set_bandwidth(
+		struct dc *dc,
+		struct dc_state *context,
+		bool decrease_allowed);
+
 uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context);
 
 void dp_receiver_power_ctrl(struct dc_link *link, bool on);
diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c
index e96ff86d2fc3..5853522a6182 100644
--- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c
@@ -244,7 +244,16 @@ static void dce120_update_dchub(
 	dh_data->dchub_info_valid = false;
 }
 
+static void dce120_set_bandwidth(
+		struct dc *dc,
+		struct dc_state *context,
+		bool decrease_allowed)
+{
+	if (context->stream_count <= 0)
+		return;
 
+	dce110_set_bandwidth(dc, context, decrease_allowed);
+}
 
 void dce120_hw_sequencer_construct(struct dc *dc)
 {
@@ -254,5 +263,6 @@ void dce120_hw_sequencer_construct(struct dc *dc)
 	dce110_hw_sequencer_construct(dc);
 	dc->hwss.enable_display_power_gating = dce120_enable_display_power_gating;
 	dc->hwss.update_dchub = dce120_update_dchub;
+	dc->hwss.set_bandwidth = dce120_set_bandwidth;
 }
 
commit 65c78961b30005447a0d9b285de93354d8308f34
Author: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
Date:   Thu Jun 28 17:50:05 2018 -0400

    drm/amd/display: flatten aux_engine and engine
    
    [Why]
    engine and aux_engine are unnecessary layers we want to remove this
    layer.
    
    [How]
    flatten engine and aux engine structs into one struct called
    aux_engine and remove all references to the engine struct.
    
    Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Reviewed-by: Harry Wentland <Harry.Wentland at amd.com>
    Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
index 4019fe07d291..8def0d9fa0ff 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
@@ -33,7 +33,6 @@
 #include "include/vector.h"
 #include "core_types.h"
 #include "dc_link_ddc.h"
-#include "engine.h"
 #include "aux_engine.h"
 
 #define AUX_POWER_UP_WA_DELAY 500
@@ -640,7 +639,6 @@ int dc_link_aux_transfer(struct ddc_service *ddc,
 			     enum i2caux_transaction_action action)
 {
 	struct ddc *ddc_pin = ddc->ddc_pin;
-	struct engine *engine;
 	struct aux_engine *aux_engine;
 	enum aux_channel_operation_result operation_result;
 	struct aux_request_transaction_data aux_req;
@@ -652,8 +650,8 @@ int dc_link_aux_transfer(struct ddc_service *ddc,
 	memset(&aux_req, 0, sizeof(aux_req));
 	memset(&aux_rep, 0, sizeof(aux_rep));
 
-	engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
-	aux_engine = engine->funcs->acquire(engine, ddc_pin);
+	aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
+	aux_engine->funcs->acquire(aux_engine, ddc_pin);
 
 	aux_req.type = type;
 	aux_req.action = action;
@@ -685,7 +683,7 @@ int dc_link_aux_transfer(struct ddc_service *ddc,
 		res = -1;
 		break;
 	}
-	aux_engine->base.funcs->release_engine(&aux_engine->base);
+	aux_engine->funcs->release_engine(aux_engine);
 	return res;
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
index b28e2120767e..3f5b2e6f7553 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
@@ -28,12 +28,12 @@
 #include "dce/dce_11_0_sh_mask.h"
 
 #define CTX \
-	aux110->base.base.ctx
+	aux110->base.ctx
 #define REG(reg_name)\
 	(aux110->regs->reg_name)
 
 #define DC_LOGGER \
-	engine->base.ctx->logger
+	engine->ctx->logger
 
 #include "reg_helper.h"
 
@@ -51,9 +51,9 @@ enum {
 	AUX_DEFER_RETRY_COUNTER = 6
 };
 static void release_engine(
-	struct engine *engine)
+	struct aux_engine *engine)
 {
-	struct aux_engine_dce110 *aux110 = FROM_ENGINE(engine);
+	struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
 
 	dal_ddc_close(engine->ddc);
 
@@ -827,22 +827,21 @@ static bool end_of_transaction_command(
 
 	/* according Syed, it does not need now DoDummyMOT */
 }
-bool submit_request(
-	struct engine *engine,
+static bool submit_request(
+	struct aux_engine *engine,
 	struct i2caux_transaction_request *request,
 	bool middle_of_transaction)
 {
-	struct aux_engine *aux_engine = FROM_AUX_ENGINE_ENGINE(engine);
 
 	bool result;
 	bool mot_used = true;
 
 	switch (request->operation) {
 	case I2CAUX_TRANSACTION_READ:
-		result = read_command(aux_engine, request, mot_used);
+		result = read_command(engine, request, mot_used);
 	break;
 	case I2CAUX_TRANSACTION_WRITE:
-		result = write_command(aux_engine, request, mot_used);
+		result = write_command(engine, request, mot_used);
 	break;
 	default:
 		result = false;
@@ -854,45 +853,45 @@ bool submit_request(
 	 */
 
 	if (!middle_of_transaction || !result)
-		end_of_transaction_command(aux_engine, request);
+		end_of_transaction_command(engine, request);
 
 	/* mask AUX interrupt */
 
 	return result;
 }
 enum i2caux_engine_type get_engine_type(
-		const struct engine *engine)
+		const struct aux_engine *engine)
 {
 	return I2CAUX_ENGINE_TYPE_AUX;
 }
 
-static struct aux_engine *acquire(
-	struct engine *engine,
+static bool acquire(
+	struct aux_engine *engine,
 	struct ddc *ddc)
 {
-	struct aux_engine *aux_engine = FROM_AUX_ENGINE_ENGINE(engine);
+
 	enum gpio_result result;
 
-	if (aux_engine->funcs->is_engine_available) {
+	if (engine->funcs->is_engine_available) {
 		/*check whether SW could use the engine*/
-		if (!aux_engine->funcs->is_engine_available(aux_engine))
-			return NULL;
+		if (!engine->funcs->is_engine_available(engine))
+			return false;
 	}
 
 	result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE,
 		GPIO_DDC_CONFIG_TYPE_MODE_AUX);
 
 	if (result != GPIO_RESULT_OK)
-		return NULL;
+		return false;
 
-	if (!aux_engine->funcs->acquire_engine(aux_engine)) {
+	if (!engine->funcs->acquire_engine(engine)) {
 		dal_ddc_close(ddc);
-		return NULL;
+		return false;
 	}
 
 	engine->ddc = ddc;
 
-	return aux_engine;
+	return true;
 }
 
 static const struct aux_engine_funcs aux_engine_funcs = {
@@ -902,9 +901,6 @@ static const struct aux_engine_funcs aux_engine_funcs = {
 	.read_channel_reply = read_channel_reply,
 	.get_channel_status = get_channel_status,
 	.is_engine_available = is_engine_available,
-};
-
-static const struct engine_funcs engine_funcs = {
 	.release_engine = release_engine,
 	.destroy_engine = dce110_engine_destroy,
 	.submit_request = submit_request,
@@ -912,10 +908,10 @@ static const struct engine_funcs engine_funcs = {
 	.acquire = acquire,
 };
 
-void dce110_engine_destroy(struct engine **engine)
+void dce110_engine_destroy(struct aux_engine **engine)
 {
 
-	struct aux_engine_dce110 *engine110 = FROM_ENGINE(*engine);
+	struct aux_engine_dce110 *engine110 = FROM_AUX_ENGINE(*engine);
 
 	kfree(engine110);
 	*engine = NULL;
@@ -927,13 +923,12 @@ struct aux_engine *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_eng
 		uint32_t timeout_period,
 		const struct dce110_aux_registers *regs)
 {
-	aux_engine110->base.base.ddc = NULL;
-	aux_engine110->base.base.ctx = ctx;
+	aux_engine110->base.ddc = NULL;
+	aux_engine110->base.ctx = ctx;
 	aux_engine110->base.delay = 0;
 	aux_engine110->base.max_defer_write_retry = 0;
-	aux_engine110->base.base.funcs = &engine_funcs;
 	aux_engine110->base.funcs = &aux_engine_funcs;
-	aux_engine110->base.base.inst = inst;
+	aux_engine110->base.inst = inst;
 	aux_engine110->timeout_period = timeout_period;
 	aux_engine110->regs = regs;
 
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h
index c6b2aec2e367..f7caab85dc80 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h
@@ -103,9 +103,9 @@ struct aux_engine *dce110_aux_engine_construct(
 		uint32_t timeout_period,
 		const struct dce110_aux_registers *regs);
 
-void dce110_engine_destroy(struct engine **engine);
+void dce110_engine_destroy(struct aux_engine **engine);
 
 bool dce110_aux_engine_acquire(
-	struct engine *aux_engine,
+	struct aux_engine *aux_engine,
 	struct ddc *ddc);
 #endif
diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
index c34c9531915e..fd2bdae4dcec 100644
--- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
@@ -586,7 +586,7 @@ struct output_pixel_processor *dce100_opp_create(
 	return &opp->base;
 }
 
-struct engine *dce100_aux_engine_create(
+struct aux_engine *dce100_aux_engine_create(
 	struct dc_context *ctx,
 	uint32_t inst)
 {
@@ -600,7 +600,7 @@ struct engine *dce100_aux_engine_create(
 				    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
 				    &aux_engine_regs[inst]);
 
-	return &aux_engine->base.base;
+	return &aux_engine->base;
 }
 
 struct clock_source *dce100_clock_source_create(
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
index 4a665a29191b..e5e9e92521e9 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
@@ -604,7 +604,7 @@ static struct output_pixel_processor *dce110_opp_create(
 	return &opp->base;
 }
 
-struct engine *dce110_aux_engine_create(
+struct aux_engine *dce110_aux_engine_create(
 	struct dc_context *ctx,
 	uint32_t inst)
 {
@@ -618,7 +618,7 @@ struct engine *dce110_aux_engine_create(
 				    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
 				    &aux_engine_regs[inst]);
 
-	return &aux_engine->base.base;
+	return &aux_engine->base;
 }
 
 struct clock_source *dce110_clock_source_create(
diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
index caf90ae2cbb0..84a05ff2d674 100644
--- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
@@ -604,7 +604,7 @@ struct output_pixel_processor *dce112_opp_create(
 	return &opp->base;
 }
 
-struct engine *dce112_aux_engine_create(
+struct aux_engine *dce112_aux_engine_create(
 	struct dc_context *ctx,
 	uint32_t inst)
 {
@@ -618,7 +618,7 @@ struct engine *dce112_aux_engine_create(
 				    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
 				    &aux_engine_regs[inst]);
 
-	return &aux_engine->base.base;
+	return &aux_engine->base;
 }
 
 struct clock_source *dce112_clock_source_create(
diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
index f7d02f2190d3..61d8e22d23c9 100644
--- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
@@ -376,7 +376,7 @@ struct output_pixel_processor *dce120_opp_create(
 			     ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);
 	return &opp->base;
 }
-struct engine *dce120_aux_engine_create(
+struct aux_engine *dce120_aux_engine_create(
 	struct dc_context *ctx,
 	uint32_t inst)
 {
@@ -390,7 +390,7 @@ struct engine *dce120_aux_engine_create(
 				    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
 				    &aux_engine_regs[inst]);
 
-	return &aux_engine->base.base;
+	return &aux_engine->base;
 }
 
 static const struct bios_registers bios_regs = {
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
index 6fb33ad2d3c8..dc9f3e9afc33 100644
--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
@@ -464,7 +464,7 @@ static struct output_pixel_processor *dce80_opp_create(
 	return &opp->base;
 }
 
-struct engine *dce80_aux_engine_create(
+struct aux_engine *dce80_aux_engine_create(
 	struct dc_context *ctx,
 	uint32_t inst)
 {
@@ -478,7 +478,7 @@ struct engine *dce80_aux_engine_create(
 				    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
 				    &aux_engine_regs[inst]);
 
-	return &aux_engine->base.base;
+	return &aux_engine->base;
 }
 
 static struct stream_encoder *dce80_stream_encoder_create(
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
index cd8c22839227..5d169f07d745 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -594,7 +594,7 @@ static struct output_pixel_processor *dcn10_opp_create(
 	return &opp->base;
 }
 
-struct engine *dcn10_aux_engine_create(
+struct aux_engine *dcn10_aux_engine_create(
 	struct dc_context *ctx,
 	uint32_t inst)
 {
@@ -608,7 +608,7 @@ struct engine *dcn10_aux_engine_create(
 				    SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
 				    &aux_engine_regs[inst]);
 
-	return &aux_engine->base.base;
+	return &aux_engine->base;
 }
 
 static struct mpc *dcn10_mpc_create(struct dc_context *ctx)
diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
index 0fa385872ed3..9f33306f9014 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -138,7 +138,7 @@ struct resource_pool {
 	struct output_pixel_processor *opps[MAX_PIPES];
 	struct timing_generator *timing_generators[MAX_PIPES];
 	struct stream_encoder *stream_enc[MAX_PIPES * 2];
-	struct engine *engines[MAX_PIPES];
+	struct aux_engine *engines[MAX_PIPES];
 	struct hubbub *hubbub;
 	struct mpc *mpc;
 	struct pp_smu_funcs_rv *pp_smu;
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h b/drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h
index 06d7e5d4cf21..e79cd4e92919 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h
@@ -26,46 +26,72 @@
 #ifndef __DAL_AUX_ENGINE_H__
 #define __DAL_AUX_ENGINE_H__
 
-#include "engine.h"
+#include "dc_ddc_types.h"
 #include "include/i2caux_interface.h"
 
-struct aux_engine;
-union aux_config;
-struct aux_engine_funcs {
-	void (*destroy)(
-		struct aux_engine **ptr);
-	bool (*acquire_engine)(
-		struct aux_engine *engine);
-	void (*configure)(
-		struct aux_engine *engine,
-		union aux_config cfg);
-	void (*submit_channel_request)(
-		struct aux_engine *engine,
-		struct aux_request_transaction_data *request);
-	void (*process_channel_reply)(
-		struct aux_engine *engine,
-		struct aux_reply_transaction_data *reply);
-	int (*read_channel_reply)(
-		struct aux_engine *engine,
-		uint32_t size,
-		uint8_t *buffer,
-		uint8_t *reply_result,
-		uint32_t *sw_status);
-	enum aux_channel_operation_result (*get_channel_status)(
-		struct aux_engine *engine,
-		uint8_t *returned_bytes);
-	bool (*is_engine_available)(struct aux_engine *engine);
+enum i2caux_transaction_operation {
+	I2CAUX_TRANSACTION_READ,
+	I2CAUX_TRANSACTION_WRITE
+};
+
+enum i2caux_transaction_address_space {
+	I2CAUX_TRANSACTION_ADDRESS_SPACE_I2C = 1,
+	I2CAUX_TRANSACTION_ADDRESS_SPACE_DPCD
+};
+
+struct i2caux_transaction_payload {
+	enum i2caux_transaction_address_space address_space;
+	uint32_t address;
+	uint32_t length;
+	uint8_t *data;
+};
+
+enum i2caux_transaction_status {
+	I2CAUX_TRANSACTION_STATUS_UNKNOWN = (-1L),
+	I2CAUX_TRANSACTION_STATUS_SUCCEEDED,
+	I2CAUX_TRANSACTION_STATUS_FAILED_CHANNEL_BUSY,
+	I2CAUX_TRANSACTION_STATUS_FAILED_TIMEOUT,
+	I2CAUX_TRANSACTION_STATUS_FAILED_PROTOCOL_ERROR,
+	I2CAUX_TRANSACTION_STATUS_FAILED_NACK,
+	I2CAUX_TRANSACTION_STATUS_FAILED_INCOMPLETE,
+	I2CAUX_TRANSACTION_STATUS_FAILED_OPERATION,
+	I2CAUX_TRANSACTION_STATUS_FAILED_INVALID_OPERATION,
+	I2CAUX_TRANSACTION_STATUS_FAILED_BUFFER_OVERFLOW,
+	I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON
+};
+
+struct i2caux_transaction_request {
+	enum i2caux_transaction_operation operation;
+	struct i2caux_transaction_payload payload;
+	enum i2caux_transaction_status status;
+};
+
+enum i2caux_engine_type {
+	I2CAUX_ENGINE_TYPE_UNKNOWN = (-1L),
+	I2CAUX_ENGINE_TYPE_AUX,
+	I2CAUX_ENGINE_TYPE_I2C_DDC_HW,
+	I2CAUX_ENGINE_TYPE_I2C_GENERIC_HW,
+	I2CAUX_ENGINE_TYPE_I2C_SW
+};
+
+enum i2c_default_speed {
+	I2CAUX_DEFAULT_I2C_HW_SPEED = 50,
+	I2CAUX_DEFAULT_I2C_SW_SPEED = 50
 };
-struct engine;
+
+union aux_config;
+
 struct aux_engine {
-	struct engine base;
+	uint32_t inst;
+	struct ddc *ddc;
+	struct dc_context *ctx;
 	const struct aux_engine_funcs *funcs;
 	/* following values are expressed in milliseconds */
 	uint32_t delay;
 	uint32_t max_defer_write_retry;
-
 	bool acquire_reset;
 };
+
 struct read_command_context {
 	uint8_t *buffer;
 	uint32_t current_read_length;
@@ -86,6 +112,7 @@ struct read_command_context {
 	bool transaction_complete;
 	bool operation_succeeded;
 };
+
 struct write_command_context {
 	bool mot;
 
@@ -110,4 +137,44 @@ struct write_command_context {
 	bool transaction_complete;
 	bool operation_succeeded;
 };
+
+
+struct aux_engine_funcs {
+	void (*destroy)(
+		struct aux_engine **ptr);
+	bool (*acquire_engine)(
+		struct aux_engine *engine);
+	void (*configure)(
+		struct aux_engine *engine,
+		union aux_config cfg);
+	void (*submit_channel_request)(
+		struct aux_engine *engine,
+		struct aux_request_transaction_data *request);
+	void (*process_channel_reply)(
+		struct aux_engine *engine,
+		struct aux_reply_transaction_data *reply);
+	int (*read_channel_reply)(
+		struct aux_engine *engine,
+		uint32_t size,
+		uint8_t *buffer,
+		uint8_t *reply_result,
+		uint32_t *sw_status);
+	enum aux_channel_operation_result (*get_channel_status)(
+		struct aux_engine *engine,
+		uint8_t *returned_bytes);
+	bool (*is_engine_available)(struct aux_engine *engine);
+	enum i2caux_engine_type (*get_engine_type)(
+		const struct aux_engine *engine);
+	bool (*acquire)(
+		struct aux_engine *engine,
+		struct ddc *ddc);
+	bool (*submit_request)(
+		struct aux_engine *engine,
+		struct i2caux_transaction_request *request,
+		bool middle_of_transaction);
+	void (*release_engine)(
+		struct aux_engine *engine);
+	void (*destroy_engine)(
+		struct aux_engine **engine);
+};
 #endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/engine.h b/drivers/gpu/drm/amd/display/dc/inc/hw/engine.h
deleted file mode 100644
index 1f5476f41236..000000000000
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/engine.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2012-15 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: AMD
- *
- */
-
-#ifndef __DAL_ENGINE_H__
-#define __DAL_ENGINE_H__
-
-#include "dc_ddc_types.h"
-
-enum i2caux_transaction_operation {
-	I2CAUX_TRANSACTION_READ,
-	I2CAUX_TRANSACTION_WRITE
-};
-
-enum i2caux_transaction_address_space {
-	I2CAUX_TRANSACTION_ADDRESS_SPACE_I2C = 1,
-	I2CAUX_TRANSACTION_ADDRESS_SPACE_DPCD
-};
-
-struct i2caux_transaction_payload {
-	enum i2caux_transaction_address_space address_space;
-	uint32_t address;
-	uint32_t length;
-	uint8_t *data;
-};
-
-enum i2caux_transaction_status {
-	I2CAUX_TRANSACTION_STATUS_UNKNOWN = (-1L),
-	I2CAUX_TRANSACTION_STATUS_SUCCEEDED,
-	I2CAUX_TRANSACTION_STATUS_FAILED_CHANNEL_BUSY,
-	I2CAUX_TRANSACTION_STATUS_FAILED_TIMEOUT,
-	I2CAUX_TRANSACTION_STATUS_FAILED_PROTOCOL_ERROR,
-	I2CAUX_TRANSACTION_STATUS_FAILED_NACK,
-	I2CAUX_TRANSACTION_STATUS_FAILED_INCOMPLETE,
-	I2CAUX_TRANSACTION_STATUS_FAILED_OPERATION,
-	I2CAUX_TRANSACTION_STATUS_FAILED_INVALID_OPERATION,
-	I2CAUX_TRANSACTION_STATUS_FAILED_BUFFER_OVERFLOW,
-	I2CAUX_TRANSACTION_STATUS_FAILED_HPD_DISCON
-};
-
-struct i2caux_transaction_request {
-	enum i2caux_transaction_operation operation;
-	struct i2caux_transaction_payload payload;
-	enum i2caux_transaction_status status;
-};
-
-enum i2caux_engine_type {
-	I2CAUX_ENGINE_TYPE_UNKNOWN = (-1L),
-	I2CAUX_ENGINE_TYPE_AUX,
-	I2CAUX_ENGINE_TYPE_I2C_DDC_HW,
-	I2CAUX_ENGINE_TYPE_I2C_GENERIC_HW,
-	I2CAUX_ENGINE_TYPE_I2C_SW
-};
-
-enum i2c_default_speed {
-	I2CAUX_DEFAULT_I2C_HW_SPEED = 50,
-	I2CAUX_DEFAULT_I2C_SW_SPEED = 50
-};
-
-struct engine;
-
-struct engine_funcs {
-	enum i2caux_engine_type (*get_engine_type)(
-		const struct engine *engine);
-	struct aux_engine* (*acquire)(
-		struct engine *engine,
-		struct ddc *ddc);
-	bool (*submit_request)(
-		struct engine *engine,
-		struct i2caux_transaction_request *request,
-		bool middle_of_transaction);
-	void (*release_engine)(
-		struct engine *engine);
-	void (*destroy_engine)(
-		struct engine **engine);
-};
-
-struct engine {
-	const struct engine_funcs *funcs;
-	uint32_t inst;
-	struct ddc *ddc;
-	struct dc_context *ctx;
-};
-
-#endif
commit 824474ba38e27ccacc9d2dd066f780e9b3c2ad78
Author: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
Date:   Fri Jul 13 18:00:06 2018 -0400

    drm/amd/display: Retry link training again
    
    [Why]
    Some receivers seem to fail the first link training but are good on
    subsequent tries. We want to retry link training again. This fixes
    HTC vive pro not lighting up after being disabled.
    
    [How]
    Check if the link training passed without fall back if this is not
    the case then we retry link training.
    
    Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Reviewed-by: Harry Wentland <Harry.Wentland at amd.com>
    Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 388a0635c38d..966d2f9c8c99 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -60,7 +60,14 @@
 
 enum {
 	LINK_RATE_REF_FREQ_IN_MHZ = 27,
-	PEAK_FACTOR_X1000 = 1006
+	PEAK_FACTOR_X1000 = 1006,
+	/*
+	* Some receivers fail to train on first try and are good
+	* on subsequent tries. 2 retries should be plenty. If we
+	* don't have a successful training then we don't expect to
+	* ever get one.
+	*/
+	LINK_TRAINING_MAX_VERIFY_RETRY = 2
 };
 
 /*******************************************************************************
@@ -760,7 +767,16 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
 				 */
 
 				/* deal with non-mst cases */
-				dp_verify_link_cap(link, &link->reported_link_cap);
+				for (i = 0; i < LINK_TRAINING_MAX_VERIFY_RETRY; i++) {
+					int fail_count = 0;
+
+					dp_verify_link_cap(link,
+							  &link->reported_link_cap,
+							  &fail_count);
+
+					if (fail_count == 0)
+						break;
+				}
 			}
 
 			/* HDMI-DVI Dongle */
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 9d901ca70588..58ee9aad13fb 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -1088,7 +1088,8 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link)
 
 bool dp_verify_link_cap(
 	struct dc_link *link,
-	struct dc_link_settings *known_limit_link_setting)
+	struct dc_link_settings *known_limit_link_setting,
+	int *fail_count)
 {
 	struct dc_link_settings max_link_cap = {0};
 	struct dc_link_settings cur_link_setting = {0};
@@ -1160,6 +1161,8 @@ bool dp_verify_link_cap(
 							skip_video_pattern);
 			if (status == LINK_TRAINING_SUCCESS)
 				success = true;
+			else
+				(*fail_count)++;
 		}
 
 		if (success)
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
index 697b5ee73845..a37255c757e0 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
@@ -35,7 +35,8 @@ struct dc_link_settings;
 
 bool dp_verify_link_cap(
 	struct dc_link *link,
-	struct dc_link_settings *known_limit_link_setting);
+	struct dc_link_settings *known_limit_link_setting,
+	int *fail_count);
 
 bool dp_validate_mode_timing(
 	struct dc_link *link,
commit 66c28d6df2d8292098839d365b82a1e30b567211
Author: Christian König <christian.koenig at amd.com>
Date:   Wed Jul 18 14:52:42 2018 +0200

    drm/amdgpu: patch the IBs for the second UVD instance v2
    
    Patch the IBs for the second UVD instance so that userspace don't need
    to care about the instance they submit to.
    
    v2: use direct IB patching
    
    Signed-off-by: Christian König <christian.koenig at amd.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Reviewed-and-tested-by: James Zhu <James.Zhu at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
index db5f3d78ab12..d74c1b242667 100644
--- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
@@ -1206,6 +1206,34 @@ static int uvd_v7_0_ring_test_ring(struct amdgpu_ring *ring)
 }
 
 /**
+ * uvd_v7_0_ring_patch_cs_in_place - Patch the IB for command submission.
+ *
+ * @p: the CS parser with the IBs
+ * @ib_idx: which IB to patch
+ *
+ */
+static int uvd_v7_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
+					   uint32_t ib_idx)
+{
+	struct amdgpu_ib *ib = &p->job->ibs[ib_idx];
+	unsigned i;
+
+	/* No patching necessary for the first instance */
+	if (!p->ring->me)
+		return 0;
+
+	for (i = 0; i < ib->length_dw; i += 2) {
+		uint32_t reg = amdgpu_get_ib_value(p, ib_idx, i);
+
+		reg -= p->adev->reg_offset[UVD_HWIP][0][1];
+		reg += p->adev->reg_offset[UVD_HWIP][1][1];
+
+		amdgpu_set_ib_value(p, ib_idx, i, reg);
+	}
+	return 0;
+}
+
+/**
  * uvd_v7_0_ring_emit_ib - execute indirect buffer
  *
  * @ring: amdgpu_ring pointer
@@ -1697,6 +1725,7 @@ static const struct amdgpu_ring_funcs uvd_v7_0_ring_vm_funcs = {
 	.get_rptr = uvd_v7_0_ring_get_rptr,
 	.get_wptr = uvd_v7_0_ring_get_wptr,
 	.set_wptr = uvd_v7_0_ring_set_wptr,
+	.patch_cs_in_place = uvd_v7_0_ring_patch_cs_in_place,
 	.emit_frame_size =
 		6 + /* hdp invalidate */
 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
commit 9d248517d4bd807c7690d55d0b6f54618fc60942
Author: Christian König <christian.koenig at amd.com>
Date:   Mon Jul 23 16:01:39 2018 +0200

    drm/amdgpu: add support for inplace IB patching for MM engines v2
    
    We are going to need that for the second UVD instance on Vega20.
    
    v2: rename to patch_cs_in_place
    
    Signed-off-by: Christian König <christian.koenig at amd.com>
    Reviewed-and-tested-by: James Zhu <James.Zhu at amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 0283e2b3c851..1f6345dda6ea 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1748,6 +1748,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
 #define amdgpu_vm_write_pte(adev, ib, pe, value, count, incr) ((adev)->vm_manager.vm_pte_funcs->write_pte((ib), (pe), (value), (count), (incr)))
 #define amdgpu_vm_set_pte_pde(adev, ib, pe, addr, count, incr, flags) ((adev)->vm_manager.vm_pte_funcs->set_pte_pde((ib), (pe), (addr), (count), (incr), (flags)))
 #define amdgpu_ring_parse_cs(r, p, ib) ((r)->funcs->parse_cs((p), (ib)))
+#define amdgpu_ring_patch_cs_in_place(r, p, ib) ((r)->funcs->patch_cs_in_place((p), (ib)))
 #define amdgpu_ring_test_ring(r) (r)->funcs->test_ring((r))
 #define amdgpu_ring_test_ib(r, t) (r)->funcs->test_ib((r), (t))
 #define amdgpu_ring_get_rptr(r) (r)->funcs->get_rptr((r))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 178d9ce4eba1..533b2e7656c0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -916,7 +916,7 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev,
 	int r;
 
 	/* Only for UVD/VCE VM emulation */
-	if (p->ring->funcs->parse_cs) {
+	if (p->ring->funcs->parse_cs || p->ring->funcs->patch_cs_in_place) {
 		unsigned i, j;
 
 		for (i = 0, j = 0; i < p->nchunks && j < p->job->num_ibs; i++) {
@@ -957,12 +957,20 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev,
 			offset = m->start * AMDGPU_GPU_PAGE_SIZE;
 			kptr += va_start - offset;
 
-			memcpy(ib->ptr, kptr, chunk_ib->ib_bytes);
-			amdgpu_bo_kunmap(aobj);
-
-			r = amdgpu_ring_parse_cs(ring, p, j);
-			if (r)
-				return r;
+			if (p->ring->funcs->parse_cs) {
+				memcpy(ib->ptr, kptr, chunk_ib->ib_bytes);
+				amdgpu_bo_kunmap(aobj);
+
+				r = amdgpu_ring_parse_cs(ring, p, j);
+				if (r)
+					return r;
+			} else {
+				ib->ptr = (uint32_t *)kptr;
+				r = amdgpu_ring_patch_cs_in_place(ring, p, j);
+				amdgpu_bo_kunmap(aobj);
+				if (r)
+					return r;
+			}
 
 			j++;
 		}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
index 5018c0b6bf1a..d242b9a51e90 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -123,6 +123,7 @@ struct amdgpu_ring_funcs {
 	void (*set_wptr)(struct amdgpu_ring *ring);
 	/* validating and patching of IBs */
 	int (*parse_cs)(struct amdgpu_cs_parser *p, uint32_t ib_idx);
+	int (*patch_cs_in_place)(struct amdgpu_cs_parser *p, uint32_t ib_idx);
 	/* constants to calculate how many DW are needed for an emit */
 	unsigned emit_frame_size;
 	unsigned emit_ib_size;
commit d97e5e6160c0e0a23963ec198c7cb1c69e6bf9e8
Author: Shakeel Butt <shakeelb at google.com>
Date:   Thu Jul 26 16:37:45 2018 -0700

    kvm, mm: account shadow page tables to kmemcg
    
    The size of kvm's shadow page tables corresponds to the size of the
    guest virtual machines on the system.  Large VMs can spend a significant
    amount of memory as shadow page tables which can not be left as system
    memory overhead.  So, account shadow page tables to the kmemcg.
    
    [shakeelb at google.com: replace (GFP_KERNEL|__GFP_ACCOUNT) with GFP_KERNEL_ACCOUNT]
      Link: http://lkml.kernel.org/r/20180629140224.205849-1-shakeelb@google.com
    Link: http://lkml.kernel.org/r/20180627181349.149778-1-shakeelb@google.com
    Signed-off-by: Shakeel Butt <shakeelb at google.com>
    Cc: Michal Hocko <mhocko at kernel.org>
    Cc: Johannes Weiner <hannes at cmpxchg.org>
    Cc: Vladimir Davydov <vdavydov.dev at gmail.com>
    Cc: Paolo Bonzini <pbonzini at redhat.com>
    Cc: Greg Thelen <gthelen at google.com>
    Cc: Radim Krčmář <rkrcmar at redhat.com>
    Cc: Peter Feiner <pfeiner at google.com>
    Cc: <stable at vger.kernel.org>
    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>

diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index d594690d8b95..6b8f11521c41 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -890,7 +890,7 @@ static int mmu_topup_memory_cache_page(struct kvm_mmu_memory_cache *cache,
 	if (cache->nobjs >= min)
 		return 0;
 	while (cache->nobjs < ARRAY_SIZE(cache->objects)) {
-		page = (void *)__get_free_page(GFP_KERNEL);
+		page = (void *)__get_free_page(GFP_KERNEL_ACCOUNT);
 		if (!page)
 			return -ENOMEM;
 		cache->objects[cache->nobjs++] = page;
commit 16e536ef47f567289a5699abee9ff7bb304bc12d
Author: Li Wang <liwang at redhat.com>
Date:   Thu Jul 26 16:37:42 2018 -0700

    zswap: re-check zswap_is_full() after do zswap_shrink()
    
    /sys/../zswap/stored_pages keeps rising in a zswap test with
    "zswap.max_pool_percent=0" parameter.  But it should not compress or
    store pages any more since there is no space in the compressed pool.
    
    Reproduce steps:
      1. Boot kernel with "zswap.enabled=1"
      2. Set the max_pool_percent to 0
          # echo 0 > /sys/module/zswap/parameters/max_pool_percent
      3. Do memory stress test to see if some pages have been compressed
          # stress --vm 1 --vm-bytes $mem_available"M" --timeout 60s
      4. Watching the 'stored_pages' number increasing or not
    
    The root cause is:
    
      When zswap_max_pool_percent is set to 0 via kernel parameter,
      zswap_is_full() will always return true due to zswap_shrink().  But if
      the shinking is able to reclain a page successfully the code then
      proceeds to compressing/storing another page, so the value of
      stored_pages will keep changing.
    
    To solve the issue, this patch adds a zswap_is_full() check again after
      zswap_shrink() to make sure it's now under the max_pool_percent, and to
      not compress/store if we reached the limit.
    
    Link: http://lkml.kernel.org/r/20180530103936.17812-1-liwang@redhat.com
    Signed-off-by: Li Wang <liwang at redhat.com>
    Acked-by: Dan Streetman <ddstreet at ieee.org>
    Cc: Seth Jennings <sjenning at redhat.com>
    Cc: Huang Ying <huang.ying.caritas at gmail.com>
    Cc: Yu Zhao <yuzhao at google.com>
    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>

diff --git a/mm/zswap.c b/mm/zswap.c
index 7d34e69507e3..cd91fd9d96b8 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -1026,6 +1026,15 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset,
 			ret = -ENOMEM;
 			goto reject;
 		}
+
+		/* A second zswap_is_full() check after
+		 * zswap_shrink() to make sure it's now
+		 * under the max_pool_percent
+		 */
+		if (zswap_is_full()) {
+			ret = -ENOMEM;
+			goto reject;
+		}
 	}
 
 	/* allocate entry */
commit fa3fc2ad99b4f025446d1cff589a8d2dd7db92f2
Author: Arnd Bergmann <arnd at arndb.de>
Date:   Thu Jul 26 16:37:38 2018 -0700

    include/linux/eventfd.h: include linux/errno.h
    
    The new gasket staging driver ran into a randconfig build failure when
    CONFIG_EVENTFD is disabled:
    
      In file included from drivers/staging/gasket/gasket_interrupt.h:11,
                       from drivers/staging/gasket/gasket_interrupt.c:4:
      include/linux/eventfd.h: In function 'eventfd_ctx_fdget':
      include/linux/eventfd.h:51:9: error: implicit declaration of function 'ERR_PTR' [-Werror=implicit-function-declaration]
    
    I can't see anything wrong with including eventfd.h before err.h, so the
    easiest fix is to make it possible to do this by including the file
    where it is needed.
    
    Link: http://lkml.kernel.org/r/20180724110737.3985088-1-arnd@arndb.de
    Fixes: 9a69f5087ccc ("drivers/staging: Gasket driver framework + Apex driver")
    Signed-off-by: Arnd Bergmann <arnd at arndb.de>
    Cc: Eric Biggers <ebiggers at google.com>
    Cc: Al Viro <viro at zeniv.linux.org.uk>
    Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>

diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h
index 7094718b653b..ffcc7724ca21 100644
--- a/include/linux/eventfd.h
+++ b/include/linux/eventfd.h
@@ -11,6 +11,7 @@
 
 #include <linux/fcntl.h>
 #include <linux/wait.h>
+#include <linux/err.h>
 
 /*
  * CAREFUL: Check include/uapi/asm-generic/fcntl.h when defining
commit bfd40eaff5abb9f62c8ef94ca13ed0d94a560f10
Author: Kirill A. Shutemov <kirill.shutemov at linux.intel.com>
Date:   Thu Jul 26 16:37:35 2018 -0700

    mm: fix vma_is_anonymous() false-positives
    
    vma_is_anonymous() relies on ->vm_ops being NULL to detect anonymous
    VMA.  This is unreliable as ->mmap may not set ->vm_ops.
    
    False-positive vma_is_anonymous() may lead to crashes:
    
            next ffff8801ce5e7040 prev ffff8801d20eca50 mm ffff88019c1e13c0
            prot 27 anon_vma ffff88019680cdd8 vm_ops 0000000000000000
            pgoff 0 file ffff8801b2ec2d00 private_data 0000000000000000
            flags: 0xff(read|write|exec|shared|mayread|maywrite|mayexec|mayshare)
            ------------[ cut here ]------------
            kernel BUG at mm/memory.c:1422!
            invalid opcode: 0000 [#1] SMP KASAN
            CPU: 0 PID: 18486 Comm: syz-executor3 Not tainted 4.18.0-rc3+ #136
            Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google
            01/01/2011
            RIP: 0010:zap_pmd_range mm/memory.c:1421 [inline]
            RIP: 0010:zap_pud_range mm/memory.c:1466 [inline]
            RIP: 0010:zap_p4d_range mm/memory.c:1487 [inline]
            RIP: 0010:unmap_page_range+0x1c18/0x2220 mm/memory.c:1508
            Call Trace:
             unmap_single_vma+0x1a0/0x310 mm/memory.c:1553
             zap_page_range_single+0x3cc/0x580 mm/memory.c:1644
             unmap_mapping_range_vma mm/memory.c:2792 [inline]
             unmap_mapping_range_tree mm/memory.c:2813 [inline]
             unmap_mapping_pages+0x3a7/0x5b0 mm/memory.c:2845
             unmap_mapping_range+0x48/0x60 mm/memory.c:2880
             truncate_pagecache+0x54/0x90 mm/truncate.c:800
             truncate_setsize+0x70/0xb0 mm/truncate.c:826
             simple_setattr+0xe9/0x110 fs/libfs.c:409
             notify_change+0xf13/0x10f0 fs/attr.c:335
             do_truncate+0x1ac/0x2b0 fs/open.c:63
             do_sys_ftruncate+0x492/0x560 fs/open.c:205
             __do_sys_ftruncate fs/open.c:215 [inline]
             __se_sys_ftruncate fs/open.c:213 [inline]
             __x64_sys_ftruncate+0x59/0x80 fs/open.c:213
             do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290
             entry_SYSCALL_64_after_hwframe+0x49/0xbe
    
    Reproducer:
    
            #include <stdio.h>
            #include <stddef.h>
            #include <stdint.h>
            #include <stdlib.h>
            #include <string.h>
            #include <sys/types.h>
            #include <sys/stat.h>
            #include <sys/ioctl.h>
            #include <sys/mman.h>
            #include <unistd.h>
            #include <fcntl.h>
    
            #define KCOV_INIT_TRACE                 _IOR('c', 1, unsigned long)
            #define KCOV_ENABLE                     _IO('c', 100)
            #define KCOV_DISABLE                    _IO('c', 101)
            #define COVER_SIZE                      (1024<<10)
    
            #define KCOV_TRACE_PC  0
            #define KCOV_TRACE_CMP 1
    
            int main(int argc, char **argv)
            {
                    int fd;
                    unsigned long *cover;
    
                    system("mount -t debugfs none /sys/kernel/debug");
                    fd = open("/sys/kernel/debug/kcov", O_RDWR);
                    ioctl(fd, KCOV_INIT_TRACE, COVER_SIZE);
                    cover = mmap(NULL, COVER_SIZE * sizeof(unsigned long),
                                    PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
                    munmap(cover, COVER_SIZE * sizeof(unsigned long));
                    cover = mmap(NULL, COVER_SIZE * sizeof(unsigned long),
                                    PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
                    memset(cover, 0, COVER_SIZE * sizeof(unsigned long));
                    ftruncate(fd, 3UL << 20);
                    return 0;
            }
    
    This can be fixed by assigning anonymous VMAs own vm_ops and not relying
    on it being NULL.
    
    If ->mmap() failed to set ->vm_ops, mmap_region() will set it to
    dummy_vm_ops.  This way we will have non-NULL ->vm_ops for all VMAs.
    
    Link: http://lkml.kernel.org/r/20180724121139.62570-4-kirill.shutemov@linux.intel.com
    Signed-off-by: Kirill A. Shutemov <kirill.shutemov at linux.intel.com>
    Reported-by: syzbot+3f84280d52be9b7083cc at syzkaller.appspotmail.com
    Acked-by: Linus Torvalds <torvalds at linux-foundation.org>
    Reviewed-by: Andrew Morton <akpm at linux-foundation.org>
    Cc: Dmitry Vyukov <dvyukov at google.com>
    Cc: Oleg Nesterov <oleg at redhat.com>
    Cc: Andrea Arcangeli <aarcange at redhat.com>
    Cc: <stable at vger.kernel.org>
    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>

diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index ffeb60d3434c..df66a9dd0aae 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -708,6 +708,7 @@ static int mmap_zero(struct file *file, struct vm_area_struct *vma)
 #endif
 	if (vma->vm_flags & VM_SHARED)
 		return shmem_zero_setup(vma);
+	vma_set_anonymous(vma);
 	return 0;
 }
 
diff --git a/fs/exec.c b/fs/exec.c
index 72e961a62adb..bdd0eacefdf5 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -293,6 +293,7 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
 	bprm->vma = vma = vm_area_alloc(mm);
 	if (!vma)
 		return -ENOMEM;
+	vma_set_anonymous(vma);
 
 	if (down_write_killable(&mm->mmap_sem)) {
 		err = -EINTR;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 31540f166987..7ba6d356d18f 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -454,10 +454,18 @@ struct vm_operations_struct {
 
 static inline void vma_init(struct vm_area_struct *vma, struct mm_struct *mm)
 {
+	static const struct vm_operations_struct dummy_vm_ops = {};
+
 	vma->vm_mm = mm;
+	vma->vm_ops = &dummy_vm_ops;
 	INIT_LIST_HEAD(&vma->anon_vma_chain);
 }
 
+static inline void vma_set_anonymous(struct vm_area_struct *vma)
+{
+	vma->vm_ops = NULL;
+}
+
 struct mmu_gather;
 struct inode;
 
diff --git a/mm/mmap.c b/mm/mmap.c
index ff1944d8d458..17bbf4d3e24f 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1778,6 +1778,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
 		error = shmem_zero_setup(vma);
 		if (error)
 			goto free_vma;
+	} else {
+		vma_set_anonymous(vma);
 	}
 
 	vma_link(mm, vma, prev, rb_link, rb_parent);
@@ -2983,6 +2985,7 @@ static int do_brk_flags(unsigned long addr, unsigned long len, unsigned long fla
 		return -ENOMEM;
 	}
 
+	vma_set_anonymous(vma);
 	vma->vm_start = addr;
 	vma->vm_end = addr + len;
 	vma->vm_pgoff = pgoff;
diff --git a/mm/nommu.c b/mm/nommu.c
index 1d22fdbf7d7c..9fc9e43335b6 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1145,6 +1145,8 @@ static int do_mmap_private(struct vm_area_struct *vma,
 		if (ret < len)
 			memset(base + ret, 0, len - ret);
 
+	} else {
+		vma_set_anonymous(vma);
 	}
 
 	return 0;
commit 2c4541e24c55e2847bede93e33d749280edd429a
Author: Kirill A. Shutemov <kirill.shutemov at linux.intel.com>
Date:   Thu Jul 26 16:37:30 2018 -0700

    mm: use vma_init() to initialize VMAs on stack and data segments
    
    Make sure to initialize all VMAs properly, not only those which come
    from vm_area_cachep.
    
    Link: http://lkml.kernel.org/r/20180724121139.62570-3-kirill.shutemov@linux.intel.com
    Signed-off-by: Kirill A. Shutemov <kirill.shutemov at linux.intel.com>
    Acked-by: Linus Torvalds <torvalds at linux-foundation.org>
    Reviewed-by: Andrew Morton <akpm at linux-foundation.org>
    Cc: Dmitry Vyukov <dvyukov at google.com>
    Cc: Oleg Nesterov <oleg at redhat.com>
    Cc: Andrea Arcangeli <aarcange at redhat.com>
    Cc: <stable at vger.kernel.org>
    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>

diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 225d1c58d2de..d9c299133111 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -338,6 +338,7 @@ static struct vm_area_struct gate_vma = {
 
 static int __init gate_vma_init(void)
 {
+	vma_init(&gate_vma, NULL);
 	gate_vma.vm_page_prot = PAGE_READONLY_EXEC;
 	return 0;
 }
diff --git a/arch/arm/mach-rpc/ecard.c b/arch/arm/mach-rpc/ecard.c
index 39aef4876ed4..8db62cc54a6a 100644
--- a/arch/arm/mach-rpc/ecard.c
+++ b/arch/arm/mach-rpc/ecard.c
@@ -237,8 +237,8 @@ static void ecard_init_pgtables(struct mm_struct *mm)
 
 	memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (EASI_SIZE / PGDIR_SIZE));
 
+	vma_init(&vma, mm);
 	vma.vm_flags = VM_EXEC;
-	vma.vm_mm = mm;
 
 	flush_tlb_range(&vma, IO_START, IO_START + IO_SIZE);
 	flush_tlb_range(&vma, EASI_START, EASI_START + EASI_SIZE);
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index ffdaea7954bb..d87f2d646caa 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -37,7 +37,9 @@ static inline void __tlb_remove_table(void *_table)
 
 static inline void tlb_flush(struct mmu_gather *tlb)
 {
-	struct vm_area_struct vma = { .vm_mm = tlb->mm, };
+	struct vm_area_struct vma;
+
+	vma_init(&vma, tlb->mm);
 
 	/*
 	 * The ASID allocator will either invalidate the ASID or mark
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index ecc6818191df..1854e49aa18a 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -108,11 +108,13 @@ static pte_t get_clear_flush(struct mm_struct *mm,
 			     unsigned long pgsize,
 			     unsigned long ncontig)
 {
-	struct vm_area_struct vma = { .vm_mm = mm };
+	struct vm_area_struct vma;
 	pte_t orig_pte = huge_ptep_get(ptep);
 	bool valid = pte_valid(orig_pte);
 	unsigned long i, saddr = addr;
 
+	vma_init(&vma, mm);
+
 	for (i = 0; i < ncontig; i++, addr += pgsize, ptep++) {
 		pte_t pte = ptep_get_and_clear(mm, addr, ptep);
 
@@ -145,9 +147,10 @@ static void clear_flush(struct mm_struct *mm,
 			     unsigned long pgsize,
 			     unsigned long ncontig)
 {
-	struct vm_area_struct vma = { .vm_mm = mm };
+	struct vm_area_struct vma;
 	unsigned long i, saddr = addr;
 
+	vma_init(&vma, mm);
 	for (i = 0; i < ncontig; i++, addr += pgsize, ptep++)
 		pte_clear(mm, addr, ptep);
 
diff --git a/arch/ia64/include/asm/tlb.h b/arch/ia64/include/asm/tlb.h
index 44f0ac0df308..db89e7306081 100644
--- a/arch/ia64/include/asm/tlb.h
+++ b/arch/ia64/include/asm/tlb.h
@@ -120,7 +120,7 @@ ia64_tlb_flush_mmu_tlbonly(struct mmu_gather *tlb, unsigned long start, unsigned
 		 */
 		struct vm_area_struct vma;
 
-		vma.vm_mm = tlb->mm;
+		vma_init(&vma, tlb->mm);
 		/* flush the address range from the tlb: */
 		flush_tlb_range(&vma, start, end);
 		/* now flush the virt. page-table area mapping the address range: */
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index bdb14a369137..e6c6dfd98de2 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -273,7 +273,7 @@ static struct vm_area_struct gate_vma;
 
 static int __init gate_vma_init(void)
 {
-	gate_vma.vm_mm = NULL;
+	vma_init(&gate_vma, NULL);
 	gate_vma.vm_start = FIXADDR_USER_START;
 	gate_vma.vm_end = FIXADDR_USER_END;
 	gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
diff --git a/arch/x86/um/mem_32.c b/arch/x86/um/mem_32.c
index 744afdc18cf3..56c44d865f7b 100644
--- a/arch/x86/um/mem_32.c
+++ b/arch/x86/um/mem_32.c
@@ -16,7 +16,7 @@ static int __init gate_vma_init(void)
 	if (!FIXADDR_USER_START)
 		return 0;
 
-	gate_vma.vm_mm = NULL;
+	vma_init(&gate_vma, NULL);
 	gate_vma.vm_start = FIXADDR_USER_START;
 	gate_vma.vm_end = FIXADDR_USER_END;
 	gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index d508c7844681..40d4c66c7751 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -411,6 +411,7 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
 	bool truncate_op = (lend == LLONG_MAX);
 
 	memset(&pseudo_vma, 0, sizeof(struct vm_area_struct));
+	vma_init(&pseudo_vma, current->mm);
 	pseudo_vma.vm_flags = (VM_HUGETLB | VM_MAYSHARE | VM_SHARED);
 	pagevec_init(&pvec);
 	next = start;
@@ -595,6 +596,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset,
 	 * as input to create an allocation policy.
 	 */
 	memset(&pseudo_vma, 0, sizeof(struct vm_area_struct));
+	vma_init(&pseudo_vma, mm);
 	pseudo_vma.vm_flags = (VM_HUGETLB | VM_MAYSHARE | VM_SHARED);
 	pseudo_vma.vm_file = file;
 
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 9ac49ef17b4e..01f1a14facc4 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -2505,6 +2505,7 @@ void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol)
 
 		/* Create pseudo-vma that contains just the policy */
 		memset(&pvma, 0, sizeof(struct vm_area_struct));
+		vma_init(&pvma, NULL);
 		pvma.vm_end = TASK_SIZE;	/* policy covers entire file */
 		mpol_set_shared_policy(sp, &pvma, new); /* adds ref */
 
diff --git a/mm/shmem.c b/mm/shmem.c
index 2cab84403055..41b9bbf24e16 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1421,6 +1421,7 @@ static void shmem_pseudo_vma_init(struct vm_area_struct *vma,
 {
 	/* Create a pseudo vma that just contains the policy */
 	memset(vma, 0, sizeof(*vma));
+	vma_init(vma, NULL);
 	/* Bias interleave by inode number to distribute better across nodes */
 	vma->vm_pgoff = index + info->vfs_inode.i_ino;
 	vma->vm_policy = mpol_shared_policy_lookup(&info->policy, index);
commit 027232da7c7c1c7f04383f93bd798e475dde5285
Author: Kirill A. Shutemov <kirill.shutemov at linux.intel.com>
Date:   Thu Jul 26 16:37:25 2018 -0700

    mm: introduce vma_init()
    
    Not all VMAs allocated with vm_area_alloc().  Some of them allocated on
    stack or in data segment.
    
    The new helper can be use to initialize VMA properly regardless where it
    was allocated.
    
    Link: http://lkml.kernel.org/r/20180724121139.62570-2-kirill.shutemov@linux.intel.com
    Signed-off-by: Kirill A. Shutemov <kirill.shutemov at linux.intel.com>
    Acked-by: Linus Torvalds <torvalds at linux-foundation.org>
    Reviewed-by: Andrew Morton <akpm at linux-foundation.org>
    Cc: Dmitry Vyukov <dvyukov at google.com>
    Cc: Oleg Nesterov <oleg at redhat.com>
    Cc: Andrea Arcangeli <aarcange at redhat.com>
    Cc: <stable at vger.kernel.org>
    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>

diff --git a/include/linux/mm.h b/include/linux/mm.h
index d3a3842316b8..31540f166987 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -452,6 +452,12 @@ struct vm_operations_struct {
 					  unsigned long addr);
 };
 
+static inline void vma_init(struct vm_area_struct *vma, struct mm_struct *mm)
+{
+	vma->vm_mm = mm;
+	INIT_LIST_HEAD(&vma->anon_vma_chain);
+}
+
 struct mmu_gather;
 struct inode;
 
diff --git a/kernel/fork.c b/kernel/fork.c
index a191c05e757d..1b27babc4c78 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -312,10 +312,8 @@ struct vm_area_struct *vm_area_alloc(struct mm_struct *mm)
 {
 	struct vm_area_struct *vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
 
-	if (vma) {
-		vma->vm_mm = mm;
-		INIT_LIST_HEAD(&vma->anon_vma_chain);
-	}
+	if (vma)
+		vma_init(vma, mm);
 	return vma;
 }
 
commit 31c5bda3a656089f01963d290a40ccda181f816e
Author: Dan Williams <dan.j.williams at intel.com>
Date:   Thu Jul 26 16:37:22 2018 -0700

    mm: fix exports that inadvertently make put_page() EXPORT_SYMBOL_GPL
    
    Commit e76384884344 ("mm: introduce MEMORY_DEVICE_FS_DAX and
    CONFIG_DEV_PAGEMAP_OPS") added two EXPORT_SYMBOL_GPL() symbols, but
    these symbols are required by the inlined put_page(), thus accidentally
    making put_page() a GPL export only.  This breaks OpenAFS (at least).
    
    Mark them EXPORT_SYMBOL() instead.
    
    Link: http://lkml.kernel.org/r/153128611970.2928.11310692420711601254.stgit@dwillia2-desk3.amr.corp.intel.com
    Fixes: e76384884344 ("mm: introduce MEMORY_DEVICE_FS_DAX and CONFIG_DEV_PAGEMAP_OPS")
    Signed-off-by: Dan Williams <dan.j.williams at intel.com>
    Reported-by: Joe Gorse <jhgorse at gmail.com>
    Reported-by: John Hubbard <jhubbard at nvidia.com>
    Tested-by: Joe Gorse <jhgorse at gmail.com>
    Tested-by: John Hubbard <jhubbard at nvidia.com>
    Cc: Jérôme Glisse <jglisse at redhat.com>
    Cc: Mark Vitale <mvitale at sinenomine.net>
    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>

diff --git a/kernel/memremap.c b/kernel/memremap.c
index a734b1747466..38283363da06 100644
--- a/kernel/memremap.c
+++ b/kernel/memremap.c
@@ -321,7 +321,7 @@ EXPORT_SYMBOL_GPL(get_dev_pagemap);
 
 #ifdef CONFIG_DEV_PAGEMAP_OPS
 DEFINE_STATIC_KEY_FALSE(devmap_managed_key);
-EXPORT_SYMBOL_GPL(devmap_managed_key);
+EXPORT_SYMBOL(devmap_managed_key);
 static atomic_t devmap_enable;
 
 /*
@@ -362,5 +362,5 @@ void __put_devmap_managed_page(struct page *page)
 	} else if (!count)
 		__put_page(page);
 }
-EXPORT_SYMBOL_GPL(__put_devmap_managed_page);
+EXPORT_SYMBOL(__put_devmap_managed_page);
 #endif /* CONFIG_DEV_PAGEMAP_OPS */
commit f075faa300acc4f6301e348acde0a4580ed5f77c
Author: Davidlohr Bueso <dave at stgolabs.net>
Date:   Thu Jul 26 16:37:19 2018 -0700

    ipc/sem.c: prevent queue.status tearing in semop
    
    In order for load/store tearing prevention to work, _all_ accesses to
    the variable in question need to be done