summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/admin-guide/pm/cpufreq.rst8
-rw-r--r--Documentation/device-mapper/dm-raid.txt1
-rw-r--r--Documentation/devicetree/bindings/ata/sata_rcar.txt14
-rw-r--r--Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt2
-rw-r--r--Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt32
-rw-r--r--Documentation/devicetree/bindings/display/repaper.txt52
-rw-r--r--Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt7
-rw-r--r--Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt4
-rw-r--r--Documentation/devicetree/bindings/display/sitronix,st7586.txt22
-rw-r--r--Documentation/devicetree/bindings/display/st,stm32-ltdc.txt105
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-exar.txt5
-rw-r--r--Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt2
-rw-r--r--Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt1
-rw-r--r--Documentation/devicetree/bindings/mmc/img-dw-mshc.txt1
-rw-r--r--Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt2
-rw-r--r--Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt16
-rw-r--r--Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt1
-rw-r--r--Documentation/devicetree/bindings/net/brcm,amac.txt1
-rw-r--r--Documentation/devicetree/bindings/net/brcm,bgmac-nsp.txt24
-rw-r--r--Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt2
-rw-r--r--Documentation/devicetree/bindings/ptp/brcm,ptp-dte.txt15
-rw-r--r--Documentation/devicetree/bindings/serial/fsl-imx-uart.txt2
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt1
-rw-r--r--Documentation/fb/efifb.txt6
-rw-r--r--Documentation/gpio/gpio-legacy.txt2
-rw-r--r--Documentation/gpu/drm-internals.rst2
-rw-r--r--Documentation/gpu/drm-kms-helpers.rst9
-rw-r--r--Documentation/gpu/drm-kms.rst59
-rw-r--r--Documentation/gpu/drm-mm.rst4
-rw-r--r--Documentation/gpu/drm-uapi.rst2
-rw-r--r--Documentation/gpu/i915.rst18
-rw-r--r--Documentation/gpu/todo.rst4
-rw-r--r--Documentation/media/kapi/dtv-core.rst443
-rw-r--r--Documentation/media/typical_media_device.svg3054
-rw-r--r--Documentation/media/uapi/dvb/dvbstb.svg668
-rw-r--r--Documentation/media/uapi/v4l/bayer.svg1013
-rw-r--r--Documentation/media/uapi/v4l/constraints.svg356
-rw-r--r--Documentation/media/uapi/v4l/crop.svg253
-rw-r--r--Documentation/media/uapi/v4l/fieldseq_bt.svg170
-rw-r--r--Documentation/media/uapi/v4l/fieldseq_tb.svg175
-rw-r--r--Documentation/media/uapi/v4l/nv12mt.svg764
-rw-r--r--Documentation/media/uapi/v4l/nv12mt_example.svg2474
-rw-r--r--Documentation/media/uapi/v4l/selection.svg6957
-rw-r--r--Documentation/media/uapi/v4l/subdev-image-processing-crop.svg10
-rw-r--r--Documentation/media/uapi/v4l/subdev-image-processing-full.svg10
-rw-r--r--Documentation/media/uapi/v4l/subdev-image-processing-scaling-multi-source.svg10
-rw-r--r--Documentation/media/uapi/v4l/vbi_525.svg614
-rw-r--r--Documentation/media/uapi/v4l/vbi_625.svg388
-rw-r--r--Documentation/media/uapi/v4l/vbi_hsync.svg238
-rw-r--r--Documentation/media/uapi/v4l/vidioc-g-fmt.rst6
-rw-r--r--Documentation/media/v4l-drivers/imx.rst7
-rw-r--r--Documentation/media/v4l-drivers/index.rst1
-rw-r--r--Documentation/power/runtime_pm.txt3
-rw-r--r--MAINTAINERS4974
-rw-r--r--Makefile2
-rw-r--r--arch/alpha/include/uapi/asm/ioctls.h2
-rw-r--r--arch/arc/mm/dma.c2
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/boot/dts/armada-388-gp.dts4
-rw-r--r--arch/arm/boot/dts/da850-evm.dts21
-rw-r--r--arch/arm/boot/dts/da850-lcdk.dts7
-rw-r--r--arch/arm/boot/dts/dm8168-evm.dts34
-rw-r--r--arch/arm/boot/dts/dm816x.dtsi2
-rw-r--r--arch/arm/boot/dts/dra71-evm.dts4
-rw-r--r--arch/arm/boot/dts/exynos4.dtsi3
-rw-r--r--arch/arm/boot/dts/rk3288.dtsi4
-rw-r--r--arch/arm/boot/dts/sun8i-a83t.dtsi16
-rw-r--r--arch/arm/boot/dts/sunxi-h3-h5.dtsi2
-rw-r--r--arch/arm/boot/dts/tango4-vantage-1172.dts2
-rw-r--r--arch/arm/include/asm/bug.h2
-rw-r--r--arch/arm/include/asm/cacheflush.h2
-rw-r--r--arch/arm/include/asm/kexec.h5
-rw-r--r--arch/arm/include/asm/tlb.h11
-rw-r--r--arch/arm/include/asm/ucontext.h6
-rw-r--r--arch/arm/kernel/machine_kexec.c11
-rw-r--r--arch/arm/kernel/setup.c3
-rw-r--r--arch/arm/kernel/signal.c78
-rw-r--r--arch/arm/mach-davinci/board-da850-evm.c4
-rw-r--r--arch/arm/mach-davinci/clock.c9
-rw-r--r--arch/arm/mach-ep93xx/clock.c20
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/io.h34
-rw-r--r--arch/arm/mach-mmp/devices.c2
-rw-r--r--arch/arm/mach-mvebu/platsmp.c2
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c12
-rw-r--r--arch/arm/mach-omap1/board-osk.c4
-rw-r--r--arch/arm/mach-omap2/Makefile2
-rw-r--r--arch/arm/mach-omap2/board-generic.c3
-rw-r--r--arch/arm/mach-omap2/display.c119
-rw-r--r--arch/arm/mach-omap2/display.h1
-rw-r--r--arch/arm/mach-omap2/drm.c53
-rw-r--r--arch/arm/mach-omap2/hsmmc.c239
-rw-r--r--arch/arm/mach-omap2/hsmmc.h9
-rw-r--r--arch/arm/mach-omap2/io.c3
-rw-r--r--arch/arm/mach-omap2/pm34xx.c1
-rw-r--r--arch/arm/mach-omap2/prm3xxx.c7
-rw-r--r--arch/arm/mach-omap2/prm44xx.c55
-rw-r--r--arch/arm/mach-prima2/common.c2
-rw-r--r--arch/arm/mach-pxa/Kconfig1
-rw-r--r--arch/arm/mach-pxa/include/mach/mtd-xip.h10
-rw-r--r--arch/arm/mach-rpc/include/mach/hardware.h4
-rw-r--r--arch/arm/mach-sa1100/clock.c25
-rw-r--r--arch/arm/mach-sa1100/include/mach/mtd-xip.h4
-rw-r--r--arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c6
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c1
-rw-r--r--arch/arm/mach-w90x900/clock.c29
-rw-r--r--arch/arm/mm/dma-mapping-nommu.c45
-rw-r--r--arch/arm/mm/dma-mapping.c2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi2
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gx.dtsi2
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts4
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts103
-rw-r--r--arch/arm64/boot/dts/marvell/armada-37xx.dtsi2
-rw-r--r--arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi1
-rw-r--r--arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi3
-rw-r--r--arch/arm64/boot/dts/renesas/salvator-common.dtsi2
-rw-r--r--arch/arm64/boot/dts/renesas/ulcb.dtsi2
-rw-r--r--arch/arm64/configs/defconfig1
-rw-r--r--arch/arm64/include/asm/atomic_lse.h2
-rw-r--r--arch/arm64/include/asm/bug.h2
-rw-r--r--arch/arm64/include/asm/memory.h6
-rw-r--r--arch/arm64/include/asm/sysreg.h4
-rw-r--r--arch/arm64/include/asm/uaccess.h2
-rw-r--r--arch/arm64/kernel/cpu_ops.c4
-rw-r--r--arch/arm64/kernel/smp.c12
-rw-r--r--arch/arm64/kernel/topology.c22
-rw-r--r--arch/arm64/kernel/traps.c10
-rw-r--r--arch/arm64/kvm/sys_regs.c2
-rw-r--r--arch/arm64/lib/copy_page.S9
-rw-r--r--arch/arm64/mm/dma-mapping.c4
-rw-r--r--arch/arm64/mm/fault.c15
-rw-r--r--arch/arm64/mm/mmu.c18
-rw-r--r--arch/arm64/mm/numa.c7
-rw-r--r--arch/blackfin/include/asm/bug.h4
-rw-r--r--arch/blackfin/include/asm/flat.h3
-rw-r--r--arch/blackfin/kernel/flat.c4
-rw-r--r--arch/h8300/include/asm/flat.h2
-rw-r--r--arch/ia64/include/asm/tlb.h8
-rw-r--r--arch/m68k/include/asm/flat.h3
-rw-r--r--arch/mips/Kconfig2
-rw-r--r--arch/mips/Makefile15
-rw-r--r--arch/mips/boot/compressed/.gitignore2
-rw-r--r--arch/mips/cavium-octeon/octeon-usb.c2
-rw-r--r--arch/mips/dec/int-handler.S34
-rw-r--r--arch/mips/include/asm/cache.h2
-rw-r--r--arch/mips/include/asm/cpu-features.h3
-rw-r--r--arch/mips/include/asm/mach-ralink/ralink_regs.h2
-rw-r--r--arch/mips/include/asm/octeon/cvmx-l2c-defs.h37
-rw-r--r--arch/mips/include/asm/octeon/cvmx-l2d-defs.h60
-rw-r--r--arch/mips/include/asm/octeon/cvmx.h1
-rw-r--r--arch/mips/include/uapi/asm/ioctls.h2
-rw-r--r--arch/mips/kernel/smp.c6
-rw-r--r--arch/mips/mm/dma-default.c2
-rw-r--r--arch/mips/mm/uasm-mips.c2
-rw-r--r--arch/mips/net/ebpf_jit.c1950
-rw-r--r--arch/mips/pci/pci.c7
-rw-r--r--arch/mips/ralink/mt7620.c1
-rw-r--r--arch/mips/vdso/gettimeofday.c6
-rw-r--r--arch/mn10300/include/asm/bug.h2
-rw-r--r--arch/parisc/Kconfig3
-rw-r--r--arch/parisc/configs/712_defconfig41
-rw-r--r--arch/parisc/configs/a500_defconfig50
-rw-r--r--arch/parisc/configs/b180_defconfig17
-rw-r--r--arch/parisc/configs/c3000_defconfig38
-rw-r--r--arch/parisc/configs/c8000_defconfig17
-rw-r--r--arch/parisc/configs/default_defconfig49
-rw-r--r--arch/parisc/configs/generic-32bit_defconfig21
-rw-r--r--arch/parisc/configs/generic-64bit_defconfig48
-rw-r--r--arch/parisc/include/asm/bug.h6
-rw-r--r--arch/parisc/include/asm/pdcpat.h16
-rw-r--r--arch/parisc/include/asm/thread_info.h2
-rw-r--r--arch/parisc/include/uapi/asm/ioctls.h2
-rw-r--r--arch/parisc/kernel/cache.c39
-rw-r--r--arch/parisc/kernel/firmware.c36
-rw-r--r--arch/parisc/kernel/irq.c10
-rw-r--r--arch/parisc/kernel/pdt.c23
-rw-r--r--arch/parisc/kernel/process.c2
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S2
-rw-r--r--arch/powerpc/Makefile25
-rw-r--r--arch/powerpc/boot/Makefile14
-rw-r--r--arch/powerpc/configs/powernv_defconfig3
-rw-r--r--arch/powerpc/configs/ppc64_defconfig3
-rw-r--r--arch/powerpc/configs/pseries_defconfig3
-rw-r--r--arch/powerpc/include/asm/book3s/64/hash.h1
-rw-r--r--arch/powerpc/include/asm/book3s/64/mmu.h15
-rw-r--r--arch/powerpc/include/asm/book3s/64/pgtable.h11
-rw-r--r--arch/powerpc/include/asm/book3s/64/radix.h1
-rw-r--r--arch/powerpc/include/asm/bug.h8
-rw-r--r--arch/powerpc/include/asm/mmu_context.h18
-rw-r--r--arch/powerpc/include/asm/pgtable.h7
-rw-r--r--arch/powerpc/include/uapi/asm/ioctls.h2
-rw-r--r--arch/powerpc/kernel/entry_64.S60
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S38
-rw-r--r--arch/powerpc/kernel/idle_book3s.S21
-rw-r--r--arch/powerpc/kernel/irq.c15
-rw-r--r--arch/powerpc/kernel/process.c4
-rw-r--r--arch/powerpc/kernel/ptrace.c13
-rw-r--r--arch/powerpc/kernel/smp.c18
-rw-r--r--arch/powerpc/kernel/watchdog.c49
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_hv.c4
-rw-r--r--arch/powerpc/kvm/book3s_hv.c2
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S59
-rw-r--r--arch/powerpc/mm/mem.c1
-rw-r--r--arch/powerpc/mm/mmu_context_book3s64.c5
-rw-r--r--arch/powerpc/mm/pgtable-hash64.c44
-rw-r--r--arch/powerpc/mm/pgtable-radix.c62
-rw-r--r--arch/powerpc/mm/pgtable_64.c8
-rw-r--r--arch/powerpc/mm/subpage-prot.c2
-rw-r--r--arch/powerpc/mm/tlb-radix.c45
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_rdb.c2
-rw-r--r--arch/powerpc/platforms/powernv/idle.c41
-rw-r--r--arch/powerpc/platforms/powernv/opal.c2
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c8
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c1
-rw-r--r--arch/s390/include/asm/bug.h4
-rw-r--r--arch/s390/include/asm/tlb.h17
-rw-r--r--arch/s390/kernel/perf_cpum_sf.c2
-rw-r--r--arch/s390/kvm/kvm-s390.c8
-rw-r--r--arch/s390/mm/pgtable.c6
-rw-r--r--arch/s390/net/bpf_jit_comp.c3
-rw-r--r--arch/sh/include/asm/bug.h4
-rw-r--r--arch/sh/include/asm/tlb.h8
-rw-r--r--arch/sh/include/uapi/asm/ioctls.h2
-rw-r--r--arch/sparc/configs/sparc32_defconfig4
-rw-r--r--arch/sparc/configs/sparc64_defconfig4
-rw-r--r--arch/sparc/include/asm/mmu_context_64.h14
-rw-r--r--arch/sparc/include/asm/spitfire.h16
-rw-r--r--arch/sparc/include/asm/trap_block.h1
-rw-r--r--arch/sparc/include/uapi/asm/ioctls.h2
-rw-r--r--arch/sparc/kernel/cpu.c6
-rw-r--r--arch/sparc/kernel/cpumap.c1
-rw-r--r--arch/sparc/kernel/head_64.S22
-rw-r--r--arch/sparc/kernel/pci_sun4v.c12
-rw-r--r--arch/sparc/kernel/setup_64.c15
-rw-r--r--arch/sparc/kernel/smp_64.c185
-rw-r--r--arch/sparc/kernel/sun4v_ivec.S15
-rw-r--r--arch/sparc/kernel/traps_64.c1
-rw-r--r--arch/sparc/kernel/tsb.S12
-rw-r--r--arch/sparc/lib/U3memcpy.S4
-rw-r--r--arch/sparc/mm/init_64.c39
-rw-r--r--arch/sparc/power/hibernate.c3
-rw-r--r--arch/um/include/asm/tlb.h13
-rw-r--r--arch/x86/Kconfig.debug1
-rw-r--r--arch/x86/boot/Makefile5
-rw-r--r--arch/x86/boot/compressed/Makefile1
-rw-r--r--arch/x86/boot/string.c9
-rw-r--r--arch/x86/configs/i386_defconfig3
-rw-r--r--arch/x86/configs/x86_64_defconfig3
-rw-r--r--arch/x86/entry/entry_64.S1
-rw-r--r--arch/x86/events/core.c4
-rw-r--r--arch/x86/events/intel/core.c164
-rw-r--r--arch/x86/events/intel/cstate.c26
-rw-r--r--arch/x86/events/intel/ds.c22
-rw-r--r--arch/x86/events/intel/lbr.c4
-rw-r--r--arch/x86/events/intel/uncore_snbep.c51
-rw-r--r--arch/x86/events/perf_event.h2
-rw-r--r--arch/x86/include/asm/bug.h4
-rw-r--r--arch/x86/include/asm/entry_arch.h2
-rw-r--r--arch/x86/include/asm/hardirq.h1
-rw-r--r--arch/x86/include/asm/hw_irq.h2
-rw-r--r--arch/x86/include/asm/hypervisor.h10
-rw-r--r--arch/x86/include/asm/io.h4
-rw-r--r--arch/x86/include/asm/irq_vectors.h3
-rw-r--r--arch/x86/include/asm/kprobes.h8
-rw-r--r--arch/x86/include/asm/mmu_context.h2
-rw-r--r--arch/x86/include/asm/paravirt_types.h16
-rw-r--r--arch/x86/include/asm/processor.h2
-rw-r--r--arch/x86/kernel/acpi/boot.c8
-rw-r--r--arch/x86/kernel/apic/io_apic.c2
-rw-r--r--arch/x86/kernel/cpu/amd.c1
-rw-r--r--arch/x86/kernel/cpu/aperfmperf.c40
-rw-r--r--arch/x86/kernel/devicetree.c3
-rw-r--r--arch/x86/kernel/early-quirks.c1
-rw-r--r--arch/x86/kernel/hpet.c27
-rw-r--r--arch/x86/kernel/irq.c19
-rw-r--r--arch/x86/kernel/irqinit.c2
-rw-r--r--arch/x86/kernel/kprobes/core.c10
-rw-r--r--arch/x86/kernel/kvm.c6
-rw-r--r--arch/x86/kernel/reboot.c6
-rw-r--r--arch/x86/kvm/Kconfig2
-rw-r--r--arch/x86/kvm/hyperv.c7
-rw-r--r--arch/x86/kvm/lapic.c17
-rw-r--r--arch/x86/kvm/svm.c10
-rw-r--r--arch/x86/kvm/vmx.c308
-rw-r--r--arch/x86/kvm/x86.c24
-rw-r--r--arch/x86/math-emu/Makefile4
-rw-r--r--arch/x86/math-emu/fpu_emu.h2
-rw-r--r--arch/x86/math-emu/reg_compare.c16
-rw-r--r--arch/x86/mm/init.c3
-rw-r--r--arch/x86/platform/intel-mid/device_libs/platform_max7315.c6
-rw-r--r--arch/x86/platform/uv/tlb_uv.c29
-rw-r--r--arch/x86/xen/enlighten_hvm.c59
-rw-r--r--arch/x86/xen/smp_pv.c3
-rw-r--r--arch/x86/xen/time.c1
-rw-r--r--arch/xtensa/include/asm/Kbuild2
-rw-r--r--arch/xtensa/include/asm/device.h15
-rw-r--r--arch/xtensa/include/asm/param.h18
-rw-r--r--arch/xtensa/include/uapi/asm/ioctls.h2
-rw-r--r--arch/xtensa/kernel/xtensa_ksyms.c2
-rw-r--r--arch/xtensa/mm/cache.c16
-rw-r--r--block/bfq-iosched.c3
-rw-r--r--block/bfq-iosched.h24
-rw-r--r--block/bfq-wf2q.c148
-rw-r--r--block/bio-integrity.c6
-rw-r--r--block/blk-core.c4
-rw-r--r--block/blk-mq-cpumap.c4
-rw-r--r--block/blk-mq.c21
-rw-r--r--crypto/authencesn.c5
-rw-r--r--drivers/acpi/acpi_apd.c4
-rw-r--r--drivers/acpi/acpi_lpss.c14
-rw-r--r--drivers/acpi/acpi_watchdog.c7
-rw-r--r--drivers/acpi/ec.c39
-rw-r--r--drivers/acpi/internal.h4
-rw-r--r--drivers/acpi/nfit/core.c10
-rw-r--r--drivers/acpi/numa.c2
-rw-r--r--drivers/acpi/sleep.c6
-rw-r--r--drivers/acpi/spcr.c36
-rw-r--r--drivers/android/binder.c17
-rw-r--r--drivers/ata/Kconfig4
-rw-r--r--drivers/ata/libata-core.c6
-rw-r--r--drivers/ata/libata-eh.c7
-rw-r--r--drivers/ata/libata-scsi.c6
-rw-r--r--drivers/ata/sata_rcar.c8
-rw-r--r--drivers/atm/zatm.c2
-rw-r--r--drivers/base/dma-coherent.c164
-rw-r--r--drivers/base/dma-mapping.c2
-rw-r--r--drivers/base/firmware_class.c49
-rw-r--r--drivers/base/power/domain.c8
-rw-r--r--drivers/base/regmap/regmap-w1.c4
-rw-r--r--drivers/block/nbd.c20
-rw-r--r--drivers/block/sunvdc.c61
-rw-r--r--drivers/block/virtio_blk.c7
-rw-r--r--drivers/block/xen-blkfront.c25
-rw-r--r--drivers/block/zram/zram_drv.c4
-rw-r--r--drivers/bus/uniphier-system-bus.c14
-rw-r--r--drivers/char/agp/ali-agp.c2
-rw-r--r--drivers/char/agp/amd-k7-agp.c4
-rw-r--r--drivers/char/agp/amd64-agp.c2
-rw-r--r--drivers/char/agp/ati-agp.c2
-rw-r--r--drivers/char/agp/efficeon-agp.c2
-rw-r--r--drivers/char/agp/intel-agp.c2
-rw-r--r--drivers/char/agp/nvidia-agp.c2
-rw-r--r--drivers/char/agp/sis-agp.c2
-rw-r--r--drivers/char/agp/uninorth-agp.c2
-rw-r--r--drivers/char/random.c2
-rw-r--r--drivers/clk/clk-gemini.c14
-rw-r--r--drivers/clk/keystone/sci-clk.c66
-rw-r--r--drivers/clk/meson/clk-mpll.c7
-rw-r--r--drivers/clk/meson/clkc.h1
-rw-r--r--drivers/clk/meson/gxbb.c5
-rw-r--r--drivers/clk/meson/meson8b.c5
-rw-r--r--drivers/clk/samsung/clk-exynos5420.c16
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun5i.c2
-rw-r--r--drivers/clk/x86/clk-pmc-atom.c7
-rw-r--r--drivers/clocksource/timer-of.c12
-rw-r--r--drivers/cpufreq/intel_pstate.c29
-rw-r--r--drivers/cpuidle/cpuidle-powernv.c10
-rw-r--r--drivers/crypto/Kconfig2
-rw-r--r--drivers/crypto/bcm/spu2.c1
-rw-r--r--drivers/crypto/cavium/nitrox/nitrox_main.c3
-rw-r--r--drivers/crypto/inside-secure/safexcel.c5
-rw-r--r--drivers/crypto/inside-secure/safexcel_hash.c8
-rw-r--r--drivers/dax/device-dax.h2
-rw-r--r--drivers/dax/device.c33
-rw-r--r--drivers/dax/pmem.c12
-rw-r--r--drivers/dax/super.c6
-rw-r--r--drivers/dma-buf/dma-fence.c21
-rw-r--r--drivers/dma-buf/reservation.c99
-rw-r--r--drivers/dma-buf/sw_sync.c201
-rw-r--r--drivers/dma-buf/sync_debug.c21
-rw-r--r--drivers/dma-buf/sync_debug.h26
-rw-r--r--drivers/dma-buf/sync_file.c13
-rw-r--r--drivers/fsi/fsi-core.c7
-rw-r--r--drivers/gpio/Kconfig1
-rw-r--r--drivers/gpio/gpio-exar.c2
-rw-r--r--drivers/gpio/gpio-lp87565.c46
-rw-r--r--drivers/gpio/gpio-mxc.c3
-rw-r--r--drivers/gpio/gpio-tegra.c6
-rw-r--r--drivers/gpio/gpiolib.c9
-rw-r--r--drivers/gpu/drm/Makefile2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/Makefile2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h223
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c72
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c47
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h18
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c189
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c227
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c32
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c161
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c17
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c22
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c30
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c129
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c251
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_display.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c31
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c31
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c81
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h77
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c64
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c73
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_job.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c39
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h13
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_object.c234
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_object.h68
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c63
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c53
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h40
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c13
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_test.c56
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h82
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c488
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h22
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c18
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c18
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c85
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h62
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c25
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c504
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h39
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c77
-rw-r--r--drivers/gpu/drm/amd/amdgpu/cik.c9
-rw-r--r--drivers/gpu/drm/amd/amdgpu/cik_sdma.c60
-rw-r--r--drivers/gpu/drm/amd/amdgpu/clearstate_gfx9.h41
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v10_0.c168
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v11_0.c113
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v6_0.c152
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v8_0.c115
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_virtual.c125
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c109
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c243
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c172
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c176
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v9_0.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c18
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c80
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c78
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c91
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c142
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c111
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c46
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c15
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/psp_v10_0.c96
-rw-r--r--drivers/gpu/drm/amd/amdgpu/psp_v10_0.h5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/psp_v3_1.c10
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c42
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c70
-rw-r--r--drivers/gpu/drm/amd/amdgpu/si.c30
-rw-r--r--drivers/gpu/drm/amd/amdgpu/si_dpm.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/soc15.c66
-rw-r--r--drivers/gpu/drm/amd/amdgpu/soc15_common.h7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/soc15d.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c80
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vce_v4_0.c33
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vi.c3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_chardev.c183
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c102
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c21
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h27
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device.c127
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c325
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h1
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c8
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c8
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c40
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_events.c33
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c2
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c2
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c63
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_module.c10
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h3
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c62
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c46
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c294
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_pasid.c7
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h330
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_vi.h140
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_priv.h32
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_process.c25
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c71
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_queue.c12
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_topology.c46
-rw-r--r--drivers/gpu/drm/amd/include/atomfirmware.h63
-rw-r--r--drivers/gpu/drm/amd/include/cgs_common.h6
-rw-r--r--drivers/gpu/drm/amd/include/kgd_kfd_interface.h33
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c113
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c25
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c241
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h8
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c9
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h2
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c12
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c314
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h15
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c1291
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.h16
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c88
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c6
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h5
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/hwmgr.h2
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/pp_debug.h6
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/pp_soc15.h2
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h7
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/smu9.h13
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/smu9_driver_if.h5
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/smumgr.h3
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h4
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c19
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.h1
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c184
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h11
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c4
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c34
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.h12
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c6
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h8
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c11
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c30
-rw-r--r--drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h9
-rw-r--r--drivers/gpu/drm/arc/arcpgu_crtc.c43
-rw-r--r--drivers/gpu/drm/arc/arcpgu_drv.c61
-rw-r--r--drivers/gpu/drm/arm/hdlcd_crtc.c11
-rw-r--r--drivers/gpu/drm/arm/hdlcd_drv.c4
-rw-r--r--drivers/gpu/drm/arm/malidp_crtc.c10
-rw-r--r--drivers/gpu/drm/arm/malidp_drv.c4
-rw-r--r--drivers/gpu/drm/arm/malidp_planes.c3
-rw-r--r--drivers/gpu/drm/armada/armada_crtc.c20
-rw-r--r--drivers/gpu/drm/armada/armada_crtc.h2
-rw-r--r--drivers/gpu/drm/armada/armada_drv.c4
-rw-r--r--drivers/gpu/drm/armada/armada_fbdev.c3
-rw-r--r--drivers/gpu/drm/armada/armada_overlay.c3
-rw-r--r--drivers/gpu/drm/ast/ast_dp501.c25
-rw-r--r--drivers/gpu/drm/ast/ast_drv.c6
-rw-r--r--drivers/gpu/drm/ast/ast_drv.h4
-rw-r--r--drivers/gpu/drm/ast/ast_fb.c23
-rw-r--r--drivers/gpu/drm/ast/ast_main.c13
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c48
-rw-r--r--drivers/gpu/drm/ast/ast_ttm.c19
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c17
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c32
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h16
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c45
-rw-r--r--drivers/gpu/drm/bochs/bochs_drv.c6
-rw-r--r--drivers/gpu/drm/bochs/bochs_fbdev.c7
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511_drv.c11
-rw-r--r--drivers/gpu/drm/bridge/analogix-anx78xx.c10
-rw-r--r--drivers/gpu/drm/bridge/analogix/analogix_dp_core.c1
-rw-r--r--drivers/gpu/drm/bridge/dumb-vga-dac.c10
-rw-r--r--drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c1
-rw-r--r--drivers/gpu/drm/bridge/nxp-ptn3460.c7
-rw-r--r--drivers/gpu/drm/bridge/panel.c36
-rw-r--r--drivers/gpu/drm/bridge/parade-ps8622.c7
-rw-r--r--drivers/gpu/drm/bridge/sii902x.c9
-rw-r--r--drivers/gpu/drm/bridge/synopsys/Kconfig16
-rw-r--r--drivers/gpu/drm/bridge/synopsys/Makefile3
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c2
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c327
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h19
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c3
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c107
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.h46
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c981
-rw-r--r--drivers/gpu/drm/bridge/tc358767.c9
-rw-r--r--drivers/gpu/drm/bridge/ti-tfp410.c7
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_drv.c6
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_drv.h8
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_fbdev.c5
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_main.c10
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_mode.c71
-rw-r--r--drivers/gpu/drm/drm_atomic.c219
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c611
-rw-r--r--drivers/gpu/drm/drm_color_mgmt.c3
-rw-r--r--drivers/gpu/drm/drm_connector.c7
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c3
-rw-r--r--drivers/gpu/drm/drm_crtc_internal.h7
-rw-r--r--drivers/gpu/drm/drm_debugfs_crc.c59
-rw-r--r--drivers/gpu/drm/drm_dp_helper.c5
-rw-r--r--drivers/gpu/drm/drm_dp_mst_topology.c130
-rw-r--r--drivers/gpu/drm/drm_drv.c56
-rw-r--r--drivers/gpu/drm/drm_dumb_buffers.c26
-rw-r--r--drivers/gpu/drm/drm_edid.c440
-rw-r--r--drivers/gpu/drm/drm_fb_cma_helper.c184
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c681
-rw-r--r--drivers/gpu/drm/drm_file.c9
-rw-r--r--drivers/gpu/drm/drm_framebuffer.c2
-rw-r--r--drivers/gpu/drm/drm_gem.c47
-rw-r--r--drivers/gpu/drm/drm_gem_cma_helper.c39
-rw-r--r--drivers/gpu/drm/drm_gem_framebuffer_helper.c283
-rw-r--r--drivers/gpu/drm/drm_internal.h14
-rw-r--r--drivers/gpu/drm/drm_ioc32.c2
-rw-r--r--drivers/gpu/drm/drm_ioctl.c17
-rw-r--r--drivers/gpu/drm/drm_mipi_dsi.c6
-rw-r--r--drivers/gpu/drm/drm_mode_config.c7
-rw-r--r--drivers/gpu/drm/drm_mode_object.c159
-rw-r--r--drivers/gpu/drm/drm_modes.c91
-rw-r--r--drivers/gpu/drm/drm_modeset_helper.c1
-rw-r--r--drivers/gpu/drm/drm_modeset_lock.c12
-rw-r--r--drivers/gpu/drm/drm_of.c4
-rw-r--r--drivers/gpu/drm/drm_pci.c40
-rw-r--r--drivers/gpu/drm/drm_plane.c120
-rw-r--r--drivers/gpu/drm/drm_probe_helper.c4
-rw-r--r--drivers/gpu/drm/drm_property.c23
-rw-r--r--drivers/gpu/drm/drm_scdc_helper.c33
-rw-r--r--drivers/gpu/drm/drm_simple_kms_helper.c23
-rw-r--r--drivers/gpu/drm/drm_syncobj.c2
-rw-r--r--drivers/gpu/drm/drm_vblank.c187
-rw-r--r--drivers/gpu/drm/drm_vm.c2
-rw-r--r--drivers/gpu/drm/etnaviv/Kconfig2
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_drv.c8
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gem.c45
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c2
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c8
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gpu.c8
-rw-r--r--drivers/gpu/drm/exynos/Kconfig1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c10
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dpi.c1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c9
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dsi.c14
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fb.c41
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c26
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.c30
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.h5
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_mic.c24
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c3
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c1
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c13
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c10
-rw-r--r--drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c5
-rw-r--r--drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c2
-rw-r--r--drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c2
-rw-r--r--drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c1
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c22
-rw-r--r--drivers/gpu/drm/gma500/gem.c30
-rw-r--r--drivers/gpu/drm/gma500/gma_display.c32
-rw-r--r--drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c4
-rw-r--r--drivers/gpu/drm/gma500/mdfld_intel_display.c4
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.c7
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h2
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_display.c7
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_drv.h1
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c12
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c4
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c5
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c1
-rw-r--r--drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c8
-rw-r--r--drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c17
-rw-r--r--drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c30
-rw-r--r--drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h2
-rw-r--r--drivers/gpu/drm/i2c/tda998x_drv.c12
-rw-r--r--drivers/gpu/drm/i810/i810_drv.c5
-rw-r--r--drivers/gpu/drm/i915/Kconfig1
-rw-r--r--drivers/gpu/drm/i915/Kconfig.debug1
-rw-r--r--drivers/gpu/drm/i915/Makefile1
-rw-r--r--drivers/gpu/drm/i915/gvt/aperture_gm.c4
-rw-r--r--drivers/gpu/drm/i915/gvt/cmd_parser.c8
-rw-r--r--drivers/gpu/drm/i915/gvt/cmd_parser.h2
-rw-r--r--drivers/gpu/drm/i915/gvt/display.c28
-rw-r--r--drivers/gpu/drm/i915/gvt/execlist.c42
-rw-r--r--drivers/gpu/drm/i915/gvt/firmware.c11
-rw-r--r--drivers/gpu/drm/i915/gvt/gtt.c128
-rw-r--r--drivers/gpu/drm/i915/gvt/gtt.h26
-rw-r--r--drivers/gpu/drm/i915/gvt/gvt.h17
-rw-r--r--drivers/gpu/drm/i915/gvt/handlers.c88
-rw-r--r--drivers/gpu/drm/i915/gvt/kvmgt.c17
-rw-r--r--drivers/gpu/drm/i915/gvt/render.c54
-rw-r--r--drivers/gpu/drm/i915/gvt/scheduler.c116
-rw-r--r--drivers/gpu/drm/i915/gvt/scheduler.h1
-rw-r--r--drivers/gpu/drm/i915/gvt/vgpu.c15
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c202
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c197
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h366
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c432
-rw-r--r--drivers/gpu/drm/i915/i915_gem_clflush.c10
-rw-r--r--drivers/gpu/drm/i915/i915_gem_clflush.h2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c290
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.h79
-rw-r--r--drivers/gpu/drm/i915/i915_gem_evict.c4
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c654
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c109
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.h3
-rw-r--r--drivers/gpu/drm/i915/i915_gem_internal.c7
-rw-r--r--drivers/gpu/drm/i915/i915_gem_object.c48
-rw-r--r--drivers/gpu/drm/i915/i915_gem_object.h32
-rw-r--r--drivers/gpu/drm/i915/i915_gem_render_state.c4
-rw-r--r--drivers/gpu/drm/i915/i915_gem_request.c104
-rw-r--r--drivers/gpu/drm/i915/i915_gem_request.h2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_shrinker.c11
-rw-r--r--drivers/gpu/drm/i915/i915_gem_stolen.c8
-rw-r--r--drivers/gpu/drm/i915/i915_gem_userptr.c4
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.c11
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c377
-rw-r--r--drivers/gpu/drm/i915/i915_oa_bdw.c5310
-rw-r--r--drivers/gpu/drm/i915/i915_oa_bdw.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_bxt.c2624
-rw-r--r--drivers/gpu/drm/i915/i915_oa_bxt.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_chv.c2808
-rw-r--r--drivers/gpu/drm/i915/i915_oa_chv.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_glk.c2536
-rw-r--r--drivers/gpu/drm/i915/i915_oa_glk.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_hsw.c765
-rw-r--r--drivers/gpu/drm/i915/i915_oa_hsw.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_kblgt2.c2924
-rw-r--r--drivers/gpu/drm/i915/i915_oa_kblgt2.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_kblgt3.c2973
-rw-r--r--drivers/gpu/drm/i915/i915_oa_kblgt3.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_sklgt2.c3413
-rw-r--r--drivers/gpu/drm/i915/i915_oa_sklgt2.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_sklgt3.c2972
-rw-r--r--drivers/gpu/drm/i915/i915_oa_sklgt3.h8
-rw-r--r--drivers/gpu/drm/i915/i915_oa_sklgt4.c3026
-rw-r--r--drivers/gpu/drm/i915/i915_oa_sklgt4.h8
-rw-r--r--drivers/gpu/drm/i915/i915_params.c10
-rw-r--r--drivers/gpu/drm/i915/i915_params.h3
-rw-r--r--drivers/gpu/drm/i915/i915_pci.c7
-rw-r--r--drivers/gpu/drm/i915/i915_perf.c813
-rw-r--r--drivers/gpu/drm/i915/i915_pvinfo.h8
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h521
-rw-r--r--drivers/gpu/drm/i915/i915_selftest.h2
-rw-r--r--drivers/gpu/drm/i915/i915_sysfs.c16
-rw-r--r--drivers/gpu/drm/i915/i915_vgpu.c7
-rw-r--r--drivers/gpu/drm/i915/i915_vgpu.h3
-rw-r--r--drivers/gpu/drm/i915/i915_vma.c31
-rw-r--r--drivers/gpu/drm/i915/i915_vma.h8
-rw-r--r--drivers/gpu/drm/i915/intel_atomic_plane.c15
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c24
-rw-r--r--drivers/gpu/drm/i915/intel_color.c48
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c2
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c125
-rw-r--r--drivers/gpu/drm/i915/intel_device_info.c2
-rw-r--r--drivers/gpu/drm/i915/intel_display.c1778
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c218
-rw-r--r--drivers/gpu/drm/i915/intel_dp_aux_backlight.c98
-rw-r--r--drivers/gpu/drm/i915/intel_dp_link_training.c8
-rw-r--r--drivers/gpu/drm/i915/intel_dp_mst.c52
-rw-r--r--drivers/gpu/drm/i915/intel_dpll_mgr.c11
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h57
-rw-r--r--drivers/gpu/drm/i915/intel_dsi.c4
-rw-r--r--drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c2
-rw-r--r--drivers/gpu/drm/i915/intel_dsi_vbt.c2
-rw-r--r--drivers/gpu/drm/i915/intel_dvo.c4
-rw-r--r--drivers/gpu/drm/i915/intel_engine_cs.c45
-rw-r--r--drivers/gpu/drm/i915/intel_fbc.c4
-rw-r--r--drivers/gpu/drm/i915/intel_fbdev.c72
-rw-r--r--drivers/gpu/drm/i915/intel_fifo_underrun.c6
-rw-r--r--drivers/gpu/drm/i915/intel_gvt.c2
-rw-r--r--drivers/gpu/drm/i915/intel_hangcheck.c2
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c204
-rw-r--r--drivers/gpu/drm/i915/intel_hotplug.c57
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c36
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c38
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.h1
-rw-r--r--drivers/gpu/drm/i915/intel_lspcon.c4
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c5
-rw-r--r--drivers/gpu/drm/i915/intel_opregion.c45
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c11
-rw-r--r--drivers/gpu/drm/i915/intel_panel.c11
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c247
-rw-r--r--drivers/gpu/drm/i915/intel_psr.c1
-rw-r--r--drivers/gpu/drm/i915/intel_renderstate_gen9.c4
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c8
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h13
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c1028
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c81
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c161
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c2
-rw-r--r--drivers/gpu/drm/i915/intel_uc.c4
-rw-r--r--drivers/gpu/drm/i915/intel_uncore.c22
-rw-r--r--drivers/gpu/drm/i915/selftests/huge_gem_object.c6
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_coherency.c2
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_context.c6
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_gem_gtt.c10
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_vma.c8
-rw-r--r--drivers/gpu/drm/i915/selftests/intel_hangcheck.c343
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_context.c36
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_context.h5
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_engine.c8
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_engine.h3
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_gem_device.c32
-rw-r--r--drivers/gpu/drm/i915/selftests/mock_gtt.c3
-rw-r--r--drivers/gpu/drm/imx/imx-drm-core.c10
-rw-r--r--drivers/gpu/drm/imx/imx-ldb.c1
-rw-r--r--drivers/gpu/drm/imx/imx-tve.c1
-rw-r--r--drivers/gpu/drm/imx/ipuv3-crtc.c5
-rw-r--r--drivers/gpu/drm/imx/ipuv3-plane.c61
-rw-r--r--drivers/gpu/drm/imx/parallel-display.c3
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_color.c4
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_ovl.c4
-rw-r--r--drivers/gpu/drm/mediatek/mtk_disp_rdma.c4
-rw-r--r--drivers/gpu/drm/mediatek/mtk_dpi.c6
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_crtc.c17
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c6
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_drv.c32
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_fb.c4
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_gem.c27
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_gem.h3
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_plane.c2
-rw-r--r--drivers/gpu/drm/mediatek/mtk_dsi.c5
-rw-r--r--drivers/gpu/drm/mediatek/mtk_hdmi.c11
-rw-r--r--drivers/gpu/drm/meson/meson_crtc.c10
-rw-r--r--drivers/gpu/drm/meson/meson_drv.c7
-rw-r--r--drivers/gpu/drm/meson/meson_plane.c1
-rw-r--r--drivers/gpu/drm/meson/meson_venc_cvbs.c1
-rw-r--r--drivers/gpu/drm/mga/mga_drv.c5
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_cursor.c2
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.c7
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.h5
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_fb.c7
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_main.c10
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c62
-rw-r--r--drivers/gpu/drm/msm/Kconfig2
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx_gpu.c2
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx_gpu.h1
-rw-r--r--drivers/gpu/drm/msm/adreno/a4xx_gpu.c2
-rw-r--r--drivers/gpu/drm/msm/adreno/a4xx_gpu.h1
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_gpu.c232
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_gpu.h4
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_power.c14
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c64
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi.c5
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi.h2
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_host.c108
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_manager.c1
-rw-r--r--drivers/gpu/drm/msm/dsi/phy/dsi_phy.c2
-rw-r--r--drivers/gpu/drm/msm/edp/edp_connector.c1
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.c2
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_bridge.c6
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi_connector.c64
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c11
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c4
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c1
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c2
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c7
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c38
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c14
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c27
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c66
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h7
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c63
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c10
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c59
-rw-r--r--drivers/gpu/drm/msm/msm_atomic.c34
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c37
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h12
-rw-r--r--drivers/gpu/drm/msm/msm_fb.c45
-rw-r--r--drivers/gpu/drm/msm/msm_fbdev.c58
-rw-r--r--drivers/gpu/drm/msm/msm_gem.c58
-rw-r--r--drivers/gpu/drm/msm/msm_gem_submit.c6
-rw-r--r--drivers/gpu/drm/msm/msm_gem_vma.c2
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.c85
-rw-r--r--drivers/gpu/drm/msm/msm_kms.h2
-rw-r--r--drivers/gpu/drm/msm/msm_ringbuffer.c12
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_drv.c7
-rw-r--r--drivers/gpu/drm/mxsfb/mxsfb_out.c1
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/crtc.c62
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/overlay.c71
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c7
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c18
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_crtc.h3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c28
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c35
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c22
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_ttm.c6
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c174
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/base.c33
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c8
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c30
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c35
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgf119.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp100.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm200.c39
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c6
-rw-r--r--drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c3
-rw-r--r--drivers/gpu/drm/omapdrm/displays/connector-hdmi.c104
-rw-r--r--drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c81
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-dpi.c3
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c2
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c2
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c5
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c2
-rw-r--r--drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/Makefile2
-rw-r--r--drivers/gpu/drm/omapdrm/dss/core.c190
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dispc.c824
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dpi.c88
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dsi.c329
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss.c406
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss.h49
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss_features.c905
-rw-r--r--drivers/gpu/drm/omapdrm/dss/dss_features.h109
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi.h16
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi4.c7
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi4_core.c38
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi5.c7
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi_phy.c60
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi_pll.c24
-rw-r--r--drivers/gpu/drm/omapdrm/dss/hdmi_wp.c12
-rw-r--r--drivers/gpu/drm/omapdrm/dss/omapdss.h25
-rw-r--r--drivers/gpu/drm/omapdrm/dss/pll.c29
-rw-r--r--drivers/gpu/drm/omapdrm/dss/venc.c86
-rw-r--r--drivers/gpu/drm/omapdrm/dss/video-pll.c3
-rw-r--r--drivers/gpu/drm/omapdrm/omap_connector.c38
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c137
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c124
-rw-r--r--drivers/gpu/drm/omapdrm/omap_encoder.c3
-rw-r--r--drivers/gpu/drm/omapdrm/omap_fb.c2
-rw-r--r--drivers/gpu/drm/omapdrm/omap_fbdev.c1
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c2
-rw-r--r--drivers/gpu/drm/omapdrm/omap_plane.c3
-rw-r--r--drivers/gpu/drm/panel/panel-lvds.c16
-rw-r--r--drivers/gpu/drm/pl111/pl111_connector.c1
-rw-r--r--drivers/gpu/drm/pl111/pl111_display.c5
-rw-r--r--drivers/gpu/drm/pl111/pl111_drv.c9
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c35
-rw-r--r--drivers/gpu/drm/qxl/qxl_drv.c8
-rw-r--r--drivers/gpu/drm/qxl/qxl_drv.h1
-rw-r--r--drivers/gpu/drm/qxl/qxl_fb.c1
-rw-r--r--drivers/gpu/drm/qxl/qxl_ioctl.c17
-rw-r--r--drivers/gpu/drm/qxl/qxl_object.c4
-rw-r--r--drivers/gpu/drm/qxl/qxl_ttm.c2
-rw-r--r--drivers/gpu/drm/r128/r128_drv.c5
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon_acpi.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_acpi.h3
-rw-r--r--drivers/gpu/drm/radeon/radeon_audio.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c10
-rw-r--r--drivers/gpu/drm/radeon/radeon_cursor.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c95
-rw-r--r--drivers/gpu/drm/radeon/radeon_dp_mst.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c7
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c14
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c30
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_kfd.c16
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c32
-rw-r--r--drivers/gpu/drm/radeon/radeon_vm.c4
-rw-r--r--drivers/gpu/drm/radeon/vce_v2_0.c4
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.c199
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.h17
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.c30
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_encoder.c4
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_group.c38
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_kms.c129
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c1
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c12
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.c119
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.h3
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_vsp.c56
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_vsp.h10
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c2
-rw-r--r--drivers/gpu/drm/rockchip/Kconfig19
-rw-r--r--drivers/gpu/drm/rockchip/cdn-dp-core.c1
-rw-r--r--drivers/gpu/drm/rockchip/dw-mipi-dsi.c1
-rw-r--r--drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c110
-rw-r--r--drivers/gpu/drm/rockchip/inno_hdmi.c5
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.c21
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_fb.c31
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c2
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_gem.c28
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_gem.h3
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.c215
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.h84
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_vop_reg.c375
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_vop_reg.h905
-rw-r--r--drivers/gpu/drm/savage/savage_drv.c5
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_drv.c6
-rw-r--r--drivers/gpu/drm/sis/sis_drv.c5
-rw-r--r--drivers/gpu/drm/sti/sti_crtc.c10
-rw-r--r--drivers/gpu/drm/sti/sti_cursor.c3
-rw-r--r--drivers/gpu/drm/sti/sti_drv.c3
-rw-r--r--drivers/gpu/drm/sti/sti_dvo.c3
-rw-r--r--drivers/gpu/drm/sti/sti_gdp.c3
-rw-r--r--drivers/gpu/drm/sti/sti_hda.c1
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.c4
-rw-r--r--drivers/gpu/drm/sti/sti_hqvdp.c8
-rw-r--r--drivers/gpu/drm/stm/Kconfig10
-rw-r--r--drivers/gpu/drm/stm/Makefile2
-rw-r--r--drivers/gpu/drm/stm/drv.c23
-rw-r--r--drivers/gpu/drm/stm/dw_mipi_dsi-stm.c352
-rw-r--r--drivers/gpu/drm/stm/ltdc.c470
-rw-r--r--drivers/gpu/drm/stm/ltdc.h4
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_crtc.c10
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_drv.c11
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c3
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_layer.c2
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_rgb.c3
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_tv.c3
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_layer.c2
-rw-r--r--drivers/gpu/drm/tdfx/tdfx_drv.c5
-rw-r--r--drivers/gpu/drm/tegra/Kconfig1
-rw-r--r--drivers/gpu/drm/tegra/Makefile2
-rw-r--r--drivers/gpu/drm/tegra/dc.c22
-rw-r--r--drivers/gpu/drm/tegra/dpaux.c12
-rw-r--r--drivers/gpu/drm/tegra/drm.c116
-rw-r--r--drivers/gpu/drm/tegra/drm.h12
-rw-r--r--drivers/gpu/drm/tegra/dsi.c15
-rw-r--r--drivers/gpu/drm/tegra/fb.c8
-rw-r--r--drivers/gpu/drm/tegra/gem.c78
-rw-r--r--drivers/gpu/drm/tegra/gem.h2
-rw-r--r--drivers/gpu/drm/tegra/hdmi.c15
-rw-r--r--drivers/gpu/drm/tegra/rgb.c1
-rw-r--r--drivers/gpu/drm/tegra/sor.c15
-rw-r--r--drivers/gpu/drm/tegra/trace.c2
-rw-r--r--drivers/gpu/drm/tegra/trace.h68
-rw-r--r--drivers/gpu/drm/tegra/vic.c15
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_crtc.c20
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_drv.c8
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_panel.c1
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_plane.c1
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_tfp410.c1
-rw-r--r--drivers/gpu/drm/tinydrm/Kconfig23
-rw-r--r--drivers/gpu/drm/tinydrm/Makefile2
-rw-r--r--drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c60
-rw-r--r--drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c5
-rw-r--r--drivers/gpu/drm/tinydrm/mi0283qt.c8
-rw-r--r--drivers/gpu/drm/tinydrm/mipi-dbi.c17
-rw-r--r--drivers/gpu/drm/tinydrm/repaper.c1117
-rw-r--r--drivers/gpu/drm/tinydrm/st7586.c428
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c64
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_manager.c5
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_vm.c79
-rw-r--r--drivers/gpu/drm/ttm/ttm_page_alloc.c2
-rw-r--r--drivers/gpu/drm/udl/udl_connector.c2
-rw-r--r--drivers/gpu/drm/udl/udl_dmabuf.c2
-rw-r--r--drivers/gpu/drm/udl/udl_drv.c11
-rw-r--r--drivers/gpu/drm/udl/udl_fb.c9
-rw-r--r--drivers/gpu/drm/udl/udl_gem.c4
-rw-r--r--drivers/gpu/drm/udl/udl_main.c2
-rw-r--r--drivers/gpu/drm/vc4/Kconfig8
-rw-r--r--drivers/gpu/drm/vc4/vc4_bo.c291
-rw-r--r--drivers/gpu/drm/vc4/vc4_crtc.c116
-rw-r--r--drivers/gpu/drm/vc4/vc4_dpi.c13
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.c11
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.h40
-rw-r--r--drivers/gpu/drm/vc4/vc4_dsi.c24
-rw-r--r--drivers/gpu/drm/vc4/vc4_gem.c44
-rw-r--r--drivers/gpu/drm/vc4/vc4_hdmi.c291
-rw-r--r--drivers/gpu/drm/vc4/vc4_kms.c85
-rw-r--r--drivers/gpu/drm/vc4/vc4_plane.c19
-rw-r--r--drivers/gpu/drm/vc4/vc4_regs.h113
-rw-r--r--drivers/gpu/drm/vc4/vc4_render_cl.c63
-rw-r--r--drivers/gpu/drm/vc4/vc4_v3d.c3
-rw-r--r--drivers/gpu/drm/vc4/vc4_validate.c78
-rw-r--r--drivers/gpu/drm/vc4/vc4_validate_shaders.c72
-rw-r--r--drivers/gpu/drm/vc4/vc4_vec.c2
-rw-r--r--drivers/gpu/drm/vgem/vgem_drv.c86
-rw-r--r--drivers/gpu/drm/vgem/vgem_drv.h4
-rw-r--r--drivers/gpu/drm/vgem/vgem_fence.c2
-rw-r--r--drivers/gpu/drm/via/via_drv.c5
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_display.c11
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.c1
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.h3
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_fb.c3
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_gem.c7
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_plane.c2
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_ttm.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c24
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c10
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_context.c6
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c13
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c8
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fb.c1
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fence.c10
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c6
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c22
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.h2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c35
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_mob.c6
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_msg.c6
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_resource.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c27
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_shader.c6
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c45
-rw-r--r--drivers/gpu/drm/zte/zx_drm_drv.c6
-rw-r--r--drivers/gpu/drm/zte/zx_hdmi.c3
-rw-r--r--drivers/gpu/drm/zte/zx_plane.c2
-rw-r--r--drivers/gpu/drm/zte/zx_tvenc.c1
-rw-r--r--drivers/gpu/drm/zte/zx_vga.c1
-rw-r--r--drivers/gpu/drm/zte/zx_vou.c10
-rw-r--r--drivers/gpu/host1x/bus.c19
-rw-r--r--drivers/gpu/host1x/dev.c12
-rw-r--r--drivers/gpu/host1x/hw/intr_hw.c24
-rw-r--r--drivers/gpu/host1x/hw/syncpt_hw.c2
-rw-r--r--drivers/gpu/host1x/job.c8
-rw-r--r--drivers/gpu/ipu-v3/ipu-common.c4
-rw-r--r--drivers/hid/hid-core.c1
-rw-r--r--drivers/hid/hid-ids.h1
-rw-r--r--drivers/hid/hid-logitech-hidpp.c3
-rw-r--r--drivers/hid/hid-multitouch.c16
-rw-r--r--drivers/hid/hid-ortek.c6
-rw-r--r--drivers/hid/usbhid/hid-core.c16
-rw-r--r--drivers/hv/channel.c2
-rw-r--r--drivers/hwmon/applesmc.c13
-rw-r--r--drivers/i2c/busses/Kconfig2
-rw-r--r--drivers/i2c/busses/i2c-designware-platdrv.c6
-rw-r--r--drivers/i2c/i2c-core-acpi.c19
-rw-r--r--drivers/i2c/i2c-core-base.c1
-rw-r--r--drivers/i2c/i2c-core.h9
-rw-r--r--drivers/i2c/muxes/Kconfig2
-rw-r--r--drivers/ide/ide-timings.c18
-rw-r--r--drivers/iio/accel/bmc150-accel-core.c9
-rw-r--r--drivers/iio/accel/st_accel_core.c32
-rw-r--r--drivers/iio/adc/aspeed_adc.c26
-rw-r--r--drivers/iio/adc/axp288_adc.c42
-rw-r--r--drivers/iio/adc/sun4i-gpadc-iio.c3
-rw-r--r--drivers/iio/adc/vf610_adc.c2
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_core.c29
-rw-r--r--drivers/iio/light/tsl2563.c2
-rw-r--r--drivers/iio/pressure/st_pressure_core.c2
-rw-r--r--drivers/infiniband/core/addr.c108
-rw-r--r--drivers/infiniband/core/cma.c34
-rw-r--r--drivers/infiniband/core/roce_gid_mgmt.c11
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c38
-rw-r--r--drivers/infiniband/core/uverbs_main.c3
-rw-r--r--drivers/infiniband/core/verbs.c50
-rw-r--r--drivers/infiniband/hw/bnxt_re/bnxt_re.h9
-rw-r--r--drivers/infiniband/hw/bnxt_re/ib_verbs.c119
-rw-r--r--drivers/infiniband/hw/bnxt_re/ib_verbs.h3
-rw-r--r--drivers/infiniband/hw/bnxt_re/main.c1
-rw-r--r--drivers/infiniband/hw/bnxt_re/qplib_fp.c29
-rw-r--r--drivers/infiniband/hw/bnxt_re/qplib_fp.h1
-rw-r--r--drivers/infiniband/hw/bnxt_re/qplib_sp.c16
-rw-r--r--drivers/infiniband/hw/bnxt_re/qplib_sp.h3
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_provider.c9
-rw-r--r--drivers/infiniband/hw/cxgb4/cq.c1
-rw-r--r--drivers/infiniband/hw/cxgb4/qp.c2
-rw-r--r--drivers/infiniband/hw/hfi1/chip.c7
-rw-r--r--drivers/infiniband/hw/hfi1/qp.c7
-rw-r--r--drivers/infiniband/hw/hfi1/qp.h3
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hw_v1.c88
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_main.c3
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw.h1
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_cm.c5
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_ctrl.c2
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_main.c60
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_puda.c5
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_utils.c60
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_verbs.c19
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_verbs.h2
-rw-r--r--drivers/infiniband/hw/mlx4/cm.c4
-rw-r--r--drivers/infiniband/hw/mlx4/cq.c6
-rw-r--r--drivers/infiniband/hw/mlx4/main.c2
-rw-r--r--drivers/infiniband/hw/mlx4/mcg.c2
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h1
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c40
-rw-r--r--drivers/infiniband/hw/mlx4/srq.c8
-rw-r--r--drivers/infiniband/hw/mlx5/mr.c38
-rw-r--r--drivers/infiniband/hw/mlx5/odp.c2
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c4
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_verbs.c4
-rw-r--r--drivers/infiniband/hw/qedr/verbs.c16
-rw-r--r--drivers/infiniband/hw/qib/qib_qp.c15
-rw-r--r--drivers/infiniband/hw/qib/qib_verbs.h4
-rw-r--r--drivers/infiniband/sw/rdmavt/qp.c52
-rw-r--r--drivers/infiniband/sw/rxe/rxe_net.c3
-rw-r--r--drivers/infiniband/sw/rxe/rxe_resp.c3
-rw-r--r--drivers/infiniband/sw/rxe/rxe_verbs.c5
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c21
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ethtool.c3
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c27
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c51
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c33
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c11
-rw-r--r--drivers/infiniband/ulp/iser/iser_initiator.c6
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c10
-rw-r--r--drivers/iommu/amd_iommu.c1
-rw-r--r--drivers/iommu/amd_iommu_init.c2
-rw-r--r--drivers/iommu/arm-smmu.c23
-rw-r--r--drivers/iommu/io-pgtable-arm-v7s.c6
-rw-r--r--drivers/iommu/io-pgtable-arm.c7
-rw-r--r--drivers/iommu/io-pgtable.h9
-rw-r--r--drivers/iommu/mtk_iommu.c6
-rw-r--r--drivers/iommu/mtk_iommu.h1
-rw-r--r--drivers/irqchip/irq-digicolor.c2
-rw-r--r--drivers/irqchip/irq-gic-realview.c2
-rw-r--r--drivers/irqchip/irq-mips-cpu.c2
-rw-r--r--drivers/irqchip/irq-mips-gic.c2
-rw-r--r--drivers/isdn/divert/isdn_divert.c25
-rw-r--r--drivers/isdn/hardware/avm/c4.c2
-rw-r--r--drivers/isdn/hardware/eicon/divasmain.c2
-rw-r--r--drivers/isdn/hardware/mISDN/avmfritz.c2
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c2
-rw-r--r--drivers/isdn/hardware/mISDN/hfcpci.c2
-rw-r--r--drivers/isdn/hardware/mISDN/netjet.c2
-rw-r--r--drivers/isdn/hardware/mISDN/w6692.c2
-rw-r--r--drivers/isdn/hisax/config.c2
-rw-r--r--drivers/isdn/hisax/hfc4s8s_l1.c2
-rw-r--r--drivers/isdn/hisax/hisax_fcpcipnp.c2
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c28
-rw-r--r--drivers/isdn/i4l/isdn_common.c1
-rw-r--r--drivers/isdn/i4l/isdn_net.c5
-rw-r--r--drivers/lightnvm/pblk-rb.c4
-rw-r--r--drivers/lightnvm/pblk-read.c23
-rw-r--r--drivers/lightnvm/pblk.h2
-rw-r--r--drivers/mailbox/pcc.c2
-rw-r--r--drivers/md/bitmap.c3
-rw-r--r--drivers/md/dm-bufio.c3
-rw-r--r--drivers/md/dm-integrity.c22
-rw-r--r--drivers/md/dm-raid.c29
-rw-r--r--drivers/md/dm-table.c35
-rw-r--r--drivers/md/dm-verity-fec.c21
-rw-r--r--drivers/md/dm-zoned-metadata.c12
-rw-r--r--drivers/md/dm-zoned-reclaim.c2
-rw-r--r--drivers/md/dm-zoned-target.c8
-rw-r--r--drivers/md/md.c2
-rw-r--r--drivers/md/md.h58
-rw-r--r--drivers/md/raid1-10.c81
-rw-r--r--drivers/md/raid1.c68
-rw-r--r--drivers/md/raid10.c25
-rw-r--r--drivers/md/raid5-ppl.c2
-rw-r--r--drivers/md/raid5.c15
-rw-r--r--drivers/media/cec/cec-adap.c2
-rw-r--r--drivers/media/cec/cec-notifier.c6
-rw-r--r--drivers/media/dvb-core/dvb_ca_en50221.c143
-rw-r--r--drivers/media/dvb-core/dvb_ca_en50221.h7
-rw-r--r--drivers/media/dvb-frontends/cxd2841er.c5
-rw-r--r--drivers/media/dvb-frontends/drx39xyj/drx_driver.h15
-rw-r--r--drivers/media/dvb-frontends/lnbh25.c6
-rw-r--r--drivers/media/dvb-frontends/stv0367.c210
-rw-r--r--drivers/media/i2c/et8ek8/et8ek8_driver.c1
-rw-r--r--drivers/media/i2c/tvp5150.c25
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-core.c102
-rw-r--r--drivers/media/pci/ngene/ngene-core.c32
-rw-r--r--drivers/media/pci/ngene/ngene-i2c.c6
-rw-r--r--drivers/media/pci/ngene/ngene.h6
-rw-r--r--drivers/media/pci/tw5864/tw5864-video.c1
-rw-r--r--drivers/media/platform/Kconfig4
-rw-r--r--drivers/media/platform/coda/coda-bit.c8
-rw-r--r--drivers/media/platform/coda/coda-common.c4
-rw-r--r--drivers/media/platform/coda/coda.h2
-rw-r--r--drivers/media/platform/davinci/ccdc_hw_device.h10
-rw-r--r--drivers/media/platform/davinci/dm355_ccdc.c92
-rw-r--r--drivers/media/platform/davinci/dm644x_ccdc.c151
-rw-r--r--drivers/media/platform/davinci/vpfe_capture.c93
-rw-r--r--drivers/media/platform/davinci/vpif_capture.c2
-rw-r--r--drivers/media/platform/davinci/vpif_display.c2
-rw-r--r--drivers/media/platform/omap/omap_vout_vrfb.c133
-rw-r--r--drivers/media/platform/omap/omap_voutdef.h6
-rw-r--r--drivers/media/platform/qcom/venus/core.c18
-rw-r--r--drivers/media/platform/qcom/venus/core.h1
-rw-r--r--drivers/media/platform/qcom/venus/firmware.c76
-rw-r--r--drivers/media/platform/qcom/venus/firmware.h5
-rw-r--r--drivers/media/platform/qcom/venus/hfi_msgs.c11
-rw-r--r--drivers/media/platform/sti/bdisp/bdisp-debug.c14
-rw-r--r--drivers/media/platform/vimc/vimc-capture.c15
-rw-r--r--drivers/media/platform/vimc/vimc-debayer.c15
-rw-r--r--drivers/media/platform/vimc/vimc-scaler.c15
-rw-r--r--drivers/media/platform/vimc/vimc-sensor.c15
-rw-r--r--drivers/media/platform/vsp1/vsp1.h7
-rw-r--r--drivers/media/platform/vsp1/vsp1_bru.c45
-rw-r--r--drivers/media/platform/vsp1/vsp1_bru.h4
-rw-r--r--drivers/media/platform/vsp1/vsp1_dl.c205
-rw-r--r--drivers/media/platform/vsp1/vsp1_dl.h1
-rw-r--r--drivers/media/platform/vsp1/vsp1_drm.c286
-rw-r--r--drivers/media/platform/vsp1/vsp1_drm.h38
-rw-r--r--drivers/media/platform/vsp1/vsp1_drv.c115
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.c40
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.h5
-rw-r--r--drivers/media/platform/vsp1/vsp1_lif.c5
-rw-r--r--drivers/media/platform/vsp1/vsp1_lif.h2
-rw-r--r--drivers/media/platform/vsp1/vsp1_pipe.c27
-rw-r--r--drivers/media/platform/vsp1/vsp1_pipe.h2
-rw-r--r--drivers/media/platform/vsp1/vsp1_regs.h46
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.c69
-rw-r--r--drivers/media/platform/vsp1/vsp1_wpf.c4
-rw-r--r--drivers/media/radio/radio-wl1273.c15
-rw-r--r--drivers/media/rc/ir-lirc-codec.c2
-rw-r--r--drivers/media/tuners/fc0011.c1
-rw-r--r--drivers/media/tuners/mxl5005s.c2
-rw-r--r--drivers/media/usb/au0828/au0828-input.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/lmedm04.c10
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_core.c38
-rw-r--r--drivers/media/usb/em28xx/em28xx-cards.c18
-rw-r--r--drivers/media/usb/em28xx/em28xx-dvb.c1
-rw-r--r--drivers/media/usb/em28xx/em28xx-i2c.c2
-rw-r--r--drivers/media/usb/em28xx/em28xx-input.c2
-rw-r--r--drivers/media/usb/em28xx/em28xx.h1
-rw-r--r--drivers/media/usb/pulse8-cec/pulse8-cec.c2
-rw-r--r--drivers/media/usb/rainshadow-cec/rainshadow-cec.c18
-rw-r--r--drivers/media/usb/stkwebcam/stk-sensor.c32
-rw-r--r--drivers/media/usb/stkwebcam/stk-webcam.c70
-rw-r--r--drivers/media/usb/stkwebcam/stk-webcam.h6
-rw-r--r--drivers/media/v4l2-core/tuner-core.c2
-rw-r--r--drivers/misc/mei/pci-me.c6
-rw-r--r--drivers/misc/mei/pci-txe.c6
-rw-r--r--drivers/mmc/core/block.c3
-rw-r--r--drivers/mmc/core/mmc.c2
-rw-r--r--drivers/mmc/host/dw_mmc.c2
-rw-r--r--drivers/mmc/host/omap_hsmmc.c13
-rw-r--r--drivers/mmc/host/sdhci-of-at91.c35
-rw-r--r--drivers/mmc/host/sunxi-mmc.c8
-rw-r--r--drivers/mtd/mtd_blkdevs.c1
-rw-r--r--drivers/mtd/nand/atmel/nand-controller.c2
-rw-r--r--drivers/mtd/nand/atmel/pmecc.c21
-rw-r--r--drivers/mtd/nand/nand_base.c13
-rw-r--r--drivers/mtd/nand/nand_timings.c6
-rw-r--r--drivers/mtd/nand/sunxi_nand.c4
-rw-r--r--drivers/mux/Kconfig19
-rw-r--r--drivers/mux/mux-core.c2
-rw-r--r--drivers/net/bonding/bond_main.c4
-rw-r--r--drivers/net/dsa/b53/b53_common.c1
-rw-r--r--drivers/net/dsa/mt7530.c38
-rw-r--r--drivers/net/dsa/mt7530.h1
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.c1
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_main.c18
-rw-r--r--drivers/net/ethernet/aurora/nb8800.c9
-rw-r--r--drivers/net/ethernet/broadcom/b44.c1
-rw-r--r--drivers/net/ethernet/broadcom/bcmsysport.c4
-rw-r--r--drivers/net/ethernet/broadcom/bgmac-platform.c21
-rw-r--r--drivers/net/ethernet/broadcom/bgmac.c70
-rw-r--r--drivers/net/ethernet/broadcom/bgmac.h1
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c7
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.c301
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.h4
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmmii.c7
-rw-r--r--drivers/net/ethernet/cavium/liquidio/lio_ethtool.c2
-rw-r--r--drivers/net/ethernet/cavium/thunder/thunder_bgx.c29
-rw-r--r--drivers/net/ethernet/cavium/thunder/thunder_bgx.h2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_ptp.c3
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h2
-rw-r--r--drivers/net/ethernet/faraday/ftgmac100.c7
-rw-r--r--drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c3
-rw-r--r--drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c58
-rw-r--r--drivers/net/ethernet/ibm/ibmvnic.c15
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.c2
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c4
-rw-r--r--drivers/net/ethernet/marvell/mv643xx_eth.c2
-rw-r--r--drivers/net/ethernet/mediatek/mtk_eth_soc.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/alloc.c37
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cq.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_ethtool.c15
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_rx.c36
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_tx.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c9
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.h1
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/icm.c7
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/icm.h3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mr.c17
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/qp.c20
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/srq.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/cmd.c25
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en.h10
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_clock.c222
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_main.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eq.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c16
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/lag.c25
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h5
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/sriov.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c7
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c37
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_common.c2
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_mcp.c2
-rw-r--r--drivers/net/ethernet/qualcomm/emac/emac.c10
-rw-r--r--drivers/net/ethernet/sgi/ioc3-eth.c14
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h3
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c5
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c9
-rw-r--r--drivers/net/ethernet/sun/niu.c4
-rw-r--r--drivers/net/ethernet/sun/sunhme.h6
-rw-r--r--drivers/net/ethernet/tehuti/tehuti.c2
-rw-r--r--drivers/net/ethernet/ti/cpsw.c49
-rw-r--r--drivers/net/ethernet/ti/cpts.c111
-rw-r--r--drivers/net/ethernet/ti/cpts.h2
-rw-r--r--drivers/net/ethernet/toshiba/tc35815.c2
-rw-r--r--drivers/net/geneve.c2
-rw-r--r--drivers/net/gtp.c2
-rw-r--r--drivers/net/hyperv/hyperv_net.h3
-rw-r--r--drivers/net/hyperv/netvsc.c3
-rw-r--r--drivers/net/hyperv/netvsc_drv.c43
-rw-r--r--drivers/net/hyperv/rndis_filter.c14
-rw-r--r--drivers/net/ipvlan/ipvlan_main.c2
-rw-r--r--drivers/net/irda/mcs7780.c16
-rw-r--r--drivers/net/phy/Kconfig13
-rw-r--r--drivers/net/phy/mdio-mux.c4
-rw-r--r--drivers/net/phy/phy.c3
-rw-r--r--drivers/net/ppp/ppp_generic.c44
-rw-r--r--drivers/net/ppp/pptp.c2
-rw-r--r--drivers/net/team/team.c8
-rw-r--r--drivers/net/tun.c10
-rw-r--r--drivers/net/usb/asix.h1
-rw-r--r--drivers/net/usb/asix_common.c53
-rw-r--r--drivers/net/usb/asix_devices.c1
-rw-r--r--drivers/net/usb/cdc_ncm.c28
-rw-r--r--drivers/net/usb/huawei_cdc_ncm.c6
-rw-r--r--drivers/net/usb/lan78xx.c18
-rw-r--r--drivers/net/usb/qmi_wwan.c7
-rw-r--r--drivers/net/usb/smsc95xx.c1
-rw-r--r--drivers/net/virtio_net.c7
-rw-r--r--drivers/net/vmxnet3/vmxnet3_int.h2
-rw-r--r--drivers/net/vxlan.c1
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c8
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/tx.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c8
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ops.c6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.c15
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/trans.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/tx.c3
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800lib.c2
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c3
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/wifi.h1
-rw-r--r--drivers/nvdimm/core.c7
-rw-r--r--drivers/nvme/host/core.c41
-rw-r--r--drivers/nvme/host/fc.c121
-rw-r--r--drivers/nvme/host/pci.c67
-rw-r--r--drivers/nvme/target/admin-cmd.c16
-rw-r--r--drivers/nvme/target/configfs.c30
-rw-r--r--drivers/nvme/target/core.c5
-rw-r--r--drivers/nvme/target/fc.c321
-rw-r--r--drivers/nvme/target/nvmet.h2
-rw-r--r--drivers/nvmem/rockchip-efuse.c2
-rw-r--r--drivers/of/irq.c2
-rw-r--r--drivers/of/property.c17
-rw-r--r--drivers/parisc/pdc_stable.c8
-rw-r--r--drivers/pci/pci.c35
-rw-r--r--drivers/perf/arm_pmu.c41
-rw-r--r--drivers/perf/arm_pmu_platform.c9
-rw-r--r--drivers/perf/qcom_l2_pmu.c2
-rw-r--r--drivers/phy/broadcom/Kconfig2
-rw-r--r--drivers/pinctrl/intel/pinctrl-cherryview.c7
-rw-r--r--drivers/pinctrl/intel/pinctrl-merrifield.c6
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-armada-37xx.c25
-rw-r--r--drivers/pinctrl/stm32/Kconfig9
-rw-r--r--drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c1
-rw-r--r--drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c2
-rw-r--r--drivers/pinctrl/zte/pinctrl-zx.c11
-rw-r--r--drivers/platform/x86/Kconfig1
-rw-r--r--drivers/platform/x86/dell-wmi.c12
-rw-r--r--drivers/platform/x86/intel-vbtn.c4
-rw-r--r--drivers/platform/x86/wmi.c6
-rw-r--r--drivers/ptp/ptp_clock.c42
-rw-r--r--drivers/ptp/ptp_private.h3
-rw-r--r--drivers/s390/cio/chp.c1
-rw-r--r--drivers/s390/net/qeth_l3_main.c4
-rw-r--r--drivers/sbus/char/display7seg.c4
-rw-r--r--drivers/sbus/char/flash.c4
-rw-r--r--drivers/sbus/char/uctrl.c4
-rw-r--r--drivers/scsi/Kconfig2
-rw-r--r--drivers/scsi/aacraid/aachba.c7
-rw-r--r--drivers/scsi/aic7xxx/Makefile12
-rw-r--r--drivers/scsi/aic7xxx/aicasm/Makefile53
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_fcoe.c68
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_hwi.c45
-rw-r--r--drivers/scsi/bnx2i/bnx2i_init.c64
-rw-r--r--drivers/scsi/cxgbi/libcxgbi.c7
-rw-r--r--drivers/scsi/cxlflash/main.c11
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_v2_hw.c10
-rw-r--r--drivers/scsi/hpsa.c2
-rw-r--r--drivers/scsi/isci/request.c14
-rw-r--r--drivers/scsi/libfc/fc_disc.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c5
-rw-r--r--drivers/scsi/lpfc/lpfc_nvmet.c30
-rw-r--r--drivers/scsi/lpfc/lpfc_nvmet.h1
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c6
-rw-r--r--drivers/scsi/qedf/qedf.h3
-rw-r--r--drivers/scsi/qedf/qedf_main.c22
-rw-r--r--drivers/scsi/qedi/Kconfig1
-rw-r--r--drivers/scsi/qedi/qedi.h17
-rw-r--r--drivers/scsi/qedi/qedi_fw.c2
-rw-r--r--drivers/scsi/qedi/qedi_iscsi.c8
-rw-r--r--drivers/scsi/qedi/qedi_main.c419
-rw-r--r--drivers/scsi/qedi/qedi_nvm_iscsi_cfg.h210
-rw-r--r--drivers/scsi/qla2xxx/qla_target.c2
-rw-r--r--drivers/scsi/qla2xxx/tcm_qla2xxx.c30
-rw-r--r--drivers/scsi/scsi_transport_fc.c6
-rw-r--r--drivers/scsi/sg.c25
-rw-r--r--drivers/scsi/smartpqi/smartpqi.h2
-rw-r--r--drivers/scsi/virtio_scsi.c1
-rw-r--r--drivers/soc/zte/Kconfig1
-rw-r--r--drivers/spmi/spmi-pmic-arb.c17
-rw-r--r--drivers/spmi/spmi.c12
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/comedi/comedi_fops.c3
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c3
-rw-r--r--drivers/staging/iio/resolver/ad2s1210.c2
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c19
-rw-r--r--drivers/staging/media/atomisp/i2c/ap1302.h4
-rw-r--r--drivers/staging/media/atomisp/i2c/gc0310.h2
-rw-r--r--drivers/staging/media/atomisp/i2c/gc2235.h2
-rw-r--r--drivers/staging/media/atomisp/i2c/imx/imx.h2
-rw-r--r--drivers/staging/media/atomisp/i2c/ov2680.h3
-rw-r--r--drivers/staging/media/atomisp/i2c/ov2722.h2
-rw-r--r--drivers/staging/media/atomisp/i2c/ov5693/ov5693.h2
-rw-r--r--drivers/staging/media/atomisp/i2c/ov8858.h2
-rw-r--r--drivers/staging/media/atomisp/i2c/ov8858_btns.h2
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp2/Makefile10
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h2
-rw-r--r--drivers/staging/media/cxd2099/cxd2099.c165
-rw-r--r--drivers/staging/media/cxd2099/cxd2099.h6
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_cmd.c2
-rw-r--r--drivers/staging/rtl8188eu/os_dep/usb_intf.c1
-rw-r--r--drivers/staging/sm750fb/ddk750_chip.c2
-rw-r--r--drivers/staging/sm750fb/sm750.c24
-rw-r--r--drivers/staging/speakup/main.c2
-rw-r--r--drivers/staging/speakup/spk_priv.h2
-rw-r--r--drivers/staging/speakup/spk_ttyio.c22
-rw-r--r--drivers/staging/vboxvideo/Kconfig12
-rw-r--r--drivers/staging/vboxvideo/Makefile7
-rw-r--r--drivers/staging/vboxvideo/TODO9
-rw-r--r--drivers/staging/vboxvideo/hgsmi_base.c246
-rw-r--r--drivers/staging/vboxvideo/hgsmi_ch_setup.h66
-rw-r--r--drivers/staging/vboxvideo/hgsmi_channels.h53
-rw-r--r--drivers/staging/vboxvideo/hgsmi_defs.h92
-rw-r--r--drivers/staging/vboxvideo/modesetting.c142
-rw-r--r--drivers/staging/vboxvideo/vbox_drv.c285
-rw-r--r--drivers/staging/vboxvideo/vbox_drv.h296
-rw-r--r--drivers/staging/vboxvideo/vbox_err.h50
-rw-r--r--drivers/staging/vboxvideo/vbox_fb.c397
-rw-r--r--drivers/staging/vboxvideo/vbox_hgsmi.c115
-rw-r--r--drivers/staging/vboxvideo/vbox_irq.c197
-rw-r--r--drivers/staging/vboxvideo/vbox_main.c534
-rw-r--r--drivers/staging/vboxvideo/vbox_mode.c872
-rw-r--r--drivers/staging/vboxvideo/vbox_prime.c74
-rw-r--r--drivers/staging/vboxvideo/vbox_ttm.c472
-rw-r--r--drivers/staging/vboxvideo/vboxvideo.h491
-rw-r--r--drivers/staging/vboxvideo/vboxvideo_guest.h95
-rw-r--r--drivers/staging/vboxvideo/vboxvideo_vbe.h84
-rw-r--r--drivers/staging/vboxvideo/vbva_base.c233
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c10
-rw-r--r--drivers/target/iscsi/cxgbit/cxgbit_cm.c16
-rw-r--r--drivers/target/iscsi/cxgbit/cxgbit_target.c12
-rw-r--r--drivers/target/iscsi/iscsi_target.c6
-rw-r--r--drivers/target/iscsi/iscsi_target_login.c7
-rw-r--r--drivers/target/target_core_tpg.c4
-rw-r--r--drivers/target/target_core_transport.c4
-rw-r--r--drivers/target/target_core_user.c13
-rw-r--r--drivers/thunderbolt/eeprom.c9
-rw-r--r--drivers/thunderbolt/icm.c9
-rw-r--r--drivers/thunderbolt/switch.c11
-rw-r--r--drivers/thunderbolt/tb.h4
-rw-r--r--drivers/thunderbolt/tb_msgs.h12
-rw-r--r--drivers/tty/pty.c85
-rw-r--r--drivers/tty/serial/8250/8250_core.c23
-rw-r--r--drivers/tty/serial/8250/8250_exar.c4
-rw-r--r--drivers/tty/serial/amba-pl011.c37
-rw-r--r--drivers/tty/serial/fsl_lpuart.c24
-rw-r--r--drivers/tty/serial/imx.c27
-rw-r--r--drivers/tty/serial/sh-sci.c12
-rw-r--r--drivers/tty/serial/st-asc.c1
-rw-r--r--drivers/usb/class/cdc-acm.c3
-rw-r--r--drivers/usb/core/hcd.c4
-rw-r--r--drivers/usb/core/hub.c10
-rw-r--r--drivers/usb/core/quirks.c4
-rw-r--r--drivers/usb/dwc2/gadget.c3
-rw-r--r--drivers/usb/dwc3/core.c6
-rw-r--r--drivers/usb/dwc3/dwc3-omap.c18
-rw-r--r--drivers/usb/dwc3/gadget.c41
-rw-r--r--drivers/usb/gadget/function/f_mass_storage.c2
-rw-r--r--drivers/usb/gadget/function/f_uac1.c20
-rw-r--r--drivers/usb/gadget/function/f_uac2.c25
-rw-r--r--drivers/usb/gadget/udc/Kconfig5
-rw-r--r--drivers/usb/gadget/udc/renesas_usb3.c35
-rw-r--r--drivers/usb/gadget/udc/snps_udc_plat.c6
-rw-r--r--drivers/usb/host/pci-quirks.c91
-rw-r--r--drivers/usb/host/pci-quirks.h3
-rw-r--r--drivers/usb/host/xhci-hub.c14
-rw-r--r--drivers/usb/host/xhci-pci.c13
-rw-r--r--drivers/usb/host/xhci-ring.c11
-rw-r--r--drivers/usb/host/xhci.c10
-rw-r--r--drivers/usb/host/xhci.h1
-rw-r--r--drivers/usb/musb/musb_host.c1
-rw-r--r--drivers/usb/phy/phy-msm-usb.c17
-rw-r--r--drivers/usb/renesas_usbhs/common.c4
-rw-r--r--drivers/usb/renesas_usbhs/mod_gadget.c26
-rw-r--r--drivers/usb/renesas_usbhs/rcar3.c9
-rw-r--r--drivers/usb/serial/cp210x.c1
-rw-r--r--drivers/usb/serial/option.c2
-rw-r--r--drivers/usb/serial/pl2303.c2
-rw-r--r--drivers/usb/serial/pl2303.h1
-rw-r--r--drivers/usb/storage/isd200.c5
-rw-r--r--drivers/usb/storage/unusual_uas.h4
-rw-r--r--drivers/usb/storage/usb.c18
-rw-r--r--drivers/usb/typec/ucsi/ucsi.h1
-rw-r--r--drivers/vfio/pci/vfio_pci.c9
-rw-r--r--drivers/vfio/pci/vfio_pci_config.c13
-rw-r--r--drivers/vhost/vhost.c28
-rw-r--r--drivers/vhost/vhost.h3
-rw-r--r--drivers/video/fbdev/efifb.c8
-rw-r--r--drivers/video/fbdev/imxfb.c10
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/core.c1
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c2
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c2
-rw-r--r--drivers/virtio/virtio_balloon.c28
-rw-r--r--drivers/w1/masters/omap_hdq.c3
-rw-r--r--drivers/w1/w1.c4
-rw-r--r--drivers/xen/balloon.c3
-rw-r--r--drivers/xen/events/events_base.c15
-rw-r--r--drivers/xen/grant-table.c9
-rw-r--r--drivers/xen/xen-balloon.c22
-rw-r--r--drivers/xen/xen-selfballoon.c4
-rw-r--r--drivers/xen/xenbus/xenbus_xs.c3
-rw-r--r--drivers/xen/xenfs/super.c1
-rw-r--r--fs/binfmt_flat.c2
-rw-r--r--fs/btrfs/extent-tree.c11
-rw-r--r--fs/btrfs/tree-log.c3
-rw-r--r--fs/btrfs/volumes.c4
-rw-r--r--fs/ceph/dir.c5
-rw-r--r--fs/ext2/acl.c43
-rw-r--r--fs/ext4/acl.c25
-rw-r--r--fs/ext4/ext4.h13
-rw-r--r--fs/ext4/ext4_jbd2.h3
-rw-r--r--fs/ext4/extents.c11
-rw-r--r--fs/ext4/file.c3
-rw-r--r--fs/ext4/inode.c198
-rw-r--r--fs/ext4/ioctl.c27
-rw-r--r--fs/ext4/mballoc.c15
-rw-r--r--fs/ext4/namei.c64
-rw-r--r--fs/ext4/resize.c3
-rw-r--r--fs/ext4/super.c2
-rw-r--r--fs/ext4/xattr.c87
-rw-r--r--fs/f2fs/acl.c2
-rw-r--r--fs/f2fs/checkpoint.c10
-rw-r--r--fs/f2fs/file.c5
-rw-r--r--fs/f2fs/sysfs.c1
-rw-r--r--fs/fuse/file.c9
-rw-r--r--fs/fuse/fuse_i.h1
-rw-r--r--fs/hfsplus/posix_acl.c30
-rw-r--r--fs/isofs/inode.c8
-rw-r--r--fs/jfs/acl.c24
-rw-r--r--fs/jfs/resize.c4
-rw-r--r--fs/jfs/super.c4
-rw-r--r--fs/mount.h4
-rw-r--r--fs/namei.c2
-rw-r--r--fs/nfs/Kconfig1
-rw-r--r--fs/nfs/client.c1
-rw-r--r--fs/nfs/dir.c47
-rw-r--r--fs/nfs/file.c4
-rw-r--r--fs/nfs/filelayout/filelayout.c13
-rw-r--r--fs/nfs/flexfilelayout/flexfilelayout.c4
-rw-r--r--fs/nfs/flexfilelayout/flexfilelayoutdev.c1
-rw-r--r--fs/nfs/mount_clnt.c2
-rw-r--r--fs/nfs/nfs3proc.c11
-rw-r--r--fs/nfs/nfs4client.c3
-rw-r--r--fs/nfs/nfs4proc.c44
-rw-r--r--fs/nfs/nfs4xdr.c2
-rw-r--r--fs/nfs/pnfs_nfs.c24
-rw-r--r--fs/nfsd/nfs4callback.c6
-rw-r--r--fs/ocfs2/acl.c24
-rw-r--r--fs/overlayfs/dir.c22
-rw-r--r--fs/overlayfs/inode.c32
-rw-r--r--fs/overlayfs/namei.c41
-rw-r--r--fs/overlayfs/overlayfs.h10
-rw-r--r--fs/overlayfs/readdir.c5
-rw-r--r--fs/overlayfs/super.c13
-rw-r--r--fs/overlayfs/util.c7
-rw-r--r--fs/proc/internal.h6
-rw-r--r--fs/proc/meminfo.c8
-rw-r--r--fs/proc/task_mmu.c7
-rw-r--r--fs/reiserfs/xattr_acl.c17
-rw-r--r--fs/userfaultfd.c7
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c21
-rw-r--r--fs/xfs/libxfs/xfs_btree.c6
-rw-r--r--fs/xfs/libxfs/xfs_dir2_data.c4
-rw-r--r--fs/xfs/libxfs/xfs_refcount.c4
-rw-r--r--fs/xfs/xfs_inode.c12
-rw-r--r--fs/xfs/xfs_log_cil.c1
-rw-r--r--fs/xfs/xfs_qm.c3
-rw-r--r--fs/xfs/xfs_reflink.c4
-rw-r--r--include/acpi/acpi_numa.h1
-rw-r--r--include/asm-generic/tlb.h7
-rw-r--r--include/drm/bridge/dw_mipi_dsi.h39
-rw-r--r--include/drm/drmP.h161
-rw-r--r--include/drm/drm_atomic.h132
-rw-r--r--include/drm/drm_atomic_helper.h27
-rw-r--r--include/drm/drm_bridge.h3
-rw-r--r--include/drm/drm_connector.h42
-rw-r--r--include/drm/drm_crtc.h17
-rw-r--r--include/drm/drm_device.h190
-rw-r--r--include/drm/drm_dp_mst_helper.h10
-rw-r--r--include/drm/drm_drv.h94
-rw-r--r--include/drm/drm_edid.h11
-rw-r--r--include/drm/drm_fb_cma_helper.h4
-rw-r--r--include/drm/drm_fb_helper.h74
-rw-r--r--include/drm/drm_framebuffer.h7
-rw-r--r--include/drm/drm_gem.h17
-rw-r--r--include/drm/drm_gem_cma_helper.h5
-rw-r--r--include/drm/drm_gem_framebuffer_helper.h37
-rw-r--r--include/drm/drm_mode_config.h6
-rw-r--r--include/drm/drm_modes.h11
-rw-r--r--include/drm/drm_modeset_helper_vtables.h125
-rw-r--r--include/drm/drm_pci.h11
-rw-r--r--include/drm/drm_plane.h28
-rw-r--r--include/drm/drm_property.h2
-rw-r--r--include/drm/drm_scdc_helper.h25
-rw-r--r--include/drm/drm_simple_kms_helper.h1
-rw-r--r--include/drm/drm_vblank.h3
-rw-r--r--include/drm/tinydrm/mipi-dbi.h6
-rw-r--r--include/drm/tinydrm/tinydrm-helpers.h2
-rw-r--r--include/drm/tinydrm/tinydrm.h4
-rw-r--r--include/drm/ttm/ttm_bo_driver.h22
-rw-r--r--include/kvm/arm_pmu.h2
-rw-r--r--include/linux/acpi.h1
-rw-r--r--include/linux/binfmts.h4
-rw-r--r--include/linux/bpf-cgroup.h2
-rw-r--r--include/linux/bpf_verifier.h1
-rw-r--r--include/linux/cdev.h2
-rw-r--r--include/linux/ceph/ceph_features.h8
-rw-r--r--include/linux/ceph/osd_client.h1
-rw-r--r--include/linux/ceph/osdmap.h2
-rw-r--r--include/linux/ceph/rados.h4
-rw-r--r--include/linux/compiler-gcc.h13
-rw-r--r--include/linux/compiler.h5
-rw-r--r--include/linux/cpuhotplug.h2
-rw-r--r--include/linux/cpuset.h19
-rw-r--r--include/linux/cred.h4
-rw-r--r--include/linux/crush/crush.h2
-rw-r--r--include/linux/dax.h1
-rw-r--r--include/linux/dcache.h2
-rw-r--r--include/linux/device.h2
-rw-r--r--include/linux/dma-fence.h21
-rw-r--r--include/linux/dma-mapping.h40
-rw-r--r--include/linux/fs.h17
-rw-r--r--include/linux/fs_struct.h2
-rw-r--r--include/linux/ftrace.h6
-rw-r--r--include/linux/i2c.h3
-rw-r--r--include/linux/iio/common/st_sensors.h7
-rw-r--r--include/linux/ipc.h2
-rw-r--r--include/linux/ipc_namespace.h2
-rw-r--r--include/linux/ipv6.h6
-rw-r--r--include/linux/irq.h7
-rw-r--r--include/linux/jhash.h29
-rw-r--r--include/linux/key-type.h4
-rw-r--r--include/linux/kmod.h2
-rw-r--r--include/linux/kobject.h2
-rw-r--r--include/linux/kthread.h2
-rw-r--r--include/linux/kvm_host.h7
-rw-r--r--include/linux/libata.h2
-rw-r--r--include/linux/llist.h21
-rw-r--r--include/linux/lsm_hooks.h4
-rw-r--r--include/linux/mlx4/device.h11
-rw-r--r--include/linux/mlx5/mlx5_ifc.h10
-rw-r--r--include/linux/mlx5/qp.h1
-rw-r--r--include/linux/mm_types.h70
-rw-r--r--include/linux/module.h4
-rw-r--r--include/linux/mount.h2
-rw-r--r--include/linux/msg.h2
-rw-r--r--include/linux/mtd/nand.h6
-rw-r--r--include/linux/netfilter.h9
-rw-r--r--include/linux/nfs_fs.h2
-rw-r--r--include/linux/nfs_xdr.h2
-rw-r--r--include/linux/nvme-fc-driver.h7
-rw-r--r--include/linux/nvme-fc.h19
-rw-r--r--include/linux/nvme.h16
-rw-r--r--include/linux/pagemap.h2
-rw-r--r--include/linux/path.h2
-rw-r--r--include/linux/pci.h1
-rw-r--r--include/linux/perf/arm_pmu.h4
-rw-r--r--include/linux/phy.h2
-rw-r--r--include/linux/pid_namespace.h2
-rw-r--r--include/linux/pinctrl/pinconf-generic.h4
-rw-r--r--include/linux/platform_data/hsmmc-omap.h10
-rw-r--r--include/linux/platform_data/omap_drm.h53
-rw-r--r--include/linux/platform_data/st_sensors_pdata.h2
-rw-r--r--include/linux/proc_ns.h2
-rw-r--r--include/linux/ptp_clock_kernel.h20
-rw-r--r--include/linux/reservation.h3
-rw-r--r--include/linux/sched.h16
-rw-r--r--include/linux/sched/signal.h2
-rw-r--r--include/linux/sem.h2
-rw-r--r--include/linux/shm.h2
-rw-r--r--include/linux/sync_file.h3
-rw-r--r--include/linux/sysctl.h2
-rw-r--r--include/linux/trace_events.h2
-rw-r--r--include/linux/tty.h2
-rw-r--r--include/linux/tty_driver.h4
-rw-r--r--include/linux/usb/audio-v2.h14
-rw-r--r--include/linux/usb/cdc_ncm.h1
-rw-r--r--include/linux/user_namespace.h2
-rw-r--r--include/linux/utsname.h2
-rw-r--r--include/linux/uuid.h14
-rw-r--r--include/linux/vfio.h4
-rw-r--r--include/linux/wait.h8
-rw-r--r--include/linux/workqueue.h4
-rw-r--r--include/media/cec-notifier.h15
-rw-r--r--include/media/davinci/dm644x_ccdc.h12
-rw-r--r--include/media/davinci/vpfe_capture.h10
-rw-r--r--include/media/vsp1.h12
-rw-r--r--include/net/af_unix.h2
-rw-r--r--include/net/neighbour.h2
-rw-r--r--include/net/net_namespace.h2
-rw-r--r--include/net/netlink.h4
-rw-r--r--include/net/sctp/sctp.h4
-rw-r--r--include/net/sock.h2
-rw-r--r--include/net/tcp.h10
-rw-r--r--include/net/udp.h34
-rw-r--r--include/rdma/ib_addr.h6
-rw-r--r--include/rdma/ib_verbs.h18
-rw-r--r--include/rdma/rdma_vt.h5
-rw-r--r--include/rdma/rdmavt_qp.h14
-rw-r--r--include/sound/omap-hdmi-audio.h2
-rw-r--r--include/sound/soc.h6
-rw-r--r--include/target/iscsi/iscsi_target_core.h1
-rw-r--r--include/trace/events/ext4.h35
-rw-r--r--include/uapi/asm-generic/ioctls.h2
-rw-r--r--include/uapi/drm/armada_drm.h22
-rw-r--r--include/uapi/drm/drm_fourcc.h31
-rw-r--r--include/uapi/drm/drm_mode.h50
-rw-r--r--include/uapi/drm/i915_drm.h51
-rw-r--r--include/uapi/drm/msm_drm.h6
-rw-r--r--include/uapi/drm/qxl_drm.h6
-rw-r--r--include/uapi/drm/vc4_drm.h22
-rw-r--r--include/uapi/linux/kfd_ioctl.h37
-rw-r--r--include/uapi/linux/usb/audio.h6
-rw-r--r--include/xen/balloon.h8
-rw-r--r--ipc/msg.c3
-rw-r--r--ipc/sem.c3
-rw-r--r--ipc/shm.c4
-rw-r--r--kernel/audit.c1
-rw-r--r--kernel/bpf/syscall.c4
-rw-r--r--kernel/bpf/verifier.c129
-rw-r--r--kernel/cgroup/cgroup-internal.h3
-rw-r--r--kernel/cgroup/cgroup.c66
-rw-r--r--kernel/cgroup/cpuset.c1
-rw-r--r--kernel/cpu.c3
-rw-r--r--kernel/events/core.c33
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/futex.c9
-rw-r--r--kernel/irq/chip.c10
-rw-r--r--kernel/irq/cpuhotplug.c9
-rw-r--r--kernel/irq/internals.h10
-rw-r--r--kernel/irq/manage.c63
-rw-r--r--kernel/irq/pm.c2
-rw-r--r--kernel/locking/rtmutex.c1
-rw-r--r--kernel/pid.c3
-rw-r--r--kernel/power/snapshot.c2
-rw-r--r--kernel/sched/core.c2
-rw-r--r--kernel/sched/cputime.c6
-rw-r--r--kernel/sched/deadline.c14
-rw-r--r--kernel/signal.c11
-rw-r--r--kernel/time/timer.c2
-rw-r--r--kernel/trace/ftrace.c41
-rw-r--r--kernel/trace/ring_buffer.c10
-rw-r--r--kernel/trace/trace.c1
-rw-r--r--kernel/trace/trace.h6
-rw-r--r--kernel/workqueue.c30
-rw-r--r--lib/fault-inject.c8
-rw-r--r--lib/radix-tree.c1
-rw-r--r--lib/test_kmod.c16
-rw-r--r--lib/test_rhashtable.c57
-rw-r--r--lib/test_uuid.c2
-rw-r--r--mm/balloon_compaction.c2
-rw-r--r--mm/debug.c6
-rw-r--r--mm/huge_memory.c7
-rw-r--r--mm/hugetlb.c11
-rw-r--r--mm/internal.h5
-rw-r--r--mm/kasan/report.c1
-rw-r--r--mm/ksm.c3
-rw-r--r--mm/madvise.c1
-rw-r--r--mm/memory.c43
-rw-r--r--mm/migrate.c6
-rw-r--r--mm/mprotect.c5
-rw-r--r--mm/mremap.c8
-rw-r--r--mm/page_alloc.c13
-rw-r--r--mm/page_io.c7
-rw-r--r--mm/rmap.c88
-rw-r--r--mm/shmem.c12
-rw-r--r--mm/util.c2
-rw-r--r--mm/zsmalloc.c1
-rw-r--r--net/batman-adv/translation-table.c60
-rw-r--r--net/batman-adv/types.h2
-rw-r--r--net/bridge/br_device.c3
-rw-r--r--net/bridge/br_input.c3
-rw-r--r--net/ceph/crush/mapper.c2
-rw-r--r--net/ceph/messenger.c12
-rw-r--r--net/ceph/osd_client.c19
-rw-r--r--net/ceph/osdmap.c91
-rw-r--r--net/core/dev.c2
-rw-r--r--net/core/dev_ioctl.c5
-rw-r--r--net/core/fib_rules.c3
-rw-r--r--net/core/filter.c2
-rw-r--r--net/core/netpoll.c4
-rw-r--r--net/core/rtnetlink.c4
-rw-r--r--net/dccp/feat.c7
-rw-r--r--net/dccp/input.c2
-rw-r--r--net/dccp/ipv4.c1
-rw-r--r--net/dccp/ipv6.c1
-rw-r--r--net/dsa/dsa2.c13
-rw-r--r--net/ipv4/af_inet.c7
-rw-r--r--net/ipv4/cipso_ipv4.c12
-rw-r--r--net/ipv4/fib_frontend.c9
-rw-r--r--net/ipv4/fib_semantics.c2
-rw-r--r--net/ipv4/fou.c1
-rw-r--r--net/ipv4/igmp.c6
-rw-r--r--net/ipv4/ip_output.c16
-rw-r--r--net/ipv4/netfilter/nf_tables_arp.c3
-rw-r--r--net/ipv4/syncookies.c1
-rw-r--r--net/ipv4/tcp_bbr.c49
-rw-r--r--net/ipv4/tcp_input.c34
-rw-r--r--net/ipv4/tcp_output.c32
-rw-r--r--net/ipv4/tcp_timer.c3
-rw-r--r--net/ipv4/udp.c42
-rw-r--r--net/ipv4/udp_offload.c2
-rw-r--r--net/ipv6/exthdrs.c1
-rw-r--r--net/ipv6/ip6_output.c11
-rw-r--r--net/ipv6/output_core.c8
-rw-r--r--net/ipv6/route.c11
-rw-r--r--net/ipv6/syncookies.c1
-rw-r--r--net/ipv6/udp.c38
-rw-r--r--net/ipv6/udp_offload.c2
-rw-r--r--net/netfilter/core.c147
-rw-r--r--net/netfilter/nf_conntrack_expect.c2
-rw-r--r--net/netfilter/nf_nat_core.c17
-rw-r--r--net/netfilter/nfnetlink.c6
-rw-r--r--net/openvswitch/conntrack.c58
-rw-r--r--net/packet/af_packet.c21
-rw-r--r--net/rds/ib_recv.c5
-rw-r--r--net/rds/send.c6
-rw-r--r--net/sched/act_api.c4
-rw-r--r--net/sched/act_ipt.c22
-rw-r--r--net/sctp/sm_make_chunk.c4
-rw-r--r--net/socket.c5
-rw-r--r--net/sunrpc/xprtsock.c2
-rw-r--r--net/tipc/node.c4
-rw-r--r--samples/bpf/tcbpf2_kern.c4
-rwxr-xr-xsamples/bpf/test_tunnel_bpf.sh1
-rwxr-xr-xscripts/dtc/dtx_diff2
-rwxr-xr-xscripts/get_maintainer.pl91
-rw-r--r--scripts/parse-maintainers.pl128
-rw-r--r--security/keys/internal.h2
-rw-r--r--sound/pci/fm801.c4
-rw-r--r--sound/pci/hda/patch_conexant.c1
-rw-r--r--sound/pci/hda/patch_hdmi.c27
-rw-r--r--sound/pci/hda/patch_realtek.c145
-rw-r--r--sound/soc/codecs/msm8916-wcd-analog.c2
-rw-r--r--sound/soc/codecs/rt5663.c18
-rw-r--r--sound/soc/codecs/rt5665.c4
-rw-r--r--sound/soc/codecs/rt5665.h4
-rw-r--r--sound/soc/codecs/sgtl5000.c4
-rw-r--r--sound/soc/fsl/imx-ssi.c4
-rw-r--r--sound/soc/generic/audio-graph-card.c10
-rw-r--r--sound/soc/generic/audio-graph-scu-card.c15
-rw-r--r--sound/soc/generic/simple-card-utils.c8
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c17
-rw-r--r--sound/soc/intel/skylake/skl-messages.c8
-rw-r--r--sound/soc/intel/skylake/skl.c2
-rw-r--r--sound/soc/omap/omap-hdmi-audio.c9
-rw-r--r--sound/soc/pxa/Kconfig1
-rw-r--r--sound/soc/samsung/odroid.c6
-rw-r--r--sound/soc/sh/hac.c2
-rw-r--r--sound/soc/soc-core.c27
-rw-r--r--sound/soc/soc-pcm.c36
-rw-r--r--sound/soc/ux500/mop500.c4
-rw-r--r--tools/build/feature/test-bpf.c2
-rwxr-xr-xtools/kvm/kvm_stat/kvm_stat22
-rw-r--r--tools/lib/bpf/bpf.c7
-rw-r--r--tools/lib/bpf/bpf.h2
-rw-r--r--tools/perf/ui/browser.c2
-rw-r--r--tools/perf/util/evsel.c8
-rw-r--r--tools/perf/util/machine.c2
-rw-r--r--tools/testing/selftests/bpf/test_align.c2
-rw-r--r--tools/testing/selftests/bpf/test_pkt_md_access.c11
-rw-r--r--tools/testing/selftests/bpf/test_progs.c8
-rw-r--r--tools/testing/selftests/bpf/test_verifier.c527
-rw-r--r--virt/kvm/arm/mmu.c4
-rw-r--r--virt/kvm/arm/pmu.c43
-rw-r--r--virt/kvm/arm/vgic/vgic-init.c3
-rw-r--r--virt/kvm/arm/vgic/vgic-its.c1
-rw-r--r--virt/kvm/arm/vgic/vgic-mmio-v3.c4
-rw-r--r--virt/kvm/kvm_main.c46
2035 files changed, 52958 insertions, 67869 deletions
diff --git a/Documentation/admin-guide/pm/cpufreq.rst b/Documentation/admin-guide/pm/cpufreq.rst
index 463cf7e73db8..7af83a92d2d6 100644
--- a/Documentation/admin-guide/pm/cpufreq.rst
+++ b/Documentation/admin-guide/pm/cpufreq.rst
@@ -237,6 +237,14 @@ are the following:
This attribute is not present if the scaling driver in use does not
support it.
+``cpuinfo_cur_freq``
+ Current frequency of the CPUs belonging to this policy as obtained from
+ the hardware (in KHz).
+
+ This is expected to be the frequency the hardware actually runs at.
+ If that frequency cannot be determined, this attribute should not
+ be present.
+
``cpuinfo_max_freq``
Maximum possible operating frequency the CPUs belonging to this policy
can run at (in kHz).
diff --git a/Documentation/device-mapper/dm-raid.txt b/Documentation/device-mapper/dm-raid.txt
index 7e06e65586d4..4a0a7469fdd7 100644
--- a/Documentation/device-mapper/dm-raid.txt
+++ b/Documentation/device-mapper/dm-raid.txt
@@ -343,3 +343,4 @@ Version History
1.11.0 Fix table line argument order
(wrong raid10_copies/raid10_format sequence)
1.11.1 Add raid4/5/6 journal write-back support via journal_mode option
+1.12.1 fix for MD deadlock between mddev_suspend() and md_write_start() available
diff --git a/Documentation/devicetree/bindings/ata/sata_rcar.txt b/Documentation/devicetree/bindings/ata/sata_rcar.txt
index 0764f9ab63dc..e20eac7a3087 100644
--- a/Documentation/devicetree/bindings/ata/sata_rcar.txt
+++ b/Documentation/devicetree/bindings/ata/sata_rcar.txt
@@ -1,14 +1,22 @@
* Renesas R-Car SATA
Required properties:
-- compatible : should contain one of the following:
+- compatible : should contain one or more of the following:
- "renesas,sata-r8a7779" for R-Car H1
- ("renesas,rcar-sata" is deprecated)
- "renesas,sata-r8a7790-es1" for R-Car H2 ES1
- "renesas,sata-r8a7790" for R-Car H2 other than ES1
- "renesas,sata-r8a7791" for R-Car M2-W
- "renesas,sata-r8a7793" for R-Car M2-N
- "renesas,sata-r8a7795" for R-Car H3
+ - "renesas,rcar-gen2-sata" for a generic R-Car Gen2 compatible device
+ - "renesas,rcar-gen3-sata" for a generic R-Car Gen3 compatible device
+ - "renesas,rcar-sata" is deprecated
+
+ When compatible with the generic version nodes
+ must list the SoC-specific version corresponding
+ to the platform first followed by the generic
+ version.
+
- reg : address and length of the SATA registers;
- interrupts : must consist of one interrupt specifier.
- clocks : must contain a reference to the functional clock.
@@ -16,7 +24,7 @@ Required properties:
Example:
sata0: sata@ee300000 {
- compatible = "renesas,sata-r8a7791";
+ compatible = "renesas,sata-r8a7791", "renesas,rcar-gen2-sata";
reg = <0 0xee300000 0 0x2000>;
interrupt-parent = <&gic>;
interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt b/Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt
index f69773f4252b..941bb6a6fb13 100644
--- a/Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt
+++ b/Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt
@@ -8,7 +8,6 @@ Required properties:
Optional properties:
- clocks: Reference to the crypto engine clock.
-- dma-mask: The address mask limitation. Defaults to 64.
Example:
@@ -24,6 +23,5 @@ Example:
interrupt-names = "mem", "ring0", "ring1", "ring2", "ring3",
"eip";
clocks = <&cpm_syscon0 1 26>;
- dma-mask = <0xff 0xffffffff>;
status = "disabled";
};
diff --git a/Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt b/Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt
new file mode 100644
index 000000000000..b13adf30b8d3
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt
@@ -0,0 +1,32 @@
+Synopsys DesignWare MIPI DSI host controller
+============================================
+
+This document defines device tree properties for the Synopsys DesignWare MIPI
+DSI host controller. It doesn't constitue a device tree binding specification
+by itself but is meant to be referenced by platform-specific device tree
+bindings.
+
+When referenced from platform device tree bindings the properties defined in
+this document are defined as follows. The platform device tree bindings are
+responsible for defining whether each optional property is used or not.
+
+- reg: Memory mapped base address and length of the DesignWare MIPI DSI
+ host controller registers. (mandatory)
+
+- clocks: References to all the clocks specified in the clock-names property
+ as specified in [1]. (mandatory)
+
+- clock-names:
+ - "pclk" is the peripheral clock for either AHB and APB. (mandatory)
+ - "px_clk" is the pixel clock for the DPI/RGB input. (optional)
+
+- resets: References to all the resets specified in the reset-names property
+ as specified in [2]. (optional)
+
+- reset-names: string reset name, must be "apb" if used. (optional)
+
+- panel or bridge node: see [3]. (mandatory)
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+[2] Documentation/devicetree/bindings/reset/reset.txt
+[3] Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
diff --git a/Documentation/devicetree/bindings/display/repaper.txt b/Documentation/devicetree/bindings/display/repaper.txt
new file mode 100644
index 000000000000..f5f9f9cf6a25
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/repaper.txt
@@ -0,0 +1,52 @@
+Pervasive Displays RePaper branded e-ink displays
+
+Required properties:
+- compatible: "pervasive,e1144cs021" for 1.44" display
+ "pervasive,e1190cs021" for 1.9" display
+ "pervasive,e2200cs021" for 2.0" display
+ "pervasive,e2271cs021" for 2.7" display
+
+- panel-on-gpios: Timing controller power control
+- discharge-gpios: Discharge control
+- reset-gpios: RESET pin
+- busy-gpios: BUSY pin
+
+Required property for e2271cs021:
+- border-gpios: Border control
+
+The node for this driver must be a child node of a SPI controller, hence
+all mandatory properties described in ../spi/spi-bus.txt must be specified.
+
+Optional property:
+- pervasive,thermal-zone: name of thermometer's thermal zone
+
+Example:
+
+ display_temp: lm75@48 {
+ compatible = "lm75b";
+ reg = <0x48>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ thermal-zones {
+ display {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&display_temp>;
+ };
+ };
+
+ papirus27@0{
+ compatible = "pervasive,e2271cs021";
+ reg = <0>;
+
+ spi-max-frequency = <8000000>;
+
+ panel-on-gpios = <&gpio 23 0>;
+ border-gpios = <&gpio 14 0>;
+ discharge-gpios = <&gpio 15 0>;
+ reset-gpios = <&gpio 24 0>;
+ busy-gpios = <&gpio 25 0>;
+
+ pervasive,thermal-zone = "display";
+ };
diff --git a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
index 046076c6b277..fad8b7619647 100644
--- a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
+++ b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt
@@ -11,7 +11,9 @@ following device-specific properties.
Required properties:
-- compatible: Shall contain "rockchip,rk3288-dw-hdmi".
+- compatible: should be one of the following:
+ "rockchip,rk3288-dw-hdmi"
+ "rockchip,rk3399-dw-hdmi"
- reg: See dw_hdmi.txt.
- reg-io-width: See dw_hdmi.txt. Shall be 4.
- interrupts: HDMI interrupt number
@@ -30,7 +32,8 @@ Optional properties
I2C master controller.
- clock-names: See dw_hdmi.txt. The "cec" clock is optional.
- clock-names: May contain "cec" as defined in dw_hdmi.txt.
-
+- clock-names: May contain "grf", power for grf io.
+- clock-names: May contain "vpll", external clock for some hdmi phy.
Example:
diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
index 9eb3f0a2a078..5d835d9c1ba8 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
@@ -8,8 +8,12 @@ Required properties:
- compatible: value should be one of the following
"rockchip,rk3036-vop";
"rockchip,rk3288-vop";
+ "rockchip,rk3368-vop";
+ "rockchip,rk3366-vop";
"rockchip,rk3399-vop-big";
"rockchip,rk3399-vop-lit";
+ "rockchip,rk3228-vop";
+ "rockchip,rk3328-vop";
- interrupts: should contain a list of all VOP IP block interrupts in the
order: VSYNC, LCD_SYSTEM. The interrupt specifier
diff --git a/Documentation/devicetree/bindings/display/sitronix,st7586.txt b/Documentation/devicetree/bindings/display/sitronix,st7586.txt
new file mode 100644
index 000000000000..1d0dad1210d3
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/sitronix,st7586.txt
@@ -0,0 +1,22 @@
+Sitronix ST7586 display panel
+
+Required properties:
+- compatible: "lego,ev3-lcd".
+- a0-gpios: The A0 signal (since this binding is for serial mode, this is
+ the pin labeled D1 on the controller, not the pin labeled A0)
+- reset-gpios: Reset pin
+
+The node for this driver must be a child node of a SPI controller, hence
+all mandatory properties described in ../spi/spi-bus.txt must be specified.
+
+Optional properties:
+- rotation: panel rotation in degrees counter clockwise (0,90,180,270)
+
+Example:
+ display@0{
+ compatible = "lego,ev3-lcd";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+ a0-gpios = <&gpio 43 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio 80 GPIO_ACTIVE_HIGH>;
+ };
diff --git a/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt b/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt
index 8e1476941c0f..74b5ac7b26d6 100644
--- a/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt
+++ b/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt
@@ -1,7 +1,6 @@
* STMicroelectronics STM32 lcd-tft display controller
- ltdc: lcd-tft display controller host
- must be a sub-node of st-display-subsystem
Required properties:
- compatible: "st,stm32-ltdc"
- reg: Physical base address of the IP registers and length of memory mapped region.
@@ -13,8 +12,40 @@
Required nodes:
- Video port for RGB output.
-Example:
+* STMicroelectronics STM32 DSI controller specific extensions to Synopsys
+ DesignWare MIPI DSI host controller
+The STMicroelectronics STM32 DSI controller uses the Synopsys DesignWare MIPI
+DSI host controller. For all mandatory properties & nodes, please refer
+to the related documentation in [5].
+
+Mandatory properties specific to STM32 DSI:
+- #address-cells: Should be <1>.
+- #size-cells: Should be <0>.
+- compatible: "st,stm32-dsi".
+- clock-names:
+ - phy pll reference clock string name, must be "ref".
+- resets: see [5].
+- reset-names: see [5].
+
+Mandatory nodes specific to STM32 DSI:
+- ports: A node containing DSI input & output port nodes with endpoint
+ definitions as documented in [3] & [4].
+ - port@0: DSI input port node, connected to the ltdc rgb output port.
+ - port@1: DSI output port node, connected to a panel or a bridge input port.
+- panel or bridge node: A node containing the panel or bridge description as
+ documented in [6].
+ - port: panel or bridge port node, connected to the DSI output port (port@1).
+
+Note: You can find more documentation in the following references
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+[2] Documentation/devicetree/bindings/reset/reset.txt
+[3] Documentation/devicetree/bindings/media/video-interfaces.txt
+[4] Documentation/devicetree/bindings/graph.txt
+[5] Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt
+[6] Documentation/devicetree/bindings/display/mipi-dsi-bus.txt
+
+Example 1: RGB panel
/ {
...
soc {
@@ -34,3 +65,73 @@ Example:
};
};
};
+
+Example 2: DSI panel
+
+/ {
+ ...
+ soc {
+ ...
+ ltdc: display-controller@40016800 {
+ compatible = "st,stm32-ltdc";
+ reg = <0x40016800 0x200>;
+ interrupts = <88>, <89>;
+ resets = <&rcc STM32F4_APB2_RESET(LTDC)>;
+ clocks = <&rcc 1 CLK_LCD>;
+ clock-names = "lcd";
+
+ port {
+ ltdc_out_dsi: endpoint {
+ remote-endpoint = <&dsi_in>;
+ };
+ };
+ };
+
+
+ dsi: dsi@40016c00 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-dsi";
+ reg = <0x40016c00 0x800>;
+ clocks = <&rcc 1 CLK_F469_DSI>, <&clk_hse>;
+ clock-names = "ref", "pclk";
+ resets = <&rcc STM32F4_APB2_RESET(DSI)>;
+ reset-names = "apb";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ dsi_in: endpoint {
+ remote-endpoint = <&ltdc_out_dsi>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ dsi_out: endpoint {
+ remote-endpoint = <&dsi_in_panel>;
+ };
+ };
+
+ };
+
+ panel-dsi@0 {
+ reg = <0>; /* dsi virtual channel (0..3) */
+ compatible = ...;
+ enable-gpios = ...;
+
+ port {
+ dsi_in_panel: endpoint {
+ remote-endpoint = <&dsi_out>;
+ };
+ };
+
+ };
+
+ };
+
+ };
+};
diff --git a/Documentation/devicetree/bindings/gpio/gpio-exar.txt b/Documentation/devicetree/bindings/gpio/gpio-exar.txt
new file mode 100644
index 000000000000..4540d61824af
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-exar.txt
@@ -0,0 +1,5 @@
+Exportable MPIO interface of Exar UART chips
+
+Required properties of the device:
+ - exar,first-pin: first exportable pins (0..15)
+ - ngpios: number of exportable pins (1..16)
diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt
index d3b6e1a4713a..5aa5926029ee 100644
--- a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt
+++ b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt
@@ -40,7 +40,7 @@ Optional properties:
Example for a Mali-T760:
gpu@ffa30000 {
- compatible = "rockchip,rk3288-mali", "arm,mali-t760", "arm,mali-midgard";
+ compatible = "rockchip,rk3288-mali", "arm,mali-t760";
reg = <0xffa30000 0x10000>;
interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
index aad98442788b..a58c173b7ab9 100644
--- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
@@ -78,7 +78,6 @@ Example:
};
dwmmc0@12200000 {
- num-slots = <1>;
cap-mmc-highspeed;
cap-sd-highspeed;
broken-cd;
diff --git a/Documentation/devicetree/bindings/mmc/img-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/img-dw-mshc.txt
index 85de99fcaa2f..c54e577eea07 100644
--- a/Documentation/devicetree/bindings/mmc/img-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/img-dw-mshc.txt
@@ -24,6 +24,5 @@ Example:
fifo-depth = <0x20>;
bus-width = <4>;
- num-slots = <1>;
disable-wp;
};
diff --git a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt
index 8af1afcb86dc..07242d141773 100644
--- a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt
@@ -36,7 +36,6 @@ Example:
/* Board portion */
dwmmc0@fcd03000 {
- num-slots = <1>;
vmmc-supply = <&ldo12>;
fifo-depth = <0x100>;
pinctrl-names = "default";
@@ -52,7 +51,6 @@ Example:
dwmmc_1: dwmmc1@f723e000 {
compatible = "hisilicon,hi6220-dw-mshc";
- num-slots = <0x1>;
bus-width = <0x4>;
disable-wp;
cap-sd-highspeed;
diff --git a/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt
index 9cb55ca57461..ef3e5f14067a 100644
--- a/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt
@@ -12,12 +12,12 @@ Required Properties:
* #address-cells: should be 1.
* #size-cells: should be 0.
-# Slots: The slot specific information are contained within child-nodes with
- each child-node representing a supported slot. There should be atleast one
- child node representing a card slot. The name of the child node representing
- the slot is recommended to be slot@n where n is the unique number of the slot
- connected to the controller. The following are optional properties which
- can be included in the slot child node.
+# Slots (DEPRECATED): The slot specific information are contained within
+ child-nodes with each child-node representing a supported slot. There should
+ be atleast one child node representing a card slot. The name of the child node
+ representing the slot is recommended to be slot@n where n is the unique number
+ of the slot connected to the controller. The following are optional properties
+ which can be included in the slot child node.
* reg: specifies the physical slot number. The valid values of this
property is 0 to (num-slots -1), where num-slots is the value
@@ -63,7 +63,7 @@ Optional properties:
clock(cclk_out). If it's not specified, max is 200MHZ and min is 400KHz by default.
(Use the "max-frequency" instead of "clock-freq-min-max".)
-* num-slots: specifies the number of slots supported by the controller.
+* num-slots (DEPRECATED): specifies the number of slots supported by the controller.
The number of physical slots actually used could be equal or less than the
value specified by num-slots. If this property is not specified, the value
of num-slot property is assumed to be 1.
@@ -124,7 +124,6 @@ board specific portions as listed below.
dwmmc0@12200000 {
clock-frequency = <400000000>;
clock-freq-min-max = <400000 200000000>;
- num-slots = <1>;
broken-cd;
fifo-depth = <0x80>;
card-detect-delay = <200>;
@@ -139,7 +138,6 @@ board specific portions as listed below.
dwmmc0@12200000 {
clock-frequency = <400000000>;
clock-freq-min-max = <400000 200000000>;
- num-slots = <1>;
broken-cd;
fifo-depth = <0x80>;
card-detect-delay = <200>;
diff --git a/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt
index eaade0e5adeb..906819a90c2b 100644
--- a/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt
@@ -25,7 +25,6 @@ Example:
clock-frequency = <50000000>;
clocks = <&topcrm SD0_AHB>, <&topcrm SD0_WCLK>;
clock-names = "biu", "ciu";
- num-slots = <1>;
max-frequency = <50000000>;
cap-sdio-irq;
cap-sd-highspeed;
diff --git a/Documentation/devicetree/bindings/net/brcm,amac.txt b/Documentation/devicetree/bindings/net/brcm,amac.txt
index 2fefa1a44afd..ad16c1f481f7 100644
--- a/Documentation/devicetree/bindings/net/brcm,amac.txt
+++ b/Documentation/devicetree/bindings/net/brcm,amac.txt
@@ -11,6 +11,7 @@ Required properties:
- reg-names: Names of the registers.
"amac_base": Address and length of the GMAC registers
"idm_base": Address and length of the GMAC IDM registers
+ (required for NSP and Northstar2)
"nicpm_base": Address and length of the NIC Port Manager
registers (required for Northstar2)
- interrupts: Interrupt number
diff --git a/Documentation/devicetree/bindings/net/brcm,bgmac-nsp.txt b/Documentation/devicetree/bindings/net/brcm,bgmac-nsp.txt
deleted file mode 100644
index 022946caa7e2..000000000000
--- a/Documentation/devicetree/bindings/net/brcm,bgmac-nsp.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-Broadcom GMAC Ethernet Controller Device Tree Bindings
--------------------------------------------------------------
-
-Required properties:
- - compatible: "brcm,bgmac-nsp"
- - reg: Address and length of the GMAC registers,
- Address and length of the GMAC IDM registers
- - reg-names: Names of the registers. Must have both "gmac_base" and
- "idm_base"
- - interrupts: Interrupt number
-
-Optional properties:
-- mac-address: See ethernet.txt file in the same directory
-
-Examples:
-
-gmac0: ethernet@18022000 {
- compatible = "brcm,bgmac-nsp";
- reg = <0x18022000 0x1000>,
- <0x18110000 0x1000>;
- reg-names = "gmac_base", "idm_base";
- interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
- status = "disabled";
-};
diff --git a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt
index 194926f77194..1ff02afdc55a 100644
--- a/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt
+++ b/Documentation/devicetree/bindings/nvmem/rockchip-efuse.txt
@@ -4,7 +4,7 @@ Required properties:
- compatible: Should be one of the following.
- "rockchip,rk3066a-efuse" - for RK3066a SoCs.
- "rockchip,rk3188-efuse" - for RK3188 SoCs.
- - "rockchip,rk322x-efuse" - for RK322x SoCs.
+ - "rockchip,rk3228-efuse" - for RK3228 SoCs.
- "rockchip,rk3288-efuse" - for RK3288 SoCs.
- "rockchip,rk3399-efuse" - for RK3399 SoCs.
- reg: Should contain the registers location and exact eFuse size
diff --git a/Documentation/devicetree/bindings/ptp/brcm,ptp-dte.txt b/Documentation/devicetree/bindings/ptp/brcm,ptp-dte.txt
index 07590bcdad15..7c04e22a5d6a 100644
--- a/Documentation/devicetree/bindings/ptp/brcm,ptp-dte.txt
+++ b/Documentation/devicetree/bindings/ptp/brcm,ptp-dte.txt
@@ -1,13 +1,20 @@
-* Broadcom Digital Timing Engine(DTE) based PTP clock driver
+* Broadcom Digital Timing Engine(DTE) based PTP clock
Required properties:
-- compatible: should be "brcm,ptp-dte"
+- compatible: should contain the core compatibility string
+ and the SoC compatibility string. The SoC
+ compatibility string is to handle SoC specific
+ hardware differences.
+ Core compatibility string:
+ "brcm,ptp-dte"
+ SoC compatibility strings:
+ "brcm,iproc-ptp-dte" - for iproc based SoC's
- reg: address and length of the DTE block's NCO registers
Example:
-ptp_dte: ptp_dte@180af650 {
- compatible = "brcm,ptp-dte";
+ptp: ptp-dte@180af650 {
+ compatible = "brcm,iproc-ptp-dte", "brcm,ptp-dte";
reg = <0x180af650 0x10>;
status = "okay";
};
diff --git a/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt b/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt
index e6b572409cf5..574c3a2c77d5 100644
--- a/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt
+++ b/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt
@@ -9,7 +9,6 @@ Optional properties:
- fsl,irda-mode : Indicate the uart supports irda mode
- fsl,dte-mode : Indicate the uart works in DTE mode. The uart works
in DCE mode by default.
-- fsl,dma-size : Indicate the size of the DMA buffer and its periods
Please check Documentation/devicetree/bindings/serial/serial.txt
for the complete list of generic properties.
@@ -29,5 +28,4 @@ uart1: serial@73fbc000 {
interrupts = <31>;
uart-has-rtscts;
fsl,dte-mode;
- fsl,dma-size = <1024 4>;
};
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index daf465bef758..36b27b1efec6 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -249,6 +249,7 @@ oxsemi Oxford Semiconductor, Ltd.
panasonic Panasonic Corporation
parade Parade Technologies Inc.
pericom Pericom Technology Inc.
+pervasive Pervasive Displays, Inc.
phytec PHYTEC Messtechnik GmbH
picochip Picochip Ltd
pine64 Pine64
diff --git a/Documentation/fb/efifb.txt b/Documentation/fb/efifb.txt
index a59916c29b33..1a85c1bdaf38 100644
--- a/Documentation/fb/efifb.txt
+++ b/Documentation/fb/efifb.txt
@@ -27,5 +27,11 @@ You have to add the following kernel parameters in your elilo.conf:
Macbook Pro 17", iMac 20" :
video=efifb:i20
+Accepted options:
+
+nowc Don't map the framebuffer write combined. This can be used
+ to workaround side-effects and slowdowns on other CPU cores
+ when large amounts of console data are written.
+
--
Edgar Hucek <gimli@dark-green.com>
diff --git a/Documentation/gpio/gpio-legacy.txt b/Documentation/gpio/gpio-legacy.txt
index b34fd94f7089..5eacc147ea87 100644
--- a/Documentation/gpio/gpio-legacy.txt
+++ b/Documentation/gpio/gpio-legacy.txt
@@ -459,7 +459,7 @@ pin controller?
This is done by registering "ranges" of pins, which are essentially
cross-reference tables. These are described in
-Documentation/pinctrl.txt
+Documentation/driver-api/pinctl.rst
While the pin allocation is totally managed by the pinctrl subsystem,
gpio (under gpiolib) is still maintained by gpio drivers. It may happen
diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst
index 0d936c67bf7d..5ee9674fb9e9 100644
--- a/Documentation/gpu/drm-internals.rst
+++ b/Documentation/gpu/drm-internals.rst
@@ -201,6 +201,8 @@ drivers.
Open/Close, File Operations and IOCTLs
======================================
+.. _drm_driver_fops:
+
File Operations
---------------
diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
index 7c5e2549a58a..13dd237418cc 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -296,3 +296,12 @@ Auxiliary Modeset Helpers
.. kernel-doc:: drivers/gpu/drm/drm_modeset_helper.c
:export:
+
+Framebuffer GEM Helper Reference
+================================
+
+.. kernel-doc:: drivers/gpu/drm/drm_gem_framebuffer_helper.c
+ :doc: overview
+
+.. kernel-doc:: drivers/gpu/drm/drm_gem_framebuffer_helper.c
+ :export:
diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index 2d77c9580164..307284125d7a 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -523,9 +523,6 @@ Color Management Properties
.. kernel-doc:: drivers/gpu/drm/drm_color_mgmt.c
:doc: overview
-.. kernel-doc:: include/drm/drm_color_mgmt.h
- :internal:
-
.. kernel-doc:: drivers/gpu/drm/drm_color_mgmt.c
:export:
@@ -554,60 +551,8 @@ various modules/drivers.
Vertical Blanking
=================
-Vertical blanking plays a major role in graphics rendering. To achieve
-tear-free display, users must synchronize page flips and/or rendering to
-vertical blanking. The DRM API offers ioctls to perform page flips
-synchronized to vertical blanking and wait for vertical blanking.
-
-The DRM core handles most of the vertical blanking management logic,
-which involves filtering out spurious interrupts, keeping race-free
-blanking counters, coping with counter wrap-around and resets and
-keeping use counts. It relies on the driver to generate vertical
-blanking interrupts and optionally provide a hardware vertical blanking
-counter. Drivers must implement the following operations.
-
-- int (\*enable_vblank) (struct drm_device \*dev, int crtc); void
- (\*disable_vblank) (struct drm_device \*dev, int crtc);
- Enable or disable vertical blanking interrupts for the given CRTC.
-
-- u32 (\*get_vblank_counter) (struct drm_device \*dev, int crtc);
- Retrieve the value of the vertical blanking counter for the given
- CRTC. If the hardware maintains a vertical blanking counter its value
- should be returned. Otherwise drivers can use the
- :c:func:`drm_vblank_count()` helper function to handle this
- operation.
-
-Drivers must initialize the vertical blanking handling core with a call
-to :c:func:`drm_vblank_init()` in their load operation.
-
-Vertical blanking interrupts can be enabled by the DRM core or by
-drivers themselves (for instance to handle page flipping operations).
-The DRM core maintains a vertical blanking use count to ensure that the
-interrupts are not disabled while a user still needs them. To increment
-the use count, drivers call :c:func:`drm_vblank_get()`. Upon
-return vertical blanking interrupts are guaranteed to be enabled.
-
-To decrement the use count drivers call
-:c:func:`drm_vblank_put()`. Only when the use count drops to zero
-will the DRM core disable the vertical blanking interrupts after a delay
-by scheduling a timer. The delay is accessible through the
-vblankoffdelay module parameter or the ``drm_vblank_offdelay`` global
-variable and expressed in milliseconds. Its default value is 5000 ms.
-Zero means never disable, and a negative value means disable
-immediately. Drivers may override the behaviour by setting the
-:c:type:`struct drm_device <drm_device>`
-vblank_disable_immediate flag, which when set causes vblank interrupts
-to be disabled immediately regardless of the drm_vblank_offdelay
-value. The flag should only be set if there's a properly working
-hardware vblank counter present.
-
-When a vertical blanking interrupt occurs drivers only need to call the
-:c:func:`drm_handle_vblank()` function to account for the
-interrupt.
-
-Resources allocated by :c:func:`drm_vblank_init()` must be freed
-with a call to :c:func:`drm_vblank_cleanup()` in the driver unload
-operation handler.
+.. kernel-doc:: drivers/gpu/drm/drm_vblank.c
+ :doc: vblank handling
Vertical Blanking and Interrupt Handling Functions Reference
------------------------------------------------------------
diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst
index 9412798645c1..b08e9dcd9177 100644
--- a/Documentation/gpu/drm-mm.rst
+++ b/Documentation/gpu/drm-mm.rst
@@ -191,7 +191,7 @@ acquired and release by :c:func:`calling drm_gem_object_get()` and
holding the lock.
When the last reference to a GEM object is released the GEM core calls
-the :c:type:`struct drm_driver <drm_driver>` gem_free_object
+the :c:type:`struct drm_driver <drm_driver>` gem_free_object_unlocked
operation. That operation is mandatory for GEM-enabled drivers and must
free the GEM object and all associated resources.
@@ -492,7 +492,7 @@ DRM Sync Objects
:doc: Overview
.. kernel-doc:: include/drm/drm_syncobj.h
- :export:
+ :internal:
.. kernel-doc:: drivers/gpu/drm/drm_syncobj.c
:export:
diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst
index 858457567d3d..679373b4a03f 100644
--- a/Documentation/gpu/drm-uapi.rst
+++ b/Documentation/gpu/drm-uapi.rst
@@ -160,6 +160,8 @@ other hand, a driver requires shared state between clients which is
visible to user-space and accessible beyond open-file boundaries, they
cannot support render nodes.
+.. _drm_driver_ioctl:
+
IOCTL Support on Device Nodes
=============================
diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
index 9c7ed3e3f1e9..2e7ee0313c1c 100644
--- a/Documentation/gpu/i915.rst
+++ b/Documentation/gpu/i915.rst
@@ -417,6 +417,10 @@ integrate with drm/i915 and to handle the `DRM_I915_PERF_OPEN` ioctl.
:functions: i915_perf_open_ioctl
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
:functions: i915_perf_release
+.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
+ :functions: i915_perf_add_config_ioctl
+.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
+ :functions: i915_perf_remove_config_ioctl
i915 Perf Stream
----------------
@@ -477,4 +481,16 @@ specific details than found in the more high-level sections.
.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c
:internal:
-.. WARNING: DOCPROC directive not supported: !Cdrivers/gpu/drm/i915/i915_irq.c
+Style
+=====
+
+The drm/i915 driver codebase has some style rules in addition to (and, in some
+cases, deviating from) the kernel coding style.
+
+Register macro definition style
+-------------------------------
+
+The style guide for ``i915_reg.h``.
+
+.. kernel-doc:: drivers/gpu/drm/i915/i915_reg.h
+ :doc: The i915 register macro definition style guide
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 1ae42006deea..22af55d06ab8 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -108,8 +108,8 @@ This would be especially useful for tinydrm:
crtc state, clear that to the max values, x/y = 0 and w/h = MAX_INT, in
__drm_atomic_helper_crtc_duplicate_state().
-- Move tinydrm_merge_clips into drm_framebuffer.c, dropping the tinydrm_
- prefix ofc and using drm_fb_. drm_framebuffer.c makes sense since this
+- Move tinydrm_merge_clips into drm_framebuffer.c, dropping the tinydrm\_
+ prefix ofc and using drm_fb\_. drm_framebuffer.c makes sense since this
is a function useful to implement the fb->dirty function.
- Create a new drm_fb_dirty function which does essentially what e.g.
diff --git a/Documentation/media/kapi/dtv-core.rst b/Documentation/media/kapi/dtv-core.rst
index ff86bf0abeae..de9a228aca8a 100644
--- a/Documentation/media/kapi/dtv-core.rst
+++ b/Documentation/media/kapi/dtv-core.rst
@@ -1,6 +1,31 @@
Digital TV (DVB) devices
------------------------
+Digital TV devices are implemented by several different drivers:
+
+- A bridge driver that is responsible to talk with the bus where the other
+ devices are connected (PCI, USB, SPI), bind to the other drivers and
+ implement the digital demux logic (either in software or in hardware);
+
+- Frontend drivers that are usually implemented as two separate drivers:
+
+ - A tuner driver that implements the logic with commands the part of the
+ hardware with is reponsible to tune into a digital TV transponder or
+ physical channel. The output of a tuner is usually a baseband or
+ Intermediate Frequency (IF) signal;
+
+ - A demodulator driver (a.k.a "demod") that implements the logic with
+ commands the digital TV decoding hardware. The output of a demod is
+ a digital stream, with multiple audio, video and data channels typically
+ multiplexed using MPEG Transport Stream [#f1]_.
+
+On most hardware, the frontend drivers talk with the bridge driver using an
+I2C bus.
+
+.. [#f1] Some standards use TCP/IP for multiplexing data, like DVB-H (an
+ abandoned standard, not used anymore) and ATSC version 3.0 current
+ proposals. Currently, the DVB subsystem doesn't implement those standards.
+
Digital TV Common functions
---------------------------
@@ -55,8 +80,141 @@ Digital TV Frontend
The Digital TV Frontend kABI defines a driver-internal interface for
registering low-level, hardware specific driver to a hardware independent
frontend layer. It is only of interest for Digital TV device driver writers.
-The header file for this API is named dvb_frontend.h and located in
-drivers/media/dvb-core.
+The header file for this API is named ``dvb_frontend.h`` and located in
+``drivers/media/dvb-core``.
+
+Demodulator driver
+^^^^^^^^^^^^^^^^^^
+
+The demodulator driver is responsible to talk with the decoding part of the
+hardware. Such driver should implement :c:type:`dvb_frontend_ops`, with
+tells what type of digital TV standards are supported, and points to a
+series of functions that allow the DVB core to command the hardware via
+the code under ``drivers/media/dvb-core/dvb_frontend.c``.
+
+A typical example of such struct in a driver ``foo`` is::
+
+ static struct dvb_frontend_ops foo_ops = {
+ .delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A },
+ .info = {
+ .name = "foo DVB-T/T2/C driver",
+ .caps = FE_CAN_FEC_1_2 |
+ FE_CAN_FEC_2_3 |
+ FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 |
+ FE_CAN_FEC_7_8 |
+ FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK |
+ FE_CAN_QAM_16 |
+ FE_CAN_QAM_32 |
+ FE_CAN_QAM_64 |
+ FE_CAN_QAM_128 |
+ FE_CAN_QAM_256 |
+ FE_CAN_QAM_AUTO |
+ FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO |
+ FE_CAN_HIERARCHY_AUTO |
+ FE_CAN_MUTE_TS |
+ FE_CAN_2G_MODULATION,
+ .frequency_min = 42000000, /* Hz */
+ .frequency_max = 1002000000, /* Hz */
+ .symbol_rate_min = 870000,
+ .symbol_rate_max = 11700000
+ },
+ .init = foo_init,
+ .sleep = foo_sleep,
+ .release = foo_release,
+ .set_frontend = foo_set_frontend,
+ .get_frontend = foo_get_frontend,
+ .read_status = foo_get_status_and_stats,
+ .tune = foo_tune,
+ .i2c_gate_ctrl = foo_i2c_gate_ctrl,
+ .get_frontend_algo = foo_get_algo,
+ };
+
+A typical example of such struct in a driver ``bar`` meant to be used on
+Satellite TV reception is::
+
+ static const struct dvb_frontend_ops bar_ops = {
+ .delsys = { SYS_DVBS, SYS_DVBS2 },
+ .info = {
+ .name = "Bar DVB-S/S2 demodulator",
+ .frequency_min = 500000, /* KHz */
+ .frequency_max = 2500000, /* KHz */
+ .frequency_stepsize = 0,
+ .symbol_rate_min = 1000000,
+ .symbol_rate_max = 45000000,
+ .symbol_rate_tolerance = 500,
+ .caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK,
+ },
+ .init = bar_init,
+ .sleep = bar_sleep,
+ .release = bar_release,
+ .set_frontend = bar_set_frontend,
+ .get_frontend = bar_get_frontend,
+ .read_status = bar_get_status_and_stats,
+ .i2c_gate_ctrl = bar_i2c_gate_ctrl,
+ .get_frontend_algo = bar_get_algo,
+ .tune = bar_tune,
+
+ /* Satellite-specific */
+ .diseqc_send_master_cmd = bar_send_diseqc_msg,
+ .diseqc_send_burst = bar_send_burst,
+ .set_tone = bar_set_tone,
+ .set_voltage = bar_set_voltage,
+ };
+
+.. note::
+
+ #) For satellite digital TV standards (DVB-S, DVB-S2, ISDB-S), the
+ frequencies are specified in kHz, while, for terrestrial and cable
+ standards, they're specified in Hz. Due to that, if the same frontend
+ supports both types, you'll need to have two separate
+ :c:type:`dvb_frontend_ops` structures, one for each standard.
+ #) The ``.i2c_gate_ctrl`` field is present only when the hardware has
+ allows controlling an I2C gate (either directly of via some GPIO pin),
+ in order to remove the tuner from the I2C bus after a channel is
+ tuned.
+ #) All new drivers should implement the
+ :ref:`DVBv5 statistics <dvbv5_stats>` via ``.read_status``.
+ Yet, there are a number of callbacks meant to get statistics for
+ signal strength, S/N and UCB. Those are there to provide backward
+ compatibility with legacy applications that don't support the DVBv5
+ API. Implementing those callbacks are optional. Those callbacks may be
+ removed in the future, after we have all existing drivers supporting
+ DVBv5 stats.
+ #) Other callbacks are required for satellite TV standards, in order to
+ control LNBf and DiSEqC: ``.diseqc_send_master_cmd``,
+ ``.diseqc_send_burst``, ``.set_tone``, ``.set_voltage``.
+
+.. |delta| unicode:: U+00394
+
+The ``drivers/media/dvb-core/dvb_frontend.c`` has a kernel thread with is
+responsible for tuning the device. It supports multiple algoritms to
+detect a channel, as defined at enum :c:func:`dvbfe_algo`.
+
+The algorithm to be used is obtained via ``.get_frontend_algo``. If the driver
+doesn't fill its field at struct :c:type:`dvb_frontend_ops`, it will default to
+``DVBFE_ALGO_SW``, meaning that the dvb-core will do a zigzag when tuning,
+e. g. it will try first to use the specified center frequency ``f``,
+then, it will do ``f`` + |delta|, ``f`` - |delta|, ``f`` + 2 x |delta|,
+``f`` - 2 x |delta| and so on.
+
+If the hardware has internally a some sort of zigzag algorithm, you should
+define a ``.get_frontend_algo`` function that would return ``DVBFE_ALGO_HW``.
+
+.. note::
+
+ The core frontend support also supports
+ a third type (``DVBFE_ALGO_CUSTOM``), in order to allow the driver to
+ define its own hardware-assisted algorithm. Very few hardware need to
+ use it nowadays. Using ``DVBFE_ALGO_CUSTOM`` require to provide other
+ function callbacks at struct :c:type:`dvb_frontend_ops`.
+
+Attaching frontend driver to the bridge driver
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Before using the Digital TV frontend core, the bridge driver should attach
the frontend demod, tuner and SEC devices and call
@@ -74,6 +232,287 @@ part of their handler for :c:type:`device_driver`.\ ``resume()``.
A few other optional functions are provided to handle some special cases.
+.. _dvbv5_stats:
+
+Digital TV Frontend statistics
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Introduction
+^^^^^^^^^^^^
+
+Digital TV frontends provide a range of
+:ref:`statistics <frontend-stat-properties>` meant to help tuning the device
+and measuring the quality of service.
+
+For each statistics measurement, the driver should set the type of scale used,
+or ``FE_SCALE_NOT_AVAILABLE`` if the statistics is not available on a given
+time. Drivers should also provide the number of statistics for each type.
+that's usually 1 for most video standards [#f2]_.
+
+Drivers should initialize each statistic counters with length and
+scale at its init code. For example, if the frontend provides signal
+strength, it should have, on its init code::
+
+ struct dtv_frontend_properties *c = &state->fe.dtv_property_cache;
+
+ c->strength.len = 1;
+ c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+And, when the statistics got updated, set the scale::
+
+ c->strength.stat[0].scale = FE_SCALE_DECIBEL;
+ c->strength.stat[0].uvalue = strength;
+
+.. [#f2] For ISDB-T, it may provide both a global statistics and a per-layer
+ set of statistics. On such cases, len should be equal to 4. The first
+ value corresponds to the global stat; the other ones to each layer, e. g.:
+
+ - c->cnr.stat[0] for global S/N carrier ratio,
+ - c->cnr.stat[1] for Layer A S/N carrier ratio,
+ - c->cnr.stat[2] for layer B S/N carrier ratio,
+ - c->cnr.stat[3] for layer C S/N carrier ratio.
+
+.. note:: Please prefer to use ``FE_SCALE_DECIBEL`` instead of
+ ``FE_SCALE_RELATIVE`` for signal strength and CNR measurements.
+
+Groups of statistics
+^^^^^^^^^^^^^^^^^^^^
+
+There are several groups of statistics currently supported:
+
+Signal strength (:ref:`DTV-STAT-SIGNAL-STRENGTH`)
+ - Measures the signal strength level at the analog part of the tuner or
+ demod.
+
+ - Typically obtained from the gain applied to the tuner and/or frontend
+ in order to detect the carrier. When no carrier is detected, the gain is
+ at the maximum value (so, strength is on its minimal).
+
+ - As the gain is visible through the set of registers that adjust the gain,
+ typically, this statistics is always available [#f3]_.
+
+ - Drivers should try to make it available all the times, as this statistics
+ can be used when adjusting an antenna position and to check for troubles
+ at the cabling.
+
+ .. [#f3] On a few devices, the gain keeps floating if no carrier.
+ On such devices, strength report should check first if carrier is
+ detected at the tuner (``FE_HAS_CARRIER``, see :c:type:`fe_status`),
+ and otherwise return the lowest possible value.
+
+Carrier Signal to Noise ratio (:ref:`DTV-STAT-CNR`)
+ - Signal to Noise ratio for the main carrier.
+
+ - Signal to Noise measurement depends on the device. On some hardware, is
+ available when the main carrier is detected. On those hardware, CNR
+ measurement usually comes from the tuner (e. g. after ``FE_HAS_CARRIER``,
+ see :c:type:`fe_status`).
+
+ On other devices, it requires inner FEC decoding,
+ as the frontend measures it indirectly from other parameters (e. g. after
+ ``FE_HAS_VITERBI``, see :c:type:`fe_status`).
+
+ Having it available after inner FEC is more common.
+
+Bit counts post-FEC (:ref:`DTV-STAT-POST-ERROR-BIT-COUNT` and :ref:`DTV-STAT-POST-TOTAL-BIT-COUNT`)
+ - Those counters measure the number of bits and bit errors errors after
+ the forward error correction (FEC) on the inner coding block
+ (after Viterbi, LDPC or other inner code).
+
+ - Due to its nature, those statistics depend on full coding lock
+ (e. g. after ``FE_HAS_SYNC`` or after ``FE_HAS_LOCK``,
+ see :c:type:`fe_status`).
+
+Bit counts pre-FEC (:ref:`DTV-STAT-PRE-ERROR-BIT-COUNT` and :ref:`DTV-STAT-PRE-TOTAL-BIT-COUNT`)
+ - Those counters measure the number of bits and bit errors errors before
+ the forward error correction (FEC) on the inner coding block
+ (before Viterbi, LDPC or other inner code).
+
+ - Not all frontends provide this kind of statistics.
+
+ - Due to its nature, those statistics depend on inner coding lock (e. g.
+ after ``FE_HAS_VITERBI``, see :c:type:`fe_status`).
+
+Block counts (:ref:`DTV-STAT-ERROR-BLOCK-COUNT` and :ref:`DTV-STAT-TOTAL-BLOCK-COUNT`)
+ - Those counters measure the number of blocks and block errors errors after
+ the forward error correction (FEC) on the inner coding block
+ (before Viterbi, LDPC or other inner code).
+
+ - Due to its nature, those statistics depend on full coding lock
+ (e. g. after ``FE_HAS_SYNC`` or after
+ ``FE_HAS_LOCK``, see :c:type:`fe_status`).
+
+.. note:: All counters should be monotonically increased as they're
+ collected from the hardware.
+
+A typical example of the logic that handle status and statistics is::
+
+ static int foo_get_status_and_stats(struct dvb_frontend *fe)
+ {
+ struct foo_state *state = fe->demodulator_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+ int rc;
+ enum fe_status *status;
+
+ /* Both status and strength are always available */
+ rc = foo_read_status(fe, &status);
+ if (rc < 0)
+ return rc;
+
+ rc = foo_read_strength(fe);
+ if (rc < 0)
+ return rc;
+
+ /* Check if CNR is available */
+ if (!(fe->status & FE_HAS_CARRIER))
+ return 0;
+
+ rc = foo_read_cnr(fe);
+ if (rc < 0)
+ return rc;
+
+ /* Check if pre-BER stats are available */
+ if (!(fe->status & FE_HAS_VITERBI))
+ return 0;
+
+ rc = foo_get_pre_ber(fe);
+ if (rc < 0)
+ return rc;
+
+ /* Check if post-BER stats are available */
+ if (!(fe->status & FE_HAS_SYNC))
+ return 0;
+
+ rc = foo_get_post_ber(fe);
+ if (rc < 0)
+ return rc;
+ }
+
+ static const struct dvb_frontend_ops ops = {
+ /* ... */
+ .read_status = foo_get_status_and_stats,
+ };
+
+Statistics collect
+^^^^^^^^^^^^^^^^^^
+
+On almost all frontend hardware, the bit and byte counts are stored by
+the hardware after a certain amount of time or after the total bit/block
+counter reaches a certain value (usually programable), for example, on
+every 1000 ms or after receiving 1,000,000 bits.
+
+So, if you read the registers too soon, you'll end by reading the same
+value as in the previous reading, causing the monotonic value to be
+incremented too often.
+
+Drivers should take the responsibility to avoid too often reads. That
+can be done using two approaches:
+
+if the driver have a bit that indicates when a collected data is ready
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Driver should check such bit before making the statistics available.
+
+An example of such behavior can be found at this code snippet (adapted
+from mb86a20s driver's logic)::
+
+ static int foo_get_pre_ber(struct dvb_frontend *fe)
+ {
+ struct foo_state *state = fe->demodulator_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ int rc, bit_error;
+
+ /* Check if the BER measures are already available */
+ rc = foo_read_u8(state, 0x54);
+ if (rc < 0)
+ return rc;
+
+ if (!rc)
+ return 0;
+
+ /* Read Bit Error Count */
+ bit_error = foo_read_u32(state, 0x55);
+ if (bit_error < 0)
+ return bit_error;
+
+ /* Read Total Bit Count */
+ rc = foo_read_u32(state, 0x51);
+ if (rc < 0)
+ return rc;
+
+ c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->pre_bit_error.stat[0].uvalue += bit_error;
+ c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+ c->pre_bit_count.stat[0].uvalue += rc;
+
+ return 0;
+ }
+
+If the driver doesn't provide a statistics available check bit
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+A few devices, however, may not provide a way to check if the stats are
+available (or the way to check it is unknown). They may not even provide
+a way to directly read the total number of bits or blocks.
+
+On those devices, the driver need to ensure that it won't be reading from
+the register too often and/or estimate the total number of bits/blocks.
+
+On such drivers, a typical routine to get statistics would be like
+(adapted from dib8000 driver's logic)::
+
+ struct foo_state {
+ /* ... */
+
+ unsigned long per_jiffies_stats;
+ }
+
+ static int foo_get_pre_ber(struct dvb_frontend *fe)
+ {
+ struct foo_state *state = fe->demodulator_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ int rc, bit_error;
+ u64 bits;
+
+ /* Check if time for stats was elapsed */
+ if (!time_after(jiffies, state->per_jiffies_stats))
+ return 0;
+
+ /* Next stat should be collected in 1000 ms */
+ state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000);
+
+ /* Read Bit Error Count */
+ bit_error = foo_read_u32(state, 0x55);
+ if (bit_error < 0)
+ return bit_error;
+
+ /*
+ * On this particular frontend, there's no register that
+ * would provide the number of bits per 1000ms sample. So,
+ * some function would calculate it based on DTV properties
+ */
+ bits = get_number_of_bits_per_1000ms(fe);
+
+ c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->pre_bit_error.stat[0].uvalue += bit_error;
+ c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+ c->pre_bit_count.stat[0].uvalue += bits;
+
+ return 0;
+ }
+
+Please notice that, on both cases, we're getting the statistics using the
+:c:type:`dvb_frontend_ops` ``.read_status`` callback. The rationale is that
+the frontend core will automatically call this function periodically
+(usually, 3 times per second, when the frontend is locked).
+
+That warrants that we won't miss to collect a counter and increment the
+monotonic stats at the right time.
+
+Digital TV Frontend functions and types
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
.. kernel-doc:: drivers/media/dvb-core/dvb_frontend.h
diff --git a/Documentation/media/typical_media_device.svg b/Documentation/media/typical_media_device.svg
index 0c8abd69f39a..d6fad90ec199 100644
--- a/Documentation/media/typical_media_device.svg
+++ b/Documentation/media/typical_media_device.svg
@@ -1,2948 +1,106 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- clip-path="url(#a)"
- xml:space="preserve"
- height="179mm"
- viewBox="0 0 22648.239 17899.829"
- width="235mm"
- version="1.2"
- preserveAspectRatio="xMidYMid"
- id="svg2"
- inkscape:version="0.91 r13725"
- sodipodi:docname="typical_media_device.svg"
- style="fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round"><metadata
- id="metadata1533"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1920"
- inkscape:window-height="997"
- id="namedview1531"
- showgrid="false"
- fit-margin-top="0"
- fit-margin-left="0"
- fit-margin-right="0"
- fit-margin-bottom="0"
- inkscape:zoom="1.2707744"
- inkscape:cx="410.32614"
- inkscape:cy="316.736"
- inkscape:window-x="1920"
- inkscape:window-y="30"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg2" /><defs
- id="defs4"><clipPath
- id="a"
- clipPathUnits="userSpaceOnUse"><rect
- y="0"
- x="0"
- width="28000"
- height="21000"
- id="rect7" /></clipPath></defs><path
- style="fill:#ffccff"
- inkscape:connector-curvature="0"
- id="path11"
- d="m 10145.77,2636.013 c -518.0641,0 -1035.1241,515 -1035.1241,1031 l 0,4124 c 0,516 517.06,1032 1035.1241,1032 l 8572.152,0 c 518.064,0 1036.128,-516 1036.128,-1032 l 0,-4124 c 0,-516 -518.064,-1031 -1036.128,-1031 l -8572.152,0 z" /><path
- style="fill:#ffffcc"
- inkscape:connector-curvature="0"
- id="path15"
- d="m 1505.5459,13443.013 c -293,0 -585,292 -585,585 l 0,2340 c 0,293 292,586 585,586 l 3275,0 c 293,0 586,-293 586,-586 l 0,-2340 c 0,-293 -293,-585 -586,-585 l -3275,0 z" /><path
- style="fill:#e6e6e6"
- inkscape:connector-curvature="0"
- id="path19"
- d="m 517.1459,22.013 c -461,0 -922,461 -922,922 l 0,11169 c 0,461 461,923 922,923 l 3692,0 c 461,0 922,-462 922,-923 l 0,-11169 c 0,-461 -461,-922 -922,-922 l -3692,0 z" /><path
- style="fill:#ff8080"
- inkscape:connector-curvature="0"
- id="path23"
- d="m 2371.5459,6438.013 -2260,0 0,-1086 4520,0 0,1086 -2260,0 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path25"
- d="m 2371.5459,6438.013 -2260,0 0,-1086 4520,0 0,1086 -2260,0 z" /><text
- id="text27"
- class="TextShape"
- x="-2089.4541"
- y="-2163.9871"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan29"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan31"
- class="TextPosition"
- x="489.5459"
- y="6111.0132"><tspan
- style="fill:#000000"
- id="tspan33">Audio decoder</tspan></tspan></tspan></text>
-<path
- style="fill:#ff8080"
- inkscape:connector-curvature="0"
- id="path37"
- d="m 2371.5459,9608.013 -2260,0 0,-1270 4520,0 0,1270 -2260,0 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path39"
- d="m 2371.5459,9608.013 -2260,0 0,-1270 4520,0 0,1270 -2260,0 z" /><text
- id="text41"
- class="TextShape"
- x="-2089.4541"
- y="-2163.9871"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan43"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan45"
- class="TextPosition"
- x="527.5459"
- y="9189.0127"><tspan
- style="fill:#000000"
- id="tspan47">Video decoder</tspan></tspan></tspan></text>
-<path
- style="fill:#ff8080"
- inkscape:connector-curvature="0"
- id="path51"
- d="m 2363.5459,8053.013 -2269,0 0,-1224 4537,0 0,1224 -2268,0 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path53"
- d="m 2363.5459,8053.013 -2269,0 0,-1224 4537,0 0,1224 -2268,0 z" /><text
- id="text55"
- class="TextShape"
- x="-2089.4541"
- y="-2163.9871"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan57"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan59"
- class="TextPosition"
- x="481.5459"
- y="7657.0132"><tspan
- style="fill:#000000"
- id="tspan61">Audio encoder</tspan></tspan></tspan></text>
-<path
- style="fill:#ccffcc"
- inkscape:connector-curvature="0"
- id="path65"
- d="m 13621.546,10385.813 -3810.0001,0 0,-1281 7620.0001,0 0,1281 -3810,0 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path67"
- d="m 13621.546,10385.813 -3810.0001,0 0,-1281 7620.0001,0 0,1281 -3810,0 z" /><text
- id="text69"
- class="TextShape"
- x="-2089.4541"
- y="-2446.187"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan71"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan73"
- class="TextPosition"
- x="10287.546"
- y="9960.8135"><tspan
- style="fill:#000000"
- id="tspan75">Button Key/IR input logic</tspan></tspan></tspan></text>
-<path
- style="fill:#cfe7f5"
- inkscape:connector-curvature="0"
- id="path79"
- d="m 12079.546,12182.213 -2268.0001,0 0,-1412 4536.0001,0 0,1412 -2268,0 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path81"
- d="m 12079.546,12182.213 -2268.0001,0 0,-1412 4536.0001,0 0,1412 -2268,0 z" /><text
- id="text83"
- class="TextShape"
- x="-2089.4541"
- y="-2389.7871"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan85"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan87"
- class="TextPosition"
- x="10792.546"
- y="11692.213"><tspan
- style="fill:#000000"
- id="tspan89">EEPROM</tspan></tspan></tspan></text>
-<path
- style="fill:#ffcc99"
- inkscape:connector-curvature="0"
- id="path93"
- d="m 3050.5459,15498.013 -1563,0 0,-1715 3126,0 0,1715 -1563,0 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path95"
- d="m 3050.5459,15498.013 -1563,0 0,-1715 3126,0 0,1715 -1563,0 z" /><text
- id="text97"
- class="TextShape"
- x="-2089.4541"
- y="-2163.9871"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan99"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan101"
- class="TextPosition"
- x="2186.5459"
- y="14856.013"><tspan
- style="fill:#000000"
- id="tspan103">Sensor</tspan></tspan></tspan></text>
-<path
- style="fill:#729fcf"
- inkscape:connector-curvature="0"
- id="path107"
- d="m 4629.5459,5866.013 385,-353 0,176 1167,0 0,-176 386,353 -386,354 0,-177 -1167,0 0,177 -385,-354 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path109"
- d="m 4629.5459,5866.013 385,-353 0,176 1167,0 0,-176 386,353 -386,354 0,-177 -1167,0 0,177 -385,-354 z" /><path
- style="fill:#729fcf"
- inkscape:connector-curvature="0"
- id="path113"
- d="m 4629.5459,7448.013 385,-353 0,176 1167,0 0,-176 386,353 -386,354 0,-177 -1167,0 0,177 -385,-354 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path115"
- d="m 4629.5459,7448.013 385,-353 0,176 1167,0 0,-176 386,353 -386,354 0,-177 -1167,0 0,177 -385,-354 z" /><path
- style="fill:#729fcf"
- inkscape:connector-curvature="0"
- id="path119"
- d="m 4631.5459,8936.013 385,-353 0,176 1166,0 0,-176 386,353 -386,354 0,-177 -1166,0 0,177 -385,-354 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path121"
- d="m 4631.5459,8936.013 385,-353 0,176 1166,0 0,-176 386,353 -386,354 0,-177 -1166,0 0,177 -385,-354 z" /><path
- style="fill:#729fcf"
- inkscape:connector-curvature="0"
- id="path125"
- d="m 7872.5459,11464.213 385,-353 0,176 1166,0 0,-176 386,353 -386,354 0,-177 -1166,0 0,177 -385,-354 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path127"
- d="m 7872.5459,11464.213 385,-353 0,176 1166,0 0,-176 386,353 -386,354 0,-177 -1166,0 0,177 -385,-354 z" /><path
- style="fill:#729fcf"
- inkscape:connector-curvature="0"
- id="path131"
- d="m 7872.5459,9716.813 385,-353 0,176 1166,0 0,-176 386,353 -386,354 0,-177 -1166,0 0,177 -385,-354 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path133"
- d="m 7872.5459,9716.813 385,-353 0,176 1166,0 0,-176 386,353 -386,354 0,-177 -1166,0 0,177 -385,-354 z" /><path
- style="fill:#729fcf"
- inkscape:connector-curvature="0"
- id="path137"
- d="m 7872.5459,14994.013 670,-353 0,176 2028.0001,0 0,-176 671,353 -671,354 0,-177 -2028.0001,0 0,177 -670,-354 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path139"
- d="m 7872.5459,14994.013 670,-353 0,176 2028.0001,0 0,-176 671,353 -671,354 0,-177 -2028.0001,0 0,177 -670,-354 z" /><path
- style="fill:#729fcf"
- inkscape:connector-curvature="0"
- id="path143"
- d="m 17534.058,14104.529 978.488,840.891 -978.488,840.89 0,-420.862 -2960.48,0 0,420.862 -979.489,-840.89 979.489,-840.891 0,420.029 2960.48,0 0,-420.029 z" /><path
- style="fill:none;stroke:#3465af;stroke-width:25.77035904"
- inkscape:connector-curvature="0"
- id="path145"
- d="m 17534.058,14104.529 978.488,840.891 -978.488,840.89 0,-420.862 -2960.48,0 0,420.862 -979.489,-840.89 979.489,-840.891 0,420.029 2960.48,0 0,-420.029 z" /><text
- id="text149"
- class="TextShape"
- x="-9922.1533"
- y="-644.58704"><tspan
- style="font-weight:400;font-size:706px;font-family:'Times New Roman', serif"
- id="tspan151"
- class="TextParagraph"
- font-weight="400"
- font-size="706px"><tspan
- id="tspan153"
- transform="matrix(0,-1,1,0,8509,40173)"
- class="TextPosition"
- x="14418.847"
- y="15187.413"><tspan
- style="fill:#000000"
- id="tspan155">System Bus</tspan></tspan></tspan></text>
-<path
- style="fill:#ccffff"
- inkscape:connector-curvature="0"
- id="path159"
- d="m 11061.546,7098.013 -1250.0001,0 0,-875 2499.0001,0 0,875 -1249,0 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path161"
- d="m 11061.546,7098.013 -1250.0001,0 0,-875 2499.0001,0 0,875 -1249,0 z" /><text
- id="text163"
- class="TextShape"
- x="-2089.4541"
- y="-2163.9871"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan165"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan167"
- class="TextPosition"
- x="10125.546"
- y="6876.0132"><tspan
- style="fill:#000000"
- id="tspan169">Demux</tspan></tspan></tspan></text>
-<path
- style="fill:#729fcf"
- inkscape:connector-curvature="0"
- id="path173"
- d="m 7906.5459,6601.013 373,-357 0,178 1130,0 0,-178 374,357 -374,358 0,-179 -1130,0 0,179 -373,-358 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path175"
- d="m 7906.5459,6601.013 373,-357 0,178 1130,0 0,-178 374,357 -374,358 0,-179 -1130,0 0,179 -373,-358 z" /><path
- style="fill:#729fcf"
- inkscape:connector-curvature="0"
- id="path179"
- d="m 7906.5459,5214.013 373,-358 0,179 1130,0 0,-179 374,358 -374,358 0,-179 -1130,0 0,179 -373,-358 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path181"
- d="m 7906.5459,5214.013 373,-358 0,179 1130,0 0,-179 374,358 -374,358 0,-179 -1130,0 0,179 -373,-358 z" /><path
- style="fill:#ccffff"
- inkscape:connector-curvature="0"
- id="path185"
- d="m 14232.546,5828.013 -4421.0001,0 0,-1270 8841.0001,0 0,1270 -4420,0 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path187"
- d="m 14232.546,5828.013 -4421.0001,0 0,-1270 8841.0001,0 0,1270 -4420,0 z" /><text
- id="text189"
- class="TextShape"
- x="-2089.4541"
- y="-2163.9871"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan191"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan193"
- class="TextPosition"
- x="10696.546"
- y="5409.0132"><tspan
- style="fill:#000000"
- id="tspan195">Conditional Access Module</tspan></tspan></tspan></text>
-<path
- style="fill:#ff8080"
- inkscape:connector-curvature="0"
- id="path199"
- d="m 2355.5459,11123.013 -2269,0 0,-1224 4537,0 0,1224 -2268,0 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path201"
- d="m 2355.5459,11123.013 -2269,0 0,-1224 4537,0 0,1224 -2268,0 z" /><text
- id="text203"
- class="TextShape"
- x="-2089.4541"
- y="-2163.9871"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan205"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan207"
- class="TextPosition"
- x="511.5459"
- y="10727.013"><tspan
- style="fill:#000000"
- id="tspan209">Video encoder</tspan></tspan></tspan></text>
-<path
- style="fill:#729fcf"
- inkscape:connector-curvature="0"
- id="path213"
- d="m 4631.5459,10470.013 385,-353 0,176 1166,0 0,-176 386,353 -386,354 0,-177 -1166,0 0,177 -385,-354 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path215"
- d="m 4631.5459,10470.013 385,-353 0,176 1166,0 0,-176 386,353 -386,354 0,-177 -1166,0 0,177 -385,-354 z" /><path
- style="fill:#729fcf"
- inkscape:connector-curvature="0"
- id="path219"
- d="m 18701.546,5381.013 385,-353 0,176 1166,0 0,-176 386,353 -386,354 0,-177 -1166,0 0,177 -385,-354 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path221"
- d="m 18701.546,5381.013 385,-353 0,176 1166,0 0,-176 386,353 -386,354 0,-177 -1166,0 0,177 -385,-354 z" /><text
- id="text225"
- class="TextShape"
- x="-1976.5541"
- y="-2163.9871"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan227"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan229"
- class="TextPosition"
- x="13.4459"
- y="12314.013"><tspan
- style="fill:#000000"
- id="tspan231">Radio / Analog TV</tspan></tspan></tspan></text>
-<text
- id="text235"
- class="TextShape"
- x="-2089.4541"
- y="-2163.9871"><tspan
- style="font-weight:700;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan237"
- class="TextParagraph"
- font-weight="700"
- font-size="635px"><tspan
- id="tspan239"
- class="TextPosition"
- x="12866.546"
- y="8560.0127"><tspan
- style="fill:#000000"
- id="tspan241">Digital TV</tspan></tspan></tspan></text>
-<text
- id="text245"
- class="TextShape"
- x="-8919.0537"
- y="-1373.787"><tspan
- style="font-weight:400;font-size:494px;font-family:'Times New Roman', serif"
- id="tspan247"
- class="TextParagraph"
- font-weight="400"
- font-size="494px"><tspan
- id="tspan249"
- class="TextPosition"
- x="5804.9458"
- y="17793.213"><tspan
- style="fill:#000000"
- id="tspan251">PS.: picture is not complete: other blocks may be present</tspan></tspan></tspan></text>
-<text
- id="text255"
- class="TextShape"
- x="-2089.4541"
- y="-2163.9871"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan257"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan259"
- class="TextPosition"
- x="2109.5459"
- y="16397.014"><tspan
- style="fill:#000000"
- id="tspan261">Webcam</tspan></tspan></tspan></text>
-<path
- style="fill:#ff9900"
- inkscape:connector-curvature="0"
- id="path265"
- d="m 12462.546,13925.813 -2650.0001,0 0,-1412 5299.0001,0 0,1412 -2649,0 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path267"
- d="m 12462.546,13925.813 -2650.0001,0 0,-1412 5299.0001,0 0,1412 -2649,0 z" /><text
- id="text269"
- class="TextShape"
- x="-2089.4541"
- y="-2446.187"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan271"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan273"
- class="TextPosition"
- x="10175.546"
- y="13435.813"><tspan
- style="fill:#000000"
- id="tspan275">Processing blocks</tspan></tspan></tspan></text>
-<path
- style="fill:#729fcf"
- inkscape:connector-curvature="0"
- id="path279"
- d="m 7872.5459,13207.813 385,-353 0,176 1166,0 0,-176 386,353 -386,354 0,-177 -1166,0 0,177 -385,-354 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path281"
- d="m 7872.5459,13207.813 385,-353 0,176 1166,0 0,-176 386,353 -386,354 0,-177 -1166,0 0,177 -385,-354 z" /><path
- style="fill:#729fcf"
- inkscape:connector-curvature="0"
- id="path285"
- d="m 4612.5459,14790.013 397,-353 0,176 1201,0 0,-176 398,353 -398,354 0,-177 -1201,0 0,177 -397,-354 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path287"
- d="m 4612.5459,14790.013 397,-353 0,176 1201,0 0,-176 398,353 -398,354 0,-177 -1201,0 0,177 -397,-354 z" /><text
- id="text291"
- class="TextShape"
- x="-2428.0542"
- y="-2163.9871"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan293"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan295"
- class="TextPosition"
- x="20421.945"
- y="6628.0132"><tspan
- style="fill:#000000"
- id="tspan297">Smartcard</tspan></tspan></tspan></text>
-<path
- style="fill:#ffccff"
- inkscape:connector-curvature="0"
- id="path301"
- d="m 623.3227,436.013 c -334.5984,0 -669.1968,333 -669.1968,666 l 0,2668 c 0,333 334.5984,666 669.1968,666 l 18456.1663,0 c 334.598,0 670.202,-333 670.202,-666 l 0,-2668 c 0,-333 -335.604,-666 -670.202,-666 l -18456.1663,0 z" /><path
- style="fill:#ff8080"
- inkscape:connector-curvature="0"
- id="path305"
- d="m 3031.5459,2991.013 -1614,0 0,-1816 3227,0 0,1816 -1613,0 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path307"
- d="m 3031.5459,2991.013 -1614,0 0,-1816 3227,0 0,1816 -1613,0 z" /><text
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="text309"
- class="TextShape"
- font-weight="400"
- font-size="635px"
- x="-2089.4541"
- y="-2163.9871"><tspan
- id="tspan311"
- class="TextParagraph"><tspan
- id="tspan313"
- class="TextPosition"
- x="2284.5459"
- y="1947.0129"><tspan
- style="fill:#000000"
- id="tspan315">Tuner</tspan></tspan></tspan><tspan
- id="tspan317"
- class="TextParagraph"><tspan
- id="tspan319"
- class="TextPosition"
- x="2061.5459"
- y="2650.0129"><tspan
- style="fill:#000000"
- id="tspan321">FM/TV</tspan></tspan></tspan></text>
-<path
- style="fill:#ff8080"
- inkscape:connector-curvature="0"
- id="path325"
- d="m 812.5459,1538.013 c 0,111 40,202 88,202 l 530,0 c 48,0 89,-91 89,-202 0,-110 -41,-202 -89,-202 l -530,0 c -48,0 -88,92 -88,202 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path327"
- d="m 812.5459,1538.013 c 0,111 40,202 88,202 l 530,0 c 48,0 89,-91 89,-202 0,-110 -41,-202 -89,-202 l -530,0 c -48,0 -88,92 -88,202 z" /><path
- style="fill:#ffb3b3"
- inkscape:connector-curvature="0"
- id="path329"
- d="m 812.5459,1538.013 c 0,111 40,202 88,202 48,0 88,-91 88,-202 0,-110 -40,-202 -88,-202 -48,0 -88,92 -88,202 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path331"
- d="m 812.5459,1538.013 c 0,111 40,202 88,202 48,0 88,-91 88,-202 0,-110 -40,-202 -88,-202 -48,0 -88,92 -88,202 z" /><path
- style="fill:#ff8080"
- inkscape:connector-curvature="0"
- id="path335"
- d="m 813.5459,2103.013 c 0,110 40,202 88,202 l 530,0 c 48,0 89,-92 89,-202 0,-110 -41,-203 -89,-203 l -530,0 c -48,0 -88,93 -88,203 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path337"
- d="m 813.5459,2103.013 c 0,110 40,202 88,202 l 530,0 c 48,0 89,-92 89,-202 0,-110 -41,-203 -89,-203 l -530,0 c -48,0 -88,93 -88,203 z" /><path
- style="fill:#ffb3b3"
- inkscape:connector-curvature="0"
- id="path339"
- d="m 813.5459,2103.013 c 0,110 40,202 88,202 48,0 88,-92 88,-202 0,-110 -40,-203 -88,-203 -48,0 -88,93 -88,203 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path341"
- d="m 813.5459,2103.013 c 0,110 40,202 88,202 48,0 88,-92 88,-202 0,-110 -40,-203 -88,-203 -48,0 -88,93 -88,203 z" /><path
- style="fill:#729fcf"
- inkscape:connector-curvature="0"
- id="path345"
- d="m 4629.5459,2032.013 385,-353 0,176 1167,0 0,-176 386,353 -386,354 0,-177 -1167,0 0,177 -385,-354 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path347"
- d="m 4629.5459,2032.013 385,-353 0,176 1167,0 0,-176 386,353 -386,354 0,-177 -1167,0 0,177 -385,-354 z" /><path
- style="fill:#729fcf"
- inkscape:connector-curvature="0"
- id="path351"
- d="m 7889.5459,1986.013 402,-368 0,184 1217,0 0,-184 403,368 -403,369 0,-185 -1217,0 0,185 -402,-369 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path353"
- d="m 7889.5459,1986.013 402,-368 0,184 1217,0 0,-184 403,368 -403,369 0,-185 -1217,0 0,185 -402,-369 z" /><path
- style="fill:#ccffff"
- inkscape:connector-curvature="0"
- id="path357"
- d="m 14410.546,4025.013 -4500.0001,0 0,-1389 9000.0001,0 0,1389 -4500,0 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path359"
- d="m 14410.546,4025.013 -4500.0001,0 0,-1389 9000.0001,0 0,1389 -4500,0 z" /><text
- id="text361"
- class="TextShape"
- x="-2089.4541"
- y="-2163.9871"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan363"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan365"
- class="TextPosition"
- x="9961.5459"
- y="3546.0129"><tspan
- style="fill:#000000"
- id="tspan367">Satellite Equipment Control (SEC)</tspan></tspan></tspan></text>
-<path
- style="fill:#ccffff"
- inkscape:connector-curvature="0"
- id="path371"
- d="m 11310.546,2436.013 -1400.0001,0 0,-1000 2800.0001,0 0,1000 -1400,0 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path373"
- d="m 11310.546,2436.013 -1400.0001,0 0,-1000 2800.0001,0 0,1000 -1400,0 z" /><text
- id="text375"
- class="TextShape"
- x="-2089.4541"
- y="-2163.9871"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan377"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan379"
- class="TextPosition"
- x="10375.546"
- y="2152.0129"><tspan
- style="fill:#000000"
- id="tspan381">Demod</tspan></tspan></tspan></text>
-<path
- style="fill:#729fcf"
- inkscape:connector-curvature="0"
- id="path385"
- d="m 7889.5459,3287.013 402,-368 0,184 1217,0 0,-184 403,368 -403,369 0,-185 -1217,0 0,185 -402,-369 z" /><path
- style="fill:none;stroke:#3465af"
- inkscape:connector-curvature="0"
- id="path387"
- d="m 7889.5459,3287.013 402,-368 0,184 1217,0 0,-184 403,368 -403,369 0,-185 -1217,0 0,185 -402,-369 z" /><path
- d="m 7906.5459,9121.013 0,7302 -1270,0 0,-14605 1270,0 0,7303 z"
- id="path389"
- inkscape:connector-curvature="0"
- style="fill:#ffff99" /><path
- d="m 7906.5459,9121.013 0,7302 -1270,0 0,-14605 1270,0 0,7303 z"
- id="path391"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465af" /><text
- y="-6589.021"
- x="-20792.584"
- transform="matrix(0,-1,1,0,0,0)"
- class="TextShape"
- id="text393"><tspan
- font-size="635px"
- font-weight="400"
- class="TextParagraph"
- id="tspan395"
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"><tspan
- y="7460.9849"
- x="-11215.646"
- class="TextPosition"
- transform="matrix(0,-1,1,0,-4473,23627)"
- id="tspan397"><tspan
- id="tspan399"
- style="fill:#000000">I2C Bus (control bus)</tspan></tspan></tspan></text>
-<text
- id="text403"
- class="TextShape"
- x="-2145.854"
- y="-2163.9871"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan405"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan407"
- class="TextPosition"
- x="7245.146"
- y="1114.0129"><tspan
- style="fill:#000000"
- id="tspan409">Digital TV Frontend</tspan></tspan></tspan></text>
-<path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 863.1459,636.145 c -18.27,0 -35.525,0.99994 -53.795,2.99982"
- id="path415"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 776.8709,644.14452 c -17.255,2.99982 -35.525,6.99958 -52.78,11.99928"
- id="path417"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 692.6259,666.1432 c -16.24,5.99964 -33.495,11.99928 -49.735,19.9988"
- id="path419"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 613.4559,700.14116 c -15.225,7.99952 -31.465,16.99898 -46.69,26.99838"
- id="path421"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 539.3609,745.13846 c -14.21,9.9994 -28.42,20.99874 -42.63,31.99808"
- id="path423"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 471.3559,798.13528 c -13.195,11.99928 -26.39,23.99856 -38.57,36.99778"
- id="path425"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 410.4559,859.13162 c -11.165,12.99922 -22.33,26.99838 -33.495,40.99754"
- id="path427"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 357.6759,927.12754 c -10.15,13.99916 -19.285,28.99826 -28.42,44.9973"
- id="path429"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 314.0309,1000.1232 c -8.12,15.999 -15.225,31.998 -22.33,48.997"
- id="path431"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 280.5359,1079.1184 c -5.075,16.999 -10.15,33.998 -14.21,50.997"
- id="path433"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 260.2359,1162.1134 c -3.045,17.999 -5.075,34.9979 -6.09,52.9969"
- id="path435"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,1247.1083 0,52.9969"
- id="path437"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,1333.1032 0,52.9968"
- id="path439"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,1418.0981 0,52.9968"
- id="path441"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,1504.0929 0,52.9968"
- id="path443"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,1589.0878 0,52.9968"
- id="path445"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,1675.0827 0,52.9968"
- id="path447"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,1760.0776 0,52.9968"
- id="path449"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,1845.0725 0,53.9967"
- id="path451"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,1931.0673 0,52.9968"
- id="path453"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,2016.0622 0,52.9968"
- id="path455"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,2102.057 0,52.9969"
- id="path457"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,2187.0519 0,52.9969"
- id="path459"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,2273.0468 0,52.9968"
- id="path461"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,2358.0417 0,52.9968"
- id="path463"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,2443.0366 0,53.9967"
- id="path465"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,2529.0314 0,52.9968"
- id="path467"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,2614.0263 0,52.9968"
- id="path469"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,2700.0212 0,52.9968"
- id="path471"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,2785.0161 0,52.9968"
- id="path473"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,2871.0109 0,52.9968"
- id="path475"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,2956.0058 0,52.9968"
- id="path477"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,3041.0007 0,53.9968"
- id="path479"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,3126.9955 0,52.9969"
- id="path481"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,3211.9904 0,52.9969"
- id="path483"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,3297.9853 0,52.9968"
- id="path485"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,3382.9802 0,52.9968"
- id="path487"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,3468.975 0,52.9968"
- id="path489"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,3553.9699 0,52.9968"
- id="path491"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 254.1459,3638.9648 c 0,17.9989 1.015,35.9979 3.045,52.9968"
- id="path493"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 262.2659,3723.9597 c 4.06,17.9989 8.12,34.9979 13.195,51.9969"
- id="path495"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 285.6109,3806.9547 c 6.09,15.9991 13.195,32.9981 20.3,48.9971"
- id="path497"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 321.1359,3884.9501 c 8.12,14.9991 17.255,30.9981 27.405,45.9972"
- id="path499"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 366.8109,3957.9457 c 10.15,13.9991 21.315,27.9983 32.48,41.9975"
- id="path501"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 420.6059,4023.9417 c 12.18,12.9992 25.375,25.9985 38.57,37.9977"
- id="path503"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 483.5359,4083.9381 c 13.195,10.9994 27.405,22.9986 41.615,32.998"
- id="path505"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 552.5559,4135.935 c 14.21,9.9994 29.435,18.9989 45.675,26.9984"
- id="path507"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 627.6659,4178.9324 c 15.225,6.9996 32.48,14.9991 48.72,20.9988"
- id="path509"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 707.8509,4210.9305 c 17.255,4.9997 34.51,9.9994 51.765,13.9992"
- id="path511"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 792.0959,4230.9293 c 17.255,1.9999 35.525,3.9998 53.795,4.9997"
- id="path513"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 878.3709,4235.929 53.795,0"
- id="path515"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 964.6459,4235.929 53.795,0"
- id="path517"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1051.9359,4235.929 53.795,0"
- id="path519"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1138.2109,4235.929 53.795,0"
- id="path521"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1225.5009,4235.929 53.795,0"
- id="path523"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1311.7759,4235.929 53.795,0"
- id="path525"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1398.0509,4235.929 54.81,0"
- id="path527"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1485.3409,4235.929 53.795,0"
- id="path529"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1571.6159,4235.929 53.795,0"
- id="path531"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1658.9059,4235.929 53.795,0"
- id="path533"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1745.1809,4235.929 53.795,0"
- id="path535"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1832.4709,4235.929 53.795,0"
- id="path537"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1918.7459,4235.929 53.795,0"
- id="path539"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2005.0209,4235.929 54.81,0"
- id="path541"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2092.3109,4235.929 53.795,0"
- id="path543"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2178.5859,4235.929 53.795,0"
- id="path545"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2265.8759,4235.929 53.795,0"
- id="path547"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2352.1509,4235.929 53.795,0"
- id="path549"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2439.4409,4235.929 53.795,0"
- id="path551"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2525.7159,4235.929 53.795,0"
- id="path553"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2611.9909,4235.929 54.81,0"
- id="path555"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2699.2809,4235.929 53.795,0"
- id="path557"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2785.5559,4235.929 53.795,0"
- id="path559"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2872.8459,4235.929 53.795,0"
- id="path561"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2959.1209,4235.929 53.795,0"
- id="path563"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3046.4109,4235.929 53.795,0"
- id="path565"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3132.6859,4235.929 53.795,0"
- id="path567"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3219.9759,4235.929 53.795,0"
- id="path569"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3306.2509,4235.929 53.795,0"
- id="path571"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3392.5259,4235.929 53.795,0"
- id="path573"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3479.8159,4235.929 53.795,0"
- id="path575"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3566.0909,4235.929 53.795,0"
- id="path577"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3653.3809,4235.929 53.795,0"
- id="path579"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3739.6559,4235.929 53.795,0"
- id="path581"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3826.9459,4235.929 53.795,0"
- id="path583"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3913.2209,4235.929 53.795,0"
- id="path585"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3999.4959,4235.929 53.795,0"
- id="path587"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4086.7859,4235.929 53.795,0"
- id="path589"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4173.0609,4235.929 53.795,0"
- id="path591"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4260.3509,4235.929 53.795,0"
- id="path593"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4346.6259,4235.929 53.795,0"
- id="path595"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4433.9159,4235.929 53.795,0"
- id="path597"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4520.1909,4235.929 53.795,0"
- id="path599"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4606.4659,4235.929 54.81,0"
- id="path601"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4693.7559,4235.929 53.795,0"
- id="path603"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4780.0309,4235.929 53.795,0"
- id="path605"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4867.3209,4235.929 53.795,0"
- id="path607"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4953.5959,4235.929 53.795,0"
- id="path609"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5040.8859,4235.929 53.795,0"
- id="path611"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5127.1609,4235.929 53.795,0"
- id="path613"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5213.4359,4235.929 54.81,0"
- id="path615"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5300.7259,4235.929 53.795,0"
- id="path617"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5387.0009,4235.929 53.795,0"
- id="path619"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5474.2909,4235.929 53.795,0"
- id="path621"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5560.5659,4235.929 53.795,0"
- id="path623"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5647.8559,4235.929 53.795,0"
- id="path625"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5734.1309,4235.929 53.795,0"
- id="path627"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5820.4059,4235.929 54.81,0"
- id="path629"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5907.6959,4235.929 53.795,0"
- id="path631"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5993.9709,4235.929 53.795,0"
- id="path633"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6081.2609,4235.929 53.795,0"
- id="path635"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6167.5359,4235.929 53.795,0"
- id="path637"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6254.8259,4235.929 53.795,0"
- id="path639"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6341.1009,4235.929 53.795,0"
- id="path641"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6427.3759,4235.929 54.81,0"
- id="path643"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6514.6659,4235.929 53.795,0"
- id="path645"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6600.9409,4235.929 53.795,0"
- id="path647"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6688.2309,4235.929 53.795,0"
- id="path649"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6774.5059,4235.929 53.795,0"
- id="path651"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6861.7959,4235.929 53.795,0"
- id="path653"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6948.0709,4235.929 53.795,0"
- id="path655"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7035.3609,4235.929 53.795,0"
- id="path657"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7121.6359,4235.929 53.795,0"
- id="path659"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7207.9109,4235.929 53.795,0"
- id="path661"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7295.2009,4235.929 53.795,0"
- id="path663"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7381.4759,4235.929 53.795,0"
- id="path665"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7468.7659,4235.929 53.795,0"
- id="path667"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7555.0409,4235.929 53.795,0"
- id="path669"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7642.3309,4235.929 53.795,0"
- id="path671"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7728.6059,4235.929 53.795,0"
- id="path673"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7814.8809,4235.929 53.795,0"
- id="path675"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7902.1709,4235.929 53.795,0"
- id="path677"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7988.4459,4235.929 53.795,0"
- id="path679"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8075.7359,4235.929 53.795,0"
- id="path681"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8162.0109,4235.929 53.795,0"
- id="path683"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8249.3009,4235.929 53.795,0"
- id="path685"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8335.5759,4235.929 53.795,0"
- id="path687"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8421.8509,4235.929 53.795,0"
- id="path689"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8509.1409,4235.929 53.795,0"
- id="path691"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8595.4159,4235.929 53.795,0"
- id="path693"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8682.7059,4235.929 53.795,0"
- id="path695"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8768.9809,4235.929 53.795,0"
- id="path697"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8856.2709,4235.929 53.795,0"
- id="path699"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8942.5459,4235.929 53.795,0"
- id="path701"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9028.8209,4235.929 54.81,0"
- id="path703"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9116.1109,4235.929 53.795,0"
- id="path705"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9202.3859,4235.929 53.795,0"
- id="path707"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9289.6759,4235.929 53.795,0"
- id="path709"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9375.9509,4235.929 53.795,0"
- id="path711"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9463.2409,4235.929 53.795,0"
- id="path713"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9549.5159,4235.929 53.795,0"
- id="path715"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9635.7909,4235.929 54.81,0"
- id="path717"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9723.0809,4235.929 53.795,0"
- id="path719"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9809.3559,4235.929 53.795,0"
- id="path721"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9896.6459,4235.929 53.795,0"
- id="path723"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9982.9209,4235.929 53.7951,0"
- id="path725"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10070.211,4235.929 53.795,0"
- id="path727"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10156.486,4235.929 53.795,0"
- id="path729"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10242.761,4235.929 54.81,0"
- id="path731"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10330.051,4235.929 53.795,0"
- id="path733"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10416.326,4235.929 53.795,0"
- id="path735"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10503.616,4235.929 53.795,0"
- id="path737"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10589.891,4235.929 53.795,0"
- id="path739"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10677.181,4235.929 53.795,0"
- id="path741"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10763.456,4235.929 53.795,0"
- id="path743"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10849.731,4235.929 54.81,0"
- id="path745"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10937.021,4235.929 53.795,0"
- id="path747"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11023.296,4235.929 53.795,0"
- id="path749"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11110.586,4235.929 53.795,0"
- id="path751"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11196.861,4235.929 53.795,0"
- id="path753"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11284.151,4235.929 53.795,0"
- id="path755"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11370.426,4235.929 53.795,0"
- id="path757"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11457.716,4235.929 53.795,0"
- id="path759"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11543.991,4235.929 53.795,0"
- id="path761"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11630.266,4235.929 53.795,0"
- id="path763"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11717.556,4235.929 53.795,0"
- id="path765"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11803.831,4235.929 53.795,0"
- id="path767"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11891.121,4235.929 53.795,0"
- id="path769"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11977.396,4235.929 53.795,0"
- id="path771"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12064.686,4235.929 53.795,0"
- id="path773"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12150.961,4235.929 53.795,0"
- id="path775"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12237.236,4235.929 53.795,0"
- id="path777"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12324.526,4235.929 53.795,0"
- id="path779"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12410.801,4235.929 53.795,0"
- id="path781"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12498.091,4235.929 53.795,0"
- id="path783"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12584.366,4235.929 53.795,0"
- id="path785"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12671.656,4235.929 53.795,0"
- id="path787"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12757.931,4235.929 53.795,0"
- id="path789"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12844.206,4235.929 54.81,0"
- id="path791"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12931.496,4235.929 53.795,0"
- id="path793"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13017.771,4235.929 53.795,0"
- id="path795"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13105.061,4235.929 53.795,0"
- id="path797"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13191.336,4235.929 53.795,0"
- id="path799"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13278.626,4235.929 53.795,0"
- id="path801"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13364.901,4235.929 53.795,0"
- id="path803"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13451.176,4235.929 54.81,0"
- id="path805"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13538.466,4235.929 53.795,0"
- id="path807"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13624.741,4235.929 53.795,0"
- id="path809"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13712.031,4235.929 53.795,0"
- id="path811"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13798.306,4235.929 53.795,0"
- id="path813"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13885.596,4235.929 53.795,0"
- id="path815"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13971.871,4235.929 53.795,0"
- id="path817"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14058.146,4235.929 54.81,0"
- id="path819"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14145.436,4235.929 53.795,0"
- id="path821"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14231.711,4235.929 53.795,0"
- id="path823"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14319.001,4235.929 53.795,0"
- id="path825"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14405.276,4235.929 53.795,0"
- id="path827"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14492.566,4235.929 53.795,0"
- id="path829"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14578.841,4235.929 53.795,0"
- id="path831"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14665.116,4235.929 54.81,0"
- id="path833"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14752.406,4235.929 53.795,0"
- id="path835"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14838.681,4235.929 53.795,0"
- id="path837"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14925.971,4235.929 53.795,0"
- id="path839"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15012.246,4235.929 53.795,0"
- id="path841"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15099.536,4235.929 53.795,0"
- id="path843"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15185.811,4235.929 53.795,0"
- id="path845"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15272.086,4235.929 54.81,0"
- id="path847"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15359.376,4235.929 53.795,0"
- id="path849"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15445.651,4235.929 53.795,0"
- id="path851"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15532.941,4235.929 53.795,0"
- id="path853"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15619.216,4235.929 53.795,0"
- id="path855"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15706.506,4235.929 53.795,0"
- id="path857"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15792.781,4235.929 53.795,0"
- id="path859"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15880.071,4235.929 53.795,0"
- id="path861"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15966.346,4235.929 53.795,0"
- id="path863"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16052.621,4235.929 53.795,0"
- id="path865"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16139.911,4235.929 53.795,0"
- id="path867"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16226.186,4235.929 53.795,0"
- id="path869"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16313.476,4235.929 53.795,0"
- id="path871"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16399.751,4235.929 53.795,0"
- id="path873"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16487.041,4235.929 53.795,0"
- id="path875"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16573.316,4235.929 53.795,0"
- id="path877"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16659.591,4235.929 53.795,0"
- id="path879"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16746.881,4235.929 53.795,0"
- id="path881"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16833.156,4235.929 53.795,0"
- id="path883"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16920.446,4235.929 53.795,0"
- id="path885"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17006.721,4235.929 53.795,0"
- id="path887"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17094.011,4235.929 53.795,0"
- id="path889"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17180.286,4235.929 53.795,0"
- id="path891"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17266.561,4235.929 54.81,0"
- id="path893"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17353.851,4235.929 53.795,0"
- id="path895"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17440.126,4235.929 53.795,0"
- id="path897"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17527.416,4235.929 53.795,0"
- id="path899"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17613.691,4235.929 53.795,0"
- id="path901"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17700.981,4235.929 53.795,0"
- id="path903"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17787.256,4235.929 53.795,0"
- id="path905"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17873.531,4235.929 54.81,0"
- id="path907"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17960.821,4235.929 53.795,0"
- id="path909"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18047.096,4235.929 53.795,0"
- id="path911"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18134.386,4235.929 53.795,0"
- id="path913"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18220.661,4235.929 53.795,0"
- id="path915"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18307.951,4235.929 53.795,0"
- id="path917"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18394.226,4235.929 53.795,0"
- id="path919"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18480.501,4235.929 54.81,0"
- id="path921"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18567.791,4235.929 53.795,0"
- id="path923"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18654.066,4235.929 53.795,0"
- id="path925"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18741.356,4235.929 c 17.255,-0.9999 35.525,-1.9999 53.795,-4.9997"
- id="path927"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18827.631,4225.9296 c 17.255,-3.9998 34.51,-8.9995 51.765,-13.9992"
- id="path929"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18910.861,4200.9311 c 16.24,-5.9996 32.48,-12.9992 48.72,-20.9987"
- id="path931"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18989.016,4164.9333 c 15.225,-7.9996 31.465,-16.999 45.675,-26.9984"
- id="path933"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19062.096,4118.936 c 14.21,-9.9994 28.42,-20.9987 42.63,-31.9981"
- id="path935"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19129.086,4064.9393 c 13.195,-11.9993 25.375,-24.9985 37.555,-37.9978"
- id="path937"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19188.971,4002.943 c 11.165,-13.9992 22.33,-27.9983 33.495,-41.9975"
- id="path939"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19240.736,3933.9471 c 10.15,-14.9991 19.285,-29.9982 27.405,-44.9973"
- id="path941"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19283.366,3859.9516 c 7.105,-15.9991 14.21,-32.9981 20.3,-48.9971"
- id="path943"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19314.831,3779.9564 c 5.075,-16.999 9.135,-33.998 13.195,-50.997"
- id="path945"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19333.101,3696.9613 c 2.03,-17.9989 4.06,-34.9979 4.06,-52.9968"
- id="path947"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,3611.9664 0,-53.9967"
- id="path949"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,3525.9716 0,-52.9968"
- id="path951"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,3440.9767 0,-52.9968"
- id="path953"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,3354.9819 0,-52.9969"
- id="path955"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,3269.987 0,-52.9969"
- id="path957"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,3183.9921 0,-52.9968"
- id="path959"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,3098.9972 0,-52.9968"
- id="path961"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,3014.0023 0,-53.9967"
- id="path963"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,2928.0075 0,-52.9968"
- id="path965"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,2843.0126 0,-52.9968"
- id="path967"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,2757.0177 0,-52.9968"
- id="path969"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,2672.0228 0,-52.9968"
- id="path971"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,2586.028 0,-52.9968"
- id="path973"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,2501.0331 0,-52.9968"
- id="path975"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,2415.0383 0,-52.9969"
- id="path977"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,2330.0434 0,-52.9969"
- id="path979"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,2245.0485 0,-52.9969"
- id="path981"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,2159.0536 0,-52.9968"
- id="path983"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,2074.0587 0,-52.9968"
- id="path985"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,1988.0639 0,-52.9968"
- id="path987"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,1903.069 0,-52.9968"
- id="path989"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,1817.0741 0,-52.9968"
- id="path991"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,1732.0792 0,-52.9968"
- id="path993"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,1647.0843 0,-52.9968"
- id="path995"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,1561.0895 0,-52.9968"
- id="path997"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,1476.0946 0,-52.9968"
- id="path999"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,1390.0998 0,-52.9969"
- id="path1001"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,1305.1049 0,-52.9969"
- id="path1003"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19337.161,1219.11 c -1.015,-16.999 -3.045,-34.9979 -5.075,-51.9969"
- id="path1005"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19325.996,1135.1151 c -4.06,-16.999 -8.12,-34.9979 -14.21,-50.997"
- id="path1007"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19300.621,1053.12 c -6.09,-15.9991 -13.195,-32.998 -21.315,-48.9971"
- id="path1009"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19264.081,976.1246 c -9.135,-15.99904 -18.27,-30.99814 -28.42,-45.99724"
- id="path1011"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19216.376,904.12892 c -10.15,-13.99916 -21.315,-27.99832 -33.495,-41.99748"
- id="path1013"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19160.551,838.13288 c -12.18,-12.99922 -24.36,-24.9985 -37.555,-36.99778"
- id="path1015"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19097.621,780.13636 c -14.21,-11.99928 -28.42,-21.99868 -42.63,-32.99802"
- id="path1017"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 19027.586,729.13942 c -15.225,-8.99946 -30.45,-17.99892 -46.69,-26.99838"
- id="path1019"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18951.461,688.14188 c -16.24,-7.99952 -32.48,-13.99916 -49.735,-19.9988"
- id="path1021"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18870.261,657.14374 c -17.255,-4.9997 -34.51,-8.99946 -51.765,-11.99928"
- id="path1023"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18786.016,640.14476 c -18.27,-2.99982 -35.525,-3.99976 -53.795,-3.99976"
- id="path1025"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18699.741,636.145 -53.795,0"
- id="path1027"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18612.451,636.145 -53.795,0"
- id="path1029"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18526.176,636.145 -53.795,0"
- id="path1031"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18438.886,636.145 -53.795,0"
- id="path1033"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18352.611,636.145 -53.795,0"
- id="path1035"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18266.336,636.145 -54.81,0"
- id="path1037"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18179.046,636.145 -53.795,0"
- id="path1039"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18092.771,636.145 -53.795,0"
- id="path1041"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 18005.481,636.145 -53.795,0"
- id="path1043"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17919.206,636.145 -53.795,0"
- id="path1045"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17831.916,636.145 -53.795,0"
- id="path1047"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17745.641,636.145 -53.795,0"
- id="path1049"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17659.366,636.145 -54.81,0"
- id="path1051"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17572.076,636.145 -53.795,0"
- id="path1053"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17485.801,636.145 -53.795,0"
- id="path1055"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17398.511,636.145 -53.795,0"
- id="path1057"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17312.236,636.145 -53.795,0"
- id="path1059"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17224.946,636.145 -53.795,0"
- id="path1061"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17138.671,636.145 -53.795,0"
- id="path1063"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 17052.396,636.145 -54.81,0"
- id="path1065"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16965.106,636.145 -53.795,0"
- id="path1067"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16878.831,636.145 -53.795,0"
- id="path1069"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16791.541,636.145 -53.795,0"
- id="path1071"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16705.266,636.145 -53.795,0"
- id="path1073"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16617.976,636.145 -53.795,0"
- id="path1075"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16531.701,636.145 -53.795,0"
- id="path1077"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16445.426,636.145 -54.81,0"
- id="path1079"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16358.136,636.145 -53.795,0"
- id="path1081"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16271.861,636.145 -53.795,0"
- id="path1083"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16184.571,636.145 -53.795,0"
- id="path1085"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16098.296,636.145 -53.795,0"
- id="path1087"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 16011.006,636.145 -53.795,0"
- id="path1089"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15924.731,636.145 -53.795,0"
- id="path1091"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15837.441,636.145 -53.795,0"
- id="path1093"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15751.166,636.145 -53.795,0"
- id="path1095"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15664.891,636.145 -53.795,0"
- id="path1097"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15577.601,636.145 -53.795,0"
- id="path1099"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15491.326,636.145 -53.795,0"
- id="path1101"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15404.036,636.145 -53.795,0"
- id="path1103"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15317.761,636.145 -53.795,0"
- id="path1105"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15230.471,636.145 -53.795,0"
- id="path1107"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15144.196,636.145 -53.795,0"
- id="path1109"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 15057.921,636.145 -53.795,0"
- id="path1111"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14970.631,636.145 -53.795,0"
- id="path1113"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14884.356,636.145 -53.795,0"
- id="path1115"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14797.066,636.145 -53.795,0"
- id="path1117"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14710.791,636.145 -53.795,0"
- id="path1119"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14623.501,636.145 -53.795,0"
- id="path1121"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14537.226,636.145 -53.795,0"
- id="path1123"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14450.951,636.145 -54.81,0"
- id="path1125"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14363.661,636.145 -53.795,0"
- id="path1127"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14277.386,636.145 -53.795,0"
- id="path1129"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14190.096,636.145 -53.795,0"
- id="path1131"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14103.821,636.145 -53.795,0"
- id="path1133"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 14016.531,636.145 -53.795,0"
- id="path1135"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13930.256,636.145 -53.795,0"
- id="path1137"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13843.981,636.145 -54.81,0"
- id="path1139"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13756.691,636.145 -53.795,0"
- id="path1141"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13670.416,636.145 -53.795,0"
- id="path1143"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13583.126,636.145 -53.795,0"
- id="path1145"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13496.851,636.145 -53.795,0"
- id="path1147"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13409.561,636.145 -53.795,0"
- id="path1149"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13323.286,636.145 -53.795,0"
- id="path1151"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13237.011,636.145 -54.81,0"
- id="path1153"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13149.721,636.145 -53.795,0"
- id="path1155"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 13063.446,636.145 -53.795,0"
- id="path1157"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12976.156,636.145 -53.795,0"
- id="path1159"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12889.881,636.145 -53.795,0"
- id="path1161"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12802.591,636.145 -53.795,0"
- id="path1163"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12716.316,636.145 -53.795,0"
- id="path1165"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12630.041,636.145 -54.81,0"
- id="path1167"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12542.751,636.145 -53.795,0"
- id="path1169"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12456.476,636.145 -53.795,0"
- id="path1171"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12369.186,636.145 -53.795,0"
- id="path1173"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12282.911,636.145 -53.795,0"
- id="path1175"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12195.621,636.145 -53.795,0"
- id="path1177"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12109.346,636.145 -53.795,0"
- id="path1179"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 12022.056,636.145 -53.795,0"
- id="path1181"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11935.781,636.145 -53.795,0"
- id="path1183"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11849.506,636.145 -53.795,0"
- id="path1185"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11762.216,636.145 -53.795,0"
- id="path1187"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11675.941,636.145 -53.795,0"
- id="path1189"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11588.651,636.145 -53.795,0"
- id="path1191"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11502.376,636.145 -53.795,0"
- id="path1193"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11415.086,636.145 -53.795,0"
- id="path1195"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11328.811,636.145 -53.795,0"
- id="path1197"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11242.536,636.145 -53.795,0"
- id="path1199"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11155.246,636.145 -53.795,0"
- id="path1201"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 11068.971,636.145 -53.795,0"
- id="path1203"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10981.681,636.145 -53.795,0"
- id="path1205"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10895.406,636.145 -53.795,0"
- id="path1207"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10808.116,636.145 -53.795,0"
- id="path1209"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10721.841,636.145 -53.795,0"
- id="path1211"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10635.566,636.145 -53.795,0"
- id="path1213"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10548.276,636.145 -53.795,0"
- id="path1215"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10462.001,636.145 -53.795,0"
- id="path1217"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10374.711,636.145 -53.795,0"
- id="path1219"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10288.436,636.145 -53.795,0"
- id="path1221"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10201.146,636.145 -53.795,0"
- id="path1223"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10114.871,636.145 -53.795,0"
- id="path1225"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 10028.596,636.145 -54.8101,0"
- id="path1227"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9941.3059,636.145 -53.795,0"
- id="path1229"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9855.0309,636.145 -53.795,0"
- id="path1231"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9767.7409,636.145 -53.795,0"
- id="path1233"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9681.4659,636.145 -53.795,0"
- id="path1235"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9594.1759,636.145 -53.795,0"
- id="path1237"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9507.9009,636.145 -53.795,0"
- id="path1239"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9421.6259,636.145 -54.81,0"
- id="path1241"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9334.3359,636.145 -53.795,0"
- id="path1243"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9248.0609,636.145 -53.795,0"
- id="path1245"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9160.7709,636.145 -53.795,0"
- id="path1247"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 9074.4959,636.145 -53.795,0"
- id="path1249"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8987.2059,636.145 -53.795,0"
- id="path1251"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8900.9309,636.145 -53.795,0"
- id="path1253"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8814.6559,636.145 -54.81,0"
- id="path1255"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8727.3659,636.145 -53.795,0"
- id="path1257"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8641.0909,636.145 -53.795,0"
- id="path1259"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8553.8009,636.145 -53.795,0"
- id="path1261"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8467.5259,636.145 -53.795,0"
- id="path1263"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8380.2359,636.145 -53.795,0"
- id="path1265"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8293.9609,636.145 -53.795,0"
- id="path1267"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8207.6859,636.145 -54.81,0"
- id="path1269"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8120.3959,636.145 -53.795,0"
- id="path1271"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 8034.1209,636.145 -53.795,0"
- id="path1273"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7946.8309,636.145 -53.795,0"
- id="path1275"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7860.5559,636.145 -53.795,0"
- id="path1277"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7773.2659,636.145 -53.795,0"
- id="path1279"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7686.9909,636.145 -53.795,0"
- id="path1281"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7599.7009,636.145 -53.795,0"
- id="path1283"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7513.4259,636.145 -53.795,0"
- id="path1285"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7427.1509,636.145 -53.795,0"
- id="path1287"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7339.8609,636.145 -53.795,0"
- id="path1289"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7253.5859,636.145 -53.795,0"
- id="path1291"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7166.2959,636.145 -53.795,0"
- id="path1293"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 7080.0209,636.145 -53.795,0"
- id="path1295"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6992.7309,636.145 -53.795,0"
- id="path1297"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6906.4559,636.145 -53.795,0"
- id="path1299"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6820.1809,636.145 -53.795,0"
- id="path1301"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6732.8909,636.145 -53.795,0"
- id="path1303"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6646.6159,636.145 -53.795,0"
- id="path1305"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6559.3259,636.145 -53.795,0"
- id="path1307"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6473.0509,636.145 -53.795,0"
- id="path1309"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6385.7609,636.145 -53.795,0"
- id="path1311"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6299.4859,636.145 -53.795,0"
- id="path1313"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6213.2109,636.145 -54.81,0"
- id="path1315"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6125.9209,636.145 -53.795,0"
- id="path1317"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 6039.6459,636.145 -53.795,0"
- id="path1319"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5952.3559,636.145 -53.795,0"
- id="path1321"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5866.0809,636.145 -53.795,0"
- id="path1323"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5778.7909,636.145 -53.795,0"
- id="path1325"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5692.5159,636.145 -53.795,0"
- id="path1327"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5606.2409,636.145 -54.81,0"
- id="path1329"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5518.9509,636.145 -53.795,0"
- id="path1331"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5432.6759,636.145 -53.795,0"
- id="path1333"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5345.3859,636.145 -53.795,0"
- id="path1335"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5259.1109,636.145 -53.795,0"
- id="path1337"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5171.8209,636.145 -53.795,0"
- id="path1339"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 5085.5459,636.145 -53.795,0"
- id="path1341"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4999.2709,636.145 -54.81,0"
- id="path1343"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4911.9809,636.145 -53.795,0"
- id="path1345"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4825.7059,636.145 -53.795,0"
- id="path1347"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4738.4159,636.145 -53.795,0"
- id="path1349"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4652.1409,636.145 -53.795,0"
- id="path1351"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4564.8509,636.145 -53.795,0"
- id="path1353"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4478.5759,636.145 -53.795,0"
- id="path1355"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4392.3009,636.145 -54.81,0"
- id="path1357"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4305.0109,636.145 -53.795,0"
- id="path1359"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4218.7359,636.145 -53.795,0"
- id="path1361"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4131.4459,636.145 -53.795,0"
- id="path1363"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 4045.1709,636.145 -53.795,0"
- id="path1365"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3957.8809,636.145 -53.795,0"
- id="path1367"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3871.6059,636.145 -53.795,0"
- id="path1369"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3785.3309,636.145 -54.81,0"
- id="path1371"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3698.0409,636.145 -53.795,0"
- id="path1373"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3611.7659,636.145 -53.795,0"
- id="path1375"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3524.4759,636.145 -53.795,0"
- id="path1377"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3438.2009,636.145 -53.795,0"
- id="path1379"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3350.9109,636.145 -53.795,0"
- id="path1381"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3264.6359,636.145 -53.795,0"
- id="path1383"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3177.3459,636.145 -53.795,0"
- id="path1385"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3091.0709,636.145 -53.795,0"
- id="path1387"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 3004.7959,636.145 -53.795,0"
- id="path1389"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2917.5059,636.145 -53.795,0"
- id="path1391"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2831.2309,636.145 -53.795,0"
- id="path1393"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2743.9409,636.145 -53.795,0"
- id="path1395"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2657.6659,636.145 -53.795,0"
- id="path1397"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2570.3759,636.145 -53.795,0"
- id="path1399"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2484.1009,636.145 -53.795,0"
- id="path1401"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2397.8259,636.145 -53.795,0"
- id="path1403"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2310.5359,636.145 -53.795,0"
- id="path1405"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2224.2609,636.145 -53.795,0"
- id="path1407"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2136.9709,636.145 -53.795,0"
- id="path1409"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 2050.6959,636.145 -53.795,0"
- id="path1411"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1963.4059,636.145 -53.795,0"
- id="path1413"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1877.1309,636.145 -53.795,0"
- id="path1415"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1790.8559,636.145 -54.81,0"
- id="path1417"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1703.5659,636.145 -53.795,0"
- id="path1419"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1617.2909,636.145 -53.795,0"
- id="path1421"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1530.0009,636.145 -53.795,0"
- id="path1423"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1443.7259,636.145 -53.795,0"
- id="path1425"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1356.4359,636.145 -53.795,0"
- id="path1427"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1270.1609,636.145 -53.795,0"
- id="path1429"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1183.8859,636.145 -54.81,0"
- id="path1431"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1096.5959,636.145 -53.795,0"
- id="path1433"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 1010.3209,636.145 -53.795,0"
- id="path1435"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#3465af;stroke-width:28.432024"
- d="m 923.0309,636.145 -53.795,0"
- id="path1437"
- inkscape:connector-curvature="0" /><g
- id="g4044"><rect
- height="1100.7"
- width="1213.6"
- y="4753.1133"
- x="21109.146"
- id="rect1441"
- style="fill:#f3e777" /><path
- d="m 20656.146,5536.413 0,-405.46 150.7,-169.16 c 82.886,-93.039 170.53,-186.62 194.77,-207.96 l 44.069,-38.798 783.23,-0.086 783.23,-0.086 0,613.5 0,613.5 -978,0 -978,0 0,-405.46 z m 1027.7,136.98 0,-78.372 -169.91,4.925 -169.91,4.9249 -5.09,45.854 c -8.249,74.303 46.711,101.04 207.69,101.04 l 137.21,0 0,-78.372 z m 235.86,-262.94 4.495,-341.31 207.2,-8.6408 207.2,-8.6408 5.144,-46.443 c 9.596,-86.615 -41.863,-102.05 -322.02,-96.607 l -246.71,4.7956 -4.438,419.08 -4.439,419.08 74.537,0 74.538,0 4.494,-341.31 z m 391.3,313.72 c 26.41,-19.286 36.255,-41.399 32.697,-73.447 l -5.09,-45.854 -174.05,0 -174.05,0 -5.38,48.984 c -9.97,90.771 0.993,97.91 150.36,97.91 99.305,0 148.27,-7.6982 175.52,-27.594 z m -627.16,-274.84 0,-77.768 -174.05,0 -174.05,0 0,66.246 c 0,36.436 4.973,71.431 11.051,77.768 6.078,6.3366 84.401,11.521 174.05,11.521 l 163,0 0,-77.768 z m 659.89,-4.9154 5.125,-74.042 -179.18,4.9155 -179.18,4.9155 -5.38,48.984 c -10.473,95.348 -2.259,99.57 183.28,94.197 l 170.2,-4.9284 5.125,-74.042 z m -659.89,-237.63 0,-78.372 -169.91,4.925 -169.91,4.925 -5.097,73.447 -5.097,73.447 175,0 175,0 0,-78.372 z m 659.86,4.925 -5.097,-73.447 -174.05,0 -174.05,0 -5.38,48.984 c -10.289,93.673 -2.146,97.91 188.15,97.91 l 175.52,0 -5.097,-73.447 z m -659.86,-228.98 0,-77.768 -137.21,0 c -97.358,0 -147.91,7.8138 -174.05,26.902 -34.952,25.523 -49.645,92.242 -25.79,117.11 6.078,6.3366 84.401,11.521 174.05,11.521 l 163,0 0,-77.768 z"
- id="path1443"
- inkscape:connector-curvature="0"
- style="fill:#ca4677" /></g><text
- style="font-size:9.10937119px;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round"
- class="TextShape"
- id="text1489"
- transform="scale(1.1035537,0.9061634)"
- x="171.41566"
- y="9913.7109"><tspan
- font-size="635px"
- font-weight="400"
- class="TextParagraph"
- id="tspan1491"
- style="font-weight:400;font-size:482.03753662px;font-family:'Times New Roman', serif" /></text>
-<g
- id="g4048"><rect
- height="2342.4341"
- width="2320.7097"
- y="13737.451"
- x="18796.941"
- id="rect1447"
- style="fill:#6076b3" /><rect
- id="rect1451"
- height="137.78799"
- x="18532.135"
- width="302.70312"
- y="13817.405"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><rect
- id="rect1453"
- height="137.78799"
- x="18532.135"
- width="302.70312"
- y="14075.544"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><rect
- id="rect1455"
- height="137.78799"
- x="18532.135"
- width="302.70312"
- y="14334.443"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><rect
- id="rect1457"
- height="137.78799"
- x="18532.135"
- width="302.70312"
- y="14592.582"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><rect
- id="rect1459"
- height="137.78799"
- x="18532.135"
- width="302.70312"
- y="14850.721"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><rect
- id="rect1461"
- height="137.78799"
- x="18532.135"
- width="302.70312"
- y="15109.62"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><rect
- id="rect1463"
- height="137.78799"
- x="18532.135"
- width="302.70312"
- y="15367.759"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><rect
- id="rect1465"
- height="137.78799"
- x="18532.135"
- width="302.70312"
- y="15625.896"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><rect
- id="rect1467"
- height="137.78799"
- x="18532.135"
- width="302.70312"
- y="15884.035"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><rect
- id="rect1469"
- height="137.78799"
- x="21080.053"
- width="302.70312"
- y="13783.14"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><rect
- id="rect1471"
- height="137.78799"
- x="21080.053"
- width="302.70312"
- y="14041.277"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><rect
- id="rect1473"
- height="137.78799"
- x="21080.053"
- width="302.70312"
- y="14299.416"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><rect
- id="rect1475"
- height="137.78799"
- x="21080.053"
- width="302.70312"
- y="14558.315"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><rect
- id="rect1477"
- height="137.78799"
- x="21080.053"
- width="302.70312"
- y="14816.454"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><rect
- id="rect1479"
- height="137.78799"
- x="21080.053"
- width="302.70312"
- y="15074.593"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><rect
- id="rect1481"
- height="137.78799"
- x="21080.053"
- width="302.70312"
- y="15333.492"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><rect
- id="rect1483"
- height="137.78799"
- x="21080.053"
- width="302.70312"
- y="15591.631"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><rect
- id="rect1485"
- height="137.78799"
- x="21080.053"
- width="302.70312"
- y="15849.769"
- style="fill:#e0ee2c;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><text
- transform="scale(1.1035537,0.9061634)"
- sodipodi:linespacing="125%"
- id="text1493"
- line-height="125%"
- x="17205.688"
- y="16777.641"
- font-size="1128.9px"
- xml:space="preserve"
- style="font-size:856.96411133px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round"><tspan
- id="tspan1495"
- x="17205.688"
- y="16777.641">CPU</tspan></text>
-</g><text
- style="fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round"
- id="text1499"
- class="TextShape"
- x="-11700.553"
- y="565.61298"><tspan
- style="font-weight:400;font-size:706px;font-family:'Times New Roman', serif"
- id="tspan1501"
- class="TextParagraph"
- font-weight="400"
- font-size="706px"><tspan
- id="tspan1503"
- transform="matrix(0,-1,1,0,8509,40173)"
- class="TextPosition"
- x="12640.447"
- y="16397.613"><tspan
- style="fill:#000000"
- id="tspan1505">PCI, USB, SPI, I2C, ...</tspan></tspan></tspan></text>
-<path
- d="m 12408.066,15561.578 -1115.084,0 0,-1420.331 2230.169,0 0,1420.331 -1115.085,0 z"
- id="path1511"
- inkscape:connector-curvature="0"
- style="fill:#cfe7f5;fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round" /><path
- d="m 12408.066,15561.578 -1115.084,0 0,-1420.331 2230.169,0 0,1420.331 -1115.085,0 z"
- id="path1513"
- inkscape:connector-curvature="0"
- style="fill:none;fill-rule:evenodd;stroke:#3465af;stroke-width:19.84712601;stroke-linejoin:round" /><text
- style="fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round"
- id="text1515"
- class="TextShape"
- x="-1394.0863"
- y="590.73016"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan1517"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan1519"
- class="TextPosition"
- x="11487.915"
- y="14672.743"><tspan
- style="fill:#000000"
- id="tspan1521">Bridge</tspan></tspan></tspan></text>
-<text
- style="fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round"
- id="text1523"
- class="TextShape"
- x="-1450.5308"
- y="1324.5078"><tspan
- style="font-weight:400;font-size:635px;font-family:'Times New Roman', serif"
- id="tspan1525"
- class="TextParagraph"
- font-weight="400"
- font-size="635px"><tspan
- id="tspan1527"
- class="TextPosition"
- x="11431.471"
- y="15406.52"><tspan
- style="fill:#000000"
- id="tspan1529"> DMA</tspan></tspan></tspan></text>
-</svg> \ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?>
+<svg id="svg2" width="235mm" height="179mm" clip-path="url(#a)" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" preserveAspectRatio="xMidYMid" version="1.2" viewBox="0 0 22648.239 17899.829" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata id="metadata1533"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs id="defs4"><clipPath id="a"><rect id="rect7" width="28000" height="21000"/></clipPath></defs><path id="path11" d="m10146 2636c-518.06 0-1035.1 515-1035.1 1031v4124c0 516 517.06 1032 1035.1 1032h8572.2c518.06 0 1036.1-516 1036.1-1032v-4124c0-516-518.06-1031-1036.1-1031h-8572.2z"
+fill="#fcf" style=""/><path id="path15" d="m1505.5 13443c-293 0-585 292-585 585v2340c0 293 292 586 585 586h3275c293 0 586-293 586-586v-2340c0-293-293-585-586-585h-3275z" fill="#ffc" style=""/><path id="path19" d="m517.15 22.013c-461 0-922 461-922 922v11169c0 461 461 923 922 923h3692c461 0 922-462 922-923v-11169c0-461-461-922-922-922h-3692z" fill="#e6e6e6" style=""/><path id="path23" d="m2371.5 6438h-2260v-1086h4520v1086h-2260z" fill="#ff8080" style=""/><path id="path25" d="m2371.5 6438h-2260v-1086h4520v1086h-2260z" fill="none" stroke="#3465af" style=""/><text id="text27" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan29" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan31" class="TextPosition" x="489.5459" y="6111.0132" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan33"
+fill="#000000" font-family="Serif, serif" font-size="493.88px">Audio decoder</tspan></tspan></tspan></text>
+<path id="path37" d="m2371.5 9608h-2260v-1270h4520v1270h-2260z" fill="#ff8080" style=""/><path id="path39" d="m2371.5 9608h-2260v-1270h4520v1270h-2260z" fill="none" stroke="#3465af" style=""/><text id="text41" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan43" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan45" class="TextPosition" x="527.5459" y="9189.0127" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan47" fill="#000000" font-family="Serif, serif" font-size="493.88px">Video decoder</tspan></tspan></tspan></text>
+<path id="path51" d="m2363.5 8053h-2269v-1224h4537v1224h-2268z" fill="#ff8080" style=""/><path id="path53" d="m2363.5 8053h-2269v-1224h4537v1224h-2268z" fill="none" stroke="#3465af" style=""/><text id="text55" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan57" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan59" class="TextPosition" x="481.5459" y="7657.0132" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan61" fill="#000000" font-family="Serif, serif" font-size="493.88px">Audio encoder</tspan></tspan></tspan></text>
+<path id="path65" d="m13622 10386h-3810v-1281h7620v1281h-3810z" fill="#cfc" style=""/><path id="path67" d="m13622 10386h-3810v-1281h7620v1281h-3810z" fill="none" stroke="#3465af" style=""/><text id="text69" class="TextShape" x="-2089.4541" y="-2446.187" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan71" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan73" class="TextPosition" x="10287.546" y="9960.8135" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan75" fill="#000000" font-family="Serif, serif" font-size="493.88px">Button Key/IR input logic</tspan></tspan></tspan></text>
+<path id="path79" d="m12080 12182h-2268v-1412h4536v1412h-2268z" fill="#cfe7f5" style=""/><path id="path81" d="m12080 12182h-2268v-1412h4536v1412h-2268z" fill="none" stroke="#3465af" style=""/><text id="text83" class="TextShape" x="-2089.4541" y="-2389.7871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan85" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan87" class="TextPosition" x="10792.546" y="11692.213" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan89" fill="#000000" font-family="Serif, serif" font-size="493.88px">EEPROM</tspan></tspan></tspan></text>
+<path id="path93" d="m3050.5 15498h-1563v-1715h3126v1715h-1563z" fill="#fc9" style=""/><path id="path95" d="m3050.5 15498h-1563v-1715h3126v1715h-1563z" fill="none" stroke="#3465af" style=""/><text id="text97" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan99" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan101" class="TextPosition" x="2186.5459" y="14856.013" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan103" fill="#000000" font-family="Serif, serif" font-size="493.88px">Sensor</tspan></tspan></tspan></text>
+<path id="path107" d="m4629.5 5866 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="#729fcf" style=""/><path id="path109" d="m4629.5 5866 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path113" d="m4629.5 7448 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="#729fcf" style=""/><path id="path115" d="m4629.5 7448 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path119" d="m4631.5 8936 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="#729fcf" style=""/><path id="path121" d="m4631.5 8936 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path125" d="m7872.5 11464 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z"
+fill="#729fcf" style=""/><path id="path127" d="m7872.5 11464 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path131" d="m7872.5 9716.8 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="#729fcf" style=""/><path id="path133" d="m7872.5 9716.8 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path137" d="m7872.5 14994 670-353v176h2028v-176l671 353-671 354v-177h-2028v177l-670-354z" fill="#729fcf" style=""/><path id="path139" d="m7872.5 14994 670-353v176h2028v-176l671 353-671 354v-177h-2028v177l-670-354z" fill="none" stroke="#3465af" style=""/><path id="path143" d="m17534 14105 978.49 840.89-978.49 840.89v-420.86h-2960.5v420.86l-979.49-840.89 979.49-840.89v420.03h2960.5v-420.03z" fill="#729fcf" style=""/><path id="path145" d="m17534 14105 978.49
+840.89-978.49 840.89v-420.86h-2960.5v420.86l-979.49-840.89 979.49-840.89v420.03h2960.5v-420.03z" fill="none" stroke="#3465af" stroke-width="25.77" style=""/><text id="text149" class="TextShape" x="-9922.1533" y="-644.58704" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan151" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan153" class="TextPosition" transform="matrix(0,-1,1,0,8509,40173)" x="14418.847" y="15187.413" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan155" fill="#000000" font-family="Serif, serif" font-size="493.88px">System Bus</tspan></tspan></tspan></text>
+<path id="path159" d="m11062 7098h-1250v-875h2499v875h-1249z" fill="#cff" style=""/><path id="path161" d="m11062 7098h-1250v-875h2499v875h-1249z" fill="none" stroke="#3465af" style=""/><text id="text163" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan165" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan167" class="TextPosition" x="10125.546" y="6876.0132" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan169" fill="#000000" font-family="Serif, serif" font-size="493.88px">Demux</tspan></tspan></tspan></text>
+<path id="path173" d="m7906.5 6601 373-357v178h1130v-178l374 357-374 358v-179h-1130v179l-373-358z" fill="#729fcf" style=""/><path id="path175" d="m7906.5 6601 373-357v178h1130v-178l374 357-374 358v-179h-1130v179l-373-358z" fill="none" stroke="#3465af" style=""/><path id="path179" d="m7906.5 5214 373-358v179h1130v-179l374 358-374 358v-179h-1130v179l-373-358z" fill="#729fcf" style=""/><path id="path181" d="m7906.5 5214 373-358v179h1130v-179l374 358-374 358v-179h-1130v179l-373-358z" fill="none" stroke="#3465af" style=""/><path id="path185" d="m14233 5828h-4421v-1270h8841v1270h-4420z" fill="#cff" style=""/><path id="path187" d="m14233 5828h-4421v-1270h8841v1270h-4420z" fill="none" stroke="#3465af" style=""/><text id="text189" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan191" class="TextParagraph" font-family="Serif, serif"
+font-size="493.88px"><tspan id="tspan193" class="TextPosition" x="10696.546" y="5409.0132" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan195" fill="#000000" font-family="Serif, serif" font-size="493.88px">Conditional Access Module</tspan></tspan></tspan></text>
+<path id="path199" d="m2355.5 11123h-2269v-1224h4537v1224h-2268z" fill="#ff8080" style=""/><path id="path201" d="m2355.5 11123h-2269v-1224h4537v1224h-2268z" fill="none" stroke="#3465af" style=""/><text id="text203" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan205" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan207" class="TextPosition" x="511.5459" y="10727.013" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan209" fill="#000000" font-family="Serif, serif" font-size="493.88px">Video encoder</tspan></tspan></tspan></text>
+<path id="path213" d="m4631.5 10470 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="#729fcf" style=""/><path id="path215" d="m4631.5 10470 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path219" d="m18702 5381 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="#729fcf" style=""/><path id="path221" d="m18702 5381 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><text id="text225" class="TextShape" x="-1976.5541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan227" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan229" class="TextPosition" x="13.4459" y="12314.013" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan231" fill="#000000"
+font-family="Serif, serif" font-size="493.88px">Radio / Analog TV</tspan></tspan></tspan></text>
+<text id="text235" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan237" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan239" class="TextPosition" x="12866.546" y="8560.0127" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan241" fill="#000000" font-family="Serif, serif" font-size="493.88px">Digital TV</tspan></tspan></tspan></text>
+<text id="text245" class="TextShape" x="-8919.0537" y="-1373.787" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan247" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan249" class="TextPosition" x="5804.9458" y="17793.213" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan251" fill="#000000" font-family="Serif, serif" font-size="493.88px">PS.: picture is not complete: other blocks may be present</tspan></tspan></tspan></text>
+<text id="text255" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan257" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan259" class="TextPosition" x="2109.5459" y="16397.014" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan261" fill="#000000" font-family="Serif, serif" font-size="493.88px">Webcam</tspan></tspan></tspan></text>
+<path id="path265" d="m12463 13926h-2650v-1412h5299v1412h-2649z" fill="#f90" style=""/><path id="path267" d="m12463 13926h-2650v-1412h5299v1412h-2649z" fill="none" stroke="#3465af" style=""/><text id="text269" class="TextShape" x="-2089.4541" y="-2446.187" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan271" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan273" class="TextPosition" x="10175.546" y="13435.813" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan275" fill="#000000" font-family="Serif, serif" font-size="493.88px">Processing blocks</tspan></tspan></tspan></text>
+<path id="path279" d="m7872.5 13208 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="#729fcf" style=""/><path id="path281" d="m7872.5 13208 385-353v176h1166v-176l386 353-386 354v-177h-1166v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path285" d="m4612.5 14790 397-353v176h1201v-176l398 353-398 354v-177h-1201v177l-397-354z" fill="#729fcf" style=""/><path id="path287" d="m4612.5 14790 397-353v176h1201v-176l398 353-398 354v-177h-1201v177l-397-354z" fill="none" stroke="#3465af" style=""/><text id="text291" class="TextShape" x="-2428.0542" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan293" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan295" class="TextPosition" x="20421.945" y="6628.0132" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan297" fill="#000000"
+font-family="Serif, serif" font-size="493.88px">Smartcard</tspan></tspan></tspan></text>
+<path id="path301" d="m623.32 436.01c-334.6 0-669.2 333-669.2 666v2668c0 333 334.6 666 669.2 666h18456c334.6 0 670.2-333 670.2-666v-2668c0-333-335.6-666-670.2-666h-18456z" fill="#fcf" style=""/><path id="path305" d="m3031.5 2991h-1614v-1816h3227v1816h-1613z" fill="#ff8080" style=""/><path id="path307" d="m3031.5 2991h-1614v-1816h3227v1816h-1613z" fill="none" stroke="#3465af" style=""/><text id="text309" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan311" class="TextParagraph"><tspan id="tspan313" class="TextPosition" x="2284.5459" y="1947.0129" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan315" fill="#000000" font-family="Serif, serif" font-size="493.88px">Tuner</tspan></tspan></tspan><tspan id="tspan317" class="TextParagraph"><tspan id="tspan319" class="TextPosition" x="2061.5459" y="2650.0129"
+font-family="Serif, serif" font-size="493.88px"><tspan id="tspan321" fill="#000000" font-family="Serif, serif" font-size="493.88px">FM/TV</tspan></tspan></tspan></text>
+<path id="path325" d="m812.55 1538c0 111 40 202 88 202h530c48 0 89-91 89-202 0-110-41-202-89-202h-530c-48 0-88 92-88 202z" fill="#ff8080" style=""/><path id="path327" d="m812.55 1538c0 111 40 202 88 202h530c48 0 89-91 89-202 0-110-41-202-89-202h-530c-48 0-88 92-88 202z" fill="none" stroke="#3465af" style=""/><path id="path329" d="m812.55 1538c0 111 40 202 88 202s88-91 88-202c0-110-40-202-88-202s-88 92-88 202z" fill="#ffb3b3" style=""/><path id="path331" d="m812.55 1538c0 111 40 202 88 202s88-91 88-202c0-110-40-202-88-202s-88 92-88 202z" fill="none" stroke="#3465af" style=""/><path id="path335" d="m813.55 2103c0 110 40 202 88 202h530c48 0 89-92 89-202s-41-203-89-203h-530c-48 0-88 93-88 203z" fill="#ff8080" style=""/><path id="path337" d="m813.55 2103c0 110 40 202 88 202h530c48 0 89-92 89-202s-41-203-89-203h-530c-48 0-88 93-88 203z" fill="none" stroke="#3465af" style=""/><path
+id="path339" d="m813.55 2103c0 110 40 202 88 202s88-92 88-202-40-203-88-203-88 93-88 203z" fill="#ffb3b3" style=""/><path id="path341" d="m813.55 2103c0 110 40 202 88 202s88-92 88-202-40-203-88-203-88 93-88 203z" fill="none" stroke="#3465af" style=""/><path id="path345" d="m4629.5 2032 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="#729fcf" style=""/><path id="path347" d="m4629.5 2032 385-353v176h1167v-176l386 353-386 354v-177h-1167v177l-385-354z" fill="none" stroke="#3465af" style=""/><path id="path351" d="m7889.5 1986 402-368v184h1217v-184l403 368-403 369v-185h-1217v185l-402-369z" fill="#729fcf" style=""/><path id="path353" d="m7889.5 1986 402-368v184h1217v-184l403 368-403 369v-185h-1217v185l-402-369z" fill="none" stroke="#3465af" style=""/><path id="path357" d="m14411 4025h-4500v-1389h9e3v1389h-4500z" fill="#cff" style=""/><path id="path359" d="m14411
+4025h-4500v-1389h9e3v1389h-4500z" fill="none" stroke="#3465af" style=""/><text id="text361" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan363" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan365" class="TextPosition" x="9961.5459" y="3546.0129" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan367" fill="#000000" font-family="Serif, serif" font-size="493.88px">Satellite Equipment Control (SEC)</tspan></tspan></tspan></text>
+<path id="path371" d="m11311 2436h-1400v-1e3h2800v1e3h-1400z" fill="#cff" style=""/><path id="path373" d="m11311 2436h-1400v-1e3h2800v1e3h-1400z" fill="none" stroke="#3465af" style=""/><text id="text375" class="TextShape" x="-2089.4541" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan377" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan379" class="TextPosition" x="10375.546" y="2152.0129" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan381" fill="#000000" font-family="Serif, serif" font-size="493.88px">Demod</tspan></tspan></tspan></text>
+<path id="path385" d="m7889.5 3287 402-368v184h1217v-184l403 368-403 369v-185h-1217v185l-402-369z" fill="#729fcf" style=""/><path id="path387" d="m7889.5 3287 402-368v184h1217v-184l403 368-403 369v-185h-1217v185l-402-369z" fill="none" stroke="#3465af" style=""/><path id="path389" d="m7906.5 9121v7302h-1270v-14605h1270v7303z" fill="#ff9" style=""/><path id="path391" d="m7906.5 9121v7302h-1270v-14605h1270v7303z" fill="none" stroke="#3465af" style=""/><text id="text393" class="TextShape" transform="rotate(-90)" x="-20792.584" y="-6589.021" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan395" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan397" class="TextPosition" transform="matrix(0,-1,1,0,-4473,23627)" x="-11215.646" y="7460.9849" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan399" fill="#000000" font-family="Serif,
+serif" font-size="493.88px">I2C Bus (control bus)</tspan></tspan></tspan></text>
+<text id="text403" class="TextShape" x="-2145.854" y="-2163.9871" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan405" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan407" class="TextPosition" x="7245.146" y="1114.0129" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan409" fill="#000000" font-family="Serif, serif" font-size="493.88px">Digital TV Frontend</tspan></tspan></tspan></text>
+<path id="path415" d="m863.15 636.14c-18.27 0-35.525 0.99994-53.795 2.9998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path417" d="m776.87 644.14c-17.255 2.9998-35.525 6.9996-52.78 11.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path419" d="m692.63 666.14c-16.24 5.9996-33.495 11.999-49.735 19.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path421" d="m613.46 700.14c-15.225 7.9995-31.465 16.999-46.69 26.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path423" d="m539.36 745.14c-14.21 9.9994-28.42 20.999-42.63 31.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path425" d="m471.36 798.14c-13.195 11.999-26.39 23.999-38.57 36.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path427" d="m410.46 859.13c-11.165 12.999-22.33
+26.998-33.495 40.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path429" d="m357.68 927.13c-10.15 13.999-19.285 28.998-28.42 44.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path431" d="m314.03 1000.1c-8.12 15.999-15.225 31.998-22.33 48.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path433" d="m280.54 1079.1c-5.075 16.999-10.15 33.998-14.21 50.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path435" d="m260.24 1162.1c-3.045 17.999-5.075 34.998-6.09 52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path437" d="m254.15 1247.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path439" d="m254.15 1333.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path441" d="m254.15 1418.1v52.997"
+fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path443" d="m254.15 1504.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path445" d="m254.15 1589.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path447" d="m254.15 1675.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path449" d="m254.15 1760.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path451" d="m254.15 1845.1v53.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path453" d="m254.15 1931.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path455" d="m254.15 2016.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path457" d="m254.15 2102.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432"
+style=""/><path id="path459" d="m254.15 2187.1v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path461" d="m254.15 2273v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path463" d="m254.15 2358v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path465" d="m254.15 2443v53.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path467" d="m254.15 2529v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path469" d="m254.15 2614v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path471" d="m254.15 2700v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path473" d="m254.15 2785v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path475" d="m254.15 2871v52.997" fill="none"
+stroke="#3465af" stroke-width="28.432" style=""/><path id="path477" d="m254.15 2956v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path479" d="m254.15 3041v53.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path481" d="m254.15 3127v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path483" d="m254.15 3212v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path485" d="m254.15 3298v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path487" d="m254.15 3383v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path489" d="m254.15 3469v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path491" d="m254.15 3554v52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path493"
+d="m254.15 3639c0 17.999 1.015 35.998 3.045 52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path495" d="m262.27 3724c4.06 17.999 8.12 34.998 13.195 51.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path497" d="m285.61 3807c6.09 15.999 13.195 32.998 20.3 48.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path499" d="m321.14 3885c8.12 14.999 17.255 30.998 27.405 45.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path501" d="m366.81 3957.9c10.15 13.999 21.315 27.998 32.48 41.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path503" d="m420.61 4023.9c12.18 12.999 25.375 25.998 38.57 37.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path505" d="m483.54 4083.9c13.195 10.999 27.405 22.999 41.615 32.998" fill="none"
+stroke="#3465af" stroke-width="28.432" style=""/><path id="path507" d="m552.56 4135.9c14.21 9.9994 29.435 18.999 45.675 26.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path509" d="m627.67 4178.9c15.225 6.9996 32.48 14.999 48.72 20.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path511" d="m707.85 4210.9c17.255 4.9997 34.51 9.9994 51.765 13.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path513" d="m792.1 4230.9c17.255 1.9999 35.525 3.9998 53.795 4.9997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path515" d="m878.37 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path517" d="m964.65 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path519" d="m1051.9 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path521" d="m1138.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path523" d="m1225.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path525" d="m1311.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path527" d="m1398.1 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path529" d="m1485.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path531" d="m1571.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path533" d="m1658.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path535" d="m1745.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path537"
+d="m1832.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path539" d="m1918.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path541" d="m2005 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path543" d="m2092.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path545" d="m2178.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path547" d="m2265.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path549" d="m2352.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path551" d="m2439.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path553" d="m2525.7 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path555" d="m2612 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path557" d="m2699.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path559" d="m2785.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path561" d="m2872.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path563" d="m2959.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path565" d="m3046.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path567" d="m3132.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path569" d="m3220 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path571"
+d="m3306.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path573" d="m3392.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path575" d="m3479.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path577" d="m3566.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path579" d="m3653.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path581" d="m3739.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path583" d="m3826.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path585" d="m3913.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path587" d="m3999.5 4235.9h53.795" fill="none"
+stroke="#3465af" stroke-width="28.432" style=""/><path id="path589" d="m4086.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path591" d="m4173.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path593" d="m4260.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path595" d="m4346.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path597" d="m4433.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path599" d="m4520.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path601" d="m4606.5 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path603" d="m4693.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432"
+style=""/><path id="path605" d="m4780 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path607" d="m4867.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path609" d="m4953.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path611" d="m5040.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path613" d="m5127.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path615" d="m5213.4 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path617" d="m5300.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path619" d="m5387 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path621" d="m5474.3 4235.9h53.795"
+fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path623" d="m5560.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path625" d="m5647.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path627" d="m5734.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path629" d="m5820.4 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path631" d="m5907.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path633" d="m5994 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path635" d="m6081.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path637" d="m6167.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432"
+style=""/><path id="path639" d="m6254.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path641" d="m6341.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path643" d="m6427.4 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path645" d="m6514.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path647" d="m6600.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path649" d="m6688.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path651" d="m6774.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path653" d="m6861.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path655" d="m6948.1
+4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path657" d="m7035.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path659" d="m7121.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path661" d="m7207.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path663" d="m7295.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path665" d="m7381.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path667" d="m7468.8 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path669" d="m7555 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path671" d="m7642.3 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path673" d="m7728.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path675" d="m7814.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path677" d="m7902.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path679" d="m7988.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path681" d="m8075.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path683" d="m8162 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path685" d="m8249.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path687" d="m8335.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path689"
+d="m8421.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path691" d="m8509.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path693" d="m8595.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path695" d="m8682.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path697" d="m8769 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path699" d="m8856.3 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path701" d="m8942.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path703" d="m9028.8 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path705" d="m9116.1 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path707" d="m9202.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path709" d="m9289.7 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path711" d="m9376 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path713" d="m9463.2 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path715" d="m9549.5 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path717" d="m9635.8 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path719" d="m9723.1 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path721" d="m9809.4 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path723"
+d="m9896.6 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path725" d="m9982.9 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path727" d="m10070 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path729" d="m10156 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path731" d="m10243 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path733" d="m10330 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path735" d="m10416 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path737" d="m10504 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path739" d="m10590 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path741" d="m10677 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path743" d="m10763 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path745" d="m10850 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path747" d="m10937 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path749" d="m11023 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path751" d="m11111 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path753" d="m11197 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path755" d="m11284 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path757" d="m11370
+4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path759" d="m11458 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path761" d="m11544 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path763" d="m11630 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path765" d="m11718 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path767" d="m11804 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path769" d="m11891 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path771" d="m11977 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path773" d="m12065 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path775" d="m12151 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path777" d="m12237 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path779" d="m12325 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path781" d="m12411 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path783" d="m12498 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path785" d="m12584 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path787" d="m12672 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path789" d="m12758 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path791"
+d="m12844 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path793" d="m12931 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path795" d="m13018 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path797" d="m13105 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path799" d="m13191 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path801" d="m13279 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path803" d="m13365 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path805" d="m13451 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path807" d="m13538 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path809" d="m13625 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path811" d="m13712 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path813" d="m13798 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path815" d="m13886 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path817" d="m13972 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path819" d="m14058 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path821" d="m14145 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path823" d="m14232 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path825" d="m14319
+4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path827" d="m14405 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path829" d="m14493 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path831" d="m14579 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path833" d="m14665 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path835" d="m14752 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path837" d="m14839 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path839" d="m14926 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path841" d="m15012 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path843" d="m15100 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path845" d="m15186 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path847" d="m15272 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path849" d="m15359 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path851" d="m15446 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path853" d="m15533 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path855" d="m15619 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path857" d="m15707 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path859" d="m15793
+4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path861" d="m15880 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path863" d="m15966 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path865" d="m16053 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path867" d="m16140 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path869" d="m16226 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path871" d="m16313 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path873" d="m16400 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path875" d="m16487 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path877" d="m16573 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path879" d="m16660 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path881" d="m16747 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path883" d="m16833 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path885" d="m16920 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path887" d="m17007 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path889" d="m17094 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path891" d="m17180 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path893"
+d="m17267 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path895" d="m17354 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path897" d="m17440 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path899" d="m17527 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path901" d="m17614 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path903" d="m17701 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path905" d="m17787 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path907" d="m17874 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path909" d="m17961 4235.9h53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path911" d="m18047 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path913" d="m18134 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path915" d="m18221 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path917" d="m18308 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path919" d="m18394 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path921" d="m18481 4235.9h54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path923" d="m18568 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path925" d="m18654 4235.9h53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path927" d="m18741
+4235.9c17.255-0.9999 35.525-1.9999 53.795-4.9997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path929" d="m18828 4225.9c17.255-3.9998 34.51-8.9995 51.765-13.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path931" d="m18911 4200.9c16.24-5.9996 32.48-12.999 48.72-20.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path933" d="m18989 4164.9c15.225-7.9996 31.465-16.999 45.675-26.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path935" d="m19062 4118.9c14.21-9.9994 28.42-20.999 42.63-31.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path937" d="m19129 4064.9c13.195-11.999 25.375-24.998 37.555-37.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path939" d="m19189 4002.9c11.165-13.999 22.33-27.998 33.495-41.998" fill="none"
+stroke="#3465af" stroke-width="28.432" style=""/><path id="path941" d="m19241 3933.9c10.15-14.999 19.285-29.998 27.405-44.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path943" d="m19283 3860c7.105-15.999 14.21-32.998 20.3-48.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path945" d="m19315 3780c5.075-16.999 9.135-33.998 13.195-50.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path947" d="m19333 3697c2.03-17.999 4.06-34.998 4.06-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path949" d="m19337 3612v-53.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path951" d="m19337 3526v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path953" d="m19337 3441v-52.997" fill="none" stroke="#3465af" stroke-width="28.432"
+style=""/><path id="path955" d="m19337 3355v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path957" d="m19337 3270v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path959" d="m19337 3184v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path961" d="m19337 3099v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path963" d="m19337 3014v-53.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path965" d="m19337 2928v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path967" d="m19337 2843v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path969" d="m19337 2757v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path971" d="m19337 2672v-52.997" fill="none"
+stroke="#3465af" stroke-width="28.432" style=""/><path id="path973" d="m19337 2586v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path975" d="m19337 2501v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path977" d="m19337 2415v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path979" d="m19337 2330v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path981" d="m19337 2245v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path983" d="m19337 2159.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path985" d="m19337 2074.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path987" d="m19337 1988.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
+id="path989" d="m19337 1903.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path991" d="m19337 1817.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path993" d="m19337 1732.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path995" d="m19337 1647.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path997" d="m19337 1561.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path999" d="m19337 1476.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1001" d="m19337 1390.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1003" d="m19337 1305.1v-52.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1005" d="m19337
+1219.1c-1.015-16.999-3.045-34.998-5.075-51.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1007" d="m19326 1135.1c-4.06-16.999-8.12-34.998-14.21-50.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1009" d="m19301 1053.1c-6.09-15.999-13.195-32.998-21.315-48.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1011" d="m19264 976.12c-9.135-15.999-18.27-30.998-28.42-45.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1013" d="m19216 904.13c-10.15-13.999-21.315-27.998-33.495-41.997" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1015" d="m19161 838.13c-12.18-12.999-24.36-24.998-37.555-36.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1017" d="m19098 780.14c-14.21-11.999-28.42-21.999-42.63-32.998" fill="none"
+stroke="#3465af" stroke-width="28.432" style=""/><path id="path1019" d="m19028 729.14c-15.225-8.9995-30.45-17.999-46.69-26.998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1021" d="m18951 688.14c-16.24-7.9995-32.48-13.999-49.735-19.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1023" d="m18870 657.14c-17.255-4.9997-34.51-8.9995-51.765-11.999" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1025" d="m18786 640.14c-18.27-2.9998-35.525-3.9998-53.795-3.9998" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1027" d="m18700 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1029" d="m18612 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1031" d="m18526 636.14h-53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path1033" d="m18439 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1035" d="m18353 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1037" d="m18266 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1039" d="m18179 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1041" d="m18093 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1043" d="m18005 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1045" d="m17919 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1047" d="m17832 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
+id="path1049" d="m17746 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1051" d="m17659 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1053" d="m17572 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1055" d="m17486 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1057" d="m17399 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1059" d="m17312 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1061" d="m17225 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1063" d="m17139 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1065" d="m17052 636.14h-54.81"
+fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1067" d="m16965 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1069" d="m16879 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1071" d="m16792 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1073" d="m16705 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1075" d="m16618 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1077" d="m16532 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1079" d="m16445 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1081" d="m16358 636.14h-53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path1083" d="m16272 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1085" d="m16185 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1087" d="m16098 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1089" d="m16011 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1091" d="m15925 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1093" d="m15837 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1095" d="m15751 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1097" d="m15665 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
+id="path1099" d="m15578 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1101" d="m15491 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1103" d="m15404 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1105" d="m15318 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1107" d="m15230 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1109" d="m15144 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1111" d="m15058 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1113" d="m14971 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1115" d="m14884 636.14h-53.795"
+fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1117" d="m14797 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1119" d="m14711 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1121" d="m14624 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1123" d="m14537 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1125" d="m14451 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1127" d="m14364 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1129" d="m14277 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1131" d="m14190 636.14h-53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path1133" d="m14104 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1135" d="m14017 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1137" d="m13930 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1139" d="m13844 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1141" d="m13757 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1143" d="m13670 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1145" d="m13583 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1147" d="m13497 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
+id="path1149" d="m13410 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1151" d="m13323 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1153" d="m13237 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1155" d="m13150 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1157" d="m13063 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1159" d="m12976 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1161" d="m12890 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1163" d="m12803 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1165" d="m12716 636.14h-53.795"
+fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1167" d="m12630 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1169" d="m12543 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1171" d="m12456 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1173" d="m12369 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1175" d="m12283 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1177" d="m12196 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1179" d="m12109 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1181" d="m12022 636.14h-53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path1183" d="m11936 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1185" d="m11850 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1187" d="m11762 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1189" d="m11676 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1191" d="m11589 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1193" d="m11502 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1195" d="m11415 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1197" d="m11329 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
+id="path1199" d="m11243 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1201" d="m11155 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1203" d="m11069 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1205" d="m10982 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1207" d="m10895 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1209" d="m10808 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1211" d="m10722 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1213" d="m10636 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1215" d="m10548 636.14h-53.795"
+fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1217" d="m10462 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1219" d="m10375 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1221" d="m10288 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1223" d="m10201 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1225" d="m10115 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1227" d="m10029 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1229" d="m9941.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1231" d="m9855 636.14h-53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path1233" d="m9767.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1235" d="m9681.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1237" d="m9594.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1239" d="m9507.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1241" d="m9421.6 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1243" d="m9334.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1245" d="m9248.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1247" d="m9160.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432"
+style=""/><path id="path1249" d="m9074.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1251" d="m8987.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1253" d="m8900.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1255" d="m8814.7 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1257" d="m8727.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1259" d="m8641.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1261" d="m8553.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1263" d="m8467.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1265"
+d="m8380.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1267" d="m8294 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1269" d="m8207.7 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1271" d="m8120.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1273" d="m8034.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1275" d="m7946.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1277" d="m7860.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1279" d="m7773.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1281" d="m7687 636.14h-53.795" fill="none"
+stroke="#3465af" stroke-width="28.432" style=""/><path id="path1283" d="m7599.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1285" d="m7513.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1287" d="m7427.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1289" d="m7339.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1291" d="m7253.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1293" d="m7166.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1295" d="m7080 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1297" d="m6992.7 636.14h-53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path1299" d="m6906.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1301" d="m6820.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1303" d="m6732.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1305" d="m6646.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1307" d="m6559.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1309" d="m6473.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1311" d="m6385.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1313" d="m6299.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432"
+style=""/><path id="path1315" d="m6213.2 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1317" d="m6125.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1319" d="m6039.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1321" d="m5952.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1323" d="m5866.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1325" d="m5778.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1327" d="m5692.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1329" d="m5606.2 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1331"
+d="m5519 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1333" d="m5432.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1335" d="m5345.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1337" d="m5259.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1339" d="m5171.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1341" d="m5085.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1343" d="m4999.3 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1345" d="m4912 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1347" d="m4825.7 636.14h-53.795" fill="none"
+stroke="#3465af" stroke-width="28.432" style=""/><path id="path1349" d="m4738.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1351" d="m4652.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1353" d="m4564.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1355" d="m4478.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1357" d="m4392.3 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1359" d="m4305 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1361" d="m4218.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1363" d="m4131.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432"
+style=""/><path id="path1365" d="m4045.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1367" d="m3957.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1369" d="m3871.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1371" d="m3785.3 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1373" d="m3698 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1375" d="m3611.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1377" d="m3524.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1379" d="m3438.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1381"
+d="m3350.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1383" d="m3264.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1385" d="m3177.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1387" d="m3091.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1389" d="m3004.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1391" d="m2917.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1393" d="m2831.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1395" d="m2743.9 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1397" d="m2657.7 636.14h-53.795"
+fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1399" d="m2570.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1401" d="m2484.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1403" d="m2397.8 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1405" d="m2310.5 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1407" d="m2224.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1409" d="m2137 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1411" d="m2050.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1413" d="m1963.4 636.14h-53.795" fill="none" stroke="#3465af"
+stroke-width="28.432" style=""/><path id="path1415" d="m1877.1 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1417" d="m1790.9 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1419" d="m1703.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1421" d="m1617.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1423" d="m1530 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1425" d="m1443.7 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1427" d="m1356.4 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1429" d="m1270.2 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path
+id="path1431" d="m1183.9 636.14h-54.81" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1433" d="m1096.6 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1435" d="m1010.3 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><path id="path1437" d="m923.03 636.14h-53.795" fill="none" stroke="#3465af" stroke-width="28.432" style=""/><g id="g4044" style=""><rect id="rect1441" x="21109" y="4753.1" width="1213.6" height="1100.7" fill="#f3e777" style=""/><path id="path1443" d="m20656 5536.4v-405.46l150.7-169.16c82.886-93.039 170.53-186.62 194.77-207.96l44.069-38.798 783.23-0.086 783.23-0.086v1227h-1956v-405.46zm1027.7 136.98v-78.372l-169.91 4.925-169.91 4.9249-5.09 45.854c-8.249 74.303 46.711 101.04 207.69 101.04h137.21v-78.372zm235.86-262.94 4.495-341.31 207.2-8.6408 207.2-8.6408
+5.144-46.443c9.596-86.615-41.863-102.05-322.02-96.607l-246.71 4.7956-4.438 419.08-4.439 419.08h149.08l4.494-341.31zm391.3 313.72c26.41-19.286 36.255-41.399 32.697-73.447l-5.09-45.854h-348.1l-5.38 48.984c-9.97 90.771 0.993 97.91 150.36 97.91 99.305 0 148.27-7.6982 175.52-27.594zm-627.16-274.84v-77.768h-348.1v66.246c0 36.436 4.973 71.431 11.051 77.768 6.078 6.3366 84.401 11.521 174.05 11.521h163v-77.768zm659.89-4.9154 5.125-74.042-179.18 4.9155-179.18 4.9155-5.38 48.984c-10.473 95.348-2.259 99.57 183.28 94.197l170.2-4.9284 5.125-74.042zm-659.89-237.63v-78.372l-169.91 4.925-169.91 4.925-5.097 73.447-5.097 73.447h350v-78.372zm659.86 4.925-5.097-73.447h-348.1l-5.38 48.984c-10.289 93.673-2.146 97.91 188.15 97.91h175.52l-5.097-73.447zm-659.86-228.98v-77.768h-137.21c-97.358 0-147.91 7.8138-174.05 26.902-34.952 25.523-49.645 92.242-25.79 117.11 6.078 6.3366 84.401 11.521 174.05
+11.521h163v-77.768z" fill="#ca4677" style=""/></g><text id="text1489" class="TextShape" transform="scale(1.1036 .90616)" x="171.41566" y="9913.7109" fill-rule="evenodd" font-family="Serif, serif" font-size="493.87px" stroke-linejoin="round" stroke-width="28.222"><tspan id="tspan1491" class="TextParagraph" font-family="Serif, serif" font-size="493.87px"/></text>
+<g id="g4048" style=""><rect id="rect1447" x="18797" y="13737" width="2320.7" height="2342.4" fill="#6076b3" style=""/><rect id="rect1451" x="18532" y="13817" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1453" x="18532" y="14076" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1455" x="18532" y="14334" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1457" x="18532" y="14593" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1459" x="18532" y="14851" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round"
+stroke-width="28.222" style=""/><rect id="rect1461" x="18532" y="15110" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1463" x="18532" y="15368" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1465" x="18532" y="15626" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1467" x="18532" y="15884" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1469" x="21080" y="13783" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1471" x="21080" y="14041" width="302.7"
+height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1473" x="21080" y="14299" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1475" x="21080" y="14558" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1477" x="21080" y="14816" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1479" x="21080" y="15075" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1481" x="21080" y="15333" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round"
+stroke-width="28.222" style=""/><rect id="rect1483" x="21080" y="15592" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><rect id="rect1485" x="21080" y="15850" width="302.7" height="137.79" fill="#e0ee2c" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><text id="text1493" transform="scale(1.1036 .90616)" x="17205.688" y="16777.641" fill="#000000" fill-rule="evenodd" font-family="Sans" font-size="856.96px" letter-spacing="0px" stroke-linejoin="round" stroke-width="28.222" word-spacing="0px" style="line-height:125%" line-height="125%" xml:space="preserve"><tspan id="tspan1495" x="17205.688" y="16777.641" style="">CPU</tspan></text>
+</g><text id="text1499" class="TextShape" x="-11700.553" y="565.61298" fill-rule="evenodd" font-family="Serif, serif" font-size="493.88px" stroke-linejoin="round" stroke-width="28.222"><tspan id="tspan1501" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1503" class="TextPosition" transform="matrix(0,-1,1,0,8509,40173)" x="12640.447" y="16397.613" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1505" fill="#000000" font-family="Serif, serif" font-size="493.88px">PCI, USB, SPI, I2C, ...</tspan></tspan></tspan></text>
+<path id="path1511" d="m12408 15562h-1115.1v-1420.3h2230.2v1420.3h-1115.1z" fill="#cfe7f5" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" style=""/><path id="path1513" d="m12408 15562h-1115.1v-1420.3h2230.2v1420.3h-1115.1z" fill="none" stroke="#3465af" stroke-linejoin="round" stroke-width="19.847" style=""/><text id="text1515" class="TextShape" x="-1394.0863" y="590.73016" fill-rule="evenodd" font-family="Serif, serif" font-size="493.88px" stroke-linejoin="round" stroke-width="28.222"><tspan id="tspan1517" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1519" class="TextPosition" x="11487.915" y="14672.743" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1521" fill="#000000" font-family="Serif, serif" font-size="493.88px">Bridge</tspan></tspan></tspan></text>
+<text id="text1523" class="TextShape" x="-1450.5308" y="1324.5078" fill-rule="evenodd" font-family="Serif, serif" font-size="493.88px" stroke-linejoin="round" stroke-width="28.222"><tspan id="tspan1525" class="TextParagraph" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1527" class="TextPosition" x="11431.471" y="15406.52" font-family="Serif, serif" font-size="493.88px"><tspan id="tspan1529" fill="#000000" font-family="Serif, serif" font-size="493.88px"> DMA</tspan></tspan></tspan></text>
+</svg>
diff --git a/Documentation/media/uapi/dvb/dvbstb.svg b/Documentation/media/uapi/dvb/dvbstb.svg
index c4140fb518af..4effe45b448d 100644
--- a/Documentation/media/uapi/dvb/dvbstb.svg
+++ b/Documentation/media/uapi/dvb/dvbstb.svg
@@ -1,651 +1,17 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- version="1.2"
- width="237.70221mm"
- height="126.28221mm"
- viewBox="0 0 23770.221 12628.221"
- preserveAspectRatio="xMidYMid"
- xml:space="preserve"
- id="svg2"
- inkscape:version="0.91 r13725"
- sodipodi:docname="dvbstb.svg"
- style="fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round"><metadata
- id="metadata519"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1920"
- inkscape:window-height="997"
- id="namedview517"
- showgrid="false"
- inkscape:zoom="1.0818519"
- inkscape:cx="411.31718"
- inkscape:cy="274.87517"
- inkscape:window-x="1920"
- inkscape:window-y="30"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg2"
- fit-margin-top="0"
- fit-margin-left="0"
- fit-margin-right="0"
- fit-margin-bottom="0" /><defs
- class="ClipPathGroup"
- id="defs4" /><defs
- id="defs9" /><defs
- id="defs90" /><defs
- id="defs113" /><defs
- class="TextShapeIndex"
- id="defs124" /><defs
- class="EmbeddedBulletChars"
- id="defs128" /><defs
- class="TextEmbeddedBitmaps"
- id="defs157" /><rect
- class="BoundingBox"
- x="5355.1108"
- y="13.111"
- width="18403"
- height="9603"
- id="rect197"
- style="fill:none;stroke:none" /><path
- d="m 14556.111,9614.111 -9200,0 0,-9600 18400,0 0,9600 -9200,0 z"
- id="path199"
- inkscape:connector-curvature="0"
- style="fill:#ffffff;stroke:none" /><path
- d="m 14556.111,9614.111 -9200,0 0,-9600 18400,0 0,9600 -9200,0 z"
- id="path201"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><rect
- class="BoundingBox"
- x="13.111"
- y="4013.1111"
- width="4544"
- height="2403"
- id="rect206"
- style="fill:none;stroke:none" /><path
- d="m 2285.111,6414.111 -2271,0 0,-2400 4541,0 0,2400 -2270,0 z"
- id="path208"
- inkscape:connector-curvature="0"
- style="fill:#ffffff;stroke:none" /><path
- d="m 2285.111,6414.111 -2271,0 0,-2400 4541,0 0,2400 -2270,0 z"
- id="path210"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><text
- class="TextShape"
- id="text212"
- y="-4585.8892"
- x="-2443.8889"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan214"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="1281.111"
- y="5435.1108"
- id="tspan216"><tspan
- id="tspan218"
- style="fill:#000000;stroke:none">Antena</tspan></tspan></tspan></text>
-<rect
- class="BoundingBox"
- x="6213.1108"
- y="1813.111"
- width="4544"
- height="2403"
- id="rect223"
- style="fill:none;stroke:none" /><path
- d="m 8485.111,4214.111 -2271,0 0,-2400 4541,0 0,2400 -2270,0 z"
- id="path225"
- inkscape:connector-curvature="0"
- style="fill:#ffffff;stroke:none" /><path
- d="m 8485.111,4214.111 -2271,0 0,-2400 4541,0 0,2400 -2270,0 z"
- id="path227"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><text
- class="TextShape"
- id="text229"
- x="-2443.8889"
- y="-4585.8892"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan231"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="7217.1108"
- y="3235.1111"
- id="tspan233"><tspan
- id="tspan235"
- style="fill:#000000;stroke:none">Frontend</tspan></tspan></tspan></text>
-<rect
- class="BoundingBox"
- x="12113.111"
- y="1813.111"
- width="4544"
- height="2403"
- id="rect240"
- style="fill:none;stroke:none" /><path
- d="m 14385.111,4214.111 -2271,0 0,-2400 4541,0 0,2400 -2270,0 z"
- id="path242"
- inkscape:connector-curvature="0"
- style="fill:#ffffff;stroke:none" /><path
- d="m 14385.111,4214.111 -2271,0 0,-2400 4541,0 0,2400 -2270,0 z"
- id="path244"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><text
- class="TextShape"
- id="text246"
- x="-2443.8889"
- y="-4585.8892"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan248"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="13944.111"
- y="3235.1111"
- id="tspan250"><tspan
- id="tspan252"
- style="fill:#000000;stroke:none">CA</tspan></tspan></tspan></text>
-<rect
- class="BoundingBox"
- x="18113.111"
- y="1813.111"
- width="4544"
- height="2403"
- id="rect257"
- style="fill:none;stroke:none" /><path
- d="m 20385.111,4214.111 -2271,0 0,-2400 4541,0 0,2400 -2270,0 z"
- id="path259"
- inkscape:connector-curvature="0"
- style="fill:#ffffff;stroke:none" /><path
- d="m 20385.111,4214.111 -2271,0 0,-2400 4541,0 0,2400 -2270,0 z"
- id="path261"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><text
- class="TextShape"
- id="text263"
- x="-2443.8889"
- y="-4585.8892"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan265"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="19384.111"
- y="3235.1111"
- id="tspan267"><tspan
- id="tspan269"
- style="fill:#000000;stroke:none">Demux</tspan></tspan></tspan></text>
-<rect
- class="BoundingBox"
- x="6113.1108"
- y="5813.1108"
- width="4544"
- height="2403"
- id="rect274"
- style="fill:none;stroke:none" /><path
- d="m 8385.111,8214.111 -2271,0 0,-2400 4541,0 0,2400 -2270,0 z"
- id="path276"
- inkscape:connector-curvature="0"
- style="fill:#ffffff;stroke:none" /><path
- d="m 8385.111,8214.111 -2271,0 0,-2400 4541,0 0,2400 -2270,0 z"
- id="path278"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><text
- class="TextShape"
- id="text280"
- x="-2443.8889"
- y="-4585.8892"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan282"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="7733.1108"
- y="7235.1108"
- id="tspan284"><tspan
- id="tspan286"
- style="fill:#000000;stroke:none">SEC</tspan></tspan></tspan></text>
-<rect
- class="BoundingBox"
- x="12213.111"
- y="5813.1108"
- width="4544"
- height="2403"
- id="rect291"
- style="fill:none;stroke:none" /><path
- d="m 14485.111,8214.111 -2271,0 0,-2400 4541,0 0,2400 -2270,0 z"
- id="path293"
- inkscape:connector-curvature="0"
- style="fill:#ffffff;stroke:none" /><path
- d="m 14485.111,8214.111 -2271,0 0,-2400 4541,0 0,2400 -2270,0 z"
- id="path295"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><text
- class="TextShape"
- id="text297"
- x="-2443.8889"
- y="-4585.8892"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan299"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="13676.111"
- y="7235.1108"
- id="tspan301"><tspan
- id="tspan303"
- style="fill:#000000;stroke:none">Audio</tspan></tspan></tspan></text>
-<rect
- class="BoundingBox"
- x="18113.111"
- y="5813.1108"
- width="4544"
- height="2403"
- id="rect308"
- style="fill:none;stroke:none" /><path
- d="m 20385.111,8214.111 -2271,0 0,-2400 4541,0 0,2400 -2270,0 z"
- id="path310"
- inkscape:connector-curvature="0"
- style="fill:#ffffff;stroke:none" /><path
- d="m 20385.111,8214.111 -2271,0 0,-2400 4541,0 0,2400 -2270,0 z"
- id="path312"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><text
- class="TextShape"
- id="text314"
- x="-2443.8889"
- y="-4585.8892"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan316"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="19583.111"
- y="7235.1108"
- id="tspan318"><tspan
- id="tspan320"
- style="fill:#000000;stroke:none">Video</tspan></tspan></tspan></text>
-<rect
- class="BoundingBox"
- x="15213.111"
- y="10213.111"
- width="4544"
- height="2403"
- id="rect325"
- style="fill:none;stroke:none" /><path
- d="m 17485.111,12614.111 -2271,0 0,-2400 4541,0 0,2400 -2270,0 z"
- id="path327"
- inkscape:connector-curvature="0"
- style="fill:#ffffff;stroke:none" /><path
- d="m 17485.111,12614.111 -2271,0 0,-2400 4541,0 0,2400 -2270,0 z"
- id="path329"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><text
- class="TextShape"
- id="text331"
- x="-2443.8889"
- y="-4585.8892"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan333"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="17076.111"
- y="11635.111"
- id="tspan335"><tspan
- id="tspan337"
- style="fill:#000000;stroke:none">TV</tspan></tspan></tspan></text>
-<rect
- class="BoundingBox"
- x="4555.1108"
- y="3014.1111"
- width="1661"
- height="2202"
- id="rect342"
- style="fill:none;stroke:none" /><path
- d="m 4556.111,5214.111 1400,-1857"
- id="path344"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 6215.111,3014.111 -391,269 240,181 151,-450 z"
- id="path346"
- inkscape:connector-curvature="0"
- style="fill:#000000;stroke:none" /><rect
- class="BoundingBox"
- x="4555.1108"
- y="5213.1108"
- width="1561"
- height="1802"
- id="rect351"
- style="fill:none;stroke:none" /><path
- d="m 4556.111,5214.111 1277,1475"
- id="path353"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 6115.111,7014.111 -181,-438 -227,196 408,242 z"
- id="path355"
- inkscape:connector-curvature="0"
- style="fill:#000000;stroke:none" /><rect
- class="BoundingBox"
- x="10755.111"
- y="2864.1111"
- width="1361"
- height="301"
- id="rect360"
- style="fill:none;stroke:none" /><path
- d="m 10756.111,3014.111 929,0"
- id="path362"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 12115.111,3014.111 -450,-150 0,300 450,-150 z"
- id="path364"
- inkscape:connector-curvature="0"
- style="fill:#000000;stroke:none" /><rect
- class="BoundingBox"
- x="16655.111"
- y="2864.1111"
- width="1461"
- height="301"
- id="rect369"
- style="fill:none;stroke:none" /><path
- d="m 16656.111,3014.111 1029,0"
- id="path371"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 18115.111,3014.111 -450,-150 0,300 450,-150 z"
- id="path373"
- inkscape:connector-curvature="0"
- style="fill:#000000;stroke:none" /><rect
- class="BoundingBox"
- x="20235.111"
- y="4213.1108"
- width="301"
- height="1602"
- id="rect378"
- style="fill:none;stroke:none" /><path
- d="m 20385.111,4214.111 0,1170"
- id="path380"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 20385.111,5814.111 150,-450 -300,0 150,450 z"
- id="path382"
- inkscape:connector-curvature="0"
- style="fill:#000000;stroke:none" /><rect
- class="BoundingBox"
- x="17485.111"
- y="8213.1113"
- width="2902"
- height="2002"
- id="rect387"
- style="fill:none;stroke:none" /><path
- d="m 20385.111,8214.111 -2546,1756"
- id="path389"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 17485.111,10214.111 456,-132 -171,-247 -285,379 z"
- id="path391"
- inkscape:connector-curvature="0"
- style="fill:#000000;stroke:none" /><rect
- class="BoundingBox"
- x="14484.111"
- y="8213.1113"
- width="3002"
- height="2002"
- id="rect396"
- style="fill:none;stroke:none" /><path
- d="m 14485.111,8214.111 2642,1761"
- id="path398"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 17485.111,10214.111 -291,-374 -167,249 458,125 z"
- id="path400"
- inkscape:connector-curvature="0"
- style="fill:#000000;stroke:none" /><rect
- class="BoundingBox"
- x="14485.111"
- y="4213.1108"
- width="5902"
- height="1629"
- id="rect405"
- style="fill:none;stroke:none" /><path
- d="m 20385.111,4214.111 -51,14"
- id="path407"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 20283.111,4242.111 -52,14"
- id="path409"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 20180.111,4270.111 -51,13"
- id="path411"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 20078.111,4297.111 -52,14"
- id="path413"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 19975.111,4325.111 -51,14"
- id="path415"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 19873.111,4353.111 -52,14"
- id="path417"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 19770.111,4381.111 -51,14"
- id="path419"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 19668.111,4409.111 -52,13"
- id="path421"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 19565.111,4436.111 -51,14"
- id="path423"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 19463.111,4464.111 -52,14"
- id="path425"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 19360.111,4492.111 -51,14"
- id="path427"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 19258.111,4520.111 -52,14"
- id="path429"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 19155.111,4547.111 -51,14"
- id="path431"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 19053.111,4575.111 -52,14"
- id="path433"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 18950.111,4603.111 -51,14"
- id="path435"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 18848.111,4631.111 -51,14"
- id="path437"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 18745.111,4659.111 -51,14"
- id="path439"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 18643.111,4686.111 -51,14"
- id="path441"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 18540.111,4714.111 -51,14"
- id="path443"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 18438.111,4742.111 -51,14"
- id="path445"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 18335.111,4770.111 -51,14"
- id="path447"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 18233.111,4798.111 -51,14"
- id="path449"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 18130.111,4825.111 -51,14"
- id="path451"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 18028.111,4853.111 -51,14"
- id="path453"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 17925.111,4881.111 -51,14"
- id="path455"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 17823.111,4909.111 -51,14"
- id="path457"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 17720.111,4937.111 -51,13"
- id="path459"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 17618.111,4964.111 -51,14"
- id="path461"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 17516.111,4992.111 -52,14"
- id="path463"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 17413.111,5020.111 -51,14"
- id="path465"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 17311.111,5048.111 -52,14"
- id="path467"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 17208.111,5076.111 -51,13"
- id="path469"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 17106.111,5103.111 -52,14"
- id="path471"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 17003.111,5131.111 -51,14"
- id="path473"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 16901.111,5159.111 -52,14"
- id="path475"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 16798.111,5187.111 -51,14"
- id="path477"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 16696.111,5214.111 -52,14"
- id="path479"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 16593.111,5242.111 -51,14"
- id="path481"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 16491.111,5270.111 -52,14"
- id="path483"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 16388.111,5298.111 -51,14"
- id="path485"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 16286.111,5326.111 -52,14"
- id="path487"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 16183.111,5353.111 -51,14"
- id="path489"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 16081.111,5381.111 -51,14"
- id="path491"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 15978.111,5409.111 -51,14"
- id="path493"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 15876.111,5437.111 -51,14"
- id="path495"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 15773.111,5465.111 -51,14"
- id="path497"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 15671.111,5492.111 -51,14"
- id="path499"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 15568.111,5520.111 -51,14"
- id="path501"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 15466.111,5548.111 -51,14"
- id="path503"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 15363.111,5576.111 -51,14"
- id="path505"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 15261.111,5604.111 -51,13"
- id="path507"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 15158.111,5631.111 -51,14"
- id="path509"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 15056.111,5659.111 -51,14"
- id="path511"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 14953.111,5687.111 -51,14"
- id="path513"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000" /><path
- d="m 14485.111,5814.111 474,27 -79,-290 -395,263 z"
- id="path515"
- inkscape:connector-curvature="0"
- style="fill:#000000;stroke:none" /></svg> \ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?>
+<svg id="svg2" width="237.7mm" height="126.28mm" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" preserveAspectRatio="xMidYMid" version="1.2" viewBox="0 0 23770.221 12628.221" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata id="metadata519"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><rect id="rect197" class="BoundingBox" x="5355.1" y="13.111" width="18403" height="9603" fill="none"/><path id="path199" d="m14556 9614.1h-9200v-9600h18400v9600h-9200z" fill="#fff"/><path id="path201" d="m14556 9614.1h-9200v-9600h18400v9600h-9200z" fill="none" stroke="#000"/><rect id="rect206"
+class="BoundingBox" x="13.111" y="4013.1" width="4544" height="2403" fill="none"/><path id="path208" d="m2285.1 6414.1h-2271v-2400h4541v2400h-2270z" fill="#fff"/><path id="path210" d="m2285.1 6414.1h-2271v-2400h4541v2400h-2270z" fill="none" stroke="#000"/><text id="text212" class="TextShape" x="-2443.8889" y="-4585.8892"><tspan id="tspan214" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan216" class="TextPosition" x="1281.111" y="5435.1108"><tspan id="tspan218" fill="#000000">Antena</tspan></tspan></tspan></text>
+<rect id="rect223" class="BoundingBox" x="6213.1" y="1813.1" width="4544" height="2403" fill="none"/><path id="path225" d="m8485.1 4214.1h-2271v-2400h4541v2400h-2270z" fill="#fff"/><path id="path227" d="m8485.1 4214.1h-2271v-2400h4541v2400h-2270z" fill="none" stroke="#000"/><text id="text229" class="TextShape" x="-2443.8889" y="-4585.8892"><tspan id="tspan231" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan233" class="TextPosition" x="7217.1108" y="3235.1111"><tspan id="tspan235" fill="#000000">Frontend</tspan></tspan></tspan></text>
+<rect id="rect240" class="BoundingBox" x="12113" y="1813.1" width="4544" height="2403" fill="none"/><path id="path242" d="m14385 4214.1h-2271v-2400h4541v2400h-2270z" fill="#fff"/><path id="path244" d="m14385 4214.1h-2271v-2400h4541v2400h-2270z" fill="none" stroke="#000"/><text id="text246" class="TextShape" x="-2443.8889" y="-4585.8892"><tspan id="tspan248" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan250" class="TextPosition" x="13944.111" y="3235.1111"><tspan id="tspan252" fill="#000000">CA</tspan></tspan></tspan></text>
+<rect id="rect257" class="BoundingBox" x="18113" y="1813.1" width="4544" height="2403" fill="none"/><path id="path259" d="m20385 4214.1h-2271v-2400h4541v2400h-2270z" fill="#fff"/><path id="path261" d="m20385 4214.1h-2271v-2400h4541v2400h-2270z" fill="none" stroke="#000"/><text id="text263" class="TextShape" x="-2443.8889" y="-4585.8892"><tspan id="tspan265" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan267" class="TextPosition" x="19384.111" y="3235.1111"><tspan id="tspan269" fill="#000000">Demux</tspan></tspan></tspan></text>
+<rect id="rect274" class="BoundingBox" x="6113.1" y="5813.1" width="4544" height="2403" fill="none"/><path id="path276" d="m8385.1 8214.1h-2271v-2400h4541v2400h-2270z" fill="#fff"/><path id="path278" d="m8385.1 8214.1h-2271v-2400h4541v2400h-2270z" fill="none" stroke="#000"/><text id="text280" class="TextShape" x="-2443.8889" y="-4585.8892"><tspan id="tspan282" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan284" class="TextPosition" x="7733.1108" y="7235.1108"><tspan id="tspan286" fill="#000000">SEC</tspan></tspan></tspan></text>
+<rect id="rect291" class="BoundingBox" x="12213" y="5813.1" width="4544" height="2403" fill="none"/><path id="path293" d="m14485 8214.1h-2271v-2400h4541v2400h-2270z" fill="#fff"/><path id="path295" d="m14485 8214.1h-2271v-2400h4541v2400h-2270z" fill="none" stroke="#000"/><text id="text297" class="TextShape" x="-2443.8889" y="-4585.8892"><tspan id="tspan299" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan301" class="TextPosition" x="13676.111" y="7235.1108"><tspan id="tspan303" fill="#000000">Audio</tspan></tspan></tspan></text>
+<rect id="rect308" class="BoundingBox" x="18113" y="5813.1" width="4544" height="2403" fill="none"/><path id="path310" d="m20385 8214.1h-2271v-2400h4541v2400h-2270z" fill="#fff"/><path id="path312" d="m20385 8214.1h-2271v-2400h4541v2400h-2270z" fill="none" stroke="#000"/><text id="text314" class="TextShape" x="-2443.8889" y="-4585.8892"><tspan id="tspan316" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan318" class="TextPosition" x="19583.111" y="7235.1108"><tspan id="tspan320" fill="#000000">Video</tspan></tspan></tspan></text>
+<rect id="rect325" class="BoundingBox" x="15213" y="10213" width="4544" height="2403" fill="none"/><path id="path327" d="m17485 12614h-2271v-2400h4541v2400h-2270z" fill="#fff"/><path id="path329" d="m17485 12614h-2271v-2400h4541v2400h-2270z" fill="none" stroke="#000"/><text id="text331" class="TextShape" x="-2443.8889" y="-4585.8892"><tspan id="tspan333" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan335" class="TextPosition" x="17076.111" y="11635.111"><tspan id="tspan337" fill="#000000">TV</tspan></tspan></tspan></text>
+<rect id="rect342" class="BoundingBox" x="4555.1" y="3014.1" width="1661" height="2202" fill="none"/><path id="path344" d="m4556.1 5214.1 1400-1857" fill="none" stroke="#000"/><path id="path346" d="m6215.1 3014.1-391 269 240 181 151-450z"/><rect id="rect351" class="BoundingBox" x="4555.1" y="5213.1" width="1561" height="1802" fill="none"/><path id="path353" d="m4556.1 5214.1 1277 1475" fill="none" stroke="#000"/><path id="path355" d="m6115.1 7014.1-181-438-227 196 408 242z"/><rect id="rect360" class="BoundingBox" x="10755" y="2864.1" width="1361" height="301" fill="none"/><path id="path362" d="m10756 3014.1h929" fill="none" stroke="#000"/><path id="path364" d="m12115 3014.1-450-150v300l450-150z"/><rect id="rect369" class="BoundingBox" x="16655" y="2864.1" width="1461" height="301" fill="none"/><path id="path371" d="m16656 3014.1h1029" fill="none" stroke="#000"/><path id="path373"
+d="m18115 3014.1-450-150v300l450-150z"/><rect id="rect378" class="BoundingBox" x="20235" y="4213.1" width="301" height="1602" fill="none"/><path id="path380" d="m20385 4214.1v1170" fill="none" stroke="#000"/><path id="path382" d="m20385 5814.1 150-450h-300l150 450z"/><rect id="rect387" class="BoundingBox" x="17485" y="8213.1" width="2902" height="2002" fill="none"/><path id="path389" d="m20385 8214.1-2546 1756" fill="none" stroke="#000"/><path id="path391" d="m17485 10214 456-132-171-247-285 379z"/><rect id="rect396" class="BoundingBox" x="14484" y="8213.1" width="3002" height="2002" fill="none"/><path id="path398" d="m14485 8214.1 2642 1761" fill="none" stroke="#000"/><path id="path400" d="m17485 10214-291-374-167 249 458 125z"/><rect id="rect405" class="BoundingBox" x="14485" y="4213.1" width="5902" height="1629" fill="none"/><path id="path407" d="m20385 4214.1-51 14" fill="none"
+stroke="#000"/><path id="path409" d="m20283 4242.1-52 14" fill="none" stroke="#000"/><path id="path411" d="m20180 4270.1-51 13" fill="none" stroke="#000"/><path id="path413" d="m20078 4297.1-52 14" fill="none" stroke="#000"/><path id="path415" d="m19975 4325.1-51 14" fill="none" stroke="#000"/><path id="path417" d="m19873 4353.1-52 14" fill="none" stroke="#000"/><path id="path419" d="m19770 4381.1-51 14" fill="none" stroke="#000"/><path id="path421" d="m19668 4409.1-52 13" fill="none" stroke="#000"/><path id="path423" d="m19565 4436.1-51 14" fill="none" stroke="#000"/><path id="path425" d="m19463 4464.1-52 14" fill="none" stroke="#000"/><path id="path427" d="m19360 4492.1-51 14" fill="none" stroke="#000"/><path id="path429" d="m19258 4520.1-52 14" fill="none" stroke="#000"/><path id="path431" d="m19155 4547.1-51 14" fill="none" stroke="#000"/><path id="path433" d="m19053 4575.1-52 14"
+fill="none" stroke="#000"/><path id="path435" d="m18950 4603.1-51 14" fill="none" stroke="#000"/><path id="path437" d="m18848 4631.1-51 14" fill="none" stroke="#000"/><path id="path439" d="m18745 4659.1-51 14" fill="none" stroke="#000"/><path id="path441" d="m18643 4686.1-51 14" fill="none" stroke="#000"/><path id="path443" d="m18540 4714.1-51 14" fill="none" stroke="#000"/><path id="path445" d="m18438 4742.1-51 14" fill="none" stroke="#000"/><path id="path447" d="m18335 4770.1-51 14" fill="none" stroke="#000"/><path id="path449" d="m18233 4798.1-51 14" fill="none" stroke="#000"/><path id="path451" d="m18130 4825.1-51 14" fill="none" stroke="#000"/><path id="path453" d="m18028 4853.1-51 14" fill="none" stroke="#000"/><path id="path455" d="m17925 4881.1-51 14" fill="none" stroke="#000"/><path id="path457" d="m17823 4909.1-51 14" fill="none" stroke="#000"/><path id="path459" d="m17720
+4937.1-51 13" fill="none" stroke="#000"/><path id="path461" d="m17618 4964.1-51 14" fill="none" stroke="#000"/><path id="path463" d="m17516 4992.1-52 14" fill="none" stroke="#000"/><path id="path465" d="m17413 5020.1-51 14" fill="none" stroke="#000"/><path id="path467" d="m17311 5048.1-52 14" fill="none" stroke="#000"/><path id="path469" d="m17208 5076.1-51 13" fill="none" stroke="#000"/><path id="path471" d="m17106 5103.1-52 14" fill="none" stroke="#000"/><path id="path473" d="m17003 5131.1-51 14" fill="none" stroke="#000"/><path id="path475" d="m16901 5159.1-52 14" fill="none" stroke="#000"/><path id="path477" d="m16798 5187.1-51 14" fill="none" stroke="#000"/><path id="path479" d="m16696 5214.1-52 14" fill="none" stroke="#000"/><path id="path481" d="m16593 5242.1-51 14" fill="none" stroke="#000"/><path id="path483" d="m16491 5270.1-52 14" fill="none" stroke="#000"/><path id="path485"
+d="m16388 5298.1-51 14" fill="none" stroke="#000"/><path id="path487" d="m16286 5326.1-52 14" fill="none" stroke="#000"/><path id="path489" d="m16183 5353.1-51 14" fill="none" stroke="#000"/><path id="path491" d="m16081 5381.1-51 14" fill="none" stroke="#000"/><path id="path493" d="m15978 5409.1-51 14" fill="none" stroke="#000"/><path id="path495" d="m15876 5437.1-51 14" fill="none" stroke="#000"/><path id="path497" d="m15773 5465.1-51 14" fill="none" stroke="#000"/><path id="path499" d="m15671 5492.1-51 14" fill="none" stroke="#000"/><path id="path501" d="m15568 5520.1-51 14" fill="none" stroke="#000"/><path id="path503" d="m15466 5548.1-51 14" fill="none" stroke="#000"/><path id="path505" d="m15363 5576.1-51 14" fill="none" stroke="#000"/><path id="path507" d="m15261 5604.1-51 13" fill="none" stroke="#000"/><path id="path509" d="m15158 5631.1-51 14" fill="none" stroke="#000"/><path
+id="path511" d="m15056 5659.1-51 14" fill="none" stroke="#000"/><path id="path513" d="m14953 5687.1-51 14" fill="none" stroke="#000"/><path id="path515" d="m14485 5814.1 474 27-79-290-395 263z"/></svg>
diff --git a/Documentation/media/uapi/v4l/bayer.svg b/Documentation/media/uapi/v4l/bayer.svg
index fbd4cfb5e6bf..c395113d1876 100644
--- a/Documentation/media/uapi/v4l/bayer.svg
+++ b/Documentation/media/uapi/v4l/bayer.svg
@@ -1,984 +1,29 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- version="1.2"
- width="164.15334mm"
- height="46.771107mm"
- viewBox="0 0 16415.333 4677.1107"
- preserveAspectRatio="xMidYMid"
- xml:space="preserve"
- id="svg2"
- inkscape:version="0.91 r13725"
- sodipodi:docname="bayer.svg"
- style="fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round"><metadata
- id="metadata652"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1920"
- inkscape:window-height="997"
- id="namedview650"
- showgrid="false"
- fit-margin-top="0"
- fit-margin-left="0"
- fit-margin-right="0"
- fit-margin-bottom="0"
- inkscape:zoom="2.4000866"
- inkscape:cx="290.82284"
- inkscape:cy="82.862197"
- inkscape:window-x="1920"
- inkscape:window-y="30"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg2" /><defs
- class="ClipPathGroup"
- id="defs4" /><defs
- id="defs9" /><defs
- id="defs82" /><defs
- id="defs105" /><defs
- class="TextShapeIndex"
- id="defs116" /><defs
- class="EmbeddedBulletChars"
- id="defs120" /><defs
- class="TextEmbeddedBitmaps"
- id="defs149" /><g
- class="com.sun.star.drawing.CustomShape"
- id="g186"
- transform="translate(-3285.889,-3185.889)"><g
- id="id6"><rect
- class="BoundingBox"
- x="3299"
- y="3199"
- width="1303"
- height="1203"
- id="rect189"
- style="fill:none;stroke:none" /><path
- d="m 3950,4400 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path191"
- inkscape:connector-curvature="0"
- style="fill:#0000ff;stroke:none" /><path
- d="m 3950,4400 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path193"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text195"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan197"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="3739"
- y="4021"
- id="tspan199"><tspan
- id="tspan201"
- style="fill:#ffffff;stroke:none">B</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g203"
- transform="translate(-3285.889,-3185.889)"><g
- id="id7"><rect
- class="BoundingBox"
- x="4599"
- y="3199"
- width="1303"
- height="1203"
- id="rect206"
- style="fill:none;stroke:none" /><path
- d="m 5250,4400 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path208"
- inkscape:connector-curvature="0"
- style="fill:#00cc00;stroke:none" /><path
- d="m 5250,4400 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path210"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text212"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan214"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="5003"
- y="4021"
- id="tspan216"><tspan
- id="tspan218"
- style="fill:#ffffff;stroke:none">G</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g220"
- transform="translate(-3285.889,-3185.889)"><g
- id="id8"><rect
- class="BoundingBox"
- x="3299"
- y="4399"
- width="1303"
- height="1203"
- id="rect223"
- style="fill:none;stroke:none" /><path
- d="m 3950,5600 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path225"
- inkscape:connector-curvature="0"
- style="fill:#00cc00;stroke:none" /><path
- d="m 3950,5600 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path227"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text229"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan231"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="3703"
- y="5221"
- id="tspan233"><tspan
- id="tspan235"
- style="fill:#ffffff;stroke:none">G</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g237"
- transform="translate(-3285.889,-3185.889)"><g
- id="id9"><rect
- class="BoundingBox"
- x="4599"
- y="4399"
- width="1303"
- height="1203"
- id="rect240"
- style="fill:none;stroke:none" /><path
- d="m 5250,5600 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path242"
- inkscape:connector-curvature="0"
- style="fill:#ff0000;stroke:none" /><path
- d="m 5250,5600 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path244"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text246"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan248"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="5022"
- y="5221"
- id="tspan250"><tspan
- id="tspan252"
- style="fill:#ffffff;stroke:none">R</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g254"
- transform="translate(-3285.889,-3185.889)"><g
- id="id10"><rect
- class="BoundingBox"
- x="5999"
- y="3299"
- width="1003"
- height="1003"
- id="rect257"
- style="fill:none;stroke:none" /><path
- d="m 6500,4300 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path259"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#0000ff" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g261"
- transform="translate(-3285.889,-3185.889)"><g
- id="id11"><rect
- class="BoundingBox"
- x="4699"
- y="5699"
- width="1003"
- height="1003"
- id="rect264"
- style="fill:none;stroke:none" /><path
- d="m 5200,6700 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path266"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#00cc00" /></g></g><g
- class="com.sun.star.drawing.TextShape"
- id="g268"
- transform="translate(-3285.889,-3185.889)"><g
- id="id12"><rect
- class="BoundingBox"
- x="4000"
- y="6900"
- width="2374"
- height="963"
- id="rect271"
- style="fill:none;stroke:none" /><text
- class="TextShape"
- id="text273"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan275"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="4250"
- y="7601"
- id="tspan277"><tspan
- id="tspan279"
- style="fill:#000000;stroke:none">BGGR</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g281"
- transform="translate(-3285.889,-3185.889)"><g
- id="id13"><rect
- class="BoundingBox"
- x="8799"
- y="3199"
- width="1303"
- height="1203"
- id="rect284"
- style="fill:none;stroke:none" /><path
- d="m 9450,4400 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path286"
- inkscape:connector-curvature="0"
- style="fill:#0000ff;stroke:none" /><path
- d="m 9450,4400 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path288"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text290"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan292"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="9239"
- y="4021"
- id="tspan294"><tspan
- id="tspan296"
- style="fill:#ffffff;stroke:none">B</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g298"
- transform="translate(-3285.889,-3185.889)"><g
- id="id14"><rect
- class="BoundingBox"
- x="7499"
- y="3199"
- width="1303"
- height="1203"
- id="rect301"
- style="fill:none;stroke:none" /><path
- d="m 8150,4400 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path303"
- inkscape:connector-curvature="0"
- style="fill:#00cc00;stroke:none" /><path
- d="m 8150,4400 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path305"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text307"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan309"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="7903"
- y="4021"
- id="tspan311"><tspan
- id="tspan313"
- style="fill:#ffffff;stroke:none">G</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g315"
- transform="translate(-3285.889,-3185.889)"><g
- id="id15"><rect
- class="BoundingBox"
- x="8799"
- y="4399"
- width="1303"
- height="1203"
- id="rect318"
- style="fill:none;stroke:none" /><path
- d="m 9450,5600 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path320"
- inkscape:connector-curvature="0"
- style="fill:#00cc00;stroke:none" /><path
- d="m 9450,5600 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path322"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text324"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan326"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="9203"
- y="5221"
- id="tspan328"><tspan
- id="tspan330"
- style="fill:#ffffff;stroke:none">G</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g332"
- transform="translate(-3285.889,-3185.889)"><g
- id="id16"><rect
- class="BoundingBox"
- x="7499"
- y="4399"
- width="1303"
- height="1203"
- id="rect335"
- style="fill:none;stroke:none" /><path
- d="m 8150,5600 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path337"
- inkscape:connector-curvature="0"
- style="fill:#ff0000;stroke:none" /><path
- d="m 8150,5600 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path339"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text341"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan343"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="7922"
- y="5221"
- id="tspan345"><tspan
- id="tspan347"
- style="fill:#ffffff;stroke:none">R</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.TextShape"
- id="g349"
- transform="translate(-3285.889,-3185.889)"><g
- id="id17"><rect
- class="BoundingBox"
- x="8200"
- y="6900"
- width="2374"
- height="963"
- id="rect352"
- style="fill:none;stroke:none" /><text
- class="TextShape"
- id="text354"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan356"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="8450"
- y="7601"
- id="tspan358"><tspan
- id="tspan360"
- style="fill:#000000;stroke:none">GBRG</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g362"
- transform="translate(-3285.889,-3185.889)"><g
- id="id18"><rect
- class="BoundingBox"
- x="17299"
- y="4399"
- width="1303"
- height="1203"
- id="rect365"
- style="fill:none;stroke:none" /><path
- d="m 17950,5600 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path367"
- inkscape:connector-curvature="0"
- style="fill:#0000ff;stroke:none" /><path
- d="m 17950,5600 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path369"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text371"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan373"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="17739"
- y="5221"
- id="tspan375"><tspan
- id="tspan377"
- style="fill:#ffffff;stroke:none">B</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g379"
- transform="translate(-3285.889,-3185.889)"><g
- id="id19"><rect
- class="BoundingBox"
- x="17299"
- y="3199"
- width="1303"
- height="1203"
- id="rect382"
- style="fill:none;stroke:none" /><path
- d="m 17950,4400 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path384"
- inkscape:connector-curvature="0"
- style="fill:#00cc00;stroke:none" /><path
- d="m 17950,4400 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path386"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text388"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan390"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="17703"
- y="4021"
- id="tspan392"><tspan
- id="tspan394"
- style="fill:#ffffff;stroke:none">G</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g396"
- transform="translate(-3285.889,-3185.889)"><g
- id="id20"><rect
- class="BoundingBox"
- x="15999"
- y="4399"
- width="1303"
- height="1203"
- id="rect399"
- style="fill:none;stroke:none" /><path
- d="m 16650,5600 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path401"
- inkscape:connector-curvature="0"
- style="fill:#00cc00;stroke:none" /><path
- d="m 16650,5600 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path403"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text405"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan407"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="16403"
- y="5221"
- id="tspan409"><tspan
- id="tspan411"
- style="fill:#ffffff;stroke:none">G</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g413"
- transform="translate(-3285.889,-3185.889)"><g
- id="id21"><rect
- class="BoundingBox"
- x="15999"
- y="3199"
- width="1303"
- height="1203"
- id="rect416"
- style="fill:none;stroke:none" /><path
- d="m 16650,4400 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path418"
- inkscape:connector-curvature="0"
- style="fill:#ff0000;stroke:none" /><path
- d="m 16650,4400 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path420"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text422"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan424"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="16422"
- y="4021"
- id="tspan426"><tspan
- id="tspan428"
- style="fill:#ffffff;stroke:none">R</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.TextShape"
- id="g430"
- transform="translate(-3285.889,-3185.889)"><g
- id="id22"><rect
- class="BoundingBox"
- x="16700"
- y="6900"
- width="2374"
- height="963"
- id="rect433"
- style="fill:none;stroke:none" /><text
- class="TextShape"
- id="text435"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan437"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="16950"
- y="7601"
- id="tspan439"><tspan
- id="tspan441"
- style="fill:#000000;stroke:none">RGGB</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g443"
- transform="translate(-3285.889,-3185.889)"><g
- id="id23"><rect
- class="BoundingBox"
- x="11699"
- y="4399"
- width="1303"
- height="1203"
- id="rect446"
- style="fill:none;stroke:none" /><path
- d="m 12350,5600 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path448"
- inkscape:connector-curvature="0"
- style="fill:#0000ff;stroke:none" /><path
- d="m 12350,5600 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path450"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text452"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan454"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="12139"
- y="5221"
- id="tspan456"><tspan
- id="tspan458"
- style="fill:#ffffff;stroke:none">B</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g460"
- transform="translate(-3285.889,-3185.889)"><g
- id="id24"><rect
- class="BoundingBox"
- x="11699"
- y="3199"
- width="1303"
- height="1203"
- id="rect463"
- style="fill:none;stroke:none" /><path
- d="m 12350,4400 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path465"
- inkscape:connector-curvature="0"
- style="fill:#00cc00;stroke:none" /><path
- d="m 12350,4400 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path467"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text469"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan471"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="12103"
- y="4021"
- id="tspan473"><tspan
- id="tspan475"
- style="fill:#ffffff;stroke:none">G</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g477"
- transform="translate(-3285.889,-3185.889)"><g
- id="id25"><rect
- class="BoundingBox"
- x="12999"
- y="4399"
- width="1303"
- height="1203"
- id="rect480"
- style="fill:none;stroke:none" /><path
- d="m 13650,5600 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path482"
- inkscape:connector-curvature="0"
- style="fill:#00cc00;stroke:none" /><path
- d="m 13650,5600 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path484"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text486"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan488"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="13403"
- y="5221"
- id="tspan490"><tspan
- id="tspan492"
- style="fill:#ffffff;stroke:none">G</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g494"
- transform="translate(-3285.889,-3185.889)"><g
- id="id26"><rect
- class="BoundingBox"
- x="12999"
- y="3199"
- width="1303"
- height="1203"
- id="rect497"
- style="fill:none;stroke:none" /><path
- d="m 13650,4400 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path499"
- inkscape:connector-curvature="0"
- style="fill:#ff0000;stroke:none" /><path
- d="m 13650,4400 -650,0 0,-1200 1300,0 0,1200 -650,0 z"
- id="path501"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text503"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan505"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="13422"
- y="4021"
- id="tspan507"><tspan
- id="tspan509"
- style="fill:#ffffff;stroke:none">R</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.TextShape"
- id="g511"
- transform="translate(-3285.889,-3185.889)"><g
- id="id27"><rect
- class="BoundingBox"
- x="12400"
- y="6900"
- width="2374"
- height="963"
- id="rect514"
- style="fill:none;stroke:none" /><text
- class="TextShape"
- id="text516"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan518"
- style="font-weight:400;font-size:635px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="12650"
- y="7601"
- id="tspan520"><tspan
- id="tspan522"
- style="fill:#000000;stroke:none">GRBG</tspan></tspan></tspan></text>
-</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g524"
- transform="translate(-3285.889,-3185.889)"><g
- id="id28"><rect
- class="BoundingBox"
- x="5999"
- y="5699"
- width="1003"
- height="1003"
- id="rect527"
- style="fill:none;stroke:none" /><path
- d="m 6500,6700 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path529"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#0000ff" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g531"
- transform="translate(-3285.889,-3185.889)"><g
- id="id29"><rect
- class="BoundingBox"
- x="3399"
- y="5699"
- width="1003"
- height="1003"
- id="rect534"
- style="fill:none;stroke:none" /><path
- d="m 3900,6700 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path536"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#0000ff" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g538"
- transform="translate(-3285.889,-3185.889)"><g
- id="id30"><rect
- class="BoundingBox"
- x="5999"
- y="4499"
- width="1003"
- height="1003"
- id="rect541"
- style="fill:none;stroke:none" /><path
- d="m 6500,5500 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path543"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#00cc00" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g545"
- transform="translate(-3285.889,-3185.889)"><g
- id="id31"><rect
- class="BoundingBox"
- x="7599"
- y="5799"
- width="1003"
- height="1003"
- id="rect548"
- style="fill:none;stroke:none" /><path
- d="m 8100,6800 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path550"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#00cc00" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g552"
- transform="translate(-3285.889,-3185.889)"><g
- id="id32"><rect
- class="BoundingBox"
- x="10199"
- y="5799"
- width="1003"
- height="1003"
- id="rect555"
- style="fill:none;stroke:none" /><path
- d="m 10700,6800 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path557"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#00cc00" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g559"
- transform="translate(-3285.889,-3185.889)"><g
- id="id33"><rect
- class="BoundingBox"
- x="8899"
- y="5799"
- width="1003"
- height="1003"
- id="rect562"
- style="fill:none;stroke:none" /><path
- d="m 9400,6800 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path564"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#0000ff" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g566"
- transform="translate(-3285.889,-3185.889)"><g
- id="id34"><rect
- class="BoundingBox"
- x="10199"
- y="4499"
- width="1003"
- height="1003"
- id="rect569"
- style="fill:none;stroke:none" /><path
- d="m 10700,5500 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path571"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff0000" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g573"
- transform="translate(-3285.889,-3185.889)"><g
- id="id35"><rect
- class="BoundingBox"
- x="10199"
- y="3299"
- width="1003"
- height="1003"
- id="rect576"
- style="fill:none;stroke:none" /><path
- d="m 10700,4300 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path578"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#00cc00" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g580"
- transform="translate(-3285.889,-3185.889)"><g
- id="id36"><rect
- class="BoundingBox"
- x="14399"
- y="3299"
- width="1003"
- height="1003"
- id="rect583"
- style="fill:none;stroke:none" /><path
- d="m 14900,4300 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path585"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#00cc00" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g587"
- transform="translate(-3285.889,-3185.889)"><g
- id="id37"><rect
- class="BoundingBox"
- x="14399"
- y="5799"
- width="1003"
- height="1003"
- id="rect590"
- style="fill:none;stroke:none" /><path
- d="m 14900,6800 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path592"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#00cc00" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g594"
- transform="translate(-3285.889,-3185.889)"><g
- id="id38"><rect
- class="BoundingBox"
- x="11799"
- y="5799"
- width="1003"
- height="1003"
- id="rect597"
- style="fill:none;stroke:none" /><path
- d="m 12300,6800 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path599"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#00cc00" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g601"
- transform="translate(-3285.889,-3185.889)"><g
- id="id39"><rect
- class="BoundingBox"
- x="14399"
- y="4499"
- width="1003"
- height="1003"
- id="rect604"
- style="fill:none;stroke:none" /><path
- d="m 14900,5500 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path606"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#0000ff" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g608"
- transform="translate(-3285.889,-3185.889)"><g
- id="id40"><rect
- class="BoundingBox"
- x="13099"
- y="5799"
- width="1003"
- height="1003"
- id="rect611"
- style="fill:none;stroke:none" /><path
- d="m 13600,6800 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path613"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff0000" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g615"
- transform="translate(-3285.889,-3185.889)"><g
- id="id41"><rect
- class="BoundingBox"
- x="16099"
- y="5799"
- width="1003"
- height="1003"
- id="rect618"
- style="fill:none;stroke:none" /><path
- d="m 16600,6800 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path620"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff0000" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g622"
- transform="translate(-3398.7778,-3185.889)"><g
- id="id42"><rect
- class="BoundingBox"
- x="18799"
- y="5799"
- width="1003"
- height="1003"
- id="rect625"
- style="fill:none;stroke:none" /><path
- d="m 19300,6800 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path627"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff0000" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g629"
- transform="translate(-3398.7778,-3185.889)"><g
- id="id43"><rect
- class="BoundingBox"
- x="18799"
- y="3299"
- width="1003"
- height="1003"
- id="rect632"
- style="fill:none;stroke:none" /><path
- d="m 19300,4300 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path634"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff0000" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g636"
- transform="translate(-3285.889,-3185.889)"><g
- id="id44"><rect
- class="BoundingBox"
- x="17399"
- y="5799"
- width="1003"
- height="1003"
- id="rect639"
- style="fill:none;stroke:none" /><path
- d="m 17900,6800 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path641"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#00cc00" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g643"
- transform="translate(-3398.7778,-3185.889)"><g
- id="id45"><rect
- class="BoundingBox"
- x="18799"
- y="4499"
- width="1003"
- height="1003"
- id="rect646"
- style="fill:none;stroke:none" /><path
- d="m 19300,5500 -500,0 0,-1000 1000,0 0,1000 -500,0 z"
- id="path648"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#00cc00" /></g></g></svg> \ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?>
+<svg id="svg2" width="164.15mm" height="46.771mm" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" preserveAspectRatio="xMidYMid" version="1.2" viewBox="0 0 16415.333 4677.1107" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata id="metadata652"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><g id="g186" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id6"><rect id="rect189" class="BoundingBox" x="3299" y="3199" width="1303" height="1203" fill="none"/><path id="path191" d="m3950 4400h-650v-1200h1300v1200h-650z" fill="#00f"/><path id="path193" d="m3950
+4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text195" class="TextShape"><tspan id="tspan197" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan199" class="TextPosition" x="3739" y="4021"><tspan id="tspan201" fill="#ffffff">B</tspan></tspan></tspan></text>
+</g></g><g id="g203" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id7"><rect id="rect206" class="BoundingBox" x="4599" y="3199" width="1303" height="1203" fill="none"/><path id="path208" d="m5250 4400h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path210" d="m5250 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text212" class="TextShape"><tspan id="tspan214" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan216" class="TextPosition" x="5003" y="4021"><tspan id="tspan218" fill="#ffffff">G</tspan></tspan></tspan></text>
+</g></g><g id="g220" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id8"><rect id="rect223" class="BoundingBox" x="3299" y="4399" width="1303" height="1203" fill="none"/><path id="path225" d="m3950 5600h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path227" d="m3950 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text229" class="TextShape"><tspan id="tspan231" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan233" class="TextPosition" x="3703" y="5221"><tspan id="tspan235" fill="#ffffff">G</tspan></tspan></tspan></text>
+</g></g><g id="g237" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id9"><rect id="rect240" class="BoundingBox" x="4599" y="4399" width="1303" height="1203" fill="none"/><path id="path242" d="m5250 5600h-650v-1200h1300v1200h-650z" fill="#f00"/><path id="path244" d="m5250 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text246" class="TextShape"><tspan id="tspan248" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan250" class="TextPosition" x="5022" y="5221"><tspan id="tspan252" fill="#ffffff">R</tspan></tspan></tspan></text>
+</g></g><g id="g254" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id10" fill="none"><rect id="rect257" class="BoundingBox" x="5999" y="3299" width="1003" height="1003"/><path id="path259" d="m6500 4300h-500v-1e3h1e3v1e3h-500z" stroke="#00f"/></g></g><g id="g261" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id11" fill="none"><rect id="rect264" class="BoundingBox" x="4699" y="5699" width="1003" height="1003"/><path id="path266" d="m5200 6700h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g268" class="com.sun.star.drawing.TextShape" transform="translate(-3285.9 -3185.9)"><g id="id12"><rect id="rect271" class="BoundingBox" x="4e3" y="6900" width="2374" height="963" fill="none"/><text id="text273" class="TextShape"><tspan id="tspan275" class="TextParagraph" font-family="sans-serif" font-size="635px"
+font-weight="400"><tspan id="tspan277" class="TextPosition" x="4250" y="7601"><tspan id="tspan279" fill="#000000">BGGR</tspan></tspan></tspan></text>
+</g></g><g id="g281" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id13"><rect id="rect284" class="BoundingBox" x="8799" y="3199" width="1303" height="1203" fill="none"/><path id="path286" d="m9450 4400h-650v-1200h1300v1200h-650z" fill="#00f"/><path id="path288" d="m9450 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text290" class="TextShape"><tspan id="tspan292" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan294" class="TextPosition" x="9239" y="4021"><tspan id="tspan296" fill="#ffffff">B</tspan></tspan></tspan></text>
+</g></g><g id="g298" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id14"><rect id="rect301" class="BoundingBox" x="7499" y="3199" width="1303" height="1203" fill="none"/><path id="path303" d="m8150 4400h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path305" d="m8150 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text307" class="TextShape"><tspan id="tspan309" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan311" class="TextPosition" x="7903" y="4021"><tspan id="tspan313" fill="#ffffff">G</tspan></tspan></tspan></text>
+</g></g><g id="g315" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id15"><rect id="rect318" class="BoundingBox" x="8799" y="4399" width="1303" height="1203" fill="none"/><path id="path320" d="m9450 5600h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path322" d="m9450 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text324" class="TextShape"><tspan id="tspan326" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan328" class="TextPosition" x="9203" y="5221"><tspan id="tspan330" fill="#ffffff">G</tspan></tspan></tspan></text>
+</g></g><g id="g332" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id16"><rect id="rect335" class="BoundingBox" x="7499" y="4399" width="1303" height="1203" fill="none"/><path id="path337" d="m8150 5600h-650v-1200h1300v1200h-650z" fill="#f00"/><path id="path339" d="m8150 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text341" class="TextShape"><tspan id="tspan343" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan345" class="TextPosition" x="7922" y="5221"><tspan id="tspan347" fill="#ffffff">R</tspan></tspan></tspan></text>
+</g></g><g id="g349" class="com.sun.star.drawing.TextShape" transform="translate(-3285.9 -3185.9)"><g id="id17"><rect id="rect352" class="BoundingBox" x="8200" y="6900" width="2374" height="963" fill="none"/><text id="text354" class="TextShape"><tspan id="tspan356" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan358" class="TextPosition" x="8450" y="7601"><tspan id="tspan360" fill="#000000">GBRG</tspan></tspan></tspan></text>
+</g></g><g id="g362" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id18"><rect id="rect365" class="BoundingBox" x="17299" y="4399" width="1303" height="1203" fill="none"/><path id="path367" d="m17950 5600h-650v-1200h1300v1200h-650z" fill="#00f"/><path id="path369" d="m17950 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text371" class="TextShape"><tspan id="tspan373" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan375" class="TextPosition" x="17739" y="5221"><tspan id="tspan377" fill="#ffffff">B</tspan></tspan></tspan></text>
+</g></g><g id="g379" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id19"><rect id="rect382" class="BoundingBox" x="17299" y="3199" width="1303" height="1203" fill="none"/><path id="path384" d="m17950 4400h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path386" d="m17950 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text388" class="TextShape"><tspan id="tspan390" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan392" class="TextPosition" x="17703" y="4021"><tspan id="tspan394" fill="#ffffff">G</tspan></tspan></tspan></text>
+</g></g><g id="g396" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id20"><rect id="rect399" class="BoundingBox" x="15999" y="4399" width="1303" height="1203" fill="none"/><path id="path401" d="m16650 5600h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path403" d="m16650 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text405" class="TextShape"><tspan id="tspan407" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan409" class="TextPosition" x="16403" y="5221"><tspan id="tspan411" fill="#ffffff">G</tspan></tspan></tspan></text>
+</g></g><g id="g413" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id21"><rect id="rect416" class="BoundingBox" x="15999" y="3199" width="1303" height="1203" fill="none"/><path id="path418" d="m16650 4400h-650v-1200h1300v1200h-650z" fill="#f00"/><path id="path420" d="m16650 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text422" class="TextShape"><tspan id="tspan424" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan426" class="TextPosition" x="16422" y="4021"><tspan id="tspan428" fill="#ffffff">R</tspan></tspan></tspan></text>
+</g></g><g id="g430" class="com.sun.star.drawing.TextShape" transform="translate(-3285.9 -3185.9)"><g id="id22"><rect id="rect433" class="BoundingBox" x="16700" y="6900" width="2374" height="963" fill="none"/><text id="text435" class="TextShape"><tspan id="tspan437" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan439" class="TextPosition" x="16950" y="7601"><tspan id="tspan441" fill="#000000">RGGB</tspan></tspan></tspan></text>
+</g></g><g id="g443" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id23"><rect id="rect446" class="BoundingBox" x="11699" y="4399" width="1303" height="1203" fill="none"/><path id="path448" d="m12350 5600h-650v-1200h1300v1200h-650z" fill="#00f"/><path id="path450" d="m12350 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text452" class="TextShape"><tspan id="tspan454" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan456" class="TextPosition" x="12139" y="5221"><tspan id="tspan458" fill="#ffffff">B</tspan></tspan></tspan></text>
+</g></g><g id="g460" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id24"><rect id="rect463" class="BoundingBox" x="11699" y="3199" width="1303" height="1203" fill="none"/><path id="path465" d="m12350 4400h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path467" d="m12350 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text469" class="TextShape"><tspan id="tspan471" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan473" class="TextPosition" x="12103" y="4021"><tspan id="tspan475" fill="#ffffff">G</tspan></tspan></tspan></text>
+</g></g><g id="g477" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id25"><rect id="rect480" class="BoundingBox" x="12999" y="4399" width="1303" height="1203" fill="none"/><path id="path482" d="m13650 5600h-650v-1200h1300v1200h-650z" fill="#0c0"/><path id="path484" d="m13650 5600h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text486" class="TextShape"><tspan id="tspan488" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan490" class="TextPosition" x="13403" y="5221"><tspan id="tspan492" fill="#ffffff">G</tspan></tspan></tspan></text>
+</g></g><g id="g494" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id26"><rect id="rect497" class="BoundingBox" x="12999" y="3199" width="1303" height="1203" fill="none"/><path id="path499" d="m13650 4400h-650v-1200h1300v1200h-650z" fill="#f00"/><path id="path501" d="m13650 4400h-650v-1200h1300v1200h-650z" fill="none" stroke="#3465a4"/><text id="text503" class="TextShape"><tspan id="tspan505" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan507" class="TextPosition" x="13422" y="4021"><tspan id="tspan509" fill="#ffffff">R</tspan></tspan></tspan></text>
+</g></g><g id="g511" class="com.sun.star.drawing.TextShape" transform="translate(-3285.9 -3185.9)"><g id="id27"><rect id="rect514" class="BoundingBox" x="12400" y="6900" width="2374" height="963" fill="none"/><text id="text516" class="TextShape"><tspan id="tspan518" class="TextParagraph" font-family="sans-serif" font-size="635px" font-weight="400"><tspan id="tspan520" class="TextPosition" x="12650" y="7601"><tspan id="tspan522" fill="#000000">GRBG</tspan></tspan></tspan></text>
+</g></g><g id="g524" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id28" fill="none"><rect id="rect527" class="BoundingBox" x="5999" y="5699" width="1003" height="1003"/><path id="path529" d="m6500 6700h-500v-1e3h1e3v1e3h-500z" stroke="#00f"/></g></g><g id="g531" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id29" fill="none"><rect id="rect534" class="BoundingBox" x="3399" y="5699" width="1003" height="1003"/><path id="path536" d="m3900 6700h-500v-1e3h1e3v1e3h-500z" stroke="#00f"/></g></g><g id="g538" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id30" fill="none"><rect id="rect541" class="BoundingBox" x="5999" y="4499" width="1003" height="1003"/><path id="path543" d="m6500 5500h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g545"
+class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id31" fill="none"><rect id="rect548" class="BoundingBox" x="7599" y="5799" width="1003" height="1003"/><path id="path550" d="m8100 6800h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g552" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id32" fill="none"><rect id="rect555" class="BoundingBox" x="10199" y="5799" width="1003" height="1003"/><path id="path557" d="m10700 6800h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g559" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id33" fill="none"><rect id="rect562" class="BoundingBox" x="8899" y="5799" width="1003" height="1003"/><path id="path564" d="m9400 6800h-500v-1e3h1e3v1e3h-500z" stroke="#00f"/></g></g><g id="g566" class="com.sun.star.drawing.CustomShape"
+transform="translate(-3285.9 -3185.9)"><g id="id34" fill="none"><rect id="rect569" class="BoundingBox" x="10199" y="4499" width="1003" height="1003"/><path id="path571" d="m10700 5500h-500v-1e3h1e3v1e3h-500z" stroke="#f00"/></g></g><g id="g573" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id35" fill="none"><rect id="rect576" class="BoundingBox" x="10199" y="3299" width="1003" height="1003"/><path id="path578" d="m10700 4300h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g580" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id36" fill="none"><rect id="rect583" class="BoundingBox" x="14399" y="3299" width="1003" height="1003"/><path id="path585" d="m14900 4300h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g587" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g
+id="id37" fill="none"><rect id="rect590" class="BoundingBox" x="14399" y="5799" width="1003" height="1003"/><path id="path592" d="m14900 6800h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g594" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id38" fill="none"><rect id="rect597" class="BoundingBox" x="11799" y="5799" width="1003" height="1003"/><path id="path599" d="m12300 6800h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g601" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id39" fill="none"><rect id="rect604" class="BoundingBox" x="14399" y="4499" width="1003" height="1003"/><path id="path606" d="m14900 5500h-500v-1e3h1e3v1e3h-500z" stroke="#00f"/></g></g><g id="g608" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id40" fill="none"><rect id="rect611"
+class="BoundingBox" x="13099" y="5799" width="1003" height="1003"/><path id="path613" d="m13600 6800h-500v-1e3h1e3v1e3h-500z" stroke="#f00"/></g></g><g id="g615" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id41" fill="none"><rect id="rect618" class="BoundingBox" x="16099" y="5799" width="1003" height="1003"/><path id="path620" d="m16600 6800h-500v-1e3h1e3v1e3h-500z" stroke="#f00"/></g></g><g id="g622" class="com.sun.star.drawing.CustomShape" transform="translate(-3398.8 -3185.9)"><g id="id42" fill="none"><rect id="rect625" class="BoundingBox" x="18799" y="5799" width="1003" height="1003"/><path id="path627" d="m19300 6800h-500v-1e3h1e3v1e3h-500z" stroke="#f00"/></g></g><g id="g629" class="com.sun.star.drawing.CustomShape" transform="translate(-3398.8 -3185.9)"><g id="id43" fill="none"><rect id="rect632" class="BoundingBox" x="18799" y="3299"
+width="1003" height="1003"/><path id="path634" d="m19300 4300h-500v-1e3h1e3v1e3h-500z" stroke="#f00"/></g></g><g id="g636" class="com.sun.star.drawing.CustomShape" transform="translate(-3285.9 -3185.9)"><g id="id44" fill="none"><rect id="rect639" class="BoundingBox" x="17399" y="5799" width="1003" height="1003"/><path id="path641" d="m17900 6800h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g><g id="g643" class="com.sun.star.drawing.CustomShape" transform="translate(-3398.8 -3185.9)"><g id="id45" fill="none"><rect id="rect646" class="BoundingBox" x="18799" y="4499" width="1003" height="1003"/><path id="path648" d="m19300 5500h-500v-1e3h1e3v1e3h-500z" stroke="#0c0"/></g></g></svg>
diff --git a/Documentation/media/uapi/v4l/constraints.svg b/Documentation/media/uapi/v4l/constraints.svg
index f710ee46b1f8..7e5d7185ca49 100644
--- a/Documentation/media/uapi/v4l/constraints.svg
+++ b/Documentation/media/uapi/v4l/constraints.svg
@@ -1,346 +1,10 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- version="1.2"
- width="249.00998mm"
- height="143.00999mm"
- viewBox="0 0 24900.998 14300.999"
- preserveAspectRatio="xMidYMid"
- xml:space="preserve"
- id="svg2"
- inkscape:version="0.91 r13725"
- sodipodi:docname="constraints.svg"
- style="fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round"><metadata
- id="metadata325"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1920"
- inkscape:window-height="997"
- id="namedview323"
- showgrid="false"
- inkscape:zoom="1.0818519"
- inkscape:cx="270.29272"
- inkscape:cy="249.83854"
- inkscape:window-x="1920"
- inkscape:window-y="30"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg2"
- fit-margin-top="0"
- fit-margin-left="0"
- fit-margin-right="0"
- fit-margin-bottom="0" /><defs
- class="ClipPathGroup"
- id="defs4"><marker
- inkscape:isstock="true"
- style="overflow:visible"
- id="marker6261"
- refX="0"
- refY="0"
- orient="auto"
- inkscape:stockid="Arrow1Mend"><path
- transform="matrix(-0.4,0,0,-0.4,-4,0)"
- style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
- id="path6263"
- inkscape:connector-curvature="0" /></marker><marker
- inkscape:stockid="Arrow1Mend"
- orient="auto"
- refY="0"
- refX="0"
- id="marker6125"
- style="overflow:visible"
- inkscape:isstock="true"
- inkscape:collect="always"><path
- id="path6127"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
- style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1"
- transform="matrix(-0.4,0,0,-0.4,-4,0)"
- inkscape:connector-curvature="0" /></marker><marker
- inkscape:isstock="true"
- style="overflow:visible"
- id="marker6001"
- refX="0"
- refY="0"
- orient="auto"
- inkscape:stockid="Arrow1Mend"
- inkscape:collect="always"><path
- transform="matrix(-0.4,0,0,-0.4,-4,0)"
- style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
- id="path6003"
- inkscape:connector-curvature="0" /></marker><marker
- inkscape:stockid="Arrow1Mend"
- orient="auto"
- refY="0"
- refX="0"
- id="marker5693"
- style="overflow:visible"
- inkscape:isstock="true"
- inkscape:collect="always"><path
- id="path5695"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
- style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:1pt;stroke-opacity:1"
- transform="matrix(-0.4,0,0,-0.4,-4,0)"
- inkscape:connector-curvature="0" /></marker><marker
- inkscape:isstock="true"
- style="overflow:visible"
- id="marker5575"
- refX="0"
- refY="0"
- orient="auto"
- inkscape:stockid="Arrow1Mend"
- inkscape:collect="always"><path
- transform="matrix(-0.4,0,0,-0.4,-4,0)"
- style="fill:#000080;fill-opacity:1;fill-rule:evenodd;stroke:#000080;stroke-width:1pt;stroke-opacity:1"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
- id="path5577"
- inkscape:connector-curvature="0" /></marker><marker
- inkscape:stockid="Arrow1Mend"
- orient="auto"
- refY="0"
- refX="0"
- id="marker5469"
- style="overflow:visible"
- inkscape:isstock="true"
- inkscape:collect="always"><path
- id="path5471"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
- style="fill:#000080;fill-opacity:1;fill-rule:evenodd;stroke:#000080;stroke-width:1pt;stroke-opacity:1"
- transform="matrix(-0.4,0,0,-0.4,-4,0)"
- inkscape:connector-curvature="0" /></marker><marker
- inkscape:stockid="Arrow1Mend"
- orient="auto"
- refY="0"
- refX="0"
- id="marker5259"
- style="overflow:visible"
- inkscape:isstock="true"><path
- id="path5261"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
- style="fill:#000080;fill-opacity:1;fill-rule:evenodd;stroke:#000080;stroke-width:1pt;stroke-opacity:1"
- transform="matrix(-0.4,0,0,-0.4,-4,0)"
- inkscape:connector-curvature="0" /></marker><marker
- inkscape:stockid="Arrow2Mend"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow2Mend"
- style="overflow:visible"
- inkscape:isstock="true"><path
- id="path4241"
- style="fill:#000080;fill-opacity:1;fill-rule:evenodd;stroke:#000080;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
- d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
- transform="scale(-0.6,-0.6)"
- inkscape:connector-curvature="0" /></marker></defs><defs
- id="defs9" /><defs
- id="defs100" /><defs
- id="defs123" /><defs
- class="TextShapeIndex"
- id="defs134" /><defs
- class="EmbeddedBulletChars"
- id="defs138" /><defs
- class="TextEmbeddedBitmaps"
- id="defs167" /><g
- class="com.sun.star.drawing.CustomShape"
- id="g204"
- transform="translate(-1350,-3250)"><g
- id="id6"><rect
- class="BoundingBox"
- x="1350"
- y="3250"
- width="24901"
- height="14301"
- id="rect207"
- style="fill:none;stroke:none" /><path
- d="m 13800,17500 -12400,0 0,-14200 24800,0 0,14200 -12400,0 z"
- id="path209"
- inkscape:connector-curvature="0"
- style="fill:#ffffff;stroke:none" /><path
- d="m 13800,17500 -12400,0 0,-14200 24800,0 0,14200 -12400,0 z"
- id="path211"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff0000;stroke-width:100;stroke-linejoin:round" /><text
- class="TextShape"
- id="text213"><tspan
- class="TextParagraph"
- font-size="846px"
- font-weight="400"
- id="tspan215"
- style="font-weight:400;font-size:846px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="1652"
- y="17093"
- id="tspan217"><tspan
- id="tspan219"
- style="fill:#ff0000;stroke:none" /><tspan
- id="tspan221"
- style="fill:#ff0000;stroke:none">V4L2_SEL_FLAG_GE</tspan></tspan></tspan></text>
-</g></g><rect
- class="BoundingBox"
- x="3000"
- y="2200"
- width="18101"
- height="10101"
- id="rect226"
- style="fill:none;stroke:none" /><path
- d="m 12050,12250 -9000,0 0,-10000 18000,0 0,10000 -9000,0 z"
- id="path228"
- inkscape:connector-curvature="0"
- style="fill:#ffffff;stroke:none" /><path
- d="m 12050,12250 -9000,0 0,-10000 18000,0 0,10000 -9000,0 z"
- id="path230"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000;stroke-width:100;stroke-linejoin:round" /><text
- class="TextShape"
- id="text232"
- x="-1350"
- y="-3250"><tspan
- class="TextParagraph"
- font-size="987px"
- font-weight="400"
- id="tspan234"
- style="font-weight:400;font-size:987px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="3227"
- y="11503"
- id="tspan236"><tspan
- id="tspan238"
- style="fill:#000000;stroke:none" /><tspan
- id="tspan240"
- style="fill:#000000;stroke:none">ORIGINAL</tspan></tspan></tspan></text>
-<g
- class="com.sun.star.drawing.CustomShape"
- id="g242"
- transform="translate(-1350,-3250)"><g
- id="id8"><rect
- class="BoundingBox"
- x="7050"
- y="7950"
- width="7901"
- height="5501"
- id="rect245"
- style="fill:none;stroke:none" /><path
- d="m 11000,13400 -3900,0 0,-5400 7800,0 0,5400 -3900,0 z"
- id="path247"
- inkscape:connector-curvature="0"
- style="fill:#ffffff;stroke:none" /><path
- d="m 11000,13400 -3900,0 0,-5400 7800,0 0,5400 -3900,0 z"
- id="path249"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4;stroke-width:100;stroke-linejoin:round" /><text
- class="TextShape"
- id="text251"><tspan
- class="TextParagraph"
- font-size="776px"
- font-weight="400"
- id="tspan253"
- style="font-weight:400;font-size:776px;font-family:'Liberation Sans', sans-serif"><tspan
- class="TextPosition"
- x="7228"
- y="10969"
- id="tspan255"><tspan
- id="tspan257"
- style="fill:#000080;stroke:none">V4L2_SEL_FLAG_LE</tspan></tspan></tspan></text>
-</g></g><rect
- class="BoundingBox"
- x="13700"
- y="7100"
- width="7101"
- height="101"
- id="rect262"
- style="fill:none;stroke:none" /><path
- d="m 20750,7150 -7000,0"
- id="path264"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000080;stroke-width:99.99134064;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow2Mend)" /><rect
- class="BoundingBox"
- x="3400"
- y="7100"
- width="2101"
- height="101"
- id="rect269"
- style="fill:none;stroke:none" /><path
- d="m 3450,7150 2000,0"
- id="path271"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000080;stroke-width:100;stroke-linejoin:round;marker-end:url(#marker5575)" /><rect
- class="BoundingBox"
- x="9800"
- y="2900"
- width="101"
- height="1501"
- id="rect276"
- style="fill:none;stroke:none" /><path
- d="m 9850,2950 0,1400"
- id="path278"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000080;stroke-width:100;stroke-linejoin:round;marker-end:url(#marker5259)" /><rect
- class="BoundingBox"
- x="9600"
- y="10600"
- width="101"
- height="1301"
- id="rect283"
- style="fill:none;stroke:none" /><path
- d="m 9650,11850 0,-1200"
- id="path285"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000080;stroke-width:100;stroke-linejoin:round;marker-end:url(#marker5469)" /><rect
- class="BoundingBox"
- x="450"
- y="6850"
- width="2051"
- height="601"
- id="rect290"
- style="fill:none;stroke:none" /><path
- d="m 2450,7150 -2000.8696,0"
- id="path292"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff0000;stroke-width:132.48202515;stroke-linejoin:round;marker-end:url(#marker6125)" /><rect
- class="BoundingBox"
- x="21600"
- y="6750"
- width="2651"
- height="601"
- id="rect299"
- style="fill:none;stroke:none" /><path
- d="m 21650,7050 2522.609,0"
- id="path301"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff0000;stroke-width:120.40660858;stroke-linejoin:round;marker-end:url(#marker6001)" /><rect
- class="BoundingBox"
- x="9550"
- y="550"
- width="601"
- height="1451"
- id="rect308"
- style="fill:none;stroke:none" /><path
- d="m 9836.957,1950 0,-1453.0435"
- id="path310"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff0000;stroke-width:164.03721619;stroke-linejoin:round;marker-end:url(#marker6261)" /><rect
- class="BoundingBox"
- x="9350"
- y="12500"
- width="601"
- height="1451"
- id="rect317"
- style="fill:none;stroke:none" /><path
- d="m 9650,12550 0,1505.217"
- id="path319"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff0000;stroke-width:166.95626831;stroke-linejoin:round;marker-end:url(#marker5693)" /></svg> \ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?>
+<svg id="svg2" width="249.01mm" height="143.01mm" fill-rule="evenodd" stroke-linejoin="round" stroke-width="28.222" preserveAspectRatio="xMidYMid" version="1.2" viewBox="0 0 24900.998 14300.999" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata id="metadata325"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs id="defs4" class="ClipPathGroup"><marker id="marker6261" overflow="visible" orient="auto"><path id="path6263" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#f00" fill-rule="evenodd" stroke="#f00" stroke-width="1pt"/></marker><marker id="marker6125" overflow="visible"
+orient="auto"><path id="path6127" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#f00" fill-rule="evenodd" stroke="#f00" stroke-width="1pt"/></marker><marker id="marker6001" overflow="visible" orient="auto"><path id="path6003" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#f00" fill-rule="evenodd" stroke="#f00" stroke-width="1pt"/></marker><marker id="marker5693" overflow="visible" orient="auto"><path id="path5695" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#f00" fill-rule="evenodd" stroke="#f00" stroke-width="1pt"/></marker><marker id="marker5575" overflow="visible" orient="auto"><path id="path5577" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#000080" fill-rule="evenodd" stroke="#000080" stroke-width="1pt"/></marker><marker id="marker5469" overflow="visible"
+orient="auto"><path id="path5471" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#000080" fill-rule="evenodd" stroke="#000080" stroke-width="1pt"/></marker><marker id="marker5259" overflow="visible" orient="auto"><path id="path5261" transform="matrix(-.4 0 0 -.4 -4 0)" d="m0 0 5-5-17.5 5 17.5 5-5-5z" fill="#000080" fill-rule="evenodd" stroke="#000080" stroke-width="1pt"/></marker><marker id="Arrow2Mend" overflow="visible" orient="auto"><path id="path4241" transform="scale(-.6)" d="m8.7186 4.0337-10.926-4.0177 10.926-4.0177c-1.7455 2.3721-1.7354 5.6175-6e-7 8.0354z" fill="#000080" fill-rule="evenodd" stroke="#000080" stroke-linejoin="round" stroke-width=".625"/></marker></defs><g id="g204" class="com.sun.star.drawing.CustomShape" transform="translate(-1350,-3250)"><g id="id6"><rect id="rect207" class="BoundingBox" x="1350" y="3250" width="24901" height="14301"
+fill="none"/><path id="path209" d="m13800 17500h-12400v-14200h24800v14200h-12400z" fill="#fff"/><path id="path211" d="m13800 17500h-12400v-14200h24800v14200h-12400z" fill="none" stroke="#f00" stroke-linejoin="round" stroke-width="100"/><text id="text213" class="TextShape"><tspan id="tspan215" class="TextParagraph" font-family="sans-serif" font-size="846px" font-weight="400"><tspan id="tspan217" class="TextPosition" x="1652" y="17093" fill="#ff0000"><tspan id="tspan219"/><tspan id="tspan221">V4L2_SEL_FLAG_GE</tspan></tspan></tspan></text>
+</g></g><rect id="rect226" class="BoundingBox" x="3e3" y="2200" width="18101" height="10101" fill="none"/><path id="path228" d="m12050 12250h-9e3v-1e4h18000v1e4h-9e3z" fill="#fff"/><path id="path230" d="m12050 12250h-9e3v-1e4h18000v1e4h-9e3z" fill="none" stroke="#000" stroke-linejoin="round" stroke-width="100"/><text id="text232" class="TextShape" x="-1350" y="-3250"><tspan id="tspan234" class="TextParagraph" font-family="sans-serif" font-size="987px" font-weight="400"><tspan id="tspan236" class="TextPosition" x="3227" y="11503" fill="#000000"><tspan id="tspan238"/><tspan id="tspan240">ORIGINAL</tspan></tspan></tspan></text>
+<g id="g242" class="com.sun.star.drawing.CustomShape" transform="translate(-1350,-3250)"><g id="id8"><rect id="rect245" class="BoundingBox" x="7050" y="7950" width="7901" height="5501" fill="none"/><path id="path247" d="m11000 13400h-3900v-5400h7800v5400h-3900z" fill="#fff"/><path id="path249" d="m11000 13400h-3900v-5400h7800v5400h-3900z" fill="none" stroke="#3465a4" stroke-linejoin="round" stroke-width="100"/><text id="text251" class="TextShape"><tspan id="tspan253" class="TextParagraph" font-family="sans-serif" font-size="776px" font-weight="400"><tspan id="tspan255" class="TextPosition" x="7228" y="10969"><tspan id="tspan257" fill="#000080">V4L2_SEL_FLAG_LE</tspan></tspan></tspan></text>
+</g></g><rect id="rect262" class="BoundingBox" x="13700" y="7100" width="7101" height="101" fill="none"/><path id="path264" d="m20750 7150h-7e3" fill="none" marker-end="url(#Arrow2Mend)" stroke="#000080" stroke-linejoin="round" stroke-width="99.991"/><rect id="rect269" class="BoundingBox" x="3400" y="7100" width="2101" height="101" fill="none"/><path id="path271" d="m3450 7150h2e3" fill="none" marker-end="url(#marker5575)" stroke="#000080" stroke-linejoin="round" stroke-width="100"/><rect id="rect276" class="BoundingBox" x="9800" y="2900" width="101" height="1501" fill="none"/><path id="path278" d="m9850 2950v1400" fill="none" marker-end="url(#marker5259)" stroke="#000080" stroke-linejoin="round" stroke-width="100"/><rect id="rect283" class="BoundingBox" x="9600" y="10600" width="101" height="1301" fill="none"/><path id="path285" d="m9650 11850v-1200" fill="none"
+marker-end="url(#marker5469)" stroke="#000080" stroke-linejoin="round" stroke-width="100"/><rect id="rect290" class="BoundingBox" x="450" y="6850" width="2051" height="601" fill="none"/><path id="path292" d="m2450 7150h-2000.9" fill="none" marker-end="url(#marker6125)" stroke="#f00" stroke-linejoin="round" stroke-width="132.48"/><rect id="rect299" class="BoundingBox" x="21600" y="6750" width="2651" height="601" fill="none"/><path id="path301" d="m21650 7050h2522.6" fill="none" marker-end="url(#marker6001)" stroke="#f00" stroke-linejoin="round" stroke-width="120.41"/><rect id="rect308" class="BoundingBox" x="9550" y="550" width="601" height="1451" fill="none"/><path id="path310" d="m9837 1950v-1453" fill="none" marker-end="url(#marker6261)" stroke="#f00" stroke-linejoin="round" stroke-width="164.04"/><rect id="rect317" class="BoundingBox" x="9350" y="12500" width="601" height="1451"
+fill="none"/><path id="path319" d="m9650 12550v1505.2" fill="none" marker-end="url(#marker5693)" stroke="#f00" stroke-linejoin="round" stroke-width="166.96"/></svg>
diff --git a/Documentation/media/uapi/v4l/crop.svg b/Documentation/media/uapi/v4l/crop.svg
index dc9a471bae6b..3878fe4c49e9 100644
--- a/Documentation/media/uapi/v4l/crop.svg
+++ b/Documentation/media/uapi/v4l/crop.svg
@@ -18,33 +18,34 @@
viewBox="0 0 739.11388 339.6584"
sodipodi:docname="crop.svg"><metadata
id="metadata8"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs6"><clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath44"><path
- d="m 0,0 0,1895 4118,0 L 4118,0 0,0 Z m 3051.62,250.48 8.19,17.01 -46.93,23.31 29.61,-25.515 -38.12,8.505 47.25,-23.31 z m -1559.25,800.73 -8.5,-17.01 46.93,-23.31 -29.29,25.2 37.8,-8.19 -46.94,23.31 z"
- id="path46"
- inkscape:connector-curvature="0"
- style="clip-rule:evenodd" /></clipPath><clipPath
+ d="m 0,0 0,1895 4118,0 L 4118,0 0,0 Z m 3051.62,250.48 8.19,17.01 -46.93,23.31 29.61,-25.515 -38.12,8.505 47.25,-23.31 z m -1559.25,800.73 -8.5,-17.01 46.93,-23.31 -29.29,25.2 37.8,-8.19 -46.94,23.31 z"
+ id="path46"
+ inkscape:connector-curvature="0"
+ style="clip-rule:evenodd" /></clipPath><clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath64"><path
- d="m 0,0 0,1895 4118,0 0,-1626 -1,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -1,0 0,-1 1,0 0,-1 1,0 0,-1 2,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 2,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 2,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 -4,0 0,1 -5,0 0,1 -4,0 0,1 -5,0 0,1 -4,0 0,1 -4,0 0,1 -4,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 1,0 0,3 1,0 0,2 1,0 0,2 1,0 L 4118,0 0,0 Z m 4074,272 0,-1 1,0 0,1 -1,0 z m -1486,743 0,-1 1,0 0,1 -1,0 z m -2,1 0,-1 1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -2,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -2,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -2,0 0,1 -1,0 0,2 2,0 0,-1 4,0 0,-1 5,0 0,-1 4,0 0,-1 5,0 0,-1 5,0 0,-1 4,0 0,-1 3,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -3,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 z"
- id="path66"
- inkscape:connector-curvature="0"
- style="clip-rule:evenodd" /></clipPath><clipPath
+ d="m 0,0 0,1895 4118,0 0,-1626 -1,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -1,0 0,-1 1,0 0,-1 1,0 0,-1 2,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 2,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 2,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 1,0 0,-1 -4,0 0,1 -5,0 0,1 -4,0 0,1 -5,0 0,1 -4,0 0,1 -4,0 0,1 -4,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 1,0 0,3 1,0 0,2 1,0 0,2 1,0 L 4118,0 0,0 Z m 4074,272 0,-1 1,0 0,1 -1,0 z m -1486,743 0,-1 1,0 0,1 -1,0 z m -2,1 0,-1 1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -2,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -1,0 0,1 -2,0 0,1 -1,0 0,1 -1,0 0,1
+-1,0 0,1 -1,0 0,1 -1,0 0,1 -2,0 0,1 -1,0 0,2 2,0 0,-1 4,0 0,-1 5,0 0,-1 4,0 0,-1 5,0 0,-1 5,0 0,-1 4,0 0,-1 3,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -3,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,1 -2,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 -1,0 0,-2 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 0,-1 2,0 z"
+ id="path66"
+ inkscape:connector-curvature="0"
+ style="clip-rule:evenodd" /></clipPath><clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath84"><path
- d="m 0,0 0,1895 4118,0 0,-136 -3,0 0,-1 -11,0 0,-1 -11,0 0,-1 -11,0 0,-1 -11,0 0,-1 5,0 0,-1 6,0 0,-1 7,0 0,-1 6,0 0,-1 6,0 0,-1 4,0 0,-1 -1,0 0,-1 -3,0 0,-1 -3,0 0,-1 -2,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 7,0 0,1 11,0 0,1 11,0 0,1 11,0 0,1 3,0 L 4118,0 0,0 Z m 2552,1599 0,-1 2,0 0,1 11,0 0,1 11,0 0,1 11,0 0,1 11,0 0,1 -4,0 0,1 -7,0 0,1 -6,0 0,1 -7,0 0,1 -6,0 0,1 -3,0 0,1 2,0 0,1 2,0 0,1 3,0 0,1 3,0 0,1 3,0 0,1 3,0 0,1 3,0 0,1 2,0 0,1 3,0 0,1 3,0 0,1 3,0 0,1 -7,0 0,-1 -12,0 0,-1 -11,0 0,-1 -11,0 0,-1 -4,0 0,-1 1,0 0,-12 1,0 0,-4 z"
- id="path86"
- inkscape:connector-curvature="0"
- style="clip-rule:evenodd" /></clipPath><clipPath
+ d="m 0,0 0,1895 4118,0 0,-136 -3,0 0,-1 -11,0 0,-1 -11,0 0,-1 -11,0 0,-1 -11,0 0,-1 5,0 0,-1 6,0 0,-1 7,0 0,-1 6,0 0,-1 6,0 0,-1 4,0 0,-1 -1,0 0,-1 -3,0 0,-1 -3,0 0,-1 -2,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 -3,0 0,-1 7,0 0,1 11,0 0,1 11,0 0,1 11,0 0,1 3,0 L 4118,0 0,0 Z m 2552,1599 0,-1 2,0 0,1 11,0 0,1 11,0 0,1 11,0 0,1 11,0 0,1 -4,0 0,1 -7,0 0,1 -6,0 0,1 -7,0 0,1 -6,0 0,1 -3,0 0,1 2,0 0,1 2,0 0,1 3,0 0,1 3,0 0,1 3,0 0,1 3,0 0,1 3,0 0,1 2,0 0,1 3,0 0,1 3,0 0,1 3,0 0,1 -7,0 0,-1 -12,0 0,-1 -11,0 0,-1 -11,0 0,-1 -4,0 0,-1 1,0 0,-12 1,0 0,-4 z"
+ id="path86"
+ inkscape:connector-curvature="0"
+ style="clip-rule:evenodd" /></clipPath><clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath104"><path
- d="m 0,0 0,1895 4118,0 L 4118,0 0,0 Z m 3056.98,1740.43 -1.58,18.9 -52.6,-4.72 38.74,-6.3 -36.85,-12.6 52.29,4.72 z m -1570.28,-123.79 1.58,-18.9 52.6,4.72 -38.43,5.99 36.54,12.91 -52.29,-4.72 z"
- id="path106"
- inkscape:connector-curvature="0"
- style="clip-rule:evenodd" /></clipPath></defs><sodipodi:namedview
+ d="m 0,0 0,1895 4118,0 L 4118,0 0,0 Z m 3056.98,1740.43 -1.58,18.9 -52.6,-4.72 38.74,-6.3 -36.85,-12.6 52.29,4.72 z m -1570.28,-123.79 1.58,-18.9 52.6,4.72 -38.43,5.99 36.54,12.91 -52.29,-4.72 z"
+ id="path106"
+ inkscape:connector-curvature="0"
+ style="clip-rule:evenodd" /></clipPath></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
@@ -123,90 +124,90 @@
inkscape:connector-curvature="0" /><g
id="g40"
transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><g
- clip-path="url(#clipPath44)"
- id="g42"><path
- inkscape:connector-curvature="0"
- id="path48"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="M 1492.37,1040.5 3051.62,260.875" /></g></g><g
+ clip-path="url(#clipPath44)"
+ id="g42"><path
+ inkscape:connector-curvature="0"
+ id="path48"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="M 1492.37,1040.5 3051.62,260.875" /></g></g><g
id="g50"
transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><path
- inkscape:connector-curvature="0"
- id="path52"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 1539.31,1027.9 -37.8,8.19 29.29,-25.2 8.51,17.01" /><path
- inkscape:connector-curvature="0"
- id="path54"
- style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 1539.31,1027.9 -37.8,8.19 29.29,-25.2 8.51,17.01 z" /><path
- inkscape:connector-curvature="0"
- id="path56"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 3004.37,273.79 38.12,-8.505 -29.61,25.515 -8.51,-17.01" /><path
- inkscape:connector-curvature="0"
- id="path58"
- style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 3004.37,273.79 38.12,-8.505 -29.61,25.515 -8.51,-17.01 z" /></g><g
+ inkscape:connector-curvature="0"
+ id="path52"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 1539.31,1027.9 -37.8,8.19 29.29,-25.2 8.51,17.01" /><path
+ inkscape:connector-curvature="0"
+ id="path54"
+ style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 1539.31,1027.9 -37.8,8.19 29.29,-25.2 8.51,17.01 z" /><path
+ inkscape:connector-curvature="0"
+ id="path56"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 3004.37,273.79 38.12,-8.505 -29.61,25.515 -8.51,-17.01" /><path
+ inkscape:connector-curvature="0"
+ id="path58"
+ style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 3004.37,273.79 38.12,-8.505 -29.61,25.515 -8.51,-17.01 z" /></g><g
id="g60"
transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><g
- clip-path="url(#clipPath64)"
- id="g62"><path
- inkscape:connector-curvature="0"
- id="path68"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="M 2555.5,1040.5 4114.75,260.875" /></g></g><g
+ clip-path="url(#clipPath64)"
+ id="g62"><path
+ inkscape:connector-curvature="0"
+ id="path68"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="M 2555.5,1040.5 4114.75,260.875" /></g></g><g
id="g70"
transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><path
- inkscape:connector-curvature="0"
- id="path72"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 2602.43,1027.9 -37.8,8.19 29.3,-25.2 8.5,17.01" /><path
- inkscape:connector-curvature="0"
- id="path74"
- style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 2602.43,1027.9 -37.8,8.19 29.3,-25.2 8.5,17.01 z" /><path
- inkscape:connector-curvature="0"
- id="path76"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 4067.5,273.79 38.11,-8.505 -29.61,25.515 -8.5,-17.01" /><path
- inkscape:connector-curvature="0"
- id="path78"
- style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 4067.5,273.79 38.11,-8.505 -29.61,25.515 -8.5,-17.01 z" /></g><g
+ inkscape:connector-curvature="0"
+ id="path72"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 2602.43,1027.9 -37.8,8.19 29.3,-25.2 8.5,17.01" /><path
+ inkscape:connector-curvature="0"
+ id="path74"
+ style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 2602.43,1027.9 -37.8,8.19 29.3,-25.2 8.5,17.01 z" /><path
+ inkscape:connector-curvature="0"
+ id="path76"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 4067.5,273.79 38.11,-8.505 -29.61,25.515 -8.5,-17.01" /><path
+ inkscape:connector-curvature="0"
+ id="path78"
+ style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 4067.5,273.79 38.11,-8.505 -29.61,25.515 -8.5,-17.01 z" /></g><g
id="g80"
transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><g
- clip-path="url(#clipPath84)"
- id="g82"><path
- inkscape:connector-curvature="0"
- id="path88"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 2555.5,1607.5 1559.25,141.75" /></g></g><g
+ clip-path="url(#clipPath84)"
+ id="g82"><path
+ inkscape:connector-curvature="0"
+ id="path88"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 2555.5,1607.5 1559.25,141.75" /></g></g><g
id="g90"
transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><path
- inkscape:connector-curvature="0"
- id="path92"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 2602.12,1621.36 -36.54,-12.91 38.43,-5.99 -1.89,18.9" /><path
- inkscape:connector-curvature="0"
- id="path94"
- style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 2602.12,1621.36 -36.54,-12.91 38.43,-5.99 -1.89,18.9 z" /><path
- inkscape:connector-curvature="0"
- id="path96"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 4067.81,1735.71 36.86,12.6 -38.75,6.3 1.89,-18.9" /><path
- inkscape:connector-curvature="0"
- id="path98"
- style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 4067.81,1735.71 36.86,12.6 -38.75,6.3 1.89,-18.9 z" /></g><g
+ inkscape:connector-curvature="0"
+ id="path92"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 2602.12,1621.36 -36.54,-12.91 38.43,-5.99 -1.89,18.9" /><path
+ inkscape:connector-curvature="0"
+ id="path94"
+ style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 2602.12,1621.36 -36.54,-12.91 38.43,-5.99 -1.89,18.9 z" /><path
+ inkscape:connector-curvature="0"
+ id="path96"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 4067.81,1735.71 36.86,12.6 -38.75,6.3 1.89,-18.9" /><path
+ inkscape:connector-curvature="0"
+ id="path98"
+ style="fill:none;stroke:#000000;stroke-width:4.7249999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 4067.81,1735.71 36.86,12.6 -38.75,6.3 1.89,-18.9 z" /></g><g
id="g100"
transform="matrix(0.14375794,0,0,0.14375794,-0.12334269,-0.08856738)"><g
- clip-path="url(#clipPath104)"
- id="g102"><path
- inkscape:connector-curvature="0"
- id="path108"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 1492.37,1607.5 1559.25,141.75" /></g></g><path
+ clip-path="url(#clipPath104)"
+ id="g102"><path
+ inkscape:connector-curvature="0"
+ id="path108"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 1492.37,1607.5 1559.25,141.75" /></g></g><path
d="m 221.11869,232.99481 -5.25292,-1.85592 5.52462,-0.86111 -0.2717,2.71703"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="path112"
@@ -225,43 +226,43 @@
inkscape:connector-curvature="0" /><g
id="g120"
transform="matrix(1.4375794,0,0,1.4375794,-0.12334269,-0.08856738)"><text
- transform="matrix(1,0,0,-1,204.52,9.07751)"
- style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#d10000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="text122"><tspan
- x="0 3.3074999 6.9854398 8.45397 12.13191 15.80985 19.11735 21.320145 24.998085 28.676025 31.983524 35.661465 39.339405 41.178375 44.856316 48.534256 52.212196 55.890137 59.568073"
- y="0"
- sodipodi:role="line"
- id="tspan124">v4l2_cropcap.bounds</tspan></text>
+ transform="matrix(1,0,0,-1,204.52,9.07751)"
+ style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#d10000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="text122"><tspan
+ x="0 3.3074999 6.9854398 8.45397 12.13191 15.80985 19.11735 21.320145 24.998085 28.676025 31.983524 35.661465 39.339405 41.178375 44.856316 48.534256 52.212196 55.890137 59.568073"
+ y="0"
+ sodipodi:role="line"
+ id="tspan124">v4l2_cropcap.bounds</tspan></text>
</g><g
id="g126"
transform="matrix(1.4375794,0,0,1.4375794,-0.12334269,-0.08856738)"><text
- transform="matrix(1,0,0,-1,58.5175,166.42)"
- style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#0000d1;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="text128"><tspan
- x="0 3.3074999 6.9854398 8.45397 12.13191 15.80985 19.11735 21.320145 24.998085 28.676025 31.983524 35.661465 39.339405 41.178375 44.856316 48.534256 50.373226 52.576019 56.25396 59.561459"
- y="0"
- sodipodi:role="line"
- id="tspan130">v4l2_cropcap.defrect</tspan></text>
+ transform="matrix(1,0,0,-1,58.5175,166.42)"
+ style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#0000d1;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="text128"><tspan
+ x="0 3.3074999 6.9854398 8.45397 12.13191 15.80985 19.11735 21.320145 24.998085 28.676025 31.983524 35.661465 39.339405 41.178375 44.856316 48.534256 50.373226 52.576019 56.25396 59.561459"
+ y="0"
+ sodipodi:role="line"
+ id="tspan130">v4l2_cropcap.defrect</tspan></text>
</g><g
id="g132"
transform="matrix(1.4375794,0,0,1.4375794,-0.12334269,-0.08856738)"><text
- transform="matrix(1,0,0,-1,153.49,152.245)"
- style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#008f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="text134"><tspan
- x="0 3.3074999 6.9854398 8.45397 12.13191 15.80985 19.11735 21.320145 24.998085 28.676025 30.514996"
- y="0"
- sodipodi:role="line"
- id="tspan136">v4l2_crop.c</tspan></text>
+ transform="matrix(1,0,0,-1,153.49,152.245)"
+ style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#008f00;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="text134"><tspan
+ x="0 3.3074999 6.9854398 8.45397 12.13191 15.80985 19.11735 21.320145 24.998085 28.676025 30.514996"
+ y="0"
+ sodipodi:role="line"
+ id="tspan136">v4l2_crop.c</tspan></text>
</g><g
id="g138"
transform="matrix(1.4375794,0,0,1.4375794,-0.12334269,-0.08856738)"><text
- transform="matrix(1,0,0,-1,309.415,30.34)"
- style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#b000b0;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="text140"><tspan
- x="0 3.3074999 6.9854398 8.45397 12.13191 15.80985 17.648821 21.326759 23.529554 29.03985 32.717789"
- y="0"
- sodipodi:role="line"
- id="tspan142">v4l2_format</tspan></text>
+ transform="matrix(1,0,0,-1,309.415,30.34)"
+ style="font-variant:normal;font-weight:normal;font-size:6.61499977px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#b000b0;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="text140"><tspan
+ x="0 3.3074999 6.9854398 8.45397 12.13191 15.80985 17.648821 21.326759 23.529554 29.03985 32.717789"
+ y="0"
+ sodipodi:role="line"
+ id="tspan142">v4l2_format</tspan></text>
</g><text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:32px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
@@ -270,12 +271,12 @@
id="text3396"
sodipodi:linespacing="125%"
transform="scale(1,-1)"><tspan
- sodipodi:role="line"
- id="tspan3398"
- x="-99.291145"
- y="-239.49893"></tspan><tspan
- sodipodi:role="line"
- x="-99.291145"
- y="-199.49893"
- id="tspan3400" /></text>
+ sodipodi:role="line"
+ id="tspan3398"
+ x="-99.291145"
+ y="-239.49893"></tspan><tspan
+ sodipodi:role="line"
+ x="-99.291145"
+ y="-199.49893"
+ id="tspan3400" /></text>
</g></svg>
diff --git a/Documentation/media/uapi/v4l/fieldseq_bt.svg b/Documentation/media/uapi/v4l/fieldseq_bt.svg
index b195301771ce..909d758f8543 100644
--- a/Documentation/media/uapi/v4l/fieldseq_bt.svg
+++ b/Documentation/media/uapi/v4l/fieldseq_bt.svg
@@ -42,15 +42,15 @@
inkscape:window-maximized="1"
inkscape:current-layer="g3627" /><metadata
id="metadata3625"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs3623"><clipPath
id="clipPath4301"
clipPathUnits="userSpaceOnUse"><path
- style="clip-rule:evenodd"
- inkscape:connector-curvature="0"
- id="path4303"
- d="M 0,6040 0,0 l 5650,0 0,6040 -5650,0 z m 4786.76,-99.89 103.92,0 0,56.69 -103.92,0 0,0 85.03,-28.35 -85.03,-28.34 z" /></clipPath></defs><g
+ style="clip-rule:evenodd"
+ inkscape:connector-curvature="0"
+ id="path4303"
+ d="M 0,6040 0,0 l 5650,0 0,6040 -5650,0 z m 4786.76,-99.89 103.92,0 0,56.69 -103.92,0 0,0 85.03,-28.35 -85.03,-28.34 z" /></clipPath></defs><g
transform="matrix(1.25,0,0,-1.25,-1.0537,751.94632)"
inkscape:label="fieldseq_bt"
inkscape:groupmode="layer"
@@ -1390,13 +1390,13 @@
transform="scale(0.1,0.1)"
id="g4297"
style=""><g
- id="g4299"
- clip-path="url(#clipPath4301)"
- style=""><path
- d="m 3778.18,5968.45 1105.42,0"
- style="fill:none;stroke:#000000;stroke-width:14.17199993;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- id="path4305"
- inkscape:connector-curvature="0" /></g></g><path
+ id="g4299"
+ clip-path="url(#clipPath4301)"
+ style=""><path
+ d="m 3778.18,5968.45 1105.42,0"
+ style="fill:none;stroke:#000000;stroke-width:14.17199993;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ id="path4305"
+ inkscape:connector-curvature="0" /></g></g><path
d="m 478.676,594.011 8.503,2.834 -8.503,2.835 0,-5.669"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="path4307"
@@ -2466,148 +2466,148 @@
id="text4841"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan4843"
- sodipodi:role="line"
- y="-533.07098"
- x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP</tspan><tspan
- id="tspan4845"
- sodipodi:role="line"
- y="-465.04559"
- x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM</tspan><tspan
- id="tspan4847"
- sodipodi:role="line"
- y="-397.0202"
- x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE</tspan></text>
+ id="tspan4843"
+ sodipodi:role="line"
+ y="-533.07098"
+ x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP</tspan><tspan
+ id="tspan4845"
+ sodipodi:role="line"
+ y="-465.04559"
+ x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM</tspan><tspan
+ id="tspan4847"
+ sodipodi:role="line"
+ y="-397.0202"
+ x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE</tspan></text>
<text
y="-316.23969"
x="103.58983"
id="text4849"
style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan4851"
- sodipodi:role="line"
- y="-316.23969"
- x="103.58983 109.09226 113.67899 118.26572 122.85246 127.43919 132.47964 134.77301 140.27545 144.86218 150.81833 155.40506 160.44553 166.86365 188.62184 194.12427 198.711 203.29774 207.88448 212.47121 217.51166 219.80502 225.30746 229.8942 235.85034 240.43707 245.9395 252.35764 257.3981 262.43854 268.85669 375.69293 381.19534 385.78207 390.3688 394.95554 399.54227 404.58273 406.8761 412.37854 416.96527 422.92142 427.50815 433.01059 439.42871 444.46918 449.50961 455.92776 1.551828 7.0542617 11.640993 16.227724 20.814463 25.401194 30.441652 32.735016 38.237442 42.824177 48.780331 53.367065 58.869492 65.287621 70.328079 75.368538 81.786659">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOM</tspan><tspan
- id="tspan4853"
- sodipodi:role="line"
- y="-328.99481"
- x="10.054964 14.17972 18.766451 20.597849 25.18458 29.771311 34.358047 38.944778 41.238144 43.531509 48.118244 50.865334 53.158699 55.452068 57.283459 61.870193 63.701588 68.288322">v4l2_buffer.field:</tspan></text>
+ id="tspan4851"
+ sodipodi:role="line"
+ y="-316.23969"
+ x="103.58983 109.09226 113.67899 118.26572 122.85246 127.43919 132.47964 134.77301 140.27545 144.86218 150.81833 155.40506 160.44553 166.86365 188.62184 194.12427 198.711 203.29774 207.88448 212.47121 217.51166 219.80502 225.30746 229.8942 235.85034 240.43707 245.9395 252.35764 257.3981 262.43854 268.85669 375.69293 381.19534 385.78207 390.3688 394.95554 399.54227 404.58273 406.8761 412.37854 416.96527 422.92142 427.50815 433.01059 439.42871 444.46918 449.50961 455.92776 1.551828 7.0542617 11.640993 16.227724 20.814463 25.401194 30.441652 32.735016 38.237442 42.824177 48.780331 53.367065 58.869492 65.287621 70.328079 75.368538 81.786659">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOM</tspan><tspan
+ id="tspan4853"
+ sodipodi:role="line"
+ y="-328.99481"
+ x="10.054964 14.17972 18.766451 20.597849 25.18458 29.771311 34.358047 38.944778 41.238144 43.531509 48.118244 50.865334 53.158699 55.452068 57.283459 61.870193 63.701588 68.288322">v4l2_buffer.field:</tspan></text>
<text
y="-592.59381"
x="5.8034"
id="text4855"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan4857"
- sodipodi:role="line"
- y="-592.59381"
- x="5.8034 13.134789 19.806232 29.801399 36.472843 43.144287 47.139954 53.811398 56.475174 59.810898 66.482346 70.478004 77.149452 83.820892 87.816566 91.152283 94.488007 101.15945 107.83089 111.16662 114.50233 121.17377 131.16895 134.50468 137.84041 140.50418 147.17563 149.8394 156.51085 159.84657 163.1823 165.84607 169.84174 175.84123 179.17696 182.51268 185.8484 189.84407 196.51552 203.18695 209.18646 219.18163 221.8454 225.18112 228.51685 235.18829 241.85973 245.19545 249.19112 255.86256 259.19827 265.86972 269.20544 272.54117 282.53635 285.87207 294.53534 301.86673 309.87006 318.53336">Temporal order, bottom field first transmitted (e.g. M/NTSC)</tspan></text>
+ id="tspan4857"
+ sodipodi:role="line"
+ y="-592.59381"
+ x="5.8034 13.134789 19.806232 29.801399 36.472843 43.144287 47.139954 53.811398 56.475174 59.810898 66.482346 70.478004 77.149452 83.820892 87.816566 91.152283 94.488007 101.15945 107.83089 111.16662 114.50233 121.17377 131.16895 134.50468 137.84041 140.50418 147.17563 149.8394 156.51085 159.84657 163.1823 165.84607 169.84174 175.84123 179.17696 182.51268 185.8484 189.84407 196.51552 203.18695 209.18646 219.18163 221.8454 225.18112 228.51685 235.18829 241.85973 245.19545 249.19112 255.86256 259.19827 265.86972 269.20544 272.54117 282.53635 285.87207 294.53534 301.86673 309.87006 318.53336">Temporal order, bottom field first transmitted (e.g. M/NTSC)</tspan></text>
<text
y="-316.23981"
x="290.6604"
id="text4859"
style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan4861"
- sodipodi:role="line"
- y="-316.23981"
- x="290.6604 296.16284 300.74957 305.3363 309.92303 314.50977 319.55023 321.8436 327.34601 331.93274 337.88889 342.47565 347.51608 353.9342 477.73062 483.23306 487.81979 492.40652 496.99326 501.57999 506.62045 508.91382 514.41626 519.00299 524.95911 529.5459 534.5863 541.00446">V4L2_FIELD_TOPV4L2_FIELD_TOP</tspan></text>
+ id="tspan4861"
+ sodipodi:role="line"
+ y="-316.23981"
+ x="290.6604 296.16284 300.74957 305.3363 309.92303 314.50977 319.55023 321.8436 327.34601 331.93274 337.88889 342.47565 347.51608 353.9342 477.73062 483.23306 487.81979 492.40652 496.99326 501.57999 506.62045 508.91382 514.41626 519.00299 524.95911 529.5459 534.5863 541.00446">V4L2_FIELD_TOPV4L2_FIELD_TOP</tspan></text>
<text
y="-299.23349"
x="5.8034"
id="text4863"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan4865"
- sodipodi:role="line"
- y="-299.23349"
- x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 84.504837 93.168114 100.4995 108.50284 117.16611 123.83755 131.8409 140.50418 148.50751 157.17079 160.50652 163.84224 167.17796 175.18129 181.85274 188.52419 195.19562 201.86707 209.19846 212.53418 220.53751 227.20895 235.87224 242.54367 245.87939 254.54268 261.87405 269.87741 278.54068 285.21213 293.21545 301.87872 309.88205 318.54535 325.2168 333.22012">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_BT</tspan><tspan
- id="tspan4867"
- sodipodi:role="line"
- y="-192.9435"
- x="1.5518398 9.5551729 16.226616 22.898062 29.569506 36.240948 43.572334 46.908058 54.911392 61.582836 70.246117 76.917557 80.253281 88.916557 96.247948 104.25128 112.91456 119.586 127.58932 136.25262 144.25595 152.91924 159.59067 166.92206 174.9254 178.26112 182.25679 192.25195 194.91573 200.91524 207.58667 210.25046 212.91423 219.58568 226.25713 232.92856 239.60001">V4L2_FIELD_INTERLACED_TB (misaligned)</tspan><tspan
- id="tspan4869"
- sodipodi:role="line"
- y="-86.653496"
- x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 89.172447 97.175781 106.511 113.18245 121.18579">V4L2_FIELD_SEQ_BT</tspan></text>
+ id="tspan4865"
+ sodipodi:role="line"
+ y="-299.23349"
+ x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 84.504837 93.168114 100.4995 108.50284 117.16611 123.83755 131.8409 140.50418 148.50751 157.17079 160.50652 163.84224 167.17796 175.18129 181.85274 188.52419 195.19562 201.86707 209.19846 212.53418 220.53751 227.20895 235.87224 242.54367 245.87939 254.54268 261.87405 269.87741 278.54068 285.21213 293.21545 301.87872 309.88205 318.54535 325.2168 333.22012">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_BT</tspan><tspan
+ id="tspan4867"
+ sodipodi:role="line"
+ y="-192.9435"
+ x="1.5518398 9.5551729 16.226616 22.898062 29.569506 36.240948 43.572334 46.908058 54.911392 61.582836 70.246117 76.917557 80.253281 88.916557 96.247948 104.25128 112.91456 119.586 127.58932 136.25262 144.25595 152.91924 159.59067 166.92206 174.9254 178.26112 182.25679 192.25195 194.91573 200.91524 207.58667 210.25046 212.91423 219.58568 226.25713 232.92856 239.60001">V4L2_FIELD_INTERLACED_TB (misaligned)</tspan><tspan
+ id="tspan4869"
+ sodipodi:role="line"
+ y="-86.653496"
+ x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 89.172447 97.175781 106.511 113.18245 121.18579">V4L2_FIELD_SEQ_BT</tspan></text>
<text
y="-533.07098"
x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464"
id="text4592"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan4594"
- sodipodi:role="line"
- y="-533.07098"
- x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP</tspan></text>
+ id="tspan4594"
+ sodipodi:role="line"
+ y="-533.07098"
+ x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP</tspan></text>
<text
y="-465.04559"
x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054"
id="text4596"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan4598"
- sodipodi:role="line"
- y="-465.04559"
- x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM</tspan></text>
+ id="tspan4598"
+ sodipodi:role="line"
+ y="-465.04559"
+ x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM</tspan></text>
<text
y="-397.0202"
x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963"
id="text4600"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan4602"
- sodipodi:role="line"
- y="-397.0202"
- x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE</tspan></text>
+ id="tspan4602"
+ sodipodi:role="line"
+ y="-397.0202"
+ x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE</tspan></text>
<text
y="-299.23349"
x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 84.504837 93.168114 100.4995 108.50284 117.16611 123.83755 131.8409 140.50418 148.50751 157.17079 160.50652 163.84224 167.17796 175.18129 181.85274 188.52419 195.19562 201.86707 209.19846 212.53418 220.53751 227.20895 235.87224 242.54367 245.87939 254.54268 261.87405 269.87741 278.54068 285.21213 293.21545 301.87872 309.88205 318.54535 325.2168 333.22012"
id="text5862"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan5864"
- sodipodi:role="line"
- y="-299.23349"
- x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 84.504837 93.168114 100.4995 108.50284 117.16611 123.83755 131.8409 140.50418 148.50751 157.17079 160.50652 163.84224 167.17796 175.18129 181.85274 188.52419 195.19562 201.86707 209.19846 212.53418 220.53751 227.20895 235.87224 242.54367 245.87939 254.54268 261.87405 269.87741 278.54068 285.21213 293.21545 301.87872 309.88205 318.54535 325.2168 333.22012">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_BT</tspan></text>
+ id="tspan5864"
+ sodipodi:role="line"
+ y="-299.23349"
+ x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 84.504837 93.168114 100.4995 108.50284 117.16611 123.83755 131.8409 140.50418 148.50751 157.17079 160.50652 163.84224 167.17796 175.18129 181.85274 188.52419 195.19562 201.86707 209.19846 212.53418 220.53751 227.20895 235.87224 242.54367 245.87939 254.54268 261.87405 269.87741 278.54068 285.21213 293.21545 301.87872 309.88205 318.54535 325.2168 333.22012">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_BT</tspan></text>
<text
y="-192.9435"
x="1.5518398 9.5551729 16.226616 22.898062 29.569506 36.240948 43.572334 46.908058 54.911392 61.582836 70.246117 76.917557 80.253281 88.916557 96.247948 104.25128 112.91456 119.586 127.58932 136.25262 144.25595 152.91924 159.59067 166.92206 174.9254 178.26112 182.25679 192.25195 194.91573 200.91524 207.58667 210.25046 212.91423 219.58568 226.25713 232.92856 239.60001"
id="text5866"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan5868"
- sodipodi:role="line"
- y="-192.9435"
- x="1.5518398 9.5551729 16.226616 22.898062 29.569506 36.240948 43.572334 46.908058 54.911392 61.582836 70.246117 76.917557 80.253281 88.916557 96.247948 104.25128 112.91456 119.586 127.58932 136.25262 144.25595 152.91924 159.59067 166.92206 174.9254 178.26112 182.25679 192.25195 194.91573 200.91524 207.58667 210.25046 212.91423 219.58568 226.25713 232.92856 239.60001">V4L2_FIELD_INTERLACED_TB (misaligned)</tspan></text>
+ id="tspan5868"
+ sodipodi:role="line"
+ y="-192.9435"
+ x="1.5518398 9.5551729 16.226616 22.898062 29.569506 36.240948 43.572334 46.908058 54.911392 61.582836 70.246117 76.917557 80.253281 88.916557 96.247948 104.25128 112.91456 119.586 127.58932 136.25262 144.25595 152.91924 159.59067 166.92206 174.9254 178.26112 182.25679 192.25195 194.91573 200.91524 207.58667 210.25046 212.91423 219.58568 226.25713 232.92856 239.60001">V4L2_FIELD_INTERLACED_TB (misaligned)</tspan></text>
<text
y="-86.653496"
x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 89.172447 97.175781 106.511 113.18245 121.18579"
id="text5870"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan5872"
- sodipodi:role="line"
- y="-86.653496"
- x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 89.172447 97.175781 106.511 113.18245 121.18579">V4L2_FIELD_SEQ_BT</tspan></text>
+ id="tspan5872"
+ sodipodi:role="line"
+ y="-86.653496"
+ x="5.8034 13.806733 20.478176 27.149622 33.821064 40.492508 47.823895 51.159618 59.162952 65.834396 74.497673 81.169121 89.172447 97.175781 106.511 113.18245 121.18579">V4L2_FIELD_SEQ_BT</tspan></text>
<text
y="-316.23969"
x="103.58983 109.09226 113.67899 118.26572 122.85246 127.43919 132.47964 134.77301 140.27545 144.86218 150.81833 155.40506 160.44553 166.86365 188.62184 194.12427 198.711 203.29774 207.88448 212.47121 217.51166 219.80502 225.30746 229.8942 235.85034 240.43707 245.9395 252.35764 257.3981 262.43854 268.85669 375.69293 381.19534 385.78207 390.3688 394.95554 399.54227 404.58273 406.8761 412.37854 416.96527 422.92142 427.50815 433.01059 439.42871 444.46918 449.50961 455.92776 1.551828 7.0542617 11.640993 16.227724 20.814463 25.401194 30.441652 32.735016 38.237442 42.824177 48.780331 53.367065 58.869492 65.287621 70.328079 75.368538 81.786659"
id="text7144"
style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan7146"
- sodipodi:role="line"
- y="-316.23969"
- x="103.58983 109.09226 113.67899 118.26572 122.85246 127.43919 132.47964 134.77301 140.27545 144.86218 150.81833 155.40506 160.44553 166.86365 188.62184 194.12427 198.711 203.29774 207.88448 212.47121 217.51166 219.80502 225.30746 229.8942 235.85034 240.43707 245.9395 252.35764 257.3981 262.43854 268.85669 375.69293 381.19534 385.78207 390.3688 394.95554 399.54227 404.58273 406.8761 412.37854 416.96527 422.92142 427.50815 433.01059 439.42871 444.46918 449.50961 455.92776 1.551828 7.0542617 11.640993 16.227724 20.814463 25.401194 30.441652 32.735016 38.237442 42.824177 48.780331 53.367065 58.869492 65.287621 70.328079 75.368538 81.786659">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOM</tspan></text>
+ id="tspan7146"
+ sodipodi:role="line"
+ y="-316.23969"
+ x="103.58983 109.09226 113.67899 118.26572 122.85246 127.43919 132.47964 134.77301 140.27545 144.86218 150.81833 155.40506 160.44553 166.86365 188.62184 194.12427 198.711 203.29774 207.88448 212.47121 217.51166 219.80502 225.30746 229.8942 235.85034 240.43707 245.9395 252.35764 257.3981 262.43854 268.85669 375.69293 381.19534 385.78207 390.3688 394.95554 399.54227 404.58273 406.8761 412.37854 416.96527 422.92142 427.50815 433.01059 439.42871 444.46918 449.50961 455.92776 1.551828 7.0542617 11.640993 16.227724 20.814463 25.401194 30.441652 32.735016 38.237442 42.824177 48.780331 53.367065 58.869492 65.287621 70.328079 75.368538 81.786659">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOMV4L2_FIELD_BOTTOM</tspan></text>
<text
y="-328.99481"
x="10.054964 14.17972 18.766451 20.597849 25.18458 29.771311 34.358047 38.944778 41.238144 43.531509 48.118244 50.865334 53.158699 55.452068 57.283459 61.870193 63.701588 68.288322"
id="text7148"
style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan7150"
- sodipodi:role="line"
- y="-328.99481"
- x="10.054964 14.17972 18.766451 20.597849 25.18458 29.771311 34.358047 38.944778 41.238144 43.531509 48.118244 50.865334 53.158699 55.452068 57.283459 61.870193 63.701588 68.288322">v4l2_buffer.field:</tspan></text>
+ id="tspan7150"
+ sodipodi:role="line"
+ y="-328.99481"
+ x="10.054964 14.17972 18.766451 20.597849 25.18458 29.771311 34.358047 38.944778 41.238144 43.531509 48.118244 50.865334 53.158699 55.452068 57.283459 61.870193 63.701588 68.288322">v4l2_buffer.field:</tspan></text>
</g></svg> \ No newline at end of file
diff --git a/Documentation/media/uapi/v4l/fieldseq_tb.svg b/Documentation/media/uapi/v4l/fieldseq_tb.svg
index 6a7b10ad4ab8..7c74344e770f 100644
--- a/Documentation/media/uapi/v4l/fieldseq_tb.svg
+++ b/Documentation/media/uapi/v4l/fieldseq_tb.svg
@@ -42,15 +42,15 @@
inkscape:window-maximized="1"
inkscape:current-layer="g5551" /><metadata
id="metadata5549"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs5547"><clipPath
id="clipPath6753"
clipPathUnits="userSpaceOnUse"><path
- style="clip-rule:evenodd"
- inkscape:connector-curvature="0"
- id="path6755"
- d="M 0,6000 0,0 l 5660,0 0,6000 -5660,0 z m 4786.76,-102.89 103.92,0 0,56.69 -103.92,0 0,0 85.03,-28.35 -85.03,-28.34 z" /></clipPath></defs><g
+ style="clip-rule:evenodd"
+ inkscape:connector-curvature="0"
+ id="path6755"
+ d="M 0,6000 0,0 l 5660,0 0,6000 -5660,0 z m 4786.76,-102.89 103.92,0 0,56.69 -103.92,0 0,0 85.03,-28.35 -85.03,-28.34 z" /></clipPath></defs><g
transform="matrix(1.25,0,0,-1.25,-1.0537,746.57119)"
inkscape:label="fieldseq_tb"
inkscape:groupmode="layer"
@@ -2446,13 +2446,13 @@
transform="scale(0.1,0.1)"
id="g6749"
style=""><g
- id="g6751"
- clip-path="url(#clipPath6753)"
- style=""><path
- d="m 3778.18,5925.45 1105.42,0"
- style="fill:none;stroke:#000000;stroke-width:14.17199993;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- id="path6757"
- inkscape:connector-curvature="0" /></g></g><path
+ id="g6751"
+ clip-path="url(#clipPath6753)"
+ style=""><path
+ d="m 3778.18,5925.45 1105.42,0"
+ style="fill:none;stroke:#000000;stroke-width:14.17199993;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ id="path6757"
+ inkscape:connector-curvature="0" /></g></g><path
d="m 478.676,589.711 8.503,2.834 -8.503,2.835 0,-5.669"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="path6759"
@@ -2466,142 +2466,145 @@
id="text6765"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan6767"
- sodipodi:role="line"
- y="-528.771"
- x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP</tspan><tspan
- id="tspan6769"
- sodipodi:role="line"
- y="-460.74561"
- x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM</tspan><tspan
- id="tspan6771"
- sodipodi:role="line"
- y="-392.72021"
- x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE</tspan></text>
+ id="tspan6767"
+ sodipodi:role="line"
+ y="-528.771"
+ x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP</tspan><tspan
+ id="tspan6769"
+ sodipodi:role="line"
+ y="-460.74561"
+ x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM</tspan><tspan
+ id="tspan6771"
+ sodipodi:role="line"
+ y="-392.72021"
+ x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE</tspan></text>
<text
y="-324.69479"
x="10.05469"
id="text6773"
style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan6775"
- sodipodi:role="line"
- y="-324.69479"
- x="10.05469 14.17945 18.766184 20.597576 25.184309 29.771042 34.357777 38.944508 41.237877 43.531242 48.117977 50.865067 53.158432 55.451801 57.283192 61.869926 63.701321 68.288048">v4l2_buffer.field:</tspan><tspan
- id="tspan6777"
- sodipodi:role="line"
- y="-311.9397"
- x="10.05469 15.55712 20.143852 24.730585 29.317318 33.904053 38.944508 41.237877 46.740307 51.327042 57.283192 61.869926 66.910378 73.328506 95.0867 100.58913 105.17586 109.7626 114.34933 118.93606 123.97652 126.26987 131.77232 136.35905 142.3152 146.90193 152.40436 158.82249 163.86295 168.9034 175.32153 197.12534 202.62778 207.21451 211.80124 216.38797 220.9747 226.01515 228.30853 233.81096 238.39769 244.35384 248.94058 253.98103 260.39917 282.15695 287.65936 292.24609 296.83282 301.41956 306.00629 311.04675 313.34012 318.84256 323.42929 329.38544 333.97217 339.47461 345.89273 350.9332 355.97363 362.39175 384.19559 389.698 394.28473 398.87149 403.45822 408.04495 413.08539 415.37875 420.8812 425.46793 431.42407 436.0108 441.05127 447.46939 469.2276 474.73001 479.31674 483.90347 488.49023 493.07697 498.1174 500.41077 505.91321 510.49994 516.45612 521.04285 526.54523 532.96338 538.00385 543.04431 549.4624">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOM</tspan></text>
+ id="tspan6775"
+ sodipodi:role="line"
+ y="-324.69479"
+ x="10.05469 14.17945 18.766184 20.597576 25.184309 29.771042 34.357777 38.944508 41.237877 43.531242 48.117977 50.865067 53.158432 55.451801 57.283192 61.869926 63.701321 68.288048">v4l2_buffer.field:</tspan><tspan
+ id="tspan6777"
+ sodipodi:role="line"
+ y="-311.9397"
+ x="10.05469 15.55712 20.143852 24.730585 29.317318 33.904053 38.944508 41.237877 46.740307 51.327042 57.283192 61.869926 66.910378 73.328506 95.0867 100.58913 105.17586 109.7626 114.34933 118.93606 123.97652 126.26987 131.77232 136.35905 142.3152 146.90193 152.40436 158.82249 163.86295 168.9034 175.32153 197.12534 202.62778 207.21451 211.80124 216.38797 220.9747 226.01515 228.30853 233.81096 238.39769 244.35384 248.94058 253.98103 260.39917 282.15695 287.65936 292.24609 296.83282 301.41956 306.00629 311.04675 313.34012 318.84256 323.42929 329.38544 333.97217 339.47461 345.89273 350.9332 355.97363 362.39175 384.19559 389.698 394.28473 398.87149 403.45822 408.04495 413.08539 415.37875 420.8812 425.46793 431.42407 436.0108 441.05127 447.46939 469.2276 474.73001 479.31674 483.90347 488.49023 493.07697 498.1174 500.41077 505.91321 510.49994 516.45612 521.04285 526.54523 532.96338
+538.00385 543.04431 549.4624">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOM</tspan></text>
<text
y="-588.2937"
x="5.8031301"
id="text6779"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan6781"
- sodipodi:role="line"
- y="-588.2937"
- x="5.8031301 13.134519 19.805964 29.801128 36.472572 43.14402 47.139687 53.811131 56.474907 59.810631 66.482071 70.477737 77.149185 83.820625 87.816299 91.152016 94.48774 97.823463 104.4949 111.16635 114.50207 117.83779 120.50157 127.17302 129.83679 136.50824 139.84396 143.17969 145.84346 149.83913 155.83862 159.17435 162.51007 165.84579 169.84146 176.51291 183.18434 189.18385 199.17902 201.84279 205.17851 208.51424 215.18568 221.85713 225.19284 229.18851 235.85995 239.19568 245.86713 249.20285 252.53857 260.5419 269.87714 273.21286 281.21619 289.21951 295.89096">Temporal order, top field first transmitted (e.g. BG/PAL)</tspan><tspan
- id="tspan6783"
- sodipodi:role="line"
- y="-86.604706"
- x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 97.175514 106.51073 113.18218 120.51357">V4L2_FIELD_SEQ_TB</tspan><tspan
- id="tspan6785"
- sodipodi:role="line"
- y="-192.89471"
- x="10.05469 18.058023 24.729465 31.400909 38.072357 44.743801 52.075188 55.410912 63.414246 70.085686 78.748962 85.42041 88.756134 97.419411 104.7508 112.75413 121.41741 128.08885 136.09219 144.75546 152.7588 161.42207 168.09352 176.09685 183.42824 186.76396 190.75963 200.75479 203.41858 209.41808 216.08952 218.7533 221.41707 228.08852 234.75996 241.43141 248.10286">V4L2_FIELD_INTERLACED_BT (misaligned)</tspan><tspan
- id="tspan6787"
- sodipodi:role="line"
- y="-294.93271"
- x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 84.50457 93.167847 100.49924 108.50257 117.16585 123.83729 131.84062 140.50391 148.50723 157.17052 160.50624 163.84196 167.17769 175.18102 181.85246 188.52391 195.19534 201.86679 209.19818 212.53391 220.53723 227.20868 235.87196 242.5434 245.87912 254.5424 261.87378 269.87714 278.54041 285.21185 293.21518 301.87845 309.88177 318.54507 325.21652 332.54791">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_TB</tspan></text>
+ id="tspan6781"
+ sodipodi:role="line"
+ y="-588.2937"
+ x="5.8031301 13.134519 19.805964 29.801128 36.472572 43.14402 47.139687 53.811131 56.474907 59.810631 66.482071 70.477737 77.149185 83.820625 87.816299 91.152016 94.48774 97.823463 104.4949 111.16635 114.50207 117.83779 120.50157 127.17302 129.83679 136.50824 139.84396 143.17969 145.84346 149.83913 155.83862 159.17435 162.51007 165.84579 169.84146 176.51291 183.18434 189.18385 199.17902 201.84279 205.17851 208.51424 215.18568 221.85713 225.19284 229.18851 235.85995 239.19568 245.86713 249.20285 252.53857 260.5419 269.87714 273.21286 281.21619 289.21951 295.89096">Temporal order, top field first transmitted (e.g. BG/PAL)</tspan><tspan
+ id="tspan6783"
+ sodipodi:role="line"
+ y="-86.604706"
+ x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 97.175514 106.51073 113.18218 120.51357">V4L2_FIELD_SEQ_TB</tspan><tspan
+ id="tspan6785"
+ sodipodi:role="line"
+ y="-192.89471"
+ x="10.05469 18.058023 24.729465 31.400909 38.072357 44.743801 52.075188 55.410912 63.414246 70.085686 78.748962 85.42041 88.756134 97.419411 104.7508 112.75413 121.41741 128.08885 136.09219 144.75546 152.7588 161.42207 168.09352 176.09685 183.42824 186.76396 190.75963 200.75479 203.41858 209.41808 216.08952 218.7533 221.41707 228.08852 234.75996 241.43141 248.10286">V4L2_FIELD_INTERLACED_BT (misaligned)</tspan><tspan
+ id="tspan6787"
+ sodipodi:role="line"
+ y="-294.93271"
+ x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 84.50457 93.167847 100.49924 108.50257 117.16585 123.83729 131.84062 140.50391 148.50723 157.17052 160.50624 163.84196 167.17769 175.18102 181.85246 188.52391 195.19534 201.86679 209.19818 212.53391 220.53723 227.20868 235.87196 242.5434 245.87912 254.5424 261.87378 269.87714 278.54041 285.21185 293.21518 301.87845 309.88177 318.54507 325.21652 332.54791">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_TB</tspan></text>
<text
y="-528.771"
x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464"
id="text4583"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan4585"
- sodipodi:role="line"
- y="-528.771"
- x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP</tspan></text>
+ id="tspan4585"
+ sodipodi:role="line"
+ y="-528.771"
+ x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 88.500237 97.835464">V4L2_FIELD_TOP</tspan></text>
<text
y="-460.74561"
x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054"
id="text4587"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan4589"
- sodipodi:role="line"
- y="-460.74561"
- x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM</tspan></text>
+ id="tspan4589"
+ sodipodi:role="line"
+ y="-460.74561"
+ x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 98.507408 105.83879 113.17018 122.5054">V4L2_FIELD_BOTTOM</tspan></text>
<text
y="-392.72021"
x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963"
id="text4591"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan4593"
- sodipodi:role="line"
- y="-392.72021"
- x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE</tspan></text>
+ id="tspan4593"
+ sodipodi:role="line"
+ y="-392.72021"
+ x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 95.843628 103.17502 111.17835 119.84163 128.5049 136.50824 143.83963">V4L2_FIELD_ALTERNATE</tspan></text>
<text
y="-588.2937"
x="5.8031301 13.134519 19.805964 29.801128 36.472572 43.14402 47.139687 53.811131 56.474907 59.810631 66.482071 70.477737 77.149185 83.820625 87.816299 91.152016 94.48774 97.823463 104.4949 111.16635 114.50207 117.83779 120.50157 127.17302 129.83679 136.50824 139.84396 143.17969 145.84346 149.83913 155.83862 159.17435 162.51007 165.84579 169.84146 176.51291 183.18434 189.18385 199.17902 201.84279 205.17851 208.51424 215.18568 221.85713 225.19284 229.18851 235.85995 239.19568 245.86713 249.20285 252.53857 260.5419 269.87714 273.21286 281.21619 289.21951 295.89096"
id="text5847"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan5849"
- sodipodi:role="line"
- y="-588.2937"
- x="5.8031301 13.134519 19.805964 29.801128 36.472572 43.14402 47.139687 53.811131 56.474907 59.810631 66.482071 70.477737 77.149185 83.820625 87.816299 91.152016 94.48774 97.823463 104.4949 111.16635 114.50207 117.83779 120.50157 127.17302 129.83679 136.50824 139.84396 143.17969 145.84346 149.83913 155.83862 159.17435 162.51007 165.84579 169.84146 176.51291 183.18434 189.18385 199.17902 201.84279 205.17851 208.51424 215.18568 221.85713 225.19284 229.18851 235.85995 239.19568 245.86713 249.20285 252.53857 260.5419 269.87714 273.21286 281.21619 289.21951 295.89096">Temporal order, top field first transmitted (e.g. BG/PAL)</tspan></text>
+ id="tspan5849"
+ sodipodi:role="line"
+ y="-588.2937"
+ x="5.8031301 13.134519 19.805964 29.801128 36.472572 43.14402 47.139687 53.811131 56.474907 59.810631 66.482071 70.477737 77.149185 83.820625 87.816299 91.152016 94.48774 97.823463 104.4949 111.16635 114.50207 117.83779 120.50157 127.17302 129.83679 136.50824 139.84396 143.17969 145.84346 149.83913 155.83862 159.17435 162.51007 165.84579 169.84146 176.51291 183.18434 189.18385 199.17902 201.84279 205.17851 208.51424 215.18568 221.85713 225.19284 229.18851 235.85995 239.19568 245.86713 249.20285 252.53857 260.5419 269.87714 273.21286 281.21619 289.21951 295.89096">Temporal order, top field first transmitted (e.g. BG/PAL)</tspan></text>
<text
y="-86.604706"
x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 97.175514 106.51073 113.18218 120.51357"
id="text5851"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan5853"
- sodipodi:role="line"
- y="-86.604706"
- x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 97.175514 106.51073 113.18218 120.51357">V4L2_FIELD_SEQ_TB</tspan></text>
+ id="tspan5853"
+ sodipodi:role="line"
+ y="-86.604706"
+ x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 89.17218 97.175514 106.51073 113.18218 120.51357">V4L2_FIELD_SEQ_TB</tspan></text>
<text
y="-192.89471"
x="10.05469 18.058023 24.729465 31.400909 38.072357 44.743801 52.075188 55.410912 63.414246 70.085686 78.748962 85.42041 88.756134 97.419411 104.7508 112.75413 121.41741 128.08885 136.09219 144.75546 152.7588 161.42207 168.09352 176.09685 183.42824 186.76396 190.75963 200.75479 203.41858 209.41808 216.08952 218.7533 221.41707 228.08852 234.75996 241.43141 248.10286"
id="text5855"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan5857"
- sodipodi:role="line"
- y="-192.89471"
- x="10.05469 18.058023 24.729465 31.400909 38.072357 44.743801 52.075188 55.410912 63.414246 70.085686 78.748962 85.42041 88.756134 97.419411 104.7508 112.75413 121.41741 128.08885 136.09219 144.75546 152.7588 161.42207 168.09352 176.09685 183.42824 186.76396 190.75963 200.75479 203.41858 209.41808 216.08952 218.7533 221.41707 228.08852 234.75996 241.43141 248.10286">V4L2_FIELD_INTERLACED_BT (misaligned)</tspan></text>
+ id="tspan5857"
+ sodipodi:role="line"
+ y="-192.89471"
+ x="10.05469 18.058023 24.729465 31.400909 38.072357 44.743801 52.075188 55.410912 63.414246 70.085686 78.748962 85.42041 88.756134 97.419411 104.7508 112.75413 121.41741 128.08885 136.09219 144.75546 152.7588 161.42207 168.09352 176.09685 183.42824 186.76396 190.75963 200.75479 203.41858 209.41808 216.08952 218.7533 221.41707 228.08852 234.75996 241.43141 248.10286">V4L2_FIELD_INTERLACED_BT (misaligned)</tspan></text>
<text
y="-294.93271"
x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 84.50457 93.167847 100.49924 108.50257 117.16585 123.83729 131.84062 140.50391 148.50723 157.17052 160.50624 163.84196 167.17769 175.18102 181.85246 188.52391 195.19534 201.86679 209.19818 212.53391 220.53723 227.20868 235.87196 242.5434 245.87912 254.5424 261.87378 269.87714 278.54041 285.21185 293.21518 301.87845 309.88177 318.54507 325.21652 332.54791"
id="text5859"
style="font-variant:normal;font-weight:normal;font-size:11.9989996px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan5861"
- sodipodi:role="line"
- y="-294.93271"
- x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 84.50457 93.167847 100.49924 108.50257 117.16585 123.83729 131.84062 140.50391 148.50723 157.17052 160.50624 163.84196 167.17769 175.18102 181.85246 188.52391 195.19534 201.86679 209.19818 212.53391 220.53723 227.20868 235.87196 242.5434 245.87912 254.5424 261.87378 269.87714 278.54041 285.21185 293.21518 301.87845 309.88177 318.54507 325.21652 332.54791">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_TB</tspan></text>
+ id="tspan5861"
+ sodipodi:role="line"
+ y="-294.93271"
+ x="5.8031301 13.806463 20.477907 27.149351 33.820797 40.492241 47.823627 51.159351 59.162685 65.834129 74.497406 81.168854 84.50457 93.167847 100.49924 108.50257 117.16585 123.83729 131.84062 140.50391 148.50723 157.17052 160.50624 163.84196 167.17769 175.18102 181.85246 188.52391 195.19534 201.86679 209.19818 212.53391 220.53723 227.20868 235.87196 242.5434 245.87912 254.5424 261.87378 269.87714 278.54041 285.21185 293.21518 301.87845 309.88177 318.54507 325.21652 332.54791">V4L2_FIELD_INTERLACED / V4L2_FIELD_INTERLACED_TB</tspan></text>
<text
y="-324.69479"
x="10.05469 14.17945 18.766184 20.597576 25.184309 29.771042 34.357777 38.944508 41.237877 43.531242 48.117977 50.865067 53.158432 55.451801 57.283192 61.869926 63.701321 68.288048"
id="text7131"
style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan7133"
- sodipodi:role="line"
- y="-324.69479"
- x="10.05469 14.17945 18.766184 20.597576 25.184309 29.771042 34.357777 38.944508 41.237877 43.531242 48.117977 50.865067 53.158432 55.451801 57.283192 61.869926 63.701321 68.288048">v4l2_buffer.field:</tspan></text>
+ id="tspan7133"
+ sodipodi:role="line"
+ y="-324.69479"
+ x="10.05469 14.17945 18.766184 20.597576 25.184309 29.771042 34.357777 38.944508 41.237877 43.531242 48.117977 50.865067 53.158432 55.451801 57.283192 61.869926 63.701321 68.288048">v4l2_buffer.field:</tspan></text>
<text
y="-311.9397"
- x="10.05469 15.55712 20.143852 24.730585 29.317318 33.904053 38.944508 41.237877 46.740307 51.327042 57.283192 61.869926 66.910378 73.328506 95.0867 100.58913 105.17586 109.7626 114.34933 118.93606 123.97652 126.26987 131.77232 136.35905 142.3152 146.90193 152.40436 158.82249 163.86295 168.9034 175.32153 197.12534 202.62778 207.21451 211.80124 216.38797 220.9747 226.01515 228.30853 233.81096 238.39769 244.35384 248.94058 253.98103 260.39917 282.15695 287.65936 292.24609 296.83282 301.41956 306.00629 311.04675 313.34012 318.84256 323.42929 329.38544 333.97217 339.47461 345.89273 350.9332 355.97363 362.39175 384.19559 389.698 394.28473 398.87149 403.45822 408.04495 413.08539 415.37875 420.8812 425.46793 431.42407 436.0108 441.05127 447.46939 469.2276 474.73001 479.31674 483.90347 488.49023 493.07697 498.1174 500.41077 505.91321 510.49994 516.45612 521.04285 526.54523 532.96338 538.00385 543.04431 549.4624"
+ x="10.05469 15.55712 20.143852 24.730585 29.317318 33.904053 38.944508 41.237877 46.740307 51.327042 57.283192 61.869926 66.910378 73.328506 95.0867 100.58913 105.17586 109.7626 114.34933 118.93606 123.97652 126.26987 131.77232 136.35905 142.3152 146.90193 152.40436 158.82249 163.86295 168.9034 175.32153 197.12534 202.62778 207.21451 211.80124 216.38797 220.9747 226.01515 228.30853 233.81096 238.39769 244.35384 248.94058 253.98103 260.39917 282.15695 287.65936 292.24609 296.83282 301.41956 306.00629 311.04675 313.34012 318.84256 323.42929 329.38544 333.97217 339.47461 345.89273 350.9332 355.97363 362.39175 384.19559 389.698 394.28473 398.87149 403.45822 408.04495 413.08539 415.37875 420.8812 425.46793 431.42407 436.0108 441.05127 447.46939 469.2276 474.73001 479.31674 483.90347 488.49023 493.07697 498.1174 500.41077 505.91321 510.49994 516.45612 521.04285 526.54523 532.96338
+538.00385 543.04431 549.4624"
id="text7135"
style="font-variant:normal;font-weight:normal;font-size:8.2495203px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan7137"
- sodipodi:role="line"
- y="-311.9397"
- x="10.05469 15.55712 20.143852 24.730585 29.317318 33.904053 38.944508 41.237877 46.740307 51.327042 57.283192 61.869926 66.910378 73.328506 95.0867 100.58913 105.17586 109.7626 114.34933 118.93606 123.97652 126.26987 131.77232 136.35905 142.3152 146.90193 152.40436 158.82249 163.86295 168.9034 175.32153 197.12534 202.62778 207.21451 211.80124 216.38797 220.9747 226.01515 228.30853 233.81096 238.39769 244.35384 248.94058 253.98103 260.39917 282.15695 287.65936 292.24609 296.83282 301.41956 306.00629 311.04675 313.34012 318.84256 323.42929 329.38544 333.97217 339.47461 345.89273 350.9332 355.97363 362.39175 384.19559 389.698 394.28473 398.87149 403.45822 408.04495 413.08539 415.37875 420.8812 425.46793 431.42407 436.0108 441.05127 447.46939 469.2276 474.73001 479.31674 483.90347 488.49023 493.07697 498.1174 500.41077 505.91321 510.49994 516.45612 521.04285 526.54523 532.96338 538.00385 543.04431 549.4624">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOM</tspan></text>
+ id="tspan7137"
+ sodipodi:role="line"
+ y="-311.9397"
+ x="10.05469 15.55712 20.143852 24.730585 29.317318 33.904053 38.944508 41.237877 46.740307 51.327042 57.283192 61.869926 66.910378 73.328506 95.0867 100.58913 105.17586 109.7626 114.34933 118.93606 123.97652 126.26987 131.77232 136.35905 142.3152 146.90193 152.40436 158.82249 163.86295 168.9034 175.32153 197.12534 202.62778 207.21451 211.80124 216.38797 220.9747 226.01515 228.30853 233.81096 238.39769 244.35384 248.94058 253.98103 260.39917 282.15695 287.65936 292.24609 296.83282 301.41956 306.00629 311.04675 313.34012 318.84256 323.42929 329.38544 333.97217 339.47461 345.89273 350.9332 355.97363 362.39175 384.19559 389.698 394.28473 398.87149 403.45822 408.04495 413.08539 415.37875 420.8812 425.46793 431.42407 436.0108 441.05127 447.46939 469.2276 474.73001 479.31674 483.90347 488.49023 493.07697 498.1174 500.41077 505.91321 510.49994 516.45612 521.04285 526.54523 532.96338
+538.00385 543.04431 549.4624">V4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOMV4L2_FIELD_TOPV4L2_FIELD_BOTTOM</tspan></text>
</g></svg> \ No newline at end of file
diff --git a/Documentation/media/uapi/v4l/nv12mt.svg b/Documentation/media/uapi/v4l/nv12mt.svg
index 21fcccda9723..65d05606c04c 100644
--- a/Documentation/media/uapi/v4l/nv12mt.svg
+++ b/Documentation/media/uapi/v4l/nv12mt.svg
@@ -18,8 +18,8 @@
sodipodi:docname="nv12mt.svg"
style="fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round"><metadata
id="metadata383"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
@@ -47,11 +47,11 @@
id="defs4"><clipPath
id="presentation_clip_path"
clipPathUnits="userSpaceOnUse"><rect
- x="0"
- y="0"
- width="28000"
- height="21000"
- id="rect7" /></clipPath></defs><defs
+ x="0"
+ y="0"
+ width="28000"
+ height="21000"
+ id="rect7" /></clipPath></defs><defs
id="defs9" /><defs
id="defs80" /><defs
id="defs103" /><defs
@@ -65,386 +65,386 @@
id="g177"
transform="translate(-3285.889,-3185.889)"><g
id="g179"><g
- id="id1"
- class="Slide"
- clip-path="url(#presentation_clip_path)"><g
- class="Page"
- id="g182"><g
- class="com.sun.star.drawing.CustomShape"
- id="g184"><g
- id="id6"><rect
- class="BoundingBox"
- x="3299"
- y="3199"
- width="2403"
- height="1403"
- id="rect187"
- style="fill:none;stroke:none" /><path
- d="m 4500,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path189"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text191"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan193"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="4325"
- y="4121"
- id="tspan195"><tspan
- id="tspan197"
- style="fill:#000000;stroke:none">0</tspan></tspan></tspan></text>
+ id="id1"
+ class="Slide"
+ clip-path="url(#presentation_clip_path)"><g
+ class="Page"
+ id="g182"><g
+ class="com.sun.star.drawing.CustomShape"
+ id="g184"><g
+ id="id6"><rect
+ class="BoundingBox"
+ x="3299"
+ y="3199"
+ width="2403"
+ height="1403"
+ id="rect187"
+ style="fill:none;stroke:none" /><path
+ d="m 4500,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path189"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text191"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan193"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="4325"
+ y="4121"
+ id="tspan195"><tspan
+ id="tspan197"
+ style="fill:#000000;stroke:none">0</tspan></tspan></tspan></text>
</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g199"><g
- id="id7"><rect
- class="BoundingBox"
- x="5699"
- y="3199"
- width="2403"
- height="1403"
- id="rect202"
- style="fill:none;stroke:none" /><path
- d="m 6900,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path204"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g206"><g
- id="id8"><rect
- class="BoundingBox"
- x="8099"
- y="3199"
- width="2403"
- height="1403"
- id="rect209"
- style="fill:none;stroke:none" /><path
- d="m 9300,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path211"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text213"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan215"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="9125"
- y="4121"
- id="tspan217"><tspan
- id="tspan219"
- style="fill:#000000;stroke:none">6</tspan></tspan></tspan></text>
+ class="com.sun.star.drawing.CustomShape"
+ id="g199"><g
+ id="id7"><rect
+ class="BoundingBox"
+ x="5699"
+ y="3199"
+ width="2403"
+ height="1403"
+ id="rect202"
+ style="fill:none;stroke:none" /><path
+ d="m 6900,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path204"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /></g></g><g
+ class="com.sun.star.drawing.CustomShape"
+ id="g206"><g
+ id="id8"><rect
+ class="BoundingBox"
+ x="8099"
+ y="3199"
+ width="2403"
+ height="1403"
+ id="rect209"
+ style="fill:none;stroke:none" /><path
+ d="m 9300,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path211"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text213"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan215"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="9125"
+ y="4121"
+ id="tspan217"><tspan
+ id="tspan219"
+ style="fill:#000000;stroke:none">6</tspan></tspan></tspan></text>
</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g221"><g
- id="id9"><rect
- class="BoundingBox"
- x="5699"
- y="3199"
- width="2403"
- height="1403"
- id="rect224"
- style="fill:none;stroke:none" /><path
- d="m 6900,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path226"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text228"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan230"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="6725"
- y="4121"
- id="tspan232"><tspan
- id="tspan234"
- style="fill:#000000;stroke:none">1</tspan></tspan></tspan></text>
+ class="com.sun.star.drawing.CustomShape"
+ id="g221"><g
+ id="id9"><rect
+ class="BoundingBox"
+ x="5699"
+ y="3199"
+ width="2403"
+ height="1403"
+ id="rect224"
+ style="fill:none;stroke:none" /><path
+ d="m 6900,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path226"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text228"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan230"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="6725"
+ y="4121"
+ id="tspan232"><tspan
+ id="tspan234"
+ style="fill:#000000;stroke:none">1</tspan></tspan></tspan></text>
</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g236"><g
- id="id10"><rect
- class="BoundingBox"
- x="10499"
- y="3199"
- width="2403"
- height="1403"
- id="rect239"
- style="fill:none;stroke:none" /><path
- d="m 11700,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path241"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text243"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan245"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="11525"
- y="4121"
- id="tspan247"><tspan
- id="tspan249"
- style="fill:#000000;stroke:none">7</tspan></tspan></tspan></text>
+ class="com.sun.star.drawing.CustomShape"
+ id="g236"><g
+ id="id10"><rect
+ class="BoundingBox"
+ x="10499"
+ y="3199"
+ width="2403"
+ height="1403"
+ id="rect239"
+ style="fill:none;stroke:none" /><path
+ d="m 11700,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path241"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text243"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan245"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="11525"
+ y="4121"
+ id="tspan247"><tspan
+ id="tspan249"
+ style="fill:#000000;stroke:none">7</tspan></tspan></tspan></text>
</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g251"><g
- id="id11"><rect
- class="BoundingBox"
- x="3299"
- y="4599"
- width="2403"
- height="1403"
- id="rect254"
- style="fill:none;stroke:none" /><path
- d="m 4500,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path256"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text258"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan260"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="4325"
- y="5521"
- id="tspan262"><tspan
- id="tspan264"
- style="fill:#000000;stroke:none">2</tspan></tspan></tspan></text>
+ class="com.sun.star.drawing.CustomShape"
+ id="g251"><g
+ id="id11"><rect
+ class="BoundingBox"
+ x="3299"
+ y="4599"
+ width="2403"
+ height="1403"
+ id="rect254"
+ style="fill:none;stroke:none" /><path
+ d="m 4500,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path256"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text258"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan260"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="4325"
+ y="5521"
+ id="tspan262"><tspan
+ id="tspan264"
+ style="fill:#000000;stroke:none">2</tspan></tspan></tspan></text>
</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g266"><g
- id="id12"><rect
- class="BoundingBox"
- x="5699"
- y="4599"
- width="2403"
- height="1403"
- id="rect269"
- style="fill:none;stroke:none" /><path
- d="m 6900,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path271"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /></g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g273"><g
- id="id13"><rect
- class="BoundingBox"
- x="8099"
- y="4599"
- width="2403"
- height="1403"
- id="rect276"
- style="fill:none;stroke:none" /><path
- d="m 9300,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path278"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text280"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan282"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="9125"
- y="5521"
- id="tspan284"><tspan
- id="tspan286"
- style="fill:#000000;stroke:none">4</tspan></tspan></tspan></text>
+ class="com.sun.star.drawing.CustomShape"
+ id="g266"><g
+ id="id12"><rect
+ class="BoundingBox"
+ x="5699"
+ y="4599"
+ width="2403"
+ height="1403"
+ id="rect269"
+ style="fill:none;stroke:none" /><path
+ d="m 6900,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path271"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /></g></g><g
+ class="com.sun.star.drawing.CustomShape"
+ id="g273"><g
+ id="id13"><rect
+ class="BoundingBox"
+ x="8099"
+ y="4599"
+ width="2403"
+ height="1403"
+ id="rect276"
+ style="fill:none;stroke:none" /><path
+ d="m 9300,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path278"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text280"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan282"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="9125"
+ y="5521"
+ id="tspan284"><tspan
+ id="tspan286"
+ style="fill:#000000;stroke:none">4</tspan></tspan></tspan></text>
</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g288"><g
- id="id14"><rect
- class="BoundingBox"
- x="5699"
- y="4599"
- width="2403"
- height="1403"
- id="rect291"
- style="fill:none;stroke:none" /><path
- d="m 6900,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path293"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text295"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan297"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="6725"
- y="5521"
- id="tspan299"><tspan
- id="tspan301"
- style="fill:#000000;stroke:none">3</tspan></tspan></tspan></text>
+ class="com.sun.star.drawing.CustomShape"
+ id="g288"><g
+ id="id14"><rect
+ class="BoundingBox"
+ x="5699"
+ y="4599"
+ width="2403"
+ height="1403"
+ id="rect291"
+ style="fill:none;stroke:none" /><path
+ d="m 6900,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path293"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text295"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan297"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="6725"
+ y="5521"
+ id="tspan299"><tspan
+ id="tspan301"
+ style="fill:#000000;stroke:none">3</tspan></tspan></tspan></text>
</g></g><g
- class="com.sun.star.drawing.CustomShape"
- id="g303"><g
- id="id15"><rect
- class="BoundingBox"
- x="10499"
- y="4599"
- width="2403"
- height="1403"
- id="rect306"
- style="fill:none;stroke:none" /><path
- d="m 11700,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path308"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text310"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan312"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="11525"
- y="5521"
- id="tspan314"><tspan
- id="tspan316"
- style="fill:#000000;stroke:none">5</tspan></tspan></tspan></text>
+ class="com.sun.star.drawing.CustomShape"
+ id="g303"><g
+ id="id15"><rect
+ class="BoundingBox"
+ x="10499"
+ y="4599"
+ width="2403"
+ height="1403"
+ id="rect306"
+ style="fill:none;stroke:none" /><path
+ d="m 11700,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path308"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text310"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan312"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="11525"
+ y="5521"
+ id="tspan314"><tspan
+ id="tspan316"
+ style="fill:#000000;stroke:none">5</tspan></tspan></tspan></text>
</g></g><g
- class="com.sun.star.drawing.LineShape"
- id="g318"><g
- id="id16"><rect
- class="BoundingBox"
- x="5199"
- y="3850"
- width="1402"
- height="301"
- id="rect321"
- style="fill:none;stroke:none" /><path
- d="m 5200,4000 970,0"
- id="path323"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 6600,4000 -450,-150 0,300 450,-150 z"
- id="path325"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
- class="com.sun.star.drawing.LineShape"
- id="g327"><g
- id="id17"><rect
- class="BoundingBox"
- x="5000"
- y="4299"
- width="1202"
- height="802"
- id="rect330"
- style="fill:none;stroke:none" /><path
- d="m 6200,4300 -842,561"
- id="path332"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 5000,5100 458,-125 -167,-249 -291,374 z"
- id="path334"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
- class="com.sun.star.drawing.LineShape"
- id="g336"><g
- id="id18"><rect
- class="BoundingBox"
- x="5399"
- y="5250"
- width="1202"
- height="301"
- id="rect339"
- style="fill:none;stroke:none" /><path
- d="m 5400,5400 770,0"
- id="path341"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 6600,5400 -450,-150 0,300 450,-150 z"
- id="path343"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
- class="com.sun.star.drawing.LineShape"
- id="g345"><g
- id="id19"><rect
- class="BoundingBox"
- x="7599"
- y="5250"
- width="1202"
- height="301"
- id="rect348"
- style="fill:none;stroke:none" /><path
- d="m 7600,5400 770,0"
- id="path350"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 8800,5400 -450,-150 0,300 450,-150 z"
- id="path352"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
- class="com.sun.star.drawing.LineShape"
- id="g354"><g
- id="id20"><rect
- class="BoundingBox"
- x="9799"
- y="5250"
- width="1402"
- height="301"
- id="rect357"
- style="fill:none;stroke:none" /><path
- d="m 9800,5400 970,0"
- id="path359"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 11200,5400 -450,-150 0,300 450,-150 z"
- id="path361"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
- class="com.sun.star.drawing.LineShape"
- id="g363"><g
- id="id21"><rect
- class="BoundingBox"
- x="9900"
- y="4200"
- width="1202"
- height="802"
- id="rect366"
- style="fill:none;stroke:none" /><path
- d="m 11100,5000 -842,-561"
- id="path368"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 9900,4200 291,374 167,-249 -458,-125 z"
- id="path370"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
- class="com.sun.star.drawing.LineShape"
- id="g372"><g
- id="id22"><rect
- class="BoundingBox"
- x="9999"
- y="3850"
- width="1402"
- height="301"
- id="rect375"
- style="fill:none;stroke:none" /><path
- d="m 10000,4000 970,0"
- id="path377"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 11400,4000 -450,-150 0,300 450,-150 z"
- id="path379"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g></g></g></g></g></svg>
+ class="com.sun.star.drawing.LineShape"
+ id="g318"><g
+ id="id16"><rect
+ class="BoundingBox"
+ x="5199"
+ y="3850"
+ width="1402"
+ height="301"
+ id="rect321"
+ style="fill:none;stroke:none" /><path
+ d="m 5200,4000 970,0"
+ id="path323"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 6600,4000 -450,-150 0,300 450,-150 z"
+ id="path325"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
+ class="com.sun.star.drawing.LineShape"
+ id="g327"><g
+ id="id17"><rect
+ class="BoundingBox"
+ x="5000"
+ y="4299"
+ width="1202"
+ height="802"
+ id="rect330"
+ style="fill:none;stroke:none" /><path
+ d="m 6200,4300 -842,561"
+ id="path332"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 5000,5100 458,-125 -167,-249 -291,374 z"
+ id="path334"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
+ class="com.sun.star.drawing.LineShape"
+ id="g336"><g
+ id="id18"><rect
+ class="BoundingBox"
+ x="5399"
+ y="5250"
+ width="1202"
+ height="301"
+ id="rect339"
+ style="fill:none;stroke:none" /><path
+ d="m 5400,5400 770,0"
+ id="path341"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 6600,5400 -450,-150 0,300 450,-150 z"
+ id="path343"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
+ class="com.sun.star.drawing.LineShape"
+ id="g345"><g
+ id="id19"><rect
+ class="BoundingBox"
+ x="7599"
+ y="5250"
+ width="1202"
+ height="301"
+ id="rect348"
+ style="fill:none;stroke:none" /><path
+ d="m 7600,5400 770,0"
+ id="path350"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 8800,5400 -450,-150 0,300 450,-150 z"
+ id="path352"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
+ class="com.sun.star.drawing.LineShape"
+ id="g354"><g
+ id="id20"><rect
+ class="BoundingBox"
+ x="9799"
+ y="5250"
+ width="1402"
+ height="301"
+ id="rect357"
+ style="fill:none;stroke:none" /><path
+ d="m 9800,5400 970,0"
+ id="path359"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 11200,5400 -450,-150 0,300 450,-150 z"
+ id="path361"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
+ class="com.sun.star.drawing.LineShape"
+ id="g363"><g
+ id="id21"><rect
+ class="BoundingBox"
+ x="9900"
+ y="4200"
+ width="1202"
+ height="802"
+ id="rect366"
+ style="fill:none;stroke:none" /><path
+ d="m 11100,5000 -842,-561"
+ id="path368"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 9900,4200 291,374 167,-249 -458,-125 z"
+ id="path370"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
+ class="com.sun.star.drawing.LineShape"
+ id="g372"><g
+ id="id22"><rect
+ class="BoundingBox"
+ x="9999"
+ y="3850"
+ width="1402"
+ height="301"
+ id="rect375"
+ style="fill:none;stroke:none" /><path
+ d="m 10000,4000 970,0"
+ id="path377"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 11400,4000 -450,-150 0,300 450,-150 z"
+ id="path379"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g></g></g></g></g></svg>
diff --git a/Documentation/media/uapi/v4l/nv12mt_example.svg b/Documentation/media/uapi/v4l/nv12mt_example.svg
index d65d989ee73b..fc51fe8fda8b 100644
--- a/Documentation/media/uapi/v4l/nv12mt_example.svg
+++ b/Documentation/media/uapi/v4l/nv12mt_example.svg
@@ -18,8 +18,8 @@
sodipodi:docname="nv12mt_example.svg"
style="fill-rule:evenodd;stroke-width:28.22200012;stroke-linejoin:round"><metadata
id="metadata953"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
@@ -58,1532 +58,1532 @@
id="g188"
transform="translate(-3285.889,-3185.889)"><g
id="id6"><rect
- class="BoundingBox"
- x="3299"
- y="3199"
- width="2403"
- height="1403"
- id="rect191"
- style="fill:none;stroke:none" /><path
- d="m 4500,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path193"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text195"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan197"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="4325"
- y="4121"
- id="tspan199"><tspan
- id="tspan201"
- style="fill:#000000;stroke:none">0</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="3299"
+ y="3199"
+ width="2403"
+ height="1403"
+ id="rect191"
+ style="fill:none;stroke:none" /><path
+ d="m 4500,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path193"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text195"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan197"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="4325"
+ y="4121"
+ id="tspan199"><tspan
+ id="tspan201"
+ style="fill:#000000;stroke:none">0</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g203"
transform="translate(-3285.889,-3185.889)"><g
id="id7"><rect
- class="BoundingBox"
- x="5699"
- y="3199"
- width="2403"
- height="1403"
- id="rect206"
- style="fill:none;stroke:none" /><path
- d="m 6900,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path208"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /></g></g><g
+ class="BoundingBox"
+ x="5699"
+ y="3199"
+ width="2403"
+ height="1403"
+ id="rect206"
+ style="fill:none;stroke:none" /><path
+ d="m 6900,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path208"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /></g></g><g
class="com.sun.star.drawing.CustomShape"
id="g210"
transform="translate(-3285.889,-3185.889)"><g
id="id8"><rect
- class="BoundingBox"
- x="8099"
- y="3199"
- width="2403"
- height="1403"
- id="rect213"
- style="fill:none;stroke:none" /><path
- d="m 9300,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path215"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text217"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan219"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="9125"
- y="4121"
- id="tspan221"><tspan
- id="tspan223"
- style="fill:#000000;stroke:none">6</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="8099"
+ y="3199"
+ width="2403"
+ height="1403"
+ id="rect213"
+ style="fill:none;stroke:none" /><path
+ d="m 9300,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path215"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text217"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan219"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="9125"
+ y="4121"
+ id="tspan221"><tspan
+ id="tspan223"
+ style="fill:#000000;stroke:none">6</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g225"
transform="translate(-3285.889,-3185.889)"><g
id="id9"><rect
- class="BoundingBox"
- x="5699"
- y="3199"
- width="2403"
- height="1403"
- id="rect228"
- style="fill:none;stroke:none" /><path
- d="m 6900,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path230"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text232"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan234"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="6725"
- y="4121"
- id="tspan236"><tspan
- id="tspan238"
- style="fill:#000000;stroke:none">1</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="5699"
+ y="3199"
+ width="2403"
+ height="1403"
+ id="rect228"
+ style="fill:none;stroke:none" /><path
+ d="m 6900,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path230"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text232"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan234"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="6725"
+ y="4121"
+ id="tspan236"><tspan
+ id="tspan238"
+ style="fill:#000000;stroke:none">1</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g240"
transform="translate(-3285.889,-3185.889)"><g
id="id10"><rect
- class="BoundingBox"
- x="10499"
- y="3199"
- width="2403"
- height="1403"
- id="rect243"
- style="fill:none;stroke:none" /><path
- d="m 11700,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path245"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text247"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan249"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="11525"
- y="4121"
- id="tspan251"><tspan
- id="tspan253"
- style="fill:#000000;stroke:none">7</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="10499"
+ y="3199"
+ width="2403"
+ height="1403"
+ id="rect243"
+ style="fill:none;stroke:none" /><path
+ d="m 11700,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path245"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text247"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan249"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="11525"
+ y="4121"
+ id="tspan251"><tspan
+ id="tspan253"
+ style="fill:#000000;stroke:none">7</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g255"
transform="translate(-3285.889,-3185.889)"><g
id="id11"><rect
- class="BoundingBox"
- x="12899"
- y="3199"
- width="2403"
- height="1403"
- id="rect258"
- style="fill:none;stroke:none" /><path
- d="m 14100,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path260"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /></g></g><g
+ class="BoundingBox"
+ x="12899"
+ y="3199"
+ width="2403"
+ height="1403"
+ id="rect258"
+ style="fill:none;stroke:none" /><path
+ d="m 14100,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path260"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /></g></g><g
class="com.sun.star.drawing.CustomShape"
id="g262"
transform="translate(-3285.889,-3185.889)"><g
id="id12"><rect
- class="BoundingBox"
- x="15299"
- y="3199"
- width="2403"
- height="1403"
- id="rect265"
- style="fill:none;stroke:none" /><path
- d="m 16500,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path267"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text269"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan271"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="16325"
- y="4121"
- id="tspan273"><tspan
- id="tspan275"
- style="fill:#000000;stroke:none">9</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="15299"
+ y="3199"
+ width="2403"
+ height="1403"
+ id="rect265"
+ style="fill:none;stroke:none" /><path
+ d="m 16500,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path267"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text269"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan271"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="16325"
+ y="4121"
+ id="tspan273"><tspan
+ id="tspan275"
+ style="fill:#000000;stroke:none">9</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g277"
transform="translate(-3285.889,-3185.889)"><g
id="id13"><rect
- class="BoundingBox"
- x="12899"
- y="3199"
- width="2403"
- height="1403"
- id="rect280"
- style="fill:none;stroke:none" /><path
- d="m 14100,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path282"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text284"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan286"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="13925"
- y="4121"
- id="tspan288"><tspan
- id="tspan290"
- style="fill:#000000;stroke:none">8</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="12899"
+ y="3199"
+ width="2403"
+ height="1403"
+ id="rect280"
+ style="fill:none;stroke:none" /><path
+ d="m 14100,4600 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path282"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text284"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan286"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="13925"
+ y="4121"
+ id="tspan288"><tspan
+ id="tspan290"
+ style="fill:#000000;stroke:none">8</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g292"
transform="translate(-3285.889,-3185.889)"><g
id="id14"><rect
- class="BoundingBox"
- x="3299"
- y="4599"
- width="2403"
- height="1403"
- id="rect295"
- style="fill:none;stroke:none" /><path
- d="m 4500,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path297"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text299"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan301"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="4325"
- y="5521"
- id="tspan303"><tspan
- id="tspan305"
- style="fill:#000000;stroke:none">2</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="3299"
+ y="4599"
+ width="2403"
+ height="1403"
+ id="rect295"
+ style="fill:none;stroke:none" /><path
+ d="m 4500,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path297"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text299"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan301"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="4325"
+ y="5521"
+ id="tspan303"><tspan
+ id="tspan305"
+ style="fill:#000000;stroke:none">2</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g307"
transform="translate(-3285.889,-3185.889)"><g
id="id15"><rect
- class="BoundingBox"
- x="5699"
- y="4599"
- width="2403"
- height="1403"
- id="rect310"
- style="fill:none;stroke:none" /><path
- d="m 6900,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path312"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /></g></g><g
+ class="BoundingBox"
+ x="5699"
+ y="4599"
+ width="2403"
+ height="1403"
+ id="rect310"
+ style="fill:none;stroke:none" /><path
+ d="m 6900,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path312"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /></g></g><g
class="com.sun.star.drawing.CustomShape"
id="g314"
transform="translate(-3285.889,-3185.889)"><g
id="id16"><rect
- class="BoundingBox"
- x="8099"
- y="4599"
- width="2403"
- height="1403"
- id="rect317"
- style="fill:none;stroke:none" /><path
- d="m 9300,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path319"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text321"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan323"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="9125"
- y="5521"
- id="tspan325"><tspan
- id="tspan327"
- style="fill:#000000;stroke:none">4</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="8099"
+ y="4599"
+ width="2403"
+ height="1403"
+ id="rect317"
+ style="fill:none;stroke:none" /><path
+ d="m 9300,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path319"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text321"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan323"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="9125"
+ y="5521"
+ id="tspan325"><tspan
+ id="tspan327"
+ style="fill:#000000;stroke:none">4</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g329"
transform="translate(-3285.889,-3185.889)"><g
id="id17"><rect
- class="BoundingBox"
- x="5699"
- y="4599"
- width="2403"
- height="1403"
- id="rect332"
- style="fill:none;stroke:none" /><path
- d="m 6900,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path334"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text336"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan338"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="6725"
- y="5521"
- id="tspan340"><tspan
- id="tspan342"
- style="fill:#000000;stroke:none">3</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="5699"
+ y="4599"
+ width="2403"
+ height="1403"
+ id="rect332"
+ style="fill:none;stroke:none" /><path
+ d="m 6900,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path334"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text336"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan338"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="6725"
+ y="5521"
+ id="tspan340"><tspan
+ id="tspan342"
+ style="fill:#000000;stroke:none">3</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g344"
transform="translate(-3285.889,-3185.889)"><g
id="id18"><rect
- class="BoundingBox"
- x="10499"
- y="4599"
- width="2403"
- height="1403"
- id="rect347"
- style="fill:none;stroke:none" /><path
- d="m 11700,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path349"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text351"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan353"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="11525"
- y="5521"
- id="tspan355"><tspan
- id="tspan357"
- style="fill:#000000;stroke:none">5</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="10499"
+ y="4599"
+ width="2403"
+ height="1403"
+ id="rect347"
+ style="fill:none;stroke:none" /><path
+ d="m 11700,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path349"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text351"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan353"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="11525"
+ y="5521"
+ id="tspan355"><tspan
+ id="tspan357"
+ style="fill:#000000;stroke:none">5</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g359"
transform="translate(-3285.889,-3185.889)"><g
id="id19"><rect
- class="BoundingBox"
- x="12899"
- y="4599"
- width="2403"
- height="1403"
- id="rect362"
- style="fill:none;stroke:none" /><path
- d="m 14100,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path364"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /></g></g><g
+ class="BoundingBox"
+ x="12899"
+ y="4599"
+ width="2403"
+ height="1403"
+ id="rect362"
+ style="fill:none;stroke:none" /><path
+ d="m 14100,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path364"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /></g></g><g
class="com.sun.star.drawing.CustomShape"
id="g366"
transform="translate(-3285.889,-3185.889)"><g
id="id20"><rect
- class="BoundingBox"
- x="15299"
- y="4599"
- width="2403"
- height="1403"
- id="rect369"
- style="fill:none;stroke:none" /><path
- d="m 16500,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path371"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text373"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan375"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="16149"
- y="5521"
- id="tspan377"><tspan
- id="tspan379"
- style="fill:#000000;stroke:none">11</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="15299"
+ y="4599"
+ width="2403"
+ height="1403"
+ id="rect369"
+ style="fill:none;stroke:none" /><path
+ d="m 16500,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path371"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text373"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan375"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="16149"
+ y="5521"
+ id="tspan377"><tspan
+ id="tspan379"
+ style="fill:#000000;stroke:none">11</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g381"
transform="translate(-3285.889,-3185.889)"><g
id="id21"><rect
- class="BoundingBox"
- x="12899"
- y="4599"
- width="2403"
- height="1403"
- id="rect384"
- style="fill:none;stroke:none" /><path
- d="m 14100,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path386"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text388"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan390"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="13749"
- y="5521"
- id="tspan392"><tspan
- id="tspan394"
- style="fill:#000000;stroke:none">10</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="12899"
+ y="4599"
+ width="2403"
+ height="1403"
+ id="rect384"
+ style="fill:none;stroke:none" /><path
+ d="m 14100,6000 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path386"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text388"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan390"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="13749"
+ y="5521"
+ id="tspan392"><tspan
+ id="tspan394"
+ style="fill:#000000;stroke:none">10</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g396"
transform="translate(-3285.889,-3185.889)"><g
id="id22"><rect
- class="BoundingBox"
- x="3299"
- y="5999"
- width="2403"
- height="1403"
- id="rect399"
- style="fill:none;stroke:none" /><path
- d="m 4500,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path401"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text403"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan405"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="4149"
- y="6921"
- id="tspan407"><tspan
- id="tspan409"
- style="fill:#000000;stroke:none">12</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="3299"
+ y="5999"
+ width="2403"
+ height="1403"
+ id="rect399"
+ style="fill:none;stroke:none" /><path
+ d="m 4500,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path401"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text403"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan405"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="4149"
+ y="6921"
+ id="tspan407"><tspan
+ id="tspan409"
+ style="fill:#000000;stroke:none">12</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g411"
transform="translate(-3285.889,-3185.889)"><g
id="id23"><rect
- class="BoundingBox"
- x="5699"
- y="5999"
- width="2403"
- height="1403"
- id="rect414"
- style="fill:none;stroke:none" /><path
- d="m 6900,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path416"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /></g></g><g
+ class="BoundingBox"
+ x="5699"
+ y="5999"
+ width="2403"
+ height="1403"
+ id="rect414"
+ style="fill:none;stroke:none" /><path
+ d="m 6900,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path416"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /></g></g><g
class="com.sun.star.drawing.CustomShape"
id="g418"
transform="translate(-3285.889,-3185.889)"><g
id="id24"><rect
- class="BoundingBox"
- x="8099"
- y="5999"
- width="2403"
- height="1403"
- id="rect421"
- style="fill:none;stroke:none" /><path
- d="m 9300,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path423"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text425"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan427"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="8949"
- y="6921"
- id="tspan429"><tspan
- id="tspan431"
- style="fill:#000000;stroke:none">18</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="8099"
+ y="5999"
+ width="2403"
+ height="1403"
+ id="rect421"
+ style="fill:none;stroke:none" /><path
+ d="m 9300,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path423"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text425"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan427"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="8949"
+ y="6921"
+ id="tspan429"><tspan
+ id="tspan431"
+ style="fill:#000000;stroke:none">18</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g433"
transform="translate(-3285.889,-3185.889)"><g
id="id25"><rect
- class="BoundingBox"
- x="5699"
- y="5999"
- width="2403"
- height="1403"
- id="rect436"
- style="fill:none;stroke:none" /><path
- d="m 6900,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path438"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text440"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan442"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="6549"
- y="6921"
- id="tspan444"><tspan
- id="tspan446"
- style="fill:#000000;stroke:none">13</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="5699"
+ y="5999"
+ width="2403"
+ height="1403"
+ id="rect436"
+ style="fill:none;stroke:none" /><path
+ d="m 6900,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path438"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text440"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan442"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="6549"
+ y="6921"
+ id="tspan444"><tspan
+ id="tspan446"
+ style="fill:#000000;stroke:none">13</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g448"
transform="translate(-3285.889,-3185.889)"><g
id="id26"><rect
- class="BoundingBox"
- x="10499"
- y="5999"
- width="2403"
- height="1403"
- id="rect451"
- style="fill:none;stroke:none" /><path
- d="m 11700,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path453"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text455"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan457"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="11349"
- y="6921"
- id="tspan459"><tspan
- id="tspan461"
- style="fill:#000000;stroke:none">19</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="10499"
+ y="5999"
+ width="2403"
+ height="1403"
+ id="rect451"
+ style="fill:none;stroke:none" /><path
+ d="m 11700,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path453"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text455"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan457"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="11349"
+ y="6921"
+ id="tspan459"><tspan
+ id="tspan461"
+ style="fill:#000000;stroke:none">19</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g463"
transform="translate(-3285.889,-3185.889)"><g
id="id27"><rect
- class="BoundingBox"
- x="12899"
- y="5999"
- width="2403"
- height="1403"
- id="rect466"
- style="fill:none;stroke:none" /><path
- d="m 14100,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path468"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /></g></g><g
+ class="BoundingBox"
+ x="12899"
+ y="5999"
+ width="2403"
+ height="1403"
+ id="rect466"
+ style="fill:none;stroke:none" /><path
+ d="m 14100,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path468"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /></g></g><g
class="com.sun.star.drawing.CustomShape"
id="g470"
transform="translate(-3285.889,-3185.889)"><g
id="id28"><rect
- class="BoundingBox"
- x="15299"
- y="5999"
- width="2403"
- height="1403"
- id="rect473"
- style="fill:none;stroke:none" /><path
- d="m 16500,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path475"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text477"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan479"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="16149"
- y="6921"
- id="tspan481"><tspan
- id="tspan483"
- style="fill:#000000;stroke:none">21</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="15299"
+ y="5999"
+ width="2403"
+ height="1403"
+ id="rect473"
+ style="fill:none;stroke:none" /><path
+ d="m 16500,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path475"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text477"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan479"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="16149"
+ y="6921"
+ id="tspan481"><tspan
+ id="tspan483"
+ style="fill:#000000;stroke:none">21</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g485"
transform="translate(-3285.889,-3185.889)"><g
id="id29"><rect
- class="BoundingBox"
- x="12899"
- y="5999"
- width="2403"
- height="1403"
- id="rect488"
- style="fill:none;stroke:none" /><path
- d="m 14100,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path490"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text492"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan494"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="13749"
- y="6921"
- id="tspan496"><tspan
- id="tspan498"
- style="fill:#000000;stroke:none">20</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="12899"
+ y="5999"
+ width="2403"
+ height="1403"
+ id="rect488"
+ style="fill:none;stroke:none" /><path
+ d="m 14100,7400 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path490"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text492"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan494"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="13749"
+ y="6921"
+ id="tspan496"><tspan
+ id="tspan498"
+ style="fill:#000000;stroke:none">20</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g500"
transform="translate(-3285.889,-3185.889)"><g
id="id30"><rect
- class="BoundingBox"
- x="3299"
- y="7399"
- width="2403"
- height="1403"
- id="rect503"
- style="fill:none;stroke:none" /><path
- d="m 4500,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path505"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text507"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan509"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="4149"
- y="8321"
- id="tspan511"><tspan
- id="tspan513"
- style="fill:#000000;stroke:none">14</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="3299"
+ y="7399"
+ width="2403"
+ height="1403"
+ id="rect503"
+ style="fill:none;stroke:none" /><path
+ d="m 4500,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path505"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text507"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan509"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="4149"
+ y="8321"
+ id="tspan511"><tspan
+ id="tspan513"
+ style="fill:#000000;stroke:none">14</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g515"
transform="translate(-3285.889,-3185.889)"><g
id="id31"><rect
- class="BoundingBox"
- x="5699"
- y="7399"
- width="2403"
- height="1403"
- id="rect518"
- style="fill:none;stroke:none" /><path
- d="m 6900,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path520"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /></g></g><g
+ class="BoundingBox"
+ x="5699"
+ y="7399"
+ width="2403"
+ height="1403"
+ id="rect518"
+ style="fill:none;stroke:none" /><path
+ d="m 6900,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path520"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /></g></g><g
class="com.sun.star.drawing.CustomShape"
id="g522"
transform="translate(-3285.889,-3185.889)"><g
id="id32"><rect
- class="BoundingBox"
- x="8099"
- y="7399"
- width="2403"
- height="1403"
- id="rect525"
- style="fill:none;stroke:none" /><path
- d="m 9300,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path527"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text529"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan531"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="8949"
- y="8321"
- id="tspan533"><tspan
- id="tspan535"
- style="fill:#000000;stroke:none">16</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="8099"
+ y="7399"
+ width="2403"
+ height="1403"
+ id="rect525"
+ style="fill:none;stroke:none" /><path
+ d="m 9300,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path527"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text529"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan531"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="8949"
+ y="8321"
+ id="tspan533"><tspan
+ id="tspan535"
+ style="fill:#000000;stroke:none">16</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g537"
transform="translate(-3285.889,-3185.889)"><g
id="id33"><rect
- class="BoundingBox"
- x="5699"
- y="7399"
- width="2403"
- height="1403"
- id="rect540"
- style="fill:none;stroke:none" /><path
- d="m 6900,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path542"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text544"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan546"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="6549"
- y="8321"
- id="tspan548"><tspan
- id="tspan550"
- style="fill:#000000;stroke:none">15</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="5699"
+ y="7399"
+ width="2403"
+ height="1403"
+ id="rect540"
+ style="fill:none;stroke:none" /><path
+ d="m 6900,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path542"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text544"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan546"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="6549"
+ y="8321"
+ id="tspan548"><tspan
+ id="tspan550"
+ style="fill:#000000;stroke:none">15</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g552"
transform="translate(-3285.889,-3185.889)"><g
id="id34"><rect
- class="BoundingBox"
- x="10499"
- y="7399"
- width="2403"
- height="1403"
- id="rect555"
- style="fill:none;stroke:none" /><path
- d="m 11700,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path557"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text559"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan561"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="11349"
- y="8321"
- id="tspan563"><tspan
- id="tspan565"
- style="fill:#000000;stroke:none">17</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="10499"
+ y="7399"
+ width="2403"
+ height="1403"
+ id="rect555"
+ style="fill:none;stroke:none" /><path
+ d="m 11700,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path557"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text559"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan561"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="11349"
+ y="8321"
+ id="tspan563"><tspan
+ id="tspan565"
+ style="fill:#000000;stroke:none">17</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g567"
transform="translate(-3285.889,-3185.889)"><g
id="id35"><rect
- class="BoundingBox"
- x="12899"
- y="7399"
- width="2403"
- height="1403"
- id="rect570"
- style="fill:none;stroke:none" /><path
- d="m 14100,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path572"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /></g></g><g
+ class="BoundingBox"
+ x="12899"
+ y="7399"
+ width="2403"
+ height="1403"
+ id="rect570"
+ style="fill:none;stroke:none" /><path
+ d="m 14100,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path572"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /></g></g><g
class="com.sun.star.drawing.CustomShape"
id="g574"
transform="translate(-3285.889,-3185.889)"><g
id="id36"><rect
- class="BoundingBox"
- x="15299"
- y="7399"
- width="2403"
- height="1403"
- id="rect577"
- style="fill:none;stroke:none" /><path
- d="m 16500,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path579"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text581"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan583"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="16149"
- y="8321"
- id="tspan585"><tspan
- id="tspan587"
- style="fill:#000000;stroke:none">23</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="15299"
+ y="7399"
+ width="2403"
+ height="1403"
+ id="rect577"
+ style="fill:none;stroke:none" /><path
+ d="m 16500,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path579"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text581"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan583"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="16149"
+ y="8321"
+ id="tspan585"><tspan
+ id="tspan587"
+ style="fill:#000000;stroke:none">23</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g589"
transform="translate(-3285.889,-3185.889)"><g
id="id37"><rect
- class="BoundingBox"
- x="12899"
- y="7399"
- width="2403"
- height="1403"
- id="rect592"
- style="fill:none;stroke:none" /><path
- d="m 14100,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path594"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text596"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan598"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="13749"
- y="8321"
- id="tspan600"><tspan
- id="tspan602"
- style="fill:#000000;stroke:none">22</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="12899"
+ y="7399"
+ width="2403"
+ height="1403"
+ id="rect592"
+ style="fill:none;stroke:none" /><path
+ d="m 14100,8800 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path594"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text596"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan598"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="13749"
+ y="8321"
+ id="tspan600"><tspan
+ id="tspan602"
+ style="fill:#000000;stroke:none">22</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g604"
transform="translate(-3285.889,-3185.889)"><g
id="id38"><rect
- class="BoundingBox"
- x="3299"
- y="8799"
- width="2403"
- height="1403"
- id="rect607"
- style="fill:none;stroke:none" /><path
- d="m 4500,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path609"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text611"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan613"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="4149"
- y="9721"
- id="tspan615"><tspan
- id="tspan617"
- style="fill:#000000;stroke:none">24</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="3299"
+ y="8799"
+ width="2403"
+ height="1403"
+ id="rect607"
+ style="fill:none;stroke:none" /><path
+ d="m 4500,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path609"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text611"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan613"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="4149"
+ y="9721"
+ id="tspan615"><tspan
+ id="tspan617"
+ style="fill:#000000;stroke:none">24</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g619"
transform="translate(-3285.889,-3185.889)"><g
id="id39"><rect
- class="BoundingBox"
- x="5699"
- y="8799"
- width="2403"
- height="1403"
- id="rect622"
- style="fill:none;stroke:none" /><path
- d="m 6900,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path624"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /></g></g><g
+ class="BoundingBox"
+ x="5699"
+ y="8799"
+ width="2403"
+ height="1403"
+ id="rect622"
+ style="fill:none;stroke:none" /><path
+ d="m 6900,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path624"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /></g></g><g
class="com.sun.star.drawing.CustomShape"
id="g626"
transform="translate(-3285.889,-3185.889)"><g
id="id40"><rect
- class="BoundingBox"
- x="8099"
- y="8799"
- width="2403"
- height="1403"
- id="rect629"
- style="fill:none;stroke:none" /><path
- d="m 9300,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path631"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text633"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan635"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="8949"
- y="9721"
- id="tspan637"><tspan
- id="tspan639"
- style="fill:#000000;stroke:none">26</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="8099"
+ y="8799"
+ width="2403"
+ height="1403"
+ id="rect629"
+ style="fill:none;stroke:none" /><path
+ d="m 9300,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path631"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text633"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan635"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="8949"
+ y="9721"
+ id="tspan637"><tspan
+ id="tspan639"
+ style="fill:#000000;stroke:none">26</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g641"
transform="translate(-3285.889,-3185.889)"><g
id="id41"><rect
- class="BoundingBox"
- x="5699"
- y="8799"
- width="2403"
- height="1403"
- id="rect644"
- style="fill:none;stroke:none" /><path
- d="m 6900,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path646"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text648"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan650"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="6549"
- y="9721"
- id="tspan652"><tspan
- id="tspan654"
- style="fill:#000000;stroke:none">25</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="5699"
+ y="8799"
+ width="2403"
+ height="1403"
+ id="rect644"
+ style="fill:none;stroke:none" /><path
+ d="m 6900,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path646"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text648"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan650"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="6549"
+ y="9721"
+ id="tspan652"><tspan
+ id="tspan654"
+ style="fill:#000000;stroke:none">25</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g656"
transform="translate(-3285.889,-3185.889)"><g
id="id42"><rect
- class="BoundingBox"
- x="10499"
- y="8799"
- width="2403"
- height="1403"
- id="rect659"
- style="fill:none;stroke:none" /><path
- d="m 11700,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path661"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text663"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan665"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="11349"
- y="9721"
- id="tspan667"><tspan
- id="tspan669"
- style="fill:#000000;stroke:none">27</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="10499"
+ y="8799"
+ width="2403"
+ height="1403"
+ id="rect659"
+ style="fill:none;stroke:none" /><path
+ d="m 11700,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path661"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text663"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan665"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="11349"
+ y="9721"
+ id="tspan667"><tspan
+ id="tspan669"
+ style="fill:#000000;stroke:none">27</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g671"
transform="translate(-3285.889,-3185.889)"><g
id="id43"><rect
- class="BoundingBox"
- x="12899"
- y="8799"
- width="2403"
- height="1403"
- id="rect674"
- style="fill:none;stroke:none" /><path
- d="m 14100,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path676"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /></g></g><g
+ class="BoundingBox"
+ x="12899"
+ y="8799"
+ width="2403"
+ height="1403"
+ id="rect674"
+ style="fill:none;stroke:none" /><path
+ d="m 14100,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path676"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /></g></g><g
class="com.sun.star.drawing.CustomShape"
id="g678"
transform="translate(-3285.889,-3185.889)"><g
id="id44"><rect
- class="BoundingBox"
- x="15299"
- y="8799"
- width="2403"
- height="1403"
- id="rect681"
- style="fill:none;stroke:none" /><path
- d="m 16500,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path683"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text685"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan687"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="16149"
- y="9721"
- id="tspan689"><tspan
- id="tspan691"
- style="fill:#000000;stroke:none">29</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="15299"
+ y="8799"
+ width="2403"
+ height="1403"
+ id="rect681"
+ style="fill:none;stroke:none" /><path
+ d="m 16500,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path683"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text685"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan687"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="16149"
+ y="9721"
+ id="tspan689"><tspan
+ id="tspan691"
+ style="fill:#000000;stroke:none">29</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.CustomShape"
id="g693"
transform="translate(-3285.889,-3185.889)"><g
id="id45"><rect
- class="BoundingBox"
- x="12899"
- y="8799"
- width="2403"
- height="1403"
- id="rect696"
- style="fill:none;stroke:none" /><path
- d="m 14100,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
- id="path698"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#3465a4" /><text
- class="TextShape"
- id="text700"><tspan
- class="TextParagraph"
- font-size="635px"
- font-weight="400"
- id="tspan702"
- style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
- class="TextPosition"
- x="13749"
- y="9721"
- id="tspan704"><tspan
- id="tspan706"
- style="fill:#000000;stroke:none">28</tspan></tspan></tspan></text>
+ class="BoundingBox"
+ x="12899"
+ y="8799"
+ width="2403"
+ height="1403"
+ id="rect696"
+ style="fill:none;stroke:none" /><path
+ d="m 14100,10200 -1200,0 0,-1400 2400,0 0,1400 -1200,0 z"
+ id="path698"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#3465a4" /><text
+ class="TextShape"
+ id="text700"><tspan
+ class="TextParagraph"
+ font-size="635px"
+ font-weight="400"
+ id="tspan702"
+ style="font-weight:400;font-size:635px;font-family:sans-serif"><tspan
+ class="TextPosition"
+ x="13749"
+ y="9721"
+ id="tspan704"><tspan
+ id="tspan706"
+ style="fill:#000000;stroke:none">28</tspan></tspan></tspan></text>
</g></g><g
class="com.sun.star.drawing.LineShape"
id="g708"
transform="translate(-3285.889,-3185.889)"><g
id="id46"><rect
- class="BoundingBox"
- x="5199"
- y="3850"
- width="1402"
- height="301"
- id="rect711"
- style="fill:none;stroke:none" /><path
- d="m 5200,4000 970,0"
- id="path713"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 6600,4000 -450,-150 0,300 450,-150 z"
- id="path715"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="5199"
+ y="3850"
+ width="1402"
+ height="301"
+ id="rect711"
+ style="fill:none;stroke:none" /><path
+ d="m 5200,4000 970,0"
+ id="path713"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 6600,4000 -450,-150 0,300 450,-150 z"
+ id="path715"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g717"
transform="translate(-3285.889,-3185.889)"><g
id="id47"><rect
- class="BoundingBox"
- x="5000"
- y="4299"
- width="1202"
- height="802"
- id="rect720"
- style="fill:none;stroke:none" /><path
- d="m 6200,4300 -842,561"
- id="path722"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 5000,5100 458,-125 -167,-249 -291,374 z"
- id="path724"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="5000"
+ y="4299"
+ width="1202"
+ height="802"
+ id="rect720"
+ style="fill:none;stroke:none" /><path
+ d="m 6200,4300 -842,561"
+ id="path722"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 5000,5100 458,-125 -167,-249 -291,374 z"
+ id="path724"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g726"
transform="translate(-3285.889,-3185.889)"><g
id="id48"><rect
- class="BoundingBox"
- x="5399"
- y="5250"
- width="1202"
- height="301"
- id="rect729"
- style="fill:none;stroke:none" /><path
- d="m 5400,5400 770,0"
- id="path731"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 6600,5400 -450,-150 0,300 450,-150 z"
- id="path733"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="5399"
+ y="5250"
+ width="1202"
+ height="301"
+ id="rect729"
+ style="fill:none;stroke:none" /><path
+ d="m 5400,5400 770,0"
+ id="path731"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 6600,5400 -450,-150 0,300 450,-150 z"
+ id="path733"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g735"
transform="translate(-3285.889,-3185.889)"><g
id="id49"><rect
- class="BoundingBox"
- x="7599"
- y="5250"
- width="1202"
- height="301"
- id="rect738"
- style="fill:none;stroke:none" /><path
- d="m 7600,5400 770,0"
- id="path740"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 8800,5400 -450,-150 0,300 450,-150 z"
- id="path742"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="7599"
+ y="5250"
+ width="1202"
+ height="301"
+ id="rect738"
+ style="fill:none;stroke:none" /><path
+ d="m 7600,5400 770,0"
+ id="path740"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 8800,5400 -450,-150 0,300 450,-150 z"
+ id="path742"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g744"
transform="translate(-3285.889,-3185.889)"><g
id="id50"><rect
- class="BoundingBox"
- x="9799"
- y="5250"
- width="1402"
- height="301"
- id="rect747"
- style="fill:none;stroke:none" /><path
- d="m 9800,5400 970,0"
- id="path749"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 11200,5400 -450,-150 0,300 450,-150 z"
- id="path751"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="9799"
+ y="5250"
+ width="1402"
+ height="301"
+ id="rect747"
+ style="fill:none;stroke:none" /><path
+ d="m 9800,5400 970,0"
+ id="path749"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 11200,5400 -450,-150 0,300 450,-150 z"
+ id="path751"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g753"
transform="translate(-3285.889,-3185.889)"><g
id="id51"><rect
- class="BoundingBox"
- x="9900"
- y="4200"
- width="1202"
- height="802"
- id="rect756"
- style="fill:none;stroke:none" /><path
- d="m 11100,5000 -842,-561"
- id="path758"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 9900,4200 291,374 167,-249 -458,-125 z"
- id="path760"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="9900"
+ y="4200"
+ width="1202"
+ height="802"
+ id="rect756"
+ style="fill:none;stroke:none" /><path
+ d="m 11100,5000 -842,-561"
+ id="path758"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 9900,4200 291,374 167,-249 -458,-125 z"
+ id="path760"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g762"
transform="translate(-3285.889,-3185.889)"><g
id="id52"><rect
- class="BoundingBox"
- x="9999"
- y="3850"
- width="1402"
- height="301"
- id="rect765"
- style="fill:none;stroke:none" /><path
- d="m 10000,4000 970,0"
- id="path767"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 11400,4000 -450,-150 0,300 450,-150 z"
- id="path769"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="9999"
+ y="3850"
+ width="1402"
+ height="301"
+ id="rect765"
+ style="fill:none;stroke:none" /><path
+ d="m 10000,4000 970,0"
+ id="path767"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 11400,4000 -450,-150 0,300 450,-150 z"
+ id="path769"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g771"
transform="translate(-3285.889,-3185.889)"><g
id="id53"><rect
- class="BoundingBox"
- x="12399"
- y="3850"
- width="1202"
- height="301"
- id="rect774"
- style="fill:none;stroke:none" /><path
- d="m 12400,4000 770,0"
- id="path776"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 13600,4000 -450,-150 0,300 450,-150 z"
- id="path778"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="12399"
+ y="3850"
+ width="1202"
+ height="301"
+ id="rect774"
+ style="fill:none;stroke:none" /><path
+ d="m 12400,4000 770,0"
+ id="path776"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 13600,4000 -450,-150 0,300 450,-150 z"
+ id="path778"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g780"
transform="translate(-3285.889,-3185.889)"><g
id="id54"><rect
- class="BoundingBox"
- x="14799"
- y="3850"
- width="1202"
- height="301"
- id="rect783"
- style="fill:none;stroke:none" /><path
- d="m 14800,4000 770,0"
- id="path785"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 16000,4000 -450,-150 0,300 450,-150 z"
- id="path787"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="14799"
+ y="3850"
+ width="1202"
+ height="301"
+ id="rect783"
+ style="fill:none;stroke:none" /><path
+ d="m 14800,4000 770,0"
+ id="path785"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 16000,4000 -450,-150 0,300 450,-150 z"
+ id="path787"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g789"
transform="translate(-3285.889,-3185.889)"><g
id="id55"><rect
- class="BoundingBox"
- x="14400"
- y="4399"
- width="1402"
- height="602"
- id="rect792"
- style="fill:none;stroke:none" /><path
- d="m 15800,4400 -1005,431"
- id="path794"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 14400,5000 473,-39 -118,-276 -355,315 z"
- id="path796"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="14400"
+ y="4399"
+ width="1402"
+ height="602"
+ id="rect792"
+ style="fill:none;stroke:none" /><path
+ d="m 15800,4400 -1005,431"
+ id="path794"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 14400,5000 473,-39 -118,-276 -355,315 z"
+ id="path796"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g798"
transform="translate(-3285.889,-3185.889)"><g
id="id56"><rect
- class="BoundingBox"
- x="14599"
- y="5250"
- width="1402"
- height="301"
- id="rect801"
- style="fill:none;stroke:none" /><path
- d="m 14600,5400 970,0"
- id="path803"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 16000,5400 -450,-150 0,300 450,-150 z"
- id="path805"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="14599"
+ y="5250"
+ width="1402"
+ height="301"
+ id="rect801"
+ style="fill:none;stroke:none" /><path
+ d="m 14600,5400 970,0"
+ id="path803"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 16000,5400 -450,-150 0,300 450,-150 z"
+ id="path805"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g807"
transform="translate(-3285.889,-3185.889)"><g
id="id57"><rect
- class="BoundingBox"
- x="5199"
- y="6550"
- width="1402"
- height="301"
- id="rect810"
- style="fill:none;stroke:none" /><path
- d="m 5200,6700 970,0"
- id="path812"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 6600,6700 -450,-150 0,300 450,-150 z"
- id="path814"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="5199"
+ y="6550"
+ width="1402"
+ height="301"
+ id="rect810"
+ style="fill:none;stroke:none" /><path
+ d="m 5200,6700 970,0"
+ id="path812"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 6600,6700 -450,-150 0,300 450,-150 z"
+ id="path814"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g816"
transform="translate(-3285.889,-3129.4446)"><g
id="id58"><rect
- class="BoundingBox"
- x="5000"
- y="6999"
- width="1202"
- height="802"
- id="rect819"
- style="fill:none;stroke:none" /><path
- d="m 6200,7000 -842,561"
- id="path821"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 5000,7800 458,-125 -167,-249 -291,374 z"
- id="path823"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="5000"
+ y="6999"
+ width="1202"
+ height="802"
+ id="rect819"
+ style="fill:none;stroke:none" /><path
+ d="m 6200,7000 -842,561"
+ id="path821"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 5000,7800 458,-125 -167,-249 -291,374 z"
+ id="path823"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g825"
transform="translate(-3285.889,-3185.889)"><g
id="id59"><rect
- class="BoundingBox"
- x="5399"
- y="7950"
- width="1202"
- height="301"
- id="rect828"
- style="fill:none;stroke:none" /><path
- d="m 5400,8100 770,0"
- id="path830"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 6600,8100 -450,-150 0,300 450,-150 z"
- id="path832"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="5399"
+ y="7950"
+ width="1202"
+ height="301"
+ id="rect828"
+ style="fill:none;stroke:none" /><path
+ d="m 5400,8100 770,0"
+ id="path830"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 6600,8100 -450,-150 0,300 450,-150 z"
+ id="path832"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g834"
transform="translate(-3285.889,-3185.889)"><g
id="id60"><rect
- class="BoundingBox"
- x="7599"
- y="7950"
- width="1202"
- height="301"
- id="rect837"
- style="fill:none;stroke:none" /><path
- d="m 7600,8100 770,0"
- id="path839"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 8800,8100 -450,-150 0,300 450,-150 z"
- id="path841"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="7599"
+ y="7950"
+ width="1202"
+ height="301"
+ id="rect837"
+ style="fill:none;stroke:none" /><path
+ d="m 7600,8100 770,0"
+ id="path839"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 8800,8100 -450,-150 0,300 450,-150 z"
+ id="path841"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g843"
transform="translate(-3285.889,-3185.889)"><g
id="id61"><rect
- class="BoundingBox"
- x="9799"
- y="7950"
- width="1402"
- height="301"
- id="rect846"
- style="fill:none;stroke:none" /><path
- d="m 9800,8100 970,0"
- id="path848"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 11200,8100 -450,-150 0,300 450,-150 z"
- id="path850"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="9799"
+ y="7950"
+ width="1402"
+ height="301"
+ id="rect846"
+ style="fill:none;stroke:none" /><path
+ d="m 9800,8100 970,0"
+ id="path848"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 11200,8100 -450,-150 0,300 450,-150 z"
+ id="path850"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g852"
transform="translate(-3285.889,-3129.4446)"><g
id="id62"><rect
- class="BoundingBox"
- x="9900"
- y="6900"
- width="1202"
- height="802"
- id="rect855"
- style="fill:none;stroke:none" /><path
- d="m 11100,7700 -842,-561"
- id="path857"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 9900,6900 291,374 167,-249 -458,-125 z"
- id="path859"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="9900"
+ y="6900"
+ width="1202"
+ height="802"
+ id="rect855"
+ style="fill:none;stroke:none" /><path
+ d="m 11100,7700 -842,-561"
+ id="path857"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 9900,6900 291,374 167,-249 -458,-125 z"
+ id="path859"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g861"
transform="translate(-3285.889,-3185.889)"><g
id="id63"><rect
- class="BoundingBox"
- x="9999"
- y="6550"
- width="1402"
- height="301"
- id="rect864"
- style="fill:none;stroke:none" /><path
- d="m 10000,6700 970,0"
- id="path866"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 11400,6700 -450,-150 0,300 450,-150 z"
- id="path868"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="9999"
+ y="6550"
+ width="1402"
+ height="301"
+ id="rect864"
+ style="fill:none;stroke:none" /><path
+ d="m 10000,6700 970,0"
+ id="path866"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 11400,6700 -450,-150 0,300 450,-150 z"
+ id="path868"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g870"
transform="translate(-3285.889,-3185.889)"><g
id="id64"><rect
- class="BoundingBox"
- x="12399"
- y="6550"
- width="1202"
- height="301"
- id="rect873"
- style="fill:none;stroke:none" /><path
- d="m 12400,6700 770,0"
- id="path875"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 13600,6700 -450,-150 0,300 450,-150 z"
- id="path877"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="12399"
+ y="6550"
+ width="1202"
+ height="301"
+ id="rect873"
+ style="fill:none;stroke:none" /><path
+ d="m 12400,6700 770,0"
+ id="path875"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 13600,6700 -450,-150 0,300 450,-150 z"
+ id="path877"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g879"
transform="translate(-3285.889,-3185.889)"><g
id="id65"><rect
- class="BoundingBox"
- x="14799"
- y="6550"
- width="1202"
- height="301"
- id="rect882"
- style="fill:none;stroke:none" /><path
- d="m 14800,6700 770,0"
- id="path884"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 16000,6700 -450,-150 0,300 450,-150 z"
- id="path886"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="14799"
+ y="6550"
+ width="1202"
+ height="301"
+ id="rect882"
+ style="fill:none;stroke:none" /><path
+ d="m 14800,6700 770,0"
+ id="path884"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 16000,6700 -450,-150 0,300 450,-150 z"
+ id="path886"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g888"
transform="translate(-3285.889,-3129.4446)"><g
id="id66"><rect
- class="BoundingBox"
- x="14400"
- y="7099"
- width="1402"
- height="602"
- id="rect891"
- style="fill:none;stroke:none" /><path
- d="m 15800,7100 -1005,431"
- id="path893"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 14400,7700 473,-39 -118,-276 -355,315 z"
- id="path895"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="14400"
+ y="7099"
+ width="1402"
+ height="602"
+ id="rect891"
+ style="fill:none;stroke:none" /><path
+ d="m 15800,7100 -1005,431"
+ id="path893"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 14400,7700 473,-39 -118,-276 -355,315 z"
+ id="path895"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g897"
transform="translate(-3285.889,-3185.889)"><g
id="id67"><rect
- class="BoundingBox"
- x="14599"
- y="7950"
- width="1402"
- height="301"
- id="rect900"
- style="fill:none;stroke:none" /><path
- d="m 14600,8100 970,0"
- id="path902"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 16000,8100 -450,-150 0,300 450,-150 z"
- id="path904"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="14599"
+ y="7950"
+ width="1402"
+ height="301"
+ id="rect900"
+ style="fill:none;stroke:none" /><path
+ d="m 14600,8100 970,0"
+ id="path902"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 16000,8100 -450,-150 0,300 450,-150 z"
+ id="path904"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g906"
transform="translate(-3285.889,-3185.889)"><g
id="id68"><rect
- class="BoundingBox"
- x="5399"
- y="9450"
- width="1202"
- height="301"
- id="rect909"
- style="fill:none;stroke:none" /><path
- d="m 5400,9600 770,0"
- id="path911"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 6600,9600 -450,-150 0,300 450,-150 z"
- id="path913"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="5399"
+ y="9450"
+ width="1202"
+ height="301"
+ id="rect909"
+ style="fill:none;stroke:none" /><path
+ d="m 5400,9600 770,0"
+ id="path911"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 6600,9600 -450,-150 0,300 450,-150 z"
+ id="path913"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g915"
transform="translate(-3285.889,-3185.889)"><g
id="id69"><rect
- class="BoundingBox"
- x="7599"
- y="9450"
- width="1202"
- height="301"
- id="rect918"
- style="fill:none;stroke:none" /><path
- d="m 7600,9600 770,0"
- id="path920"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 8800,9600 -450,-150 0,300 450,-150 z"
- id="path922"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="7599"
+ y="9450"
+ width="1202"
+ height="301"
+ id="rect918"
+ style="fill:none;stroke:none" /><path
+ d="m 7600,9600 770,0"
+ id="path920"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 8800,9600 -450,-150 0,300 450,-150 z"
+ id="path922"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g924"
transform="translate(-3285.889,-3185.889)"><g
id="id70"><rect
- class="BoundingBox"
- x="9999"
- y="9450"
- width="1202"
- height="301"
- id="rect927"
- style="fill:none;stroke:none" /><path
- d="m 10000,9600 770,0"
- id="path929"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 11200,9600 -450,-150 0,300 450,-150 z"
- id="path931"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="9999"
+ y="9450"
+ width="1202"
+ height="301"
+ id="rect927"
+ style="fill:none;stroke:none" /><path
+ d="m 10000,9600 770,0"
+ id="path929"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 11200,9600 -450,-150 0,300 450,-150 z"
+ id="path931"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g933"
transform="translate(-3285.889,-3185.889)"><g
id="id71"><rect
- class="BoundingBox"
- x="12399"
- y="9450"
- width="1202"
- height="301"
- id="rect936"
- style="fill:none;stroke:none" /><path
- d="m 12400,9600 770,0"
- id="path938"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 13600,9600 -450,-150 0,300 450,-150 z"
- id="path940"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g><g
+ class="BoundingBox"
+ x="12399"
+ y="9450"
+ width="1202"
+ height="301"
+ id="rect936"
+ style="fill:none;stroke:none" /><path
+ d="m 12400,9600 770,0"
+ id="path938"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 13600,9600 -450,-150 0,300 450,-150 z"
+ id="path940"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g><g
class="com.sun.star.drawing.LineShape"
id="g942"
transform="translate(-3285.889,-3185.889)"><g
id="id72"><rect
- class="BoundingBox"
- x="14799"
- y="9450"
- width="1202"
- height="301"
- id="rect945"
- style="fill:none;stroke:none" /><path
- d="m 14800,9600 770,0"
- id="path947"
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#ff3333" /><path
- d="m 16000,9600 -450,-150 0,300 450,-150 z"
- id="path949"
- inkscape:connector-curvature="0"
- style="fill:#ff3333;stroke:none" /></g></g></svg>
+ class="BoundingBox"
+ x="14799"
+ y="9450"
+ width="1202"
+ height="301"
+ id="rect945"
+ style="fill:none;stroke:none" /><path
+ d="m 14800,9600 770,0"
+ id="path947"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ff3333" /><path
+ d="m 16000,9600 -450,-150 0,300 450,-150 z"
+ id="path949"
+ inkscape:connector-curvature="0"
+ style="fill:#ff3333;stroke:none" /></g></g></svg>
diff --git a/Documentation/media/uapi/v4l/selection.svg b/Documentation/media/uapi/v4l/selection.svg
index d309187af967..a93e3b59786d 100644
--- a/Documentation/media/uapi/v4l/selection.svg
+++ b/Documentation/media/uapi/v4l/selection.svg
@@ -1,5812 +1,1151 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="4226.3345"
- height="1686.8481"
- id="svg2"
- sodipodi:version="0.32"
- inkscape:version="0.91 r13725"
- sodipodi:docname="selection.svg"
- inkscape:output_extension="org.inkscape.output.svg.inkscape"
- version="1.0"
- style="display:inline;enable-background:new"
- inkscape:export-filename="/home/cheeseness/Documents/LCA09/mascot/tuz_final.png"
- inkscape:export-xdpi="100.03588"
- inkscape:export-ydpi="100.03588">
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- gridtolerance="10000"
- guidetolerance="10"
- objecttolerance="10"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="0.32297491"
- inkscape:cx="2113.1672"
- inkscape:cy="843.42407"
- inkscape:document-units="px"
- inkscape:current-layer="layer16"
- showgrid="false"
- inkscape:window-width="1920"
- inkscape:window-height="997"
- inkscape:window-x="1920"
- inkscape:window-y="30"
- showguides="false"
- inkscape:guide-bbox="true"
- units="mm"
- inkscape:window-maximized="1"
- fit-margin-top="0"
- fit-margin-left="0"
- fit-margin-right="0"
- fit-margin-bottom="0" />
- <defs
- id="defs4">
- <pattern
- inkscape:collect="always"
- xlink:href="#Strips1_1"
- id="pattern5557"
- patternTransform="matrix(5.4431804,0,0,10.10048,1808.3554,-48.222348)" />
- <marker
- inkscape:stockid="Arrow1Send"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Send"
- style="overflow:visible"
- inkscape:isstock="true">
- <path
- id="path7188"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
- style="fill:#f8d615;fill-opacity:1;fill-rule:evenodd;stroke:#f8d615;stroke-width:1pt;stroke-opacity:1"
- transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
- inkscape:connector-curvature="0" />
- </marker>
- <pattern
- inkscape:isstock="true"
- inkscape:stockid="Stripes 1:1"
- id="Strips1_1"
- patternTransform="translate(0,0) scale(10,10)"
- height="1"
- width="2"
- patternUnits="userSpaceOnUse"
- inkscape:collect="always">
- <rect
- id="rect5945"
- height="2"
- width="1"
- y="-0.5"
- x="0"
- style="fill:#f815bb;stroke:none" />
- </pattern>
- <linearGradient
- id="linearGradient10954"
- osb:paint="solid">
- <stop
- style="stop-color:#d9f90b;stop-opacity:1;"
- offset="0"
- id="stop10956" />
- </linearGradient>
- <linearGradient
- id="linearGradient9165"
- osb:paint="solid">
- <stop
- style="stop-color:#000000;stop-opacity:0.31330472;"
- offset="0"
- id="stop9167" />
- </linearGradient>
- <filter
- inkscape:collect="always"
- x="-0.084654994"
- width="1.16931"
- y="-0.36592469"
- height="1.7318494"
- id="filter11361">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="4.5740586"
- id="feGaussianBlur11363" />
- </filter>
- <linearGradient
- id="linearGradient7622">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop7624" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop7626" />
- </linearGradient>
- <linearGradient
- id="linearGradient4113">
- <stop
- style="stop-color:#000000;stop-opacity:0;"
- offset="0"
- id="stop4115" />
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="1"
- id="stop4117" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient3660">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop3662" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop3664" />
- </linearGradient>
- <linearGradient
- id="linearGradient3627">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop3629" />
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="1"
- id="stop3631" />
- </linearGradient>
- <linearGradient
- id="linearGradient2843">
- <stop
- id="stop2845"
- offset="0"
- style="stop-color:#000000;stop-opacity:1;" />
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0.02188784"
- id="stop2847" />
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0.75866222"
- id="stop2849" />
- <stop
- id="stop2851"
- offset="0.88508981"
- style="stop-color:#232323;stop-opacity:1;" />
- <stop
- id="stop2853"
- offset="1"
- style="stop-color:#595959;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient8964">
- <stop
- style="stop-color:#1a1a1a;stop-opacity:1;"
- offset="0"
- id="stop8966" />
- <stop
- style="stop-color:#1a1a1a;stop-opacity:0;"
- offset="1"
- id="stop8968" />
- </linearGradient>
- <linearGradient
- id="linearGradient8952">
- <stop
- style="stop-color:#0a0c0c;stop-opacity:1;"
- offset="0"
- id="stop8954" />
- <stop
- style="stop-color:#1f2727;stop-opacity:0;"
- offset="1"
- id="stop8956" />
- </linearGradient>
- <linearGradient
- id="linearGradient8430">
- <stop
- style="stop-color:#1e2323;stop-opacity:1;"
- offset="0"
- id="stop8432" />
- <stop
- id="stop8438"
- offset="0.55992389"
- style="stop-color:#181d1d;stop-opacity:1;" />
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="1"
- id="stop8434" />
- </linearGradient>
- <linearGradient
- id="linearGradient8398">
- <stop
- style="stop-color:#283131;stop-opacity:0;"
- offset="0"
- id="stop8400" />
- <stop
- id="stop8402"
- offset="0.5125587"
- style="stop-color:#1e2424;stop-opacity:0;" />
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="1"
- id="stop8404" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient4870">
- <stop
- style="stop-color:#c7bd80;stop-opacity:1;"
- offset="0"
- id="stop4872" />
- <stop
- style="stop-color:#c7bd80;stop-opacity:0;"
- offset="1"
- id="stop4874" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient4862">
- <stop
- style="stop-color:#e2e2e2;stop-opacity:1;"
- offset="0"
- id="stop4864" />
- <stop
- style="stop-color:#e2e2e2;stop-opacity:0;"
- offset="1"
- id="stop4866" />
- </linearGradient>
- <linearGradient
- id="linearGradient4478">
- <stop
- style="stop-color:#f9eed3;stop-opacity:1;"
- offset="0"
- id="stop4480" />
- <stop
- style="stop-color:#000000;stop-opacity:0;"
- offset="1"
- id="stop4482" />
- </linearGradient>
- <linearGradient
- id="linearGradient4106">
- <stop
- style="stop-color:#d9e002;stop-opacity:1;"
- offset="0"
- id="stop4108" />
- <stop
- id="stop4114"
- offset="0.5"
- style="stop-color:#a9ae01;stop-opacity:1;" />
- <stop
- style="stop-color:#717501;stop-opacity:1;"
- offset="1"
- id="stop4110" />
- </linearGradient>
- <linearGradient
- id="linearGradient4084">
- <stop
- style="stop-color:#7d7d00;stop-opacity:1;"
- offset="0"
- id="stop4086" />
- <stop
- id="stop4088"
- offset="0.3636601"
- style="stop-color:#c6c700;stop-opacity:1;" />
- <stop
- style="stop-color:#f6f800;stop-opacity:1;"
- offset="1"
- id="stop4090" />
- </linearGradient>
- <linearGradient
- id="linearGradient4041">
- <stop
- id="stop4043"
- offset="0"
- style="stop-color:#ffff00;stop-opacity:1;" />
- <stop
- id="stop4045"
- offset="1"
- style="stop-color:#ffff00;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient4025">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop4027" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop4031" />
- </linearGradient>
- <linearGradient
- id="linearGradient4013">
- <stop
- style="stop-color:#ffff00;stop-opacity:1;"
- offset="0"
- id="stop4015" />
- <stop
- style="stop-color:#b2b200;stop-opacity:1;"
- offset="1"
- id="stop4017" />
- </linearGradient>
- <linearGradient
- id="linearGradient3985">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop3987" />
- <stop
- style="stop-color:#1d1d1d;stop-opacity:1;"
- offset="1"
- id="stop3989" />
- </linearGradient>
- <linearGradient
- id="linearGradient3961">
- <stop
- style="stop-color:#283131;stop-opacity:0;"
- offset="0"
- id="stop3963" />
- <stop
- id="stop3965"
- offset="0.5"
- style="stop-color:#1e2424;stop-opacity:1;" />
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="1"
- id="stop3967" />
- </linearGradient>
- <linearGradient
- id="linearGradient3951">
- <stop
- id="stop3953"
- offset="0"
- style="stop-color:#344040;stop-opacity:1;" />
- <stop
- style="stop-color:#222929;stop-opacity:1;"
- offset="0.5"
- id="stop3955" />
- <stop
- id="stop3957"
- offset="1"
- style="stop-color:#000000;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient3909">
- <stop
- style="stop-color:#283131;stop-opacity:1;"
- offset="0"
- id="stop3911" />
- <stop
- id="stop3917"
- offset="0.5"
- style="stop-color:#1e2424;stop-opacity:1;" />
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="1"
- id="stop3913" />
- </linearGradient>
- <linearGradient
- id="linearGradient3537">
- <stop
- style="stop-color:#ada469;stop-opacity:1;"
- offset="0"
- id="stop3539" />
- <stop
- id="stop3545"
- offset="0.81132078"
- style="stop-color:#ada469;stop-opacity:1;" />
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="1"
- id="stop3541" />
- </linearGradient>
- <linearGradient
- id="linearGradient3317">
- <stop
- style="stop-color:#cfc690;stop-opacity:1"
- offset="0"
- id="stop3319" />
- <stop
- id="stop3321"
- offset="0.21161865"
- style="stop-color:#afa775;stop-opacity:1;" />
- <stop
- id="stop3323"
- offset="0.53408515"
- style="stop-color:#615c3a;stop-opacity:1;" />
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0.76504093"
- id="stop3325" />
- <stop
- id="stop3327"
- offset="1"
- style="stop-color:#403518;stop-opacity:1;" />
- </linearGradient>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3317"
- id="radialGradient3315"
- cx="543.6698"
- cy="147.3131"
- fx="543.6698"
- fy="147.3131"
- r="47.863216"
- gradientTransform="matrix(2.1382256,0,0,2.3382884,-77.03847,-101.68704)"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3537"
- id="radialGradient3543"
- cx="385"
- cy="237.00504"
- fx="385"
- fy="237.00504"
- r="86.928574"
- gradientTransform="matrix(1,0,0,0.8562038,0,34.080427)"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3909"
- id="radialGradient3915"
- cx="418.30365"
- cy="342.47794"
- fx="418.30365"
- fy="342.47794"
- r="131.4509"
- gradientTransform="matrix(1.3957347,0.6211056,-0.4244067,0.9537174,-15.061913,-227.96711)"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3951"
- id="radialGradient3933"
- cx="397.16388"
- cy="336.95245"
- fx="397.16388"
- fy="336.95245"
- r="36.75"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.9449972,2.4894837e-7,-2.4894833e-7,1.9449969,-375.31868,-318.41912)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3961"
- id="linearGradient3959"
- x1="398.21429"
- y1="343.52289"
- x2="379.28571"
- y2="265.30862"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(450.03125,73.843964)" />
- <filter
- inkscape:collect="always"
- id="filter3981"
- x="-0.30000001"
- width="1.6"
- y="-0.30000001"
- height="1.6">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="2"
- id="feGaussianBlur3983" />
- </filter>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3985"
- id="radialGradient3991"
- cx="402.48898"
- cy="317.23578"
- fx="402.48898"
- fy="317.23578"
- r="23.714285"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(4.3776616,0,0,4.3776616,-1358.3025,-1070.7357)" />
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3999">
- <path
- style="display:inline;opacity:1;fill:#f5ff04;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 179.64286,267.36218 c -22.41044,39.70292 -60.6161,115.78029 -69.28571,149.64286 -8.64721,33.7751 -8.77199,66.41654 -0.35715,86.42858 8.3602,19.88213 26.16398,35.6328 40.71428,41.42856 -0.59638,-14.37587 14.37295,-43.28583 72.85715,-72.5 58.62627,-29.28514 78.38163,-27.13086 103.57142,-47.14286 25.63006,-20.36176 12.61031,-67.04463 3.21429,-93.92857 -9.43424,-26.99328 -34.96741,-59.12448 -66.42857,-69.64285 -31.03327,-10.37532 -65.01776,-4.84837 -84.28571,5.71428 z"
- id="path4001"
- sodipodi:nodetypes="czzczzzzc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4013"
- id="radialGradient4056"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.1323239,0.7659488,-1.4550286,2.1510098,588.75376,-711.79716)"
- cx="228.81355"
- cy="440.26971"
- fx="228.81355"
- fy="440.26971"
- r="119.17509" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4041"
- id="radialGradient4060"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.05911206,2.6869855,-0.7234268,0.01591495,408.72779,-424.56452)"
- cx="275.4422"
- cy="335.34866"
- fx="275.4422"
- fy="335.34866"
- r="36.75" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4025"
- id="radialGradient4062"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.05911206,2.6869855,-0.7234268,0.01591495,408.72779,-424.56452)"
- cx="275.4422"
- cy="335.34866"
- fx="275.4422"
- fy="335.34866"
- r="36.75" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4084"
- id="linearGradient4082"
- gradientUnits="userSpaceOnUse"
- x1="182.35046"
- y1="256.11136"
- x2="145.53348"
- y2="542.20502" />
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath4100">
- <path
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.9000755px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 265.93541,126.68393 -18.76721,168.86308 174.10543,-73.12068 61.9544,88.65883 57.8844,-31.9903 -37.53442,-180.059677 -237.6426,27.648747 z"
- id="path4102"
- sodipodi:nodetypes="ccccccc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4106"
- id="radialGradient4112"
- cx="250.22678"
- cy="475.09763"
- fx="250.22678"
- fy="475.09763"
- r="95.98877"
- gradientTransform="matrix(1.2259004,-0.7077739,0.1413989,0.2449102,322.22326,608.91815)"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4478"
- id="linearGradient4484"
- x1="412.08926"
- y1="404.91574"
- x2="417.375"
- y2="401.82648"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4478"
- id="linearGradient4486"
- x1="411.91071"
- y1="404.91577"
- x2="417.375"
- y2="401.82648"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4478"
- id="linearGradient4488"
- x1="411.91071"
- y1="405.54077"
- x2="417.375"
- y2="401.82648"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4478"
- id="linearGradient4490"
- x1="412.08926"
- y1="405.54077"
- x2="417.375"
- y2="401.82648"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4478"
- id="linearGradient4492"
- x1="411.73212"
- y1="405.54077"
- x2="417.375"
- y2="401.82648"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4862"
- id="radialGradient4868"
- cx="429.56738"
- cy="377.42877"
- fx="429.56738"
- fy="377.42877"
- r="72.079735"
- gradientTransform="matrix(1,0,0,0.618034,0,144.16496)"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4870"
- id="radialGradient4876"
- cx="437.6991"
- cy="391.21735"
- fx="437.6991"
- fy="391.21735"
- r="36.611931"
- gradientTransform="matrix(1,0,0,0.618034,0,149.43174)"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4013"
- id="radialGradient3585"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.1323239,0.7659488,-1.4550286,2.1510098,588.75376,-711.79716)"
- cx="228.81355"
- cy="440.26971"
- fx="228.81355"
- fy="440.26971"
- r="119.17509" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4084"
- id="linearGradient3587"
- gradientUnits="userSpaceOnUse"
- x1="182.35046"
- y1="256.11136"
- x2="145.53348"
- y2="542.20502" />
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8514">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 352.24553,211.99185 c -3.80443,-25.26423 -16.80972,-50.63802 -17.1568,-75.52523 -0.18626,-13.35552 3.27285,-26.57091 13.75553,-39.554046 36.34702,-65.295835 116.94091,-84.694685 185.93466,-91.465427 86.92239,-11.016801 184.91267,17.940072 233.37134,95.401283 54.12402,75.7333 56.67476,172.53912 80.61204,259.52795 29.43779,127.1276 54.77914,256.21414 60.39224,386.85035 -3.06348,78.18185 -8.42634,165.18415 -60.50321,228.13413 -48.02654,50.35744 -122.78647,50.05304 -187.06988,59.00234 -90.55539,4.655 -184.35153,-16.1458 -261.7839,-64.19824 -64.77564,-37.94001 -95.73019,-113.47863 -97.2794,-186.01958 -8.38917,-79.87516 26.39152,-153.80851 51.6204,-227.15961 7.47061,-82.76107 9.41286,-166.24775 9.65334,-249.38484 -0.83682,-32.19544 -7.08953,-63.81733 -11.54636,-95.60908 z"
- id="path8516"
- sodipodi:nodetypes="cscccccccccccc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8604">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 352.24553,211.99185 c -3.80443,-25.26423 -16.80972,-50.63802 -17.1568,-75.52523 -0.18626,-13.35552 3.27285,-26.57091 13.75553,-39.554046 36.34702,-65.295835 116.94091,-84.694685 185.93466,-91.465427 86.92239,-11.016801 184.91267,17.940072 233.37134,95.401283 54.12402,75.7333 56.67476,172.53912 80.61204,259.52795 29.43779,127.1276 54.77914,256.21414 60.39224,386.85035 -3.06348,78.18185 -8.42634,165.18415 -60.50321,228.13413 -48.02654,50.35744 -122.78647,50.05304 -187.06988,59.00234 -90.55539,4.655 -184.35153,-16.1458 -261.7839,-64.19824 -64.77564,-37.94001 -95.73019,-113.47863 -97.2794,-186.01958 -8.38917,-79.87516 26.39152,-153.80851 51.6204,-227.15961 7.47061,-82.76107 9.41286,-166.24775 9.65334,-249.38484 -0.83682,-32.19544 -7.08953,-63.81733 -11.54636,-95.60908 z"
- id="path8606"
- sodipodi:nodetypes="cscccccccccccc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8610">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 352.24553,211.99185 c -3.80443,-25.26423 -16.80972,-50.63802 -17.1568,-75.52523 -0.18626,-13.35552 3.27285,-26.57091 13.75553,-39.554046 36.34702,-65.295835 116.94091,-84.694685 185.93466,-91.465427 86.92239,-11.016801 184.91267,17.940072 233.37134,95.401283 54.12402,75.7333 56.67476,172.53912 80.61204,259.52795 29.43779,127.1276 54.77914,256.21414 60.39224,386.85035 -3.06348,78.18185 -8.42634,165.18415 -60.50321,228.13413 -48.02654,50.35744 -122.78647,50.05304 -187.06988,59.00234 -90.55539,4.655 -184.35153,-16.1458 -261.7839,-64.19824 -64.77564,-37.94001 -95.73019,-113.47863 -97.2794,-186.01958 -8.38917,-79.87516 26.39152,-153.80851 51.6204,-227.15961 7.47061,-82.76107 9.41286,-166.24775 9.65334,-249.38484 -0.83682,-32.19544 -7.08953,-63.81733 -11.54636,-95.60908 z"
- id="path8612"
- sodipodi:nodetypes="cscccccccccccc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8616">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 352.24553,211.99185 c -3.80443,-25.26423 -16.80972,-50.63802 -17.1568,-75.52523 -0.18626,-13.35552 3.27285,-26.57091 13.75553,-39.554046 36.34702,-65.295835 116.94091,-84.694685 185.93466,-91.465427 86.92239,-11.016801 184.91267,17.940072 233.37134,95.401283 54.12402,75.7333 56.67476,172.53912 80.61204,259.52795 29.43779,127.1276 54.77914,256.21414 60.39224,386.85035 -3.06348,78.18185 -8.42634,165.18415 -60.50321,228.13413 -48.02654,50.35744 -122.78647,50.05304 -187.06988,59.00234 -90.55539,4.655 -184.35153,-16.1458 -261.7839,-64.19824 -64.77564,-37.94001 -95.73019,-113.47863 -97.2794,-186.01958 -8.38917,-79.87516 26.39152,-153.80851 51.6204,-227.15961 7.47061,-82.76107 9.41286,-166.24775 9.65334,-249.38484 -0.83682,-32.19544 -7.08953,-63.81733 -11.54636,-95.60908 z"
- id="path8618"
- sodipodi:nodetypes="cscccccccccccc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8622">
- <path
- style="display:inline;opacity:1;fill:#202020;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 821.64329,477.88997 c 0,0 22.61947,-6.50681 35.74275,-5.87273 13.12328,0.63409 30.64158,1.93862 43.70885,12.18619 13.06727,10.24756 25.06774,27.14007 34.11239,58.36965 9.04465,31.22958 1.69832,99.25201 -6.17603,143.34735 -7.87435,44.09534 -28.2651,106.11298 -45,140 -16.7349,33.88702 -49.79771,77.4952 -60.56943,89.87616 -11.36422,13.06197 -56.20589,36.42617 -79.43057,42.26667 5.3033,-10.6066 48.89976,-50.58884 35,-60.71426 -14.01897,-10.21226 -45.76009,45.98236 -84.29315,29.03317 21.38231,-13.13212 41.7794,-51.18606 34.04061,-66.59445 -7.84025,-15.61039 -30.70493,48.75757 -93.53554,37.01288 30.05204,-27.52666 55.40706,-70.90401 41.2627,-82.9797 -14.41516,-12.30687 -60.46175,54.29315 -60.46175,54.29315 0,0 -2.8219,-41.70118 13.7732,-68.60732 16.63935,-26.97787 79.65297,-81.61527 99.55313,-111.70342 19.90015,-30.08814 33.61256,-66.00902 42.13542,-92.51794 8.52286,-26.50892 15.80094,-77.09954 15.80094,-77.09954"
- id="path8624"
- sodipodi:nodetypes="czzzzzzczczczczzzc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8642">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#0f0f0f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 366.88839,504.13471 c 0,0 -29.55406,40.57305 -47.85714,74.28571 -18.30309,33.71267 -58.62109,126.35694 -70.35714,171.07143 -11.7594,44.80344 -62.5,123.57144 -62.5,123.57144 l 76.07143,18.21428 c 0,0 11.80712,-12.82335 31.07142,-46.07143 19.2643,-33.24808 60.35715,-138.57143 60.35715,-138.57143 l 13.21428,-202.5 z"
- id="path8644"
- sodipodi:nodetypes="czzcczcc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8658">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#0b0b0b;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 569.03125,1018.7776 c -4.28571,0.7143 -27.62815,3.6181 -57.85714,10 -30.22899,6.3819 -99.77493,25.9619 -142.85715,35.7143 -43.08222,9.7524 -117.26443,34.816 -156.91262,27.2654 -39.64818,-7.5506 -89.51595,-64.4083 -89.51595,-64.4083 l 4.28572,-94.28571 c 0,0 85.88551,-16.20094 112.14285,-33.57143 26.25735,-17.37049 45.58238,-49.66598 59.28572,-71.42857 13.70334,-21.76259 32.85714,-71.42858 32.85714,-71.42858 l 238.57143,262.14289 z"
- id="path8660"
- sodipodi:nodetypes="czzzcczzcc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8802"
- x="-0.35311759"
- width="1.7062352"
- y="-0.1817714"
- height="1.3635428">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="48.038491"
- id="feGaussianBlur8804" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter8806"
- x="-0.61142862"
- width="2.2228572"
- y="-0.14930232"
- height="1.2986046">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="37.830213"
- id="feGaussianBlur8808" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter8810"
- x="-0.23519406"
- width="1.4703881"
- y="-0.24500646"
- height="1.4900129">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="58.328041"
- id="feGaussianBlur8812" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter8814"
- x="-0.20466694"
- width="1.4093339"
- y="-0.29007819"
- height="1.5801564">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="22.300169"
- id="feGaussianBlur8816" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter8818"
- x="-0.34381232"
- width="1.6876246"
- y="-0.18433961"
- height="1.3686792">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="34.542167"
- id="feGaussianBlur8820" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter8822"
- x="-0.2742857"
- width="1.5485713"
- y="-0.21333334"
- height="1.4266667">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="11.313708"
- id="feGaussianBlur8824" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter8826"
- x="-0.25894088"
- width="1.5178818"
- y="-0.2236412"
- height="1.4472824">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="19.631544"
- id="feGaussianBlur8828" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter8856"
- x="-0.3253231"
- width="1.6506462"
- y="-0.19013336"
- height="1.3802667">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="28.712591"
- id="feGaussianBlur8858" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter8860"
- x="-0.38093024"
- width="1.7618605"
- y="-0.17518716"
- height="1.3503743">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="19.304015"
- id="feGaussianBlur8862" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter8888"
- x="-0.2112188"
- width="1.4224375"
- y="-0.16808605"
- height="1.3361721">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="8.3693583"
- id="feGaussianBlur8890" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter8892"
- x="-0.18692794"
- width="1.3738559"
- y="-0.23646873"
- height="1.4729375">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="31.21228"
- id="feGaussianBlur8894" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8906">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 352.24553,211.99185 c -3.80443,-25.26423 -16.80972,-50.63802 -17.1568,-75.52523 -0.18626,-13.35552 3.27285,-26.57091 13.75553,-39.554046 36.34702,-65.295835 116.94091,-84.694685 185.93466,-91.465427 86.92239,-11.016801 184.91267,17.940072 233.37134,95.401283 54.12402,75.7333 56.67476,172.53912 80.61204,259.52795 29.43779,127.1276 54.77914,256.21414 60.39224,386.85035 -3.06348,78.18185 -8.42634,165.18415 -60.50321,228.13413 -48.02654,50.35744 -122.78647,50.05304 -187.06988,59.00234 -90.55539,4.655 -184.35153,-16.1458 -261.7839,-64.19824 -64.77564,-37.94001 -95.73019,-113.47863 -97.2794,-186.01958 -8.38917,-79.87516 26.39152,-153.80851 51.6204,-227.15961 7.47061,-82.76107 9.41286,-166.24775 9.65334,-249.38484 -0.83682,-32.19544 -7.08953,-63.81733 -11.54636,-95.60908 z"
- id="path8908"
- sodipodi:nodetypes="cscccccccccccc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8940"
- x="-0.25152978"
- width="1.5030596"
- y="-0.053035267"
- height="1.1060705">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="13.024603"
- id="feGaussianBlur8942" />
- </filter>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient8952"
- id="linearGradient8958"
- x1="609.31244"
- y1="239.46866"
- x2="560.83142"
- y2="262.86206"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(450.03125,73.843964)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient8964"
- id="linearGradient8970"
- x1="603.84064"
- y1="627.85303"
- x2="616.24396"
- y2="585.42664"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(450.03125,73.843964)" />
- <filter
- inkscape:collect="always"
- id="filter9020"
- x="-0.32861114"
- width="1.6572223"
- y="-0.182"
- height="1.364">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="20.912684"
- id="feGaussianBlur9022" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter9024"
- x="-0.55453134"
- width="2.1090627"
- y="-0.51434779"
- height="2.0286956">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="20.912684"
- id="feGaussianBlur9026" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter9044"
- x="-0.32631579"
- width="1.6526316"
- y="-0.84545463"
- height="2.6909094">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="21.92031"
- id="feGaussianBlur9046" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter9048"
- x="-0.40879121"
- width="1.8175824"
- y="-0.71538466"
- height="2.4307692">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="21.92031"
- id="feGaussianBlur9050" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3587"
- x="-0.1">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="8.881432"
- id="feGaussianBlur3589" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3602">
- <path
- sodipodi:nodetypes="czzzzzzczczczczzzc"
- id="path3604"
- d="m 647.61204,540.04601 c 0,0 22.61947,-6.50681 35.74275,-5.87273 13.12328,0.63409 30.64158,1.93862 43.70885,12.18619 13.06727,10.24756 25.06774,27.14007 34.11239,58.36965 9.04465,31.22958 1.69832,99.25201 -6.17603,143.34735 -7.87435,44.09534 -28.2651,106.11298 -45,140 -16.7349,33.88702 -49.79771,77.4952 -60.56943,89.87616 -11.36422,13.06197 -56.20589,36.42617 -79.43057,42.26667 5.3033,-10.6066 48.89976,-50.58884 35,-60.71426 -14.01897,-10.21226 -45.76009,45.98236 -84.29315,29.03317 21.38231,-13.13212 41.7794,-51.18606 34.04061,-66.59445 -7.84025,-15.61039 -30.70493,48.75757 -93.53554,37.01288 30.05204,-27.52666 55.40706,-70.90401 41.2627,-82.9797 -14.41516,-12.30687 -60.46175,54.29315 -60.46175,54.29315 0,0 -2.8219,-41.70118 13.7732,-68.60732 16.63935,-26.97787 79.65297,-81.61527 99.55313,-111.70342 19.90015,-30.08814 33.61256,-66.00902 42.13542,-92.51794 8.52286,-26.50892 15.80094,-77.09954 15.80094,-77.09954"
- style="display:inline;opacity:1;fill:#202020;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter4120"
- x="-0.2770822"
- width="1.5541644"
- y="-0.32482043"
- height="1.6496409">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="19.956289"
- id="feGaussianBlur4122" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3631">
- <path
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 760.16396,935.83377 c 6.7941,18.90279 10.49369,33.29969 11.8903,51.21189 1.39662,17.91234 -3.78268,51.80084 -2.90046,70.65614 0.88175,18.8452 8.13369,40.099 27.34463,48.9689 19.41887,8.9658 49.31924,10.2113 74.11984,-3.1456 24.8006,-13.357 57.40102,-70.3255 70.97426,-97.3087 13.62385,-27.08394 38.76107,-114.49737 44.6608,-149.76859 5.89973,-35.27121 2.55054,-41.30077 -4.61748,-49.05549 2.6403,-27.84015 -1.49972,-54.93543 13.10969,-87.18618 -30.24901,11.8257 -37.38229,40.1607 -48.31889,65.50508 -8.00091,-50.93293 0.20916,-71.27319 3.31889,-101.21936 -29.06476,14.77791 -42.86151,47.11402 -45,92.85714 -10.92395,-1.3042 -21.39144,-4.43423 -33.57143,-0.71429 -0.26404,-46.02334 -1.46356,-76.88941 8.91063,-114.20649 -53.25547,21.02686 -62.94728,106.5941 -56.05349,112.77792 -10.88282,0.535 -21.37108,-1.2973 -32.85714,2.85715 0.63892,-42.57135 -0.26046,-84.90861 -30,-122.85715 0,0 -30.95806,80.92234 -31.42857,103.57143 -0.47051,22.64909 9.45159,40.16588 9.45159,40.16588 0,0 -8.56807,36.74051 -6.29859,58.23223 2.29585,21.74146 20.4429,59.67617 27.26542,78.65809 z"
- id="path3633"
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3665">
- <path
- sodipodi:nodetypes="czzcczcc"
- id="path3667"
- d="m 366.88839,504.13471 c 0,0 -29.55406,40.57305 -47.85714,74.28571 -18.30309,33.71267 -58.62109,126.35694 -70.35714,171.07143 -11.7594,44.80344 -62.5,123.57144 -62.5,123.57144 l 76.07143,18.21428 c 0,0 11.80712,-12.82335 31.07142,-46.07143 19.2643,-33.24808 60.35715,-138.57143 60.35715,-138.57143 l 13.21428,-202.5 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#0f0f0f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3677">
- <path
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 586.13271,997.98981 c 6.7941,18.90279 10.49369,33.29969 11.8903,51.21189 1.39662,17.9123 -3.78268,51.8008 -2.90046,70.6561 0.88175,18.8452 8.13369,40.099 27.34463,48.9689 19.41887,8.9658 49.31924,10.2113 74.11984,-3.1456 24.8006,-13.357 57.40102,-70.3255 70.97426,-97.3087 13.62385,-27.0839 38.76107,-114.49733 44.6608,-149.76855 5.89973,-35.27121 2.55054,-41.30077 -4.61748,-49.05549 2.6403,-27.84015 -1.49972,-54.93543 13.10969,-87.18618 -30.24901,11.8257 -37.38229,40.1607 -48.31889,65.50508 -8.00091,-50.93293 0.20916,-71.27319 3.31889,-101.21936 -29.06476,14.77791 -42.86151,47.11402 -45,92.85714 -10.92395,-1.3042 -21.39144,-4.43423 -33.57143,-0.71429 -0.26404,-46.02334 -1.46356,-76.88941 8.91063,-114.20649 -53.25547,21.02686 -62.94728,106.5941 -56.05349,112.77792 -10.88282,0.535 -21.37108,-1.2973 -32.85714,2.85715 0.63892,-42.57135 -0.26046,-84.90861 -30,-122.85715 0,0 -30.95806,80.92234 -31.42857,103.57143 -0.47051,22.64909 9.45159,40.16588 9.45159,40.16588 0,0 -8.56807,36.74051 -6.29859,58.23223 2.29585,21.74146 20.4429,59.67617 27.26542,78.65809 z"
- id="path3679"
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter3898">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="10.892985"
- id="feGaussianBlur3900" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter4130"
- x="-0.49509686"
- width="1.9901937"
- y="-0.26708817"
- height="1.5341763">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="10.730622"
- id="feGaussianBlur4132" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter4141"
- x="-0.40611032"
- width="1.8122206"
- y="-0.30260596"
- height="1.6052119">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="9.8586086"
- id="feGaussianBlur4143" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath4177">
- <path
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- id="path4179"
- d="m 586.13271,997.98981 c 6.7941,18.90279 10.49369,33.29969 11.8903,51.21189 1.39662,17.9123 -3.78268,51.8008 -2.90046,70.6561 0.88175,18.8452 8.13369,40.099 27.34463,48.9689 19.41887,8.9658 49.31924,10.2113 74.11984,-3.1456 24.8006,-13.357 57.40102,-70.3255 70.97426,-97.3087 13.62385,-27.0839 38.76107,-114.49733 44.6608,-149.76855 5.89973,-35.27121 2.55054,-41.30077 -4.61748,-49.05549 2.6403,-27.84015 -1.49972,-54.93543 13.10969,-87.18618 -30.24901,11.8257 -37.38229,40.1607 -48.31889,65.50508 -8.00091,-50.93293 0.20916,-71.27319 3.31889,-101.21936 -29.06476,14.77791 -42.86151,47.11402 -45,92.85714 -10.92395,-1.3042 -21.39144,-4.43423 -33.57143,-0.71429 -0.26404,-46.02334 -1.46356,-76.88941 8.91063,-114.20649 -53.25547,21.02686 -62.94728,106.5941 -56.05349,112.77792 -10.88282,0.535 -21.37108,-1.2973 -32.85714,2.85715 0.63892,-42.57135 -0.26046,-84.90861 -30,-122.85715 0,0 -30.95806,80.92234 -31.42857,103.57143 -0.47051,22.64909 9.45159,40.16588 9.45159,40.16588 0,0 -8.56807,36.74051 -6.29859,58.23223 2.29585,21.74146 20.4429,59.67617 27.26542,78.65809 z"
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter4185">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="3.6164709"
- id="feGaussianBlur4187" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter4105">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="3.8640966"
- id="feGaussianBlur4107" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath2833">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#292929;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 569.03125,1018.7776 c -4.28571,0.7143 -27.62815,3.6181 -57.85714,10 -30.22899,6.3819 -57.31395,4.9661 -135.78608,17.3296 -79.85178,12.5808 -94.06436,42.5423 -108.12225,47.0643 -14.70014,4.7286 -145.37739,-65.8225 -145.37739,-65.8225 l 4.28572,-94.28571 c 0,0 85.88551,-16.20094 112.14285,-33.57143 26.25735,-17.37049 45.58238,-49.66598 59.28572,-71.42857 13.70334,-21.76259 32.85714,-71.42858 32.85714,-71.42858 l 238.57143,262.14289 z"
- id="path2835"
- sodipodi:nodetypes="czzzcczzcc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2843"
- id="linearGradient2841"
- gradientUnits="userSpaceOnUse"
- x1="347.89655"
- y1="1070.2124"
- x2="275.58191"
- y2="867.97992" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3627"
- id="linearGradient3688"
- gradientUnits="userSpaceOnUse"
- x1="699.32867"
- y1="269.76755"
- x2="698.97504"
- y2="346.1351" />
- <mask
- maskUnits="userSpaceOnUse"
- id="mask3684">
- <ellipse
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient3688);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.43724918px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="path3686"
- transform="translate(-174.03125,62.156036)"
- cx="579.474"
- cy="260.57516"
- rx="192.6866"
- ry="164.04877" />
- </mask>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3622">
- <path
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 266.27183,924.57186 c -1.40727,18.80121 -1.1449,32.75103 2.08174,49.30328 3.22665,16.55234 16.40608,45.90736 20.3344,63.18376 3.92622,17.2671 2.69413,38.3096 -12.45944,51.1482 -15.31761,12.9774 -42.05127,21.5989 -67.8323,15.7338 -25.78106,-5.8653 -69.54907,-49.2234 -88.59019,-70.2283 C 100.6939,1012.6293 56.045183,939.86194 41.867508,909.43681 27.689836,879.01169 29.207903,872.71824 33.747793,863.90708 24.381071,839.38658 21.334081,813.84027 0.03533552,788.33044 30.360815,791.44488 43.915625,815.28677 60.161025,835.47019 54.631129,787.39416 42.10631,771.05369 31.787073,744.74589 c 29.994295,6.08166 50.57936,31.8724 63.979783,72.7125 9.554154,-3.91791 18.237764,-9.37294 30.187414,-9.0612 -11.2975,-41.6958 -17.94946,-69.91584 -36.687255,-101.06994 53.441965,5.67033 83.657025,80.63932 78.971425,87.9608 9.97797,-2.24399 19.00565,-6.53038 30.43653,-5.65167 -11.24896,-38.34702 -21.04781,-76.8679 -3.65971,-118.64818 0,0 48.28678,65.43687 54.38966,85.80577 6.10287,20.36891 1.51881,38.70052 1.51881,38.70052 0,0 16.95957,31.08529 20.29392,51.09413 3.3731,20.24135 -3.53269,59.10332 -4.94582,77.98324 z"
- id="path3624"
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3636">
- <path
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 760.16396,935.83377 c 6.7941,18.90279 10.49369,33.29969 11.8903,51.21189 1.39662,17.91234 -3.78268,51.80084 -2.90046,70.65614 0.88175,18.8452 8.13369,40.099 27.34463,48.9689 19.41887,8.9658 49.31924,10.2113 74.11984,-3.1456 24.8006,-13.357 57.40102,-70.3255 70.97426,-97.3087 13.62385,-27.08394 38.76107,-114.49737 44.6608,-149.76859 5.89973,-35.27121 2.55054,-41.30077 -4.61748,-49.05549 2.6403,-27.84015 -1.49972,-54.93543 13.10969,-87.18618 -30.24901,11.8257 -37.38229,40.1607 -48.31889,65.50508 -8.00091,-50.93293 0.20916,-71.27319 3.31889,-101.21936 -29.06476,14.77791 -42.86151,47.11402 -45,92.85714 -10.92395,-1.3042 -21.39144,-4.43423 -33.57143,-0.71429 -0.26404,-46.02334 -1.46356,-76.88941 8.91063,-114.20649 -53.25547,21.02686 -62.94728,106.5941 -56.05349,112.77792 -10.88282,0.535 -21.37108,-1.2973 -32.85714,2.85715 0.63892,-42.57135 -0.26046,-84.90861 -30,-122.85715 0,0 -30.95806,80.92234 -31.42857,103.57143 -0.47051,22.64909 9.45159,40.16588 9.45159,40.16588 0,0 -8.56807,36.74051 -6.29859,58.23223 2.29585,21.74146 20.4429,59.67617 27.26542,78.65809 z"
- id="path3638"
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- inkscape:connector-curvature="0" />
- </clipPath>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3660"
- id="linearGradient3666"
- x1="1255.7386"
- y1="667.09216"
- x2="893.69995"
- y2="858.01099"
- gradientUnits="userSpaceOnUse" />
- <filter
- inkscape:collect="always"
- id="filter3779"
- x="-0.087980822"
- width="1.1759616"
- y="-0.17728332"
- height="1.3545666">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="16.340344"
- id="feGaussianBlur3781" />
- </filter>
- <filter
- id="filter3785"
- inkscape:label="White Fur">
- <feTurbulence
- id="feTurbulence3787"
- type="fractalNoise"
- baseFrequency="0.24044943820224721"
- numOctaves="10"
- seed="655"
- result="result0" />
- <feDisplacementMap
- id="feDisplacementMap3789"
- in="SourceGraphic"
- in2="result0"
- scale="62"
- xChannelSelector="B"
- yChannelSelector="G" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3677">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="2.0397518"
- id="feGaussianBlur3679" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3722">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#121212;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 709.28572,844.50504 c 54.28571,-1.42857 126.035,-15.05199 170,-26.78572 44.05271,-11.75714 125.88628,-36.34724 175.35708,-57.85714 49.3393,-21.45272 113.6037,-59.2816 154.2858,-92.14285 40.5081,-32.72069 52.3899,-55.81981 60.7143,-33.57143 8.3691,22.36779 -16.407,56.32562 -37.8572,81.07143 -21.6041,24.9234 -52.7313,52.70533 -98.9286,89.28571 C 1086.6598,841.08542 976.77458,906.08967 920,933.07647 c -57.06606,27.12536 -128.20334,58.23842 -172.14286,72.50003 -43.93952,14.2616 -131.42857,31.0714 -131.42857,31.0714 l 92.85715,-192.14286 z"
- id="path3724"
- sodipodi:nodetypes="czzzzzzzzcc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3986">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#121212;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 709.28572,844.50504 c 54.28571,-1.42857 126.035,-15.05199 170,-26.78572 44.05271,-11.75714 125.88628,-36.34724 175.35708,-57.85714 49.3393,-21.45272 113.6037,-59.2816 154.2858,-92.14285 40.5081,-32.72069 52.3899,-55.81981 60.7143,-33.57143 8.3691,22.36779 -16.407,56.32562 -37.8572,81.07143 -21.6041,24.9234 -52.7313,52.70533 -98.9286,89.28571 C 1086.6598,841.08542 976.77458,906.08967 920,933.07647 c -57.06606,27.12536 -128.20334,58.23842 -172.14286,72.50003 -43.93952,14.2616 -131.42857,31.0714 -131.42857,31.0714 l 92.85715,-192.14286 z"
- id="path3988"
- sodipodi:nodetypes="czzzzzzzzcc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3992">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#121212;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 709.28572,844.50504 c 54.28571,-1.42857 126.035,-15.05199 170,-26.78572 44.05271,-11.75714 125.88628,-36.34724 175.35708,-57.85714 49.3393,-21.45272 113.6037,-59.2816 154.2858,-92.14285 40.5081,-32.72069 52.3899,-55.81981 60.7143,-33.57143 8.3691,22.36779 -16.407,56.32562 -37.8572,81.07143 -21.6041,24.9234 -52.7313,52.70533 -98.9286,89.28571 C 1086.6598,841.08542 976.77458,906.08967 920,933.07647 c -57.06606,27.12536 -128.20334,58.23842 -172.14286,72.50003 -43.93952,14.2616 -131.42857,31.0714 -131.42857,31.0714 l 92.85715,-192.14286 z"
- id="path3994"
- sodipodi:nodetypes="czzzzzzzzcc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3998">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 178.21428,274.14789 c -3.80443,-25.26423 -16.80972,-50.63802 -17.1568,-75.52523 -0.18626,-13.35552 3.27285,-26.57091 13.75553,-39.55405 36.34702,-65.295835 116.94091,-84.694685 185.93466,-91.465427 86.92239,-11.016801 184.91267,17.940072 233.37134,95.401287 54.12402,75.7333 56.67476,172.53912 80.61204,259.52795 29.43779,127.1276 54.77914,256.21414 60.39224,386.85035 -3.06348,78.18185 -8.42634,165.18415 -60.50321,228.13413 -48.02654,50.3574 -122.78647,50.053 -187.06988,59.0023 -90.55539,4.655 -184.35153,-16.1458 -261.7839,-64.1982 -64.77564,-37.94001 -95.73019,-113.47863 -97.2794,-186.01958 -8.38917,-79.87516 26.39152,-153.80851 51.6204,-227.15961 7.47061,-82.76107 9.41286,-166.24775 9.65334,-249.38484 -0.83682,-32.19544 -7.08953,-63.81733 -11.54636,-95.60908 z"
- id="path4000"
- sodipodi:nodetypes="cscccccccccccc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter4002"
- x="-0.24334238"
- width="1.4866848"
- y="-0.39104807"
- height="1.7820961">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="14.589518"
- id="feGaussianBlur4004" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter4010"
- x="-0.14577261"
- width="1.2915452"
- y="-0.23523259"
- height="1.4704652">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="4.4442907"
- id="feGaussianBlur4012" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter4053">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.6062947"
- id="feGaussianBlur4055" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter4079">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="6.5887624"
- id="feGaussianBlur4081" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter4083">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.5052066"
- id="feGaussianBlur4085" />
- </filter>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4113"
- id="radialGradient4119"
- cx="296.33783"
- cy="427.17749"
- fx="296.33783"
- fy="427.17749"
- r="19.704132"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(2.9797125,0,0,2.9797125,-599.28727,-827.0855)" />
- <filter
- inkscape:collect="always"
- id="filter6949"
- x="-0.10294895"
- width="1.2058979"
- y="-0.34224695"
- height="1.6844939">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6951" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6953"
- x="-0.098320946"
- width="1.1966419"
- y="-0.19750816"
- height="1.3950163">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6955" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6957"
- x="-0.098213427"
- width="1.1964267"
- y="-0.19838208"
- height="1.3967642">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6959" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6961"
- x="-0.09919104"
- width="1.1983821"
- y="-0.22643611"
- height="1.4528722">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6963" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6965"
- x="-0.099081434"
- width="1.1981629"
- y="-0.22529824"
- height="1.4505965">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6967" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6969"
- x="-0.10450897"
- width="1.2090179"
- y="-0.40468886"
- height="1.8093777">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6971" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6973"
- x="-0.10330495"
- width="1.2066098"
- y="-0.36439717"
- height="1.7287945">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6975" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6977"
- x="-0.10224481"
- width="1.2044896"
- y="-0.32371372"
- height="1.6474274">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6979" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6981"
- x="-0.10052545"
- width="1.2010509"
- y="-0.2742162"
- height="1.5484324">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6983" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6985"
- x="-0.098428868"
- width="1.1968577"
- y="-0.20853186"
- height="1.4170637">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6987" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6989"
- x="-0.098428868"
- width="1.1968577"
- y="-0.20287035"
- height="1.4057407">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6991" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6993"
- x="-0.098213255"
- width="1.1964265"
- y="-0.19838208"
- height="1.3967642">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6995" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6997">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6999" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7001">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur7003" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7285"
- x="-0.030884685"
- width="1.0617694"
- y="-0.10267408"
- height="1.2053483">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7287" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7289">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7291" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7293">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7295" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7297">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7299" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7301">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7303" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7305">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7307" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7309">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7311" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7313">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7315" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7317">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7319" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7321">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7323" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7325"
- x="-0.031352691"
- width="1.0627054"
- y="-0.12140666"
- height="1.2428133">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7327" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7329"
- x="-0.030991485"
- width="1.061983"
- y="-0.10931916"
- height="1.2186383">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7331" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7333">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7335" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7337">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7339" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7345">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.7233839"
- id="feGaussianBlur7347" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath7421">
- <path
- sodipodi:type="inkscape:offset"
- inkscape:radius="0"
- inkscape:original="M 1111.4062 -285.9375 L 1107.4688 -284.0625 C 1107.4283 -284.05228 1107.3692 -284.04201 1107.3438 -284.03125 C 1106.925 -283.8184 1107.1791 -283.93067 1106.6875 -283.71875 C 1106.2014 -283.50919 1104.9499 -283.13456 1102.5938 -282.25 C 1099.2626 -280.99942 1096.7895 -280.10016 1095.5938 -279.1875 C 1094.0576 -279.16623 1091.8733 -278.95419 1089.9375 -278.46875 C 1086.956 -277.72108 1085.0823 -277.29474 1083.1875 -276.875 C 1081.2927 -276.45527 1081.512 -276.23281 1080.3125 -276 C 1079.0159 -275.74833 1078.5911 -276.00899 1074.875 -275.21875 C 1071.3851 -274.4766 1065.9802 -273.28768 1064.7188 -272.53125 C 1063.1348 -272.71203 1060.8513 -272.85303 1058.875 -272.5625 C 1055.8346 -272.11554 1053.9588 -271.88974 1052.0312 -271.65625 C 1051.3758 -271.57687 1050.9902 -271.45547 1050.6875 -271.375 C 1050.2613 -271.24334 1050.0017 -271.11498 1049.3125 -271.03125 C 1048.0009 -270.87188 1047.5503 -271.18808 1043.7812 -270.75 C 1040.2273 -270.33691 1034.7758 -269.47718 1033.5312 -268.8125 C 1031.9322 -269.10979 1029.6735 -269.34669 1027.6875 -269.15625 C 1024.6287 -268.86293 1022.7155 -268.67226 1020.7812 -268.5 C 1018.847 -268.32773 1019.0926 -268.07763 1017.875 -267.96875 C 1016.5588 -267.85105 1016.1152 -268.13238 1012.3438 -267.71875 C 1008.8017 -267.3303 1003.3359 -266.50948 1002.0625 -265.84375 C 1000.4636 -266.13844 998.1753 -266.35076 996.1875 -266.15625 C 993.12921 -265.857 991.2463 -265.67601 989.3125 -265.5 C 988.65501 -265.44015 988.27245 -265.32144 987.96875 -265.25 C 987.54105 -265.13104 987.28525 -265.03193 986.59375 -264.96875 C 985.27775 -264.84849 984.834 -265.16363 981.0625 -264.75 C 977.50631 -264.35998 972.0569 -263.51084 970.8125 -262.84375 C 969.21381 -263.13793 966.95265 -263.36747 964.96875 -263.15625 C 961.91305 -262.83092 959.9947 -262.63001 958.0625 -262.4375 C 956.13031 -262.24499 956.37275 -261.99662 955.15625 -261.875 C 953.84137 -261.74353 953.3932 -262.03954 949.625 -261.59375 C 946.08611 -261.17509 940.6473 -260.30158 939.375 -259.625 C 937.77741 -259.90604 935.51505 -260.04543 933.53125 -259.8125 C 930.47927 -259.45413 928.58625 -259.24464 926.65625 -259.03125 C 926.00007 -258.95869 925.6156 -258.85856 925.3125 -258.78125 C 924.88571 -258.65402 924.6276 -258.51405 923.9375 -258.4375 C 922.62411 -258.29181 922.17015 -258.61152 918.40625 -258.125 C 914.85737 -257.66624 909.4276 -256.70598 908.1875 -256 C 906.59441 -256.24424 904.3537 -256.38135 902.375 -256.125 C 899.32741 -255.73018 897.4243 -255.47655 895.5 -255.21875 C 893.57571 -254.96096 893.7739 -254.72522 892.5625 -254.5625 C 891.25301 -254.3866 890.8153 -254.66688 887.0625 -254.09375 C 883.53821 -253.55551 878.1393 -252.39458 876.875 -251.65625 C 875.28751 -251.85979 873.0295 -251.91098 871.0625 -251.5625 C 868.03631 -251.02638 866.1636 -250.70081 864.25 -250.375 C 863.59941 -250.26423 863.2363 -250.10406 862.9375 -250 C 862.51681 -249.83512 862.27405 -249.6687 861.59375 -249.53125 C 860.29905 -249.26966 859.86665 -249.53745 856.15625 -248.71875 C 852.65777 -247.9468 847.31035 -246.33582 846.09375 -245.5 C 844.53085 -245.57745 842.33625 -245.41472 840.40625 -244.90625 C 837.43387 -244.12312 835.58855 -243.67416 833.71875 -243.15625 C 831.84875 -242.63835 832.0521 -242.38897 830.875 -242.0625 C 829.60251 -241.7096 829.17795 -241.95541 825.53125 -240.875 C 822.10657 -239.86037 816.88185 -237.94183 815.65625 -237.03125 C 814.11747 -237.01851 811.93645 -236.75903 810.03125 -236.15625 C 807.10027 -235.22891 805.2809 -234.69783 803.4375 -234.09375 C 802.81071 -233.88837 802.44585 -233.70117 802.15625 -233.5625 C 801.74867 -233.34889 801.50295 -233.15375 800.84375 -232.9375 C 799.58925 -232.52596 799.1576 -232.74846 795.5625 -231.5 C 792.17261 -230.32283 786.96755 -228.2863 785.78125 -227.34375 C 784.25737 -227.28408 782.1312 -226.94888 780.25 -226.28125 C 777.35261 -225.25296 775.55095 -224.60577 773.71875 -223.96875 C 771.88655 -223.33174 772.0909 -223.12021 770.9375 -222.71875 C 769.69071 -222.28479 769.27395 -222.51903 765.71875 -221.15625 C 762.38005 -219.87645 757.23165 -217.6737 756.03125 -216.6875 C 754.52407 -216.57981 752.39555 -216.1887 750.53125 -215.46875 C 747.66307 -214.36115 745.90735 -213.68719 744.09375 -213 C 743.47705 -212.76637 743.0973 -212.55797 742.8125 -212.40625 C 742.81251 -212.40625 742.8125 -212.37673 742.8125 -212.375 L 734.8125 -209.1875 L 736.625 -194.46875 C 736.36701 -194.52956 742.8125 -191.15625 742.8125 -191.15625 C 743.03891 -191.30093 743.26145 -191.42886 743.53125 -191.53125 C 744.61177 -191.94123 745.70285 -191.74702 749.53125 -193.21875 C 753.35977 -194.69049 754.7553 -195.22373 755.4375 -195.625 C 756.11711 -196.02478 757.04925 -196.50437 757.65625 -197.15625 C 759.48317 -197.294 761.22705 -197.64948 762.59375 -198.15625 C 765.56175 -199.25677 767.4691 -199.96244 769.375 -200.625 C 771.28081 -201.28754 771.72915 -202.03987 772.78125 -202.40625 C 773.87287 -202.78636 774.97635 -202.57163 778.84375 -203.9375 C 782.71115 -205.30336 784.1269 -205.76458 784.8125 -206.15625 C 785.51361 -206.55677 786.5133 -207.08923 787.125 -207.75 C 789.09581 -207.80466 790.94195 -208.13463 792.40625 -208.625 C 795.40777 -209.63008 797.3324 -210.24671 799.25 -210.875 C 800.78861 -211.3791 801.42415 -211.92177 802.15625 -212.3125 C 802.38647 -212.44681 802.63215 -212.56623 802.90625 -212.65625 C 804.00457 -213.01673 805.0877 -212.73762 809 -213.96875 C 812.91231 -215.19988 814.366 -215.6417 815.0625 -216 C 815.75641 -216.35697 816.6926 -216.79261 817.3125 -217.40625 C 819.17771 -217.42891 820.94835 -217.67308 822.34375 -218.09375 C 825.37415 -219.00729 827.33615 -219.52385 829.28125 -220.0625 C 831.22637 -220.60114 831.70745 -221.32702 832.78125 -221.625 C 833.89527 -221.93415 835.00125 -221.61761 838.96875 -222.65625 C 842.93625 -223.69488 844.38625 -224.08898 845.09375 -224.40625 C 845.82855 -224.73584 846.90765 -225.15997 847.53125 -225.78125 C 849.52907 -225.66525 851.3887 -225.80134 852.875 -226.15625 C 855.95311 -226.89125 857.9584 -227.25719 859.9375 -227.65625 C 861.52541 -227.97643 862.1818 -228.4468 862.9375 -228.75 C 863.17501 -228.8568 863.4044 -228.94276 863.6875 -229 C 864.82091 -229.22919 865.99215 -228.79107 870.03125 -229.5 C 874.07067 -230.20893 875.5315 -230.42709 876.25 -230.6875 C 876.96581 -230.94694 877.95435 -231.25474 878.59375 -231.78125 C 880.51795 -231.54176 882.34165 -231.55672 883.78125 -231.78125 C 886.90767 -232.26887 888.9358 -232.48192 890.9375 -232.75 C 892.93921 -233.01807 893.42625 -233.69514 894.53125 -233.84375 C 895.67767 -233.99793 896.8071 -233.54218 900.875 -234.0625 C 904.94281 -234.58282 906.43525 -234.75823 907.15625 -235 C 907.89337 -235.24714 908.95435 -235.58623 909.59375 -236.125 C 911.64375 -235.78947 913.56745 -235.72704 915.09375 -235.90625 C 918.23595 -236.27521 920.27375 -236.46561 922.28125 -236.6875 C 923.89207 -236.86552 924.5459 -237.2957 925.3125 -237.53125 C 925.55341 -237.61677 925.80655 -237.68685 926.09375 -237.71875 C 927.24345 -237.84647 928.39505 -237.3721 932.46875 -237.84375 C 936.54245 -238.3154 938.0278 -238.45435 938.75 -238.6875 C 939.46941 -238.91977 940.45025 -239.16096 941.09375 -239.65625 C 943.03005 -239.32279 944.8638 -239.25201 946.3125 -239.40625 C 949.45851 -239.7412 951.49 -239.92484 953.5 -240.125 C 955.50991 -240.32514 955.98415 -240.95139 957.09375 -241.0625 C 958.24485 -241.17778 959.39025 -240.69744 963.46875 -241.125 C 967.54725 -241.55256 969.05765 -241.68709 969.78125 -241.90625 C 970.52047 -242.13011 971.57685 -242.4195 972.21875 -242.9375 C 974.27575 -242.53883 976.2206 -242.4441 977.75 -242.59375 C 980.89871 -242.90185 982.9258 -243.067 984.9375 -243.25 C 986.55151 -243.39682 987.20055 -243.81055 987.96875 -244.03125 C 988.21005 -244.11211 988.4623 -244.16116 988.75 -244.1875 C 989.90211 -244.29295 991.0429 -243.79475 995.125 -244.1875 C 999.20711 -244.58025 1000.7139 -244.71834 1001.4375 -244.9375 C 1002.1584 -245.15583 1003.1371 -245.3852 1003.7812 -245.875 C 1005.7193 -245.52501 1007.5501 -245.42062 1009 -245.5625 C 1012.1487 -245.8706 1014.1758 -246.03575 1016.1875 -246.21875 C 1018.1991 -246.40174 1018.7017 -247.05677 1019.8125 -247.15625 C 1020.9648 -247.25948 1022.1047 -246.77142 1026.1875 -247.15625 C 1030.2704 -247.54107 1031.7762 -247.65725 1032.5 -247.875 C 1033.2393 -248.09743 1034.2956 -248.38949 1034.9375 -248.90625 C 1036.9949 -248.50448 1038.9404 -248.40292 1040.4688 -248.5625 C 1043.6153 -248.89102 1045.6458 -249.0852 1047.6562 -249.28125 C 1049.2692 -249.43854 1049.9219 -249.91273 1050.6875 -250.15625 C 1050.9282 -250.24429 1051.1507 -250.27762 1051.4375 -250.3125 C 1052.5858 -250.4522 1053.7542 -249.97259 1057.8125 -250.5625 C 1061.8708 -251.15242 1063.3743 -251.33964 1064.0938 -251.59375 C 1064.8104 -251.84691 1065.7684 -252.15182 1066.4062 -252.6875 C 1068.3259 -252.47556 1070.1262 -252.53609 1071.5625 -252.78125 C 1074.6816 -253.31365 1076.6741 -253.70986 1078.6562 -254.09375 C 1080.6383 -254.47762 1081.1305 -255.1334 1082.2188 -255.375 C 1083.3475 -255.62566 1084.489 -255.25871 1088.4688 -256.25 C 1092.4483 -257.24127 1093.8983 -257.6693 1094.5938 -258.03125 C 1095.316 -258.40725 1096.3555 -258.90183 1096.9688 -259.5625 C 1098.9317 -259.57454 1100.7625 -259.85355 1102.1875 -260.40625 C 1105.1387 -261.55085 1107.0607 -262.27567 1108.875 -263.15625 C 1110.3307 -263.86277 1111.1941 -264.85828 1111.4062 -265.15625 C 1111.6185 -265.4542 1111.5051 -265.8848 1111.5312 -265.90625 C 1111.5742 -265.94148 1111.8716 -266.00028 1112.0312 -266.34375 C 1112.8902 -268.19082 1114.3544 -271.97139 1114.4688 -272.65625 C 1114.5825 -273.33839 1114.6368 -274.00902 1114.6875 -274.40625 C 1114.7169 -274.63575 1114.5404 -275.28515 1114.5625 -275.34375 C 1114.5934 -275.42579 1114.8508 -275.59432 1114.9062 -275.84375 C 1115.1725 -277.04206 1114.9953 -278.05111 1114.7812 -279.46875 C 1114.5673 -280.88638 1113.8096 -284.08338 1113.1562 -284.9375 C 1112.4973 -285.79922 1111.9314 -285.94801 1111.4062 -285.9375 z "
- style="display:inline;fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- id="path7423"
- d="m 1111.4062,-285.9375 -3.9374,1.875 c -0.041,0.0102 -0.1,0.0205 -0.125,0.0312 -0.4188,0.21285 -0.1647,0.10058 -0.6563,0.3125 -0.4861,0.20956 -1.7376,0.58419 -4.0937,1.46875 -3.3312,1.25058 -5.8043,2.14984 -7,3.0625 -1.5362,0.0213 -3.7205,0.23331 -5.6563,0.71875 -2.9815,0.74767 -4.8552,1.17401 -6.75,1.59375 -1.8948,0.41973 -1.6755,0.64219 -2.875,0.875 -1.2966,0.25167 -1.7214,-0.009 -5.4375,0.78125 -3.4899,0.74215 -8.8948,1.93107 -10.1562,2.6875 -1.584,-0.18078 -3.8675,-0.32178 -5.8438,-0.0312 -3.0404,0.44696 -4.9162,0.67276 -6.8438,0.90625 -0.6554,0.0794 -1.041,0.20078 -1.3437,0.28125 -0.4262,0.13166 -0.6858,0.26002 -1.375,0.34375 -1.3116,0.15937 -1.7622,-0.15683 -5.5313,0.28125 -3.5539,0.41309 -9.0054,1.27282 -10.25,1.9375 -1.599,-0.29729 -3.8577,-0.53419 -5.8437,-0.34375 -3.0588,0.29332 -4.972,0.48399 -6.9063,0.65625 -1.9342,0.17227 -1.6886,0.42237 -2.9062,0.53125 -1.3162,0.1177 -1.7598,-0.16363 -5.5312,0.25 -3.5421,0.38845 -9.0079,1.20927 -10.2813,1.875 -1.5989,-0.29469 -3.8872,-0.50701 -5.875,-0.3125 -3.05829,0.29925 -4.9412,0.48024 -6.875,0.65625 -0.65749,0.0598 -1.04005,0.17856 -1.34375,0.25 -0.4277,0.11896 -0.6835,0.21807 -1.375,0.28125 -1.316,0.12026 -1.75975,-0.19488 -5.53125,0.21875 -3.55619,0.39002 -9.0056,1.23916 -10.25,1.90625 -1.59869,-0.29418 -3.85985,-0.52372 -5.84375,-0.3125 -3.0557,0.32533 -4.97405,0.52624 -6.90625,0.71875 -1.93219,0.19251 -1.68975,0.44088 -2.90625,0.5625 -1.31488,0.13147 -1.76305,-0.16454 -5.53125,0.28125 -3.53889,0.41866 -8.9777,1.29217 -10.25,1.96875 -1.59759,-0.28104 -3.85995,-0.42043 -5.84375,-0.1875 -3.05198,0.35837 -4.945,0.56786 -6.875,0.78125 -0.65618,0.0726 -1.04065,0.17269 -1.34375,0.25 -0.42679,0.12723 -0.6849,0.2672 -1.375,0.34375 -1.31339,0.14569 -1.76735,-0.17402 -5.53125,0.3125 -3.54888,0.45876 -8.97865,1.41902 -10.21875,2.125 -1.59309,-0.24424 -3.8338,-0.38135 -5.8125,-0.125 -3.04759,0.39482 -4.9507,0.64845 -6.875,0.90625 -1.92429,0.25779 -1.7261,0.49353 -2.9375,0.65625 -1.30949,0.1759 -1.7472,-0.10438 -5.5,0.46875 -3.52429,0.53824 -8.9232,1.69917 -10.1875,2.4375 -1.58749,-0.20354 -3.8455,-0.25473 -5.8125,0.0937 -3.02619,0.53612 -4.8989,0.86169 -6.8125,1.1875 -0.65059,0.11077 -1.0137,0.27094 -1.3125,0.375 -0.42069,0.16488 -0.66345,0.3313 -1.34375,0.46875 -1.2947,0.26159 -1.7271,-0.006 -5.4375,0.8125 -3.49848,0.77195 -8.8459,2.38293 -10.0625,3.21875 -1.5629,-0.0774 -3.7575,0.0853 -5.6875,0.59375 -2.97238,0.78313 -4.8177,1.23209 -6.6875,1.75 -1.87,0.5179 -1.66665,0.76728 -2.84375,1.09375 -1.27249,0.3529 -1.69705,0.10709 -5.34375,1.1875 -3.42468,1.01463 -8.6494,2.93317 -9.875,3.84375 -1.53878,0.0127 -3.7198,0.27222 -5.625,0.875 -2.93098,0.92734 -4.75035,1.45842 -6.59375,2.0625 -0.62679,0.20538 -0.99165,0.39258 -1.28125,0.53125 -0.40758,0.21361 -0.6533,0.40875 -1.3125,0.625 -1.2545,0.41154 -1.68615,0.18904 -5.28125,1.4375 -3.38989,1.17717 -8.59495,3.2137 -9.78125,4.15625 -1.52388,0.0597 -3.65005,0.39487 -5.53125,1.0625 -2.89739,1.02829 -4.69905,1.67548 -6.53125,2.3125 -1.8322,0.63701 -1.62785,0.84854 -2.78125,1.25 -1.24679,0.43396 -1.66355,0.19972 -5.21875,1.5625 -3.3387,1.2798 -8.4871,3.48255 -9.6875,4.46875 -1.50718,0.10769 -3.6357,0.4988 -5.5,1.21875 -2.86818,1.1076 -4.6239,1.78156 -6.4375,2.46875 -0.6167,0.23363 -0.99645,0.44203 -1.28125,0.59375 10e-6,0 0,0.0295 0,0.0312 l -8,3.1875 1.8125,14.71875 c -0.25799,-0.0608 6.1875,3.3125 6.1875,3.3125 0.22641,-0.14468 0.44895,-0.27261 0.71875,-0.375 1.08052,-0.40998 2.1716,-0.21577 6,-1.6875 3.82852,-1.47174 5.22405,-2.00498 5.90625,-2.40625 0.67961,-0.39978 1.61175,-0.87937 2.21875,-1.53125 1.82692,-0.13775 3.5708,-0.49323 4.9375,-1 2.968,-1.10052 4.87535,-1.80619 6.78125,-2.46875 1.90581,-0.66254 2.35415,-1.41487 3.40625,-1.78125 1.09162,-0.38011 2.1951,-0.16538 6.0625,-1.53125 3.8674,-1.36586 5.28315,-1.82708 5.96875,-2.21875 0.70111,-0.40052 1.7008,-0.93298 2.3125,-1.59375 1.97081,-0.0547 3.81695,-0.38463 5.28125,-0.875 3.00152,-1.00508 4.92615,-1.62171 6.84375,-2.25 1.53861,-0.5041 2.17415,-1.04677 2.90625,-1.4375 0.23022,-0.13431 0.4759,-0.25373 0.75,-0.34375 1.09832,-0.36048 2.18145,-0.0814 6.09375,-1.3125 3.91231,-1.23113 5.366,-1.67295 6.0625,-2.03125 0.69391,-0.35697 1.6301,-0.79261 2.25,-1.40625 1.86521,-0.0227 3.63585,-0.26683 5.03125,-0.6875 3.0304,-0.91354 4.9924,-1.4301 6.9375,-1.96875 1.94512,-0.53864 2.4262,-1.26452 3.5,-1.5625 1.11402,-0.30915 2.22,0.007 6.1875,-1.03125 3.9675,-1.03863 5.4175,-1.43273 6.125,-1.75 0.7348,-0.32959 1.8139,-0.75372 2.4375,-1.375 1.99782,0.116 3.85745,-0.0201 5.34375,-0.375 3.07811,-0.735 5.0834,-1.10094 7.0625,-1.5 1.58791,-0.32018 2.2443,-0.79055 3,-1.09375 0.23751,-0.1068 0.4669,-0.19276 0.75,-0.25 1.13341,-0.22919 2.30465,0.20893 6.34375,-0.5 4.03942,-0.70893 5.50025,-0.92709 6.21875,-1.1875 0.71581,-0.25944 1.70435,-0.56724 2.34375,-1.09375 1.9242,0.23949 3.7479,0.22453 5.1875,0 3.12642,-0.48762 5.15455,-0.70067 7.15625,-0.96875 2.00171,-0.26807 2.48875,-0.94514 3.59375,-1.09375 1.14642,-0.15418 2.27585,0.30157 6.34375,-0.21875 4.06781,-0.52032 5.56025,-0.69573 6.28125,-0.9375 0.73712,-0.24714 1.7981,-0.58623 2.4375,-1.125 2.05,0.33553 3.9737,0.39796 5.5,0.21875 3.1422,-0.36896 5.18,-0.55936 7.1875,-0.78125 1.61082,-0.17802 2.26465,-0.6082 3.03125,-0.84375 0.24091,-0.0855 0.49405,-0.1556 0.78125,-0.1875 1.1497,-0.12772 2.3013,0.34665 6.375,-0.125 4.0737,-0.47165 5.55905,-0.6106 6.28125,-0.84375 0.71941,-0.23227 1.70025,-0.47346 2.34375,-0.96875 1.9363,0.33346 3.77005,0.40424 5.21875,0.25 3.14601,-0.33495 5.1775,-0.51859 7.1875,-0.71875 2.00991,-0.20014 2.48415,-0.82639 3.59375,-0.9375 1.1511,-0.11528 2.2965,0.36506 6.375,-0.0625 4.0785,-0.42756 5.5889,-0.56209 6.3125,-0.78125 0.73922,-0.22386 1.7956,-0.51325 2.4375,-1.03125 2.057,0.39867 4.00185,0.4934 5.53125,0.34375 3.14871,-0.3081 5.1758,-0.47325 7.1875,-0.65625 1.61401,-0.14682 2.26305,-0.56055 3.03125,-0.78125 0.2413,-0.0809 0.49355,-0.12991 0.78125,-0.15625 1.15211,-0.10545 2.2929,0.39275 6.375,0 4.08211,-0.39275 5.5889,-0.53084 6.3125,-0.75 0.7209,-0.21833 1.6996,-0.4477 2.3437,-0.9375 1.9381,0.34999 3.7689,0.45438 5.2188,0.3125 3.1487,-0.3081 5.1758,-0.47325 7.1875,-0.65625 2.0116,-0.18299 2.5142,-0.83802 3.625,-0.9375 1.1523,-0.10323 2.2922,0.38483 6.375,0 4.0829,-0.38482 5.5887,-0.501 6.3125,-0.71875 0.7393,-0.22243 1.7956,-0.51449 2.4375,-1.03125 2.0574,0.40177 4.0029,0.50333 5.5313,0.34375 3.1465,-0.32852 5.177,-0.5227 7.1874,-0.71875 1.613,-0.15729 2.2657,-0.63148 3.0313,-0.875 0.2407,-0.088 0.4632,-0.12137 0.75,-0.15625 1.1483,-0.1397 2.3167,0.33991 6.375,-0.25 4.0583,-0.58992 5.5618,-0.77714 6.2813,-1.03125 0.7166,-0.25316 1.6746,-0.55807 2.3124,-1.09375 1.9197,0.21194 3.72,0.15141 5.1563,-0.0937 3.1191,-0.5324 5.1116,-0.92861 7.0937,-1.3125 1.9821,-0.38387 2.4743,-1.03965 3.5626,-1.28125 1.1287,-0.25066 2.2702,0.11629 6.25,-0.875 3.9795,-0.99127 5.4295,-1.4193 6.125,-1.78125 0.7222,-0.376 1.7617,-0.87058 2.375,-1.53125 1.9629,-0.012 3.7937,-0.29105 5.2187,-0.84375 2.9512,-1.1446 4.8732,-1.86942 6.6875,-2.75 1.4557,-0.70652 2.3191,-1.70203 2.5312,-2 0.2123,-0.29795 0.099,-0.72855 0.125,-0.75 0.043,-0.0352 0.3404,-0.094 0.5,-0.4375 0.859,-1.84707 2.3232,-5.62764 2.4376,-6.3125 0.1137,-0.68214 0.168,-1.35277 0.2187,-1.75 0.029,-0.2295 -0.1471,-0.8789 -0.125,-0.9375 0.031,-0.082 0.2883,-0.25057 0.3437,-0.5 0.2663,-1.19831 0.089,-2.20736 -0.125,-3.625 -0.2139,-1.41763 -0.9716,-4.61463 -1.625,-5.46875 -0.6589,-0.86172 -1.2248,-1.01051 -1.75,-1 z"
- transform="translate(0.08004571,-0.03125)" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter7578"
- x="-0.08160872"
- width="1.1632174"
- y="-0.22659944"
- height="1.4531989">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="2.437399"
- id="feGaussianBlur7580" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7594"
- x="-0.040804356"
- width="1.0816087"
- y="-0.11329972"
- height="1.2265995">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.2186995"
- id="feGaussianBlur7596" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath7606">
- <path
- id="path7608"
- d="m 1049.205,-282.26672 -0.09,0.008 c -1.3874,0.88445 -6.6033,1.6072 -6.629,9.52344 -0.024,7.42525 15.0129,17.09146 17.1563,18.09375 1.7302,0.80909 3.5916,1.40876 5.4063,1.71875 l 1.4374,0.21875 c 1.9197,0.21194 3.72,0.15141 5.1563,-0.0937 3.1191,-0.5324 5.1116,-0.92861 7.0937,-1.3125 1.9821,-0.38387 2.4743,-1.03965 3.5626,-1.28125 1.1287,-0.25066 2.2702,0.11629 6.25,-0.875 3.9795,-0.99128 5.4294,-1.4193 6.125,-1.78125 0.7222,-0.37601 1.7617,-0.87058 2.375,-1.53125 1.9629,-0.012 3.7937,-0.29105 5.2187,-0.84375 2.9512,-1.14461 4.8732,-1.86942 6.6875,-2.75 1.4557,-0.70653 2.3191,-1.70203 2.5312,-2 0.2123,-0.29796 0.099,-0.72855 0.125,-0.75 0.043,-0.0352 0.3405,-0.094 0.5,-0.4375 0.859,-1.84708 2.3232,-5.62764 2.4376,-6.3125 0.1137,-0.68215 0.168,-1.35277 0.2187,-1.75 0.029,-0.22951 -0.1471,-0.8789 -0.125,-0.9375 0.031,-0.082 0.2883,-0.25057 0.3437,-0.5 0.2663,-1.19832 0.089,-2.20736 -0.125,-3.625 -0.2139,-1.41764 -0.9716,-4.61463 -1.625,-5.46875 -0.4194,-0.54857 -0.7993,-0.7925 -1.1562,-0.90625 -0.067,-0.0173 -0.1239,-0.0467 -0.1875,-0.0625 -0.021,-0.004 -0.042,0.003 -0.062,0 -0.3116,-0.0755 -0.6085,-0.15867 -1.1562,-0.21875 -0.9855,-0.10812 -2.4247,-0.2594 -3.9688,-0.25 -0.5147,0.003 -1.0371,0.0476 -1.5625,0.0937 -3.5589,0.31228 -9.0098,0.99108 -10.2187,1.625 -1.6331,-0.33402 -3.9482,-0.61223 -5.9376,-0.46875 -3.064,0.22097 -4.9677,0.34219 -6.9062,0.46875 -1.9384,0.12655 -1.6861,0.38864 -2.9062,0.46875 -1.3191,0.0866 -1.7869,-0.22325 -5.5626,0.0937 -3.5457,0.29772 -8.9806,0.99317 -10.2187,1.625 -1.6334,-0.33451 -3.9459,-0.61239 -5.9375,-0.46875 -3.0642,0.22098 -4.9678,0.37344 -6.9062,0.5 -0.6592,0.043 -1.0424,0.12393 -1.3438,0.1875 z"
- style="display:inline;opacity:0.82448976;fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter7610"
- x="-0.021942979"
- width="1.0438859"
- y="-0.10017137"
- height="1.2003427">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.57530213"
- id="feGaussianBlur7612" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath7616">
- <path
- id="path7618"
- d="m 205.47016,-408.97318 -0.0901,0.002 c -1.44563,0.78566 -6.69921,1.14335 -7.27625,9.03857 -0.54134,7.40553 13.78595,18.09566 15.85433,19.24481 1.66964,0.92764 3.48475,1.65551 5.27345,2.09115 l 1.41867,0.31834 c 1.90027,0.34514 3.70042,0.41015 5.15031,0.26563 3.1486,-0.31384 5.16386,-0.57031 7.16789,-0.8152 2.00402,-0.24488 2.5407,-0.86478 3.64319,-1.02999 1.14342,-0.17143 2.25659,0.27414 6.29577,-0.43753 4.03888,-0.71169 5.51507,-1.03768 6.23419,-1.3503 0.74664,-0.32479 1.81806,-0.74575 2.47589,-1.3621 1.95897,0.12471 3.80476,-0.0261 5.2648,-0.47819 3.02376,-0.93627 4.99157,-1.52544 6.8628,-2.27751 1.50138,-0.60342 2.43202,-1.53636 2.66436,-1.81883 0.23254,-0.28245 0.14951,-0.71989 0.17694,-0.73948 0.0453,-0.0322 0.34622,-0.0701 0.52926,-0.40161 0.98557,-1.78276 2.70955,-5.45215 2.87137,-6.12738 0.16094,-0.67257 0.26182,-1.33778 0.34007,-1.73051 0.0453,-0.22691 -0.0855,-0.88701 -0.0594,-0.94393 0.0365,-0.0797 0.30505,-0.22988 0.37769,-0.47485 0.34913,-1.17686 0.24274,-2.19578 0.1278,-3.6249 -0.11463,-1.42909 -0.64781,-4.6711 -1.24013,-5.56865 -0.38017,-0.57646 -0.74215,-0.84625 -1.09026,-0.98459 -0.0657,-0.0219 -0.12035,-0.0553 -0.1827,-0.0754 -0.0207,-0.005 -0.0418,2.3e-4 -0.0623,-0.004 -0.30559,-0.097 -0.59597,-0.20067 -1.13816,-0.29875 -0.97557,-0.1765 -2.40074,-0.42766 -3.94175,-0.52584 -0.51366,-0.0327 -1.0379,-0.0247 -1.56523,-0.0153 -3.57201,0.0636 -9.05695,0.3611 -10.30707,0.90928 -1.60587,-0.44697 -3.89597,-0.88576 -5.89053,-0.8812 -3.07195,0.007 -4.97947,-0.005 -6.92207,-0.0134 -1.94251,-0.009 -1.70908,0.27025 -2.9318,0.26518 -1.32192,-0.005 -1.76701,-0.34717 -5.55562,-0.29393 -3.55782,0.05 -9.02796,0.36522 -10.30706,0.90927 -1.60614,-0.44747 -3.89367,-0.88575 -5.89043,-0.88118 -3.07215,0.007 -4.98175,0.0265 -6.92426,0.0177 -0.66059,-0.003 -1.0485,0.051 -1.35359,0.0934 z"
- style="display:inline;opacity:0.82448976;fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- </clipPath>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient7622"
- id="linearGradient7708"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(-19.091883,4.2426407)"
- x1="774.97668"
- y1="-211.87105"
- x2="755.11584"
- y2="-202.67865" />
- <mask
- maskUnits="userSpaceOnUse"
- id="mask7704">
- <path
- style="fill:url(#linearGradient7708);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 718.40812,-224.31217 33.25,56 275.99998,-24 159.5,-48.25 -66.5,-82.75 -402.24998,99 z"
- id="path7706"
- inkscape:connector-curvature="0" />
- </mask>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient8430"
- id="radialGradient7904"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(-0.3324832,0.9022288,-0.9582407,-0.3531242,305.29227,19.909497)"
- cx="142.95833"
- cy="107.09234"
- fx="142.95833"
- fy="107.09234"
- r="66.981766" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3317"
- id="radialGradient7906"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.0036478,-1.0345492e-7,1.7124628e-7,1.6613125,-160.53487,-96.205369)"
- cx="317.78754"
- cy="129.65378"
- fx="317.78754"
- fy="129.65378"
- r="47.863216" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient8398"
- id="radialGradient7908"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(2.0747661,-0.1577957,0.2382425,3.1325183,-550.77432,-65.728909)"
- cx="325.30847"
- cy="80.909554"
- fx="325.30847"
- fy="80.909554"
- r="26.937988" />
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8209">
- <path
- sodipodi:nodetypes="czcc"
- id="path8211"
- d="m 734.03125,519.49186 c 0,0 16.75513,37.01806 28.70141,53.95395 11.94629,16.93589 52.72716,56.04605 52.72716,56.04605 l 0.59717,-138.58975"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8225">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="10.661912"
- id="feGaussianBlur8227" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter8333">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="7.18"
- id="feGaussianBlur8335" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8338">
- <path
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- id="path8340"
- d="m 266.27183,924.57185 c -1.40727,18.80122 -1.1449,32.75104 2.08174,49.30328 3.22666,16.55238 16.40609,45.90737 20.33441,63.18377 3.92621,17.2671 2.69413,38.3097 -12.45944,51.1482 -15.31761,12.9775 -42.05127,21.599 -67.8323,15.7338 -25.78106,-5.8653 -69.54908,-49.2234 -88.59019,-70.2283 C 100.6939,1012.6293 56.045182,939.86193 41.867507,909.4368 27.689835,879.01168 29.207902,872.71823 33.747792,863.90708 24.38107,839.38658 21.33408,813.84026 0.03533448,788.33044 30.360814,791.44487 43.915624,815.28676 60.161024,835.47019 54.631128,787.39416 42.106309,771.05368 31.787072,744.74589 c 29.994295,6.08165 50.57936,31.87239 63.979783,72.7125 9.554155,-3.91792 18.237765,-9.37294 30.187415,-9.0612 -11.2975,-41.6958 -17.94947,-69.91585 -36.687256,-101.06994 53.441966,5.67032 83.657026,80.63932 78.971426,87.9608 9.97797,-2.24399 19.00565,-6.53038 30.43653,-5.65167 -11.24897,-38.34703 -21.04782,-76.8679 -3.65971,-118.64819 0,0 48.28678,65.43688 54.38965,85.80578 6.10288,20.3689 1.51882,38.70051 1.51882,38.70051 0,0 16.95957,31.0853 20.29392,51.09414 3.3731,20.24134 -3.53269,59.10331 -4.94582,77.98323 z"
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8354">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="6.82"
- id="feGaussianBlur8356" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8359">
- <path
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- id="path8361"
- d="m 266.27183,924.57185 c -1.40727,18.80122 -1.1449,32.75104 2.08174,49.30328 3.22666,16.55238 16.40609,45.90737 20.33441,63.18377 3.92621,17.2671 2.69413,38.3097 -12.45944,51.1482 -15.31761,12.9775 -42.05127,21.599 -67.8323,15.7338 -25.78106,-5.8653 -69.54908,-49.2234 -88.59019,-70.2283 C 100.6939,1012.6293 56.045182,939.86193 41.867507,909.4368 27.689835,879.01168 29.207902,872.71823 33.747792,863.90708 24.38107,839.38658 21.33408,813.84026 0.03533448,788.33044 30.360814,791.44487 43.915624,815.28676 60.161024,835.47019 54.631128,787.39416 42.106309,771.05368 31.787072,744.74589 c 29.994295,6.08165 50.57936,31.87239 63.979783,72.7125 9.554155,-3.91792 18.237765,-9.37294 30.187415,-9.0612 -11.2975,-41.6958 -17.94947,-69.91585 -36.687256,-101.06994 53.441966,5.67032 83.657026,80.63932 78.971426,87.9608 9.97797,-2.24399 19.00565,-6.53038 30.43653,-5.65167 -11.24897,-38.34703 -21.04782,-76.8679 -3.65971,-118.64819 0,0 48.28678,65.43688 54.38965,85.80578 6.10288,20.3689 1.51882,38.70051 1.51882,38.70051 0,0 16.95957,31.0853 20.29392,51.09414 3.3731,20.24134 -3.53269,59.10331 -4.94582,77.98323 z"
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8379"
- x="-0.14413793"
- width="1.288276"
- y="-0.10278689"
- height="1.2055738">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="7.389266"
- id="feGaussianBlur8381" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8392">
- <path
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- id="path8394"
- d="m 760.16396,935.83377 c 6.7941,18.90279 10.49369,33.29969 11.8903,51.21189 1.39662,17.91234 -3.78268,51.80084 -2.90046,70.65614 0.88175,18.8452 8.13369,40.099 27.34463,48.9689 19.41887,8.9658 49.31924,10.2113 74.11984,-3.1456 24.8006,-13.357 57.40102,-70.3255 70.97426,-97.3087 13.62385,-27.08394 38.76107,-114.49737 44.6608,-149.76859 5.89973,-35.27121 2.55054,-41.30077 -4.61748,-49.05549 2.6403,-27.84015 -1.49972,-54.93543 13.10969,-87.18618 -30.24901,11.8257 -37.38229,40.1607 -48.31889,65.50508 -8.00091,-50.93293 0.20916,-71.27319 3.31889,-101.21936 -29.06476,14.77791 -42.86151,47.11402 -45,92.85714 -10.92395,-1.3042 -21.39144,-4.43423 -33.57143,-0.71429 -0.26404,-46.02334 -1.46356,-76.88941 8.91063,-114.20649 -53.25547,21.02686 -62.94728,106.5941 -56.05349,112.77792 -10.88282,0.535 -21.37108,-1.2973 -32.85714,2.85715 0.63892,-42.57135 -0.26046,-84.90861 -30,-122.85715 0,0 -30.95806,80.92234 -31.42857,103.57143 -0.47051,22.64909 9.45159,40.16588 9.45159,40.16588 0,0 -8.56807,36.74051 -6.29859,58.23223 2.29585,21.74146 20.4429,59.67617 27.26542,78.65809 z"
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8404"
- x="-0.090268657"
- width="1.1805373"
- y="-0.10250848"
- height="1.205017">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="5.3457272"
- id="feGaussianBlur8406" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8417">
- <path
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- id="path8419"
- d="m 760.16396,935.83377 c 6.7941,18.90279 10.49369,33.29969 11.8903,51.21189 1.39662,17.91234 -3.78268,51.80084 -2.90046,70.65614 0.88175,18.8452 8.13369,40.099 27.34463,48.9689 19.41887,8.9658 49.31924,10.2113 74.11984,-3.1456 24.8006,-13.357 57.40102,-70.3255 70.97426,-97.3087 13.62385,-27.08394 38.76107,-114.49737 44.6608,-149.76859 5.89973,-35.27121 2.55054,-41.30077 -4.61748,-49.05549 2.6403,-27.84015 -1.49972,-54.93543 13.10969,-87.18618 -30.24901,11.8257 -37.38229,40.1607 -48.31889,65.50508 -8.00091,-50.93293 0.20916,-71.27319 3.31889,-101.21936 -29.06476,14.77791 -42.86151,47.11402 -45,92.85714 -10.92395,-1.3042 -21.39144,-4.43423 -33.57143,-0.71429 -0.26404,-46.02334 -1.46356,-76.88941 8.91063,-114.20649 -53.25547,21.02686 -62.94728,106.5941 -56.05349,112.77792 -10.88282,0.535 -21.37108,-1.2973 -32.85714,2.85715 0.63892,-42.57135 -0.26046,-84.90861 -30,-122.85715 0,0 -30.95806,80.92234 -31.42857,103.57143 -0.47051,22.64909 9.45159,40.16588 9.45159,40.16588 0,0 -8.56807,36.74051 -6.29859,58.23223 2.29585,21.74146 20.4429,59.67617 27.26542,78.65809 z"
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- x="-0.084654994"
- width="1.16931"
- y="-0.36592469"
- height="1.7318494"
- id="filter11361-3">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="4.5740586"
- id="feGaussianBlur11363-6" />
- </filter>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient8430"
- id="radialGradient7904-7"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(-0.3324832,0.9022288,-0.9582407,-0.3531242,305.29227,19.909497)"
- cx="142.95833"
- cy="107.09234"
- fx="142.95833"
- fy="107.09234"
- r="66.981766" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3317"
- id="radialGradient7906-6"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.0036478,-1.0345492e-7,1.7124628e-7,1.6613125,-160.53487,-96.205369)"
- cx="317.78754"
- cy="129.65378"
- fx="317.78754"
- fy="129.65378"
- r="47.863216" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient8398"
- id="radialGradient7908-0"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(2.0747661,-0.1577957,0.2382425,3.1325183,-550.77432,-65.728909)"
- cx="325.30847"
- cy="80.909554"
- fx="325.30847"
- fy="80.909554"
- r="26.937988" />
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8658-06">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#0b0b0b;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 569.03125,1018.7776 c -4.28571,0.7143 -27.62815,3.6181 -57.85714,10 -30.22899,6.3819 -99.77493,25.9619 -142.85715,35.7143 -43.08222,9.7524 -117.26443,34.816 -156.91262,27.2654 -39.64818,-7.5506 -89.51595,-64.4083 -89.51595,-64.4083 l 4.28572,-94.28571 c 0,0 85.88551,-16.20094 112.14285,-33.57143 26.25735,-17.37049 45.58238,-49.66598 59.28572,-71.42857 13.70334,-21.76259 32.85714,-71.42858 32.85714,-71.42858 l 238.57143,262.14289 z"
- id="path8660-2"
- sodipodi:nodetypes="czzzcczzcc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8888-6"
- x="-0.2112188"
- width="1.4224375"
- y="-0.16808605"
- height="1.3361721">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="8.3693583"
- id="feGaussianBlur8890-1" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath2833-2">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#292929;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 569.03125,1018.7776 c -4.28571,0.7143 -27.62815,3.6181 -57.85714,10 -30.22899,6.3819 -57.31395,4.9661 -135.78608,17.3296 -79.85178,12.5808 -94.06436,42.5423 -108.12225,47.0643 -14.70014,4.7286 -145.37739,-65.8225 -145.37739,-65.8225 l 4.28572,-94.28571 c 0,0 85.88551,-16.20094 112.14285,-33.57143 26.25735,-17.37049 45.58238,-49.66598 59.28572,-71.42857 13.70334,-21.76259 32.85714,-71.42858 32.85714,-71.42858 l 238.57143,262.14289 z"
- id="path2835-3"
- sodipodi:nodetypes="czzzcczzcc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8892-7"
- x="-0.18692794"
- width="1.3738559"
- y="-0.23646873"
- height="1.4729375">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="31.21228"
- id="feGaussianBlur8894-5" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3665-9">
- <path
- sodipodi:nodetypes="czzcczcc"
- id="path3667-2"
- d="m 366.88839,504.13471 c 0,0 -29.55406,40.57305 -47.85714,74.28571 -18.30309,33.71267 -58.62109,126.35694 -70.35714,171.07143 -11.7594,44.80344 -62.5,123.57144 -62.5,123.57144 l 76.07143,18.21428 c 0,0 11.80712,-12.82335 31.07142,-46.07143 19.2643,-33.24808 60.35715,-138.57143 60.35715,-138.57143 l 13.21428,-202.5 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#0f0f0f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8856-2"
- x="-0.3253231"
- width="1.6506462"
- y="-0.19013336"
- height="1.3802667">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="28.712591"
- id="feGaussianBlur8858-8" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8642-9">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#0f0f0f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 366.88839,504.13471 c 0,0 -29.55406,40.57305 -47.85714,74.28571 -18.30309,33.71267 -58.62109,126.35694 -70.35714,171.07143 -11.7594,44.80344 -62.5,123.57144 -62.5,123.57144 l 76.07143,18.21428 c 0,0 11.80712,-12.82335 31.07142,-46.07143 19.2643,-33.24808 60.35715,-138.57143 60.35715,-138.57143 l 13.21428,-202.5 z"
- id="path8644-7"
- sodipodi:nodetypes="czzcczcc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8860-3"
- x="-0.38093024"
- width="1.7618605"
- y="-0.17518716"
- height="1.3503743">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="19.304015"
- id="feGaussianBlur8862-6" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath7616-1">
- <path
- id="path7618-2"
- d="m 205.47016,-408.97318 -0.0901,0.002 c -1.44563,0.78566 -6.69921,1.14335 -7.27625,9.03857 -0.54134,7.40553 13.78595,18.09566 15.85433,19.24481 1.66964,0.92764 3.48475,1.65551 5.27345,2.09115 l 1.41867,0.31834 c 1.90027,0.34514 3.70042,0.41015 5.15031,0.26563 3.1486,-0.31384 5.16386,-0.57031 7.16789,-0.8152 2.00402,-0.24488 2.5407,-0.86478 3.64319,-1.02999 1.14342,-0.17143 2.25659,0.27414 6.29577,-0.43753 4.03888,-0.71169 5.51507,-1.03768 6.23419,-1.3503 0.74664,-0.32479 1.81806,-0.74575 2.47589,-1.3621 1.95897,0.12471 3.80476,-0.0261 5.2648,-0.47819 3.02376,-0.93627 4.99157,-1.52544 6.8628,-2.27751 1.50138,-0.60342 2.43202,-1.53636 2.66436,-1.81883 0.23254,-0.28245 0.14951,-0.71989 0.17694,-0.73948 0.0453,-0.0322 0.34622,-0.0701 0.52926,-0.40161 0.98557,-1.78276 2.70955,-5.45215 2.87137,-6.12738 0.16094,-0.67257 0.26182,-1.33778 0.34007,-1.73051 0.0453,-0.22691 -0.0855,-0.88701 -0.0594,-0.94393 0.0365,-0.0797 0.30505,-0.22988 0.37769,-0.47485 0.34913,-1.17686 0.24274,-2.19578 0.1278,-3.6249 -0.11463,-1.42909 -0.64781,-4.6711 -1.24013,-5.56865 -0.38017,-0.57646 -0.74215,-0.84625 -1.09026,-0.98459 -0.0657,-0.0219 -0.12035,-0.0553 -0.1827,-0.0754 -0.0207,-0.005 -0.0418,2.3e-4 -0.0623,-0.004 -0.30559,-0.097 -0.59597,-0.20067 -1.13816,-0.29875 -0.97557,-0.1765 -2.40074,-0.42766 -3.94175,-0.52584 -0.51366,-0.0327 -1.0379,-0.0247 -1.56523,-0.0153 -3.57201,0.0636 -9.05695,0.3611 -10.30707,0.90928 -1.60587,-0.44697 -3.89597,-0.88576 -5.89053,-0.8812 -3.07195,0.007 -4.97947,-0.005 -6.92207,-0.0134 -1.94251,-0.009 -1.70908,0.27025 -2.9318,0.26518 -1.32192,-0.005 -1.76701,-0.34717 -5.55562,-0.29393 -3.55782,0.05 -9.02796,0.36522 -10.30706,0.90927 -1.60614,-0.44747 -3.89367,-0.88575 -5.89043,-0.88118 -3.07215,0.007 -4.98175,0.0265 -6.92426,0.0177 -0.66059,-0.003 -1.0485,0.051 -1.35359,0.0934 z"
- style="display:inline;opacity:0.82448976;fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter7610-9"
- x="-0.021942979"
- width="1.0438859"
- y="-0.10017137"
- height="1.2003427">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.57530213"
- id="feGaussianBlur7612-3" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath7606-1">
- <path
- id="path7608-9"
- d="m 1049.205,-282.26672 -0.09,0.008 c -1.3874,0.88445 -6.6033,1.6072 -6.629,9.52344 -0.024,7.42525 15.0129,17.09146 17.1563,18.09375 1.7302,0.80909 3.5916,1.40876 5.4063,1.71875 l 1.4374,0.21875 c 1.9197,0.21194 3.72,0.15141 5.1563,-0.0937 3.1191,-0.5324 5.1116,-0.92861 7.0937,-1.3125 1.9821,-0.38387 2.4743,-1.03965 3.5626,-1.28125 1.1287,-0.25066 2.2702,0.11629 6.25,-0.875 3.9795,-0.99128 5.4294,-1.4193 6.125,-1.78125 0.7222,-0.37601 1.7617,-0.87058 2.375,-1.53125 1.9629,-0.012 3.7937,-0.29105 5.2187,-0.84375 2.9512,-1.14461 4.8732,-1.86942 6.6875,-2.75 1.4557,-0.70653 2.3191,-1.70203 2.5312,-2 0.2123,-0.29796 0.099,-0.72855 0.125,-0.75 0.043,-0.0352 0.3405,-0.094 0.5,-0.4375 0.859,-1.84708 2.3232,-5.62764 2.4376,-6.3125 0.1137,-0.68215 0.168,-1.35277 0.2187,-1.75 0.029,-0.22951 -0.1471,-0.8789 -0.125,-0.9375 0.031,-0.082 0.2883,-0.25057 0.3437,-0.5 0.2663,-1.19832 0.089,-2.20736 -0.125,-3.625 -0.2139,-1.41764 -0.9716,-4.61463 -1.625,-5.46875 -0.4194,-0.54857 -0.7993,-0.7925 -1.1562,-0.90625 -0.067,-0.0173 -0.1239,-0.0467 -0.1875,-0.0625 -0.021,-0.004 -0.042,0.003 -0.062,0 -0.3116,-0.0755 -0.6085,-0.15867 -1.1562,-0.21875 -0.9855,-0.10812 -2.4247,-0.2594 -3.9688,-0.25 -0.5147,0.003 -1.0371,0.0476 -1.5625,0.0937 -3.5589,0.31228 -9.0098,0.99108 -10.2187,1.625 -1.6331,-0.33402 -3.9482,-0.61223 -5.9376,-0.46875 -3.064,0.22097 -4.9677,0.34219 -6.9062,0.46875 -1.9384,0.12655 -1.6861,0.38864 -2.9062,0.46875 -1.3191,0.0866 -1.7869,-0.22325 -5.5626,0.0937 -3.5457,0.29772 -8.9806,0.99317 -10.2187,1.625 -1.6334,-0.33451 -3.9459,-0.61239 -5.9375,-0.46875 -3.0642,0.22098 -4.9678,0.37344 -6.9062,0.5 -0.6592,0.043 -1.0424,0.12393 -1.3438,0.1875 z"
- style="display:inline;opacity:0.82448976;fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter7578-4"
- x="-0.08160872"
- width="1.1632174"
- y="-0.22659944"
- height="1.4531989">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="2.437399"
- id="feGaussianBlur7580-7" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7594-8"
- x="-0.040804356"
- width="1.0816087"
- y="-0.11329972"
- height="1.2265995">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.2186995"
- id="feGaussianBlur7596-4" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8616-5">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 352.24553,211.99185 c -3.80443,-25.26423 -16.80972,-50.63802 -17.1568,-75.52523 -0.18626,-13.35552 3.27285,-26.57091 13.75553,-39.554046 36.34702,-65.295835 116.94091,-84.694685 185.93466,-91.465427 86.92239,-11.016801 184.91267,17.940072 233.37134,95.401283 54.12402,75.7333 56.67476,172.53912 80.61204,259.52795 29.43779,127.1276 54.77914,256.21414 60.39224,386.85035 -3.06348,78.18185 -8.42634,165.18415 -60.50321,228.13413 -48.02654,50.35744 -122.78647,50.05304 -187.06988,59.00234 -90.55539,4.655 -184.35153,-16.1458 -261.7839,-64.19824 -64.77564,-37.94001 -95.73019,-113.47863 -97.2794,-186.01958 -8.38917,-79.87516 26.39152,-153.80851 51.6204,-227.15961 7.47061,-82.76107 9.41286,-166.24775 9.65334,-249.38484 -0.83682,-32.19544 -7.08953,-63.81733 -11.54636,-95.60908 z"
- id="path8618-0"
- sodipodi:nodetypes="cscccccccccccc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8940-3"
- x="-0.25152978"
- width="1.5030596"
- y="-0.053035267"
- height="1.1060705">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="13.024603"
- id="feGaussianBlur8942-6" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8209-6">
- <path
- sodipodi:nodetypes="czcc"
- id="path8211-3"
- d="m 734.03125,519.49186 c 0,0 16.75513,37.01806 28.70141,53.95395 11.94629,16.93589 52.72716,56.04605 52.72716,56.04605 l 0.59717,-138.58975"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8822-2"
- x="-0.2742857"
- width="1.5485713"
- y="-0.21333334"
- height="1.4266667">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="11.313708"
- id="feGaussianBlur8824-0" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3998-6">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 178.21428,274.14789 c -3.80443,-25.26423 -16.80972,-50.63802 -17.1568,-75.52523 -0.18626,-13.35552 3.27285,-26.57091 13.75553,-39.55405 36.34702,-65.295835 116.94091,-84.694685 185.93466,-91.465427 86.92239,-11.016801 184.91267,17.940072 233.37134,95.401287 54.12402,75.7333 56.67476,172.53912 80.61204,259.52795 29.43779,127.1276 54.77914,256.21414 60.39224,386.85035 -3.06348,78.18185 -8.42634,165.18415 -60.50321,228.13413 -48.02654,50.3574 -122.78647,50.053 -187.06988,59.0023 -90.55539,4.655 -184.35153,-16.1458 -261.7839,-64.1982 -64.77564,-37.94001 -95.73019,-113.47863 -97.2794,-186.01958 -8.38917,-79.87516 26.39152,-153.80851 51.6204,-227.15961 7.47061,-82.76107 9.41286,-166.24775 9.65334,-249.38484 -0.83682,-32.19544 -7.08953,-63.81733 -11.54636,-95.60908 z"
- id="path4000-1"
- sodipodi:nodetypes="cscccccccccccc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter3677-5">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="2.0397518"
- id="feGaussianBlur3679-5" />
- </filter>
- <filter
- id="filter3785-4"
- inkscape:label="White Fur">
- <feTurbulence
- id="feTurbulence3787-7"
- type="fractalNoise"
- baseFrequency="0.24044943820224721"
- numOctaves="10"
- seed="655"
- result="result0" />
- <feDisplacementMap
- id="feDisplacementMap3789-65"
- in="SourceGraphic"
- in2="result0"
- scale="62"
- xChannelSelector="B"
- yChannelSelector="G" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8604-69">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 352.24553,211.99185 c -3.80443,-25.26423 -16.80972,-50.63802 -17.1568,-75.52523 -0.18626,-13.35552 3.27285,-26.57091 13.75553,-39.554046 36.34702,-65.295835 116.94091,-84.694685 185.93466,-91.465427 86.92239,-11.016801 184.91267,17.940072 233.37134,95.401283 54.12402,75.7333 56.67476,172.53912 80.61204,259.52795 29.43779,127.1276 54.77914,256.21414 60.39224,386.85035 -3.06348,78.18185 -8.42634,165.18415 -60.50321,228.13413 -48.02654,50.35744 -122.78647,50.05304 -187.06988,59.00234 -90.55539,4.655 -184.35153,-16.1458 -261.7839,-64.19824 -64.77564,-37.94001 -95.73019,-113.47863 -97.2794,-186.01958 -8.38917,-79.87516 26.39152,-153.80851 51.6204,-227.15961 7.47061,-82.76107 9.41286,-166.24775 9.65334,-249.38484 -0.83682,-32.19544 -7.08953,-63.81733 -11.54636,-95.60908 z"
- id="path8606-3"
- sodipodi:nodetypes="cscccccccccccc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8802-7"
- x="-0.35311759"
- width="1.7062352"
- y="-0.1817714"
- height="1.3635428">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="48.038491"
- id="feGaussianBlur8804-4" />
- </filter>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3317"
- id="radialGradient3315-5"
- cx="543.6698"
- cy="147.3131"
- fx="543.6698"
- fy="147.3131"
- r="47.863216"
- gradientTransform="matrix(2.1382256,0,0,2.3382884,-77.03847,-101.68704)"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3537"
- id="radialGradient3543-4"
- cx="385"
- cy="237.00504"
- fx="385"
- fy="237.00504"
- r="86.928574"
- gradientTransform="matrix(1,0,0,0.8562038,0,34.080427)"
- gradientUnits="userSpaceOnUse" />
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath4100-3">
- <path
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.9000755px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 265.93541,126.68393 -18.76721,168.86308 174.10543,-73.12068 61.9544,88.65883 57.8844,-31.9903 -37.53442,-180.059677 -237.6426,27.648747 z"
- id="path4102-0"
- sodipodi:nodetypes="ccccccc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter4120-7"
- x="-0.2770822"
- width="1.5541644"
- y="-0.32482043"
- height="1.6496409">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="19.956289"
- id="feGaussianBlur4122-8" />
- </filter>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3961"
- id="radialGradient3915-6"
- cx="418.30365"
- cy="342.47794"
- fx="418.30365"
- fy="342.47794"
- r="131.4509"
- gradientTransform="matrix(1.3957347,0.6211056,-0.4244067,0.9537174,-15.061913,-227.96711)"
- gradientUnits="userSpaceOnUse" />
- <mask
- maskUnits="userSpaceOnUse"
- id="mask3684-3">
- <ellipse
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient3688);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.43724918px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="path3686-1"
- transform="translate(-174.03125,62.156036)"
- cx="579.474"
- cy="260.57516"
- rx="192.6866"
- ry="164.04877" />
- </mask>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3951"
- id="radialGradient3933-8"
- cx="397.16388"
- cy="336.95245"
- fx="397.16388"
- fy="336.95245"
- r="36.75"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.9449972,2.4894837e-7,-2.4894833e-7,1.9449969,-375.31868,-318.41912)" />
- <filter
- inkscape:collect="always"
- id="filter8806-6"
- x="-0.61142862"
- width="2.2228572"
- y="-0.14930232"
- height="1.2986046">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="37.830213"
- id="feGaussianBlur8808-4" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter8826-9"
- x="-0.25894088"
- width="1.5178818"
- y="-0.2236412"
- height="1.4472824">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="19.631544"
- id="feGaussianBlur8828-5" />
- </filter>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3985"
- id="radialGradient3991-0"
- cx="402.48898"
- cy="317.23578"
- fx="402.48898"
- fy="317.23578"
- r="23.714285"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(4.3776616,0,0,4.3776616,-1358.3025,-1070.7357)" />
- <filter
- inkscape:collect="always"
- id="filter3981-7"
- x="-0.30000001"
- width="1.6"
- y="-0.30000001"
- height="1.6">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="2"
- id="feGaussianBlur3983-1" />
- </filter>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4106"
- id="radialGradient4112-7"
- cx="250.22678"
- cy="475.09763"
- fx="250.22678"
- fy="475.09763"
- r="95.98877"
- gradientTransform="matrix(1.2259004,-0.7077739,0.1413989,0.2449102,322.22326,608.91815)"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4013"
- id="radialGradient3585-2"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.1323239,0.7659488,-1.4550286,2.1510098,588.75376,-711.79716)"
- cx="228.81355"
- cy="440.26971"
- fx="228.81355"
- fy="440.26971"
- r="119.17509" />
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3999-0">
- <path
- style="display:inline;opacity:1;fill:#f5ff04;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 179.64286,267.36218 c -22.41044,39.70292 -60.6161,115.78029 -69.28571,149.64286 -8.64721,33.7751 -8.77199,66.41654 -0.35715,86.42858 8.3602,19.88213 26.16398,35.6328 40.71428,41.42856 -0.59638,-14.37587 14.37295,-43.28583 72.85715,-72.5 58.62627,-29.28514 78.38163,-27.13086 103.57142,-47.14286 25.63006,-20.36176 12.61031,-67.04463 3.21429,-93.92857 -9.43424,-26.99328 -34.96741,-59.12448 -66.42857,-69.64285 -31.03327,-10.37532 -65.01776,-4.84837 -84.28571,5.71428 z"
- id="path4001-61"
- sodipodi:nodetypes="czzczzzzc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4041"
- id="radialGradient4060-5"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.05911206,2.6869855,-0.7234268,0.01591495,408.72779,-424.56452)"
- cx="275.4422"
- cy="335.34866"
- fx="275.4422"
- fy="335.34866"
- r="36.75" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient7622"
- id="radialGradient4062-9"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.05911206,2.6869855,-0.7234268,0.01591495,408.72779,-424.56452)"
- cx="275.4422"
- cy="335.34866"
- fx="275.4422"
- fy="335.34866"
- r="36.75" />
- <filter
- inkscape:collect="always"
- id="filter4079-1">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="6.5887624"
- id="feGaussianBlur4081-1" />
- </filter>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4013"
- id="radialGradient4056-5"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.1323239,0.7659488,-1.4550286,2.1510098,588.75376,-711.79716)"
- cx="228.81355"
- cy="440.26971"
- fx="228.81355"
- fy="440.26971"
- r="119.17509" />
- <filter
- inkscape:collect="always"
- id="filter4083-9">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.5052066"
- id="feGaussianBlur4085-7" />
- </filter>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4113"
- id="radialGradient4119-7"
- cx="296.33783"
- cy="427.17749"
- fx="296.33783"
- fy="427.17749"
- r="19.704132"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(2.9797125,0,0,2.9797125,-599.28727,-827.0855)" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4862"
- id="radialGradient4868-3"
- cx="429.56738"
- cy="377.42877"
- fx="429.56738"
- fy="377.42877"
- r="72.079735"
- gradientTransform="matrix(1,0,0,0.618034,0,144.16496)"
- gradientUnits="userSpaceOnUse" />
- <filter
- inkscape:collect="always"
- id="filter4002-6"
- x="-0.24334238"
- width="1.4866848"
- y="-0.39104807"
- height="1.7820961">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="14.589518"
- id="feGaussianBlur4004-3" />
- </filter>
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4870"
- id="radialGradient4876-9"
- cx="437.6991"
- cy="391.21735"
- fx="437.6991"
- fy="391.21735"
- r="36.611931"
- gradientTransform="matrix(1,0,0,0.618034,0,149.43174)"
- gradientUnits="userSpaceOnUse" />
- <filter
- inkscape:collect="always"
- id="filter4010-1"
- x="-0.14577261"
- width="1.2915452"
- y="-0.23523259"
- height="1.4704652">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="4.4442907"
- id="feGaussianBlur4012-2" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter4053-9">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.6062947"
- id="feGaussianBlur4055-3" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8514-8">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 352.24553,211.99185 c -3.80443,-25.26423 -16.80972,-50.63802 -17.1568,-75.52523 -0.18626,-13.35552 3.27285,-26.57091 13.75553,-39.554046 36.34702,-65.295835 116.94091,-84.694685 185.93466,-91.465427 86.92239,-11.016801 184.91267,17.940072 233.37134,95.401283 54.12402,75.7333 56.67476,172.53912 80.61204,259.52795 29.43779,127.1276 54.77914,256.21414 60.39224,386.85035 -3.06348,78.18185 -8.42634,165.18415 -60.50321,228.13413 -48.02654,50.35744 -122.78647,50.05304 -187.06988,59.00234 -90.55539,4.655 -184.35153,-16.1458 -261.7839,-64.19824 -64.77564,-37.94001 -95.73019,-113.47863 -97.2794,-186.01958 -8.38917,-79.87516 26.39152,-153.80851 51.6204,-227.15961 7.47061,-82.76107 9.41286,-166.24775 9.65334,-249.38484 -0.83682,-32.19544 -7.08953,-63.81733 -11.54636,-95.60908 z"
- id="path8516-8"
- sodipodi:nodetypes="cscccccccccccc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8814-5"
- x="-0.20466694"
- width="1.4093339"
- y="-0.29007819"
- height="1.5801564">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="22.300169"
- id="feGaussianBlur8816-0" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8610-9">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 352.24553,211.99185 c -3.80443,-25.26423 -16.80972,-50.63802 -17.1568,-75.52523 -0.18626,-13.35552 3.27285,-26.57091 13.75553,-39.554046 36.34702,-65.295835 116.94091,-84.694685 185.93466,-91.465427 86.92239,-11.016801 184.91267,17.940072 233.37134,95.401283 54.12402,75.7333 56.67476,172.53912 80.61204,259.52795 29.43779,127.1276 54.77914,256.21414 60.39224,386.85035 -3.06348,78.18185 -8.42634,165.18415 -60.50321,228.13413 -48.02654,50.35744 -122.78647,50.05304 -187.06988,59.00234 -90.55539,4.655 -184.35153,-16.1458 -261.7839,-64.19824 -64.77564,-37.94001 -95.73019,-113.47863 -97.2794,-186.01958 -8.38917,-79.87516 26.39152,-153.80851 51.6204,-227.15961 7.47061,-82.76107 9.41286,-166.24775 9.65334,-249.38484 -0.83682,-32.19544 -7.08953,-63.81733 -11.54636,-95.60908 z"
- id="path8612-6"
- sodipodi:nodetypes="cscccccccccccc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8810-3"
- x="-0.23519406"
- width="1.4703881"
- y="-0.24500646"
- height="1.4900129">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="58.328041"
- id="feGaussianBlur8812-8" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8622-5">
- <path
- style="display:inline;opacity:1;fill:#202020;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 821.64329,477.88997 c 0,0 22.61947,-6.50681 35.74275,-5.87273 13.12328,0.63409 30.64158,1.93862 43.70885,12.18619 13.06727,10.24756 25.06774,27.14007 34.11239,58.36965 9.04465,31.22958 1.69832,99.25201 -6.17603,143.34735 -7.87435,44.09534 -28.2651,106.11298 -45,140 -16.7349,33.88702 -49.79771,77.4952 -60.56943,89.87616 -11.36422,13.06197 -56.20589,36.42617 -79.43057,42.26667 5.3033,-10.6066 48.89976,-50.58884 35,-60.71426 -14.01897,-10.21226 -45.76009,45.98236 -84.29315,29.03317 21.38231,-13.13212 41.7794,-51.18606 34.04061,-66.59445 -7.84025,-15.61039 -30.70493,48.75757 -93.53554,37.01288 30.05204,-27.52666 55.40706,-70.90401 41.2627,-82.9797 -14.41516,-12.30687 -60.46175,54.29315 -60.46175,54.29315 0,0 -2.8219,-41.70118 13.7732,-68.60732 16.63935,-26.97787 79.65297,-81.61527 99.55313,-111.70342 19.90015,-30.08814 33.61256,-66.00902 42.13542,-92.51794 8.52286,-26.50892 15.80094,-77.09954 15.80094,-77.09954"
- id="path8624-61"
- sodipodi:nodetypes="czzzzzzczczczczzzc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8818-1"
- x="-0.34381232"
- width="1.6876246"
- y="-0.18433961"
- height="1.3686792">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="34.542167"
- id="feGaussianBlur8820-5" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8906-9">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#262f2f;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 352.24553,211.99185 c -3.80443,-25.26423 -16.80972,-50.63802 -17.1568,-75.52523 -0.18626,-13.35552 3.27285,-26.57091 13.75553,-39.554046 36.34702,-65.295835 116.94091,-84.694685 185.93466,-91.465427 86.92239,-11.016801 184.91267,17.940072 233.37134,95.401283 54.12402,75.7333 56.67476,172.53912 80.61204,259.52795 29.43779,127.1276 54.77914,256.21414 60.39224,386.85035 -3.06348,78.18185 -8.42634,165.18415 -60.50321,228.13413 -48.02654,50.35744 -122.78647,50.05304 -187.06988,59.00234 -90.55539,4.655 -184.35153,-16.1458 -261.7839,-64.19824 -64.77564,-37.94001 -95.73019,-113.47863 -97.2794,-186.01958 -8.38917,-79.87516 26.39152,-153.80851 51.6204,-227.15961 7.47061,-82.76107 9.41286,-166.24775 9.65334,-249.38484 -0.83682,-32.19544 -7.08953,-63.81733 -11.54636,-95.60908 z"
- id="path8908-8"
- sodipodi:nodetypes="cscccccccccccc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3602-4">
- <path
- sodipodi:nodetypes="czzzzzzczczczczzzc"
- id="path3604-8"
- d="m 647.61204,540.04601 c 0,0 22.61947,-6.50681 35.74275,-5.87273 13.12328,0.63409 30.64158,1.93862 43.70885,12.18619 13.06727,10.24756 25.06774,27.14007 34.11239,58.36965 9.04465,31.22958 1.69832,99.25201 -6.17603,143.34735 -7.87435,44.09534 -28.2651,106.11298 -45,140 -16.7349,33.88702 -49.79771,77.4952 -60.56943,89.87616 -11.36422,13.06197 -56.20589,36.42617 -79.43057,42.26667 5.3033,-10.6066 48.89976,-50.58884 35,-60.71426 -14.01897,-10.21226 -45.76009,45.98236 -84.29315,29.03317 21.38231,-13.13212 41.7794,-51.18606 34.04061,-66.59445 -7.84025,-15.61039 -30.70493,48.75757 -93.53554,37.01288 30.05204,-27.52666 55.40706,-70.90401 41.2627,-82.9797 -14.41516,-12.30687 -60.46175,54.29315 -60.46175,54.29315 0,0 -2.8219,-41.70118 13.7732,-68.60732 16.63935,-26.97787 79.65297,-81.61527 99.55313,-111.70342 19.90015,-30.08814 33.61256,-66.00902 42.13542,-92.51794 8.52286,-26.50892 15.80094,-77.09954 15.80094,-77.09954"
- style="display:inline;opacity:1;fill:#202020;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter3587-1"
- x="-0.1">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="8.881432"
- id="feGaussianBlur3589-0" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3992-4">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#121212;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 709.28572,844.50504 c 54.28571,-1.42857 126.035,-15.05199 170,-26.78572 44.05271,-11.75714 125.88628,-36.34724 175.35708,-57.85714 49.3393,-21.45272 113.6037,-59.2816 154.2858,-92.14285 40.5081,-32.72069 52.3899,-55.81981 60.7143,-33.57143 8.3691,22.36779 -16.407,56.32562 -37.8572,81.07143 -21.6041,24.9234 -52.7313,52.70533 -98.9286,89.28571 C 1086.6598,841.08542 976.77458,906.08967 920,933.07647 c -57.06606,27.12536 -128.20334,58.23842 -172.14286,72.50003 -43.93952,14.2616 -131.42857,31.0714 -131.42857,31.0714 l 92.85715,-192.14286 z"
- id="path3994-4"
- sodipodi:nodetypes="czzzzzzzzcc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter3779-4"
- x="-0.087980822"
- width="1.1759616"
- y="-0.17728332"
- height="1.3545666">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="16.340344"
- id="feGaussianBlur3781-4" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3986-7">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#121212;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 709.28572,844.50504 c 54.28571,-1.42857 126.035,-15.05199 170,-26.78572 44.05271,-11.75714 125.88628,-36.34724 175.35708,-57.85714 49.3393,-21.45272 113.6037,-59.2816 154.2858,-92.14285 40.5081,-32.72069 52.3899,-55.81981 60.7143,-33.57143 8.3691,22.36779 -16.407,56.32562 -37.8572,81.07143 -21.6041,24.9234 -52.7313,52.70533 -98.9286,89.28571 C 1086.6598,841.08542 976.77458,906.08967 920,933.07647 c -57.06606,27.12536 -128.20334,58.23842 -172.14286,72.50003 -43.93952,14.2616 -131.42857,31.0714 -131.42857,31.0714 l 92.85715,-192.14286 z"
- id="path3988-6"
- sodipodi:nodetypes="czzzzzzzzcc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3722-3">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#121212;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 709.28572,844.50504 c 54.28571,-1.42857 126.035,-15.05199 170,-26.78572 44.05271,-11.75714 125.88628,-36.34724 175.35708,-57.85714 49.3393,-21.45272 113.6037,-59.2816 154.2858,-92.14285 40.5081,-32.72069 52.3899,-55.81981 60.7143,-33.57143 8.3691,22.36779 -16.407,56.32562 -37.8572,81.07143 -21.6041,24.9234 -52.7313,52.70533 -98.9286,89.28571 C 1086.6598,841.08542 976.77458,906.08967 920,933.07647 c -57.06606,27.12536 -128.20334,58.23842 -172.14286,72.50003 -43.93952,14.2616 -131.42857,31.0714 -131.42857,31.0714 l 92.85715,-192.14286 z"
- id="path3724-1"
- sodipodi:nodetypes="czzzzzzzzcc"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8225-7">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="10.661912"
- id="feGaussianBlur8227-5" />
- </filter>
- <mask
- maskUnits="userSpaceOnUse"
- id="mask7704-9">
- <path
- style="fill:url(#linearGradient7708);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 718.40812,-224.31217 33.25,56 275.99998,-24 159.5,-48.25 -66.5,-82.75 -402.24998,99 z"
- id="path7706-6"
- inkscape:connector-curvature="0" />
- </mask>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath7421-7">
- <path
- sodipodi:type="inkscape:offset"
- inkscape:radius="0"
- inkscape:original="M 1111.4062 -285.9375 L 1107.4688 -284.0625 C 1107.4283 -284.05228 1107.3692 -284.04201 1107.3438 -284.03125 C 1106.925 -283.8184 1107.1791 -283.93067 1106.6875 -283.71875 C 1106.2014 -283.50919 1104.9499 -283.13456 1102.5938 -282.25 C 1099.2626 -280.99942 1096.7895 -280.10016 1095.5938 -279.1875 C 1094.0576 -279.16623 1091.8733 -278.95419 1089.9375 -278.46875 C 1086.956 -277.72108 1085.0823 -277.29474 1083.1875 -276.875 C 1081.2927 -276.45527 1081.512 -276.23281 1080.3125 -276 C 1079.0159 -275.74833 1078.5911 -276.00899 1074.875 -275.21875 C 1071.3851 -274.4766 1065.9802 -273.28768 1064.7188 -272.53125 C 1063.1348 -272.71203 1060.8513 -272.85303 1058.875 -272.5625 C 1055.8346 -272.11554 1053.9588 -271.88974 1052.0312 -271.65625 C 1051.3758 -271.57687 1050.9902 -271.45547 1050.6875 -271.375 C 1050.2613 -271.24334 1050.0017 -271.11498 1049.3125 -271.03125 C 1048.0009 -270.87188 1047.5503 -271.18808 1043.7812 -270.75 C 1040.2273 -270.33691 1034.7758 -269.47718 1033.5312 -268.8125 C 1031.9322 -269.10979 1029.6735 -269.34669 1027.6875 -269.15625 C 1024.6287 -268.86293 1022.7155 -268.67226 1020.7812 -268.5 C 1018.847 -268.32773 1019.0926 -268.07763 1017.875 -267.96875 C 1016.5588 -267.85105 1016.1152 -268.13238 1012.3438 -267.71875 C 1008.8017 -267.3303 1003.3359 -266.50948 1002.0625 -265.84375 C 1000.4636 -266.13844 998.1753 -266.35076 996.1875 -266.15625 C 993.12921 -265.857 991.2463 -265.67601 989.3125 -265.5 C 988.65501 -265.44015 988.27245 -265.32144 987.96875 -265.25 C 987.54105 -265.13104 987.28525 -265.03193 986.59375 -264.96875 C 985.27775 -264.84849 984.834 -265.16363 981.0625 -264.75 C 977.50631 -264.35998 972.0569 -263.51084 970.8125 -262.84375 C 969.21381 -263.13793 966.95265 -263.36747 964.96875 -263.15625 C 961.91305 -262.83092 959.9947 -262.63001 958.0625 -262.4375 C 956.13031 -262.24499 956.37275 -261.99662 955.15625 -261.875 C 953.84137 -261.74353 953.3932 -262.03954 949.625 -261.59375 C 946.08611 -261.17509 940.6473 -260.30158 939.375 -259.625 C 937.77741 -259.90604 935.51505 -260.04543 933.53125 -259.8125 C 930.47927 -259.45413 928.58625 -259.24464 926.65625 -259.03125 C 926.00007 -258.95869 925.6156 -258.85856 925.3125 -258.78125 C 924.88571 -258.65402 924.6276 -258.51405 923.9375 -258.4375 C 922.62411 -258.29181 922.17015 -258.61152 918.40625 -258.125 C 914.85737 -257.66624 909.4276 -256.70598 908.1875 -256 C 906.59441 -256.24424 904.3537 -256.38135 902.375 -256.125 C 899.32741 -255.73018 897.4243 -255.47655 895.5 -255.21875 C 893.57571 -254.96096 893.7739 -254.72522 892.5625 -254.5625 C 891.25301 -254.3866 890.8153 -254.66688 887.0625 -254.09375 C 883.53821 -253.55551 878.1393 -252.39458 876.875 -251.65625 C 875.28751 -251.85979 873.0295 -251.91098 871.0625 -251.5625 C 868.03631 -251.02638 866.1636 -250.70081 864.25 -250.375 C 863.59941 -250.26423 863.2363 -250.10406 862.9375 -250 C 862.51681 -249.83512 862.27405 -249.6687 861.59375 -249.53125 C 860.29905 -249.26966 859.86665 -249.53745 856.15625 -248.71875 C 852.65777 -247.9468 847.31035 -246.33582 846.09375 -245.5 C 844.53085 -245.57745 842.33625 -245.41472 840.40625 -244.90625 C 837.43387 -244.12312 835.58855 -243.67416 833.71875 -243.15625 C 831.84875 -242.63835 832.0521 -242.38897 830.875 -242.0625 C 829.60251 -241.7096 829.17795 -241.95541 825.53125 -240.875 C 822.10657 -239.86037 816.88185 -237.94183 815.65625 -237.03125 C 814.11747 -237.01851 811.93645 -236.75903 810.03125 -236.15625 C 807.10027 -235.22891 805.2809 -234.69783 803.4375 -234.09375 C 802.81071 -233.88837 802.44585 -233.70117 802.15625 -233.5625 C 801.74867 -233.34889 801.50295 -233.15375 800.84375 -232.9375 C 799.58925 -232.52596 799.1576 -232.74846 795.5625 -231.5 C 792.17261 -230.32283 786.96755 -228.2863 785.78125 -227.34375 C 784.25737 -227.28408 782.1312 -226.94888 780.25 -226.28125 C 777.35261 -225.25296 775.55095 -224.60577 773.71875 -223.96875 C 771.88655 -223.33174 772.0909 -223.12021 770.9375 -222.71875 C 769.69071 -222.28479 769.27395 -222.51903 765.71875 -221.15625 C 762.38005 -219.87645 757.23165 -217.6737 756.03125 -216.6875 C 754.52407 -216.57981 752.39555 -216.1887 750.53125 -215.46875 C 747.66307 -214.36115 745.90735 -213.68719 744.09375 -213 C 743.47705 -212.76637 743.0973 -212.55797 742.8125 -212.40625 C 742.81251 -212.40625 742.8125 -212.37673 742.8125 -212.375 L 734.8125 -209.1875 L 736.625 -194.46875 C 736.36701 -194.52956 742.8125 -191.15625 742.8125 -191.15625 C 743.03891 -191.30093 743.26145 -191.42886 743.53125 -191.53125 C 744.61177 -191.94123 745.70285 -191.74702 749.53125 -193.21875 C 753.35977 -194.69049 754.7553 -195.22373 755.4375 -195.625 C 756.11711 -196.02478 757.04925 -196.50437 757.65625 -197.15625 C 759.48317 -197.294 761.22705 -197.64948 762.59375 -198.15625 C 765.56175 -199.25677 767.4691 -199.96244 769.375 -200.625 C 771.28081 -201.28754 771.72915 -202.03987 772.78125 -202.40625 C 773.87287 -202.78636 774.97635 -202.57163 778.84375 -203.9375 C 782.71115 -205.30336 784.1269 -205.76458 784.8125 -206.15625 C 785.51361 -206.55677 786.5133 -207.08923 787.125 -207.75 C 789.09581 -207.80466 790.94195 -208.13463 792.40625 -208.625 C 795.40777 -209.63008 797.3324 -210.24671 799.25 -210.875 C 800.78861 -211.3791 801.42415 -211.92177 802.15625 -212.3125 C 802.38647 -212.44681 802.63215 -212.56623 802.90625 -212.65625 C 804.00457 -213.01673 805.0877 -212.73762 809 -213.96875 C 812.91231 -215.19988 814.366 -215.6417 815.0625 -216 C 815.75641 -216.35697 816.6926 -216.79261 817.3125 -217.40625 C 819.17771 -217.42891 820.94835 -217.67308 822.34375 -218.09375 C 825.37415 -219.00729 827.33615 -219.52385 829.28125 -220.0625 C 831.22637 -220.60114 831.70745 -221.32702 832.78125 -221.625 C 833.89527 -221.93415 835.00125 -221.61761 838.96875 -222.65625 C 842.93625 -223.69488 844.38625 -224.08898 845.09375 -224.40625 C 845.82855 -224.73584 846.90765 -225.15997 847.53125 -225.78125 C 849.52907 -225.66525 851.3887 -225.80134 852.875 -226.15625 C 855.95311 -226.89125 857.9584 -227.25719 859.9375 -227.65625 C 861.52541 -227.97643 862.1818 -228.4468 862.9375 -228.75 C 863.17501 -228.8568 863.4044 -228.94276 863.6875 -229 C 864.82091 -229.22919 865.99215 -228.79107 870.03125 -229.5 C 874.07067 -230.20893 875.5315 -230.42709 876.25 -230.6875 C 876.96581 -230.94694 877.95435 -231.25474 878.59375 -231.78125 C 880.51795 -231.54176 882.34165 -231.55672 883.78125 -231.78125 C 886.90767 -232.26887 888.9358 -232.48192 890.9375 -232.75 C 892.93921 -233.01807 893.42625 -233.69514 894.53125 -233.84375 C 895.67767 -233.99793 896.8071 -233.54218 900.875 -234.0625 C 904.94281 -234.58282 906.43525 -234.75823 907.15625 -235 C 907.89337 -235.24714 908.95435 -235.58623 909.59375 -236.125 C 911.64375 -235.78947 913.56745 -235.72704 915.09375 -235.90625 C 918.23595 -236.27521 920.27375 -236.46561 922.28125 -236.6875 C 923.89207 -236.86552 924.5459 -237.2957 925.3125 -237.53125 C 925.55341 -237.61677 925.80655 -237.68685 926.09375 -237.71875 C 927.24345 -237.84647 928.39505 -237.3721 932.46875 -237.84375 C 936.54245 -238.3154 938.0278 -238.45435 938.75 -238.6875 C 939.46941 -238.91977 940.45025 -239.16096 941.09375 -239.65625 C 943.03005 -239.32279 944.8638 -239.25201 946.3125 -239.40625 C 949.45851 -239.7412 951.49 -239.92484 953.5 -240.125 C 955.50991 -240.32514 955.98415 -240.95139 957.09375 -241.0625 C 958.24485 -241.17778 959.39025 -240.69744 963.46875 -241.125 C 967.54725 -241.55256 969.05765 -241.68709 969.78125 -241.90625 C 970.52047 -242.13011 971.57685 -242.4195 972.21875 -242.9375 C 974.27575 -242.53883 976.2206 -242.4441 977.75 -242.59375 C 980.89871 -242.90185 982.9258 -243.067 984.9375 -243.25 C 986.55151 -243.39682 987.20055 -243.81055 987.96875 -244.03125 C 988.21005 -244.11211 988.4623 -244.16116 988.75 -244.1875 C 989.90211 -244.29295 991.0429 -243.79475 995.125 -244.1875 C 999.20711 -244.58025 1000.7139 -244.71834 1001.4375 -244.9375 C 1002.1584 -245.15583 1003.1371 -245.3852 1003.7812 -245.875 C 1005.7193 -245.52501 1007.5501 -245.42062 1009 -245.5625 C 1012.1487 -245.8706 1014.1758 -246.03575 1016.1875 -246.21875 C 1018.1991 -246.40174 1018.7017 -247.05677 1019.8125 -247.15625 C 1020.9648 -247.25948 1022.1047 -246.77142 1026.1875 -247.15625 C 1030.2704 -247.54107 1031.7762 -247.65725 1032.5 -247.875 C 1033.2393 -248.09743 1034.2956 -248.38949 1034.9375 -248.90625 C 1036.9949 -248.50448 1038.9404 -248.40292 1040.4688 -248.5625 C 1043.6153 -248.89102 1045.6458 -249.0852 1047.6562 -249.28125 C 1049.2692 -249.43854 1049.9219 -249.91273 1050.6875 -250.15625 C 1050.9282 -250.24429 1051.1507 -250.27762 1051.4375 -250.3125 C 1052.5858 -250.4522 1053.7542 -249.97259 1057.8125 -250.5625 C 1061.8708 -251.15242 1063.3743 -251.33964 1064.0938 -251.59375 C 1064.8104 -251.84691 1065.7684 -252.15182 1066.4062 -252.6875 C 1068.3259 -252.47556 1070.1262 -252.53609 1071.5625 -252.78125 C 1074.6816 -253.31365 1076.6741 -253.70986 1078.6562 -254.09375 C 1080.6383 -254.47762 1081.1305 -255.1334 1082.2188 -255.375 C 1083.3475 -255.62566 1084.489 -255.25871 1088.4688 -256.25 C 1092.4483 -257.24127 1093.8983 -257.6693 1094.5938 -258.03125 C 1095.316 -258.40725 1096.3555 -258.90183 1096.9688 -259.5625 C 1098.9317 -259.57454 1100.7625 -259.85355 1102.1875 -260.40625 C 1105.1387 -261.55085 1107.0607 -262.27567 1108.875 -263.15625 C 1110.3307 -263.86277 1111.1941 -264.85828 1111.4062 -265.15625 C 1111.6185 -265.4542 1111.5051 -265.8848 1111.5312 -265.90625 C 1111.5742 -265.94148 1111.8716 -266.00028 1112.0312 -266.34375 C 1112.8902 -268.19082 1114.3544 -271.97139 1114.4688 -272.65625 C 1114.5825 -273.33839 1114.6368 -274.00902 1114.6875 -274.40625 C 1114.7169 -274.63575 1114.5404 -275.28515 1114.5625 -275.34375 C 1114.5934 -275.42579 1114.8508 -275.59432 1114.9062 -275.84375 C 1115.1725 -277.04206 1114.9953 -278.05111 1114.7812 -279.46875 C 1114.5673 -280.88638 1113.8096 -284.08338 1113.1562 -284.9375 C 1112.4973 -285.79922 1111.9314 -285.94801 1111.4062 -285.9375 z "
- style="display:inline;fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- id="path7423-8"
- d="m 1111.4062,-285.9375 -3.9374,1.875 c -0.041,0.0102 -0.1,0.0205 -0.125,0.0312 -0.4188,0.21285 -0.1647,0.10058 -0.6563,0.3125 -0.4861,0.20956 -1.7376,0.58419 -4.0937,1.46875 -3.3312,1.25058 -5.8043,2.14984 -7,3.0625 -1.5362,0.0213 -3.7205,0.23331 -5.6563,0.71875 -2.9815,0.74767 -4.8552,1.17401 -6.75,1.59375 -1.8948,0.41973 -1.6755,0.64219 -2.875,0.875 -1.2966,0.25167 -1.7214,-0.009 -5.4375,0.78125 -3.4899,0.74215 -8.8948,1.93107 -10.1562,2.6875 -1.584,-0.18078 -3.8675,-0.32178 -5.8438,-0.0312 -3.0404,0.44696 -4.9162,0.67276 -6.8438,0.90625 -0.6554,0.0794 -1.041,0.20078 -1.3437,0.28125 -0.4262,0.13166 -0.6858,0.26002 -1.375,0.34375 -1.3116,0.15937 -1.7622,-0.15683 -5.5313,0.28125 -3.5539,0.41309 -9.0054,1.27282 -10.25,1.9375 -1.599,-0.29729 -3.8577,-0.53419 -5.8437,-0.34375 -3.0588,0.29332 -4.972,0.48399 -6.9063,0.65625 -1.9342,0.17227 -1.6886,0.42237 -2.9062,0.53125 -1.3162,0.1177 -1.7598,-0.16363 -5.5312,0.25 -3.5421,0.38845 -9.0079,1.20927 -10.2813,1.875 -1.5989,-0.29469 -3.8872,-0.50701 -5.875,-0.3125 -3.05829,0.29925 -4.9412,0.48024 -6.875,0.65625 -0.65749,0.0598 -1.04005,0.17856 -1.34375,0.25 -0.4277,0.11896 -0.6835,0.21807 -1.375,0.28125 -1.316,0.12026 -1.75975,-0.19488 -5.53125,0.21875 -3.55619,0.39002 -9.0056,1.23916 -10.25,1.90625 -1.59869,-0.29418 -3.85985,-0.52372 -5.84375,-0.3125 -3.0557,0.32533 -4.97405,0.52624 -6.90625,0.71875 -1.93219,0.19251 -1.68975,0.44088 -2.90625,0.5625 -1.31488,0.13147 -1.76305,-0.16454 -5.53125,0.28125 -3.53889,0.41866 -8.9777,1.29217 -10.25,1.96875 -1.59759,-0.28104 -3.85995,-0.42043 -5.84375,-0.1875 -3.05198,0.35837 -4.945,0.56786 -6.875,0.78125 -0.65618,0.0726 -1.04065,0.17269 -1.34375,0.25 -0.42679,0.12723 -0.6849,0.2672 -1.375,0.34375 -1.31339,0.14569 -1.76735,-0.17402 -5.53125,0.3125 -3.54888,0.45876 -8.97865,1.41902 -10.21875,2.125 -1.59309,-0.24424 -3.8338,-0.38135 -5.8125,-0.125 -3.04759,0.39482 -4.9507,0.64845 -6.875,0.90625 -1.92429,0.25779 -1.7261,0.49353 -2.9375,0.65625 -1.30949,0.1759 -1.7472,-0.10438 -5.5,0.46875 -3.52429,0.53824 -8.9232,1.69917 -10.1875,2.4375 -1.58749,-0.20354 -3.8455,-0.25473 -5.8125,0.0937 -3.02619,0.53612 -4.8989,0.86169 -6.8125,1.1875 -0.65059,0.11077 -1.0137,0.27094 -1.3125,0.375 -0.42069,0.16488 -0.66345,0.3313 -1.34375,0.46875 -1.2947,0.26159 -1.7271,-0.006 -5.4375,0.8125 -3.49848,0.77195 -8.8459,2.38293 -10.0625,3.21875 -1.5629,-0.0774 -3.7575,0.0853 -5.6875,0.59375 -2.97238,0.78313 -4.8177,1.23209 -6.6875,1.75 -1.87,0.5179 -1.66665,0.76728 -2.84375,1.09375 -1.27249,0.3529 -1.69705,0.10709 -5.34375,1.1875 -3.42468,1.01463 -8.6494,2.93317 -9.875,3.84375 -1.53878,0.0127 -3.7198,0.27222 -5.625,0.875 -2.93098,0.92734 -4.75035,1.45842 -6.59375,2.0625 -0.62679,0.20538 -0.99165,0.39258 -1.28125,0.53125 -0.40758,0.21361 -0.6533,0.40875 -1.3125,0.625 -1.2545,0.41154 -1.68615,0.18904 -5.28125,1.4375 -3.38989,1.17717 -8.59495,3.2137 -9.78125,4.15625 -1.52388,0.0597 -3.65005,0.39487 -5.53125,1.0625 -2.89739,1.02829 -4.69905,1.67548 -6.53125,2.3125 -1.8322,0.63701 -1.62785,0.84854 -2.78125,1.25 -1.24679,0.43396 -1.66355,0.19972 -5.21875,1.5625 -3.3387,1.2798 -8.4871,3.48255 -9.6875,4.46875 -1.50718,0.10769 -3.6357,0.4988 -5.5,1.21875 -2.86818,1.1076 -4.6239,1.78156 -6.4375,2.46875 -0.6167,0.23363 -0.99645,0.44203 -1.28125,0.59375 10e-6,0 0,0.0295 0,0.0312 l -8,3.1875 1.8125,14.71875 c -0.25799,-0.0608 6.1875,3.3125 6.1875,3.3125 0.22641,-0.14468 0.44895,-0.27261 0.71875,-0.375 1.08052,-0.40998 2.1716,-0.21577 6,-1.6875 3.82852,-1.47174 5.22405,-2.00498 5.90625,-2.40625 0.67961,-0.39978 1.61175,-0.87937 2.21875,-1.53125 1.82692,-0.13775 3.5708,-0.49323 4.9375,-1 2.968,-1.10052 4.87535,-1.80619 6.78125,-2.46875 1.90581,-0.66254 2.35415,-1.41487 3.40625,-1.78125 1.09162,-0.38011 2.1951,-0.16538 6.0625,-1.53125 3.8674,-1.36586 5.28315,-1.82708 5.96875,-2.21875 0.70111,-0.40052 1.7008,-0.93298 2.3125,-1.59375 1.97081,-0.0547 3.81695,-0.38463 5.28125,-0.875 3.00152,-1.00508 4.92615,-1.62171 6.84375,-2.25 1.53861,-0.5041 2.17415,-1.04677 2.90625,-1.4375 0.23022,-0.13431 0.4759,-0.25373 0.75,-0.34375 1.09832,-0.36048 2.18145,-0.0814 6.09375,-1.3125 3.91231,-1.23113 5.366,-1.67295 6.0625,-2.03125 0.69391,-0.35697 1.6301,-0.79261 2.25,-1.40625 1.86521,-0.0227 3.63585,-0.26683 5.03125,-0.6875 3.0304,-0.91354 4.9924,-1.4301 6.9375,-1.96875 1.94512,-0.53864 2.4262,-1.26452 3.5,-1.5625 1.11402,-0.30915 2.22,0.007 6.1875,-1.03125 3.9675,-1.03863 5.4175,-1.43273 6.125,-1.75 0.7348,-0.32959 1.8139,-0.75372 2.4375,-1.375 1.99782,0.116 3.85745,-0.0201 5.34375,-0.375 3.07811,-0.735 5.0834,-1.10094 7.0625,-1.5 1.58791,-0.32018 2.2443,-0.79055 3,-1.09375 0.23751,-0.1068 0.4669,-0.19276 0.75,-0.25 1.13341,-0.22919 2.30465,0.20893 6.34375,-0.5 4.03942,-0.70893 5.50025,-0.92709 6.21875,-1.1875 0.71581,-0.25944 1.70435,-0.56724 2.34375,-1.09375 1.9242,0.23949 3.7479,0.22453 5.1875,0 3.12642,-0.48762 5.15455,-0.70067 7.15625,-0.96875 2.00171,-0.26807 2.48875,-0.94514 3.59375,-1.09375 1.14642,-0.15418 2.27585,0.30157 6.34375,-0.21875 4.06781,-0.52032 5.56025,-0.69573 6.28125,-0.9375 0.73712,-0.24714 1.7981,-0.58623 2.4375,-1.125 2.05,0.33553 3.9737,0.39796 5.5,0.21875 3.1422,-0.36896 5.18,-0.55936 7.1875,-0.78125 1.61082,-0.17802 2.26465,-0.6082 3.03125,-0.84375 0.24091,-0.0855 0.49405,-0.1556 0.78125,-0.1875 1.1497,-0.12772 2.3013,0.34665 6.375,-0.125 4.0737,-0.47165 5.55905,-0.6106 6.28125,-0.84375 0.71941,-0.23227 1.70025,-0.47346 2.34375,-0.96875 1.9363,0.33346 3.77005,0.40424 5.21875,0.25 3.14601,-0.33495 5.1775,-0.51859 7.1875,-0.71875 2.00991,-0.20014 2.48415,-0.82639 3.59375,-0.9375 1.1511,-0.11528 2.2965,0.36506 6.375,-0.0625 4.0785,-0.42756 5.5889,-0.56209 6.3125,-0.78125 0.73922,-0.22386 1.7956,-0.51325 2.4375,-1.03125 2.057,0.39867 4.00185,0.4934 5.53125,0.34375 3.14871,-0.3081 5.1758,-0.47325 7.1875,-0.65625 1.61401,-0.14682 2.26305,-0.56055 3.03125,-0.78125 0.2413,-0.0809 0.49355,-0.12991 0.78125,-0.15625 1.15211,-0.10545 2.2929,0.39275 6.375,0 4.08211,-0.39275 5.5889,-0.53084 6.3125,-0.75 0.7209,-0.21833 1.6996,-0.4477 2.3437,-0.9375 1.9381,0.34999 3.7689,0.45438 5.2188,0.3125 3.1487,-0.3081 5.1758,-0.47325 7.1875,-0.65625 2.0116,-0.18299 2.5142,-0.83802 3.625,-0.9375 1.1523,-0.10323 2.2922,0.38483 6.375,0 4.0829,-0.38482 5.5887,-0.501 6.3125,-0.71875 0.7393,-0.22243 1.7956,-0.51449 2.4375,-1.03125 2.0574,0.40177 4.0029,0.50333 5.5313,0.34375 3.1465,-0.32852 5.177,-0.5227 7.1874,-0.71875 1.613,-0.15729 2.2657,-0.63148 3.0313,-0.875 0.2407,-0.088 0.4632,-0.12137 0.75,-0.15625 1.1483,-0.1397 2.3167,0.33991 6.375,-0.25 4.0583,-0.58992 5.5618,-0.77714 6.2813,-1.03125 0.7166,-0.25316 1.6746,-0.55807 2.3124,-1.09375 1.9197,0.21194 3.72,0.15141 5.1563,-0.0937 3.1191,-0.5324 5.1116,-0.92861 7.0937,-1.3125 1.9821,-0.38387 2.4743,-1.03965 3.5626,-1.28125 1.1287,-0.25066 2.2702,0.11629 6.25,-0.875 3.9795,-0.99127 5.4295,-1.4193 6.125,-1.78125 0.7222,-0.376 1.7617,-0.87058 2.375,-1.53125 1.9629,-0.012 3.7937,-0.29105 5.2187,-0.84375 2.9512,-1.1446 4.8732,-1.86942 6.6875,-2.75 1.4557,-0.70652 2.3191,-1.70203 2.5312,-2 0.2123,-0.29795 0.099,-0.72855 0.125,-0.75 0.043,-0.0352 0.3404,-0.094 0.5,-0.4375 0.859,-1.84707 2.3232,-5.62764 2.4376,-6.3125 0.1137,-0.68214 0.168,-1.35277 0.2187,-1.75 0.029,-0.2295 -0.1471,-0.8789 -0.125,-0.9375 0.031,-0.082 0.2883,-0.25057 0.3437,-0.5 0.2663,-1.19831 0.089,-2.20736 -0.125,-3.625 -0.2139,-1.41763 -0.9716,-4.61463 -1.625,-5.46875 -0.6589,-0.86172 -1.2248,-1.01051 -1.75,-1 z"
- transform="translate(0.08004571,-0.03125)" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter7001-5">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur7003-7" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6949-4"
- x="-0.10294895"
- width="1.2058979"
- y="-0.34224695"
- height="1.6844939">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6951-1" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6961-8"
- x="-0.09919104"
- width="1.1983821"
- y="-0.22643611"
- height="1.4528722">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6963-5" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6957-9"
- x="-0.098213427"
- width="1.1964267"
- y="-0.19838208"
- height="1.3967642">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6959-7" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6997-5">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6999-3" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6953-8"
- x="-0.098320946"
- width="1.1966419"
- y="-0.19750816"
- height="1.3950163">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6955-8" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6993-3"
- x="-0.098213255"
- width="1.1964265"
- y="-0.19838208"
- height="1.3967642">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6995-1" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6989-8"
- x="-0.098428868"
- width="1.1968577"
- y="-0.20287035"
- height="1.4057407">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6991-9" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6985-6"
- x="-0.098428868"
- width="1.1968577"
- y="-0.20853186"
- height="1.4170637">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6987-4" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6965-3"
- x="-0.099081434"
- width="1.1981629"
- y="-0.22529824"
- height="1.4505965">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6967-3" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6981-3"
- x="-0.10052545"
- width="1.2010509"
- y="-0.2742162"
- height="1.5484324">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6983-8" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6977-6"
- x="-0.10224481"
- width="1.2044896"
- y="-0.32371372"
- height="1.6474274">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6979-0" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6973-4"
- x="-0.10330495"
- width="1.2066098"
- y="-0.36439717"
- height="1.7287945">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6975-8" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter6969-8"
- x="-0.10450897"
- width="1.2090179"
- y="-0.40468886"
- height="1.8093777">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.1675612"
- id="feGaussianBlur6971-8" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7345-9">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="1.7233839"
- id="feGaussianBlur7347-7" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7333-7">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7335-6" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7285-4"
- x="-0.030884685"
- width="1.0617694"
- y="-0.10267408"
- height="1.2053483">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7287-3" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7289-0">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7291-3" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7293-0">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7295-9" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7337-2">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7339-5" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7297-4">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7299-0" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7301-5">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7303-9" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7305-4">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7307-6" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7309-9">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7311-2" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7313-2">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7315-4" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7317-7">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7319-7" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7321-5">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7323-4" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7329-8"
- x="-0.030991485"
- width="1.061983"
- y="-0.10931916"
- height="1.2186383">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7331-1" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter7325-2"
- x="-0.031352691"
- width="1.0627054"
- y="-0.12140666"
- height="1.2428133">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.35026836"
- id="feGaussianBlur7327-8" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter9048-9"
- x="-0.40879121"
- width="1.8175824"
- y="-0.71538466"
- height="2.4307692">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="21.92031"
- id="feGaussianBlur9050-3" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3631-6">
- <path
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 760.16396,935.83377 c 6.7941,18.90279 10.49369,33.29969 11.8903,51.21189 1.39662,17.91234 -3.78268,51.80084 -2.90046,70.65614 0.88175,18.8452 8.13369,40.099 27.34463,48.9689 19.41887,8.9658 49.31924,10.2113 74.11984,-3.1456 24.8006,-13.357 57.40102,-70.3255 70.97426,-97.3087 13.62385,-27.08394 38.76107,-114.49737 44.6608,-149.76859 5.89973,-35.27121 2.55054,-41.30077 -4.61748,-49.05549 2.6403,-27.84015 -1.49972,-54.93543 13.10969,-87.18618 -30.24901,11.8257 -37.38229,40.1607 -48.31889,65.50508 -8.00091,-50.93293 0.20916,-71.27319 3.31889,-101.21936 -29.06476,14.77791 -42.86151,47.11402 -45,92.85714 -10.92395,-1.3042 -21.39144,-4.43423 -33.57143,-0.71429 -0.26404,-46.02334 -1.46356,-76.88941 8.91063,-114.20649 -53.25547,21.02686 -62.94728,106.5941 -56.05349,112.77792 -10.88282,0.535 -21.37108,-1.2973 -32.85714,2.85715 0.63892,-42.57135 -0.26046,-84.90861 -30,-122.85715 0,0 -30.95806,80.92234 -31.42857,103.57143 -0.47051,22.64909 9.45159,40.16588 9.45159,40.16588 0,0 -8.56807,36.74051 -6.29859,58.23223 2.29585,21.74146 20.4429,59.67617 27.26542,78.65809 z"
- id="path3633-8"
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3677-0">
- <path
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 586.13271,997.98981 c 6.7941,18.90279 10.49369,33.29969 11.8903,51.21189 1.39662,17.9123 -3.78268,51.8008 -2.90046,70.6561 0.88175,18.8452 8.13369,40.099 27.34463,48.9689 19.41887,8.9658 49.31924,10.2113 74.11984,-3.1456 24.8006,-13.357 57.40102,-70.3255 70.97426,-97.3087 13.62385,-27.0839 38.76107,-114.49733 44.6608,-149.76855 5.89973,-35.27121 2.55054,-41.30077 -4.61748,-49.05549 2.6403,-27.84015 -1.49972,-54.93543 13.10969,-87.18618 -30.24901,11.8257 -37.38229,40.1607 -48.31889,65.50508 -8.00091,-50.93293 0.20916,-71.27319 3.31889,-101.21936 -29.06476,14.77791 -42.86151,47.11402 -45,92.85714 -10.92395,-1.3042 -21.39144,-4.43423 -33.57143,-0.71429 -0.26404,-46.02334 -1.46356,-76.88941 8.91063,-114.20649 -53.25547,21.02686 -62.94728,106.5941 -56.05349,112.77792 -10.88282,0.535 -21.37108,-1.2973 -32.85714,2.85715 0.63892,-42.57135 -0.26046,-84.90861 -30,-122.85715 0,0 -30.95806,80.92234 -31.42857,103.57143 -0.47051,22.64909 9.45159,40.16588 9.45159,40.16588 0,0 -8.56807,36.74051 -6.29859,58.23223 2.29585,21.74146 20.4429,59.67617 27.26542,78.65809 z"
- id="path3679-2"
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter3898-1">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="10.892985"
- id="feGaussianBlur3900-0" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3622-5">
- <path
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 266.27183,924.57186 c -1.40727,18.80121 -1.1449,32.75103 2.08174,49.30328 3.22665,16.55234 16.40608,45.90736 20.3344,63.18376 3.92622,17.2671 2.69413,38.3096 -12.45944,51.1482 -15.31761,12.9774 -42.05127,21.5989 -67.8323,15.7338 -25.78106,-5.8653 -69.54907,-49.2234 -88.59019,-70.2283 C 100.6939,1012.6293 56.045183,939.86194 41.867508,909.43681 27.689836,879.01169 29.207903,872.71824 33.747793,863.90708 24.381071,839.38658 21.334081,813.84027 0.03533552,788.33044 30.360815,791.44488 43.915625,815.28677 60.161025,835.47019 54.631129,787.39416 42.10631,771.05369 31.787073,744.74589 c 29.994295,6.08166 50.57936,31.8724 63.979783,72.7125 9.554154,-3.91791 18.237764,-9.37294 30.187414,-9.0612 -11.2975,-41.6958 -17.94946,-69.91584 -36.687255,-101.06994 53.441965,5.67033 83.657025,80.63932 78.971425,87.9608 9.97797,-2.24399 19.00565,-6.53038 30.43653,-5.65167 -11.24896,-38.34702 -21.04781,-76.8679 -3.65971,-118.64818 0,0 48.28678,65.43687 54.38966,85.80577 6.10287,20.36891 1.51881,38.70052 1.51881,38.70052 0,0 16.95957,31.08529 20.29392,51.09413 3.3731,20.24135 -3.53269,59.10332 -4.94582,77.98324 z"
- id="path3624-1"
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter9024-1"
- x="-0.55453134"
- width="2.1090627"
- y="-0.51434779"
- height="2.0286956">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="20.912684"
- id="feGaussianBlur9026-0" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter9020-8"
- x="-0.32861114"
- width="1.6572223"
- y="-0.182"
- height="1.364">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="20.912684"
- id="feGaussianBlur9022-5" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter9044-0"
- x="-0.32631579"
- width="1.6526316"
- y="-0.84545463"
- height="2.6909094">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="21.92031"
- id="feGaussianBlur9046-6" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath4177-4">
- <path
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- id="path4179-6"
- d="m 586.13271,997.98981 c 6.7941,18.90279 10.49369,33.29969 11.8903,51.21189 1.39662,17.9123 -3.78268,51.8008 -2.90046,70.6561 0.88175,18.8452 8.13369,40.099 27.34463,48.9689 19.41887,8.9658 49.31924,10.2113 74.11984,-3.1456 24.8006,-13.357 57.40102,-70.3255 70.97426,-97.3087 13.62385,-27.0839 38.76107,-114.49733 44.6608,-149.76855 5.89973,-35.27121 2.55054,-41.30077 -4.61748,-49.05549 2.6403,-27.84015 -1.49972,-54.93543 13.10969,-87.18618 -30.24901,11.8257 -37.38229,40.1607 -48.31889,65.50508 -8.00091,-50.93293 0.20916,-71.27319 3.31889,-101.21936 -29.06476,14.77791 -42.86151,47.11402 -45,92.85714 -10.92395,-1.3042 -21.39144,-4.43423 -33.57143,-0.71429 -0.26404,-46.02334 -1.46356,-76.88941 8.91063,-114.20649 -53.25547,21.02686 -62.94728,106.5941 -56.05349,112.77792 -10.88282,0.535 -21.37108,-1.2973 -32.85714,2.85715 0.63892,-42.57135 -0.26046,-84.90861 -30,-122.85715 0,0 -30.95806,80.92234 -31.42857,103.57143 -0.47051,22.64909 9.45159,40.16588 9.45159,40.16588 0,0 -8.56807,36.74051 -6.29859,58.23223 2.29585,21.74146 20.4429,59.67617 27.26542,78.65809 z"
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter4105-2">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="3.8640966"
- id="feGaussianBlur4107-5" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter4130-8"
- x="-0.49509686"
- width="1.9901937"
- y="-0.26708817"
- height="1.5341763">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="10.730622"
- id="feGaussianBlur4132-6" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter4141-2"
- x="-0.40611032"
- width="1.8122206"
- y="-0.30260596"
- height="1.6052119">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="9.8586086"
- id="feGaussianBlur4143-8" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8338-4">
- <path
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- id="path8340-7"
- d="m 266.27183,924.57185 c -1.40727,18.80122 -1.1449,32.75104 2.08174,49.30328 3.22666,16.55238 16.40609,45.90737 20.33441,63.18377 3.92621,17.2671 2.69413,38.3097 -12.45944,51.1482 -15.31761,12.9775 -42.05127,21.599 -67.8323,15.7338 -25.78106,-5.8653 -69.54908,-49.2234 -88.59019,-70.2283 C 100.6939,1012.6293 56.045182,939.86193 41.867507,909.4368 27.689835,879.01168 29.207902,872.71823 33.747792,863.90708 24.38107,839.38658 21.33408,813.84026 0.03533448,788.33044 30.360814,791.44487 43.915624,815.28676 60.161024,835.47019 54.631128,787.39416 42.106309,771.05368 31.787072,744.74589 c 29.994295,6.08165 50.57936,31.87239 63.979783,72.7125 9.554155,-3.91792 18.237765,-9.37294 30.187415,-9.0612 -11.2975,-41.6958 -17.94947,-69.91585 -36.687256,-101.06994 53.441966,5.67032 83.657026,80.63932 78.971426,87.9608 9.97797,-2.24399 19.00565,-6.53038 30.43653,-5.65167 -11.24897,-38.34703 -21.04782,-76.8679 -3.65971,-118.64819 0,0 48.28678,65.43688 54.38965,85.80578 6.10288,20.3689 1.51882,38.70051 1.51882,38.70051 0,0 16.95957,31.0853 20.29392,51.09414 3.3731,20.24134 -3.53269,59.10331 -4.94582,77.98323 z"
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8333-2">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="7.18"
- id="feGaussianBlur8335-4" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8359-0">
- <path
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- id="path8361-6"
- d="m 266.27183,924.57185 c -1.40727,18.80122 -1.1449,32.75104 2.08174,49.30328 3.22666,16.55238 16.40609,45.90737 20.33441,63.18377 3.92621,17.2671 2.69413,38.3097 -12.45944,51.1482 -15.31761,12.9775 -42.05127,21.599 -67.8323,15.7338 -25.78106,-5.8653 -69.54908,-49.2234 -88.59019,-70.2283 C 100.6939,1012.6293 56.045182,939.86193 41.867507,909.4368 27.689835,879.01168 29.207902,872.71823 33.747792,863.90708 24.38107,839.38658 21.33408,813.84026 0.03533448,788.33044 30.360814,791.44487 43.915624,815.28676 60.161024,835.47019 54.631128,787.39416 42.106309,771.05368 31.787072,744.74589 c 29.994295,6.08165 50.57936,31.87239 63.979783,72.7125 9.554155,-3.91792 18.237765,-9.37294 30.187415,-9.0612 -11.2975,-41.6958 -17.94947,-69.91585 -36.687256,-101.06994 53.441966,5.67032 83.657026,80.63932 78.971426,87.9608 9.97797,-2.24399 19.00565,-6.53038 30.43653,-5.65167 -11.24897,-38.34703 -21.04782,-76.8679 -3.65971,-118.64819 0,0 48.28678,65.43688 54.38965,85.80578 6.10288,20.3689 1.51882,38.70051 1.51882,38.70051 0,0 16.95957,31.0853 20.29392,51.09414 3.3731,20.24134 -3.53269,59.10331 -4.94582,77.98323 z"
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8354-2">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="6.82"
- id="feGaussianBlur8356-9" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath3636-90">
- <path
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 760.16396,935.83377 c 6.7941,18.90279 10.49369,33.29969 11.8903,51.21189 1.39662,17.91234 -3.78268,51.80084 -2.90046,70.65614 0.88175,18.8452 8.13369,40.099 27.34463,48.9689 19.41887,8.9658 49.31924,10.2113 74.11984,-3.1456 24.8006,-13.357 57.40102,-70.3255 70.97426,-97.3087 13.62385,-27.08394 38.76107,-114.49737 44.6608,-149.76859 5.89973,-35.27121 2.55054,-41.30077 -4.61748,-49.05549 2.6403,-27.84015 -1.49972,-54.93543 13.10969,-87.18618 -30.24901,11.8257 -37.38229,40.1607 -48.31889,65.50508 -8.00091,-50.93293 0.20916,-71.27319 3.31889,-101.21936 -29.06476,14.77791 -42.86151,47.11402 -45,92.85714 -10.92395,-1.3042 -21.39144,-4.43423 -33.57143,-0.71429 -0.26404,-46.02334 -1.46356,-76.88941 8.91063,-114.20649 -53.25547,21.02686 -62.94728,106.5941 -56.05349,112.77792 -10.88282,0.535 -21.37108,-1.2973 -32.85714,2.85715 0.63892,-42.57135 -0.26046,-84.90861 -30,-122.85715 0,0 -30.95806,80.92234 -31.42857,103.57143 -0.47051,22.64909 9.45159,40.16588 9.45159,40.16588 0,0 -8.56807,36.74051 -6.29859,58.23223 2.29585,21.74146 20.4429,59.67617 27.26542,78.65809 z"
- id="path3638-8"
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter4185-1">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="3.6164709"
- id="feGaussianBlur4187-3" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8392-1">
- <path
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- id="path8394-1"
- d="m 760.16396,935.83377 c 6.7941,18.90279 10.49369,33.29969 11.8903,51.21189 1.39662,17.91234 -3.78268,51.80084 -2.90046,70.65614 0.88175,18.8452 8.13369,40.099 27.34463,48.9689 19.41887,8.9658 49.31924,10.2113 74.11984,-3.1456 24.8006,-13.357 57.40102,-70.3255 70.97426,-97.3087 13.62385,-27.08394 38.76107,-114.49737 44.6608,-149.76859 5.89973,-35.27121 2.55054,-41.30077 -4.61748,-49.05549 2.6403,-27.84015 -1.49972,-54.93543 13.10969,-87.18618 -30.24901,11.8257 -37.38229,40.1607 -48.31889,65.50508 -8.00091,-50.93293 0.20916,-71.27319 3.31889,-101.21936 -29.06476,14.77791 -42.86151,47.11402 -45,92.85714 -10.92395,-1.3042 -21.39144,-4.43423 -33.57143,-0.71429 -0.26404,-46.02334 -1.46356,-76.88941 8.91063,-114.20649 -53.25547,21.02686 -62.94728,106.5941 -56.05349,112.77792 -10.88282,0.535 -21.37108,-1.2973 -32.85714,2.85715 0.63892,-42.57135 -0.26046,-84.90861 -30,-122.85715 0,0 -30.95806,80.92234 -31.42857,103.57143 -0.47051,22.64909 9.45159,40.16588 9.45159,40.16588 0,0 -8.56807,36.74051 -6.29859,58.23223 2.29585,21.74146 20.4429,59.67617 27.26542,78.65809 z"
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8379-0"
- x="-0.14413793"
- width="1.288276"
- y="-0.10278689"
- height="1.2055738">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="7.389266"
- id="feGaussianBlur8381-3" />
- </filter>
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath8417-4">
- <path
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- id="path8419-03"
- d="m 760.16396,935.83377 c 6.7941,18.90279 10.49369,33.29969 11.8903,51.21189 1.39662,17.91234 -3.78268,51.80084 -2.90046,70.65614 0.88175,18.8452 8.13369,40.099 27.34463,48.9689 19.41887,8.9658 49.31924,10.2113 74.11984,-3.1456 24.8006,-13.357 57.40102,-70.3255 70.97426,-97.3087 13.62385,-27.08394 38.76107,-114.49737 44.6608,-149.76859 5.89973,-35.27121 2.55054,-41.30077 -4.61748,-49.05549 2.6403,-27.84015 -1.49972,-54.93543 13.10969,-87.18618 -30.24901,11.8257 -37.38229,40.1607 -48.31889,65.50508 -8.00091,-50.93293 0.20916,-71.27319 3.31889,-101.21936 -29.06476,14.77791 -42.86151,47.11402 -45,92.85714 -10.92395,-1.3042 -21.39144,-4.43423 -33.57143,-0.71429 -0.26404,-46.02334 -1.46356,-76.88941 8.91063,-114.20649 -53.25547,21.02686 -62.94728,106.5941 -56.05349,112.77792 -10.88282,0.535 -21.37108,-1.2973 -32.85714,2.85715 0.63892,-42.57135 -0.26046,-84.90861 -30,-122.85715 0,0 -30.95806,80.92234 -31.42857,103.57143 -0.47051,22.64909 9.45159,40.16588 9.45159,40.16588 0,0 -8.56807,36.74051 -6.29859,58.23223 2.29585,21.74146 20.4429,59.67617 27.26542,78.65809 z"
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- </clipPath>
- <filter
- inkscape:collect="always"
- id="filter8404-9"
- x="-0.090268657"
- width="1.1805373"
- y="-0.10250848"
- height="1.205017">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="5.3457272"
- id="feGaussianBlur8406-1" />
- </filter>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient2843"
- id="linearGradient6951"
- gradientUnits="userSpaceOnUse"
- x1="347.89655"
- y1="1070.2124"
- x2="275.58191"
- y2="867.97992" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient8964"
- id="linearGradient6953"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(450.03125,73.843964)"
- x1="603.84064"
- y1="627.85303"
- x2="616.24396"
- y2="585.42664" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient8952"
- id="linearGradient6955"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(450.03125,73.843964)"
- x1="609.31244"
- y1="239.46866"
- x2="560.83142"
- y2="262.86206" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3961"
- id="linearGradient6957"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(450.03125,73.843964)"
- x1="398.21429"
- y1="343.52289"
- x2="379.28571"
- y2="265.30862" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4084"
- id="linearGradient6959"
- gradientUnits="userSpaceOnUse"
- x1="182.35046"
- y1="256.11136"
- x2="145.53348"
- y2="542.20502" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4084"
- id="linearGradient6961"
- gradientUnits="userSpaceOnUse"
- x1="182.35046"
- y1="256.11136"
- x2="145.53348"
- y2="542.20502" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4478"
- id="linearGradient6963"
- gradientUnits="userSpaceOnUse"
- x1="412.08926"
- y1="404.91574"
- x2="417.375"
- y2="401.82648" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4478"
- id="linearGradient6965"
- gradientUnits="userSpaceOnUse"
- x1="411.91071"
- y1="404.91577"
- x2="417.375"
- y2="401.82648" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4478"
- id="linearGradient6967"
- gradientUnits="userSpaceOnUse"
- x1="411.91071"
- y1="405.54077"
- x2="417.375"
- y2="401.82648" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4478"
- id="linearGradient6969"
- gradientUnits="userSpaceOnUse"
- x1="412.08926"
- y1="405.54077"
- x2="417.375"
- y2="401.82648" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4478"
- id="linearGradient6971"
- gradientUnits="userSpaceOnUse"
- x1="411.73212"
- y1="405.54077"
- x2="417.375"
- y2="401.82648" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3660"
- id="linearGradient6973"
- gradientUnits="userSpaceOnUse"
- x1="1255.7386"
- y1="667.09216"
- x2="893.69995"
- y2="858.01099" />
- <clipPath
- clipPathUnits="userSpaceOnUse"
- id="clipPath6975">
- <rect
- id="rect6977"
- width="440"
- height="376"
- x="547.99994"
- y="205.32277"
- style="display:inline;opacity:1;fill:none;fill-opacity:1;stroke:#f8d615;stroke-width:18;stroke-linejoin:miter;stroke-miterlimit:1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;enable-background:new" />
- </clipPath>
- <marker
- inkscape:stockid="Arrow1Send"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Send-4"
- style="overflow:visible"
- inkscape:isstock="true">
- <path
- inkscape:connector-curvature="0"
- id="path7188-9"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
- style="fill:#f8d615;fill-opacity:1;fill-rule:evenodd;stroke:#f8d615;stroke-width:1pt;stroke-opacity:1"
- transform="matrix(-0.2,0,0,-0.2,-1.2,0)" />
- </marker>
- </defs>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:groupmode="layer"
- id="layer1"
- inkscape:label="Shadow"
- transform="translate(48.571445,195.53053)" />
- <g
- inkscape:groupmode="layer"
- id="layer20"
- inkscape:label="New Ear"
- transform="translate(48.571445,195.53053)" />
- <g
- inkscape:groupmode="layer"
- id="layer21"
- inkscape:label="Rendered2"
- style="display:inline"
- transform="translate(48.571445,195.53053)" />
- <g
- inkscape:groupmode="layer"
- id="layer15"
- inkscape:label="Feet"
- style="display:inline"
- transform="translate(48.571445,195.53053)" />
- <g
- inkscape:groupmode="layer"
- id="layer16"
- inkscape:label="Left Foot"
- style="display:inline"
- transform="translate(48.571445,195.53053)">
- <rect
- style="display:inline;opacity:1;fill:#a8a8a8;fill-opacity:1;stroke:#000000;stroke-width:20.89992332;stroke-linejoin:miter;stroke-miterlimit:1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;enable-background:new"
- id="rect6676-3-7-5"
- width="1876.7191"
- height="1562.9667"
- x="-38.121483"
- y="-86.153076" />
- <rect
- style="display:inline;opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:20.92477036;stroke-linejoin:miter;stroke-miterlimit:1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;enable-background:new"
- id="rect6676-3-7"
- width="1878.7875"
- height="1564.9603"
- x="2288.5129"
- y="-84.10511" />
- <rect
- style="display:inline;opacity:1;fill:#a8a8a8;fill-opacity:1;stroke:#f83615;stroke-width:20.39127541;stroke-linejoin:miter;stroke-miterlimit:1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;enable-background:new"
- id="rect6676-3"
- width="1833.4282"
- height="1522.9458"
- x="2309.7717"
- y="-62.567806" />
- <g
- id="g4303">
- <path
- inkscape:export-ydpi="142.10527"
- inkscape:export-xdpi="142.10527"
- inkscape:export-filename="/home/cheeseness/Documents/LCA09/mascot/tuz_new.png"
- transform="matrix(10.726753,0,0,10.726753,-2882.1235,-4565.4583)"
- sodipodi:nodetypes="cccccccccsccccccccccc"
- id="path10326"
- d="m 304.64285,526.6479 c -10,0.35715 -18.21428,2.85714 -18.21428,2.85714 l 7.5,6.07143 10.35714,3.57143 16.07143,0.35714 22.5,-5.35714 7.85714,1.07143 20.35715,-2.14286 -10.35715,6.78572 c 5.45923,-1.02361 17.39329,3.56911 9.64286,5.35714 -1.74,0.40142 13.92857,-4.64285 13.92857,-4.64285 l 2.5,-4.64287 3.57143,-9.28571 11.42857,0 18.21428,-4.64286 3.57144,-4.99999 -16.07144,1.07142 -12.14285,2.14286 -14.64286,-5 -70.6921,16.70774 -5.37933,-5.27917 z"
- style="display:inline;opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter11361);enable-background:new"
- inkscape:connector-curvature="0" />
- <g
- transform="matrix(0.71084,-0.1937433,0.262963,0.9648058,503.68027,136.48399)"
- id="g7882"
- style="display:inline;opacity:1;enable-background:new">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient7904);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 245.12255,100.05344 c 0,0 -47.12811,-31.646921 -67.21465,-35.800939 -20.03792,-4.143963 -38.4729,-3.317578 -51.93364,13.607323 -13.46074,16.924901 -12.07739,61.265196 -13.53554,86.969546 -1.45815,25.70435 2.54945,70.17701 17.6046,88.66552 15.05516,18.4885 45.88634,13.58502 49.92695,21.4137 2.21283,4.28736 65.15228,-174.85515 65.15228,-174.85515 z"
- id="path7876"
- sodipodi:nodetypes="czzzzcc"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient7906);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 135.37935,82.017807 c 0,0 26.34355,1.938783 37.63307,13.903188 11.41494,12.097335 13.73457,21.331515 15.29586,37.734585 1.56337,16.42499 -0.84957,28.41812 -7.81382,36.03734 -6.96425,7.61922 -1.00429,19.58332 -25.91605,12.07107 -24.91176,-7.51225 -27.03224,-27.78298 -26.51523,-46.30475 0.51721,-18.52898 7.31617,-53.441433 7.31617,-53.441433 z"
- id="path7878"
- sodipodi:nodetypes="czzzzzc"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;opacity:1;fill:url(#radialGradient7908);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 135.648,81.927211 c 0,0 -4.64465,16.365075 0.58825,28.563099 5.48794,12.79254 27.22425,44.26007 27.22425,54.65565 l 22.65625,-5 c 2.54218,-6.96644 3.21052,-15.75206 2.1875,-26.5 -1.56129,-16.40307 -3.8663,-25.62141 -15.28125,-37.718749 -9.65488,-10.232047 -31.59311,-13.374857 -37.375,-14 z"
- id="path7880"
- sodipodi:nodetypes="czccssc"
- inkscape:connector-curvature="0" />
- </g>
- <path
- sodipodi:nodetypes="czzzcczzcc"
- id="path7917"
- d="m 845.03125,1154.7776 c -4.28571,0.7143 -27.62815,3.6181 -57.85714,10 -30.22899,6.3819 -57.31395,4.9661 -135.78608,17.3296 -79.85178,12.5808 -94.06436,42.5423 -108.12225,47.0643 -14.70014,4.7286 -145.37739,-65.8225 -145.37739,-65.8225 l 4.28572,-94.2857 c 0,0 85.88551,-16.2009 112.14285,-33.5714 26.25735,-17.3705 45.58238,-49.66602 59.28572,-71.42861 13.70334,-21.76259 32.85714,-71.42858 32.85714,-71.42858 l 238.57143,262.14289 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- transform="translate(276,136)"
- sodipodi:nodetypes="ccccc"
- clip-path="url(#clipPath8658)"
- id="path7919"
- d="m 332.34019,898.38549 -32.73181,-61.29956 -37.61734,45.10646 c 2.17675,1.31711 5.77425,-20.85603 45.6004,-64.41708 l 24.74875,80.61018 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8888);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- transform="translate(276,136)"
- sodipodi:nodetypes="cccccc"
- clip-path="url(#clipPath2833)"
- id="path7923"
- d="m 200.81833,863.03015 146.3711,-51.61879 243.95184,226.27414 -241.83052,140.0072 -181.01934,-87.6813 32.52692,-226.98125 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient2841);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8892);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="czzcczcc"
- id="path7921"
- d="m 642.88839,640.13471 c 0,0 -29.55406,40.57305 -47.85714,74.28571 -18.30309,33.71267 -58.62109,126.35694 -70.35714,171.07143 -11.7594,44.80344 -62.5,123.57145 -62.5,123.57145 l 76.07143,18.2143 c 0,0 11.80712,-12.8234 31.07142,-46.07146 19.2643,-33.24808 60.35715,-138.57143 60.35715,-138.57143 l 13.21428,-202.5 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#0f0f0f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- transform="translate(276,136)"
- clip-path="url(#clipPath3665)"
- sodipodi:nodetypes="ccccccc"
- id="path7925"
- d="m 430.28131,381.94122 c -7.07106,2.82843 -236.18124,32.15181 -236.18124,32.15181 l -39.63961,359.83304 90.19849,92.63961 52.3259,-114.5513 100.46804,-186.39192 32.82842,-183.68124 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.4;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8856);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="czzzzcc"
- id="path7927"
- d="m 969.67051,1164.0346 c 0,0 23.25628,11.3937 36.06779,20.4761 12.6974,9.0015 29.4724,24.6491 41.6924,37.3605 12.3055,12.8002 20.1127,22.5987 41.5327,24.1608 21.4322,1.5629 53.2824,-8.7876 73.296,-24.6642 20.0135,-15.8766 45.6469,-69.2328 45.6469,-69.2328 l -127.1608,-143.0717"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- transform="translate(276,136)"
- sodipodi:nodetypes="ccccc"
- clip-path="url(#clipPath8642)"
- id="path7929"
- d="M 331.34019,641.50471 216.17367,835.36467 260.2153,925.96265 357.79603,732.21539 331.34019,641.50471 Z"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.75;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8860);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <g
- inkscape:transform-center-y="-28.255779"
- inkscape:transform-center-x="-347.89063"
- transform="matrix(0.9934486,0.1142802,-0.1142802,0.9934486,-9.24324,588.09054)"
- id="g7931"
- style="display:inline;opacity:1;enable-background:new">
- <path
- id="path7933"
- d="m 1049.205,-282.26672 -0.09,0.008 c -1.3874,0.88445 -6.6033,1.6072 -6.629,9.52344 -0.024,7.42525 15.0129,17.09146 17.1563,18.09375 1.7302,0.80909 3.5916,1.40876 5.4063,1.71875 l 1.4374,0.21875 c 1.9197,0.21194 3.72,0.15141 5.1563,-0.0937 3.1191,-0.5324 5.1116,-0.92861 7.0937,-1.3125 1.9821,-0.38387 2.4743,-1.03965 3.5626,-1.28125 1.1287,-0.25066 2.2702,0.11629 6.25,-0.875 3.9795,-0.99128 5.4294,-1.4193 6.125,-1.78125 0.7222,-0.37601 1.7617,-0.87058 2.375,-1.53125 1.9629,-0.012 3.7937,-0.29105 5.2187,-0.84375 2.9512,-1.14461 4.8732,-1.86942 6.6875,-2.75 1.4557,-0.70653 2.3191,-1.70203 2.5312,-2 0.2123,-0.29796 0.099,-0.72855 0.125,-0.75 0.043,-0.0352 0.3405,-0.094 0.5,-0.4375 0.859,-1.84708 2.3232,-5.62764 2.4376,-6.3125 0.1137,-0.68215 0.168,-1.35277 0.2187,-1.75 0.029,-0.22951 -0.1471,-0.8789 -0.125,-0.9375 0.031,-0.082 0.2883,-0.25057 0.3437,-0.5 0.2663,-1.19832 0.089,-2.20736 -0.125,-3.625 -0.2139,-1.41764 -0.9716,-4.61463 -1.625,-5.46875 -0.4194,-0.54857 -0.7993,-0.7925 -1.1562,-0.90625 -0.067,-0.0173 -0.1239,-0.0467 -0.1875,-0.0625 -0.021,-0.004 -0.042,0.003 -0.062,0 -0.3116,-0.0755 -0.6085,-0.15867 -1.1562,-0.21875 -0.9855,-0.10812 -2.4247,-0.2594 -3.9688,-0.25 -0.5147,0.003 -1.0371,0.0476 -1.5625,0.0937 -3.5589,0.31228 -9.0098,0.99108 -10.2187,1.625 -1.6331,-0.33402 -3.9482,-0.61223 -5.9376,-0.46875 -3.064,0.22097 -4.9677,0.34219 -6.9062,0.46875 -1.9384,0.12655 -1.6861,0.38864 -2.9062,0.46875 -1.3191,0.0866 -1.7869,-0.22325 -5.5626,0.0937 -3.5457,0.29772 -8.9806,0.99317 -10.2187,1.625 -1.6334,-0.33451 -3.9459,-0.61239 -5.9375,-0.46875 -3.0642,0.22098 -4.9678,0.37344 -6.9062,0.5 -0.6592,0.043 -1.0424,0.12393 -1.3438,0.1875 z"
- style="display:inline;opacity:1;fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- <g
- transform="matrix(0.9975712,-0.06965428,0.06965428,0.9975712,872.72062,140.02502)"
- id="g7935"
- style="display:inline;filter:url(#filter7610);enable-background:new"
- clip-path="url(#clipPath7616)">
- <path
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 229.94262,-409.12268 c -3.55781,0.05 -9.0242,0.36009 -10.30334,0.90414 -1.60609,-0.44747 -3.90316,-0.88131 -5.89995,-0.87674 -3.07199,0.007 -4.96469,0.009 -6.90727,0 -0.66047,-0.003 -1.04759,0.0672 -1.35267,0.10959 0,0 0,1.09593 0,1.09593 0.11972,-0.17947 0.39252,-0.69046 0.94975,-0.76715 0.74758,-0.10289 5.16928,-0.15123 7.31019,-0.1096 1.7746,0.0345 4.45523,0.27427 6.38921,0.95895 0.3214,0.11378 0.61925,0.27378 0.89219,0.41097 1.96342,0.98693 7.94336,4.30154 7.94336,4.30154 0,0 -6.63275,-3.94768 -7.48287,-4.43853 -0.20331,-0.11739 -0.57464,-0.25769 -1.03609,-0.41098 1.22063,-0.44779 5.07597,-0.61971 7.82823,-0.71235 3.0245,-0.10182 3.34776,-0.0896 5.41069,0.19179 2.12931,0.29043 3.33851,0.60276 3.33851,0.60276 -1e-5,0 -0.0784,-0.64118 1.03609,-0.79455 0.74757,-0.10289 5.16929,-0.15123 7.31019,-0.1096 2.0695,0.0403 5.36605,0.40716 7.2814,1.36992 1.00332,0.50433 3.03564,1.56863 4.79535,2.53571 l 0.0956,-0.0194 c 0,0 -3.58034,-2.16242 -4.43047,-2.65327 -0.20331,-0.11739 -0.57463,-0.25769 -1.03609,-0.41098 1.22062,-0.44779 5.04719,-0.61971 7.79945,-0.71235 3.0245,-0.10182 3.34775,-0.0896 5.41069,0.19179 1.95316,0.2664 3.01292,0.53006 3.19461,0.57536 0,0 -0.0271,-0.31146 -0.0271,-0.31146 -0.40903,-0.13645 -0.71424,-0.23335 -1.40038,-0.35748 -1.30081,-0.23533 -3.39912,-0.60156 -5.50857,-0.56398 -3.57195,0.0636 -9.05328,0.35596 -10.30334,0.90414 -1.60583,-0.44695 -3.87662,-0.8813 -5.87117,-0.87674 -3.07199,0.007 -4.99348,0.009 -6.93605,0 -1.94256,-0.009 -1.71268,0.27907 -2.93558,0.27398 -1.32191,-0.005 -1.76612,-0.35463 -5.55459,-0.30138 0,0 0,0 0,0"
- id="path7937"
- sodipodi:nodetypes="ccssscsssscscsscsssccscssccsscssscc"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cssccsscc"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 206.1989,-407.47878 c 1.92021,0.81706 4.57715,2.19283 6.15897,3.39739 1.58184,1.20456 2.90757,1.77368 5.55459,3.91795 0.88557,0.71738 1.74865,1.34985 2.59193,1.92174 l 0.54057,-0.19011 c -0.71323,-0.48339 -1.46776,-1.02031 -2.26909,-1.62203 -2.82223,-2.11921 -3.62655,-2.80973 -6.01507,-4.27414 -2.38854,-1.4644 -4.09948,-2.36576 -6.5619,-3.1508 0,0 0,0 0,0"
- id="path7939"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="csccscc"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 237.79963,-407.47878 c 1.92021,0.81706 4.60594,2.19283 6.18775,3.39739 0.81307,0.61916 1.55849,1.07042 2.45046,1.65401 l 0.649,-0.11666 c -0.79831,-0.57637 -1.57177,-1.09435 -2.69653,-1.78394 -2.38854,-1.4644 -4.12826,-2.36576 -6.59068,-3.1508 0,0 0,0 0,0"
- id="path7941"
- inkscape:connector-curvature="0" />
- </g>
- <g
- id="g7943"
- clip-path="url(#clipPath7606)">
- <path
- sodipodi:nodetypes="czzzzzzzzzzzzzz"
- id="path7945"
- d="m 1056.25,-278.80481 c 4.1446,-1.47877 10,3.125 10,3.125 0.899,0.28092 2.7251,-0.89447 2.6243,-1.68614 0,0 -1.5503,-1.86062 -0.3743,-2.93886 1.176,-1.07824 5.296,1.50738 7.5,1.625 2.204,0.11762 5.5621,-0.22941 7,-0.75 1.4379,-0.52059 1.1129,-1.42459 2.625,-1.75 1.5121,-0.32541 5.1189,1.03754 7.0605,1.16883 1.9416,0.13129 4.6481,0.33427 5.8145,-0.16883 1.1664,-0.5031 0.1782,-1.15921 1.875,-1.875 1.6968,-0.71579 7.7602,-0.95662 9.625,-0.125 1.8648,0.83162 1.8099,0.5192 2.625,3 0.8151,2.4808 7.4398,5.16285 -1.125,13.375 -8.5648,8.21215 -59.3779,13.78594 -65.625,2.75 -6.2471,-11.03594 6.2304,-14.27123 10.375,-15.75 z"
- style="display:inline;opacity:0.75;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7578);enable-background:new"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="czzzzzzzzzzzzzz"
- id="path7947"
- d="m 1058.5,-275.42981 c 4.1446,-1.47877 10,3.125 10,3.125 0.899,0.28092 2.7251,-0.89447 2.6243,-1.68614 0,0 -1.5503,-1.86062 -0.3743,-2.93886 1.176,-1.07824 5.296,1.50738 7.5,1.625 2.204,0.11762 5.5621,-0.22941 7,-0.75 1.4379,-0.52059 1.1129,-1.42459 2.625,-1.75 1.5121,-0.32541 5.1189,1.03754 7.0605,1.16883 1.9416,0.13129 4.6481,0.33427 5.8145,-0.16883 1.1664,-0.5031 0.1782,-1.15921 1.875,-1.875 1.6968,-0.71579 7.7602,-0.95662 9.625,-0.125 1.8648,0.83162 1.8099,0.5192 2.625,3 0.8151,2.4808 7.4398,5.16285 -1.125,13.375 -8.5648,8.21215 -59.3779,13.78594 -65.625,2.75 -6.2471,-11.03594 6.2304,-14.27123 10.375,-15.75 z"
- style="display:inline;opacity:0.75;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7594);enable-background:new"
- inkscape:connector-curvature="0" />
- </g>
- </g>
- <path
- sodipodi:nodetypes="cscccccccccccc"
- id="path7949"
- d="m 628.24553,347.99185 c -3.80443,-25.26423 -16.80972,-50.63802 -17.1568,-75.52523 -0.18626,-13.35552 3.27285,-26.57091 13.75553,-39.55405 36.34702,-65.29583 116.94091,-84.69468 185.93466,-91.46542 86.92239,-11.0168 184.91267,17.94007 233.37138,95.40128 54.124,75.7333 56.6747,172.53912 80.612,259.52795 29.4378,127.1276 54.7791,256.21414 60.3922,386.85035 -3.0634,78.18185 -8.4263,165.18417 -60.5032,228.13417 -48.0265,50.3574 -122.7864,50.053 -187.06985,59.0023 -90.55539,4.655 -184.35153,-16.1458 -261.7839,-64.1982 -64.77564,-37.94 -95.73019,-113.47867 -97.2794,-186.01962 -8.38917,-79.87516 26.39152,-153.80851 51.6204,-227.15961 7.47061,-82.76107 9.41286,-166.24775 9.65334,-249.38484 -0.83682,-32.19544 -7.08953,-63.81733 -11.54636,-95.60908 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#101414;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- transform="translate(276,136)"
- clip-path="url(#clipPath8616)"
- sodipodi:nodetypes="ccccczzzcc"
- id="path7951"
- d="m 311.83409,415.43155 9.8995,121.62237 -60.10408,136.47161 15.55635,174.65537 c 15.61326,61.8792 32.18545,98.66905 74.37615,117.05383 4.31911,-36.23998 -38.61152,-142.95988 -39.24264,-189.11984 -0.63145,-46.18445 10.83034,-108.60786 30.67767,-158.29647 20.04835,-50.19188 36.89674,-44.84642 42.12489,-92.59293 5.22815,-47.74651 -17.4264,-149.39192 -17.4264,-149.39192 l -55.86144,39.59798 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8940);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="czcc"
- id="path7953"
- d="m 1010.0312,655.49186 c 0,0 16.7552,37.01806 28.7015,53.95395 11.9462,16.93589 52.7271,56.04605 52.7271,56.04605 l 52.5972,-127.58975"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient8970);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- transform="translate(276,136)"
- clip-path="url(#clipPath8209)"
- sodipodi:nodetypes="cccc"
- id="path7955"
- d="m 730.31998,536.56864 c 0,8.48528 42.54774,58.46803 42.54774,58.46803 l 12.60659,-28.76954 -55.15433,-29.69849 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.07999998;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8822);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <g
- clip-path="url(#clipPath3998)"
- id="g7957"
- style="display:inline;opacity:1;enable-background:new"
- transform="translate(450.03125,73.843964)">
- <g
- id="g7959"
- style="filter:url(#filter3677)"
- transform="translate(-174.03125,62.156036)">
- <g
- style="filter:url(#filter3785)"
- id="g7961">
- <path
- style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 425.88244,476.99186 c 10.80543,-1.47866 24.74401,3.35451 44.64286,3.21428 19.89885,-0.14023 57.45322,-16.91122 82.14285,-17.14286 24.68963,-0.23164 62.7517,12.28406 79.28572,15 16.53402,2.71594 22.84832,-0.15852 27.49999,7.85715 4.65167,8.01567 1.92671,10.74724 -10.35714,20.71429 -12.28385,9.96705 -40.78968,12.63632 -66.07143,12.85714 -25.28234,0.22082 -70.38129,7.07852 -95.35714,3.92856 -24.97585,-3.14996 -56.93756,-7.82267 -68.92857,-17.85714 -11.99101,-10.03447 -19.85084,-16.73182 -17.5,-23.92857 2.35084,-7.19675 13.83743,-3.16419 24.64286,-4.64285 z"
- id="path7963"
- sodipodi:nodetypes="czzzzzzzzzz"
- inkscape:connector-curvature="0" />
- <rect
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="rect7965"
- width="381.83765"
- height="181.01935"
- x="343.6539"
- y="412.60312" />
- </g>
- <g
- style="filter:url(#filter3785)"
- id="g7967">
- <path
- transform="translate(174.03125,-62.156036)"
- style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 687.14286,452.36218 c -10.46169,9.71443 -86.9796,19.00514 -100.71429,29.28572 -13.73469,10.28058 -14.75252,12.88826 -12.14286,20 2.60966,7.11174 6.54527,9.40572 25.71429,8.57142 19.16902,-0.8343 98.57143,-27.62172 98.57143,-21.42857 l -11.42857,-36.42857 z"
- id="path7969"
- sodipodi:nodetypes="czzzcc"
- inkscape:connector-curvature="0" />
- <rect
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="rect7971"
- width="207.8894"
- height="162.63455"
- x="702.86414"
- y="344.82138" />
- </g>
- </g>
- <g
- id="g7973"
- style="display:inline;opacity:0.18000004;enable-background:new"
- transform="translate(-174.03125,62.156036)">
- <g
- style="filter:url(#filter3785)"
- id="g7975">
- <path
- style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 425.88244,476.99186 c 10.80543,-1.47866 24.74401,3.35451 44.64286,3.21428 19.89885,-0.14023 57.45322,-16.91122 82.14285,-17.14286 24.68963,-0.23164 62.7517,12.28406 79.28572,15 16.53402,2.71594 22.84832,-0.15852 27.49999,7.85715 4.65167,8.01567 1.92671,10.74724 -10.35714,20.71429 -12.28385,9.96705 -40.78968,12.63632 -66.07143,12.85714 -25.28234,0.22082 -70.38129,7.07852 -95.35714,3.92856 -24.97585,-3.14996 -56.93756,-7.82267 -68.92857,-17.85714 -11.99101,-10.03447 -19.85084,-16.73182 -17.5,-23.92857 2.35084,-7.19675 13.83743,-3.16419 24.64286,-4.64285 z"
- id="path7977"
- sodipodi:nodetypes="czzzzzzzzzz"
- inkscape:connector-curvature="0" />
- <rect
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="rect7979"
- width="381.83765"
- height="181.01935"
- x="343.6539"
- y="412.60312" />
- </g>
- <g
- style="filter:url(#filter3785)"
- id="g7981">
- <path
- transform="translate(174.03125,-62.156036)"
- style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 687.14286,452.36218 c -10.46169,9.71443 -86.9796,19.00514 -100.71429,29.28572 -13.73469,10.28058 -14.75252,12.88826 -12.14286,20 2.60966,7.11174 6.54527,9.40572 25.71429,8.57142 19.16902,-0.8343 98.57143,-27.62172 98.57143,-21.42857 l -11.42857,-36.42857 z"
- id="path7983"
- sodipodi:nodetypes="czzzcc"
- inkscape:connector-curvature="0" />
- <rect
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="rect7985"
- width="207.8894"
- height="162.63455"
- x="702.86414"
- y="344.82138" />
- </g>
- </g>
- </g>
- <path
- transform="translate(276,136)"
- sodipodi:nodetypes="cccccscc"
- clip-path="url(#clipPath8604)"
- id="path7987"
- d="M 582.65599,-7.4183011 695.79307,78.848726 804.68752,337.64981 842.87128,545.5392 963.07944,637.46308 c 0,0 -12.72793,-287.08535 -19.799,-313.95541 C 936.20938,296.63761 793.37381,-69.643698 793.37381,-69.643698 L 582.65599,-7.4183011 Z"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.75;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8802);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="czzzzzzc"
- id="path7989"
- d="m 964.13839,239.599 c 0,0 8.67732,10.89662 24.10715,11.96428 15.42986,1.06766 49.72166,-39.95267 70.17856,-52.14285 20.4793,-12.20353 47.0464,-26.60225 63.9286,-20.35714 16.8821,6.2451 22.1578,26.43609 27.8571,48.03571 5.6994,21.59961 6.7186,61.81389 -2.6785,92.85715 -9.3972,31.04325 -50.5033,73.10375 -65.3572,103.39285 -14.8539,30.2891 -11.6071,39.82143 -11.6071,39.82143"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient8958);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="czzzzc"
- id="path7991"
- d="m 1124.4955,207.63471 c -15.8928,-0.89286 -49.7188,12.10583 -66.0714,24.28572 -16.4386,12.2439 -29.2209,24.1144 -29.2857,52.14285 -0.065,28.20604 13.1191,39.07641 29.1071,46.96429 15.988,7.88789 33.6862,7.11928 51.9643,-11.78571 18.2782,-18.905 14.2857,-111.60715 14.2857,-111.60715 z"
- style="display:inline;opacity:1;fill:url(#radialGradient3315);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- <ellipse
- clip-path="url(#clipPath4100)"
- transform="matrix(0.9434749,-0.1239943,0.1440089,1.0957669,451.94827,134.5988)"
- id="path7993"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.75;fill:url(#radialGradient3543);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter4120);enable-background:accumulate"
- cx="385"
- cy="237.00504"
- rx="86.428574"
- ry="73.928574" />
- <path
- mask="url(#mask3684)"
- sodipodi:nodetypes="csczzc"
- id="path7995"
- d="m 527.60588,407.44884 c 0,0 -122.04144,38.40348 -187.51434,9.63181 -65.47289,-28.77166 -74.37725,-124.71847 -74.37725,-124.71847 0,0 73.38158,-80.50393 129.92078,-83.61476 55.82705,-3.07164 90.57386,20.14332 114.87001,65.85171 24.352,45.81348 17.1008,132.84971 17.1008,132.84971 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient3915);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- transform="translate(450.03125,73.843964)"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="czcc"
- id="path7997"
- d="m 772.17411,393.349 c 0,0 36.21754,-27.38247 51.60714,-35.89286 15.17734,-8.39301 25.71428,-11.60714 35.89285,-11.60714 l -15.53571,66.96428"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient3959);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <circle
- transform="translate(449.49554,74.915393)"
- id="path7999"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient3933);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- cx="409.28571"
- cy="306.64789"
- r="36.25" />
- <path
- transform="translate(276,136)"
- clip-path="url(#clipPath8616)"
- sodipodi:nodetypes="cccccccccc"
- id="path8001"
- d="m 311.83409,415.43155 9.8995,121.62237 -60.10408,136.47161 15.55635,174.65537 c 15.61326,61.8792 32.18545,98.66905 74.37615,117.05383 4.31911,-36.23998 8.68161,-72.36764 -31.24264,-223.11984 l 17.67767,-69.29647 72.12489,-138.59293 -42.4264,-158.39192 -55.86144,39.59798 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8806);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="czzcc"
- id="path8003"
- d="m 635.21025,581.13004 c -14.14214,12.72792 39.23347,34.58015 76.36753,24.04163 37.13406,-10.53852 104.64487,-35.56437 103.23759,-79.19596 -1.40728,-43.63158 -76.36753,-128.69343 -76.36753,-128.69343 L 635.21025,581.13004 Z"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8826);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <circle
- transform="translate(449.67411,74.915393)"
- id="path8005"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient3991);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- cx="410"
- cy="306.64789"
- r="23.214285" />
- <circle
- transform="translate(451.99554,73.486821)"
- id="path8007"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter3981);enable-background:accumulate"
- cx="414.28571"
- cy="303.07648"
- r="7.5" />
- <path
- sodipodi:nodetypes="czzzczc"
- id="path8009"
- d="m 789.31696,478.349 c 0,0 7.02281,19.56859 -1.07143,35 -8.09424,15.43141 -42.32317,38.98822 -67.49999,50 -25.30972,11.06991 -85.473,32.96393 -101.78572,41.96428 -16.46148,9.08243 -18.21428,12.67857 -18.21428,12.67857 0,0 -7.14693,-19.06441 28.74999,-51.7857 36.17211,-32.97214 142.02712,-48.0495 159.82143,-87.85715 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient4112);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <g
- transform="translate(780.74553,74.55825)"
- id="g8011"
- style="display:inline;opacity:1;enable-background:new">
- <path
- style="display:inline;opacity:1;fill:url(#radialGradient3585);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 179.64286,267.36218 c -22.41044,39.70292 -60.6161,115.78029 -69.28571,149.64286 -8.64721,33.7751 -8.77199,66.41654 -0.35715,86.42858 8.3602,19.88213 26.16398,35.6328 40.71428,41.42856 -0.59638,-14.37587 14.37295,-43.28583 72.85715,-72.5 58.62627,-29.28514 78.38163,-27.13086 103.57142,-47.14286 25.63006,-20.36176 8.20587,-79.64664 3.21429,-93.92857 -4.99158,-14.28193 -1.23663,-3.37974 -1.94602,-5.09301 -10.68928,-25.81592 -34.21432,-54.4303 -64.48255,-64.54984 -30.26823,-10.11954 -65.01776,-4.84837 -84.28571,5.71428 z"
- id="path8013"
- sodipodi:nodetypes="czzczzzszc"
- clip-path="url(#clipPath3999)"
- transform="translate(-329.81481,0)"
- inkscape:connector-curvature="0" />
- <ellipse
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient4060);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="path8015"
- transform="matrix(0.8823874,0.4705236,-0.4705236,0.8823874,-166.62245,2.387362)"
- cx="183.57143"
- cy="338.07648"
- rx="64.715881"
- ry="134.00607" />
- <ellipse
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient4062);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="path8017"
- transform="matrix(0.8823874,0.4705236,-0.4705236,0.8823874,-162.19388,-18.755495)"
- cx="183.57143"
- cy="338.07648"
- rx="64.715881"
- ry="134.00607" />
- <path
- style="display:inline;opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3587);stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4079);enable-background:new"
- d="m 179.64286,267.36218 c -22.41044,39.70292 -60.6161,115.78029 -69.28571,149.64286 -8.64721,33.7751 -8.77199,66.41654 -0.35715,86.42858 8.3602,19.88213 26.16398,35.6328 40.71428,41.42856 -0.59638,-14.37587 14.37295,-43.28583 72.85715,-72.5 58.62627,-29.28514 78.38163,-27.13086 103.57142,-47.14286 25.63006,-20.36176 8.20587,-79.64664 3.21429,-93.92857 -4.99158,-14.28193 -1.23663,-3.37974 -1.94602,-5.09301 -10.68928,-25.81592 -34.21432,-54.4303 -64.48255,-64.54984 -30.26823,-10.11954 -65.01776,-4.84837 -84.28571,5.71428 z"
- id="path8019"
- sodipodi:nodetypes="czzczzzszc"
- clip-path="url(#clipPath3999)"
- transform="translate(-329.81481,3e-7)"
- inkscape:connector-curvature="0" />
- </g>
- <circle
- transform="translate(452.55663,72.581273)"
- id="path8021"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- cx="310.71429"
- cy="398.07648"
- r="19.704132" />
- <circle
- transform="translate(450.55663,72.581273)"
- id="path8023"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient4056);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4082);stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter4083);enable-background:accumulate"
- cx="310.71429"
- cy="398.07648"
- r="19.704132" />
- <circle
- transform="translate(450.55663,72.581273)"
- id="path8025"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient4119);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- cx="310.71429"
- cy="398.07648"
- r="19.704132" />
- <ellipse
- inkscape:transform-center-y="-3.6935079"
- inkscape:transform-center-x="-47.231976"
- transform="matrix(0.9969564,-0.07796167,0.07796167,0.9969564,436.61877,125.29509)"
- id="path8027"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient4868);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter4002);enable-background:accumulate"
- cx="429.56738"
- cy="377.42877"
- rx="72.079735"
- ry="44.547726" />
- <ellipse
- inkscape:transform-center-y="-13.056625"
- inkscape:transform-center-x="-20.955902"
- transform="matrix(1.4357951,-0.06999104,0.06999104,1.4357951,235.18065,-63.86546)"
- id="path8029"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient4876);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter4010);enable-background:accumulate"
- cx="437.6991"
- cy="391.21735"
- rx="36.611931"
- ry="22.627417" />
- <g
- style="display:inline;opacity:1;filter:url(#filter4053);enable-background:new"
- id="g8031"
- transform="translate(450.03125,73.843964)">
- <circle
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4484);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="path8033"
- cx="413.66071"
- cy="401.82648"
- r="3.2142856" />
- <circle
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4486);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="path8035"
- transform="translate(13.125009,8.1249913)"
- cx="413.66071"
- cy="401.82648"
- r="3.2142856" />
- <circle
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4488);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="path8037"
- transform="translate(32.946437,7.4999913)"
- cx="413.66071"
- cy="401.82648"
- r="3.2142856" />
- <circle
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4490);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="path8039"
- transform="translate(24.910723,-10.267866)"
- cx="413.66071"
- cy="401.82648"
- r="3.2142856" />
- <circle
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4492);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="path8041"
- transform="translate(47.589294,-0.6250087)"
- cx="413.66071"
- cy="401.82648"
- r="3.2142856" />
- </g>
- <path
- sodipodi:nodetypes="ccccccccc"
- id="path8043"
- d="m 896.20301,482.92837 c 0.98509,4.35008 4.53707,6.17948 7.38673,7.89182 4.46068,2.51292 6.52016,1.52211 9.15451,-0.75761 1.60195,-1.92117 10.68311,-4.69865 15.59423,-7.07107 4.32961,-1.45891 8.9033,-5.35873 13.38452,-8.33376 3.39514,-1.62724 5.34664,0.35464 7.82868,1.01015 2.94412,0.71661 4.41117,2.17175 6.06092,3.53554 2.39616,1.17519 -0.9279,3.14313 3.283,4.29314 1.19091,0.21794 2.41695,0.57645 3.28299,-0.50507"
- style="display:inline;opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cccccccccccc"
- id="path8045"
- d="m 910.85021,475.35223 c 2.31494,-0.032 3.17778,0.64253 5.49271,-0.82075 3.45564,-3.08113 5.40254,-3.14477 7.95495,-4.41942 3.02657,-1.31523 6.5357,8.15169 10.10153,9.84899 2.39509,-0.82142 1.28914,1.79379 1.45209,2.65165 0.0571,2.64684 2.80694,3.67806 4.35628,5.42957 3.31604,2.25549 7.37523,6.29546 11.11168,5.3033 6.44525,-2.93107 10.27922,-1.28146 16.28871,-7.38674 0.70405,-1.18134 -0.58425,-6.8946 3.09359,-7.19734 2.52399,0.25338 4.16667,0.0502 6.06092,0.56822 5.441,2.11719 7.73778,6.45 14.71034,7.95495 6.1829,0.96639 7.61264,3.79426 13.88959,5.05076"
- style="display:inline;opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccccccccccccc"
- id="path8047"
- d="m 876.98133,483.52197 c 2.39858,-0.7938 6.10613,4.1921 8.17313,7.04568 0.59281,2.67952 1.15377,5.48645 0.75761,12.12183 0.78513,2.41754 2.68049,3.03095 4.79823,3.283 3.11745,-0.53678 5.87669,-1.3243 7.3236,-3.03046 1.8716,-1.94167 5.31253,2.39394 8.08122,4.04061 3.61009,1.91209 7.77378,1.97886 11.8693,2.27284 1.70358,-0.23064 2.3704,4.51515 3.28299,8.08123 0.38414,4.37806 -0.88544,6.89569 -1.76776,9.84898 -0.2943,2.49655 2.9885,3.52974 6.31345,4.54569 3.18244,0.74124 6.54424,1.66184 9.09137,1.76777 5.14186,0.87491 8.08874,2.69052 12.12183,4.04061 2.23914,0.81655 3.26019,2.24216 4.54569,3.53553"
- style="display:inline;opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- <path
- transform="translate(276,136)"
- clip-path="url(#clipPath8514)"
- id="path8049"
- d="m 332,187.69519 c 0,0 57.5,-25.5 57.5,-28 0,-2.5 5.5,-52 5.5,-52 0,0 91,-48.500001 91.5,-50.500001 0.5,-2 86,-62.0000004 86,-62.0000004 L 386.5,17.195189 311,123.19519 l 21,64.5 z"
- style="display:inline;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter8814);enable-background:new"
- inkscape:connector-curvature="0" />
- <path
- id="path8051"
- d="m 1697.2846,722.5514 c 0,0 -115.9655,73.5391 -123.0365,77.78174 -7.0711,4.24264 -230.5169,137.17872 -230.5169,137.17872 l 4.2427,39.59798 216.3747,-100.40917 117.3797,-101.82337 15.5563,-52.3259 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- transform="translate(276,136)"
- sodipodi:nodetypes="cccccscccc"
- clip-path="url(#clipPath8610)"
- id="path8053"
- d="m 528.91587,556.85291 c -5.65685,-1.41421 -181.01933,74.95332 -181.01933,74.95332 l -33.94113,181.01934 51.09546,193.94823 257.2031,67.6813 c 0,0 206.47518,152.735 212.13203,148.4924 5.65686,-4.2426 168.2914,-193.7473 168.2914,-193.7473 L 842.87128,845.35248 796.20224,667.16157 528.91587,556.85291 Z"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8810);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="czzzzzzczczczczzzc"
- id="path8055"
- d="m 1097.6433,613.88997 c 0,0 22.6195,-6.50681 35.7427,-5.87273 13.1233,0.63409 30.6416,1.93862 43.7089,12.18619 13.0673,10.24756 25.0677,27.14007 34.1124,58.36965 9.0446,31.22958 1.6983,99.25201 -6.1761,143.34735 -7.8743,44.09534 -28.2651,106.11298 -45,140 -16.7348,33.88702 -49.7977,77.49517 -60.5694,89.87617 -11.3642,13.062 -56.2059,36.4262 -79.4306,42.2667 5.3034,-10.6066 48.8998,-50.5889 35,-60.7143 -14.0189,-10.2123 -45.76,45.9824 -84.2931,29.0332 21.38231,-13.1321 41.7794,-51.1861 34.0406,-66.59448 -7.84024,-15.61039 -30.70492,48.75758 -93.53553,37.01288 30.05204,-27.5267 55.40706,-70.90401 41.2627,-82.9797 -14.41516,-12.30687 -60.46175,54.2932 -60.46175,54.2932 0,0 -2.8219,-41.70123 13.7732,-68.60737 16.63935,-26.97787 79.65297,-81.61527 99.55308,-111.70342 19.9002,-30.08814 33.6126,-66.00902 42.1355,-92.51794 8.5228,-26.50892 15.8009,-77.09954 15.8009,-77.09954"
- style="display:inline;opacity:1;fill:#0c0c0c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- <path
- transform="translate(276,136)"
- sodipodi:nodetypes="cccccccccc"
- clip-path="url(#clipPath8622)"
- id="path8057"
- d="m 770.74639,609.17881 -50.91169,97.58074 -79.90307,111.01576 34.64824,71.41778 42.42641,79.19597 72.12489,-45.25484 14.14214,-192.33305 21.2132,-138.59292 -14.14214,-90.15612 -39.59798,107.12668 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8818);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- transform="translate(276,136)"
- sodipodi:nodetypes="cczcccccc"
- clip-path="url(#clipPath8906)"
- id="path8059"
- d="m 295,846.19519 6.64488,-68.92285 c 0,0 90.31951,89.00457 162.35512,122.92285 72.03561,33.91828 308,62 308,62 l 154,-26 -36,162.00001 -286,26 -298,-89 -11,-189.00001 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8810);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- clip-path="url(#clipPath3602)"
- sodipodi:nodetypes="cccccccccccc"
- id="path8061"
- d="m 405.79629,845.99023 74.95332,65.05383 2.49963,16.8804 19.40336,10.15891 6.49204,23.05109 31.70905,-8.3711 14.84924,48.08324 c 12.25652,12.7279 89.79344,-113.1097 55.86143,38.1838 l -60.81118,16.2635 -89.20292,-94.69286 -62.82503,-53.79963 7.07106,-60.81118 z"
- style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3587);enable-background:new"
- transform="translate(450.03125,73.843964)"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="czzzzzzzzcc"
- id="path8063"
- d="m 1159.317,918.349 c 54.2857,-1.42857 126.035,-15.05199 170,-26.78572 44.0527,-11.75714 125.8863,-36.34724 175.357,-57.85714 49.3393,-21.45272 113.6038,-59.2816 154.2859,-92.14285 40.5081,-32.72069 52.3899,-55.81981 60.7142,-33.57143 8.3691,22.36779 -16.4069,56.32562 -37.8571,81.07143 -21.6042,24.9234 -52.7314,52.70533 -98.9287,89.28571 -46.1973,36.58038 -156.0825,101.58463 -212.8571,128.5714 -57.066,27.1254 -128.2033,58.2385 -172.1428,72.5001 -43.9395,14.2616 -131.4286,31.0714 -131.4286,31.0714 L 1159.317,918.349 Z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#121212;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- clip-path="url(#clipPath3992)"
- sodipodi:nodetypes="czczzcc"
- id="path8065"
- d="m 1241.5965,652.95007 c 0,0 -64.7215,54.33706 -145.6639,98.99494 -82.0244,45.25484 -284.25704,93.3381 -284.25704,93.3381 0,0 -15.10137,21.05196 45.25489,28.28428 60.35626,7.23232 224.08195,-53.30069 278.60015,-96.16654 54.5182,-42.86585 120.2081,-111.72286 120.2081,-111.72286 l -14.1422,-12.72792 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.5;fill:url(#linearGradient3666);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter3779);enable-background:accumulate"
- transform="translate(450.03125,73.843964)"
- inkscape:connector-curvature="0" />
- <g
- clip-path="url(#clipPath3986)"
- id="g8067"
- style="display:inline;opacity:1;enable-background:new"
- transform="translate(450.03125,73.843964)">
- <g
- id="g8069"
- style="filter:url(#filter3677)"
- transform="translate(-174.03125,62.156036)">
- <g
- id="g8071"
- style="filter:url(#filter3785)">
- <path
- transform="translate(174.03125,-62.156036)"
- style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 1094.2857,725.93361 c 0,0 -0.2961,26.16091 4.6428,37.85715 4.9389,11.69624 20.0381,26.48665 28.5715,31.42857 8.5334,4.94192 18.9286,8.57142 18.9286,8.57142 l 117.8571,-115 17.8572,-75.71428 -96.4286,38.57143 -91.4286,74.28571 z"
- id="path8073"
- sodipodi:nodetypes="czzccccc"
- inkscape:connector-curvature="0" />
- <rect
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="rect8075"
- width="333.75412"
- height="309.71277"
- x="1197.8389"
- y="486.14224" />
- </g>
- </g>
- <g
- id="g8077"
- style="display:inline;opacity:0.18000004;enable-background:new"
- transform="translate(-174.03125,62.156036)">
- <g
- id="g8079"
- style="filter:url(#filter3785)">
- <path
- transform="translate(174.03125,-62.156036)"
- style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 1094.2857,725.93361 c 0,0 -0.2961,26.16091 4.6428,37.85715 4.9389,11.69624 20.0381,26.48665 28.5715,31.42857 8.5334,4.94192 18.9286,8.57142 18.9286,8.57142 l 117.8571,-115 17.8572,-75.71428 -96.4286,38.57143 -91.4286,74.28571 z"
- id="path8081"
- sodipodi:nodetypes="czzccccc"
- inkscape:connector-curvature="0" />
- <rect
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="rect8083"
- width="333.75412"
- height="309.71277"
- x="1197.8389"
- y="486.14224" />
- </g>
- </g>
- </g>
- <path
- sodipodi:nodetypes="cssssccccccssssssssccssssssccssssc"
- clip-path="url(#clipPath3722)"
- id="path8085"
- d="m 1264.1875,605 c -4.4911,0.73268 -8.157,3.45509 -11.9375,6.40625 -10.0813,7.86976 -28.1695,34.42524 -48.0312,50.46875 -39.8674,32.20316 -103.996,69.97701 -152.5626,91.09375 -48.614,21.13738 -130.54122,45.81801 -174.31245,57.5 -43.39821,11.58246 -115.04403,25.13107 -168.25,26.53125 l -4.5625,0.125 -2,4.125 -92.84375,192.125 -6.5,13.4688 14.65625,-2.8438 c 0,0 87.26968,-16.6514 132.34375,-31.2812 44.7252,-14.51667 115.79086,-45.66683 173.03125,-72.87505 C 980.82199,912.46306 1090.1551,847.86412 1137.5,810.375 c 46.3608,-36.70982 77.8049,-64.71682 99.9375,-90.25 10.9011,-12.576 22.7448,-27.53144 31.0313,-42.75 8.2864,-15.21856 19.1597,-44.21808 13.6874,-58.84375 -1.2177,-3.25474 -2.5514,-6.0613 -4.5937,-8.5 -2.0423,-2.4387 -8.4747,-1.57199 -8.5625,-5.03125 -0.2098,-8.26482 -3.3155,-0.24423 -4.8125,0 z m 2.1563,15.21875 c 0.4148,0.58574 1.0311,1.55766 1.7812,3.5625 2.8968,7.74213 -1.4407,31.89875 -8.8125,45.4375 -7.3718,13.53875 -22.6384,28.92394 -33.1875,41.09375 -21.0754,24.31356 -51.9037,51.86156 -97.9375,88.3125 -45.0496,35.67159 -155.46033,101.09459 -211.40625,127.6875 -56.89173,27.04249 -128.09616,58.1184 -171.25,72.125 -36.36491,11.8031 -95.84471,23.8338 -115.71875,27.7813 L 714.09375,851.75 c 54.70691,-2.0493 123.79259,-15.21635 167.125,-26.78125 44.33422,-11.83225 126.07865,-36.33633 176.40625,-58.21875 50.112,-21.78871 112.5344,-61.16816 154.0312,-94.6875 20.6464,-16.67721 41.7449,-42.54588 49.8126,-48.84375 2.437,-1.90242 4.0806,-2.6358 4.875,-3 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.83300003;fill:#050505;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:15;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;filter:url(#filter8225);enable-background:accumulate"
- transform="translate(450.03125,73.843964)"
- inkscape:connector-curvature="0" />
- <g
- inkscape:transform-center-y="-12.859654"
- inkscape:transform-center-x="-185.09603"
- transform="matrix(0.9934486,0.1142802,-0.1142802,0.9934486,-9.24324,588.09054)"
- mask="url(#mask7704)"
- id="g8087"
- style="display:inline;opacity:1;enable-background:new">
- <path
- sodipodi:nodetypes="ccssscsssscssssscsssscssssscsssscssssscsssscssssscsssscssssscsssscssscccccssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsssssssssssc"
- id="path8089"
- d="m 1111.4062,-285.9375 -3.9374,1.875 c -0.041,0.0102 -0.1,0.0205 -0.125,0.0312 -0.4188,0.21285 -0.1647,0.10058 -0.6563,0.3125 -0.4861,0.20956 -1.7376,0.58419 -4.0937,1.46875 -3.3312,1.25058 -5.8043,2.14984 -7,3.0625 -1.5362,0.0213 -3.7205,0.23331 -5.6563,0.71875 -2.9815,0.74767 -4.8552,1.17401 -6.75,1.59375 -1.8948,0.41973 -1.6755,0.64219 -2.875,0.875 -1.2966,0.25167 -1.7214,-0.009 -5.4375,0.78125 -3.4899,0.74215 -8.8948,1.93107 -10.1562,2.6875 -1.584,-0.18078 -3.8675,-0.32178 -5.8438,-0.0312 -3.0404,0.44696 -4.9162,0.67276 -6.8438,0.90625 -0.6554,0.0794 -1.041,0.20078 -1.3437,0.28125 -0.4262,0.13166 -0.6858,0.26002 -1.375,0.34375 -1.3116,0.15937 -1.7622,-0.15683 -5.5313,0.28125 -3.5539,0.41309 -9.0054,1.27282 -10.25,1.9375 -1.599,-0.29729 -3.8577,-0.53419 -5.8437,-0.34375 -3.0588,0.29332 -4.972,0.48399 -6.9063,0.65625 -1.9342,0.17227 -1.6886,0.42237 -2.9062,0.53125 -1.3162,0.1177 -1.7598,-0.16363 -5.5312,0.25 -3.5421,0.38845 -9.0079,1.20927 -10.2813,1.875 -1.5989,-0.29469 -3.8872,-0.50701 -5.875,-0.3125 -3.05829,0.29925 -4.9412,0.48024 -6.875,0.65625 -0.65749,0.0598 -1.04005,0.17856 -1.34375,0.25 -0.4277,0.11896 -0.6835,0.21807 -1.375,0.28125 -1.316,0.12026 -1.75975,-0.19488 -5.53125,0.21875 -3.55619,0.39002 -9.0056,1.23916 -10.25,1.90625 -1.59869,-0.29418 -3.85985,-0.52372 -5.84375,-0.3125 -3.0557,0.32533 -4.97405,0.52624 -6.90625,0.71875 -1.93219,0.19251 -1.68975,0.44088 -2.90625,0.5625 -1.31488,0.13147 -1.76305,-0.16454 -5.53125,0.28125 -3.53889,0.41866 -8.9777,1.29217 -10.25,1.96875 -1.59759,-0.28104 -3.85995,-0.42043 -5.84375,-0.1875 -3.05198,0.35837 -4.945,0.56786 -6.875,0.78125 -0.65618,0.0726 -1.04065,0.17269 -1.34375,0.25 -0.42679,0.12723 -0.6849,0.2672 -1.375,0.34375 -1.31339,0.14569 -1.76735,-0.17402 -5.53125,0.3125 -3.54888,0.45876 -8.97865,1.41902 -10.21875,2.125 -1.59309,-0.24424 -3.8338,-0.38135 -5.8125,-0.125 -3.04759,0.39482 -4.9507,0.64845 -6.875,0.90625 -1.92429,0.25779 -1.7261,0.49353 -2.9375,0.65625 -1.30949,0.1759 -1.7472,-0.10438 -5.5,0.46875 -3.52429,0.53824 -8.9232,1.69917 -10.1875,2.4375 -1.58749,-0.20354 -3.8455,-0.25473 -5.8125,0.0937 -3.02619,0.53612 -4.8989,0.86169 -6.8125,1.1875 -0.65059,0.11077 -1.0137,0.27094 -1.3125,0.375 -0.42069,0.16488 -0.66345,0.3313 -1.34375,0.46875 -1.2947,0.26159 -1.7271,-0.006 -5.4375,0.8125 -3.49848,0.77195 -8.8459,2.38293 -10.0625,3.21875 -1.5629,-0.0774 -3.7575,0.0853 -5.6875,0.59375 -2.97238,0.78313 -4.8177,1.23209 -6.6875,1.75 -1.87,0.5179 -1.66665,0.76728 -2.84375,1.09375 -1.27249,0.3529 -1.69705,0.10709 -5.34375,1.1875 -3.42468,1.01463 -8.6494,2.93317 -9.875,3.84375 -1.53878,0.0127 -3.7198,0.27222 -5.625,0.875 -2.93098,0.92734 -4.75035,1.45842 -6.59375,2.0625 -0.62679,0.20538 -0.99165,0.39258 -1.28125,0.53125 -0.40758,0.21361 -0.6533,0.40875 -1.3125,0.625 -1.2545,0.41154 -1.68615,0.18904 -5.28125,1.4375 -3.38989,1.17717 -8.59495,3.2137 -9.78125,4.15625 -1.52388,0.0597 -3.65005,0.39487 -5.53125,1.0625 -2.89739,1.02829 -4.69905,1.67548 -6.53125,2.3125 -1.8322,0.63701 -1.62785,0.84854 -2.78125,1.25 -1.24679,0.43396 -1.66355,0.19972 -5.21875,1.5625 -3.3387,1.2798 -8.4871,3.48255 -9.6875,4.46875 -1.50718,0.10769 -3.6357,0.4988 -5.5,1.21875 -2.86818,1.1076 -4.6239,1.78156 -6.4375,2.46875 -0.6167,0.23363 -0.99645,0.44203 -1.28125,0.59375 10e-6,0 0,0.0295 0,0.0312 l -8,3.1875 -12.4759,3.49189 7.92966,19.27772 c -0.59163,1.97357 12.54624,-4.73836 12.54624,-4.73836 0.22641,-0.14468 0.44895,-0.27261 0.71875,-0.375 1.08052,-0.40998 2.1716,-0.21577 6,-1.6875 3.82852,-1.47174 5.22405,-2.00498 5.90625,-2.40625 0.67961,-0.39978 1.61175,-0.87937 2.21875,-1.53125 1.82692,-0.13775 3.5708,-0.49323 4.9375,-1 2.968,-1.10052 4.87535,-1.80619 6.78125,-2.46875 1.90581,-0.66254 2.35415,-1.41487 3.40625,-1.78125 1.09162,-0.38011 2.1951,-0.16538 6.0625,-1.53125 3.8674,-1.36586 5.28315,-1.82708 5.96875,-2.21875 0.70111,-0.40052 1.7008,-0.93298 2.3125,-1.59375 1.97081,-0.0547 3.81695,-0.38463 5.28125,-0.875 3.00152,-1.00508 4.92615,-1.62171 6.84375,-2.25 1.53861,-0.5041 2.17415,-1.04677 2.90625,-1.4375 0.23022,-0.13431 0.4759,-0.25373 0.75,-0.34375 1.09832,-0.36048 2.18145,-0.0814 6.09375,-1.3125 3.91231,-1.23113 5.366,-1.67295 6.0625,-2.03125 0.69391,-0.35697 1.6301,-0.79261 2.25,-1.40625 1.86521,-0.0227 3.63585,-0.26683 5.03125,-0.6875 3.0304,-0.91354 4.9924,-1.4301 6.9375,-1.96875 1.94512,-0.53864 2.4262,-1.26452 3.5,-1.5625 1.11402,-0.30915 2.22,0.007 6.1875,-1.03125 3.9675,-1.03863 5.4175,-1.43273 6.125,-1.75 0.7348,-0.32959 1.8139,-0.75372 2.4375,-1.375 1.99782,0.116 3.85745,-0.0201 5.34375,-0.375 3.07811,-0.735 5.0834,-1.10094 7.0625,-1.5 1.58791,-0.32018 2.2443,-0.79055 3,-1.09375 0.23751,-0.1068 0.4669,-0.19276 0.75,-0.25 1.13341,-0.22919 2.30465,0.20893 6.34375,-0.5 4.03942,-0.70893 5.50025,-0.92709 6.21875,-1.1875 0.71581,-0.25944 1.70435,-0.56724 2.34375,-1.09375 1.9242,0.23949 3.7479,0.22453 5.1875,0 3.12642,-0.48762 5.15455,-0.70067 7.15625,-0.96875 2.00171,-0.26807 2.48875,-0.94514 3.59375,-1.09375 1.14642,-0.15418 2.27585,0.30157 6.34375,-0.21875 4.06781,-0.52032 5.56025,-0.69573 6.28125,-0.9375 0.73712,-0.24714 1.7981,-0.58623 2.4375,-1.125 2.05,0.33553 3.9737,0.39796 5.5,0.21875 3.1422,-0.36896 5.18,-0.55936 7.1875,-0.78125 1.61082,-0.17802 2.26465,-0.6082 3.03125,-0.84375 0.24091,-0.0855 0.49405,-0.1556 0.78125,-0.1875 1.1497,-0.12772 2.3013,0.34665 6.375,-0.125 4.0737,-0.47165 5.55905,-0.6106 6.28125,-0.84375 0.71941,-0.23227 1.70025,-0.47346 2.34375,-0.96875 1.9363,0.33346 3.77005,0.40424 5.21875,0.25 3.14601,-0.33495 5.1775,-0.51859 7.1875,-0.71875 2.00991,-0.20014 2.48415,-0.82639 3.59375,-0.9375 1.1511,-0.11528 2.2965,0.36506 6.375,-0.0625 4.0785,-0.42756 5.5889,-0.56209 6.3125,-0.78125 0.73922,-0.22386 1.7956,-0.51325 2.4375,-1.03125 2.057,0.39867 4.00185,0.4934 5.53125,0.34375 3.14871,-0.3081 5.1758,-0.47325 7.1875,-0.65625 1.61401,-0.14682 2.26305,-0.56055 3.03125,-0.78125 0.2413,-0.0809 0.49355,-0.12991 0.78125,-0.15625 1.15211,-0.10545 2.2929,0.39275 6.375,0 4.08211,-0.39275 5.5889,-0.53084 6.3125,-0.75 0.7209,-0.21833 1.6996,-0.4477 2.3437,-0.9375 1.9381,0.34999 3.7689,0.45438 5.2188,0.3125 3.1487,-0.3081 5.1758,-0.47325 7.1875,-0.65625 2.0116,-0.18299 2.5142,-0.83802 3.625,-0.9375 1.1523,-0.10323 2.2922,0.38483 6.375,0 4.0829,-0.38482 5.5887,-0.501 6.3125,-0.71875 0.7393,-0.22243 1.7956,-0.51449 2.4375,-1.03125 2.0574,0.40177 4.0029,0.50333 5.5313,0.34375 3.1465,-0.32852 5.177,-0.5227 7.1874,-0.71875 1.613,-0.15729 2.2657,-0.63148 3.0313,-0.875 0.2407,-0.088 0.4632,-0.12137 0.75,-0.15625 1.1483,-0.1397 2.3167,0.33991 6.375,-0.25 4.0583,-0.58992 5.5618,-0.77714 6.2813,-1.03125 0.7166,-0.25316 1.6746,-0.55807 2.3124,-1.09375 1.9197,0.21194 3.72,0.15141 5.1563,-0.0937 3.1191,-0.5324 5.1116,-0.92861 7.0937,-1.3125 1.9821,-0.38387 2.4743,-1.03965 3.5626,-1.28125 1.1287,-0.25066 2.2702,0.11629 6.25,-0.875 3.9795,-0.99127 5.4295,-1.4193 6.125,-1.78125 0.7222,-0.376 1.7617,-0.87058 2.375,-1.53125 1.9629,-0.012 3.7937,-0.29105 5.2187,-0.84375 2.9512,-1.1446 4.8732,-1.86942 6.6875,-2.75 1.4557,-0.70652 2.3191,-1.70203 2.5312,-2 0.2123,-0.29795 0.099,-0.72855 0.125,-0.75 0.043,-0.0352 0.3404,-0.094 0.5,-0.4375 0.859,-1.84707 2.3232,-5.62764 2.4376,-6.3125 0.1137,-0.68214 0.168,-1.35277 0.2187,-1.75 0.029,-0.2295 -0.1471,-0.8789 -0.125,-0.9375 0.031,-0.082 0.2883,-0.25057 0.3437,-0.5 0.2663,-1.19831 0.089,-2.20736 -0.125,-3.625 -0.2139,-1.41763 -0.9716,-4.61463 -1.625,-5.46875 -0.6589,-0.86172 -1.2248,-1.01051 -1.75,-1 z"
- style="display:inline;fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- transform="translate(0.08004571,-0.03125)"
- inkscape:connector-curvature="0" />
- <g
- id="g8091"
- clip-path="url(#clipPath7421)">
- <path
- sodipodi:nodetypes="czscsssscssssscsssscssssscsssscssssscsssscssssscsssscssssscsssscssccsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscc"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7001);enable-background:new"
- d="m 1107.409,-284.04961 c -0.4187,0.21283 -0.1556,0.0939 -0.6472,0.30581 -0.4861,0.20954 -1.7234,0.57439 -4.0796,1.45895 -3.3311,1.25057 -5.8302,2.15344 -7.0259,3.0661 -1.5361,0.0213 -3.7205,0.23331 -5.6563,0.71875 -2.9815,0.74766 -4.8552,1.17401 -6.75,1.59375 -1.8948,0.41972 -1.6755,0.64219 -2.875,0.875 -1.2966,0.25166 -1.7214,-0.009 -5.4375,0.78125 -3.4899,0.74214 -8.8948,1.93107 -10.1562,2.6875 -1.5839,-0.18079 -3.8675,-0.32178 -5.8438,-0.0312 -3.0404,0.44695 -4.9162,0.67276 -6.8437,0.90625 -0.6554,0.0794 -1.0411,0.20078 -1.3438,0.28125 -0.4262,0.13165 -0.6858,0.26002 -1.375,0.34375 -1.3116,0.15936 -1.7622,-0.15683 -5.5312,0.28125 -3.5539,0.41308 -9.0054,1.27282 -10.25,1.9375 -1.599,-0.2973 -3.8578,-0.53419 -5.8438,-0.34375 -3.0588,0.29331 -4.972,0.48399 -6.9062,0.65625 -1.9343,0.17226 -1.6887,0.42237 -2.9063,0.53125 -1.3162,0.11769 -1.7598,-0.16363 -5.5312,0.25 -3.5419,0.38844 -9.0079,1.20927 -10.2813,1.875 -1.5989,-0.2947 -3.88717,-0.50701 -5.875,-0.3125 -3.05824,0.29924 -4.94113,0.48024 -6.875,0.65625 -0.65749,0.0598 -1.04004,0.17856 -1.34375,0.25 -0.42765,0.11895 -0.68351,0.21807 -1.375,0.28125 -1.31596,0.12025 -1.75976,-0.19488 -5.53125,0.21875 -3.55614,0.39001 -9.00554,1.23916 -10.25,1.90625 -1.59863,-0.29419 -3.85984,-0.52372 -5.84375,-0.3125 -3.0556,0.32532 -4.97404,0.52624 -6.90625,0.71875 -1.93221,0.1925 -1.68987,0.44088 -2.90625,0.5625 -1.31488,0.13146 -1.76298,-0.16454 -5.53125,0.28125 -3.53887,0.41865 -8.97768,1.29217 -10.25,1.96875 -1.59755,-0.28105 -3.85996,-0.42043 -5.84375,-0.1875 -3.05198,0.35836 -4.94508,0.56786 -6.875,0.78125 -0.6562,0.0725 -1.04066,0.17269 -1.34375,0.25 -0.42677,0.12722 -0.68491,0.2672 -1.375,0.34375 -1.31333,0.14568 -1.76746,-0.17402 -5.53125,0.3125 -3.54889,0.45875 -8.97863,1.41902 -10.21875,2.125 -1.59305,-0.24424 -3.83381,-0.38135 -5.8125,-0.125 -3.04759,0.39481 -4.95071,0.64845 -6.875,0.90625 -1.92428,0.25779 -1.72611,0.49353 -2.9375,0.65625 -1.30946,0.1759 -1.74719,-0.10438 -5.5,0.46875 -3.52429,0.53824 -8.92315,1.69917 -10.1875,2.4375 -1.5875,-0.20354 -3.8455,-0.25473 -5.8125,0.0937 -3.02617,0.53612 -4.89889,0.86169 -6.8125,1.1875 -0.65061,0.11077 -1.01371,0.27094 -1.3125,0.375 -0.42067,0.16488 -0.66345,0.3313 -1.34375,0.46875 -1.29465,0.26159 -1.72712,-0.006 -5.4375,0.8125 -3.49853,0.77195 -8.84595,2.38293 -10.0625,3.21875 -1.56278,-0.0774 -3.75758,0.0853 -5.6875,0.59375 -2.97244,0.78313 -4.81761,1.23209 -6.6875,1.75 -1.86988,0.5179 -1.6666,0.76728 -2.84375,1.09375 -1.27246,0.3529 -1.69703,0.10709 -5.34375,1.1875 -3.4247,1.01463 -8.64944,2.93317 -9.875,3.84375 -1.53883,0.0127 -3.71983,0.27222 -5.625,0.875 -2.93106,0.92734 -4.75031,1.45842 -6.59375,2.0625 -0.62676,0.20538 -0.99173,0.39258 -1.28125,0.53125 -0.40763,0.21361 -0.65334,0.40875 -1.3125,0.625 -1.25446,0.41154 -1.68611,0.18904 -5.28125,1.4375 -3.38985,1.17717 -8.59498,3.2137 -9.78125,4.15625 -1.52389,0.0597 -3.65005,0.39487 -5.53125,1.0625 -2.89739,1.02829 -4.69908,1.67548 -6.53125,2.3125 -1.83217,0.63701 -1.62785,0.84854 -2.78125,1.25 -1.24678,0.43396 -1.66361,0.19972 -5.21875,1.5625 -3.33867,1.2798 -8.48715,3.48255 -9.6875,4.46875 -1.50718,0.10769 -3.63569,0.4988 -5.5,1.21875 -2.86818,1.1076 -4.6238,1.78156 -6.4375,2.46875 -0.61666,0.23363 -0.99641,0.44203 -1.28125,0.59375 0,0 0,1.09375 0,1.09375 0.11178,-0.22236 0.38599,-0.81743 0.90625,-1.09375 0.69797,-0.37072 4.81363,-1.99337 6.8125,-2.71875 1.65686,-0.60125 4.15389,-1.32868 5.96875,-1.3125 0.30162,0.003 0.58762,0.0509 0.84375,0.0937 1.84249,0.30825 7.46875,1.5625 7.46875,1.5625 -10e-6,0 -6.23349,-1.64675 -7.03125,-1.84375 -0.19079,-0.0471 -0.53572,-0.0687 -0.96875,-0.0625 1.14546,-0.86971 4.761,-2.39351 7.34375,-3.4375 2.83822,-1.14727 3.11681,-1.25182 5.0625,-1.65625 2.0083,-0.41744 3.15625,-0.5 3.15625,-0.5 0,10e-6 -0.0824,-0.60114 0.96875,-1.125 0.7051,-0.35141 4.88702,-1.8924 6.90625,-2.5625 1.9519,-0.64773 5.0574,-1.3585 6.875,-1 1.86323,0.3675 7.53125,1.8125 7.53125,1.8125 10e-6,0 -6.287,-1.87111 -7.09375,-2.09375 -0.19292,-0.0532 -0.53084,-0.086 -0.96875,-0.0937 1.15834,-0.83288 4.79444,-2.19532 7.40625,-3.15625 2.87016,-1.05601 3.16734,-1.1618 5.125,-1.53125 1.85349,-0.34979 2.85884,-0.42548 3.03125,-0.4375 0.1136,-0.21724 0.37745,-0.81002 0.90625,-1.0625 0.70944,-0.33874 4.92607,-1.71275 6.96875,-2.3125 1.69317,-0.49711 4.24077,-1.03677 6.09375,-0.90625 0.30795,0.0217 0.61349,0.0973 0.875,0.15625 1.88118,0.42432 7.59375,2.03125 7.59375,2.03125 10e-6,0 -6.34174,-2.06525 -7.15625,-2.3125 -0.19479,-0.0591 -0.55788,-0.10394 -1,-0.125 1.16949,-0.79755 4.86302,-2.05622 7.5,-2.9375 2.89781,-0.96847 3.23301,-1.00332 5.21875,-1.28125 2.04965,-0.28689 3.1875,-0.3125 3.1875,-0.3125 -2e-5,0 -0.0728,-0.60697 1,-1.0625 0.7196,-0.30557 4.99098,-1.50075 7.0625,-2 2.00244,-0.48258 5.19849,-0.92829 7.0625,-0.40625 1.91078,0.53515 7.71875,2.5 7.71875,2.5 0,0 -6.42266,-2.42351 -7.25,-2.71875 -0.19784,-0.0706 -0.58216,-0.14039 -1.03125,-0.1875 1.1879,-0.72865 4.91527,-1.77408 7.59375,-2.5 2.94342,-0.79775 3.29208,-0.77083 5.3125,-0.90625 1.91289,-0.12823 2.94705,-0.0711 3.125,-0.0625 0.11728,-0.20366 0.39176,-0.77948 0.9375,-0.96875 0.73219,-0.25394 5.07852,-1.04789 7.1875,-1.375 1.74813,-0.27111 4.40088,-0.4847 6.3125,-0.0937 0.31766,0.065 0.60522,0.18551 0.875,0.28125 1.94074,0.68873 7.84375,3.09375 7.84375,3.09375 10e-6,0 -6.53471,-2.95077 -7.375,-3.3125 -0.20097,-0.0865 -0.57513,-0.16679 -1.03125,-0.25 1.2065,-0.63318 5.02956,-1.3956 7.75,-1.90625 2.98953,-0.56119 3.30023,-0.52954 5.34375,-0.53125 2.10926,-0.002 3.3125,0.125 3.3125,0.125 0,1e-5 -0.0727,-0.63119 1.03125,-0.9375 0.74052,-0.20547 5.12612,-0.83387 7.25,-1.0625 2.05302,-0.22099 5.31863,-0.25222 7.21875,0.46875 1.94779,0.73907 7.84375,3.375 7.84375,3.375 2e-5,0 -6.56288,-3.17897 -7.40625,-3.5625 -0.20168,-0.0917 -0.54221,-0.18621 -1,-0.28125 1.21092,-0.60188 4.98442,-1.24884 7.71875,-1.65625 3.0048,-0.44772 3.32551,-0.4517 5.375,-0.40625 1.94045,0.043 3.00699,0.19423 3.1875,0.21875 0.11892,-0.19316 0.3839,-0.76583 0.9375,-0.90625 0.74271,-0.18838 5.15429,-0.73428 7.28125,-0.9375 1.76303,-0.16842 4.42009,-0.23429 6.34375,0.25 0.31968,0.0805 0.60351,0.20359 0.875,0.3125 1.95293,0.78349 7.90625,3.46875 7.90625,3.46875 -2e-5,0 -6.59191,-3.25348 -7.4375,-3.65625 -0.20222,-0.0963 -0.57226,-0.20703 -1.03125,-0.3125 1.21414,-0.57427 5.04366,-1.12219 7.78125,-1.5 3.00838,-0.4152 3.32307,-0.44263 5.375,-0.375 2.11798,0.0698 3.3125,0.25 3.3125,0.25 -2e-5,0 -0.0773,-0.63741 1.03125,-0.90625 0.74362,-0.18035 5.15176,-0.66355 7.28125,-0.84375 2.05847,-0.17417 5.34324,-0.12432 7.25,0.65625 1.95459,0.80016 7.875,3.53125 7.875,3.53125 -2e-5,0 -6.55993,-3.30876 -7.40625,-3.71875 -0.20237,-0.0981 -0.57186,-0.2031 -1.03125,-0.3125 1.21517,-0.5639 5.01008,-1.1143 7.75,-1.46875 3.01091,-0.38952 3.32131,-0.39765 5.375,-0.3125 1.94439,0.0806 3.00663,0.25324 3.1875,0.28125 0.11916,-0.19086 0.38277,-0.74531 0.9375,-0.875 0.74426,-0.174 5.14993,-0.65047 7.28125,-0.8125 1.76662,-0.13427 4.4497,-0.12571 6.375,0.375 0.32,0.0832 0.6033,0.20127 0.875,0.3125 1.9546,0.80016 7.9063,3.5625 7.9063,3.5625 -10e-5,0 -6.5912,-3.34001 -7.4375,-3.75 -0.2024,-0.0981 -0.5719,-0.20311 -1.0313,-0.3125 1.2151,-0.5639 5.0413,-1.08306 7.7813,-1.4375 3.0109,-0.38953 3.3525,-0.4289 5.4062,-0.34375 2.1197,0.0879 3.3125,0.3125 3.3125,0.3125 0,0 -0.078,-0.64902 1.0313,-0.90625 0.7443,-0.17256 5.1495,-0.62336 7.2812,-0.78125 2.0606,-0.1526 5.3429,-0.0968 7.25,0.6875 1.955,0.80395 7.875,3.5 7.875,3.5 0,0 -6.5598,-3.27587 -7.4062,-3.6875 -0.2025,-0.0984 -0.5718,-0.20222 -1.0313,-0.3125 1.2154,-0.56154 5.0119,-1.12778 7.75,-1.5 3.009,-0.40905 3.3227,-0.41558 5.375,-0.34375 1.9431,0.068 3.0072,0.16485 3.1875,0.1875 0.1188,-0.1944 0.3846,-0.72881 0.9375,-0.875 0.7418,-0.19612 5.1311,-0.82878 7.25,-1.09375 1.7564,-0.21961 4.4053,-0.33231 6.3125,0.0312 0.3169,0.0604 0.6058,0.18938 0.875,0.28125 1.9362,0.66092 7.8438,2.9375 7.8438,2.9375 -1e-4,0 -6.5367,-2.80655 -7.375,-3.15625 -0.2005,-0.0836 -0.5762,-0.17333 -1.0313,-0.25 1.2037,-0.65046 5.0191,-1.37195 7.7188,-2 2.9667,-0.6902 3.2889,-0.75507 5.3125,-0.875 2.0886,-0.1238 3.2812,-0.0312 3.2812,-0.0312 0,1e-5 -0.087,-0.63205 1,-1.03125 0.7292,-0.2678 5.0472,-1.33797 7.125,-1.8125 2.0085,-0.45869 5.1679,-1.0293 7,-0.625 1.8781,0.41446 13.5782,3.01563 13.5782,3.01563 0,0 -12.3275,-3.02266 -13.1407,-3.26563 -0.1945,-0.0581 -0.5586,-0.10626 -1,-0.125 1.1676,-0.80369 3.5142,-1.6873 6.1094,-2.70312 1.6814,-0.65818 0.9237,-0.37659 2.7759,-1.0036 1.7536,-0.59366 2.4854,-1.01071 2.6304,-1.11299 0.3461,-0.20651 -0.356,-0.12188 -0.5442,-0.0424 z"
- id="path8093"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6949);enable-background:new"
- d="m 1082.625,-275.125 c 1.873,0.39348 4.4961,1.14555 6.0313,1.96875 1.5352,0.82319 2.8222,1.056 5.375,2.5 2.5266,1.42926 4.7958,2.00696 6.9687,2.53125 2.3476,0.56642 5.4354,0.71523 8.8438,1.1875 -1.0889,-0.83975 -6.6074,-1.17245 -8.4063,-1.5625 -1.7989,-0.39006 -3.8941,-1.01616 -6.5937,-2.3125 -2.6997,-1.29634 -3.4944,-1.79896 -5.8125,-2.6875 -2.3182,-0.88854 -4.0044,-1.38314 -6.4063,-1.625 z"
- id="path8095"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6961);enable-background:new"
- d="m 1051.4688,-270 c 1.9053,0.57759 4.5281,1.61572 6.0937,2.59375 1.5656,0.97802 2.8802,1.35981 5.5,3.125 2.593,1.74716 4.9859,2.70927 7.25,3.59375 2.4461,0.95557 5.6826,1.65713 9.4063,3.0625 -1.1896,-1.13784 -7.0631,-2.68675 -8.9375,-3.375 -1.8745,-0.68825 -4.0818,-1.5662 -6.875,-3.28125 -2.7933,-1.71504 -3.5736,-2.2839 -5.9375,-3.40625 -2.3641,-1.12234 -4.0567,-1.83455 -6.5,-2.3125 z"
- id="path8097"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6957);enable-background:new"
- d="m 1020.2188,-266.84375 c 1.9119,0.63811 4.5812,1.75536 6.1562,2.8125 1.5751,1.05715 2.8956,1.50867 5.5313,3.40625 2.6086,1.87821 5.0284,3.03003 7.3125,4.0625 2.4677,1.11545 5.7645,2.1733 9.5312,3.84375 -1.2033,-1.22253 -7.2028,-3.31423 -9.0937,-4.125 -1.891,-0.81077 -4.0649,-1.89379 -6.875,-3.75 -2.8102,-1.8562 -3.6218,-2.47693 -6,-3.71875 -2.3783,-1.2418 -4.1107,-1.97569 -6.5625,-2.53125 z"
- id="path8099"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cssscscsscsssccscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssccscsscscssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsszsszssszzcczzzczzzc"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6997);enable-background:new"
- d="m 1110.1719,-266.89063 c 0.1508,0.0486 0.688,0.631 0.1094,1.48438 -0.8101,1.19459 -5.7049,3.32429 -8.5625,4.125 -2.8449,0.79712 -6.2901,0.97774 -10.5625,-0.375 -4.3016,-1.36195 -5.4697,-2.46872 -10.6563,-4.3125 4.664,2.11517 6.1953,3.95233 10.125,5.34375 1.6207,0.57387 3.3671,0.9396 5.0625,1.03125 -0.4451,0.32563 -1.5303,0.9833 -3.5625,1.59375 -2.7955,0.83969 -6.6491,1.53378 -8.25,1.625 -1.5146,0.0863 -3.142,-0.51249 -3.4375,-0.625 0.1667,0.10308 0.3732,0.37734 -0.25,1.03125 -0.8993,0.94363 -6.1474,1.923 -9.125,2.25 -2.9643,0.32555 -6.5216,-0.016 -10.9062,-1.90625 -3.978,-1.71497 -5.339,-2.91536 -9.4063,-4.75 0,0 0,0.15625 0,0.15625 3.6431,2.09529 5.284,3.88327 8.875,5.5625 1.7302,0.80909 3.5917,1.40876 5.4063,1.71875 -0.5349,0.28676 -1.5578,0.71151 -3.4375,1.03125 -2.869,0.48796 -6.809,0.81614 -8.4375,0.75 -0.8507,-0.0345 -1.7286,-0.18437 -2.4063,-0.40625 -0.6848,-0.21488 -1.1897,-0.44467 -1.3125,-0.5 0.1694,0.10721 0.4311,0.40288 -0.2187,1.03125 -0.9097,0.87962 -6.2461,1.33638 -9.25,1.46875 -2.9905,0.13179 -6.5889,-0.45063 -11,-2.5625 -4.4412,-2.12626 -5.6415,-3.4016 -10.9063,-5.78125 4.7343,2.59704 6.2865,4.6291 10.3438,6.71875 1.6733,0.86185 3.4852,1.49425 5.25,1.9375 -0.4633,0.23332 -1.5894,0.68814 -3.6875,0.9375 -2.8863,0.34298 -6.8346,0.49288 -8.4688,0.375 -1.5462,-0.1115 -3.2312,-0.85696 -3.5312,-1 0.1691,0.12029 0.4138,0.41048 -0.2188,1 -0.9128,0.85073 -6.2441,1.26212 -9.25,1.375 -2.9925,0.11237 -6.5897,-0.49043 -11,-2.59375 -4.00125,-1.90823 -5.38803,-3.13783 -9.46875,-5.09375 -3e-5,0 0,0.15625 0,0.15625 3.65506,2.20392 5.29421,4.05255 8.90625,5.90625 1.74029,0.89315 3.637,1.52827 5.4688,1.96875 -0.54,0.2483 -1.5781,0.61533 -3.4688,0.84375 -2.88568,0.34858 -6.86605,0.52095 -8.5,0.40625 -0.85345,-0.0599 -1.72631,-0.25791 -2.40625,-0.5 -0.6871,-0.2353 -1.18935,-0.47226 -1.3125,-0.53125 0.16998,0.11227 0.46448,0.42225 -0.1875,1.03125 -0.91265,0.8525 -6.27533,1.29337 -9.28125,1.40625 -2.99246,0.11237 -6.59346,-0.52805 -11,-2.59375 -4.43653,-2.07978 -5.64688,-3.33171 -10.90625,-5.65625 4.72938,2.54749 6.29074,4.5778 10.34375,6.625 1.67155,0.84433 3.48554,1.46643 5.25,1.90625 -0.46323,0.23422 -1.5897,0.68407 -3.6875,0.9375 -2.88569,0.34858 -6.8362,0.56952 -8.46875,0.46875 -1.54456,-0.0953 -3.20031,-0.82885 -3.5,-0.96875 0.16899,0.11853 0.38192,0.40385 -0.25,1 -0.91186,0.86028 -6.24665,1.33025 -9.25,1.46875 -2.98995,0.1379 -6.56745,-0.45068 -10.96875,-2.46875 -3.99308,-1.83089 -5.36511,-3.0292 -9.4375,-4.90625 -2e-5,0 0,0.15625 0,0.15625 3.64761,2.13327 5.27033,3.93487 8.875,5.71875 1.73675,0.85951 3.60727,1.45014 5.4375,1.875 -0.53947,0.2529 -1.55063,0.64129 -3.4375,0.90625 -2.87978,0.40436 -6.83813,0.64562 -8.46875,0.5625 -0.85172,-0.0434 -1.7277,-0.20855 -2.40625,-0.4375 -0.68569,-0.22201 -1.1896,-0.44339 -1.3125,-0.5 0.16959,0.10899 0.4319,0.40965 -0.21875,1.03125 -0.91079,0.87014 -6.25021,1.39152 -9.25,1.5625 -2.98633,0.17021 -6.57381,-0.31577 -10.96875,-2.28125 -4.42489,-1.97888 -5.60596,-3.22819 -10.84375,-5.375 4.70997,2.38767 6.27017,4.38873 10.3125,6.34375 1.66715,0.80631 3.46043,1.39658 5.21875,1.78125 -0.46163,0.2487 -1.597,0.71225 -3.6875,1.03125 -2.8756,0.43876 -6.7804,0.7331 -8.40625,0.6875 -1.53823,-0.0431 -3.2328,-0.74522 -3.53125,-0.875 0.16833,0.11282 0.41057,0.41375 -0.21875,1.03125 -0.90812,0.8911 -6.20295,1.52825 -9.1875,1.8125 -2.97118,0.28298 -6.57342,-0.1758 -10.9375,-1.9375 -3.95934,-1.59831 -5.32915,-2.79487 -9.34375,-4.3125 3e-5,0 0,0.15625 0,0.15625 3.5959,1.81135 5.23831,3.58233 8.8125,5.15625 1.72207,0.75835 3.58748,1.28895 5.40625,1.625 -0.53609,0.27908 -1.56658,0.68763 -3.4375,1.0625 -2.85539,0.5721 -6.78942,1.01939 -8.40625,1.03125 -0.84451,0.006 -1.70608,-0.0809 -2.375,-0.25 -0.67591,-0.16151 -1.16009,-0.32923 -1.28125,-0.375 0.16722,0.094 0.42267,0.38348 -0.21875,1.0625 -0.89787,0.95052 -6.18648,1.91708 -9.125,2.4375 -2.92534,0.51809 -6.43215,0.37424 -10.71875,-1.03125 -4.3158,-1.41507 -5.47277,-2.52994 -10.5625,-3.96875 4.57685,1.75101 6.08855,3.56006 10.03125,5 1.62608,0.59389 3.36885,0.95565 5.09375,1.15625 -0.45285,0.29702 -1.55478,0.88339 -3.59375,1.46875 -2.80472,0.80517 -6.63886,1.57583 -8.21875,1.75 -1.49475,0.1648 -3.11623,-0.31681 -3.40625,-0.40625 0.16356,0.0901 0.39278,0.35993 -0.21875,1.0625 -0.88247,1.01385 -6.04452,2.37165 -8.9375,3.0625 -2.88002,0.68778 -6.3356,0.76002 -10.5625,-0.4375 -3.83485,-1.08645 -5.17258,-2.07237 -9.0625,-3.125 -10e-6,0 0,0.15625 0,0.15625 3.48418,1.39485 5.06941,2.9194 8.53125,4.03125 1.66793,0.53572 3.45578,0.78674 5.21875,0.875 -0.51964,0.35212 -1.50039,0.91452 -3.3125,1.53125 -2.76566,0.94125 -6.59024,1.93537 -8.15625,2.15625 -0.81794,0.11539 -1.6331,0.12283 -2.28125,0.0312 -0.65496,-0.0832 -1.1326,-0.21827 -1.25,-0.25 0.16204,0.0746 0.43399,0.34044 -0.1875,1.09375 -0.87,1.05453 -6.00963,2.65925 -8.875,3.4375 -2.85253,0.77476 -6.25912,0.9582 -10.4375,-0.0937 -4.20683,-1.05913 -5.35669,-2.04166 -10.34375,-3.15625 4.48454,1.45946 5.96935,3.13523 9.8125,4.25 1.58504,0.45977 3.28679,0.63825 4.96875,0.6875 -0.44157,0.33676 -1.51251,1.02773 -3.5,1.78125 -2.73393,1.03649 -6.45198,2.16269 -8,2.4375 -1.46462,0.26002 -3.05958,-0.11654 -3.34375,-0.1875 0.16025,0.0796 0.38044,0.32098 -0.21875,1.0625 -0.86466,1.07006 -5.91652,2.81815 -8.75,3.6875 -2.8208,0.86547 -6.2075,1.15631 -10.34375,0.21875 -3.75259,-0.85061 -5.04785,-1.71647 -8.875,-2.59375 0,0 0,0.15625 0,0.15625 3.42796,1.23779 4.98741,2.6323 8.375,3.53125 1.63216,0.43314 3.36704,0.58301 5.09375,0.5625 -0.50893,0.38417 -1.47675,1.02182 -3.25,1.75 -2.70634,1.11134 -6.43633,2.30781 -7.96875,2.625 -0.8004,0.16569 -1.61231,0.21862 -2.25,0.15625 0,0 0,0.51552 0,0.92229 0,0.26507 0,0.48396 0,0.48396 0.22645,-0.14468 0.44891,-0.27261 0.71875,-0.375 1.08052,-0.40998 2.17161,-0.21577 6,-1.6875 3.82843,-1.47174 5.22412,-2.00498 5.90625,-2.40625 0.6796,-0.39978 1.61165,-0.87937 2.21875,-1.53125 1.82685,-0.13775 3.57075,-0.49323 4.9375,-1 2.96812,-1.10052 4.87537,-1.80619 6.78125,-2.46875 1.90586,-0.66254 2.35409,-1.41487 3.40625,-1.78125 1.09155,-0.38011 2.19511,-0.16538 6.0625,-1.53125 3.86745,-1.36586 5.28316,-1.82708 5.96875,-2.21875 0.70109,-0.40052 1.70081,-0.93298 2.3125,-1.59375 1.9708,-0.0547 3.81685,-0.38463 5.28125,-0.875 3.00148,-1.00508 4.92615,-1.62171 6.84375,-2.25 1.5386,-0.5041 2.17402,-1.04677 2.90625,-1.4375 0.23016,-0.13431 0.47574,-0.25373 0.75,-0.34375 1.09823,-0.36048 2.18145,-0.0814 6.09375,-1.3125 3.91233,-1.23113 5.36605,-1.67295 6.0625,-2.03125 0.69388,-0.35697 1.63015,-0.79261 2.25,-1.40625 1.86521,-0.0227 3.63581,-0.26683 5.03125,-0.6875 3.03043,-0.91354 4.99238,-1.4301 6.9375,-1.96875 1.94511,-0.53864 2.42618,-1.26452 3.5,-1.5625 1.11401,-0.30915 2.21994,0.007 6.1875,-1.03125 3.96761,-1.03863 5.41758,-1.43273 6.125,-1.75 0.73487,-0.32959 1.81383,-0.75372 2.4375,-1.375 1.99774,0.116 3.85743,-0.0201 5.34375,-0.375 3.07811,-0.735 5.08344,-1.10094 7.0625,-1.5 1.58792,-0.32018 2.24429,-0.79055 3,-1.09375 0.23757,-0.1068 0.46695,-0.19276 0.75,-0.25 1.13347,-0.22919 2.30448,0.20893 6.34375,-0.5 4.03933,-0.70893 5.50025,-0.92709 6.21875,-1.1875 0.71586,-0.25944 1.70428,-0.56724 2.34375,-1.09375 1.92427,0.23949 3.74788,0.22453 5.1875,0 3.12633,-0.48762 5.15455,-0.70067 7.15625,-0.96875 2.00171,-0.26807 2.48869,-0.94514 3.59375,-1.09375 1.14639,-0.15418 2.27592,0.30157 6.34375,-0.21875 4.06784,-0.52032 5.56013,-0.69573 6.28125,-0.9375 0.7371,-0.24714 1.79809,-0.58623 2.4375,-1.125 2.05007,0.33553 3.97378,0.39796 5.5,0.21875 3.14231,-0.36896 5.17994,-0.55936 7.1875,-0.78125 1.61076,-0.17802 2.26467,-0.6082 3.03125,-0.84375 0.24094,-0.0855 0.49412,-0.1556 0.78125,-0.1875 1.14978,-0.12772 2.30129,0.34665 6.375,-0.125 4.07374,-0.47165 5.55909,-0.6106 6.28125,-0.84375 0.71946,-0.23227 1.70024,-0.47346 2.34375,-0.96875 1.93637,0.33346 3.77006,0.40424 5.21875,0.25 3.14602,-0.33495 5.17756,-0.51859 7.1875,-0.71875 2.00996,-0.20014 2.48414,-0.82639 3.59375,-0.9375 1.15114,-0.11528 2.29643,0.36506 6.375,-0.0625 4.07861,-0.42756 5.58886,-0.56209 6.3125,-0.78125 0.73915,-0.22386 1.79572,-0.51325 2.4375,-1.03125 2.0571,0.39867 4.00187,0.4934 5.53125,0.34375 3.14873,-0.3081 5.17584,-0.47325 7.1875,-0.65625 1.61407,-0.14682 2.2631,-0.56055 3.03125,-0.78125 0.24142,-0.0809 0.49353,-0.12991 0.78125,-0.15625 1.15211,-0.10545 2.29296,0.39275 6.375,0 4.08208,-0.39275 5.5889,-0.53084 6.3125,-0.75 0.7209,-0.21833 1.6997,-0.4477 2.3438,-0.9375 1.938,0.34999 3.7688,0.45438 5.2187,0.3125 3.1487,-0.3081 5.1758,-0.47325 7.1875,-0.65625 2.0116,-0.18299 2.5142,-0.83802 3.625,-0.9375 1.1523,-0.10323 2.2922,0.38483 6.375,0 4.0829,-0.38482 5.5887,-0.501 6.3125,-0.71875 0.7393,-0.22243 1.7956,-0.51449 2.4375,-1.03125 2.0574,0.40177 4.0029,0.50333 5.5313,0.34375 3.1466,-0.32852 5.1771,-0.5227 7.1875,-0.71875 1.613,-0.15729 2.2656,-0.63148 3.0312,-0.875 0.2407,-0.088 0.4632,-0.12137 0.75,-0.15625 1.1483,-0.1397 2.3167,0.33991 6.375,-0.25 4.0583,-0.58992 5.5618,-0.77714 6.2813,-1.03125 0.7167,-0.25316 1.6745,-0.55807 2.3125,-1.09375 1.9197,0.21194 3.7199,0.15141 5.1562,-0.0937 3.1191,-0.5324 5.1116,-0.92861 7.0938,-1.3125 1.9821,-0.38387 2.4743,-1.03965 3.5625,-1.28125 1.1288,-0.25066 2.2703,0.11629 6.25,-0.875 3.9796,-0.99128 5.4296,-1.4193 6.125,-1.78125 0.7223,-0.37601 1.7619,-0.87058 2.375,-1.53125 1.963,-0.012 3.7937,-0.29105 5.2187,-0.84375 2.9512,-1.14461 4.8732,-1.86942 6.6875,-2.75 1.4557,-0.70653 2.3348,-1.68641 2.5469,-1.98438 0.2122,-0.29796 0.1118,-0.7453 0.1379,-0.76675 0.043,-0.0352 0.3193,-0.085 0.479,-0.42844 0.8589,-1.84708 2.321,-5.64459 2.4352,-6.32945 0.1137,-0.68216 0.1638,-1.34774 0.2145,-1.74497 0.029,-0.22952 -0.1467,-0.86544 -0.1246,-0.92404 0.031,-0.0821 0.3045,-0.26528 0.3599,-0.51471 0.2663,-1.19833 0.089,-2.19129 -0.1251,-3.60893 -0.214,-1.41764 -0.9837,-4.62214 -1.6369,-5.47626 -0.6589,-0.86172 -1.2229,-1.01117 -1.7479,-1.00066 -0.2086,0.26976 0.1368,0.26309 0.1626,0.31261 0.6806,0.0508 0.934,0.36864 1.4192,0.89662 0.4852,0.52798 1.4428,3.93956 1.5794,5.38995 0.1366,1.45039 0.19,2.8602 -0.088,3.46864 -0.2781,0.60845 -0.9442,0.42864 -1.2366,0.49452 0.531,0.18589 0.8908,0.21322 0.9524,1.05768 0.059,0.81338 -0.1332,1.63969 -0.5198,2.80562 -0.3912,1.18001 -1.8452,4.34998 -2.2857,4.59877 -0.4523,0.25551 -0.9524,0.18199 -1.288,0.0511 z"
- id="path8101"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6953);enable-background:new"
- d="m 988.75,-263.84375 c 1.91161,0.6344 4.55027,1.75841 6.125,2.8125 1.57477,1.05409 2.8961,1.48252 5.5313,3.375 2.6082,1.87314 5.0269,3.01522 7.3125,4.0625 2.4693,1.13147 5.7521,2.15474 9.5312,3.9375 -1.2072,-1.2584 -7.139,-3.36445 -9.0312,-4.1875 -1.8922,-0.82304 -4.128,-1.93049 -6.9375,-3.78125 -2.80961,-1.85075 -3.62224,-2.48154 -6.00005,-3.71875 -2.37782,-1.23719 -4.07988,-1.9492 -6.53125,-2.5 z"
- id="path8103"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6993);enable-background:new"
- d="m 957.5,-260.78125 c 1.91,0.6181 4.58288,1.70934 6.15625,2.75 1.57339,1.04066 2.89608,1.48252 5.53125,3.375 2.60823,1.87315 5.02692,3.01521 7.3125,4.0625 2.46931,1.13147 5.75213,2.15475 9.53125,3.9375 -1.20728,-1.2584 -7.20154,-3.3957 -9.09375,-4.21875 -1.89217,-0.82304 -4.09666,-1.9305 -6.90625,-3.78125 -2.80958,-1.85075 -3.59295,-2.43932 -5.96875,-3.65625 -2.37578,-1.21691 -4.11321,-1.93885 -6.5625,-2.46875 z"
- id="path8105"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6989);enable-background:new"
- d="m 926.09375,-257.375 c 1.90772,0.59745 4.55348,1.66384 6.125,2.6875 1.5715,1.02365 2.87022,1.43971 5.5,3.28125 2.60291,1.82273 5.02887,2.9722 7.3125,4 2.4672,1.11041 5.75535,2.09323 9.53125,3.84375 -1.20623,-1.2481 -7.1719,-3.31809 -9.0625,-4.125 -1.89058,-0.8069 -4.10242,-1.89104 -6.90625,-3.6875 -2.80385,-1.79644 -3.62704,-2.40251 -6,-3.59375 -2.37297,-1.19124 -4.05362,-1.90283 -6.5,-2.40625 z"
- id="path8107"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6985);enable-background:new"
- d="m 894.90625,-253.5625 c 1.90213,0.55355 4.58701,1.58887 6.15625,2.59375 1.56923,1.00487 2.87401,1.40864 5.5,3.21875 2.59912,1.79164 5.00034,2.87189 7.28125,3.875 2.46428,1.08374 5.75984,2.04029 9.53125,3.75 -1.2048,-1.23507 -7.17416,-3.24478 -9.0625,-4.03125 -1.88832,-0.78647 -4.0752,-1.8308 -6.875,-3.59375 -2.79977,-1.76294 -3.59919,-2.36836 -5.96875,-3.53125 -2.36957,-1.16288 -4.12325,-1.83412 -6.5625,-2.28125 z"
- id="path8109"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6965);enable-background:new"
- d="m 863.71875,-248.65625 c 1.88062,0.42909 4.50427,1.38038 6.0625,2.3125 1.55823,0.93211 2.85233,1.25776 5.46875,3 2.58971,1.72444 4.98067,2.70802 7.25,3.625 2.45176,0.99069 5.73959,1.87707 9.5,3.5 -1.20131,-1.20734 -7.15249,-3.06609 -9.03125,-3.78125 -1.87875,-0.71517 -4.0854,-1.68442 -6.875,-3.375 -2.78963,-1.69057 -3.58461,-2.22822 -5.9375,-3.28125 -2.35292,-1.05301 -4.02584,-1.71248 -6.4375,-2 z"
- id="path8111"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6981);enable-background:new"
- d="m 833.15625,-241.375 c 1.84836,0.29644 4.46945,0.97632 6,1.78125 1.53058,0.80493 2.81374,1.05573 5.375,2.53125 2.53504,1.46046 4.89068,2.32509 7.125,3.0625 2.41399,0.79668 5.65711,1.46689 9.375,2.84375 -1.18771,-1.12873 -7.08772,-2.58975 -8.9375,-3.15625 -1.84977,-0.5665 -4.00342,-1.37392 -6.75,-2.84375 -2.74657,-1.46983 -3.50136,-1.92028 -5.8125,-2.78125 -2.31115,-0.86095 -4.00471,-1.32009 -6.375,-1.4375 z"
- id="path8113"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6977);enable-background:new"
- d="m 802.90625,-232.3125 c 1.8222,0.21127 4.36576,0.80057 5.875,1.53125 1.50925,0.73066 2.75568,0.92998 5.28125,2.28125 2.49976,1.33746 4.83154,2.04843 7.03125,2.65625 2.37653,0.65667 5.56464,1.07288 9.21875,2.1875 -1.16735,-1.04496 -6.92888,-2.10329 -8.75,-2.5625 -1.82111,-0.45921 -3.95225,-1.12696 -6.65625,-2.4375 -2.70403,-1.31052 -3.47106,-1.7199 -5.75,-2.46875 -2.27895,-0.74883 -3.91325,-1.17931 -6.25,-1.1875 z"
- id="path8115"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6973);enable-background:new"
- d="m 773.1875,-222.1875 c 1.81109,0.1787 4.32059,0.66506 5.8125,1.34375 1.49194,0.67869 2.7534,0.79822 5.25,2.0625 2.47107,1.25138 4.79005,1.89614 6.96875,2.4375 2.35387,0.58488 5.49134,0.89752 9.09375,1.84375 -1.15084,-0.99116 -6.85251,-1.7833 -8.65625,-2.1875 -1.80372,-0.4042 -3.91553,-1.02116 -6.59375,-2.25 -2.67818,-1.22884 -3.40345,-1.61089 -5.65625,-2.28125 -2.25279,-0.67034 -3.89627,-1.00232 -6.21875,-0.96875 z"
- id="path8117"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6969);enable-background:new"
- d="m 743.5625,-211.1875 c 1.79281,0.12911 4.27313,0.54965 5.75,1.1875 1.4769,0.63785 2.7161,0.74156 5.1875,1.9375 2.44618,1.18372 4.72054,1.74666 6.875,2.21875 2.32767,0.51003 5.4196,0.68064 9,1.5625 -1.14379,-0.9706 -6.74759,-1.59065 -8.53125,-1.9375 -1.78367,-0.34684 -3.88285,-0.88756 -6.53125,-2.03125 -2.64841,-1.14368 -3.39495,-1.51631 -5.625,-2.125 -2.23008,-0.60868 -3.82594,-0.90966 -6.125,-0.8125 z"
- id="path8119"
- inkscape:connector-curvature="0" />
- <g
- style="fill:#ffffff;fill-opacity:1;filter:url(#filter7345)"
- id="g8121">
- <path
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 744.9375,-212.11731 c 0,0 7.22229,-3.22318 9.0625,-3.5 1.84021,-0.27682 3.35225,-0.003 6,0.5625 2.64775,0.56573 8.7357,2.21518 11.1875,3.375 2.4518,1.15982 5.3125,3.5625 5.3125,3.5625 0,0 -7.14644,-2.78019 -10.1875,-3.5625 -3.04106,-0.78231 -7.64461,-2.08374 -10.375,-2.3125 -2.73039,-0.22876 -11,1.875 -11,1.875 z"
- id="path8123"
- sodipodi:nodetypes="czzzczzc"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 735.46875,-206.95416 c 0,0 3.65979,-2.22318 5.5,-2.5 1.84021,-0.27682 3.66475,0.24677 6.3125,0.8125 2.64775,0.56573 8.7357,2.21518 11.1875,3.375 2.4518,1.15982 6.5625,2.125 6.5625,2.125 0,0 -8.39644,-1.34269 -11.4375,-2.125 -3.04106,-0.78231 -7.95711,-2.33374 -10.6875,-2.5625 -2.73039,-0.22876 -7.4375,0.875 -7.4375,0.875 z"
- id="path8125"
- sodipodi:nodetypes="czzzczzc"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 759.85042,-217.61116 c 0,0 8.5437,-3.29857 10.39778,-3.45786 1.85409,-0.1593 3.64166,0.4792 6.2481,1.21208 2.60644,0.73288 8.57724,2.76594 10.95036,4.07925 2.37312,1.31331 6.41417,2.53782 6.41417,2.53782 0,0 -8.29413,-1.87365 -11.27931,-2.84767 -2.98519,-0.97402 -7.79269,-2.83478 -10.50302,-3.23662 -2.71033,-0.40184 -12.22808,1.713 -12.22808,1.713 z"
- id="path8127"
- sodipodi:nodetypes="czzzczzc"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 775.19813,-223.2266 c 0,0 7.77133,-2.78244 9.62831,-2.90349 1.85697,-0.12104 3.631,0.55417 6.22178,1.34062 2.59077,0.78645 8.5184,2.94217 10.86394,4.30412 2.34555,1.36195 6.36049,2.6695 6.36049,2.6695 0,0 -8.25373,-2.04423 -11.21821,-3.07958 -2.96447,-1.03535 -7.73259,-2.99481 -10.43406,-3.45243 -2.70147,-0.45763 -11.42225,1.12126 -11.42225,1.12126 z"
- id="path8129"
- sodipodi:nodetypes="czzzczzc"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 789.64298,-227.95417 c 0,0 8.68256,-3.52031 10.54154,-3.60535 1.85897,-0.085 3.61958,0.62442 6.19463,1.46093 2.57505,0.83649 8.45979,3.10666 10.77851,4.5138 2.31872,1.40715 6.30757,2.79224 6.30757,2.79224 0,0 -8.21257,-2.20377 -11.15643,-3.29636 -2.94386,-1.09259 -7.67312,-3.14408 -10.36522,-3.65397 -2.69209,-0.50988 -12.3006,1.78871 -12.3006,1.78871 z"
- id="path8131"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.852145"
- inkscape:transform-center-y="-4.3190906"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 804.49513,-233.32948 c 0,0 7.80756,-2.58281 9.66654,-2.66785 1.85897,-0.085 3.61958,0.62442 6.19463,1.46093 2.57505,0.83649 8.45979,3.10666 10.77851,4.5138 2.31872,1.40715 6.30757,2.79224 6.30757,2.79224 0,0 -8.21257,-2.20377 -11.15643,-3.29636 -2.94386,-1.09259 -7.67312,-3.14408 -10.36522,-3.65397 -2.69209,-0.50988 -11.4256,0.85121 -11.4256,0.85121 z"
- id="path8133"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.852145"
- inkscape:transform-center-y="-4.3190906"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 819.55763,-237.57948 c 0,0 8.55756,-2.58281 10.41654,-2.66785 1.85897,-0.085 3.61958,0.62442 6.19463,1.46093 2.57505,0.83649 8.45979,3.10666 10.77851,4.5138 2.31872,1.40715 6.30757,2.79224 6.30757,2.79224 0,0 -8.21257,-2.20377 -11.15643,-3.29636 -2.94386,-1.09259 -7.67312,-3.14408 -10.36522,-3.65397 -2.69209,-0.50988 -12.1756,0.85121 -12.1756,0.85121 z"
- id="path8135"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.852145"
- inkscape:transform-center-y="-4.3190906"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 836.23395,-242.60125 c 0,0 6.96702,-1.98723 8.82784,-1.96757 1.86081,0.0197 3.57873,0.82702 6.10265,1.80705 2.52393,0.98 8.27166,3.57758 10.50756,5.11291 2.2359,1.53535 6.14053,3.14261 6.14053,3.14261 0,0 -8.07561,-2.66222 -10.95336,-3.91866 -2.87774,-1.25645 -7.48412,-3.5707 -10.14328,-4.23121 -2.65915,-0.66049 -10.48194,0.0549 -10.48194,0.0549 z"
- id="path8137"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.64141"
- inkscape:transform-center-y="-4.9269042"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 850.73028,-246.00461 c 0,0 7.68784,-2.02768 9.54782,-1.96854 1.85997,0.0592 3.56038,0.90279 6.06293,1.93616 2.50255,1.03334 8.19387,3.75232 10.39668,5.33475 2.20282,1.58245 6.07245,3.2722 6.07245,3.2722 0,0 -8.01729,-2.83298 -10.86772,-4.15022 -2.85043,-1.31723 -7.40666,-3.72872 -10.0512,-4.4455 -2.64454,-0.71678 -11.16096,0.0211 -11.16096,0.0211 z"
- id="path8139"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.55068"
- inkscape:transform-center-y="-5.1542119"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 864.82496,-249.21081 c 0,0 8.16952,-1.96906 10.02688,-1.85396 1.85735,0.11512 3.53158,1.00956 6.0019,2.11779 2.47031,1.10821 8.0772,3.99727 10.23138,5.64531 2.15418,1.64804 5.9712,3.45352 5.9712,3.45352 0,0 -7.92839,-3.07306 -10.73787,-4.4755 -2.80949,-1.40244 -7.29106,-3.94999 -9.91283,-4.74606 -2.62176,-0.79606 -11.58066,-0.1411 -11.58066,-0.1411 z"
- id="path8141"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.41151"
- inkscape:transform-center-y="-5.4740887"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 881.38485,-251.60282 c 0,0 8.08536,-1.90809 9.93837,-1.73664 1.853,0.17147 3.4993,1.11633 5.93482,2.29908 2.43553,1.18271 7.95209,4.2407 10.05523,5.95339 2.10314,1.7127 5.86357,3.63326 5.86357,3.63326 0,0 -7.8314,-3.3124 -10.597,-4.7995 -2.76561,-1.48712 -7.16775,-4.16959 -9.76414,-5.04491 -2.59637,-0.87531 -11.43085,-0.30468 -11.43085,-0.30468 z"
- id="path8143"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.258805"
- inkscape:transform-center-y="-5.79376"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 896.58415,-254.34724 c 0,0 7.64166,-1.4277 9.49547,-1.26515 1.8538,0.16256 3.50462,1.0995 5.94579,2.27053 2.44118,1.171 7.97238,4.20246 10.08372,5.90502 2.11134,1.70258 5.88096,3.60505 5.88096,3.60505 0,0 -7.84723,-3.27474 -10.61995,-4.74855 -2.77271,-1.4738 -7.18769,-4.13509 -9.78825,-4.99793 -2.60055,-0.86282 -10.99774,-0.76897 -10.99774,-0.76897 z"
- id="path8145"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.28378"
- inkscape:transform-center-y="-5.7433893"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 911.45328,-255.98544 c 0,0 8.64166,-1.5527 10.49547,-1.39015 1.8538,0.16256 3.50462,1.0995 5.94579,2.27053 2.44118,1.171 7.97238,4.20246 10.08372,5.90502 2.11134,1.70258 5.88096,3.60505 5.88096,3.60505 0,0 -7.84723,-3.27474 -10.61995,-4.74855 -2.77271,-1.4738 -7.18769,-4.13509 -9.78825,-4.99793 -2.60055,-0.86282 -11.99774,-0.64397 -11.99774,-0.64397 z"
- id="path8147"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.28378"
- inkscape:transform-center-y="-5.7433893"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 927.70328,-258.29794 c 0,0 7.64166,-0.8652 9.49547,-0.70265 1.8538,0.16256 3.50462,1.0995 5.94579,2.27053 2.44118,1.171 7.97238,4.20246 10.08372,5.90502 2.11134,1.70258 5.88096,3.60505 5.88096,3.60505 0,0 -7.84723,-3.27474 -10.61995,-4.74855 -2.77271,-1.4738 -7.18769,-4.13509 -9.78825,-4.99793 -2.60055,-0.86282 -10.99774,-1.33147 -10.99774,-1.33147 z"
- id="path8149"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.28378"
- inkscape:transform-center-y="-5.7433893"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 942.82828,-259.48544 c 0,0 8.57916,-1.4902 10.43297,-1.32765 1.8538,0.16256 3.50462,1.0995 5.94579,2.27053 2.44118,1.171 7.97238,4.20246 10.08372,5.90502 2.11134,1.70258 5.88096,3.60505 5.88096,3.60505 0,0 -7.84723,-3.27474 -10.61995,-4.74855 -2.77271,-1.4738 -7.18769,-4.13509 -9.78825,-4.99793 -2.60055,-0.86282 -11.93524,-0.70647 -11.93524,-0.70647 z"
- id="path8151"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.28378"
- inkscape:transform-center-y="-5.7433893"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 959.07828,-261.54794 c 0,0 7.82916,-0.8027 9.68297,-0.64015 1.8538,0.16256 3.50462,1.0995 5.94579,2.27053 2.44118,1.171 7.97238,4.20246 10.08372,5.90502 2.11134,1.70258 5.88096,3.60505 5.88096,3.60505 0,0 -7.84723,-3.27474 -10.61995,-4.74855 -2.77271,-1.4738 -7.18769,-4.13509 -9.78825,-4.99793 -2.60055,-0.86282 -11.18524,-1.39397 -11.18524,-1.39397 z"
- id="path8153"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.28378"
- inkscape:transform-center-y="-5.7433893"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 974.45328,-262.79794 c 0,0 8.39166,-1.1777 10.24547,-1.01515 1.8538,0.16256 3.50462,1.0995 5.94579,2.27053 2.44118,1.171 7.97238,4.20246 10.08376,5.90502 2.1113,1.70258 5.8809,3.60505 5.8809,3.60505 0,0 -7.84721,-3.27474 -10.61993,-4.74855 -2.77271,-1.4738 -7.18769,-4.13509 -9.78825,-4.99793 -2.60055,-0.86282 -11.74774,-1.01897 -11.74774,-1.01897 z"
- id="path8155"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.28378"
- inkscape:transform-center-y="-5.7433893"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 990.64078,-264.86044 c 0,0 6.89166,-0.9902 8.74547,-0.82765 1.85385,0.16256 3.50465,1.0995 5.94575,2.27053 2.4412,1.171 7.9724,4.20246 10.0838,5.90502 2.1113,1.70258 5.8809,3.60505 5.8809,3.60505 0,0 -7.8472,-3.27474 -10.6199,-4.74855 -2.7727,-1.4738 -7.1877,-4.13509 -9.7883,-4.99793 -2.60053,-0.86282 -10.24772,-1.20647 -10.24772,-1.20647 z"
- id="path8157"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.28378"
- inkscape:transform-center-y="-5.7433893"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 1007.7658,-265.79794 c 0,0 6.8291,-1.1777 8.683,-1.01515 1.8538,0.16256 3.5046,1.0995 5.9457,2.27053 2.4412,1.171 7.9724,4.20246 10.0838,5.90502 2.1113,1.70258 5.8809,3.60505 5.8809,3.60505 0,0 -7.8472,-3.27474 -10.6199,-4.74855 -2.7727,-1.4738 -7.1877,-4.13509 -9.7883,-4.99793 -2.6005,-0.86282 -10.1852,-1.01897 -10.1852,-1.01897 z"
- id="path8159"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.28378"
- inkscape:transform-center-y="-5.7433893"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 1023.8908,-267.79794 c 0,0 6.0791,-0.4277 7.933,-0.26515 1.8538,0.16256 3.5046,1.0995 5.9457,2.27053 2.4412,1.171 7.9724,4.20246 10.0838,5.90502 2.1113,1.70258 5.8809,3.60505 5.8809,3.60505 0,0 -7.8472,-3.27474 -10.6199,-4.74855 -2.7727,-1.4738 -7.1877,-4.13509 -9.7883,-4.99793 -2.6005,-0.86282 -9.4352,-1.76897 -9.4352,-1.76897 z"
- id="path8161"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.28378"
- inkscape:transform-center-y="-5.7433893"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 1039.7033,-269.17294 c 0,0 6.4541,-0.6777 8.308,-0.51515 1.8538,0.16256 3.5046,1.0995 5.9457,2.27053 2.4412,1.171 7.9724,4.20246 10.0838,5.90502 2.1113,1.70258 5.8809,3.60505 5.8809,3.60505 0,0 -7.8472,-3.27474 -10.6199,-4.74855 -2.7727,-1.4738 -7.1877,-4.13509 -9.7883,-4.99793 -2.6005,-0.86282 -9.8102,-1.51897 -9.8102,-1.51897 z"
- id="path8163"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.28378"
- inkscape:transform-center-y="-5.7433893"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 1055.2718,-271.03319 c 0,0 5.4976,-0.90945 7.3578,-0.85348 1.8601,0.056 3.5619,0.89674 6.0661,1.92586 2.5044,1.0291 8.2003,3.7384 10.4058,5.31709 2.2055,1.57871 6.078,3.2619 6.078,3.2619 0,0 -8.022,-2.81939 -10.8748,-4.13178 -2.8526,-1.31238 -7.4129,-3.71613 -10.0587,-4.42843 -2.6457,-0.71228 -8.9742,-1.09116 -8.9742,-1.09116 z"
- id="path8165"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.55813"
- inkscape:transform-center-y="-5.1360724"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 1072.7007,-273.48537 c 0,0 4.5472,-1.15581 6.408,-1.18621 1.8607,-0.0304 3.5996,0.73049 6.1489,1.64231 2.5494,0.91177 8.3649,3.35386 10.6414,4.8285 2.2763,1.47468 6.2227,2.97636 6.2227,2.97636 0,0 -8.1442,-2.44411 -11.0547,-3.62272 -2.9105,-1.1786 -7.5774,-3.36815 -10.2534,-3.95691 -2.6759,-0.58875 -8.1129,-0.68133 -8.1129,-0.68133 z"
- id="path8167"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.74758"
- inkscape:transform-center-y="-4.6370147"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 1087.1585,-276.5244 c 0,0 5.96,-1.77355 7.8202,-1.83024 1.86,-0.0567 3.6096,0.67955 6.1715,1.55525 2.562,0.87566 2.5226,0.85713 5.3335,1.49015 2.7969,0.62986 7.0767,1.51313 7.0767,1.51313 0,0 -3.6155,-0.0163 -6.7923,-0.46614 -3.1155,-0.44119 -7.3743,-1.69825 -10.0584,-2.24913 -2.6839,-0.55088 -9.5512,-0.013 -9.5512,-0.013 z"
- id="path8169"
- sodipodi:nodetypes="czzzczzc"
- inkscape:transform-center-x="13.79933"
- inkscape:transform-center-y="-4.4842392"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 1099.25,-279.92981 c 0.1612,0.26862 11.2081,-4.60046 12.1875,-4.6875 0.9794,-0.087 2,3.125 2,3.125 0,0 -0.7751,-1.50434 -2.875,-1.0625 -2.0999,0.44184 -11.3009,2.67141 -11.3125,2.625 z"
- id="path8171"
- sodipodi:nodetypes="czczc"
- inkscape:connector-curvature="0" />
- </g>
- <path
- sodipodi:nodetypes="czscsssscssssscsssscssssscsssscssssscsssscssssscsssscssssscsssscssccsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscc"
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7333);enable-background:new"
- d="m 1107.4532,-284.0938 c -0.4187,0.21283 -0.1556,0.0939 -0.6472,0.30581 -0.4861,0.20954 -1.7234,0.57439 -4.0796,1.45895 -3.3311,1.25057 -5.8302,2.15344 -7.0259,3.0661 -1.5361,0.0213 -3.7205,0.23331 -5.6563,0.71875 -2.9815,0.74766 -4.8552,1.17401 -6.75,1.59375 -1.8948,0.41972 -1.6755,0.64219 -2.875,0.875 -1.2966,0.25166 -1.7214,-0.009 -5.4375,0.78125 -3.4899,0.74214 -8.8948,1.93107 -10.1562,2.6875 -1.5839,-0.18079 -3.8675,-0.32178 -5.8438,-0.0312 -3.0404,0.44695 -4.9162,0.67276 -6.8437,0.90625 -0.6554,0.0794 -1.0411,0.20078 -1.3438,0.28125 -0.4262,0.13165 -0.6858,0.26002 -1.375,0.34375 -1.3116,0.15936 -1.7622,-0.15683 -5.5312,0.28125 -3.5539,0.41308 -9.0054,1.27282 -10.25,1.9375 -1.599,-0.2973 -3.8578,-0.53419 -5.8438,-0.34375 -3.0588,0.29331 -4.972,0.48399 -6.9062,0.65625 -1.9343,0.17226 -1.6887,0.42237 -2.9063,0.53125 -1.3162,0.11769 -1.7598,-0.16363 -5.5312,0.25 -3.5419,0.38844 -9.0079,1.20927 -10.2813,1.875 -1.5989,-0.2947 -3.88718,-0.50701 -5.87501,-0.3125 -3.05824,0.29924 -4.94113,0.48024 -6.875,0.65625 -0.65749,0.0598 -1.04004,0.17856 -1.34375,0.25 -0.42765,0.11895 -0.68351,0.21807 -1.375,0.28125 -1.31596,0.12025 -1.75976,-0.19488 -5.53125,0.21875 -3.55614,0.39001 -9.00554,1.23916 -10.25,1.90625 -1.59863,-0.29419 -3.85984,-0.52372 -5.84375,-0.3125 -3.0556,0.32532 -4.97404,0.52624 -6.90625,0.71875 -1.93221,0.1925 -1.68987,0.44088 -2.90625,0.5625 -1.31488,0.13146 -1.76298,-0.16454 -5.53125,0.28125 -3.53887,0.41865 -8.97768,1.29217 -10.25,1.96875 -1.59755,-0.28105 -3.85996,-0.42043 -5.84375,-0.1875 -3.05198,0.35836 -4.94508,0.56786 -6.875,0.78125 -0.6562,0.0726 -1.04066,0.17269 -1.34375,0.25 -0.42677,0.12722 -0.68491,0.2672 -1.375,0.34375 -1.31333,0.14568 -1.76746,-0.17402 -5.53125,0.3125 -3.54889,0.45875 -8.97863,1.41902 -10.21875,2.125 -1.59305,-0.24424 -3.83381,-0.38135 -5.8125,-0.125 -3.04759,0.39481 -4.95071,0.64845 -6.875,0.90625 -1.92428,0.25779 -1.72611,0.49353 -2.9375,0.65625 -1.30946,0.1759 -1.74719,-0.10438 -5.5,0.46875 -3.52429,0.53824 -8.92315,1.69917 -10.1875,2.4375 -1.5875,-0.20354 -3.8455,-0.25473 -5.8125,0.0937 -3.02617,0.53612 -4.89889,0.86169 -6.8125,1.1875 -0.65061,0.11077 -1.01371,0.27094 -1.3125,0.375 -0.42067,0.16488 -0.66345,0.3313 -1.34375,0.46875 -1.29465,0.26159 -1.72712,-0.006 -5.4375,0.8125 -3.49853,0.77195 -8.84595,2.38293 -10.0625,3.21875 -1.56278,-0.0775 -3.75758,0.0853 -5.6875,0.59375 -2.97244,0.78313 -4.81761,1.23209 -6.6875,1.75 -1.86988,0.5179 -1.6666,0.76728 -2.84375,1.09375 -1.27246,0.3529 -1.69703,0.10709 -5.34375,1.1875 -3.4247,1.01463 -8.64944,2.93317 -9.875,3.84375 -1.53883,0.0127 -3.71983,0.27222 -5.625,0.875 -2.93106,0.92734 -4.75031,1.45842 -6.59375,2.0625 -0.62676,0.20538 -0.99173,0.39258 -1.28125,0.53125 -0.40763,0.21361 -0.65334,0.40875 -1.3125,0.625 -1.25446,0.41154 -1.68611,0.18904 -5.28125,1.4375 -3.38985,1.17717 -8.59498,3.2137 -9.78125,4.15625 -1.52389,0.0597 -3.65005,0.39487 -5.53125,1.0625 -2.89739,1.02829 -4.69908,1.67548 -6.53125,2.3125 -1.83217,0.63701 -1.62785,0.84854 -2.78125,1.25 -1.24678,0.43396 -1.66361,0.19972 -5.21875,1.5625 -3.33867,1.2798 -8.48715,3.48255 -9.6875,4.46875 -1.50718,0.10769 -3.63569,0.4988 -5.5,1.21875 -2.86818,1.1076 -4.6238,1.78156 -6.4375,2.46875 -0.61666,0.23363 -0.99641,0.44203 -1.28125,0.59375 0,0 0,1.09375 0,1.09375 0.11178,-0.22236 0.38599,-0.81743 0.90625,-1.09375 0.69797,-0.37072 4.81363,-1.99337 6.8125,-2.71875 1.65686,-0.60125 4.15389,-1.32868 5.96875,-1.3125 0.30162,0.003 0.58762,0.0509 0.84375,0.0937 1.84249,0.30825 7.46875,1.5625 7.46875,1.5625 -10e-6,0 -6.23349,-1.64675 -7.03125,-1.84375 -0.19079,-0.0471 -0.53572,-0.0687 -0.96875,-0.0625 1.14546,-0.86971 4.761,-2.39351 7.34375,-3.4375 2.83822,-1.14727 3.11681,-1.25182 5.0625,-1.65625 2.0083,-0.41744 3.15625,-0.5 3.15625,-0.5 0,1e-5 -0.0824,-0.60114 0.96875,-1.125 0.7051,-0.35141 4.88702,-1.8924 6.90625,-2.5625 1.9519,-0.64773 5.0574,-1.3585 6.875,-1 1.86323,0.3675 7.53125,1.8125 7.53125,1.8125 1e-5,0 -6.287,-1.87111 -7.09375,-2.09375 -0.19292,-0.0533 -0.53084,-0.086 -0.96875,-0.0937 1.15834,-0.83288 4.79444,-2.19532 7.40625,-3.15625 2.87016,-1.05601 3.16734,-1.1618 5.125,-1.53125 1.85349,-0.34979 2.85884,-0.42548 3.03125,-0.4375 0.1136,-0.21724 0.37745,-0.81002 0.90625,-1.0625 0.70944,-0.33874 4.92607,-1.71275 6.96875,-2.3125 1.69317,-0.49711 4.24077,-1.03677 6.09375,-0.90625 0.30795,0.0217 0.61349,0.0973 0.875,0.15625 1.88118,0.42432 7.59375,2.03125 7.59375,2.03125 1e-5,0 -6.34174,-2.06525 -7.15625,-2.3125 -0.19479,-0.0591 -0.55788,-0.10394 -1,-0.125 1.16949,-0.79755 4.86302,-2.05622 7.5,-2.9375 2.89781,-0.96847 3.23301,-1.00332 5.21875,-1.28125 2.04965,-0.28689 3.1875,-0.3125 3.1875,-0.3125 -2e-5,0 -0.0727,-0.60697 1,-1.0625 0.7196,-0.30557 4.99098,-1.50075 7.0625,-2 2.00244,-0.48258 5.19849,-0.92829 7.0625,-0.40625 1.91078,0.53515 7.71875,2.5 7.71875,2.5 0,0 -6.42266,-2.42351 -7.25,-2.71875 -0.19784,-0.0706 -0.58216,-0.14039 -1.03125,-0.1875 1.1879,-0.72865 4.91527,-1.77408 7.59375,-2.5 2.94342,-0.79775 3.29208,-0.77083 5.3125,-0.90625 1.91289,-0.12823 2.94705,-0.0711 3.125,-0.0625 0.11728,-0.20366 0.39176,-0.77948 0.9375,-0.96875 0.73219,-0.25394 5.07852,-1.04789 7.1875,-1.375 1.74813,-0.27111 4.40088,-0.4847 6.3125,-0.0937 0.31766,0.065 0.60522,0.18551 0.875,0.28125 1.94074,0.68873 7.84375,3.09375 7.84375,3.09375 1e-5,0 -6.53471,-2.95077 -7.375,-3.3125 -0.20097,-0.0865 -0.57513,-0.16679 -1.03125,-0.25 1.2065,-0.63318 5.02956,-1.3956 7.75,-1.90625 2.98953,-0.56119 3.30023,-0.52954 5.34375,-0.53125 2.10926,-0.002 3.3125,0.125 3.3125,0.125 0,1e-5 -0.0727,-0.63119 1.03125,-0.9375 0.74052,-0.20547 5.12612,-0.83387 7.25,-1.0625 2.05302,-0.22099 5.31863,-0.25222 7.21875,0.46875 1.94779,0.73907 7.84375,3.375 7.84375,3.375 2e-5,0 -6.56288,-3.17897 -7.40625,-3.5625 -0.20168,-0.0917 -0.54221,-0.18621 -1,-0.28125 1.21092,-0.60188 4.98442,-1.24884 7.71875,-1.65625 3.0048,-0.44772 3.32551,-0.4517 5.375,-0.40625 1.94045,0.043 3.00699,0.19423 3.1875,0.21875 0.11892,-0.19316 0.3839,-0.76583 0.9375,-0.90625 0.74271,-0.18838 5.15429,-0.73428 7.28125,-0.9375 1.76303,-0.16842 4.42009,-0.23429 6.34375,0.25 0.31968,0.0805 0.60351,0.20359 0.875,0.3125 1.95293,0.78349 7.90625,3.46875 7.90625,3.46875 -2e-5,0 -6.59191,-3.25348 -7.4375,-3.65625 -0.20222,-0.0963 -0.57226,-0.20703 -1.03125,-0.3125 1.21414,-0.57427 5.04366,-1.12219 7.78125,-1.5 3.00838,-0.4152 3.32307,-0.44263 5.375,-0.375 2.11798,0.0698 3.3125,0.25 3.3125,0.25 -2e-5,0 -0.0772,-0.63741 1.03125,-0.90625 0.74362,-0.18035 5.15176,-0.66355 7.28125,-0.84375 2.05847,-0.17417 5.34324,-0.12432 7.25,0.65625 1.95459,0.80016 7.875,3.53125 7.875,3.53125 -2e-5,0 -6.55993,-3.30876 -7.40625,-3.71875 -0.20237,-0.0981 -0.57186,-0.2031 -1.03125,-0.3125 1.21517,-0.5639 5.01008,-1.1143 7.75,-1.46875 3.01091,-0.38952 3.32131,-0.39765 5.375,-0.3125 1.94439,0.0806 3.00663,0.25324 3.1875,0.28125 0.11916,-0.19086 0.38277,-0.74531 0.9375,-0.875 0.74426,-0.174 5.14993,-0.65047 7.28125,-0.8125 1.76662,-0.13427 4.44971,-0.12571 6.37501,0.375 0.32,0.0832 0.6033,0.20127 0.875,0.3125 1.9546,0.80016 7.9063,3.5625 7.9063,3.5625 -1e-4,0 -6.5912,-3.34001 -7.4375,-3.75 -0.2024,-0.0981 -0.5719,-0.20311 -1.0313,-0.3125 1.2151,-0.5639 5.0413,-1.08306 7.7813,-1.4375 3.0109,-0.38953 3.3525,-0.4289 5.4062,-0.34375 2.1197,0.0879 3.3125,0.3125 3.3125,0.3125 0,0 -0.078,-0.64902 1.0313,-0.90625 0.7443,-0.17256 5.1495,-0.62336 7.2812,-0.78125 2.0606,-0.1526 5.3429,-0.0968 7.25,0.6875 1.955,0.80395 7.875,3.5 7.875,3.5 0,0 -6.5598,-3.27587 -7.4062,-3.6875 -0.2025,-0.0984 -0.5718,-0.20222 -1.0313,-0.3125 1.2154,-0.56154 5.0119,-1.12778 7.75,-1.5 3.009,-0.40905 3.3227,-0.41558 5.375,-0.34375 1.9431,0.068 3.0072,0.16485 3.1875,0.1875 0.1188,-0.1944 0.3846,-0.72881 0.9375,-0.875 0.7418,-0.19612 5.1311,-0.82878 7.25,-1.09375 1.7564,-0.21961 4.4053,-0.33231 6.3125,0.0312 0.3169,0.0604 0.6058,0.18938 0.875,0.28125 1.9362,0.66092 7.8438,2.9375 7.8438,2.9375 -10e-5,0 -6.5367,-2.80655 -7.375,-3.15625 -0.2005,-0.0836 -0.5762,-0.17333 -1.0313,-0.25 1.2037,-0.65046 5.0191,-1.37195 7.7188,-2 2.9667,-0.6902 3.2889,-0.75507 5.3125,-0.875 2.0886,-0.1238 3.2812,-0.0312 3.2812,-0.0312 0,1e-5 -0.087,-0.63205 1,-1.03125 0.7292,-0.2678 5.0472,-1.33797 7.125,-1.8125 2.0085,-0.45869 5.1679,-1.0293 7,-0.625 1.8781,0.41446 13.5782,3.01563 13.5782,3.01563 0,0 -12.3275,-3.02266 -13.1407,-3.26563 -0.1945,-0.0581 -0.5586,-0.10626 -1,-0.125 1.1676,-0.80369 3.5142,-1.6873 6.1094,-2.70312 1.6814,-0.65818 0.9237,-0.37659 2.7759,-1.0036 1.7536,-0.59366 2.4854,-1.01071 2.6304,-1.11299 0.3461,-0.20651 -0.356,-0.12188 -0.5442,-0.0424 z"
- id="path8173"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7285);enable-background:new"
- d="m 1082.625,-275.125 c 1.873,0.39348 4.4961,1.14555 6.0313,1.96875 1.5352,0.82319 2.8222,1.056 5.375,2.5 2.5266,1.42926 4.7958,2.00696 6.9687,2.53125 2.3476,0.56642 5.4354,0.71523 8.8438,1.1875 -1.0889,-0.83975 -6.6074,-1.17245 -8.4063,-1.5625 -1.7989,-0.39006 -3.8941,-1.01616 -6.5937,-2.3125 -2.6997,-1.29634 -3.4944,-1.79896 -5.8125,-2.6875 -2.3182,-0.88854 -4.0044,-1.38314 -6.4063,-1.625 z"
- id="path8175"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7289);enable-background:new"
- d="m 1051.4688,-270 c 1.9053,0.57759 4.5281,1.61572 6.0937,2.59375 1.5656,0.97802 2.8802,1.35981 5.5,3.125 2.593,1.74716 4.9859,2.70927 7.25,3.59375 2.4461,0.95557 5.6826,1.65713 9.4063,3.0625 -1.1896,-1.13784 -7.0631,-2.68675 -8.9375,-3.375 -1.8745,-0.68825 -4.0818,-1.5662 -6.875,-3.28125 -2.7933,-1.71504 -3.5736,-2.2839 -5.9375,-3.40625 -2.3641,-1.12234 -4.0567,-1.83455 -6.5,-2.3125 z"
- id="path8177"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7293);enable-background:new"
- d="m 1020.2188,-266.84375 c 1.9119,0.63811 4.5812,1.75536 6.1562,2.8125 1.5751,1.05715 2.8956,1.50867 5.5313,3.40625 2.6086,1.87821 5.0284,3.03003 7.3125,4.0625 2.4677,1.11545 5.7645,2.1733 9.5312,3.84375 -1.2033,-1.22253 -7.2028,-3.31423 -9.0937,-4.125 -1.891,-0.81077 -4.0649,-1.89379 -6.875,-3.75 -2.8102,-1.8562 -3.6218,-2.47693 -6,-3.71875 -2.3783,-1.2418 -4.1107,-1.97569 -6.5625,-2.53125 z"
- id="path8179"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cssscscsscsssccscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssccscsscscssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsszsszssszzcczzzczzzc"
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7337);enable-background:new"
- d="m 1110.1719,-266.89063 c 0.1508,0.0486 0.688,0.631 0.1094,1.48438 -0.8101,1.19459 -5.7049,3.32429 -8.5625,4.125 -2.8449,0.79712 -6.2901,0.97774 -10.5625,-0.375 -4.3016,-1.36195 -5.4697,-2.46872 -10.6563,-4.3125 4.664,2.11517 6.1953,3.95233 10.125,5.34375 1.6207,0.57387 3.3671,0.9396 5.0625,1.03125 -0.4451,0.32563 -1.5303,0.9833 -3.5625,1.59375 -2.7955,0.83969 -6.6491,1.53378 -8.25,1.625 -1.5146,0.0863 -3.142,-0.51249 -3.4375,-0.625 0.1667,0.10308 0.3732,0.37734 -0.25,1.03125 -0.8993,0.94363 -6.1474,1.923 -9.125,2.25 -2.9643,0.32555 -6.5216,-0.016 -10.9062,-1.90625 -3.978,-1.71497 -5.339,-2.91536 -9.4063,-4.75 0,0 0,0.15625 0,0.15625 3.6431,2.09529 5.284,3.88327 8.875,5.5625 1.7302,0.80909 3.5917,1.40876 5.4063,1.71875 -0.5349,0.28676 -1.5578,0.71151 -3.4375,1.03125 -2.869,0.48796 -6.809,0.81614 -8.4375,0.75 -0.8507,-0.0345 -1.7286,-0.18437 -2.4063,-0.40625 -0.6848,-0.21488 -1.1897,-0.44467 -1.3125,-0.5 0.1694,0.10721 0.4311,0.40288 -0.2187,1.03125 -0.9097,0.87962 -6.2461,1.33638 -9.25,1.46875 -2.9905,0.13179 -6.5889,-0.45063 -11,-2.5625 -4.4412,-2.12626 -5.6415,-3.4016 -10.9063,-5.78125 4.7343,2.59704 6.2865,4.6291 10.3438,6.71875 1.6733,0.86185 3.4852,1.49425 5.25,1.9375 -0.4633,0.23332 -1.5894,0.68814 -3.6875,0.9375 -2.8863,0.34298 -6.8346,0.49288 -8.4688,0.375 -1.5462,-0.1115 -3.2312,-0.85696 -3.5312,-1 0.1691,0.12029 0.4138,0.41048 -0.2188,1 -0.9128,0.85073 -6.2441,1.26212 -9.25,1.375 -2.9925,0.11237 -6.5897,-0.49043 -11,-2.59375 -4.00125,-1.90823 -5.38803,-3.13783 -9.46875,-5.09375 -3e-5,0 0,0.15625 0,0.15625 3.65506,2.20392 5.29421,4.05255 8.90625,5.90625 1.74029,0.89315 3.637,1.52827 5.4688,1.96875 -0.54,0.2483 -1.5781,0.61533 -3.4688,0.84375 -2.88568,0.34858 -6.86605,0.52095 -8.5,0.40625 -0.85345,-0.0599 -1.72631,-0.25791 -2.40625,-0.5 -0.6871,-0.2353 -1.18935,-0.47226 -1.3125,-0.53125 0.16998,0.11227 0.46448,0.42225 -0.1875,1.03125 -0.91265,0.8525 -6.27533,1.29337 -9.28125,1.40625 -2.99246,0.11237 -6.59346,-0.52805 -11,-2.59375 -4.43653,-2.07978 -5.64688,-3.33171 -10.90625,-5.65625 4.72938,2.54749 6.29074,4.5778 10.34375,6.625 1.67155,0.84433 3.48554,1.46643 5.25,1.90625 -0.46323,0.23422 -1.5897,0.68407 -3.6875,0.9375 -2.88569,0.34858 -6.8362,0.56952 -8.46875,0.46875 -1.54456,-0.0953 -3.20031,-0.82885 -3.5,-0.96875 0.16899,0.11853 0.38192,0.40385 -0.25,1 -0.91186,0.86028 -6.24665,1.33025 -9.25,1.46875 -2.98995,0.1379 -6.56745,-0.45068 -10.96875,-2.46875 -3.99308,-1.83089 -5.36511,-3.0292 -9.4375,-4.90625 -2e-5,0 0,0.15625 0,0.15625 3.64761,2.13327 5.27033,3.93487 8.875,5.71875 1.73675,0.85951 3.60727,1.45014 5.4375,1.875 -0.53947,0.2529 -1.55063,0.64129 -3.4375,0.90625 -2.87978,0.40436 -6.83813,0.64562 -8.46875,0.5625 -0.85172,-0.0434 -1.7277,-0.20855 -2.40625,-0.4375 -0.68569,-0.22201 -1.1896,-0.44339 -1.3125,-0.5 0.16959,0.10899 0.4319,0.40965 -0.21875,1.03125 -0.91079,0.87014 -6.25021,1.39152 -9.25,1.5625 -2.98633,0.17021 -6.57381,-0.31577 -10.96875,-2.28125 -4.42489,-1.97888 -5.60596,-3.22819 -10.84375,-5.375 4.70997,2.38767 6.27017,4.38873 10.3125,6.34375 1.66715,0.80631 3.46043,1.39658 5.21875,1.78125 -0.46163,0.2487 -1.597,0.71225 -3.6875,1.03125 -2.8756,0.43876 -6.7804,0.7331 -8.40625,0.6875 -1.53823,-0.0431 -3.2328,-0.74522 -3.53125,-0.875 0.16833,0.11282 0.41057,0.41375 -0.21875,1.03125 -0.90812,0.8911 -6.20295,1.52825 -9.1875,1.8125 -2.97118,0.28298 -6.57342,-0.1758 -10.9375,-1.9375 -3.95934,-1.59831 -5.32915,-2.79487 -9.34375,-4.3125 3e-5,0 0,0.15625 0,0.15625 3.5959,1.81135 5.23831,3.58233 8.8125,5.15625 1.72207,0.75835 3.58748,1.28895 5.40625,1.625 -0.53609,0.27908 -1.56658,0.68763 -3.4375,1.0625 -2.85539,0.5721 -6.78942,1.01939 -8.40625,1.03125 -0.84451,0.006 -1.70608,-0.0809 -2.375,-0.25 -0.67591,-0.16151 -1.16009,-0.32923 -1.28125,-0.375 0.16722,0.094 0.42267,0.38348 -0.21875,1.0625 -0.89787,0.95052 -6.18648,1.91708 -9.125,2.4375 -2.92534,0.51809 -6.43215,0.37424 -10.71875,-1.03125 -4.3158,-1.41507 -5.47277,-2.52994 -10.5625,-3.96875 4.57685,1.75101 6.08855,3.56006 10.03125,5 1.62608,0.59389 3.36885,0.95565 5.09375,1.15625 -0.45285,0.29702 -1.55478,0.88339 -3.59375,1.46875 -2.80472,0.80517 -6.63886,1.57583 -8.21875,1.75 -1.49475,0.1648 -3.11623,-0.31681 -3.40625,-0.40625 0.16356,0.0901 0.39278,0.35993 -0.21875,1.0625 -0.88247,1.01385 -6.04452,2.37165 -8.9375,3.0625 -2.88002,0.68778 -6.3356,0.76002 -10.5625,-0.4375 -3.83485,-1.08645 -5.17258,-2.07237 -9.0625,-3.125 -10e-6,0 0,0.15625 0,0.15625 3.48418,1.39485 5.06941,2.9194 8.53125,4.03125 1.66793,0.53572 3.45578,0.78674 5.21875,0.875 -0.51964,0.35212 -1.50039,0.91452 -3.3125,1.53125 -2.76566,0.94125 -6.59024,1.93537 -8.15625,2.15625 -0.81794,0.11539 -1.6331,0.12283 -2.28125,0.0312 -0.65496,-0.0832 -1.1326,-0.21827 -1.25,-0.25 0.16204,0.0746 0.43399,0.34044 -0.1875,1.09375 -0.87,1.05453 -6.00963,2.65925 -8.875,3.4375 -2.85253,0.77476 -6.25912,0.9582 -10.4375,-0.0937 -4.20683,-1.05913 -5.35669,-2.04166 -10.34375,-3.15625 4.48454,1.45946 5.96935,3.13523 9.8125,4.25 1.58504,0.45977 3.28679,0.63825 4.96875,0.6875 -0.44157,0.33676 -1.51251,1.02773 -3.5,1.78125 -2.73393,1.03649 -6.45198,2.16269 -8,2.4375 -1.46462,0.26002 -3.05958,-0.11654 -3.34375,-0.1875 0.16025,0.0796 0.38044,0.32098 -0.21875,1.0625 -0.86466,1.07006 -5.91652,2.81815 -8.75,3.6875 -2.8208,0.86547 -6.2075,1.15631 -10.34375,0.21875 -3.75259,-0.85061 -5.04785,-1.71647 -8.875,-2.59375 0,0 0,0.15625 0,0.15625 3.42796,1.23779 4.98741,2.6323 8.375,3.53125 1.63216,0.43314 3.36704,0.58301 5.09375,0.5625 -0.50893,0.38417 -1.47675,1.02182 -3.25,1.75 -2.70634,1.11134 -6.43633,2.30781 -7.96875,2.625 -0.8004,0.16569 -1.61231,0.21862 -2.25,0.15625 0,0 0,0.51552 0,0.92229 0,0.26507 0,0.48396 0,0.48396 0.22645,-0.14468 0.44891,-0.27261 0.71875,-0.375 1.08052,-0.40998 2.17161,-0.21577 6,-1.6875 3.82843,-1.47174 5.22412,-2.00498 5.90625,-2.40625 0.6796,-0.39978 1.61165,-0.87937 2.21875,-1.53125 1.82685,-0.13775 3.57075,-0.49323 4.9375,-1 2.96812,-1.10052 4.87537,-1.80619 6.78125,-2.46875 1.90586,-0.66254 2.35409,-1.41487 3.40625,-1.78125 1.09155,-0.38011 2.19511,-0.16538 6.0625,-1.53125 3.86745,-1.36586 5.28316,-1.82708 5.96875,-2.21875 0.70109,-0.40052 1.70081,-0.93298 2.3125,-1.59375 1.9708,-0.0547 3.81685,-0.38463 5.28125,-0.875 3.00148,-1.00508 4.92615,-1.62171 6.84375,-2.25 1.5386,-0.5041 2.17402,-1.04677 2.90625,-1.4375 0.23016,-0.13431 0.47574,-0.25373 0.75,-0.34375 1.09823,-0.36048 2.18145,-0.0814 6.09375,-1.3125 3.91233,-1.23113 5.36605,-1.67295 6.0625,-2.03125 0.69388,-0.35697 1.63015,-0.79261 2.25,-1.40625 1.86521,-0.0227 3.63581,-0.26683 5.03125,-0.6875 3.03043,-0.91354 4.99238,-1.4301 6.9375,-1.96875 1.94511,-0.53864 2.42618,-1.26452 3.5,-1.5625 1.11401,-0.30915 2.21994,0.007 6.1875,-1.03125 3.96761,-1.03863 5.41758,-1.43273 6.125,-1.75 0.73487,-0.32959 1.81383,-0.75372 2.4375,-1.375 1.99774,0.116 3.85743,-0.0201 5.34375,-0.375 3.07811,-0.735 5.08344,-1.10094 7.0625,-1.5 1.58792,-0.32018 2.24429,-0.79055 3,-1.09375 0.23757,-0.1068 0.46695,-0.19276 0.75,-0.25 1.13347,-0.22919 2.30448,0.20893 6.34375,-0.5 4.03933,-0.70893 5.50025,-0.92709 6.21875,-1.1875 0.71586,-0.25944 1.70428,-0.56724 2.34375,-1.09375 1.92427,0.23949 3.74788,0.22453 5.1875,0 3.12633,-0.48762 5.15455,-0.70067 7.15625,-0.96875 2.00171,-0.26807 2.48869,-0.94514 3.59375,-1.09375 1.14639,-0.15418 2.27592,0.30157 6.34375,-0.21875 4.06784,-0.52032 5.56013,-0.69573 6.28125,-0.9375 0.7371,-0.24714 1.79809,-0.58623 2.4375,-1.125 2.05007,0.33553 3.97378,0.39796 5.5,0.21875 3.14231,-0.36896 5.17994,-0.55936 7.1875,-0.78125 1.61076,-0.17802 2.26467,-0.6082 3.03125,-0.84375 0.24094,-0.0855 0.49412,-0.1556 0.78125,-0.1875 1.14978,-0.12772 2.30129,0.34665 6.375,-0.125 4.07374,-0.47165 5.55909,-0.6106 6.28125,-0.84375 0.71946,-0.23227 1.70024,-0.47346 2.34375,-0.96875 1.93637,0.33346 3.77006,0.40424 5.21875,0.25 3.14602,-0.33495 5.17756,-0.51859 7.1875,-0.71875 2.00996,-0.20014 2.48414,-0.82639 3.59375,-0.9375 1.15114,-0.11528 2.29643,0.36506 6.375,-0.0625 4.07861,-0.42756 5.58886,-0.56209 6.3125,-0.78125 0.73915,-0.22386 1.79572,-0.51325 2.4375,-1.03125 2.0571,0.39867 4.00187,0.4934 5.53125,0.34375 3.14873,-0.3081 5.17584,-0.47325 7.1875,-0.65625 1.61407,-0.14682 2.2631,-0.56055 3.03125,-0.78125 0.24142,-0.0809 0.49353,-0.12991 0.78125,-0.15625 1.15211,-0.10545 2.29296,0.39275 6.375,0 4.08208,-0.39275 5.5889,-0.53084 6.3125,-0.75 0.7209,-0.21833 1.6997,-0.4477 2.3438,-0.9375 1.938,0.34999 3.7688,0.45438 5.2187,0.3125 3.1487,-0.3081 5.1758,-0.47325 7.1875,-0.65625 2.0116,-0.18299 2.5142,-0.83802 3.625,-0.9375 1.1523,-0.10323 2.2922,0.38483 6.375,0 4.0829,-0.38482 5.5887,-0.501 6.3125,-0.71875 0.7393,-0.22243 1.7956,-0.51449 2.4375,-1.03125 2.0574,0.40177 4.0029,0.50333 5.5313,0.34375 3.1466,-0.32852 5.1771,-0.5227 7.1875,-0.71875 1.613,-0.15729 2.2656,-0.63148 3.0312,-0.875 0.2407,-0.088 0.4632,-0.12137 0.75,-0.15625 1.1483,-0.1397 2.3167,0.33991 6.375,-0.25 4.0583,-0.58992 5.5618,-0.77714 6.2813,-1.03125 0.7167,-0.25316 1.6745,-0.55807 2.3125,-1.09375 1.9197,0.21194 3.7199,0.15141 5.1562,-0.0937 3.1191,-0.5324 5.1116,-0.92861 7.0938,-1.3125 1.9821,-0.38387 2.4743,-1.03965 3.5625,-1.28125 1.1288,-0.25066 2.2703,0.11629 6.25,-0.875 3.9796,-0.99128 5.4296,-1.4193 6.125,-1.78125 0.7223,-0.37601 1.7619,-0.87058 2.375,-1.53125 1.963,-0.012 3.7937,-0.29105 5.2187,-0.84375 2.9512,-1.14461 4.8732,-1.86942 6.6875,-2.75 1.4557,-0.70653 2.3348,-1.68641 2.5469,-1.98438 0.2122,-0.29796 0.1118,-0.7453 0.1379,-0.76675 0.043,-0.0352 0.3193,-0.085 0.479,-0.42844 0.8589,-1.84708 2.321,-5.64459 2.4352,-6.32945 0.1137,-0.68216 0.1638,-1.34774 0.2145,-1.74497 0.029,-0.22952 -0.1467,-0.86544 -0.1246,-0.92404 0.031,-0.0821 0.3045,-0.26528 0.3599,-0.51471 0.2663,-1.19833 0.089,-2.19129 -0.1251,-3.60893 -0.214,-1.41764 -0.9837,-4.62214 -1.6369,-5.47626 -0.6589,-0.86172 -1.2229,-1.01117 -1.7479,-1.00066 -0.2086,0.26976 0.1368,0.26309 0.1626,0.31261 0.6806,0.0508 0.934,0.36864 1.4192,0.89662 0.4852,0.52798 1.2218,3.85117 1.3584,5.30156 0.1366,1.45039 0.19,2.8602 -0.088,3.46864 -0.2781,0.60845 -0.7232,0.51703 -1.0156,0.58291 0.531,0.18589 0.6698,0.12483 0.7314,0.96929 0.059,0.81338 -0.1332,1.63969 -0.5198,2.80562 -0.3912,1.18001 -1.8452,4.34998 -2.2857,4.59877 -0.4523,0.25551 -0.7314,0.27038 -1.067,0.13944 z"
- id="path8181"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7297);enable-background:new"
- d="m 988.75,-263.84375 c 1.91161,0.6344 4.55027,1.75841 6.125,2.8125 1.57477,1.05409 2.8961,1.48252 5.5313,3.375 2.6082,1.87314 5.0269,3.01522 7.3125,4.0625 2.4693,1.13147 5.7521,2.15474 9.5312,3.9375 -1.2072,-1.2584 -7.139,-3.36445 -9.0312,-4.1875 -1.8922,-0.82304 -4.128,-1.93049 -6.9375,-3.78125 -2.80961,-1.85075 -3.62224,-2.48154 -6.00005,-3.71875 -2.37782,-1.23719 -4.07988,-1.9492 -6.53125,-2.5 z"
- id="path8183"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7301);enable-background:new"
- d="m 957.5,-260.78125 c 1.91,0.6181 4.58288,1.70934 6.15625,2.75 1.57339,1.04066 2.89608,1.48252 5.53125,3.375 2.60823,1.87315 5.02692,3.01521 7.3125,4.0625 2.46931,1.13147 5.75213,2.15475 9.53125,3.9375 -1.20728,-1.2584 -7.20154,-3.3957 -9.09375,-4.21875 -1.89217,-0.82304 -4.09666,-1.9305 -6.90625,-3.78125 -2.80958,-1.85075 -3.59295,-2.43932 -5.96875,-3.65625 -2.37578,-1.21691 -4.11321,-1.93885 -6.5625,-2.46875 z"
- id="path8185"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7305);enable-background:new"
- d="m 926.09375,-257.375 c 1.90772,0.59745 4.55348,1.66384 6.125,2.6875 1.5715,1.02365 2.87022,1.43971 5.5,3.28125 2.60291,1.82273 5.02887,2.9722 7.3125,4 2.4672,1.11041 5.75535,2.09323 9.53125,3.84375 -1.20623,-1.2481 -7.1719,-3.31809 -9.0625,-4.125 -1.89058,-0.8069 -4.10242,-1.89104 -6.90625,-3.6875 -2.80385,-1.79644 -3.62704,-2.40251 -6,-3.59375 -2.37297,-1.19124 -4.05362,-1.90283 -6.5,-2.40625 z"
- id="path8187"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7309);enable-background:new"
- d="m 894.90625,-253.5625 c 1.90213,0.55355 4.58701,1.58887 6.15625,2.59375 1.56923,1.00487 2.87401,1.40864 5.5,3.21875 2.59912,1.79164 5.00034,2.87189 7.28125,3.875 2.46428,1.08374 5.75984,2.04029 9.53125,3.75 -1.2048,-1.23507 -7.17416,-3.24478 -9.0625,-4.03125 -1.88832,-0.78647 -4.0752,-1.8308 -6.875,-3.59375 -2.79977,-1.76294 -3.59919,-2.36836 -5.96875,-3.53125 -2.36957,-1.16288 -4.12325,-1.83412 -6.5625,-2.28125 z"
- id="path8189"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7313);enable-background:new"
- d="m 863.71875,-248.65625 c 1.88062,0.42909 4.50427,1.38038 6.0625,2.3125 1.55823,0.93211 2.85233,1.25776 5.46875,3 2.58971,1.72444 4.98067,2.70802 7.25,3.625 2.45176,0.99069 5.73959,1.87707 9.5,3.5 -1.20131,-1.20734 -7.15249,-3.06609 -9.03125,-3.78125 -1.87875,-0.71517 -4.0854,-1.68442 -6.875,-3.375 -2.78963,-1.69057 -3.58461,-2.22822 -5.9375,-3.28125 -2.35292,-1.05301 -4.02584,-1.71248 -6.4375,-2 z"
- id="path8191"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7317);enable-background:new"
- d="m 833.15625,-241.375 c 1.84836,0.29644 4.46945,0.97632 6,1.78125 1.53058,0.80493 2.81374,1.05573 5.375,2.53125 2.53504,1.46046 4.89068,2.32509 7.125,3.0625 2.41399,0.79668 5.65711,1.46689 9.375,2.84375 -1.18771,-1.12873 -7.08772,-2.58975 -8.9375,-3.15625 -1.84977,-0.5665 -4.00342,-1.37392 -6.75,-2.84375 -2.74657,-1.46983 -3.50136,-1.92028 -5.8125,-2.78125 -2.31115,-0.86095 -4.00471,-1.32009 -6.375,-1.4375 z"
- id="path8193"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7321);enable-background:new"
- d="m 802.90625,-232.3125 c 1.8222,0.21127 4.36576,0.80057 5.875,1.53125 1.50925,0.73066 2.75568,0.92998 5.28125,2.28125 2.49976,1.33746 4.83154,2.04843 7.03125,2.65625 2.37653,0.65667 5.56464,1.07288 9.21875,2.1875 -1.16735,-1.04496 -6.92888,-2.10329 -8.75,-2.5625 -1.82111,-0.45921 -3.95225,-1.12696 -6.65625,-2.4375 -2.70403,-1.31052 -3.47106,-1.7199 -5.75,-2.46875 -2.27895,-0.74883 -3.91325,-1.17931 -6.25,-1.1875 z"
- id="path8195"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7329);enable-background:new"
- d="m 773.1875,-222.1875 c 1.81109,0.1787 4.32059,0.66506 5.8125,1.34375 1.49194,0.67869 2.7534,0.79822 5.25,2.0625 2.47107,1.25138 4.79005,1.89614 6.96875,2.4375 2.35387,0.58488 5.49134,0.89752 9.09375,1.84375 -1.15084,-0.99116 -6.85251,-1.7833 -8.65625,-2.1875 -1.80372,-0.4042 -3.91553,-1.02116 -6.59375,-2.25 -2.67818,-1.22884 -3.40345,-1.61089 -5.65625,-2.28125 -2.25279,-0.67034 -3.89627,-1.00232 -6.21875,-0.96875 z"
- id="path8197"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7325);enable-background:new"
- d="m 743.5625,-211.1875 c 1.79281,0.12911 4.27313,0.54965 5.75,1.1875 1.4769,0.63785 2.7161,0.74156 5.1875,1.9375 2.44618,1.18372 4.72054,1.74666 6.875,2.21875 2.32767,0.51003 5.4196,0.68064 9,1.5625 -1.14379,-0.9706 -6.74759,-1.59065 -8.53125,-1.9375 -1.78367,-0.34684 -3.88285,-0.88756 -6.53125,-2.03125 -2.64841,-1.14368 -3.39495,-1.51631 -5.625,-2.125 -2.23008,-0.60868 -3.82594,-0.90966 -6.125,-0.8125 z"
- id="path8199"
- inkscape:connector-curvature="0" />
- </g>
- </g>
- <path
- sodipodi:nodetypes="ccccccccc"
- id="path8201"
- d="m 863.87812,475.6679 c 1.64212,-3.218 3.51781,-5.73529 4.86136,-9.84898 0.79872,-3.65789 3.31204,-2.03073 7.26047,-8.3969 1.40193,-2.2395 5.47653,0.39136 8.9651,-2.39911 1.27072,-0.80319 2.88488,-0.40431 4.48256,-0.0631 3.76539,1.31896 5.82576,3.70355 8.33376,5.80837 6.13906,5.97023 20.53414,7.94327 23.48604,6.31346 1.43405,-2.90474 7.88128,-5.40888 12.37437,-11.11168 0.74811,-1.12267 11.72936,-8.74446 14.64721,-6.56599"
- style="display:inline;opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccccccccccc"
- id="path8203"
- d="m 888.50059,465.25071 c 7.36341,-3.23297 13.8109,-8.9084 20.70813,-13.38452 3.31057,-1.96954 6.86983,3.21601 10.796,3.59866 2.29773,-0.21813 3.7129,1.20259 5.68211,1.6415 5.15636,1.31779 2.39793,3.86488 9.97526,6.43972 6.15561,1.7204 8.9074,-6.79847 14.89975,-7.3236 4.87739,-0.50299 8.09892,-0.31603 11.61675,-0.25254 3.92696,0.13889 4.07855,-3.4976 6.06092,-5.3033 2.98056,-2.80522 7.15561,-1.84972 10.14485,-4.7409 1.01754,-1.38468 1.95458,-3.01085 2.73459,-5.10809 0.88201,-2.00034 3.04006,0.30598 4.79823,1.26269"
- style="display:inline;opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- <path
- id="path8994"
- d="m 403.27922,1056.3058 56.56854,-42.4264 72.12489,14.1421 -46.66904,52.3259 -53.74012,7.0711 -28.28427,-31.1127 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter9048);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- id="path4189"
- d="m 542.27183,1060.5719 c -1.40727,18.8012 -1.1449,32.751 2.08174,49.3033 3.22666,16.5523 16.40609,45.9073 20.33441,63.1837 3.92621,17.2671 2.69413,38.3097 -12.45944,51.1483 -15.31761,12.9774 -42.05128,21.5989 -67.83231,15.7337 -25.78105,-5.8652 -69.54907,-49.2234 -88.59019,-70.2283 -19.11214,-21.0833 -63.76086,-93.8506 -77.93853,-124.2758 -14.17767,-30.4251 -12.65961,-36.7186 -8.11972,-45.52972 -9.36672,-24.5205 -12.41371,-50.06681 -33.71245,-75.57664 30.32547,3.11444 43.88028,26.95633 60.12568,47.13975 -5.52989,-48.07603 -18.05471,-64.4165 -28.37395,-90.7243 29.9943,6.08165 50.57936,31.87239 63.97979,72.7125 9.55415,-3.91791 18.23776,-9.37294 30.18741,-9.0612 -11.2975,-41.6958 -17.94946,-69.91584 -36.68725,-101.06994 53.44196,5.67033 83.65702,80.63932 78.97142,87.9608 9.97797,-2.24399 19.00565,-6.53038 30.43653,-5.65167 -11.24897,-38.34702 -21.04781,-76.8679 -3.65971,-118.64819 0,0 48.28678,65.43688 54.38966,85.80578 6.10287,20.3689 1.51881,38.70051 1.51881,38.70051 0,0 16.95957,31.0853 20.29392,51.09414 3.3731,20.24138 -3.53269,59.10328 -4.94582,77.98328 z"
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- <path
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,995.28646,23.53493)"
- clip-path="url(#clipPath3631)"
- sodipodi:nodetypes="cccccccccccccccccccccc"
- id="path4191"
- d="m 719.5,738.69519 18.31177,15.43196 44.41103,-15.38821 23.2772,-25.54375 11.46397,19.22065 30.67161,12.78354 25.09737,5.72837 L 892,723.19519 908.02309,747.02126 947,752.19519 l 10.24541,-6.19852 6.75471,8.6982 25.49988,11.00032 2,-40.5 L 955.94866,710.6576 923.45591,689.1305 883.0038,677.66492 861.69668,662.13148 840,685.19519 755.02878,638.61208 722,676.69519 l -2.5,62 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter3587);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,822.28931,10.93589)"
- sodipodi:nodetypes="ccssscsssssssssssssccccscccccccccsscccccccccccssscccccccccccccccsccccssssssssssssscccsssc"
- clip-path="url(#clipPath3677)"
- id="path4193"
- d="m 584,696.5 -6.5625,17.15625 c 0,0 -7.81152,20.36488 -15.6875,43.65625 -3.93799,11.64568 -7.88302,24.04145 -10.9375,35.125 -3.05448,11.08355 -5.33586,20.37986 -5.5,28.28125 -0.39807,19.16196 5.74653,34.8883 8.9375,41.75 -0.77153,3.55523 -1.99137,9.45432 -3.34375,18.09375 -1.92042,12.26821 -3.71827,27.15441 -2.375,39.875 1.38209,13.08835 6.81222,28.18765 12.59375,43.03125 5.78153,14.8436 12.05435,29.22711 15.21875,38.03125 6.63206,18.4519 9.99296,31.5763 11.3125,48.5 0.58135,7.4561 -0.24227,20.336 -1.25,33.375 -1.00773,13.039 -2.18661,26.3014 -1.6875,36.9688 0.98911,21.1398 9.32798,46.8347 33.375,57.9374 22.77483,10.5154 55.32682,11.7022 83.4375,-3.4374 16.15992,-8.7034 30.07634,-27.0976 43.375,-46.9063 13.29866,-19.8087 24.96917,-41.0534 31.9375,-54.9063 15.35292,-30.5212 39.39353,-115.46418 45.625,-152.7187 3.01859,-18.04653 3.92166,-29.06555 2.625,-38.03125 -0.97853,-6.76604 -3.82819,-12.1474 -6.875,-16.21875 2.04274,-27.50791 -0.73207,-51.36878 11.96875,-79.40625 L 840.75,763.375 l -23.8125,9.3125 c -17.48975,6.83753 -28.90164,19.04536 -36.59375,32.0625 -0.32251,0.54577 -0.56314,1.10776 -0.875,1.65625 0.22203,-22.51521 4.40784,-37.63759 6.59375,-58.6875 l 1.96875,-19 L 771,737.375 c -30.59449,15.55571 -45.69489,48.19321 -49.71875,90.21875 -4.24532,-0.62547 -8.8314,-1.01965 -13.8125,-0.84375 -0.29149,-39.18036 -0.39629,-67.03685 8.59375,-99.375 l 5.59375,-20.125 -19.4375,7.65625 c -30.90937,12.20394 -47.85954,41.93073 -56.625,68.375 -4.38273,13.22214 -6.74582,25.80121 -7.59375,35.9375 -0.23203,2.77373 -0.31106,5.31132 -0.3125,7.71875 -3.24187,-0.0364 -6.42052,0.13589 -10.0625,0.5 0.0416,-39.00473 -3.48424,-79.75415 -32.28125,-116.5 L 584,696.5 Z m 5.8125,43.8125 c 16.80691,30.64383 17.47451,63.96728 16.9375,99.75 l -0.21875,15.0625 12.03493,-6.53921 c 8.66205,-3.13302 19.56058,-0.22752 31.93382,-0.83579 l 14.67465,9.3566 -6.3309,-25.7941 c -0.0897,-0.22997 -0.22046,-0.41669 -0.25,-0.71875 -0.19951,-2.03986 -0.22232,-5.47307 0.125,-9.625 0.69464,-8.30386 2.78957,-19.58524 6.625,-31.15625 5.15532,-15.55294 13.48801,-31.19248 25.125,-42.53125 -4.68381,28.63798 -3.21559,60.25934 -3.01164,95.80514 l -2.76593,13.26164 15.49632,-7.59803 c 9.0294,-2.75771 17.18897,-0.34996 29.28125,1.09375 l 13.24632,9.44423 L 741.09375,840 c 1.44793,-30.97177 8.22149,-53.67808 20.71875,-68.875 -2.98688,19.77884 -5.43043,41.7848 0.3125,78.34375 l 1.06552,6.37318 -2.93815,11.51685 10.61711,-8.16818 9.18973,10.22198 -1.54828,-10.4636 L 781.9375,852 c 5.70102,-13.21149 10.17282,-26.21337 16.34375,-36.65625 0.95986,-1.62434 2.03153,-3.06436 3.0625,-4.5625 -3.68066,21.15535 -2.42716,40.20815 -4.09375,57.78125 l -4.68014,7.80698 7.39889,0.22427 c 3.22005,3.48361 3.8675,3.85068 4.5625,8.65625 0.695,4.80557 0.31862,14.40035 -2.5625,31.625 -5.56799,33.28792 -31.84562,77.83981 -43.7404,101.4864 -6.60491,13.1304 -18.52833,57.4859 -31.12335,76.2465 -12.59502,18.7605 -28.53137,39.7673 -37.17204,44.4209 -21.49052,11.5742 -44.55594,25.5059 -60.61889,18.0895 -14.37486,-6.637 -23.03969,-21.1927 -23.81407,-37.7433 -0.38311,-8.188 0.61279,-21.3092 1.625,-34.4062 1.01221,-13.0971 11.28891,-22.5708 15.42339,-36.5626 5.37229,-18.1808 -1.44687,-36.5944 -12.5,-53.93745 -6.48655,-10.17778 -23.9768,-24.2579 -29.54839,-38.5625 -5.57159,-14.3046 -10.36751,-29.00315 -11.28125,-37.65625 -0.92621,-8.77113 0.4225,-23.02502 2.21875,-34.5 1.79625,-11.47497 3.84375,-20.28125 3.84375,-20.28125 l 9.42278,-3.6152 -10.48528,-3.8848 c 0,0 -8.49889,-15.3101 -8.09375,-34.8125 0.0711,-3.42316 1.83626,-12.72805 4.71875,-23.1875 2.88249,-10.45945 6.76466,-22.55271 10.625,-33.96875 3.04439,-9.00308 5.78063,-16.60345 8.34375,-23.6875 z"
- style="display:inline;opacity:0.58775509;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3898);enable-background:new"
- inkscape:connector-curvature="0" />
- <g
- transform="translate(276,136)"
- clip-path="url(#clipPath3622)"
- id="g3617"
- style="display:inline;enable-background:new">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter9024);enable-background:accumulate"
- d="m -15.66751,843.48852 -49.49748,-15.55635 -26.87005,52.3259 41.01219,45.25484 49.49747,-38.18377 -14.14213,-43.84062 z"
- id="path4195"
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,-52.200498,74.09707)"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter9020);enable-background:accumulate"
- d="m 118.70648,859.93048 -55.154328,-46.66904 -43.84062,36.76955 33.94113,53.74011 -13.596814,85.46203 -39.44536579,28.29217 -41.01220021,11.3137 -2.82842,46.669 56.56854,25.4559 18.943987,-69.65 23.45655,-58.85663 46.347541,-72.61491 16.62,-39.91188 z"
- id="path4197"
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,-46.92842,75.511284)"
- sodipodi:nodetypes="ccccccccccccc"
- inkscape:connector-curvature="0" />
- </g>
- <path
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,229.07158,211.51128)"
- id="path4199"
- d="m -70.82184,932.58397 60.81118,-26.87005 100.40916,31.1127 -63.63961,31.11269 -82.02438,-16.97056 -15.55635,-18.38478 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter9044);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,822.28931,10.93589)"
- clip-path="url(#clipPath4177)"
- sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccczzzcccccc"
- id="path4201"
- d="m 583.0625,715.75 c -12.10609,34.44974 -26.7145,68.53333 -31.75,104.84375 -0.83208,14.92867 4.58915,29.15943 8.84375,43.0625 -5.91624,27.20126 -10.13681,56.89995 1.15625,83.125 13.51717,38.16085 35.00147,75.68215 32.42279,117.46825 -0.9483,29.2942 -9.01444,60.9941 5.38971,88.2817 10.19864,19.3348 33.13956,27.3117 53.96785,27.6676 27.86219,1.1741 56.46261,-11.6216 72.0009,-35.2613 22.59549,-29.3717 41.80051,-61.4973 55.23865,-96.0598 16.89053,-45.506 29.6718,-92.56072 37.93402,-140.3989 1.8244,-12.94106 3.10108,-27.46985 -4.57892,-38.82255 -3.43115,-7.33632 0.0421,-15.56014 -0.68457,-23.30977 0.674,-24.99466 4.01232,-50.66376 16.65332,-72.59648 -17.73313,6.4446 -35.07268,16.55971 -44.00307,33.86425 -3.93508,6.70955 -7.60482,13.57413 -11.37193,20.38575 -3.54999,-30.01408 3.71963,-59.64828 6.78125,-89.28125 -20.16604,9.05463 -36.87672,25.65522 -44.17495,46.682 -6.30463,15.58003 -8.80222,32.31718 -10.26255,49.03675 -8.25334,-1.51925 -16.68447,-2.10155 -25.0625,-1.5 -0.96308,-38.69787 -0.46696,-79.40715 10.96875,-115.90625 -18.68113,6.21776 -35.16621,18.73551 -45.62803,35.38723 -13.85254,20.87979 -21.2614,45.75395 -23.05947,70.61277 0.58534,4.32454 -0.0613,11.84009 -6.34375,9.875 -5.33118,0.0176 -10.62908,0.67883 -15.9375,1.09375 1.14784,-39.38148 -3.34144,-81.6282 -27.0625,-114.21875 -3.06071,-3.63717 -5.63685,-7.68438 -8.625,-11.34375 -0.9375,2.4375 -1.875,4.875 -2.8125,7.3125 z m 7.75,13.84375 c 18.56527,29.29629 22.4825,64.82012 22.125,98.875 0.20409,5.17526 -0.51656,11.8292 0.125,16.0625 12.31856,-6.10275 26.73912,-2.4399 39.78125,-2.1875 2.31712,1.22325 3.1921,1.65243 1.90625,-1.40625 -4.16455,-13.95285 -1.84828,-28.613 1.80504,-42.40764 6.36687,-26.29064 20.62828,-51.08798 42.81996,-67.02986 -8.61709,37.23706 -5.71658,76.56161 -6.09375,113.96875 12.25344,-6.9099 27.27879,-3.44613 40.03125,-0.25 3.39222,3.5348 2.28935,-0.72948 2.1875,-3.8125 -0.48309,-21.37058 4.13133,-43.06963 13.6875,-62.15625 5.96266,-10.68727 14.24338,-19.80379 22.4375,-28.875 -7.87156,33.8381 -9.2029,69.33593 -2.71875,103.5 1.72485,-1.41118 4.60681,-0.45414 5.65625,-0.375 9.68369,-21.23682 16.35112,-45.38062 34.89016,-60.74185 1.87329,-0.37122 -1.44818,8.52495 -1.48391,11.8981 -3.53488,21.84581 -7.17516,44.14234 -8.78421,66.21911 -8.78379,2.34171 2.84835,2.32354 3.46875,4.0625 7.92311,10.5658 4.66299,24.40472 3.63165,36.35334 -7.06405,45.03355 -22.14231,87.36194 -35.95355,130.6798 -12.07476,32.9493 -27.3742,58.8525 -47.88808,87.2015 -10.95257,13.5514 -23.24472,27.8513 -40.84375,32.5 -20.15601,6.2413 -44.20676,10.8769 -62.59956,0.046 -17.28966,-12.3414 -21.02393,-35.7089 -19.26226,-55.6864 0.0488,-15.8262 4.93886,-28.5121 4.4106,-43.4918 -0.53824,-15.2629 -2.29135,-30.5647 -6.54261,-46.8663 -4.25126,-16.30162 -9.04325,-24.91794 -16.11906,-41.57338 -7.24111,-17.04456 -15.07015,-36.74863 -18.20542,-56.28842 -1.74948,-18.62714 2.89171,-37.12262 5.78125,-55.25 3.29623,-2.83696 -1.59799,-5.19659 -2.3125,-8.1875 -7.60113,-17.01508 -8.40747,-36.7749 -2.74234,-54.55998 7.1302,-25.0723 15.76087,-49.63241 24.67984,-74.12752 0.70833,1.30208 1.41667,2.60417 2.125,3.90625 z"
- style="display:inline;opacity:0.58775509;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4105);enable-background:new"
- inkscape:connector-curvature="0" />
- <path
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,995.28646,23.53493)"
- clip-path="url(#clipPath3631)"
- sodipodi:nodetypes="cccccccc"
- id="path4203"
- d="m 735.05635,733.03834 2.75542,21.08881 44.41103,-15.38821 4.85063,-22.38975 -3.93617,-22.05222 -22.45163,-36.59301 -8.28004,30.30494 -17.34924,45.02944 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter4130);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,995.28646,23.53493)"
- clip-path="url(#clipPath3631)"
- sodipodi:nodetypes="cccccccc"
- id="path4205"
- d="m 831.81321,730.29452 15.82237,14.90486 20.85473,2.89994 -1.59029,-39.92598 8.32561,-30.50842 -7.16499,-6.34106 -21.69669,20.9424 -14.55074,38.02826 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter4141);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <g
- transform="translate(276,136)"
- clip-path="url(#clipPath8338)"
- style="display:inline;filter:url(#filter8333);enable-background:new"
- id="g8317">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 964.00012,754.69487 18.42881,7.46479 9.07107,-36.96447 -14.87031,4.83886 -12.62957,24.66082 z"
- id="path4209"
- sodipodi:nodetypes="ccccc"
- clip-path="none"
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,719.28646,-112.46507)"
- inkscape:connector-curvature="0" />
- <rect
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="rect8315"
- width="182"
- height="177"
- x="-55"
- y="757.19519" />
- </g>
- <g
- transform="translate(276,136)"
- clip-path="url(#clipPath8359)"
- style="display:inline;filter:url(#filter8354);enable-background:new"
- id="g8346">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 910.14441,746.31415 32.61295,5.17393 -0.36119,-23.87619 7.18853,-29.68221 -8.45112,-5.26365 -21.82194,26.51077 -9.16723,27.13735 z"
- id="path4207"
- sodipodi:nodetypes="ccccccc"
- clip-path="none"
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,719.28646,-112.46507)"
- inkscape:connector-curvature="0" />
- <rect
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="rect8344"
- width="165"
- height="176"
- x="-22"
- y="696.19519" />
- </g>
- <path
- sodipodi:nodetypes="czzzzzzcccccccccczczz"
- id="path8848"
- d="m 1036.164,1071.8338 c 6.7941,18.9028 10.4937,33.2997 11.8903,51.2119 1.3966,17.9123 -3.7827,51.8008 -2.9005,70.6561 0.8818,18.8452 8.1337,40.099 27.3446,48.9689 19.4189,8.9658 49.3193,10.2113 74.1199,-3.1456 24.8006,-13.357 57.401,-70.3255 70.9742,-97.3087 13.6239,-27.0839 38.7611,-114.4974 44.6608,-149.76859 5.8998,-35.27121 2.5506,-41.30077 -4.6174,-49.05549 2.6403,-27.84015 -1.4998,-54.93543 13.1096,-87.18618 -30.249,11.8257 -37.3823,40.1607 -48.3189,65.50508 -8.0009,-50.93293 0.2092,-71.27319 3.3189,-101.21936 -29.0647,14.77791 -42.8615,47.11402 -45,92.85714 -10.9239,-1.3042 -21.3914,-4.43423 -33.5714,-0.71429 -0.264,-46.02334 -1.4635,-76.88941 8.9106,-114.20649 -53.2554,21.02686 -62.9472,106.5941 -56.0535,112.77792 -10.8828,0.535 -21.371,-1.2973 -32.8571,2.85715 0.6389,-42.57135 -0.2605,-84.90861 -30,-122.85715 0,0 -30.958,80.92234 -31.4286,103.57143 -0.4705,22.64909 9.4516,40.16588 9.4516,40.16588 0,0 -8.568,36.74051 -6.2986,58.23223 2.2959,21.74142 20.4429,59.67622 27.2655,78.65812 z"
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- inkscape:connector-curvature="0" />
- <path
- transform="translate(276,136)"
- clip-path="url(#clipPath3631)"
- sodipodi:nodetypes="cccccccccccccccccccccc"
- id="path3635"
- d="m 719.5,738.69519 18.31177,15.43196 44.41103,-15.38821 23.2772,-25.54375 11.46397,19.22065 30.67161,12.78354 25.09737,5.72837 L 892,723.19519 908.02309,747.02126 947,752.19519 l 10.24541,-6.19852 6.75471,8.6982 25.49988,11.00032 2,-40.5 L 955.94866,710.6576 923.45591,689.1305 883.0038,677.66492 861.69668,662.13148 840,685.19519 755.02878,638.61208 722,676.69519 l -2.5,62 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter3587);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccssscsssssssssssssccccscccccccccsscccccccccccssscccccccccccccccsccccssssssssssssscccsssc"
- clip-path="url(#clipPath3677)"
- id="path3669"
- d="m 584,696.5 -6.5625,17.15625 c 0,0 -7.81152,20.36488 -15.6875,43.65625 -3.93799,11.64568 -7.88302,24.04145 -10.9375,35.125 -3.05448,11.08355 -5.33586,20.37986 -5.5,28.28125 -0.39807,19.16196 5.74653,34.8883 8.9375,41.75 -0.77153,3.55523 -1.99137,9.45432 -3.34375,18.09375 -1.92042,12.26821 -3.71827,27.15441 -2.375,39.875 1.38209,13.08835 6.81222,28.18765 12.59375,43.03125 5.78153,14.8436 12.05435,29.22711 15.21875,38.03125 6.63206,18.4519 9.99296,31.5763 11.3125,48.5 0.58135,7.4561 -0.24227,20.336 -1.25,33.375 -1.00773,13.039 -2.18661,26.3014 -1.6875,36.9688 0.98911,21.1398 9.32798,46.8347 33.375,57.9374 22.77483,10.5154 55.32682,11.7022 83.4375,-3.4374 16.15992,-8.7034 30.07634,-27.0976 43.375,-46.9063 13.29866,-19.8087 24.96917,-41.0534 31.9375,-54.9063 15.35292,-30.5212 39.39353,-115.46418 45.625,-152.7187 3.01859,-18.04653 3.92166,-29.06555 2.625,-38.03125 -0.97853,-6.76604 -3.82819,-12.1474 -6.875,-16.21875 2.04274,-27.50791 -0.73207,-51.36878 11.96875,-79.40625 L 840.75,763.375 l -23.8125,9.3125 c -17.48975,6.83753 -28.90164,19.04536 -36.59375,32.0625 -0.32251,0.54577 -0.56314,1.10776 -0.875,1.65625 0.22203,-22.51521 4.40784,-37.63759 6.59375,-58.6875 l 1.96875,-19 L 771,737.375 c -30.59449,15.55571 -45.69489,48.19321 -49.71875,90.21875 -4.24532,-0.62547 -8.8314,-1.01965 -13.8125,-0.84375 -0.29149,-39.18036 -0.39629,-67.03685 8.59375,-99.375 l 5.59375,-20.125 -19.4375,7.65625 c -30.90937,12.20394 -47.85954,41.93073 -56.625,68.375 -4.38273,13.22214 -6.74582,25.80121 -7.59375,35.9375 -0.23203,2.77373 -0.31106,5.31132 -0.3125,7.71875 -3.24187,-0.0364 -6.42052,0.13589 -10.0625,0.5 0.0416,-39.00473 -3.48424,-79.75415 -32.28125,-116.5 L 584,696.5 Z m 5.8125,43.8125 c 16.80691,30.64383 17.47451,63.96728 16.9375,99.75 l -0.21875,15.0625 12.03493,-6.53921 c 8.66205,-3.13302 19.56058,-0.22752 31.93382,-0.83579 l 14.67465,9.3566 -6.3309,-25.7941 c -0.0897,-0.22997 -0.22046,-0.41669 -0.25,-0.71875 -0.19951,-2.03986 -0.22232,-5.47307 0.125,-9.625 0.69464,-8.30386 2.78957,-19.58524 6.625,-31.15625 5.15532,-15.55294 13.48801,-31.19248 25.125,-42.53125 -4.68381,28.63798 -3.21559,60.25934 -3.01164,95.80514 l -2.76593,13.26164 15.49632,-7.59803 c 9.0294,-2.75771 17.18897,-0.34996 29.28125,1.09375 l 13.24632,9.44423 L 741.09375,840 c 1.44793,-30.97177 8.22149,-53.67808 20.71875,-68.875 -2.98688,19.77884 -5.43043,41.7848 0.3125,78.34375 l 1.06552,6.37318 -2.93815,11.51685 10.61711,-8.16818 9.18973,10.22198 -1.54828,-10.4636 L 781.9375,852 c 5.70102,-13.21149 10.17282,-26.21337 16.34375,-36.65625 0.95986,-1.62434 2.03153,-3.06436 3.0625,-4.5625 -3.68066,21.15535 -2.42716,40.20815 -4.09375,57.78125 l -4.68014,7.80698 7.39889,0.22427 c 3.22005,3.48361 3.8675,3.85068 4.5625,8.65625 0.695,4.80557 0.31862,14.40035 -2.5625,31.625 -5.56799,33.28792 -31.79272,123.1659 -43.6875,146.8125 -6.60491,13.1304 -18.02998,33.8957 -30.625,52.6563 -12.59502,18.7605 -27.35933,35.5338 -36,40.1874 -21.49052,11.5742 -48.7808,10.2602 -64.84375,2.8438 -14.37486,-6.637 -20.53812,-23.4494 -21.3125,-40 -0.38311,-8.188 0.61279,-21.3092 1.625,-34.4062 1.01221,-13.0971 11.28891,-22.5708 15.42339,-36.5626 5.37229,-18.1808 -1.44687,-36.5944 -12.5,-53.93745 -6.48655,-10.17778 -23.9768,-24.2579 -29.54839,-38.5625 -5.57159,-14.3046 -10.36751,-29.00315 -11.28125,-37.65625 -0.92621,-8.77113 0.4225,-23.02502 2.21875,-34.5 1.79625,-11.47497 3.84375,-20.28125 3.84375,-20.28125 l 9.42278,-3.6152 -10.48528,-3.8848 c 0,0 -8.49889,-15.3101 -8.09375,-34.8125 0.0711,-3.42316 1.83626,-12.72805 4.71875,-23.1875 2.88249,-10.45945 6.76466,-22.55271 10.625,-33.96875 3.04439,-9.00308 5.78063,-16.60345 8.34375,-23.6875 z"
- style="display:inline;opacity:0.58775509;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3898);enable-background:new"
- transform="translate(450.03125,73.843964)"
- inkscape:connector-curvature="0" />
- <g
- transform="translate(276,136)"
- clip-path="url(#clipPath3636)"
- id="g3628">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter9024);enable-background:accumulate"
- d="m 824.48651,818.48242 -49.49748,-15.55635 -26.87005,52.3259 41.01219,45.25484 49.49747,-38.18377 -14.14213,-43.84062 z"
- id="path8988"
- inkscape:connector-curvature="0" />
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter9020);enable-background:accumulate"
- d="m 964.49365,855.25197 -55.15433,-46.66904 -43.84062,36.76955 33.94113,53.74011 7.07106,66.46804 -50.91168,35.35537 -41.0122,11.3137 -2.82842,46.669 56.56854,25.4559 63.63961,-76.3676 24.04163,-94.75227 8.48528,-57.98276 z"
- id="path8990"
- inkscape:connector-curvature="0" />
- </g>
- <path
- id="path8992"
- d="m 1045.3322,1043.5779 60.8112,-26.8701 100.4091,31.1127 -63.6396,31.1127 -82.0244,-16.9706 -15.5563,-18.3847 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter9044);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- clip-path="url(#clipPath4177)"
- sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccczzzcccccc"
- id="path4149"
- d="m 583.0625,715.75 c -12.10609,34.44974 -26.7145,68.53333 -31.75,104.84375 -0.83208,14.92867 4.58915,29.15943 8.84375,43.0625 -5.91624,27.20126 -10.13681,56.89995 1.15625,83.125 13.51717,38.16085 35.00147,75.68215 32.42279,117.46825 -0.9483,29.2942 -9.01444,60.9941 5.38971,88.2817 10.19864,19.3348 33.13956,27.3117 53.96785,27.6676 27.86219,1.1741 56.46261,-11.6216 72.0009,-35.2613 22.59549,-29.3717 41.80051,-61.4973 55.23865,-96.0598 16.89053,-45.506 29.6718,-92.56072 37.93402,-140.3989 1.8244,-12.94106 3.10108,-27.46985 -4.57892,-38.82255 -3.43115,-7.33632 0.0421,-15.56014 -0.68457,-23.30977 0.674,-24.99466 4.01232,-50.66376 16.65332,-72.59648 -17.73313,6.4446 -35.07268,16.55971 -44.00307,33.86425 -3.93508,6.70955 -7.60482,13.57413 -11.37193,20.38575 -3.54999,-30.01408 3.71963,-59.64828 6.78125,-89.28125 -20.16604,9.05463 -36.87672,25.65522 -44.17495,46.682 -6.30463,15.58003 -8.80222,32.31718 -10.26255,49.03675 -8.25334,-1.51925 -16.68447,-2.10155 -25.0625,-1.5 -0.96308,-38.69787 -0.46696,-79.40715 10.96875,-115.90625 -18.68113,6.21776 -35.16621,18.73551 -45.62803,35.38723 -13.85254,20.87979 -21.2614,45.75395 -23.05947,70.61277 0.58534,4.32454 -0.0613,11.84009 -6.34375,9.875 -5.33118,0.0176 -10.62908,0.67883 -15.9375,1.09375 1.14784,-39.38148 -3.34144,-81.6282 -27.0625,-114.21875 -3.06071,-3.63717 -5.63685,-7.68438 -8.625,-11.34375 -0.9375,2.4375 -1.875,4.875 -2.8125,7.3125 z m 7.75,13.84375 c 18.56527,29.29629 22.4825,64.82012 22.125,98.875 0.20409,5.17526 -0.51656,11.8292 0.125,16.0625 12.31856,-6.10275 26.73912,-2.4399 39.78125,-2.1875 2.31712,1.22325 3.1921,1.65243 1.90625,-1.40625 -4.16455,-13.95285 -1.84828,-28.613 1.80504,-42.40764 6.36687,-26.29064 20.62828,-51.08798 42.81996,-67.02986 -8.61709,37.23706 -5.71658,76.56161 -6.09375,113.96875 12.25344,-6.9099 27.27879,-3.44613 40.03125,-0.25 3.39222,3.5348 2.28935,-0.72948 2.1875,-3.8125 -0.48309,-21.37058 4.13133,-43.06963 13.6875,-62.15625 5.96266,-10.68727 14.24338,-19.80379 22.4375,-28.875 -7.87156,33.8381 -9.2029,69.33593 -2.71875,103.5 1.72485,-1.41118 4.60681,-0.45414 5.65625,-0.375 9.68369,-21.23682 16.35112,-45.38062 34.89016,-60.74185 1.87329,-0.37122 -1.44818,8.52495 -1.48391,11.8981 -3.53488,21.84581 -3.2972,44.17323 -4.90625,66.25 -1.31238,1.37679 2.84835,2.32354 3.46875,4.0625 7.92311,10.5658 3.12294,24.83149 2.0916,36.78011 -7.06405,45.03355 -21.76553,88.37934 -35.57677,131.69714 -12.07476,32.9493 -30.7197,63.08 -51.23358,91.429 -10.95257,13.5514 -23.24472,27.8513 -40.84375,32.5 -20.15601,6.2413 -43.57595,5.1744 -61.96875,-5.6562 -17.28966,-12.3414 -21.02393,-35.7089 -19.26226,-55.6864 0.0488,-15.8262 2.37211,-27.8008 7.91747,-42.8053 5.54535,-15.0045 2.47105,-31.3317 -1.78021,-47.6333 -4.25126,-16.3016 -12.17903,-26.26002 -21.82158,-42.20417 -9.64255,-15.94415 -17.6369,-36.03734 -20.77217,-55.57713 -1.74948,-18.62714 2.89171,-37.12262 5.78125,-55.25 3.29623,-2.83696 -1.59799,-5.19659 -2.3125,-8.1875 -7.60113,-17.01508 -8.40747,-36.7749 -2.74234,-54.55998 7.1302,-25.0723 15.76087,-49.63241 24.67984,-74.12752 0.70833,1.30208 1.41667,2.60417 2.125,3.90625 z"
- style="display:inline;opacity:0.58775509;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4185);enable-background:new"
- transform="translate(450.03125,73.843964)"
- inkscape:connector-curvature="0" />
- <path
- transform="translate(276,136)"
- clip-path="url(#clipPath3631)"
- sodipodi:nodetypes="cccccccc"
- id="path3902"
- d="m 735.05635,733.03834 2.75542,21.08881 44.41103,-15.38821 4.85063,-22.38975 -3.93617,-22.05222 -22.45163,-36.59301 -8.28004,30.30494 -17.34924,45.02944 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter4130);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- transform="translate(276,136)"
- clip-path="url(#clipPath3631)"
- sodipodi:nodetypes="cccccccc"
- id="path4135"
- d="m 831.81321,730.29452 15.82237,14.90486 20.85473,2.89994 -1.59029,-39.92598 8.32561,-30.50842 -7.16499,-6.34106 -21.69669,20.9424 -14.55074,38.02826 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter4141);enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <g
- transform="translate(276,136)"
- clip-path="url(#clipPath8392)"
- style="filter:url(#filter8379)"
- id="g8367">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 910.14441,746.31415 32.61295,5.17393 -0.36119,-23.87619 7.18853,-29.68221 -8.45112,-5.26365 -21.82194,26.51077 -9.16723,27.13735 z"
- id="path4145"
- sodipodi:nodetypes="ccccccc"
- clip-path="none"
- inkscape:connector-curvature="0" />
- <rect
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="rect8365"
- width="123.03658"
- height="172.53406"
- x="877.51953"
- y="650.19098" />
- </g>
- <g
- transform="translate(276,136)"
- clip-path="url(#clipPath8417)"
- style="filter:url(#filter8404)"
- id="g8400">
- <path
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 964.00012,754.69487 18.42881,7.46479 9.07107,-36.96447 -14.87031,4.83886 -12.62957,24.66082 z"
- id="path4147"
- sodipodi:nodetypes="ccccc"
- clip-path="none"
- inkscape:connector-curvature="0" />
- <rect
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="rect8398"
- width="142.12846"
- height="125.1579"
- x="924.89569"
- y="677.06104" />
- </g>
+<?xml version="1.0" encoding="UTF-8"?>
+<svg enable-background="new" version="1" viewBox="0 0 4226.3 1686.8" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <pattern id="ig" xlink:href="#ka" patternTransform="matrix(5.4432 0 0 10.1 1722.4 161.06)"/>
+ <marker id="er" overflow="visible" orient="auto">
+ <path d="m-1.2 0l-1 1 3.5-1-3.5-1 1 1z" fill="#f8d615" fill-rule="evenodd" stroke="#f8d615" stroke-width=".2pt"/>
+ </marker>
+ <pattern id="ka" width="2" height="1" patternTransform="scale(10)" patternUnits="userSpaceOnUse">
+ <path d="M0-.5h1v2H0z" fill="#f815bb"/>
+ </pattern>
+ <filter id="ep" x="-.085" y="-.366" width="1.169" height="1.732">
+ <feGaussianBlur stdDeviation="4.574"/>
+ </filter>
+ <linearGradient id="n">
+ <stop stop-color="#fff" offset="0"/>
+ <stop stop-color="#fff" stop-opacity="0" offset="1"/>
+ </linearGradient>
+ <linearGradient id="j">
+ <stop stop-color="#f9eed3" offset="0"/>
+ <stop stop-opacity="0" offset="1"/>
+ </linearGradient>
+ <linearGradient id="s">
+ <stop stop-color="#283131" stop-opacity="0" offset="0"/>
+ <stop stop-color="#1e2424" offset=".5"/>
+ <stop offset="1"/>
+ </linearGradient>
+ <linearGradient id="u">
+ <stop stop-color="#cfc690" offset="0"/>
+ <stop stop-color="#afa775" offset=".212"/>
+ <stop stop-color="#615c3a" offset=".534"/>
+ <stop offset=".765"/>
+ <stop stop-color="#403518" offset="1"/>
+ </linearGradient>
+ <radialGradient id="jd" cx="418.3" cy="342.48" r="131.45" gradientTransform="matrix(1.3957 .62111 -.42441 .95372 -15.062 -227.97)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#283131" offset="0"/>
+ <stop stop-color="#1e2424" offset=".5"/>
+ <stop offset="1"/>
+ </radialGradient>
+ <filter id="iz" x="-.3" y="-.3" width="1.6" height="1.6">
+ <feGaussianBlur stdDeviation="2"/>
+ </filter>
+ <clipPath id="ea">
+ <path d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 12.61-67.045 3.214-93.929-9.434-26.993-34.967-59.124-66.429-69.643-31.033-10.375-65.018-4.848-84.286 5.714z" fill="#f5ff04" fill-rule="evenodd"/>
+ </clipPath>
+ <radialGradient id="iy" cx="275.44" cy="335.35" r="36.75" gradientTransform="matrix(.05911 2.687 -.72343 .01591 408.73 -424.56)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#fff" offset="0"/>
+ <stop stop-color="#fff" stop-opacity="0" offset="1"/>
+ </radialGradient>
+ <clipPath id="kb">
+ <path d="m265.94 126.68l-18.767 168.86 174.11-73.121 61.954 88.659 57.884-31.99-37.534-180.06-237.64 27.649z" fill-rule="evenodd" stroke="#000" stroke-width=".9"/>
+ </clipPath>
+ <clipPath id="jz">
+ <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
+ </clipPath>
+ <clipPath id="kd">
+ <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
+ </clipPath>
+ <clipPath id="jx">
+ <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
+ </clipPath>
+ <clipPath id="en">
+ <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
+ </clipPath>
+ <clipPath id="jw">
+ <path d="M821.64 477.89s22.619-6.507 35.743-5.873c13.123.634 30.642 1.939 43.709 12.186 13.067 10.248 25.068 27.14 34.112 58.37s1.698 99.252-6.176 143.35-28.265 106.11-45 140-49.798 77.495-60.569 89.876c-11.364 13.062-56.206 36.426-79.431 42.267 5.303-10.607 48.9-50.589 35-60.714-14.019-10.212-45.76 45.982-84.293 29.033 21.382-13.132 41.779-51.186 34.041-66.594-7.84-15.61-30.705 48.758-93.536 37.013 30.052-27.527 55.407-70.904 41.263-82.98-14.415-12.307-60.462 54.293-60.462 54.293s-2.822-41.7 13.773-68.607c16.639-26.978 79.653-81.615 99.553-111.7 19.9-30.088 33.613-66.009 42.135-92.518s15.801-77.1 15.801-77.1" enable-background="new" fill="#202020" fill-rule="evenodd" stroke="#000"/>
+ </clipPath>
+ <clipPath id="kp">
+ <path d="m366.89 504.13s-29.554 40.573-47.857 74.286-58.621 126.36-70.357 171.07c-11.759 44.803-62.5 123.57-62.5 123.57l76.071 18.214s11.807-12.823 31.071-46.071 60.357-138.57 60.357-138.57l13.214-202.5z" enable-background="accumulate" fill="#0f0f0f" fill-rule="evenodd" stroke="#000"/>
+ </clipPath>
+ <clipPath id="eo">
+ <path d="M569.03 1018.8c-4.286.714-27.628 3.618-57.857 10s-99.775 25.962-142.86 35.714-117.26 34.816-156.91 27.265c-39.648-7.55-89.516-64.408-89.516-64.408l4.286-94.286s85.886-16.201 112.14-33.571c26.257-17.37 45.582-49.666 59.286-71.429s32.857-71.429 32.857-71.429l238.57 262.14z" enable-background="accumulate" fill="#0b0b0b" fill-rule="evenodd" stroke="#000"/>
+ </clipPath>
+ <filter id="kc" x="-.353" y="-.182" width="1.706" height="1.363">
+ <feGaussianBlur stdDeviation="48.038"/>
+ </filter>
+ <filter id="jb" x="-.611" y="-.149" width="2.223" height="1.299">
+ <feGaussianBlur stdDeviation="37.83"/>
+ </filter>
+ <filter id="eg" x="-.235" y="-.245" width="1.47" height="1.49">
+ <feGaussianBlur stdDeviation="58.328"/>
+ </filter>
+ <filter id="jy" x="-.205" y="-.29" width="1.409" height="1.58">
+ <feGaussianBlur stdDeviation="22.3"/>
+ </filter>
+ <filter id="jv" x="-.344" y="-.184" width="1.688" height="1.369">
+ <feGaussianBlur stdDeviation="34.542"/>
+ </filter>
+ <filter id="kf" x="-.274" y="-.213" width="1.549" height="1.427">
+ <feGaussianBlur stdDeviation="11.314"/>
+ </filter>
+ <filter id="ja" x="-.259" y="-.224" width="1.518" height="1.447">
+ <feGaussianBlur stdDeviation="19.632"/>
+ </filter>
+ <filter id="kq" x="-.325" y="-.19" width="1.651" height="1.38">
+ <feGaussianBlur stdDeviation="28.713"/>
+ </filter>
+ <filter id="ko" x="-.381" y="-.175" width="1.762" height="1.35">
+ <feGaussianBlur stdDeviation="19.304"/>
+ </filter>
+ <filter id="kv" x="-.211" y="-.168" width="1.422" height="1.336">
+ <feGaussianBlur stdDeviation="8.369"/>
+ </filter>
+ <filter id="ks" x="-.187" y="-.236" width="1.374" height="1.473">
+ <feGaussianBlur stdDeviation="31.212"/>
+ </filter>
+ <clipPath id="ju">
+ <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
+ </clipPath>
+ <filter id="ki" x="-.252" y="-.053" width="1.503" height="1.106">
+ <feGaussianBlur stdDeviation="13.025"/>
+ </filter>
+ <linearGradient id="t" x1="603.84" x2="616.24" y1="627.85" y2="585.43" gradientTransform="translate(450.03 73.844)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#1a1a1a" offset="0"/>
+ <stop stop-color="#1a1a1a" stop-opacity="0" offset="1"/>
+ </linearGradient>
+ <filter id="dq" x="-.329" y="-.182" width="1.657" height="1.364">
+ <feGaussianBlur stdDeviation="20.913"/>
+ </filter>
+ <filter id="dr" x="-.555" y="-.514" width="2.109" height="2.029">
+ <feGaussianBlur stdDeviation="20.913"/>
+ </filter>
+ <filter id="cy" x="-.326" y="-.845" width="1.653" height="2.691">
+ <feGaussianBlur stdDeviation="21.92"/>
+ </filter>
+ <filter id="he" x="-.409" y="-.715" width="1.818" height="2.431">
+ <feGaussianBlur stdDeviation="21.92"/>
+ </filter>
+ <filter id="o">
+ <feGaussianBlur stdDeviation="8.881"/>
+ </filter>
+ <clipPath id="jt">
+ <path d="M647.61 540.05s22.619-6.507 35.743-5.873c13.123.634 30.642 1.939 43.709 12.186 13.067 10.248 25.068 27.14 34.112 58.37s1.698 99.252-6.176 143.35-28.265 106.11-45 140-49.798 77.495-60.569 89.876c-11.364 13.062-56.206 36.426-79.431 42.267 5.303-10.607 48.9-50.589 35-60.714-14.019-10.212-45.76 45.982-84.293 29.033 21.382-13.132 41.779-51.186 34.041-66.594-7.84-15.61-30.705 48.758-93.536 37.013 30.052-27.527 55.407-70.904 41.263-82.98-14.415-12.307-60.462 54.293-60.462 54.293s-2.822-41.7 13.773-68.607c16.639-26.978 79.653-81.615 99.553-111.7 19.9-30.088 33.613-66.009 42.135-92.518s15.801-77.1 15.801-77.1" enable-background="new" fill="#202020" fill-rule="evenodd"/>
+ </clipPath>
+ <filter id="je" x="-.277" y="-.325" width="1.554" height="1.65">
+ <feGaussianBlur stdDeviation="19.956"/>
+ </filter>
+ <clipPath id="e">
+ <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+ </clipPath>
+ <clipPath id="kr">
+ <path d="m366.89 504.13s-29.554 40.573-47.857 74.286-58.621 126.36-70.357 171.07c-11.759 44.803-62.5 123.57-62.5 123.57l76.071 18.214s11.807-12.823 31.071-46.071 60.357-138.57 60.357-138.57l13.214-202.5z" enable-background="accumulate" fill="#0f0f0f" fill-rule="evenodd"/>
+ </clipPath>
+ <clipPath id="am">
+ <path d="M586.13 997.99c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+ </clipPath>
+ <filter id="ds">
+ <feGaussianBlur stdDeviation="10.893"/>
+ </filter>
+ <filter id="bz" x="-.495" y="-.267" width="1.99" height="1.534">
+ <feGaussianBlur stdDeviation="10.731"/>
+ </filter>
+ <filter id="by" x="-.406" y="-.303" width="1.812" height="1.605">
+ <feGaussianBlur stdDeviation="9.859"/>
+ </filter>
+ <clipPath id="cj">
+ <path d="M586.13 997.99c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+ </clipPath>
+ <filter id="il">
+ <feGaussianBlur stdDeviation="3.616"/>
+ </filter>
+ <filter id="ir">
+ <feGaussianBlur stdDeviation="3.864"/>
+ </filter>
+ <clipPath id="ku">
+ <path d="M569.03 1018.8c-4.286.714-27.628 3.618-57.857 10s-57.314 4.966-135.79 17.33c-79.852 12.581-94.064 42.542-108.12 47.064-14.7 4.729-145.38-65.822-145.38-65.822l4.286-94.286s85.886-16.201 112.14-33.571c26.257-17.37 45.582-49.666 59.286-71.429s32.857-71.429 32.857-71.429l238.57 262.14z" enable-background="accumulate" fill="#292929" fill-rule="evenodd" stroke="#000"/>
+ </clipPath>
+ <linearGradient id="dt" x1="699.33" x2="698.98" y1="269.77" y2="346.14" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#fff" offset="0"/>
+ <stop offset="1"/>
+ </linearGradient>
+ <mask id="jc" maskUnits="userSpaceOnUse">
+ <ellipse transform="translate(-174.03 62.156)" cx="579.47" cy="260.58" rx="192.69" ry="164.05" enable-background="accumulate" fill="url(#dt)"/>
+ </mask>
+ <clipPath id="is">
+ <path d="m266.27 924.57c-1.407 18.801-1.145 32.751 2.082 49.303s16.406 45.907 20.334 63.184c3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.977-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.416-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+ </clipPath>
+ <clipPath id="im">
+ <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd" stroke="#000"/>
+ </clipPath>
+ <filter id="jq" x="-.088" y="-.177" width="1.176" height="1.355">
+ <feGaussianBlur stdDeviation="16.34"/>
+ </filter>
+ <filter id="i">
+ <feTurbulence baseFrequency=".24" numOctaves="10" result="result0" seed="655" type="fractalNoise"/>
+ <feDisplacementMap in="SourceGraphic" in2="result0" scale="62" xChannelSelector="B" yChannelSelector="G"/>
+ </filter>
+ <filter id="em">
+ <feGaussianBlur stdDeviation="2.04"/>
+ </filter>
+ <clipPath id="jo">
+ <path d="m709.29 844.51c54.286-1.429 126.04-15.052 170-26.786 44.053-11.757 125.89-36.347 175.36-57.857 49.339-21.453 113.6-59.282 154.29-92.143 40.508-32.721 52.39-55.82 60.714-33.571 8.37 22.368-16.407 56.326-37.857 81.071-21.604 24.923-52.731 52.705-98.929 89.286s-156.08 101.58-212.86 128.57c-57.066 27.125-128.2 58.238-172.14 72.5s-131.43 31.071-131.43 31.071l92.857-192.14z" enable-background="accumulate" fill="#121212" fill-rule="evenodd"/>
+ </clipPath>
+ <clipPath id="jp">
+ <path d="m709.29 844.51c54.286-1.429 126.04-15.052 170-26.786 44.053-11.757 125.89-36.347 175.36-57.857 49.339-21.453 113.6-59.282 154.29-92.143 40.508-32.721 52.39-55.82 60.714-33.571 8.37 22.368-16.407 56.326-37.857 81.071-21.604 24.923-52.731 52.705-98.929 89.286s-156.08 101.58-212.86 128.57c-57.066 27.125-128.2 58.238-172.14 72.5s-131.43 31.071-131.43 31.071l92.857-192.14z" enable-background="accumulate" fill="#121212" fill-rule="evenodd"/>
+ </clipPath>
+ <clipPath id="js">
+ <path d="m709.29 844.51c54.286-1.429 126.04-15.052 170-26.786 44.053-11.757 125.89-36.347 175.36-57.857 49.339-21.453 113.6-59.282 154.29-92.143 40.508-32.721 52.39-55.82 60.714-33.571 8.37 22.368-16.407 56.326-37.857 81.071-21.604 24.923-52.731 52.705-98.929 89.286s-156.08 101.58-212.86 128.57c-57.066 27.125-128.2 58.238-172.14 72.5s-131.43 31.071-131.43 31.071l92.857-192.14z" enable-background="accumulate" fill="#121212" fill-rule="evenodd"/>
+ </clipPath>
+ <clipPath id="ke">
+ <path d="M178.21 274.15c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd"/>
+ </clipPath>
+ <filter id="iv" x="-.243" y="-.391" width="1.487" height="1.782">
+ <feGaussianBlur stdDeviation="14.59"/>
+ </filter>
+ <filter id="iu" x="-.146" y="-.235" width="1.292" height="1.47">
+ <feGaussianBlur stdDeviation="4.444"/>
+ </filter>
+ <filter id="it">
+ <feGaussianBlur stdDeviation=".606"/>
+ </filter>
+ <filter id="ix">
+ <feGaussianBlur stdDeviation="6.589"/>
+ </filter>
+ <filter id="iw">
+ <feGaussianBlur stdDeviation="1.505"/>
+ </filter>
+ <filter id="jj" x="-.103" y="-.342" width="1.206" height="1.685">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="jf" x="-.098" y="-.198" width="1.197" height="1.395">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="jh" x="-.098" y="-.198" width="1.196" height="1.397">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="ji" x="-.099" y="-.226" width="1.198" height="1.453">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="hy" x="-.099" y="-.225" width="1.198" height="1.451">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="hu" x="-.105" y="-.405" width="1.209" height="1.809">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="hv" x="-.103" y="-.364" width="1.207" height="1.729">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="hw" x="-.102" y="-.324" width="1.204" height="1.647">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="hx" x="-.101" y="-.274" width="1.201" height="1.548">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="hz" x="-.098" y="-.209" width="1.197" height="1.417">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="ia" x="-.098" y="-.203" width="1.197" height="1.406">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="ib" x="-.098" y="-.198" width="1.196" height="1.397">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="jg">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="jk">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="hr" x="-.031" y="-.103" width="1.062" height="1.205">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="hq">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="hp">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="hn">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="hm">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="hl">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="hk">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="hj">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="hi">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="hh">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="hf" x="-.031" y="-.121" width="1.063" height="1.243">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="hg" x="-.031" y="-.109" width="1.062" height="1.219">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="hs">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="ho">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="ht">
+ <feGaussianBlur stdDeviation="1.723"/>
+ </filter>
+ <clipPath id="jl">
+ <path transform="translate(.08 -.031)" d="M1111.4-285.94l-3.937 1.875c-.041.01-.1.02-.125.031-.42.213-.165.1-.657.313-.486.21-1.737.584-4.093 1.469-3.332 1.25-5.805 2.15-7 3.062-1.537.021-3.72.233-5.657.719a227.677 227.677 0 0 1-6.75 1.594c-1.895.42-1.675.642-2.875.875-1.296.251-1.721-.01-5.437.78-3.49.743-8.895 1.932-10.156 2.688-1.584-.18-3.868-.321-5.844-.03-3.04.446-4.916.672-6.844.905-.655.08-1.04.201-1.344.282-.426.131-.685.26-1.375.343-1.311.16-1.762-.156-5.53.282-3.555.413-9.006 1.272-10.25 1.937-1.6-.297-3.859-.534-5.845-.344-3.058.294-4.972.484-6.906.657-1.934.172-1.688.422-2.906.53-1.316.119-1.76-.163-5.531.25-3.542.39-9.008 1.21-10.281 1.876-1.6-.295-3.887-.507-5.875-.313-3.059.3-4.941.48-6.875.657-.658.06-1.04.178-1.344.25-.428.119-.683.218-1.375.28-1.316.121-1.76-.194-5.531.22-3.556.39-9.006 1.239-10.25
+1.906-1.599-.294-3.86-.524-5.844-.313-3.056.326-4.974.527-6.906.719s-1.69.44-2.906.563c-1.315.131-1.763-.165-5.532.28-3.539.42-8.977 1.293-10.25 1.97-1.597-.281-3.86-.42-5.843-.188-3.052.358-4.945.568-6.875.781-.657.073-1.041.173-1.344.25-.427.128-.685.268-1.375.344-1.314.146-1.768-.174-5.531.313-3.55.458-8.979 1.419-10.22 2.125-1.593-.245-3.833-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.924.258-1.726.493-2.937.656-1.31.176-1.748-.104-5.5.469-3.525.538-8.924 1.699-10.188 2.437-1.588-.203-3.846-.254-5.813.094-3.026.536-4.899.862-6.812 1.188-.651.11-1.014.27-1.313.375-.42.164-.663.33-1.344.468-1.294.262-1.727-.006-5.437.813-3.499.772-8.846 2.383-10.062 3.219-1.563-.078-3.758.085-5.688.593-2.972.783-4.817 1.232-6.687 1.75s-1.667.768-2.844 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.93.928-4.75 1.459-6.594
+2.063-.626.205-.991.393-1.28.531-.408.214-.654.409-1.313.625-1.255.412-1.687.19-5.282 1.438-3.39 1.177-8.595 3.213-9.78 4.156-1.525.06-3.65.395-5.532 1.062-2.897 1.029-4.699 1.676-6.531 2.313-1.832.637-1.628.848-2.781 1.25-1.247.434-1.664.2-5.22 1.562-3.338 1.28-8.486 3.483-9.687 4.47-1.507.107-3.635.498-5.5 1.218a1047.26 1047.26 0 0 1-6.437 2.469c-.617.233-.997.442-1.281.594v.03l-8 3.188 1.812 14.72c-.258-.062 6.188 3.312 6.188 3.312.226-.145.449-.273.718-.375 1.08-.41 2.172-.216 6-1.688 3.829-1.471 5.224-2.005 5.907-2.406.68-.4 1.611-.88 2.218-1.531 1.827-.138 3.571-.493 4.938-1 2.968-1.1 4.875-1.806 6.781-2.469 1.906-.662 2.354-1.415 3.406-1.781 1.092-.38 2.195-.166 6.063-1.531 3.867-1.366 5.283-1.827 5.969-2.22.7-.4 1.7-.932 2.312-1.593 1.97-.055 3.817-.385 5.281-.875 3.002-1.005 4.927-1.622 6.844-2.25 1.539-.504 2.174-1.047 2.906-1.437.23-.135.476-.254.75-.344 1.099-.36 2.182-.082
+6.094-1.313 3.912-1.23 5.366-1.673 6.063-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.635-.267 5.03-.688 3.031-.913 4.993-1.43 6.938-1.968 1.945-.539 2.427-1.265 3.5-1.563 1.114-.31 2.22.007 6.188-1.031 3.967-1.039 5.417-1.433 6.125-1.75.735-.33 1.814-.754 2.437-1.375 1.998.116 3.858-.02 5.344-.375 3.078-.735 5.084-1.101 7.063-1.5 1.588-.32 2.244-.79 3-1.094a3.4 3.4 0 0 1 .75-.25c1.133-.23 2.304.209 6.343-.5 4.04-.709 5.5-.927 6.22-1.187.715-.26 1.704-.568 2.343-1.094 1.924.24 3.748.224 5.188 0 3.126-.488 5.154-.7 7.156-.969 2.001-.268 2.489-.945 3.594-1.094 1.146-.154 2.275.302 6.343-.219 4.068-.52 5.56-.695 6.282-.937.737-.247 1.798-.586 2.437-1.125 2.05.336 3.974.398 5.5.219 3.142-.37 5.18-.56 7.188-.782 1.61-.178 2.264-.608 3.03-.843.242-.086.495-.156.782-.188 1.15-.127 2.301.347 6.375-.125s5.559-.61 6.281-.844c.72-.232 1.7-.473 2.344-.968 1.936.333 3.77.404 5.219.25 3.146-.335
+5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.594-.938 1.151-.115 2.297.366 6.375-.062s5.589-.562 6.313-.781c.739-.224 1.795-.514 2.437-1.031 2.057.398 4.002.493 5.531.343 3.149-.308 5.176-.473 7.188-.656 1.614-.147 2.263-.56 3.031-.781.241-.081.494-.13.781-.156 1.152-.106 2.293.392 6.375 0s5.59-.531 6.313-.75c.72-.219 1.7-.448 2.343-.938 1.939.35 3.77.454 5.22.313 3.148-.309 5.175-.474 7.187-.657 2.011-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.588-.501 6.312-.719c.74-.222 1.796-.514 2.438-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.177-.523 7.187-.72 1.613-.156 2.266-.63 3.032-.874.24-.088.463-.122.75-.156 1.148-.14 2.316.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.312-1.093 1.92.212 3.72.151 5.157-.094 3.119-.533 5.111-.929 7.093-1.313 1.983-.383 2.475-1.04 3.563-1.28 1.129-.251 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.722-.376 1.762-.87
+2.375-1.531 1.963-.012 3.794-.291 5.219-.844 2.95-1.145 4.873-1.87 6.687-2.75 1.456-.706 2.32-1.702 2.531-2 .213-.298.1-.729.125-.75.043-.035.34-.094.5-.437.86-1.848 2.324-5.628 2.438-6.313.114-.682.168-1.353.219-1.75.029-.23-.147-.879-.125-.937.03-.082.288-.251.343-.5.267-1.199.09-2.208-.125-3.625-.213-1.418-.971-4.615-1.625-5.47-.658-.861-1.224-1.01-1.75-1z" enable-background="new" fill="#bcb786" fill-rule="evenodd"/>
+ </clipPath>
+ <filter id="kk" x="-.082" y="-.227" width="1.163" height="1.453">
+ <feGaussianBlur stdDeviation="2.437"/>
+ </filter>
+ <filter id="kj" x="-.041" y="-.113" width="1.082" height="1.227">
+ <feGaussianBlur stdDeviation="1.219"/>
+ </filter>
+ <clipPath id="kl">
+ <path d="M1049.2-282.27l-.09.008c-1.387.884-6.603 1.607-6.629 9.523-.024 7.426 15.013 17.091 17.156 18.094 1.73.81 3.592 1.41 5.406 1.72l1.438.218c1.92.212 3.72.151 5.156-.094 3.12-.532 5.112-.928 7.094-1.312 1.982-.384 2.474-1.04 3.562-1.281 1.129-.251 2.27.116 6.25-.875 3.98-.992 5.43-1.42 6.125-1.782.723-.376 1.762-.87 2.375-1.53 1.963-.013 3.794-.292 5.219-.845 2.951-1.144 4.873-1.869 6.688-2.75 1.455-.706 2.319-1.702 2.53-2 .213-.298.1-.728.126-.75.043-.035.34-.094.5-.437.859-1.847 2.323-5.628 2.437-6.313.114-.682.168-1.352.219-1.75.029-.23-.147-.879-.125-.937.031-.082.288-.25.344-.5.266-1.198.089-2.208-.125-3.625-.214-1.418-.972-4.615-1.625-5.469-.42-.548-.8-.792-1.157-.906-.067-.017-.123-.047-.187-.063-.021-.004-.042.003-.062 0-.312-.075-.609-.158-1.156-.218-.986-.109-2.425-.26-3.969-.25-.515.003-1.037.047-1.563.093-3.558.313-9.01.991-10.218
+1.625-1.634-.334-3.949-.612-5.938-.468-3.064.22-4.968.342-6.906.468-1.939.127-1.686.389-2.906.469-1.32.087-1.787-.223-5.563.094-3.546.297-8.98.993-10.22 1.625-1.632-.335-3.945-.613-5.937-.469-3.064.221-4.967.373-6.906.5-.659.043-1.042.124-1.344.187z" enable-background="new" fill="#bcb786" fill-rule="evenodd" opacity=".824"/>
+ </clipPath>
+ <filter id="km" x="-.022" width="1.044">
+ <feGaussianBlur stdDeviation=".575"/>
+ </filter>
+ <clipPath id="kn">
+ <path d="M205.47-408.97l-.09.002c-1.446.786-6.7 1.143-7.276 9.039-.542 7.405 13.786 18.096 15.854 19.245 1.67.927 3.484 1.655 5.273 2.09l1.419.32c1.9.344 3.7.41 5.15.265 3.149-.314 5.164-.57 7.168-.815 2.004-.245 2.54-.865 3.643-1.03 1.144-.172 2.257.274 6.296-.438s5.515-1.038 6.234-1.35c.747-.325 1.818-.746 2.476-1.362 1.96.124 3.805-.026 5.265-.479 3.024-.936 4.991-1.525 6.863-2.277 1.501-.603 2.432-1.536 2.664-1.819.233-.282.15-.72.177-.74.045-.032.346-.07.53-.4.985-1.784 2.709-5.453 2.87-6.128.162-.673.263-1.338.34-1.73.046-.228-.085-.888-.059-.945.037-.08.305-.23.378-.475.35-1.177.243-2.195.128-3.625-.115-1.429-.648-4.67-1.24-5.568-.38-.577-.742-.846-1.09-.985-.066-.022-.12-.055-.183-.075-.02-.005-.042 0-.063-.004-.305-.097-.596-.2-1.138-.299-.975-.176-2.4-.428-3.942-.526a19.346 19.346 0 0
+0-1.565-.015c-3.572.064-9.057.361-10.307.91-1.606-.448-3.896-.886-5.89-.882-3.072.007-4.98-.005-6.922-.013-1.943-.01-1.71.27-2.932.265-1.322-.005-1.767-.347-5.556-.294-3.558.05-9.028.365-10.307.91-1.606-.448-3.893-.887-5.89-.882-3.072.007-4.982.027-6.924.018-.661-.003-1.049.05-1.354.093z" enable-background="new" fill="#bcb786" fill-rule="evenodd" opacity=".824"/>
+ </clipPath>
+ <linearGradient id="w" x1="774.98" x2="755.12" y1="-211.87" y2="-202.68" gradientTransform="translate(-19.092 4.243)" gradientUnits="userSpaceOnUse" xlink:href="#n"/>
+ <mask id="jm" maskUnits="userSpaceOnUse">
+ <path d="m718.41-224.31l33.25 56 276-24 159.5-48.25-66.5-82.75-402.25 99z" fill="url(#w)" fill-rule="evenodd"/>
+ </mask>
+ <clipPath id="kg">
+ <path d="M734.03 519.49s16.755 37.018 28.701 53.954 52.727 56.046 52.727 56.046l.597-138.59" enable-background="accumulate" fill="#1a1a1a" fill-rule="evenodd" stroke="#000"/>
+ </clipPath>
+ <filter id="jn">
+ <feGaussianBlur stdDeviation="10.662"/>
+ </filter>
+ <filter id="ip">
+ <feGaussianBlur stdDeviation="7.18"/>
+ </filter>
+ <clipPath id="iq">
+ <path d="m266.27 924.57c-1.407 18.801-1.145 32.751 2.082 49.303 3.226 16.552 16.406 45.907 20.334 63.184 3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.978-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.417-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+ </clipPath>
+ <filter id="in">
+ <feGaussianBlur stdDeviation="6.82"/>
+ </filter>
+ <clipPath id="io">
+ <path d="m266.27 924.57c-1.407 18.801-1.145 32.751 2.082 49.303 3.226 16.552 16.406 45.907 20.334 63.184 3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.978-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.417-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+ </clipPath>
+ <filter id="ij" x="-.144" y="-.103" width="1.288" height="1.206">
+ <feGaussianBlur stdDeviation="7.389"/>
+ </filter>
+ <clipPath id="ik">
+ <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+ </clipPath>
+ <filter id="ih" x="-.09" y="-.103" width="1.181" height="1.205">
+ <feGaussianBlur stdDeviation="5.346"/>
+ </filter>
+ <clipPath id="ii">
+ <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+ </clipPath>
+ <clipPath id="gc">
+ <path d="M569.03 1018.8c-4.286.714-27.628 3.618-57.857 10s-99.775 25.962-142.86 35.714-117.26 34.816-156.91 27.265c-39.648-7.55-89.516-64.408-89.516-64.408l4.286-94.286s85.886-16.201 112.14-33.571c26.257-17.37 45.582-49.666 59.286-71.429s32.857-71.429 32.857-71.429l238.57 262.14z" enable-background="accumulate" fill="#0b0b0b" fill-rule="evenodd" stroke="#000"/>
+ </clipPath>
+ <filter id="gb" x="-.211" y="-.168" width="1.422" height="1.336">
+ <feGaussianBlur stdDeviation="8.369"/>
+ </filter>
+ <clipPath id="fz">
+ <path d="M205.47-408.97l-.09.002c-1.446.786-6.7 1.143-7.276 9.039-.542 7.405 13.786 18.096 15.854 19.245 1.67.927 3.484 1.655 5.273 2.09l1.419.32c1.9.344 3.7.41 5.15.265 3.149-.314 5.164-.57 7.168-.815 2.004-.245 2.54-.865 3.643-1.03 1.144-.172 2.257.274 6.296-.438s5.515-1.038 6.234-1.35c.747-.325 1.818-.746 2.476-1.362 1.96.124 3.805-.026 5.265-.479 3.024-.936 4.991-1.525 6.863-2.277 1.501-.603 2.432-1.536 2.664-1.819.233-.282.15-.72.177-.74.045-.032.346-.07.53-.4.985-1.784 2.709-5.453 2.87-6.128.162-.673.263-1.338.34-1.73.046-.228-.085-.888-.059-.945.037-.08.305-.23.378-.475.35-1.177.243-2.195.128-3.625-.115-1.429-.648-4.67-1.24-5.568-.38-.577-.742-.846-1.09-.985-.066-.022-.12-.055-.183-.075-.02-.005-.042 0-.063-.004-.305-.097-.596-.2-1.138-.299-.975-.176-2.4-.428-3.942-.526a19.346 19.346 0 0
+0-1.565-.015c-3.572.064-9.057.361-10.307.91-1.606-.448-3.896-.886-5.89-.882-3.072.007-4.98-.005-6.922-.013-1.943-.01-1.71.27-2.932.265-1.322-.005-1.767-.347-5.556-.294-3.558.05-9.028.365-10.307.91-1.606-.448-3.893-.887-5.89-.882-3.072.007-4.982.027-6.924.018-.661-.003-1.049.05-1.354.093z" enable-background="new" fill="#bcb786" fill-rule="evenodd" opacity=".824"/>
+ </clipPath>
+ <filter id="fy" x="-.022" width="1.044">
+ <feGaussianBlur stdDeviation=".575"/>
+ </filter>
+ <clipPath id="fx">
+ <path d="M1049.2-282.27l-.09.008c-1.387.884-6.603 1.607-6.629 9.523-.024 7.426 15.013 17.091 17.156 18.094 1.73.81 3.592 1.41 5.406 1.72l1.438.218c1.92.212 3.72.151 5.156-.094 3.12-.532 5.112-.928 7.094-1.312 1.982-.384 2.474-1.04 3.562-1.281 1.129-.251 2.27.116 6.25-.875 3.98-.992 5.43-1.42 6.125-1.782.723-.376 1.762-.87 2.375-1.53 1.963-.013 3.794-.292 5.219-.845 2.951-1.144 4.873-1.869 6.688-2.75 1.455-.706 2.319-1.702 2.53-2 .213-.298.1-.728.126-.75.043-.035.34-.094.5-.437.859-1.847 2.323-5.628 2.437-6.313.114-.682.168-1.352.219-1.75.029-.23-.147-.879-.125-.937.031-.082.288-.25.344-.5.266-1.198.089-2.208-.125-3.625-.214-1.418-.972-4.615-1.625-5.469-.42-.548-.8-.792-1.157-.906-.067-.017-.123-.047-.187-.063-.021-.004-.042.003-.062 0-.312-.075-.609-.158-1.156-.218-.986-.109-2.425-.26-3.969-.25-.515.003-1.037.047-1.563.093-3.558.313-9.01.991-10.218
+1.625-1.634-.334-3.949-.612-5.938-.468-3.064.22-4.968.342-6.906.468-1.939.127-1.686.389-2.906.469-1.32.087-1.787-.223-5.563.094-3.546.297-8.98.993-10.22 1.625-1.632-.335-3.945-.613-5.937-.469-3.064.221-4.967.373-6.906.5-.659.043-1.042.124-1.344.187z" enable-background="new" fill="#bcb786" fill-rule="evenodd" opacity=".824"/>
+ </clipPath>
+ <filter id="fw" x="-.082" y="-.227" width="1.163" height="1.453">
+ <feGaussianBlur stdDeviation="2.437"/>
+ </filter>
+ <filter id="fv" x="-.041" y="-.113" width="1.082" height="1.227">
+ <feGaussianBlur stdDeviation="1.219"/>
+ </filter>
+ <clipPath id="y">
+ <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
+ </clipPath>
+ <filter id="fu" x="-.252" y="-.053" width="1.503" height="1.106">
+ <feGaussianBlur stdDeviation="13.025"/>
+ </filter>
+ <clipPath id="fs">
+ <path d="M734.03 519.49s16.755 37.018 28.701 53.954 52.727 56.046 52.727 56.046l.597-138.59" enable-background="accumulate" fill="#1a1a1a" fill-rule="evenodd" stroke="#000"/>
+ </clipPath>
+ <filter id="fr" x="-.274" y="-.213" width="1.549" height="1.427">
+ <feGaussianBlur stdDeviation="11.314"/>
+ </filter>
+ <clipPath id="fq">
+ <path d="M178.21 274.15c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd"/>
+ </clipPath>
+ <filter id="aq">
+ <feGaussianBlur stdDeviation="2.04"/>
+ </filter>
+ <filter id="g">
+ <feTurbulence baseFrequency=".24" numOctaves="10" result="result0" seed="655" type="fractalNoise"/>
+ <feDisplacementMap in="SourceGraphic" in2="result0" scale="62" xChannelSelector="B" yChannelSelector="G"/>
+ </filter>
+ <clipPath id="fp">
+ <path d="M352.25 211.99c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.027 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#262f2f" fill-rule="evenodd" stroke="#000"/>
+ </clipPath>
+ <filter id="fo" x="-.353" y="-.182" width="1.706" height="1.363">
+ <feGaussianBlur stdDeviation="48.038"/>
+ </filter>
+ <clipPath id="fn">
+ <path d="m265.94 126.68l-18.767 168.86 174.11-73.121 61.954 88.659 57.884-31.99-37.534-180.06-237.64 27.649z" fill-rule="evenodd" stroke="#000" stroke-width=".9"/>
+ </clipPath>
+ <filter id="fm" x="-.277" y="-.325" width="1.554" height="1.65">
+ <feGaussianBlur stdDeviation="19.956"/>
+ </filter>
+ <mask id="fk" maskUnits="userSpaceOnUse">
+ <ellipse transform="translate(-174.03 62.156)" cx="579.47" cy="260.58" rx="192.69" ry="164.05" enable-background="accumulate" fill="url(#dt)"/>
+ </mask>
+ <filter id="fj" x="-.611" y="-.149" width="2.223" height="1.299">
+ <feGaussianBlur stdDeviation="37.83"/>
+ </filter>
+ <filter id="fi" x="-.259" y="-.224" width="1.518" height="1.447">
+ <feGaussianBlur stdDeviation="19.632"/>
+ </filter>
+ <filter id="fh" x="-.3" y="-.3" width="1.6" height="1.6">
+ <feGaussianBlur stdDeviation="2"/>
+ </filter>
+ <clipPath id="x">
+ <path d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 12.61-67.045 3.214-93.929-9.434-26.993-34.967-59.124-66.429-69.643-31.033-10.375-65.018-4.848-84.286 5.714z" fill="#f5ff04" fill-rule="evenodd"/>
+ </clipPath>
+ <filter id="hd">
+ <feGaussianBlur stdDeviation="6.589"/>
+ </filter>
+ <filter id="hc">
+ <feGaussianBlur stdDeviation="1.505"/>
+ </filter>
+ <filter id="hb" x="-.243" y="-.391" width="1.487" height="1.782">
+ <feGaussianBlur stdDeviation="14.59"/>
+ </filter>
+ <filter id="ha" x="-.146" y="-.235" width="1.292" height="1.47">
+ <feGaussianBlur stdDeviation="4.444"/>
+ </filter>
+ <filter id="gz">
+ <feGaussianBlur stdDeviation=".606"/>
+ </filter>
+ <clipPath id="if">
+ <path d="m709.29 844.51c54.286-1.429 126.04-15.052 170-26.786 44.053-11.757 125.89-36.347 175.36-57.857 49.339-21.453 113.6-59.282 154.29-92.143 40.508-32.721 52.39-55.82 60.714-33.571 8.37 22.368-16.407 56.326-37.857 81.071-21.604 24.923-52.731 52.705-98.929 89.286s-156.08 101.58-212.86 128.57c-57.066 27.125-128.2 58.238-172.14 72.5s-131.43 31.071-131.43 31.071l92.857-192.14z" enable-background="accumulate" fill="#121212" fill-rule="evenodd"/>
+ </clipPath>
+ <mask id="gy" maskUnits="userSpaceOnUse">
+ <path d="m718.41-224.31l33.25 56 276-24 159.5-48.25-66.5-82.75-402.25 99z" fill="url(#w)" fill-rule="evenodd"/>
+ </mask>
+ <clipPath id="gx">
+ <path transform="translate(.08 -.031)" d="M1111.4-285.94l-3.937 1.875c-.041.01-.1.02-.125.031-.42.213-.165.1-.657.313-.486.21-1.737.584-4.093 1.469-3.332 1.25-5.805 2.15-7 3.062-1.537.021-3.72.233-5.657.719a227.677 227.677 0 0 1-6.75 1.594c-1.895.42-1.675.642-2.875.875-1.296.251-1.721-.01-5.437.78-3.49.743-8.895 1.932-10.156 2.688-1.584-.18-3.868-.321-5.844-.03-3.04.446-4.916.672-6.844.905-.655.08-1.04.201-1.344.282-.426.131-.685.26-1.375.343-1.311.16-1.762-.156-5.53.282-3.555.413-9.006 1.272-10.25 1.937-1.6-.297-3.859-.534-5.845-.344-3.058.294-4.972.484-6.906.657-1.934.172-1.688.422-2.906.53-1.316.119-1.76-.163-5.531.25-3.542.39-9.008 1.21-10.281 1.876-1.6-.295-3.887-.507-5.875-.313-3.059.3-4.941.48-6.875.657-.658.06-1.04.178-1.344.25-.428.119-.683.218-1.375.28-1.316.121-1.76-.194-5.531.22-3.556.39-9.006 1.239-10.25
+1.906-1.599-.294-3.86-.524-5.844-.313-3.056.326-4.974.527-6.906.719s-1.69.44-2.906.563c-1.315.131-1.763-.165-5.532.28-3.539.42-8.977 1.293-10.25 1.97-1.597-.281-3.86-.42-5.843-.188-3.052.358-4.945.568-6.875.781-.657.073-1.041.173-1.344.25-.427.128-.685.268-1.375.344-1.314.146-1.768-.174-5.531.313-3.55.458-8.979 1.419-10.22 2.125-1.593-.245-3.833-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.924.258-1.726.493-2.937.656-1.31.176-1.748-.104-5.5.469-3.525.538-8.924 1.699-10.188 2.437-1.588-.203-3.846-.254-5.813.094-3.026.536-4.899.862-6.812 1.188-.651.11-1.014.27-1.313.375-.42.164-.663.33-1.344.468-1.294.262-1.727-.006-5.437.813-3.499.772-8.846 2.383-10.062 3.219-1.563-.078-3.758.085-5.688.593-2.972.783-4.817 1.232-6.687 1.75s-1.667.768-2.844 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.93.928-4.75 1.459-6.594
+2.063-.626.205-.991.393-1.28.531-.408.214-.654.409-1.313.625-1.255.412-1.687.19-5.282 1.438-3.39 1.177-8.595 3.213-9.78 4.156-1.525.06-3.65.395-5.532 1.062-2.897 1.029-4.699 1.676-6.531 2.313-1.832.637-1.628.848-2.781 1.25-1.247.434-1.664.2-5.22 1.562-3.338 1.28-8.486 3.483-9.687 4.47-1.507.107-3.635.498-5.5 1.218a1047.26 1047.26 0 0 1-6.437 2.469c-.617.233-.997.442-1.281.594v.03l-8 3.188 1.812 14.72c-.258-.062 6.188 3.312 6.188 3.312.226-.145.449-.273.718-.375 1.08-.41 2.172-.216 6-1.688 3.829-1.471 5.224-2.005 5.907-2.406.68-.4 1.611-.88 2.218-1.531 1.827-.138 3.571-.493 4.938-1 2.968-1.1 4.875-1.806 6.781-2.469 1.906-.662 2.354-1.415 3.406-1.781 1.092-.38 2.195-.166 6.063-1.531 3.867-1.366 5.283-1.827 5.969-2.22.7-.4 1.7-.932 2.312-1.593 1.97-.055 3.817-.385 5.281-.875 3.002-1.005 4.927-1.622 6.844-2.25 1.539-.504 2.174-1.047 2.906-1.437.23-.135.476-.254.75-.344 1.099-.36 2.182-.082
+6.094-1.313 3.912-1.23 5.366-1.673 6.063-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.635-.267 5.03-.688 3.031-.913 4.993-1.43 6.938-1.968 1.945-.539 2.427-1.265 3.5-1.563 1.114-.31 2.22.007 6.188-1.031 3.967-1.039 5.417-1.433 6.125-1.75.735-.33 1.814-.754 2.437-1.375 1.998.116 3.858-.02 5.344-.375 3.078-.735 5.084-1.101 7.063-1.5 1.588-.32 2.244-.79 3-1.094a3.4 3.4 0 0 1 .75-.25c1.133-.23 2.304.209 6.343-.5 4.04-.709 5.5-.927 6.22-1.187.715-.26 1.704-.568 2.343-1.094 1.924.24 3.748.224 5.188 0 3.126-.488 5.154-.7 7.156-.969 2.001-.268 2.489-.945 3.594-1.094 1.146-.154 2.275.302 6.343-.219 4.068-.52 5.56-.695 6.282-.937.737-.247 1.798-.586 2.437-1.125 2.05.336 3.974.398 5.5.219 3.142-.37 5.18-.56 7.188-.782 1.61-.178 2.264-.608 3.03-.843.242-.086.495-.156.782-.188 1.15-.127 2.301.347 6.375-.125s5.559-.61 6.281-.844c.72-.232 1.7-.473 2.344-.968 1.936.333 3.77.404 5.219.25 3.146-.335
+5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.594-.938 1.151-.115 2.297.366 6.375-.062s5.589-.562 6.313-.781c.739-.224 1.795-.514 2.437-1.031 2.057.398 4.002.493 5.531.343 3.149-.308 5.176-.473 7.188-.656 1.614-.147 2.263-.56 3.031-.781.241-.081.494-.13.781-.156 1.152-.106 2.293.392 6.375 0s5.59-.531 6.313-.75c.72-.219 1.7-.448 2.343-.938 1.939.35 3.77.454 5.22.313 3.148-.309 5.175-.474 7.187-.657 2.011-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.588-.501 6.312-.719c.74-.222 1.796-.514 2.438-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.177-.523 7.187-.72 1.613-.156 2.266-.63 3.032-.874.24-.088.463-.122.75-.156 1.148-.14 2.316.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.312-1.093 1.92.212 3.72.151 5.157-.094 3.119-.533 5.111-.929 7.093-1.313 1.983-.383 2.475-1.04 3.563-1.28 1.129-.251 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.722-.376 1.762-.87
+2.375-1.531 1.963-.012 3.794-.291 5.219-.844 2.95-1.145 4.873-1.87 6.687-2.75 1.456-.706 2.32-1.702 2.531-2 .213-.298.1-.729.125-.75.043-.035.34-.094.5-.437.86-1.848 2.324-5.628 2.438-6.313.114-.682.168-1.353.219-1.75.029-.23-.147-.879-.125-.937.03-.082.288-.251.343-.5.267-1.199.09-2.208-.125-3.625-.213-1.418-.971-4.615-1.625-5.47-.658-.861-1.224-1.01-1.75-1z" enable-background="new" fill="#bcb786" fill-rule="evenodd"/>
+ </clipPath>
+ <filter id="gw">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="gv" x="-.103" y="-.342" width="1.206" height="1.685">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="gu" x="-.099" y="-.226" width="1.198" height="1.453">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="gt" x="-.098" y="-.198" width="1.196" height="1.397">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="gs">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="gr" x="-.098" y="-.198" width="1.197" height="1.395">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="gq" x="-.098" y="-.198" width="1.196" height="1.397">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="gp" x="-.098" y="-.203" width="1.197" height="1.406">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="go" x="-.098" y="-.209" width="1.197" height="1.417">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="gn" x="-.099" y="-.225" width="1.198" height="1.451">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="gm" x="-.101" y="-.274" width="1.201" height="1.548">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="gl" x="-.102" y="-.324" width="1.204" height="1.647">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="gk" x="-.103" y="-.364" width="1.207" height="1.729">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="gj" x="-.105" y="-.405" width="1.209" height="1.809">
+ <feGaussianBlur stdDeviation="1.168"/>
+ </filter>
+ <filter id="gi">
+ <feGaussianBlur stdDeviation="1.723"/>
+ </filter>
+ <filter id="gh">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="gg" x="-.031" y="-.103" width="1.062" height="1.205">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="gf">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="ge">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="ff">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="fe">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="fd">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="fc">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="fb">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="fa">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="ez">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="ey">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="ex" x="-.031" y="-.109" width="1.062" height="1.219">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <filter id="ew" x="-.031" y="-.121" width="1.063" height="1.243">
+ <feGaussianBlur stdDeviation=".35"/>
+ </filter>
+ <clipPath id="ie">
+ <path d="m266.27 924.57c-1.407 18.801-1.145 32.751 2.082 49.303 3.226 16.552 16.406 45.907 20.334 63.184 3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.978-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.417-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+ </clipPath>
+ <filter id="id">
+ <feGaussianBlur stdDeviation="7.18"/>
+ </filter>
+ <clipPath id="ic">
+ <path d="m266.27 924.57c-1.407 18.801-1.145 32.751 2.082 49.303 3.226 16.552 16.406 45.907 20.334 63.184 3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.978-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.417-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+ </clipPath>
+ <filter id="gd">
+ <feGaussianBlur stdDeviation="6.82"/>
+ </filter>
+ <clipPath id="ev">
+ <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+ </clipPath>
+ <filter id="eu" x="-.144" y="-.103" width="1.288" height="1.206">
+ <feGaussianBlur stdDeviation="7.389"/>
+ </filter>
+ <clipPath id="et">
+ <path d="M760.16 935.83c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.974-97.309 13.624-27.084 38.76-114.5 44.66-149.77 5.9-35.27 2.551-41.3-4.617-49.055 2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-.714-.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.052 112.78-10.883.535-21.371-1.297-32.857 2.857.638-42.57-.261-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57s9.452 40.166 9.452 40.166-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.265 78.658z" enable-background="new" fill="#ada469" fill-rule="evenodd"/>
+ </clipPath>
+ <filter id="es" x="-.09" y="-.103" width="1.181" height="1.205">
+ <feGaussianBlur stdDeviation="5.346"/>
+ </filter>
+ <marker id="eq" overflow="visible" orient="auto">
+ <path d="m-1.2 0l-1 1 3.5-1-3.5-1 1 1z" fill="#f8d615" fill-rule="evenodd" stroke="#f8d615" stroke-width=".2pt"/>
+ </marker>
+ <radialGradient id="r" cx="142.96" cy="107.09" r="66.982" gradientTransform="matrix(-.33248 .90223 -.95824 -.35312 305.29 19.909)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#1e2323" offset="0"/>
+ <stop stop-color="#181d1d" offset=".56"/>
+ <stop offset="1"/>
+ </radialGradient>
+ <radialGradient id="q" cx="317.79" cy="129.65" r="47.863" gradientTransform="matrix(1.0036 0 0 1.6613 -160.53 -96.205)" gradientUnits="userSpaceOnUse" xlink:href="#u"/>
+ <radialGradient id="p" cx="325.31" cy="80.91" r="26.938" gradientTransform="matrix(2.0748 -.1578 .23824 3.1325 -550.77 -65.729)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#283131" stop-opacity="0" offset="0"/>
+ <stop stop-color="#1e2424" stop-opacity="0" offset=".513"/>
+ <stop offset="1"/>
+ </radialGradient>
+ <linearGradient id="kt" x1="347.9" x2="275.58" y1="1070.2" y2="867.98" gradientUnits="userSpaceOnUse">
+ <stop offset="0"/>
+ <stop offset=".022"/>
+ <stop offset=".759"/>
+ <stop stop-color="#232323" offset=".885"/>
+ <stop stop-color="#595959" offset="1"/>
+ </linearGradient>
+ <linearGradient id="kh" x1="603.84" x2="616.24" y1="627.85" y2="585.43" gradientTransform="translate(450.03 73.844)" gradientUnits="userSpaceOnUse" xlink:href="#t"/>
+ <linearGradient id="el" x1="609.31" x2="560.83" y1="239.47" y2="262.86" gradientTransform="translate(450.03 73.844)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#0a0c0c" offset="0"/>
+ <stop stop-color="#1f2727" stop-opacity="0" offset="1"/>
+ </linearGradient>
+ <radialGradient id="ek" cx="543.67" cy="147.31" r="47.863" gradientTransform="matrix(2.1382 0 0 2.3383 -77.038 -101.69)" gradientUnits="userSpaceOnUse" xlink:href="#u"/>
+ <radialGradient id="ef" cx="385" cy="237.01" r="86.929" gradientTransform="matrix(1 0 0 .8562 0 34.08)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#ada469" offset="0"/>
+ <stop stop-color="#ada469" offset=".811"/>
+ <stop stop-color="#fff" offset="1"/>
+ </radialGradient>
+ <linearGradient id="ee" x1="398.21" x2="379.29" y1="343.52" y2="265.31" gradientTransform="translate(450.03 73.844)" gradientUnits="userSpaceOnUse" xlink:href="#s"/>
+ <radialGradient id="ed" cx="397.16" cy="336.95" r="36.75" gradientTransform="translate(-375.32 -318.42) scale(1.945)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#344040" offset="0"/>
+ <stop stop-color="#222929" offset=".5"/>
+ <stop offset="1"/>
+ </radialGradient>
+ <radialGradient id="ec" cx="402.49" cy="317.24" r="23.714" gradientTransform="translate(-1358.3 -1070.7) scale(4.3777)" gradientUnits="userSpaceOnUse">
+ <stop offset="0"/>
+ <stop stop-color="#1d1d1d" offset="1"/>
+ </radialGradient>
+ <radialGradient id="eb" cx="250.23" cy="475.1" r="95.989" gradientTransform="matrix(1.2259 -.70777 .1414 .24491 322.22 608.92)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#d9e002" offset="0"/>
+ <stop stop-color="#a9ae01" offset=".5"/>
+ <stop stop-color="#717501" offset="1"/>
+ </radialGradient>
+ <radialGradient id="m" cx="228.81" cy="440.27" r="119.18" gradientTransform="matrix(1.1323 .76595 -1.455 2.151 588.75 -711.8)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#ff0" offset="0"/>
+ <stop stop-color="#b2b200" offset="1"/>
+ </radialGradient>
+ <radialGradient id="dz" cx="275.44" cy="335.35" r="36.75" gradientTransform="matrix(.05911 2.687 -.72343 .01591 408.73 -424.56)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#ff0" offset="0"/>
+ <stop stop-color="#ff0" stop-opacity="0" offset="1"/>
+ </radialGradient>
+ <linearGradient id="l" x1="182.35" x2="145.53" y1="256.11" y2="542.21" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#7d7d00" offset="0"/>
+ <stop stop-color="#c6c700" offset=".364"/>
+ <stop stop-color="#f6f800" offset="1"/>
+ </linearGradient>
+ <radialGradient id="dy" cx="296.34" cy="427.18" r="19.704" gradientTransform="translate(-599.29 -827.09) scale(2.9797)" gradientUnits="userSpaceOnUse">
+ <stop stop-opacity="0" offset="0"/>
+ <stop offset="1"/>
+ </radialGradient>
+ <radialGradient id="dx" cx="429.57" cy="377.43" r="72.08" gradientTransform="matrix(1 0 0 .61803 0 144.16)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#e2e2e2" offset="0"/>
+ <stop stop-color="#e2e2e2" stop-opacity="0" offset="1"/>
+ </radialGradient>
+ <radialGradient id="dw" cx="437.7" cy="391.22" r="36.612" gradientTransform="matrix(1 0 0 .61803 0 149.43)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#c7bd80" offset="0"/>
+ <stop stop-color="#c7bd80" stop-opacity="0" offset="1"/>
+ </radialGradient>
+ <linearGradient id="dv" x1="412.09" x2="417.38" y1="404.92" y2="401.83" gradientUnits="userSpaceOnUse" xlink:href="#j"/>
+ <linearGradient id="du" x1="411.91" x2="417.38" y1="404.92" y2="401.83" gradientUnits="userSpaceOnUse" xlink:href="#j"/>
+ <linearGradient id="ej" x1="411.91" x2="417.38" y1="405.54" y2="401.83" gradientUnits="userSpaceOnUse" xlink:href="#j"/>
+ <linearGradient id="ei" x1="412.09" x2="417.38" y1="405.54" y2="401.83" gradientUnits="userSpaceOnUse" xlink:href="#j"/>
+ <linearGradient id="eh" x1="411.73" x2="417.38" y1="405.54" y2="401.83" gradientUnits="userSpaceOnUse" xlink:href="#j"/>
+ <linearGradient id="jr" x1="1255.7" x2="893.7" y1="667.09" y2="858.01" gradientUnits="userSpaceOnUse" xlink:href="#n"/>
+ <linearGradient id="ft" x1="603.84" x2="616.24" y1="627.85" y2="585.43" gradientTransform="matrix(1.0057 0 0 2.3995 3424.4 -24.137)" gradientUnits="userSpaceOnUse" xlink:href="#t"/>
+ <radialGradient id="fl" cx="418.3" cy="342.48" r="131.45" gradientTransform="matrix(1.3957 .62111 -.42441 .95372 -15.062 -227.97)" gradientUnits="userSpaceOnUse" xlink:href="#s"/>
+ <radialGradient id="fg" cx="275.44" cy="335.35" r="36.75" gradientTransform="matrix(.05911 2.687 -.72343 .01591 408.73 -424.56)" gradientUnits="userSpaceOnUse" xlink:href="#n"/>
+ <clipPath id="ga">
+ <path d="M3492.3 296.46H3930v902.66h-437.7z" fill="#fff"/>
+ </clipPath>
+ </defs>
+ <g stroke-miterlimit="1">
+ <path d="M10.45 109.38h1876.7v1563H10.45z" enable-background="new" fill="#a8a8a8" stroke="#000" stroke-width="20.9"/>
+ <path d="M2337.1 111.42h1878.8v1565H2337.1z" enable-background="new" fill="none" stroke="#000" stroke-width="20.925"/>
+ <path d="M2358.4 132.96h1833.4v1522.9H2358.4z" enable-background="new" fill="#a8a8a8" stroke="#f83615" stroke-width="20.391"/>
+ </g>
+ <g fill-rule="evenodd">
+ <path transform="translate(-2833.5 -4370) scale(10.727)" d="M304.64 526.65c-10 .357-18.214 2.857-18.214 2.857l7.5 6.071 10.357 3.572 16.071.357 22.5-5.357 7.857 1.071 20.357-2.143-10.357 6.786c5.46-1.023 17.393 3.57 9.643 5.357-1.74.402 13.929-4.643 13.929-4.643l2.5-4.642 3.571-9.286h11.43l18.213-4.643 3.572-5-16.071 1.071-12.143 2.143-14.643-5-70.692 16.708-5.38-5.279z" enable-background="new" filter="url(#ep)" opacity=".5"/>
+ <g enable-background="new">
+ <path transform="matrix(.71084 -.19374 .26296 .96481 552.25 332.01)" d="m245.12 100.05s-47.128-31.647-67.215-35.801c-20.038-4.144-38.473-3.318-51.934 13.607s-12.077 61.265-13.536 86.97 2.55 70.177 17.605 88.666c15.055 18.488 45.886 13.585 49.927 21.414 2.213 4.287 65.152-174.86 65.152-174.86z" enable-background="accumulate" fill="url(#r)"/>
+ <path transform="matrix(.71084 -.19374 .26296 .96481 552.25 332.01)" d="M135.38 82.018s26.344 1.939 37.633 13.903c11.415 12.097 13.735 21.332 15.296 37.735 1.563 16.425-.85 28.418-7.814 36.037s-1.004 19.583-25.916 12.071-27.032-27.783-26.515-46.305c.517-18.529 7.316-53.441 7.316-53.441z" enable-background="accumulate" fill="url(#q)"/>
+ <path transform="matrix(.71084 -.19374 .26296 .96481 552.25 332.01)" d="M135.65 81.927s-4.645 16.365.588 28.563c5.488 12.793 27.224 44.26 27.224 54.656l22.656-5c2.542-6.966 3.21-15.752 2.188-26.5-1.562-16.403-3.867-25.621-15.281-37.719-9.655-10.232-31.593-13.375-37.375-14z" enable-background="new" fill="url(#p)"/>
+ </g>
+ <path d="m893.6 1350.3c-4.286 0.714-27.628 3.618-57.857 10s-57.314 4.966-135.79 17.33c-79.852 12.581-94.064 42.542-108.12 47.064-14.7 4.729-145.38-65.822-145.38-65.822l4.286-94.286s85.886-16.201 112.14-33.571c26.257-17.37 45.582-49.666 59.286-71.429s32.857-71.429 32.857-71.429l238.57 262.14z" enable-background="accumulate" stroke="#000"/>
+ <path transform="translate(324.57 331.53)" d="m332.34 898.39l-32.732-61.3-37.617 45.106c2.177 1.317 5.774-20.856 45.6-64.417l24.749 80.61z" clip-path="url(#eo)" enable-background="accumulate" fill="#fff" filter="url(#kv)" opacity=".5"/>
+ <path transform="translate(324.57 331.53)" d="m200.82 863.03l146.37-51.619 243.95 226.27-241.83 140.01-181.02-87.681 32.527-226.98z" clip-path="url(#ku)" enable-background="accumulate" fill="url(#kt)" filter="url(#ks)"/>
+ <path d="m691.46 835.66s-29.554 40.573-47.857 74.286-58.621 126.36-70.357 171.07c-11.759 44.803-62.5 123.57-62.5 123.57l76.071 18.214s11.807-12.823 31.071-46.071 60.357-138.57 60.357-138.57l13.214-202.5z" enable-background="accumulate" fill="#0f0f0f"/>
+ <path transform="translate(324.57 331.53)" d="m430.28 381.94c-7.071 2.828-236.18 32.152-236.18 32.152l-39.64 359.83 90.198 92.64 52.326-114.55 100.47-186.39 32.828-183.68z" clip-path="url(#kr)" enable-background="accumulate" fill="#fff" filter="url(#kq)" opacity=".4"/>
+ <path d="m1018.2 1359.5s23.256 11.394 36.068 20.476c12.697 9.001 29.472 24.649 41.692 37.36 12.306 12.8 20.113 22.599 41.533 24.161 21.432 1.563 53.282-8.788 73.296-24.664 20.014-15.877 45.647-69.233 45.647-69.233l-127.16-143.07" enable-background="accumulate" stroke="#000"/>
+ <path transform="translate(324.57 331.53)" d="M331.34 641.5L216.17 835.36l44.042 90.598 97.581-193.75-26.456-90.711z" clip-path="url(#kp)" enable-background="accumulate" filter="url(#ko)" opacity=".75"/>
+ <g enable-background="new">
+ <path d="M1113.913 623.101l-.09-.002c-1.48.72-6.744.842-7.674 8.704-.872 7.373 12.962 18.694 14.976 19.936 1.626 1.001 3.407 1.81 5.174 2.325l1.403.382c1.883.43 3.679.575 5.134.496 3.16-.173 5.184-.339 7.197-.493 2.013-.155 2.577-.75 3.686-.866 1.15-.12 2.242.375 6.309-.155 4.066-.53 5.556-.79 6.288-1.07.76-.29 1.85-.663 2.534-1.25 1.952.213 3.803.145 5.281-.241 3.063-.8 5.055-1.3 6.958-1.968 1.527-.536 2.499-1.426 2.744-1.698.245-.271.181-.712.21-.73.046-.03.348-.055.546-.378 1.065-1.737 2.951-5.325 3.143-5.993.191-.664.322-1.324.417-1.713.056-.225-.045-.89-.017-.946.04-.078.315-.216.399-.457.402-1.16.34-2.183.29-3.616-.05-1.433-.438-4.695-.99-5.618-.353-.593-.703-.88-1.044-1.033-.065-.025-.118-.06-.18-.083-.02-.007-.042-.002-.061-.007-.301-.111-.586-.228-1.124-.35-.966-.22-2.379-.535-3.914-.702a19.278 19.278 0 0
+0-1.563-.085c-3.571-.097-9.064-.045-10.338.446-1.584-.518-3.852-1.06-5.845-1.144-3.069-.13-4.974-.228-6.914-.324-1.94-.095-1.72.194-2.941.134-1.32-.065-1.75-.426-5.537-.543-3.556-.11-9.035-.04-10.338.447-1.584-.52-3.85-1.06-5.845-1.144-3.07-.131-4.978-.197-6.918-.293-.66-.032-1.05.004-1.356.033z" enable-background="new" fill="#bcb786"/>
+ <g transform="rotate(2.568 -22364 20373)" clip-path="url(#kn)" enable-background="new" filter="url(#km)">
+ <path d="M229.94-409.12c-3.558.05-9.024.36-10.303.904-1.606-.447-3.903-.881-5.9-.877a979.03 979.03 0 0 1-6.907 0c-.66-.003-1.048.068-1.353.11v1.096c.12-.18.393-.69.95-.767.747-.103 5.17-.151 7.31-.11 1.775.035 4.455.274 6.39.96.32.113.618.273.891.41 1.964.987 7.944 4.302 7.944 4.302s-6.633-3.948-7.483-4.439c-.203-.117-.575-.258-1.036-.41 1.22-.449 5.076-.62 7.828-.713 3.024-.102 3.348-.09 5.41.192 2.13.29 3.34.602 3.34.602s-.08-.64 1.035-.794c.748-.103 5.17-.152 7.31-.11 2.07.04 5.366.407 7.282 1.37 1.003.504 3.035 1.569 4.795 2.536l.096-.02s-3.58-2.162-4.43-2.653c-.204-.117-.575-.258-1.037-.411 1.22-.448 5.047-.62 7.8-.712 3.024-.102 3.347-.09 5.41.191 1.954.267 3.013.53 3.195.576l-.027-.312a8.503 8.503 0 0 0-1.4-.357c-1.301-.235-3.4-.602-5.51-.564-3.571.064-9.052.356-10.302.904-1.606-.447-3.877-.881-5.871-.877-3.072.007-4.994.01-6.936
+0-1.943-.009-1.713.28-2.936.274-1.322-.005-1.766-.354-5.555-.301M206.2-407.48c1.92.817 4.577 2.193 6.159 3.397s2.908 1.774 5.555 3.918c.885.718 1.748 1.35 2.591 1.922l.541-.19a57.511 57.511 0 0 1-2.269-1.622c-2.822-2.12-3.627-2.81-6.015-4.274s-4.1-2.366-6.562-3.15" enable-background="new"/>
+ <path d="M237.8-407.48c1.92.817 4.606 2.193 6.188 3.397.813.62 1.558 1.07 2.45 1.654l.65-.116a40.414 40.414 0 0 0-2.697-1.784c-2.389-1.465-4.128-2.366-6.59-3.151" enable-background="new"/>
+ </g>
+ <g transform="rotate(6.561 -6814.9 734.73)" clip-path="url(#kl)">
+ <path d="M1056.2-278.8c4.145-1.479 10 3.125 10 3.125.899.28 2.725-.894 2.624-1.686 0 0-1.55-1.86-.374-2.939s5.296 1.507 7.5 1.625 5.562-.23 7-.75 1.113-1.425 2.625-1.75 5.119 1.038 7.06 1.169 4.649.334 5.815-.169.178-1.16 1.875-1.875 7.76-.957 9.625-.125 1.81.52 2.625 3 7.44 5.163-1.125 13.375-59.378 13.786-65.625 2.75 6.23-14.271 10.375-15.75z" enable-background="new" filter="url(#kk)" opacity=".75"/>
+ <path d="M1058.5-275.43c4.145-1.479 10 3.125 10 3.125.899.28 2.725-.894 2.624-1.686 0 0-1.55-1.86-.374-2.939s5.296 1.507 7.5 1.625 5.562-.23 7-.75 1.113-1.425 2.625-1.75 5.119 1.038 7.06 1.169 4.649.334 5.815-.169.178-1.16 1.875-1.875 7.76-.957 9.625-.125 1.81.52 2.625 3 7.44 5.163-1.125 13.375-59.378 13.786-65.625 2.75 6.23-14.271 10.375-15.75z" enable-background="new" filter="url(#kj)" opacity=".75"/>
+ </g>
+ </g>
+ <path d="M676.821 543.52c-3.804-25.264-16.81-50.638-17.157-75.525-.186-13.356 3.273-26.571 13.756-39.554 36.347-65.296 116.94-84.695 185.93-91.465 86.922-11.017 184.91 17.94 233.37 95.401 54.124 75.733 56.675 172.54 80.612 259.53 29.438 127.13 54.779 256.21 60.392 386.85-3.063 78.182-8.426 165.18-60.503 228.13-48.026 50.357-122.79 50.053-187.07 59.002-90.555 4.655-184.35-16.146-261.78-64.198-64.776-37.94-95.73-113.48-97.279-186.02-8.39-79.875 26.392-153.81 51.62-227.16 7.47-82.761 9.413-166.25 9.653-249.38-.837-32.195-7.09-63.817-11.546-95.609z" enable-background="accumulate" fill="#101414"/>
+ <path transform="translate(324.57 331.53)" d="M311.83 415.43l9.9 121.62-60.105 136.47 15.556 174.66c15.613 61.879 32.185 98.669 74.376 117.05 4.32-36.24-38.612-142.96-39.243-189.12-.631-46.184 10.83-108.61 30.678-158.3 20.048-50.192 36.897-44.846 42.125-92.593s-17.426-149.39-17.426-149.39l-55.86 39.598z" clip-path="url(#en)" enable-background="accumulate" fill="#fff" filter="url(#ki)" opacity=".25"/>
+ <path transform="translate(48.571 195.53)" d="m1010 655.49s16.755 37.018 28.702 53.954c11.946 16.936 52.727 56.046 52.727 56.046l52.597-127.59" enable-background="accumulate" fill="url(#kh)"/>
+ <path transform="translate(324.57 331.53)" d="m730.32 536.57c0 8.485 42.548 58.468 42.548 58.468l12.607-28.77-55.154-29.698z" clip-path="url(#kg)" enable-background="accumulate" fill="#fff" filter="url(#kf)" opacity=".08"/>
+ </g>
+ <g transform="translate(498.6 269.37)" clip-path="url(#ke)" enable-background="new">
+ <g transform="translate(-174.03 62.156)" filter="url(#em)">
+ <g filter="url(#i)">
+ <path d="M425.88 476.99c10.805-1.479 24.744 3.354 44.643 3.214s57.453-16.91 82.143-17.143 62.752 12.284 79.286 15 22.848-.158 27.5 7.857 1.927 10.747-10.357 20.714-40.79 12.636-66.071 12.857c-25.282.221-70.381 7.079-95.357 3.93s-56.938-7.824-68.929-17.858-19.851-16.732-17.5-23.929 13.837-3.164 24.643-4.643z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+ <path d="M343.65 412.6h381.84v181.02H343.65z" enable-background="accumulate" fill="none"/>
+ </g>
+ <g filter="url(#i)">
+ <path d="m861.17 390.2c-10.462 9.714-86.98 19.005-100.71 29.286s-14.753 12.888-12.143 20 6.545 9.406 25.714 8.571 98.571-27.622 98.571-21.429l-11.429-36.429z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+ <path d="M702.86 344.82h207.89v162.63H702.86z" enable-background="accumulate" fill="none"/>
+ </g>
+ </g>
+ <g enable-background="new" opacity=".18">
+ <g transform="translate(-174.03 62.156)" filter="url(#i)">
+ <path d="M425.88 476.99c10.805-1.479 24.744 3.354 44.643 3.214s57.453-16.91 82.143-17.143 62.752 12.284 79.286 15 22.848-.158 27.5 7.857 1.927 10.747-10.357 20.714-40.79 12.636-66.071 12.857c-25.282.221-70.381 7.079-95.357 3.93s-56.938-7.824-68.929-17.858-19.851-16.732-17.5-23.929 13.837-3.164 24.643-4.643z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+ <path d="M343.65 412.6h381.84v181.02H343.65z" enable-background="accumulate" fill="none"/>
+ </g>
+ <g transform="translate(-174.03 62.156)" filter="url(#i)">
+ <path d="m861.17 390.2c-10.462 9.714-86.98 19.005-100.71 29.286s-14.753 12.888-12.143 20 6.545 9.406 25.714 8.571 98.571-27.622 98.571-21.429l-11.429-36.429z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+ <path d="M702.86 344.82h207.89v162.63H702.86z" enable-background="accumulate" fill="none"/>
+ </g>
+ </g>
+ </g>
+ <g transform="translate(48.571 195.53)" fill-rule="evenodd">
+ <path transform="translate(276 136)" d="m582.66-7.418l113.14 86.267 108.89 258.8 38.184 207.89 120.21 91.924s-12.728-287.09-19.799-313.96-149.91-393.15-149.91-393.15l-210.72 62.225z" clip-path="url(#kd)" enable-background="accumulate" filter="url(#kc)" opacity=".75"/>
+ <path d="m964.14 239.6s8.677 10.897 24.107 11.964c15.43 1.068 49.722-39.953 70.179-52.143 20.479-12.204 47.046-26.602 63.929-20.357 16.882 6.245 22.158 26.436 27.857 48.036 5.7 21.6 6.719 61.814-2.679 92.857-9.397 31.043-50.502 73.104-65.356 103.39s-11.607 39.821-11.607 39.821" enable-background="accumulate" fill="url(#el)"/>
+ <path d="m1124.5 207.63c-15.893-0.893-49.719 12.106-66.071 24.286-16.439 12.244-29.221 24.114-29.286 52.143-0.065 28.206 13.119 39.076 29.107 46.964s33.686 7.12 51.964-11.786c18.278-18.905 14.286-111.61 14.286-111.61z" enable-background="new" fill="url(#ek)"/>
+ <ellipse transform="matrix(.94347 -.12399 .14401 1.0958 451.95 134.6)" cx="385" cy="237.01" rx="86.429" ry="73.929" clip-path="url(#kb)" enable-background="accumulate" fill="url(#ef)" filter="url(#je)" opacity=".75"/>
+ <path transform="translate(450.03 73.844)" d="m527.61 407.45s-122.04 38.403-187.51 9.632c-65.473-28.772-74.377-124.72-74.377-124.72s73.382-80.504 129.92-83.615c55.827-3.072 90.574 20.143 114.87 65.852 24.352 45.813 17.101 132.85 17.101 132.85z" enable-background="accumulate" fill="url(#jd)" mask="url(#jc)"/>
+ <path d="m772.17 393.35s36.218-27.382 51.607-35.893c15.177-8.393 25.714-11.607 35.893-11.607l-15.536 66.964" enable-background="accumulate" fill="url(#ee)"/>
+ <circle transform="translate(449.5 74.915)" cx="409.29" cy="306.65" r="36.25" enable-background="accumulate" fill="url(#ed)"/>
+ <path transform="translate(276 136)" d="m311.83 415.43l9.9 121.62-60.105 136.47 15.556 174.66c15.613 61.879 32.185 98.669 74.376 117.05 4.32-36.24 8.682-72.368-31.243-223.12l17.678-69.296 72.125-138.59-42.426-158.39-55.86 39.598z" clip-path="url(#en)" enable-background="accumulate" fill="#fff" filter="url(#jb)" opacity=".3"/>
+ <path d="m635.21 581.13c-14.142 12.728 39.233 34.58 76.368 24.042s104.64-35.564 103.24-79.196c-1.407-43.632-76.368-128.69-76.368-128.69l-103.24 183.85z" enable-background="accumulate" filter="url(#ja)" opacity=".5"/>
+ <circle transform="translate(449.67 74.915)" cx="410" cy="306.65" r="23.214" enable-background="accumulate" fill="url(#ec)"/>
+ <circle transform="translate(452 73.487)" cx="414.29" cy="303.08" r="7.5" enable-background="accumulate" fill="#fff" filter="url(#iz)" stroke="#000" stroke-linejoin="bevel"/>
+ <path d="m789.32 478.35s7.023 19.569-1.071 35-42.323 38.988-67.5 50c-25.31 11.07-85.473 32.964-101.79 41.964-16.461 9.082-18.214 12.679-18.214 12.679s-7.147-19.064 28.75-51.786c36.172-32.972 142.03-48.05 159.82-87.857z" enable-background="accumulate" fill="url(#eb)"/>
+ </g>
+ <g enable-background="new">
+ <g transform="translate(829.32 270.09)" fill-rule="evenodd">
+ <path transform="translate(-329.81)" d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 8.206-79.647 3.214-93.929s-1.236-3.38-1.946-5.093c-10.689-25.816-34.214-54.43-64.483-64.55s-65.018-4.848-84.286 5.714z" clip-path="url(#ea)" fill="url(#m)"/>
+ <ellipse transform="rotate(28.068 -88.085 -332.1)" cx="183.57" cy="338.08" rx="64.716" ry="134.01" enable-background="accumulate" fill="url(#dz)"/>
+ <ellipse transform="rotate(28.068 -43.578 -333.81)" cx="183.57" cy="338.08" rx="64.716" ry="134.01" enable-background="accumulate" fill="url(#iy)"/>
+ </g>
+ <path transform="translate(499.51 270.09)" d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 8.206-79.647 3.214-93.929s-1.236-3.38-1.946-5.093c-10.689-25.816-34.214-54.43-64.483-64.55s-65.018-4.848-84.286 5.714z" clip-path="url(#ea)" enable-background="new" fill="none" filter="url(#ix)" stroke="url(#l)" stroke-width="20.8"/>
+ </g>
+ <g transform="translate(48.571 195.53)" fill-rule="evenodd">
+ <circle transform="translate(452.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" stroke="#000" stroke-linejoin="bevel"/>
+ <circle transform="translate(450.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" fill="url(#m)" filter="url(#iw)" stroke="url(#l)" stroke-width="20.8"/>
+ <circle transform="translate(450.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" fill="url(#dy)"/>
+ <ellipse transform="rotate(-4.471 1823.1 -5529.2)" cx="429.57" cy="377.43" rx="72.08" ry="44.548" enable-background="accumulate" fill="url(#dx)" filter="url(#iv)"/>
+ <ellipse transform="matrix(1.4358 -.07 .07 1.4358 235.18 -63.865)" cx="437.7" cy="391.22" rx="36.612" ry="22.627" enable-background="accumulate" fill="url(#dw)" filter="url(#iu)"/>
+ <g transform="translate(450.03 73.844)" enable-background="new" filter="url(#it)">
+ <circle cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#dv)"/>
+ <circle transform="translate(13.125 8.125)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#du)"/>
+ <circle transform="translate(32.946 7.5)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#ej)"/>
+ <circle transform="translate(24.911 -10.268)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#ei)"/>
+ <circle transform="translate(47.589 -.625)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#eh)"/>
+ </g>
+ </g>
+ <g fill="none" stroke="#000">
+ <path d="M944.771 678.46c.985 4.35 4.537 6.18 7.387 7.892 4.46 2.513 6.52 1.522 9.154-.758 1.602-1.921 10.683-4.698 15.594-7.07 4.33-1.46 8.904-5.36 13.385-8.335 3.395-1.627 5.347.355 7.829 1.01 2.944.717 4.411 2.172 6.06 3.536 2.397 1.175-.927 3.143 3.284 4.293 1.19.218 2.417.577 3.283-.505" enable-background="new"/>
+ <path d="M959.421 670.88c2.315-.032 3.178.643 5.493-.82 3.455-3.082 5.402-3.146 7.955-4.42 3.026-1.315 6.535 8.152 10.102 9.849 2.395-.822 1.289 1.794 1.452 2.651.057 2.647 2.807 3.679 4.356 5.43 3.316 2.256 7.375 6.296 11.112 5.303 6.445-2.93 10.28-1.281 16.29-7.386.703-1.182-.585-6.895 3.093-7.198 2.524.254 4.166.05 6.06.569 5.442 2.117 7.738 6.45 14.71 7.955 6.184.966 7.613 3.794 13.89 5.05M925.551 679.05c2.399-.794 6.106 4.192 8.173 7.046.593 2.68 1.154 5.486.758 12.122.785 2.417 2.68 3.03 4.798 3.283 3.117-.537 5.877-1.325 7.324-3.03 1.871-1.943 5.312 2.393 8.08 4.04 3.61 1.912 7.775 1.979 11.87 2.273 1.703-.231 2.37 4.515 3.283 8.08.384 4.379-.886 6.896-1.768 9.85-.294 2.496 2.988 3.53 6.313 4.545 3.183.742 6.545 1.662 9.092 1.768 5.142.875 8.088 2.69 12.122 4.04 2.239.817 3.26 2.243 4.545 3.536" enable-background="new"/>
+ </g>
+ <g fill-rule="evenodd">
+ <path transform="translate(324.57 331.53)" d="m332 187.7s57.5-25.5 57.5-28 5.5-52 5.5-52 91-48.5 91.5-50.5 86-62 86-62l-186 22-75.5 106z" clip-path="url(#jz)" enable-background="new" fill="#fff" filter="url(#jy)" opacity=".25"/>
+ <path d="m1745.9 918.08s-115.97 73.539-123.04 77.782c-7.071 4.243-230.52 137.18-230.52 137.18l4.243 39.598 216.37-100.41 117.38-101.82 15.556-52.326z" enable-background="accumulate" fill="#fff" opacity=".25"/>
+ <path transform="translate(324.57 331.53)" d="m528.92 556.85c-5.657-1.414-181.02 74.953-181.02 74.953l-33.941 181.02 51.095 193.95 257.2 67.681s206.48 152.74 212.13 148.49c5.657-4.243 168.29-193.75 168.29-193.75l-159.81-183.85-46.669-178.19-267.29-110.31z" clip-path="url(#jx)" enable-background="accumulate" filter="url(#eg)" opacity=".5"/>
+ <path d="m1146.2 809.42s22.62-6.507 35.743-5.873 30.642 1.939 43.709 12.186c13.067 10.248 25.068 27.14 34.112 58.37 9.045 31.23 1.698 99.252-6.176 143.35-7.874 44.095-28.265 106.11-45 140-16.735 33.887-49.798 77.495-60.57 89.876-11.363 13.062-56.205 36.426-79.43 42.267 5.303-10.607 48.9-50.589 35-60.714-14.02-10.212-45.76 45.982-84.293 29.033 21.382-13.132 41.779-51.186 34.04-66.594-7.84-15.61-30.704 48.758-93.535 37.013 30.052-27.527 55.407-70.904 41.263-82.98-14.415-12.307-60.462 54.293-60.462 54.293s-2.822-41.7 13.773-68.607c16.639-26.978 79.653-81.615 99.553-111.7 19.9-30.088 33.613-66.009 42.136-92.518s15.8-77.1 15.8-77.1" enable-background="new" fill="#0c0c0c"/>
+ <path transform="translate(324.57 331.53)" d="m770.75 609.18l-50.912 97.581-79.903 111.02 34.648 71.418 42.426 79.196 72.125-45.255 14.142-192.33 21.213-138.59-14.142-90.156-39.598 107.13z" clip-path="url(#jw)" enable-background="accumulate" fill="#fff" filter="url(#jv)" opacity=".25"/>
+ <path transform="translate(324.57 331.53)" d="m295 846.2l6.645-68.923s90.32 89.005 162.36 122.92 308 62 308 62l154-26-36 162-286 26-298-89-11-189z" clip-path="url(#ju)" enable-background="accumulate" filter="url(#eg)"/>
+ <path transform="translate(498.6 269.37)" d="m405.8 845.99l74.953 65.054 2.5 16.88 19.403 10.159 6.492 23.051 31.709-8.371 14.849 48.083c12.257 12.728 89.793-113.11 55.86 38.184l-60.81 16.264-89.203-94.693-62.825-53.8 7.07-60.811z" clip-path="url(#jt)" enable-background="new" fill="#fff" filter="url(#o)"/>
+ <path d="m1207.9 1113.9c54.286-1.429 126.04-15.052 170-26.786 44.053-11.757 125.89-36.347 175.36-57.857 49.339-21.453 113.6-59.282 154.29-92.143 40.508-32.721 52.39-55.82 60.714-33.571 8.37 22.368-16.407 56.326-37.857 81.071-21.604 24.923-52.731 52.705-98.929 89.286s-156.08 101.58-212.86 128.57c-57.066 27.125-128.2 58.238-172.14 72.5s-131.43 31.071-131.43 31.071l92.857-192.14z" enable-background="accumulate" fill="#121212"/>
+ <path transform="translate(498.6 269.37)" d="m1241.6 652.95s-64.722 54.337-145.66 98.995c-82.024 45.255-284.26 93.338-284.26 93.338s-15.101 21.052 45.255 28.284 224.08-53.301 278.6-96.167 120.21-111.72 120.21-111.72l-14.142-12.728z" clip-path="url(#js)" enable-background="accumulate" fill="url(#jr)" filter="url(#jq)" opacity=".5"/>
+ </g>
+ <g transform="translate(498.6 269.37)" clip-path="url(#jp)" enable-background="new">
+ <g filter="url(#em)">
+ <g transform="translate(-174.03 62.156)" filter="url(#i)">
+ <path d="m1268.3 663.77s-0.296 26.161 4.643 37.857 20.038 26.487 28.572 31.429 18.929 8.571 18.929 8.571l117.86-115 17.857-75.714-96.43 38.571-91.428 74.286z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+ <path d="M1197.8 486.14h333.75v309.71H1197.8z" enable-background="accumulate" fill="none"/>
+ </g>
+ </g>
+ <g transform="translate(-174.03 62.156)" enable-background="new" filter="url(#i)" opacity=".18">
+ <path d="m1268.3 663.77s-0.296 26.161 4.643 37.857 20.038 26.487 28.572 31.429 18.929 8.571 18.929 8.571l117.86-115 17.857-75.714-96.43 38.571-91.428 74.286z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+ <path d="M1197.8 486.14h333.75v309.71H1197.8z" enable-background="accumulate" fill="none"/>
+ </g>
+ </g>
+ <path transform="translate(498.6 269.37)" d="M1264.2 605c-4.491.733-8.157 3.455-11.938 6.406-10.081 7.87-28.17 34.425-48.031 50.47-39.867 32.202-104 69.976-152.56 91.093-48.614 21.137-130.54 45.818-174.31 57.5-43.398 11.582-115.04 25.131-168.25 26.531l-4.562.125-2 4.125-92.844 192.12-6.5 13.47 14.656-2.845s87.27-16.65 132.34-31.28c44.725-14.518 115.79-45.668 173.03-72.876 57.603-27.38 166.94-91.98 214.28-129.47 46.36-36.71 77.805-64.717 99.938-90.25 10.9-12.576 22.745-27.53 31.03-42.75 8.287-15.219 19.16-44.218 13.688-58.844-1.218-3.254-2.552-6.06-4.594-8.5s-8.475-1.572-8.563-5.03c-.21-8.266-3.315-.245-4.812 0zm2.156 15.219c.415.586 1.031 1.558 1.782 3.563 2.896 7.742-1.441 31.899-8.813 45.438s-22.638 28.924-33.188 41.094c-21.075 24.314-51.904 51.862-97.938 88.312-45.05 35.672-155.46 101.09-211.41 127.69-56.892 27.042-128.1 58.118-171.25 72.125-36.365 11.803-95.845 23.834-115.72
+27.78l84.281-174.47c54.707-2.049 123.79-15.215 167.12-26.78 44.334-11.832 126.08-36.336 176.41-58.22 50.112-21.788 112.53-61.167 154.03-94.687 20.646-16.677 41.745-42.546 49.813-48.844 2.437-1.903 4.08-2.636 4.875-3z" clip-path="url(#jo)" enable-background="accumulate" fill="#050505" fill-rule="evenodd" filter="url(#jn)" opacity=".833"/>
+ <g transform="rotate(6.561 -6814.9 734.74)" enable-background="new" fill-rule="evenodd" mask="url(#jm)">
+ <path d="M1111.48-285.971l-3.937 1.875c-.041.01-.1.02-.125.031-.42.213-.165.1-.657.312-.486.21-1.737.585-4.093 1.47-3.332 1.25-5.805 2.15-7 3.062-1.537.021-3.72.233-5.657.719a227.677 227.677 0 0 1-6.75 1.593c-1.894.42-1.675.642-2.875.875-1.296.252-1.721-.009-5.437.782-3.49.742-8.895 1.93-10.156 2.687-1.584-.18-3.868-.322-5.844-.031-3.04.447-4.916.673-6.844.906-.655.08-1.04.2-1.343.281-.427.132-.686.26-1.375.344-1.312.16-1.763-.157-5.532.281-3.554.413-9.005 1.273-10.25 1.938-1.599-.297-3.857-.534-5.843-.344-3.06.293-4.972.484-6.907.656-1.934.173-1.688.423-2.906.532-1.316.117-1.76-.164-5.531.25-3.542.388-9.008 1.209-10.281 1.875-1.6-.295-3.887-.507-5.875-.313-3.058.3-4.941.48-6.875.656-.658.06-1.04.179-1.344.25-.428.12-.683.218-1.375.282-1.316.12-1.76-.195-5.531.218-3.556.39-9.006 1.24-10.25
+1.907-1.599-.295-3.86-.524-5.844-.313-3.056.325-4.974.526-6.906.719s-1.69.44-2.906.562c-1.315.132-1.763-.164-5.532.282-3.538.418-8.977 1.292-10.25 1.968-1.597-.28-3.86-.42-5.843-.187-3.052.358-4.945.568-6.875.781-.657.073-1.041.173-1.344.25-.427.127-.685.267-1.375.344-1.314.146-1.768-.174-5.531.312-3.55.46-8.979 1.42-10.22 2.125-1.592-.244-3.833-.381-5.812-.125-3.047.395-4.95.649-6.875.907-1.924.257-1.726.493-2.937.656-1.31.176-1.748-.105-5.5.469-3.525.538-8.924 1.699-10.188 2.437-1.588-.203-3.846-.255-5.813.094-3.026.536-4.899.861-6.812 1.187-.65.111-1.014.271-1.313.375-.42.165-.663.332-1.344.469-1.294.262-1.727-.006-5.437.813-3.499.771-8.846 2.382-10.062 3.218-1.563-.077-3.758.086-5.688.594-2.972.783-4.817 1.232-6.687 1.75s-1.667.767-2.844 1.094c-1.272.353-1.697.107-5.344 1.187-3.424 1.015-8.65 2.934-9.875 3.844-1.539.013-3.72.272-5.625.875-2.93.928-4.75 1.459-6.594
+2.063-.626.205-.991.392-1.28.53-.408.215-.654.41-1.313.626-1.255.411-1.686.189-5.281 1.437-3.39 1.178-8.595 3.214-9.782 4.157-1.524.06-3.65.395-5.53 1.062-2.898 1.028-4.7 1.676-6.532 2.313-1.832.637-1.628.848-2.781 1.25-1.247.434-1.664.2-5.22 1.562-3.338 1.28-8.486 3.483-9.687 4.469-1.507.108-3.635.499-5.5 1.219a1047.26 1047.26 0 0 1-6.437 2.469c-.617.233-.997.442-1.281.593v.031l-8 3.188-12.476 3.492 7.93 19.278c-.592 1.973 12.545-4.739 12.545-4.739.227-.144.45-.272.72-.375 1.08-.41 2.17-.215 6-1.687 3.828-1.472 5.223-2.005 5.905-2.406.68-.4 1.612-.88 2.22-1.531 1.826-.138 3.57-.494 4.937-1 2.968-1.1 4.875-1.807 6.78-2.47 1.907-.662 2.355-1.414 3.407-1.78 1.092-.38 2.195-.166 6.063-1.532 3.867-1.366 5.283-1.827 5.968-2.218.702-.4 1.701-.933 2.313-1.594 1.97-.055 3.817-.385 5.281-.875 3.002-1.005 4.926-1.622 6.844-2.25 1.538-.504 2.174-1.047 2.906-1.438.23-.134.476-.253.75-.343 1.098-.36
+2.181-.082 6.094-1.313 3.912-1.231 5.366-1.673 6.062-2.031.694-.357 1.63-.793 2.25-1.406 1.866-.023 3.636-.267 5.032-.688 3.03-.913 4.992-1.43 6.937-1.969 1.945-.538 2.426-1.264 3.5-1.562 1.114-.31 2.22.007 6.188-1.031 3.967-1.039 5.417-1.433 6.125-1.75.734-.33 1.813-.754 2.437-1.375 1.998.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101 7.062-1.5 1.588-.32 2.245-.79 3-1.094a3.4 3.4 0 0 1 .75-.25c1.134-.23 2.305.209 6.344-.5 4.04-.71 5.5-.927 6.219-1.188.716-.26 1.704-.567 2.344-1.093 1.924.239 3.748.224 5.187 0 3.127-.488 5.155-.701 7.156-.97 2.002-.267 2.49-.944 3.594-1.093 1.147-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.281-.937.737-.247 1.798-.586 2.438-1.125 2.05.335 3.973.398 5.5.218 3.142-.368 5.18-.559 7.187-.78 1.611-.179 2.265-.609 3.031-.845.241-.085.495-.155.782-.187 1.15-.128 2.301.347 6.375-.125s5.559-.61 6.28-.844c.72-.232 1.701-.473 2.345-.969 1.936.334 3.77.405
+5.219.25 3.146-.334 5.177-.518 7.187-.718 2.01-.2 2.484-.827 3.594-.938 1.15-.115 2.296.365 6.375-.062s5.589-.562 6.312-.782c.74-.223 1.796-.513 2.438-1.03 2.057.398 4.002.493 5.531.343 3.149-.308 5.176-.473 7.188-.656 1.614-.147 2.263-.56 3.03-.781.242-.081.494-.13.782-.157 1.152-.105 2.293.393 6.375 0s5.589-.53 6.312-.75c.721-.218 1.7-.447 2.344-.937 1.938.35 3.769.454 5.219.312 3.149-.308 5.176-.473 7.187-.656 2.012-.183 2.515-.838 3.625-.937 1.153-.104 2.293.384 6.375 0 4.083-.385 5.59-.501 6.313-.72.74-.222 1.796-.514 2.437-1.03 2.058.401 4.003.503 5.532.343 3.146-.328 5.177-.522 7.187-.718 1.613-.158 2.266-.632 3.031-.875.241-.088.464-.122.75-.157 1.149-.14 2.317.34 6.375-.25 4.059-.59 5.562-.777 6.282-1.03.716-.254 1.674-.559 2.312-1.095 1.92.212 3.72.152 5.156-.093 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.563-1.281 1.128-.25 2.27.116 6.25-.875s5.43-1.42
+6.125-1.781c.722-.376 1.761-.87 2.375-1.531 1.963-.012 3.793-.292 5.218-.844 2.952-1.145 4.874-1.87 6.688-2.75 1.456-.707 2.32-1.702 2.531-2 .212-.298.1-.729.125-.75.043-.035.34-.094.5-.438.86-1.847 2.323-5.627 2.438-6.312.113-.682.168-1.353.218-1.75.03-.23-.147-.88-.125-.938.031-.082.289-.25.344-.5.266-1.198.09-2.207-.125-3.625-.214-1.417-.972-4.614-1.625-5.469-.659-.861-1.225-1.01-1.75-1z" enable-background="new" fill="#bcb786"/>
+ <g clip-path="url(#jl)">
+ <path d="M1107.4-284.05c-.419.213-.156.094-.647.306-.486.21-1.724.574-4.08 1.459-3.33 1.25-5.83 2.153-7.026 3.066-1.536.021-3.72.233-5.656.719a227.709 227.709 0 0 1-6.75 1.593c-1.895.42-1.676.643-2.875.875-1.297.252-1.721-.009-5.438.782-3.49.742-8.894 1.93-10.156 2.687-1.583-.18-3.867-.322-5.843-.031-3.04.447-4.917.673-6.844.906-.655.08-1.041.201-1.344.282-.426.131-.686.26-1.375.343-1.311.16-1.762-.157-5.531.282-3.554.413-9.005 1.272-10.25 1.937-1.599-.297-3.858-.534-5.844-.344-3.059.294-4.972.484-6.906.657-1.934.172-1.689.422-2.906.53-1.317.118-1.76-.163-5.532.25-3.541.39-9.007 1.21-10.28 1.876-1.6-.295-3.888-.507-5.876-.313-3.058.3-4.94.48-6.875.657-.657.06-1.04.178-1.343.25-.428.118-.684.218-1.375.28-1.316.121-1.76-.194-5.532.22-3.556.39-9.005 1.239-10.25
+1.906-1.598-.294-3.86-.524-5.843-.313-3.056.326-4.974.526-6.907.719-1.932.192-1.69.44-2.906.562-1.315.132-1.763-.164-5.53.282-3.54.418-8.979 1.292-10.25 1.969-1.599-.282-3.86-.42-5.845-.188-3.052.358-4.945.568-6.875.781-.656.073-1.04.173-1.344.25-.426.127-.684.267-1.375.344-1.313.146-1.767-.174-5.53.313-3.55.458-8.98 1.419-10.22 2.125-1.593-.245-3.834-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.925.258-1.726.493-2.938.656-1.31.176-1.747-.104-5.5.469-3.524.538-8.923 1.699-10.188 2.437-1.587-.203-3.845-.254-5.812.094-3.026.536-4.9.862-6.813 1.187-.65.111-1.013.271-1.312.375-.42.165-.664.332-1.344.47-1.295.26-1.727-.007-5.438.812-3.498.772-8.846 2.383-10.062 3.219-1.562-.078-3.757.085-5.687.593-2.972.783-4.818 1.232-6.688 1.75s-1.666.768-2.843 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.931.928-4.75 1.459-6.594
+2.063-.627.205-.992.392-1.281.531-.408.214-.653.409-1.313.625-1.254.412-1.686.19-5.28 1.438-3.39 1.177-8.596 3.213-9.782 4.156-1.524.06-3.65.395-5.531 1.062-2.898 1.029-4.7 1.676-6.531 2.313-1.833.637-1.628.848-2.782 1.25-1.246.434-1.663.2-5.218 1.562-3.34 1.28-8.488 3.483-9.688 4.47-1.507.107-3.636.498-5.5 1.218a1044.752 1044.752 0 0 1-6.437 2.469c-.617.233-.997.442-1.282.593v1.094c.112-.222.386-.817.907-1.094.698-.37 4.813-1.993 6.812-2.718 1.657-.602 4.154-1.329 5.969-1.313.302.003.588.051.844.094 1.842.308 7.468 1.562 7.468 1.562s-6.233-1.646-7.03-1.843c-.191-.048-.536-.07-.97-.063 1.146-.87 4.762-2.393 7.344-3.437 2.839-1.148 3.117-1.252 5.063-1.657 2.008-.417 3.156-.5 3.156-.5s-.082-.6.969-1.125c.705-.351 4.887-1.892 6.906-2.562 1.952-.648 5.057-1.359 6.875-1 1.863.367 7.531 1.812 7.531 1.812s-6.287-1.87-7.094-2.093c-.193-.054-.53-.086-.968-.094 1.158-.833 4.794-2.195 7.406-3.156
+2.87-1.056 3.167-1.162 5.125-1.532 1.853-.35 2.859-.425 3.031-.437.114-.217.377-.81.906-1.063.71-.338 4.926-1.712 6.97-2.312 1.692-.497 4.24-1.037 6.093-.906.308.021.613.097.875.156 1.881.424 7.594 2.031 7.594 2.031s-6.342-2.065-7.157-2.312c-.194-.06-.557-.104-1-.125 1.17-.798 4.863-2.057 7.5-2.938 2.898-.968 3.233-1.003 5.22-1.281 2.049-.287 3.187-.313 3.187-.313s-.073-.607 1-1.062c.72-.306 4.99-1.5 7.062-2 2.003-.483 5.199-.928 7.063-.406 1.91.535 7.719 2.5 7.719 2.5s-6.423-2.424-7.25-2.72c-.198-.07-.583-.14-1.032-.187 1.188-.728 4.916-1.774 7.594-2.5 2.944-.797 3.292-.77 5.313-.906 1.913-.128 2.947-.07 3.125-.062.117-.204.391-.78.937-.97.732-.253 5.079-1.047 7.188-1.374 1.748-.271 4.4-.485 6.312-.094.318.065.605.186.875.281 1.94.69 7.844 3.094 7.844 3.094s-6.535-2.95-7.375-3.312c-.201-.087-.575-.167-1.031-.25 1.206-.633 5.03-1.396 7.75-1.906 2.99-.562 3.3-.53 5.344-.532 2.109-.002
+3.312.125 3.312.125s-.073-.63 1.031-.937c.74-.206 5.126-.834 7.25-1.063 2.053-.22 5.319-.252 7.22.47 1.947.738 7.843 3.374 7.843 3.374s-6.563-3.179-7.406-3.562c-.202-.092-.543-.187-1-.282 1.21-.602 4.984-1.248 7.718-1.656 3.005-.448 3.326-.452 5.375-.406 1.94.043 3.007.194 3.188.219.119-.194.384-.766.937-.907.743-.188 5.155-.734 7.282-.937 1.763-.169 4.42-.234 6.343.25.32.08.604.203.875.312 1.953.784 7.907 3.47 7.907 3.47s-6.592-3.254-7.438-3.657c-.202-.096-.572-.207-1.031-.313 1.214-.574 5.044-1.122 7.781-1.5 3.009-.415 3.323-.442 5.375-.375 2.118.07 3.313.25 3.313.25s-.078-.637 1.03-.906c.745-.18 5.153-.663 7.282-.844 2.059-.174 5.343-.124 7.25.657 1.955.8 7.875 3.53 7.875 3.53s-6.56-3.308-7.406-3.718c-.202-.098-.572-.203-1.031-.312 1.215-.564 5.01-1.115 7.75-1.47 3.01-.389 3.321-.397 5.375-.312 1.944.08 3.006.254 3.187.282.12-.191.383-.746.938-.875.744-.174 5.15-.65 7.28-.813
+1.767-.134 4.45-.126 6.376.375.32.083.603.201.875.313 1.954.8 7.906 3.562 7.906 3.562s-6.591-3.34-7.437-3.75c-.203-.098-.572-.203-1.032-.312 1.215-.564 5.042-1.084 7.782-1.438 3.01-.39 3.352-.429 5.406-.344 2.12.088 3.312.313 3.312.313s-.078-.65 1.032-.906c.744-.173 5.15-.624 7.28-.782 2.061-.152 5.344-.096 7.25.688 1.956.804 7.876 3.5 7.876 3.5s-6.56-3.276-7.406-3.688c-.203-.098-.572-.202-1.032-.312 1.216-.562 5.012-1.128 7.75-1.5 3.01-.41 3.323-.416 5.375-.344 1.943.068 3.008.165 3.188.188.119-.195.384-.73.937-.875.742-.197 5.131-.83 7.25-1.094 1.757-.22 4.406-.333 6.313.031.317.06.606.19.875.281 1.936.661 7.844 2.938 7.844 2.938s-6.537-2.807-7.375-3.156c-.2-.084-.577-.174-1.032-.25 1.204-.651 5.02-1.372 7.72-2 2.966-.69 3.288-.756 5.312-.875 2.088-.124 3.28-.032 3.28-.032s-.086-.632 1-1.03c.73-.269 5.048-1.339 7.126-1.813 2.008-.46 5.168-1.03 7-.625 1.878.414 13.578 3.015 13.578
+3.015s-12.328-3.022-13.141-3.265c-.195-.058-.559-.107-1-.125 1.167-.804 3.514-1.688 6.11-2.703 1.68-.659.923-.377 2.775-1.004 1.754-.594 2.486-1.01 2.63-1.113.347-.207-.355-.122-.544-.042z" enable-background="new" filter="url(#jk)"/>
+ <path d="m1082.6-275.12c1.873 0.393 4.496 1.146 6.031 1.969s2.822 1.056 5.375 2.5c2.527 1.43 4.796 2.007 6.969 2.531 2.348 0.566 5.435 0.715 8.844 1.188-1.09-0.84-6.608-1.173-8.406-1.563-1.8-0.39-3.895-1.016-6.594-2.313-2.7-1.296-3.495-1.799-5.813-2.687-2.318-0.889-4.004-1.383-6.406-1.625z" enable-background="new" filter="url(#jj)"/>
+ <path d="M1051.5-270c1.905.578 4.528 1.616 6.094 2.594 1.565.978 2.88 1.36 5.5 3.125 2.593 1.747 4.986 2.71 7.25 3.594 2.446.955 5.682 1.657 9.406 3.062-1.19-1.138-7.063-2.687-8.938-3.375-1.874-.688-4.081-1.566-6.874-3.281-2.794-1.715-3.574-2.284-5.938-3.406-2.364-1.123-4.057-1.835-6.5-2.313z" enable-background="new" filter="url(#ji)"/>
+ <path d="m1020.2-266.84c1.912 0.638 4.581 1.755 6.156 2.813 1.575 1.057 2.896 1.508 5.531 3.406 2.61 1.878 5.029 3.03 7.313 4.062 2.468 1.116 5.764 2.174 9.531 3.844-1.203-1.222-7.203-3.314-9.094-4.125-1.89-0.81-4.064-1.894-6.874-3.75s-3.622-2.477-6-3.719c-2.379-1.242-4.111-1.975-6.563-2.531z" enable-background="new" filter="url(#jh)"/>
+ <path d="M1110.2-266.89c.15.049.688.631.11 1.484-.81 1.195-5.705 3.325-8.563 4.125-2.845.798-6.29.978-10.562-.375-4.302-1.362-5.47-2.468-10.656-4.312 4.664 2.115 6.195 3.952 10.125 5.344 1.62.574 3.367.94 5.062 1.03-.445.327-1.53.984-3.562 1.595-2.796.84-6.65 1.534-8.25 1.625-1.515.086-3.142-.513-3.438-.625.167.103.374.377-.25 1.03-.899.945-6.147 1.924-9.125 2.25-2.964.326-6.521-.015-10.906-1.905-3.978-1.715-5.339-2.916-9.406-4.75v.156c3.643 2.095 5.284 3.883 8.875 5.562 1.73.81 3.592 1.41 5.406 1.72-.534.286-1.557.71-3.437 1.03-2.87.488-6.81.817-8.438.75-.85-.034-1.728-.184-2.406-.406-.685-.215-1.19-.444-1.312-.5.169.107.43.403-.22 1.031-.909.88-6.245 1.337-9.25 1.47-2.99.131-6.588-.451-11-2.563-4.44-2.127-5.64-3.402-10.905-5.782 4.734 2.597 6.286 4.63 10.344 6.72 1.673.861 3.485 1.493 5.25 1.937-.463.233-1.59.688-3.688.937-2.886.343-6.834.493-8.468.375-1.547-.111-3.232-.857-3.532-1
+.17.12.414.41-.218 1-.913.851-6.244 1.262-9.25 1.375-2.993.113-6.59-.49-11-2.594-4.002-1.908-5.388-3.137-9.47-5.093v.156c3.656 2.204 5.295 4.053 8.907 5.906 1.74.893 3.637 1.528 5.469 1.969-.54.248-1.578.615-3.469.844-2.886.348-6.866.52-8.5.406a9.446 9.446 0 0 1-2.406-.5 12.532 12.532 0 0 1-1.313-.531c.17.112.465.422-.187 1.03-.913.853-6.275 1.294-9.281 1.407-2.993.112-6.594-.528-11-2.594-4.437-2.08-5.647-3.331-10.906-5.656 4.729 2.548 6.29 4.578 10.344 6.625 1.671.844 3.485 1.467 5.25 1.906-.464.235-1.59.684-3.688.938-2.886.348-6.836.57-8.469.469-1.544-.096-3.2-.83-3.5-.97.17.12.382.405-.25 1-.912.861-6.246 1.331-9.25 1.47-2.99.138-6.567-.451-10.969-2.47-3.993-1.83-5.365-3.028-9.437-4.905v.156c3.647 2.133 5.27 3.935 8.875 5.719 1.737.86 3.607 1.45 5.437 1.875-.54.253-1.55.64-3.437.906-2.88.404-6.838.646-8.469.562a9.36 9.36 0 0 1-2.406-.437 12.971 12.971 0 0
+1-1.313-.5c.17.109.432.41-.218 1.031-.911.87-6.25 1.392-9.25 1.563-2.987.17-6.574-.316-10.97-2.282-4.424-1.978-5.605-3.228-10.843-5.375 4.71 2.388 6.27 4.39 10.312 6.344a23.73 23.73 0 0 0 5.218 1.781c-.461.25-1.597.713-3.687 1.032-2.876.438-6.78.733-8.406.687-1.539-.043-3.233-.745-3.532-.875.169.113.411.414-.218 1.031-.908.891-6.203 1.529-9.188 1.813-2.971.283-6.573-.176-10.938-1.938-3.96-1.598-5.329-2.795-9.344-4.312v.156c3.596 1.811 5.239 3.582 8.813 5.156 1.722.759 3.587 1.29 5.406 1.625-.536.28-1.566.688-3.437 1.063-2.856.572-6.79 1.02-8.407 1.031-.844.006-1.706-.08-2.375-.25-.676-.162-1.16-.33-1.28-.375.166.094.422.383-.22 1.062-.897.951-6.186 1.918-9.125 2.438-2.925.518-6.432.374-10.719-1.031-4.315-1.415-5.472-2.53-10.562-3.969 4.577 1.751 6.09 3.56 10.031 5 1.627.594 3.37.956 5.094 1.156-.453.297-1.555.884-3.594 1.469-2.804.805-6.638 1.576-8.218
+1.75-1.495.165-3.117-.317-3.407-.406.164.09.393.36-.218 1.062-.883 1.014-6.045 2.372-8.938 3.063-2.88.687-6.335.76-10.562-.438-3.835-1.086-5.172-2.072-9.062-3.125v.156c3.484 1.395 5.07 2.92 8.53 4.032 1.669.535 3.457.786 5.22.875-.52.352-1.5.914-3.313 1.53-2.765.942-6.59 1.936-8.156 2.157-.818.115-1.633.123-2.281.031-.655-.083-1.133-.218-1.25-.25.162.075.434.34-.188 1.094-.87 1.055-6.01 2.66-8.875 3.438-2.852.774-6.259.958-10.438-.094-4.206-1.06-5.356-2.042-10.344-3.156 4.485 1.46 5.97 3.135 9.813 4.25 1.585.46 3.287.638 4.969.687-.442.337-1.513 1.028-3.5 1.781-2.734 1.037-6.452 2.163-8 2.438-1.465.26-3.06-.117-3.344-.188.16.08.38.321-.219 1.063-.865 1.07-5.916 2.818-8.75 3.687-2.82.866-6.207 1.157-10.344.22-3.753-.852-5.048-1.717-8.875-2.595v.157c3.428 1.237 4.987 2.632 8.375 3.53 1.632.434 3.367.584 5.094.563-.51.384-1.477 1.022-3.25 1.75-2.706 1.112-6.436 2.308-7.969
+2.625-.8.166-1.612.219-2.25.157v1.406c.227-.145.449-.273.719-.375 1.08-.41 2.171-.216 6-1.688 3.828-1.471 5.224-2.005 5.906-2.406.68-.4 1.612-.88 2.219-1.531 1.827-.138 3.57-.493 4.937-1 2.968-1.1 4.876-1.806 6.782-2.469 1.905-.663 2.354-1.415 3.406-1.781 1.091-.38 2.195-.166 6.062-1.531 3.868-1.366 5.283-1.827 5.969-2.22.701-.4 1.7-.932 2.313-1.593 1.97-.055 3.816-.385 5.28-.875 3.002-1.005 4.927-1.622 6.845-2.25 1.538-.504 2.174-1.047 2.906-1.437.23-.135.475-.254.75-.344 1.098-.36 2.181-.082 6.094-1.313 3.912-1.23 5.366-1.673 6.062-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.636-.267 5.031-.688 3.03-.913 4.993-1.43 6.938-1.968 1.945-.54 2.426-1.265 3.5-1.563 1.114-.31 2.22.007 6.187-1.031 3.968-1.039 5.418-1.433 6.125-1.75.735-.33 1.814-.754 2.438-1.375 1.997.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101 7.062-1.5 1.588-.32 2.244-.79 3-1.094.238-.107.467-.193.75-.25 1.134-.23
+2.305.209 6.344-.5s5.5-.927 6.219-1.187c.715-.26 1.704-.568 2.343-1.094 1.925.24 3.748.224 5.188 0 3.126-.488 5.155-.7 7.156-.969 2.002-.268 2.489-.945 3.594-1.094 1.146-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.28-.937.738-.247 1.799-.586 2.438-1.125 2.05.335 3.974.398 5.5.219 3.143-.37 5.18-.56 7.188-.782 1.61-.178 2.265-.608 3.031-.843a3.43 3.43 0 0 1 .781-.188c1.15-.128 2.302.347 6.375-.125s5.56-.61 6.282-.844c.719-.232 1.7-.473 2.343-.968 1.937.333 3.77.404 5.22.25 3.145-.335 5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.593-.938 1.152-.115 2.297.366 6.375-.062s5.59-.562 6.313-.781c.74-.224 1.796-.514 2.437-1.031 2.058.398 4.002.493 5.532.343 3.148-.308 5.175-.473 7.187-.656 1.614-.147 2.263-.56 3.031-.781.242-.081.494-.13.782-.156 1.152-.106 2.293.392 6.375 0 4.082-.393 5.589-.531 6.312-.75.721-.219 1.7-.448 2.344-.938 1.938.35 3.769.454 5.219.313 3.148-.309 5.175-.474
+7.187-.657 2.012-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.589-.501 6.313-.719c.739-.222 1.795-.514 2.437-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.178-.523 7.188-.72 1.613-.156 2.266-.63 3.031-.874.24-.088.463-.122.75-.156 1.148-.14 2.317.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.313-1.093 1.92.211 3.72.151 5.156-.094 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.562-1.28 1.13-.252 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.723-.376 1.762-.87 2.375-1.531 1.963-.012 3.794-.291 5.22-.844 2.95-1.145 4.872-1.87 6.687-2.75 1.455-.707 2.334-1.686 2.547-1.984.212-.298.111-.746.137-.767.043-.035.32-.085.48-.429.858-1.847 2.32-5.644
+2.435-6.329.113-.682.163-1.348.214-1.745.03-.23-.147-.865-.125-.924.031-.082.305-.265.36-.515.267-1.198.09-2.191-.125-3.609-.214-1.417-.983-4.622-1.637-5.476-.659-.862-1.223-1.011-1.748-1-.208.27.137.262.163.312.68.05.934.369 1.42.897s1.442 3.94 1.579 5.39.19 2.86-.088 3.468c-.278.609-.944.429-1.237.495.531.186.89.213.953 1.057.058.814-.134 1.64-.52 2.806-.391 1.18-1.845 4.35-2.286 4.599-.452.255-.952.182-1.288.05z" enable-background="new" filter="url(#jg)"/>
+ <path d="m988.75-263.84c1.912 0.634 4.55 1.758 6.125 2.813 1.575 1.054 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.062 2.47 1.132 5.752 2.155 9.531 3.938-1.207-1.259-7.139-3.365-9.031-4.188s-4.128-1.93-6.938-3.781-3.622-2.482-6-3.719c-2.377-1.237-4.08-1.95-6.53-2.5z" enable-background="new" filter="url(#jf)"/>
+ <path d="M957.5-260.78c1.91.618 4.583 1.71 6.156 2.75 1.574 1.04 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.063 2.47 1.131 5.752 2.154 9.531 3.937-1.207-1.258-7.201-3.396-9.094-4.219-1.892-.823-4.096-1.93-6.906-3.781-2.81-1.85-3.593-2.44-5.969-3.656s-4.113-1.939-6.562-2.469z" enable-background="new" filter="url(#ib)"/>
+ <path d="M926.09-257.38c1.908.597 4.553 1.664 6.125 2.688 1.571 1.023 2.87 1.44 5.5 3.28 2.603 1.823 5.029 2.973 7.313 4 2.467 1.111 5.755 2.094 9.53 3.845-1.205-1.249-7.171-3.319-9.062-4.125s-4.102-1.891-6.906-3.688c-2.804-1.796-3.627-2.402-6-3.594-2.373-1.191-4.054-1.903-6.5-2.406z" enable-background="new" filter="url(#ia)"/>
+ <path d="M894.91-253.56c1.902.554 4.587 1.589 6.156 2.594s2.874 1.408 5.5 3.219c2.6 1.791 5 2.871 7.281 3.875 2.465 1.083 5.76 2.04 9.532 3.75-1.205-1.236-7.175-3.245-9.063-4.032-1.888-.786-4.075-1.83-6.875-3.593s-3.6-2.369-5.969-3.532c-2.37-1.163-4.123-1.834-6.562-2.28z" enable-background="new" filter="url(#hz)"/>
+ <path d="M863.72-248.66c1.88.43 4.504 1.38 6.063 2.313 1.558.932 2.852 1.257 5.468 3 2.59 1.724 4.981 2.708 7.25 3.625 2.452.99 5.74 1.877 9.5 3.5-1.201-1.208-7.152-3.067-9.03-3.782-1.88-.715-4.086-1.684-6.876-3.375s-3.585-2.228-5.937-3.28-4.026-1.713-6.438-2z" enable-background="new" filter="url(#hy)"/>
+ <path d="m833.16-241.38c1.848 0.296 4.47 0.976 6 1.781s2.814 1.056 5.375 2.531c2.535 1.46 4.89 2.326 7.125 3.063 2.414 0.797 5.657 1.467 9.375 2.844-1.188-1.129-7.088-2.59-8.938-3.156-1.85-0.567-4.003-1.374-6.75-2.844-2.746-1.47-3.5-1.92-5.812-2.781-2.311-0.861-4.005-1.32-6.375-1.438z" enable-background="new" filter="url(#hx)"/>
+ <path d="m802.91-232.31c1.822 0.211 4.366 0.8 5.875 1.531 1.51 0.73 2.756 0.93 5.281 2.281 2.5 1.338 4.832 2.049 7.031 2.657 2.377 0.656 5.565 1.073 9.22 2.187-1.168-1.045-6.93-2.103-8.75-2.562-1.822-0.46-3.953-1.127-6.657-2.438s-3.471-1.72-5.75-2.469-3.913-1.179-6.25-1.187z" enable-background="new" filter="url(#hw)"/>
+ <path d="M773.19-222.19c1.811.179 4.32.665 5.813 1.344 1.491.678 2.753.798 5.25 2.062 2.47 1.252 4.79 1.896 6.968 2.438 2.354.585 5.492.897 9.094 1.844-1.15-.992-6.852-1.784-8.656-2.188s-3.916-1.021-6.594-2.25c-2.678-1.229-3.403-1.61-5.656-2.281-2.253-.67-3.896-1.002-6.219-.969z" enable-background="new" filter="url(#hv)"/>
+ <path d="M743.56-211.19c1.793.13 4.273.55 5.75 1.188s2.716.741 5.188 1.937c2.446 1.184 4.72 1.747 6.874 2.219 2.328.51 5.42.68 9 1.562-1.143-.97-6.747-1.59-8.53-1.937-1.784-.347-3.884-.888-6.532-2.031-2.648-1.144-3.395-1.517-5.625-2.125-2.23-.61-3.826-.91-6.125-.813z" enable-background="new" filter="url(#hu)"/>
+ <g fill="#fff" filter="url(#ht)">
+ <path d="M744.94-212.12s7.222-3.223 9.063-3.5 3.352-.003 6 .563c2.647.565 8.735 2.215 11.188 3.374s5.312 3.563 5.312 3.563-7.146-2.78-10.188-3.563-7.645-2.083-10.375-2.312-11 1.875-11 1.875z"/>
+ <path d="m735.47-206.95s3.66-2.223 5.5-2.5 3.665 0.247 6.313 0.813 8.735 2.215 11.188 3.375 6.562 2.125 6.562 2.125-8.396-1.343-11.438-2.125-7.957-2.334-10.688-2.563-7.438 0.875-7.438 0.875zm24.38-10.66s8.544-3.299 10.398-3.458c1.854-0.16 3.642 0.48 6.248 1.212s8.577 2.766 10.95 4.08 6.414 2.537 6.414 2.537-8.294-1.873-11.279-2.848c-2.985-0.974-7.792-2.834-10.503-3.236s-12.228 1.713-12.228 1.713zm15.35-5.62s7.771-2.782 9.628-2.904c1.857-0.12 3.631 0.555 6.222 1.341 2.59 0.787 8.519 2.942 10.864 4.304 2.346 1.362 6.36 2.67 6.36 2.67s-8.253-2.045-11.217-3.08c-2.965-1.035-7.733-2.995-10.434-3.452-2.702-0.458-11.422 1.121-11.422 1.121zm14.44-4.72s8.683-3.52 10.542-3.605 3.62 0.624 6.195 1.46c2.575 0.837 8.46 3.107 10.779 4.514 2.318 1.408 6.307 2.793 6.307 2.793s-8.212-2.204-11.156-3.297-7.673-3.144-10.365-3.654-12.3 1.789-12.3 1.789zm14.86-5.38s7.808-2.583 9.666-2.668c1.86-0.085 3.62
+0.625 6.195 1.461 2.575 0.837 8.46 3.107 10.78 4.514 2.318 1.407 6.307 2.792 6.307 2.792s-8.213-2.204-11.156-3.296-7.673-3.144-10.365-3.654-11.426 0.85-11.426 0.85zm15.06-4.25s8.558-2.583 10.417-2.668 3.62 0.625 6.195 1.461c2.575 0.837 8.46 3.107 10.779 4.514 2.318 1.407 6.307 2.792 6.307 2.792s-8.212-2.204-11.156-3.296-7.673-3.144-10.365-3.654-12.176 0.85-12.176 0.85zm16.67-5.02s6.967-1.987 8.828-1.968c1.86 0.02 3.579 0.827 6.102 1.807 2.524 0.98 8.272 3.578 10.508 5.113 2.236 1.536 6.14 3.143 6.14 3.143s-8.075-2.662-10.952-3.919c-2.878-1.256-7.484-3.57-10.143-4.231-2.66-0.66-10.482 0.055-10.482 0.055zm14.5-3.4s7.688-2.028 9.548-1.968 3.56 0.902 6.063 1.936c2.502 1.033 8.194 3.752 10.397 5.335 2.203 1.582 6.072 3.272 6.072 3.272s-8.017-2.833-10.868-4.15c-2.85-1.318-7.407-3.73-10.05-4.446s-11.162 0.021-11.162 0.021zm14.09-3.21s8.17-1.97 10.027-1.854c1.857 0.115 3.532 1.01 6.002
+2.118s8.077 3.997 10.23 5.645 5.972 3.454 5.972 3.454-7.928-3.074-10.738-4.476-7.291-3.95-9.913-4.746c-2.621-0.796-11.58-0.141-11.58-0.141zm16.56-2.39s8.085-1.908 9.938-1.737c1.853 0.172 3.5 1.117 5.935 2.3 2.436 1.182 7.952 4.24 10.055 5.953s5.864 3.633 5.864 3.633-7.832-3.312-10.597-4.8-7.168-4.169-9.764-5.044c-2.597-0.876-11.431-0.305-11.431-0.305zm15.2-2.75s7.642-1.428 9.495-1.265c1.854 0.162 3.505 1.1 5.946 2.27s7.973 4.203 10.084 5.905c2.112 1.703 5.881 3.605 5.881 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-10.998-0.77-10.998-0.77zm14.87-1.64s8.642-1.553 10.495-1.39c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.846-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.863-11.998-0.644-11.998-0.644zm16.25-2.31s7.642-0.865 9.495-0.703c1.854 0.163 3.505 1.1 5.946 2.27s7.973 4.203 10.084
+5.906c2.112 1.702 5.881 3.605 5.881 3.605s-7.847-3.275-10.62-4.749c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.862-10.998-1.331-10.998-1.331zm15.13-1.19s8.58-1.49 10.433-1.328c1.854 0.163 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.906c2.111 1.702 5.88 3.605 5.88 3.605s-7.846-3.275-10.62-4.749c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.862-11.935-0.706-11.935-0.706zm16.25-2.06s7.83-0.803 9.683-0.64c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.846-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.863-11.185-1.394-11.185-1.394zm15.37-1.25s8.392-1.178 10.245-1.015c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-11.748-1.02-11.748-1.02zm16.19-2.06s6.892-0.99 8.745-0.828c1.854 0.163 3.505 1.1 5.946 2.27s7.973 4.203
+10.084 5.906c2.112 1.702 5.881 3.605 5.881 3.605s-7.847-3.275-10.62-4.749-7.188-4.135-9.788-4.998c-2.6-0.862-10.248-1.206-10.248-1.206zm17.16-0.94s6.83-1.178 8.683-1.015c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-10.185-1.02-10.185-1.02zm16.1-2s6.08-0.428 7.933-0.265c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-9.435-1.77-9.435-1.77zm15.8-1.37s6.454-0.678 8.308-0.515c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-9.81-1.52-9.81-1.52zm15.6-1.86s5.498-0.91 7.358-0.853c1.86 0.056 3.562 0.896 6.066 1.925
+2.504 1.03 8.2 3.739 10.406 5.318 2.205 1.578 6.078 3.261 6.078 3.261s-8.022-2.819-10.875-4.131c-2.853-1.313-7.413-3.716-10.06-4.429-2.645-0.712-8.973-1.091-8.973-1.091zm17.4-2.46s4.547-1.156 6.408-1.186c1.86-0.03 3.6 0.73 6.149 1.642 2.55 0.912 8.365 3.354 10.64 4.829 2.277 1.474 6.224 2.976 6.224 2.976s-8.145-2.444-11.055-3.623c-2.91-1.178-7.578-3.368-10.253-3.957-2.676-0.588-8.113-0.68-8.113-0.68zm14.5-3.03s5.96-1.774 7.82-1.83c1.86-0.057 3.61 0.68 6.172 1.555 2.562 0.876 2.522 0.857 5.333 1.49 2.797 0.63 7.077 1.513 7.077 1.513s-3.616-0.016-6.792-0.466c-3.116-0.441-7.375-1.698-10.058-2.249-2.684-0.55-9.552-0.013-9.552-0.013z" enable-background="new"/>
+ <path d="M1099.2-279.93c.161.269 11.208-4.6 12.188-4.688.98-.087 2 3.125 2 3.125s-.775-1.504-2.875-1.062-11.301 2.671-11.312 2.625z"/>
+ </g>
+ <path d="M1107.5-284.09c-.419.213-.156.094-.647.306-.486.21-1.724.574-4.08 1.459-3.33 1.25-5.83 2.153-7.026 3.066-1.536.021-3.72.233-5.656.719a227.709 227.709 0 0 1-6.75 1.593c-1.895.42-1.676.643-2.875.875-1.297.252-1.721-.009-5.438.782-3.49.742-8.894 1.93-10.156 2.687-1.583-.18-3.867-.322-5.843-.031-3.04.447-4.917.673-6.844.906-.655.08-1.041.201-1.344.282-.426.131-.686.26-1.375.343-1.311.16-1.762-.157-5.531.282-3.554.413-9.005 1.272-10.25 1.937-1.599-.297-3.858-.534-5.844-.344-3.059.294-4.972.484-6.906.657-1.934.172-1.689.422-2.906.53-1.317.118-1.76-.163-5.532.25-3.541.39-9.007 1.21-10.28 1.876-1.6-.295-3.888-.507-5.876-.313-3.058.3-4.94.48-6.875.657-.657.06-1.04.178-1.343.25-.428.118-.684.218-1.375.28-1.316.121-1.76-.194-5.532.22-3.556.39-9.005 1.239-10.25
+1.906-1.598-.294-3.86-.524-5.843-.313-3.056.326-4.974.526-6.907.719-1.932.192-1.69.44-2.906.562-1.315.132-1.763-.164-5.53.282-3.54.418-8.979 1.292-10.25 1.969-1.599-.282-3.86-.42-5.845-.188-3.052.358-4.945.568-6.875.781-.656.073-1.04.173-1.344.25-.426.127-.684.267-1.375.344-1.313.146-1.767-.174-5.53.313-3.55.458-8.98 1.419-10.22 2.125-1.593-.245-3.834-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.925.258-1.726.493-2.938.656-1.31.176-1.747-.104-5.5.469-3.524.538-8.923 1.699-10.188 2.437-1.587-.203-3.845-.254-5.812.094-3.026.536-4.9.862-6.813 1.187-.65.111-1.013.271-1.312.375-.42.165-.664.332-1.344.47-1.295.26-1.727-.007-5.438.812-3.498.772-8.846 2.383-10.062 3.219-1.562-.078-3.757.085-5.687.593-2.972.783-4.818 1.232-6.688 1.75s-1.666.768-2.843 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.931.928-4.75 1.459-6.594
+2.063-.627.205-.992.392-1.281.531-.408.214-.653.409-1.313.625-1.254.412-1.686.19-5.28 1.438-3.39 1.177-8.596 3.213-9.782 4.156-1.524.06-3.65.395-5.531 1.062-2.898 1.029-4.7 1.676-6.531 2.313-1.833.637-1.628.848-2.782 1.25-1.246.434-1.663.2-5.218 1.562-3.34 1.28-8.488 3.483-9.688 4.47-1.507.107-3.636.498-5.5 1.218a1044.752 1044.752 0 0 1-6.437 2.469c-.617.233-.997.442-1.282.593v1.094c.112-.222.386-.817.907-1.094.698-.37 4.813-1.993 6.812-2.718 1.657-.602 4.154-1.329 5.969-1.313.302.003.588.051.844.094 1.842.308 7.468 1.562 7.468 1.562s-6.233-1.646-7.03-1.843c-.191-.048-.536-.07-.97-.063 1.146-.87 4.762-2.393 7.344-3.437 2.839-1.148 3.117-1.252 5.063-1.657 2.008-.417 3.156-.5 3.156-.5s-.082-.6.969-1.125c.705-.351 4.887-1.892 6.906-2.562 1.952-.648 5.057-1.359 6.875-1 1.863.367 7.531 1.812 7.531 1.812s-6.287-1.87-7.094-2.093c-.193-.054-.53-.086-.968-.094 1.158-.833 4.794-2.195 7.406-3.156
+2.87-1.056 3.167-1.162 5.125-1.532 1.853-.35 2.859-.425 3.031-.437.114-.217.377-.81.906-1.063.71-.338 4.926-1.712 6.97-2.312 1.692-.497 4.24-1.037 6.093-.906.308.021.613.097.875.156 1.881.424 7.594 2.031 7.594 2.031s-6.342-2.065-7.157-2.312c-.194-.06-.557-.104-1-.125 1.17-.798 4.863-2.057 7.5-2.938 2.898-.968 3.233-1.003 5.22-1.281 2.049-.287 3.187-.313 3.187-.313s-.073-.607 1-1.062c.72-.306 4.99-1.5 7.062-2 2.003-.483 5.199-.928 7.063-.406 1.91.535 7.719 2.5 7.719 2.5s-6.423-2.424-7.25-2.72c-.198-.07-.583-.14-1.032-.187 1.188-.728 4.916-1.774 7.594-2.5 2.944-.797 3.292-.77 5.313-.906 1.913-.128 2.947-.07 3.125-.062.117-.204.391-.78.937-.97.732-.253 5.079-1.047 7.188-1.374 1.748-.271 4.4-.485 6.312-.094.318.065.605.186.875.281 1.94.69 7.844 3.094 7.844 3.094s-6.535-2.95-7.375-3.312c-.201-.087-.575-.167-1.031-.25 1.206-.633 5.03-1.396 7.75-1.906 2.99-.562 3.3-.53 5.344-.532 2.109-.002
+3.312.125 3.312.125s-.073-.63 1.031-.937c.74-.206 5.126-.834 7.25-1.063 2.053-.22 5.319-.252 7.22.47 1.947.738 7.843 3.374 7.843 3.374s-6.563-3.179-7.406-3.562c-.202-.092-.543-.187-1-.282 1.21-.602 4.984-1.248 7.718-1.656 3.005-.448 3.326-.452 5.375-.406 1.94.043 3.007.194 3.188.219.119-.194.384-.766.937-.907.743-.188 5.155-.734 7.282-.937 1.763-.169 4.42-.234 6.343.25.32.08.604.203.875.312 1.953.784 7.907 3.47 7.907 3.47s-6.592-3.254-7.438-3.657c-.202-.096-.572-.207-1.031-.313 1.214-.574 5.044-1.122 7.781-1.5 3.009-.415 3.323-.442 5.375-.375 2.118.07 3.313.25 3.313.25s-.078-.637 1.03-.906c.745-.18 5.153-.663 7.282-.844 2.059-.174 5.343-.124 7.25.657 1.955.8 7.875 3.53 7.875 3.53s-6.56-3.308-7.406-3.718c-.202-.098-.572-.203-1.031-.312 1.215-.564 5.01-1.115 7.75-1.47 3.01-.389 3.321-.397 5.375-.312 1.944.08 3.006.254 3.187.282.12-.191.383-.746.938-.875.744-.174 5.15-.65 7.28-.813
+1.767-.134 4.45-.126 6.376.375.32.083.603.201.875.313 1.954.8 7.906 3.562 7.906 3.562s-6.591-3.34-7.437-3.75c-.203-.098-.572-.203-1.032-.312 1.215-.564 5.042-1.084 7.782-1.438 3.01-.39 3.352-.429 5.406-.344 2.12.088 3.312.313 3.312.313s-.078-.65 1.032-.906c.744-.173 5.15-.624 7.28-.782 2.061-.152 5.344-.096 7.25.688 1.956.804 7.876 3.5 7.876 3.5s-6.56-3.276-7.406-3.688c-.203-.098-.572-.202-1.032-.312 1.216-.562 5.012-1.128 7.75-1.5 3.01-.41 3.323-.416 5.375-.344 1.943.068 3.008.165 3.188.188.119-.195.384-.73.937-.875.742-.197 5.131-.83 7.25-1.094 1.757-.22 4.406-.333 6.313.031.317.06.606.19.875.281 1.936.661 7.844 2.938 7.844 2.938s-6.537-2.807-7.375-3.156c-.2-.084-.577-.174-1.032-.25 1.204-.651 5.02-1.372 7.72-2 2.966-.69 3.288-.756 5.312-.875 2.088-.124 3.28-.032 3.28-.032s-.086-.632 1-1.03c.73-.269 5.048-1.339 7.126-1.813 2.008-.46 5.168-1.03 7-.625 1.878.414 13.578 3.015 13.578
+3.015s-12.328-3.022-13.141-3.265c-.195-.058-.559-.107-1-.125 1.167-.804 3.514-1.688 6.11-2.703 1.68-.659.923-.377 2.775-1.004 1.754-.594 2.486-1.01 2.63-1.113.347-.207-.355-.122-.544-.042z" enable-background="new" filter="url(#hs)" opacity=".25"/>
+ <path d="m1082.6-275.12c1.873 0.393 4.496 1.146 6.031 1.969s2.822 1.056 5.375 2.5c2.527 1.43 4.796 2.007 6.969 2.531 2.348 0.566 5.435 0.715 8.844 1.188-1.09-0.84-6.608-1.173-8.406-1.563-1.8-0.39-3.895-1.016-6.594-2.313-2.7-1.296-3.495-1.799-5.813-2.687-2.318-0.889-4.004-1.383-6.406-1.625z" enable-background="new" filter="url(#hr)" opacity=".25"/>
+ <path d="M1051.5-270c1.905.578 4.528 1.616 6.094 2.594 1.565.978 2.88 1.36 5.5 3.125 2.593 1.747 4.986 2.71 7.25 3.594 2.446.955 5.682 1.657 9.406 3.062-1.19-1.138-7.063-2.687-8.938-3.375-1.874-.688-4.081-1.566-6.874-3.281-2.794-1.715-3.574-2.284-5.938-3.406-2.364-1.123-4.057-1.835-6.5-2.313z" enable-background="new" filter="url(#hq)" opacity=".25"/>
+ <path d="m1020.2-266.84c1.912 0.638 4.581 1.755 6.156 2.813 1.575 1.057 2.896 1.508 5.531 3.406 2.61 1.878 5.029 3.03 7.313 4.062 2.468 1.116 5.764 2.174 9.531 3.844-1.203-1.222-7.203-3.314-9.094-4.125-1.89-0.81-4.064-1.894-6.874-3.75s-3.622-2.477-6-3.719c-2.379-1.242-4.111-1.975-6.563-2.531z" enable-background="new" filter="url(#hp)" opacity=".25"/>
+ <path d="M1110.2-266.89c.15.049.688.631.11 1.484-.81 1.195-5.705 3.325-8.563 4.125-2.845.798-6.29.978-10.562-.375-4.302-1.362-5.47-2.468-10.656-4.312 4.664 2.115 6.195 3.952 10.125 5.344 1.62.574 3.367.94 5.062 1.03-.445.327-1.53.984-3.562 1.595-2.796.84-6.65 1.534-8.25 1.625-1.515.086-3.142-.513-3.438-.625.167.103.374.377-.25 1.03-.899.945-6.147 1.924-9.125 2.25-2.964.326-6.521-.015-10.906-1.905-3.978-1.715-5.339-2.916-9.406-4.75v.156c3.643 2.095 5.284 3.883 8.875 5.562 1.73.81 3.592 1.41 5.406 1.72-.534.286-1.557.71-3.437 1.03-2.87.488-6.81.817-8.438.75-.85-.034-1.728-.184-2.406-.406-.685-.215-1.19-.444-1.312-.5.169.107.43.403-.22 1.031-.909.88-6.245 1.337-9.25 1.47-2.99.131-6.588-.451-11-2.563-4.44-2.127-5.64-3.402-10.905-5.782 4.734 2.597 6.286 4.63 10.344 6.72 1.673.861 3.485 1.493 5.25 1.937-.463.233-1.59.688-3.688.937-2.886.343-6.834.493-8.468.375-1.547-.111-3.232-.857-3.532-1
+.17.12.414.41-.218 1-.913.851-6.244 1.262-9.25 1.375-2.993.113-6.59-.49-11-2.594-4.002-1.908-5.388-3.137-9.47-5.093v.156c3.656 2.204 5.295 4.053 8.907 5.906 1.74.893 3.637 1.528 5.469 1.969-.54.248-1.578.615-3.469.844-2.886.348-6.866.52-8.5.406a9.446 9.446 0 0 1-2.406-.5 12.532 12.532 0 0 1-1.313-.531c.17.112.465.422-.187 1.03-.913.853-6.275 1.294-9.281 1.407-2.993.112-6.594-.528-11-2.594-4.437-2.08-5.647-3.331-10.906-5.656 4.729 2.548 6.29 4.578 10.344 6.625 1.671.844 3.485 1.467 5.25 1.906-.464.235-1.59.684-3.688.938-2.886.348-6.836.57-8.469.469-1.544-.096-3.2-.83-3.5-.97.17.12.382.405-.25 1-.912.861-6.246 1.331-9.25 1.47-2.99.138-6.567-.451-10.969-2.47-3.993-1.83-5.365-3.028-9.437-4.905v.156c3.647 2.133 5.27 3.935 8.875 5.719 1.737.86 3.607 1.45 5.437 1.875-.54.253-1.55.64-3.437.906-2.88.404-6.838.646-8.469.562a9.36 9.36 0 0 1-2.406-.437 12.971 12.971 0 0
+1-1.313-.5c.17.109.432.41-.218 1.031-.911.87-6.25 1.392-9.25 1.563-2.987.17-6.574-.316-10.97-2.282-4.424-1.978-5.605-3.228-10.843-5.375 4.71 2.388 6.27 4.39 10.312 6.344a23.73 23.73 0 0 0 5.218 1.781c-.461.25-1.597.713-3.687 1.032-2.876.438-6.78.733-8.406.687-1.539-.043-3.233-.745-3.532-.875.169.113.411.414-.218 1.031-.908.891-6.203 1.529-9.188 1.813-2.971.283-6.573-.176-10.938-1.938-3.96-1.598-5.329-2.795-9.344-4.312v.156c3.596 1.811 5.239 3.582 8.813 5.156 1.722.759 3.587 1.29 5.406 1.625-.536.28-1.566.688-3.437 1.063-2.856.572-6.79 1.02-8.407 1.031-.844.006-1.706-.08-2.375-.25-.676-.162-1.16-.33-1.28-.375.166.094.422.383-.22 1.062-.897.951-6.186 1.918-9.125 2.438-2.925.518-6.432.374-10.719-1.031-4.315-1.415-5.472-2.53-10.562-3.969 4.577 1.751 6.09 3.56 10.031 5 1.627.594 3.37.956 5.094 1.156-.453.297-1.555.884-3.594 1.469-2.804.805-6.638 1.576-8.218
+1.75-1.495.165-3.117-.317-3.407-.406.164.09.393.36-.218 1.062-.883 1.014-6.045 2.372-8.938 3.063-2.88.687-6.335.76-10.562-.438-3.835-1.086-5.172-2.072-9.062-3.125v.156c3.484 1.395 5.07 2.92 8.53 4.032 1.669.535 3.457.786 5.22.875-.52.352-1.5.914-3.313 1.53-2.765.942-6.59 1.936-8.156 2.157-.818.115-1.633.123-2.281.031-.655-.083-1.133-.218-1.25-.25.162.075.434.34-.188 1.094-.87 1.055-6.01 2.66-8.875 3.438-2.852.774-6.259.958-10.438-.094-4.206-1.06-5.356-2.042-10.344-3.156 4.485 1.46 5.97 3.135 9.813 4.25 1.585.46 3.287.638 4.969.687-.442.337-1.513 1.028-3.5 1.781-2.734 1.037-6.452 2.163-8 2.438-1.465.26-3.06-.117-3.344-.188.16.08.38.321-.219 1.063-.865 1.07-5.916 2.818-8.75 3.687-2.82.866-6.207 1.157-10.344.22-3.753-.852-5.048-1.717-8.875-2.595v.157c3.428 1.237 4.987 2.632 8.375 3.53 1.632.434 3.367.584 5.094.563-.51.384-1.477 1.022-3.25 1.75-2.706 1.112-6.436 2.308-7.969
+2.625-.8.166-1.612.219-2.25.157v1.406c.227-.145.449-.273.719-.375 1.08-.41 2.171-.216 6-1.688 3.828-1.471 5.224-2.005 5.906-2.406.68-.4 1.612-.88 2.219-1.531 1.827-.138 3.57-.493 4.937-1 2.968-1.1 4.876-1.806 6.782-2.469 1.905-.663 2.354-1.415 3.406-1.781 1.091-.38 2.195-.166 6.062-1.531 3.868-1.366 5.283-1.827 5.969-2.22.701-.4 1.7-.932 2.313-1.593 1.97-.055 3.816-.385 5.28-.875 3.002-1.005 4.927-1.622 6.845-2.25 1.538-.504 2.174-1.047 2.906-1.437.23-.135.475-.254.75-.344 1.098-.36 2.181-.082 6.094-1.313 3.912-1.23 5.366-1.673 6.062-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.636-.267 5.031-.688 3.03-.913 4.993-1.43 6.938-1.968 1.945-.54 2.426-1.265 3.5-1.563 1.114-.31 2.22.007 6.187-1.031 3.968-1.039 5.418-1.433 6.125-1.75.735-.33 1.814-.754 2.438-1.375 1.997.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101 7.062-1.5 1.588-.32 2.244-.79 3-1.094.238-.107.467-.193.75-.25 1.134-.23
+2.305.209 6.344-.5s5.5-.927 6.219-1.187c.715-.26 1.704-.568 2.343-1.094 1.925.24 3.748.224 5.188 0 3.126-.488 5.155-.7 7.156-.969 2.002-.268 2.489-.945 3.594-1.094 1.146-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.28-.937.738-.247 1.799-.586 2.438-1.125 2.05.335 3.974.398 5.5.219 3.143-.37 5.18-.56 7.188-.782 1.61-.178 2.265-.608 3.031-.843a3.43 3.43 0 0 1 .781-.188c1.15-.128 2.302.347 6.375-.125s5.56-.61 6.282-.844c.719-.232 1.7-.473 2.343-.968 1.937.333 3.77.404 5.22.25 3.145-.335 5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.593-.938 1.152-.115 2.297.366 6.375-.062s5.59-.562 6.313-.781c.74-.224 1.796-.514 2.437-1.031 2.058.398 4.002.493 5.532.343 3.148-.308 5.175-.473 7.187-.656 1.614-.147 2.263-.56 3.031-.781.242-.081.494-.13.782-.156 1.152-.106 2.293.392 6.375 0 4.082-.393 5.589-.531 6.312-.75.721-.219 1.7-.448 2.344-.938 1.938.35 3.769.454 5.219.313 3.148-.309 5.175-.474
+7.187-.657 2.012-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.589-.501 6.313-.719c.739-.222 1.795-.514 2.437-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.178-.523 7.188-.72 1.613-.156 2.266-.63 3.031-.874.24-.088.463-.122.75-.156 1.148-.14 2.317.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.313-1.093 1.92.211 3.72.151 5.156-.094 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.562-1.28 1.13-.252 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.723-.376 1.762-.87 2.375-1.531 1.963-.012 3.794-.291 5.22-.844 2.95-1.145 4.872-1.87 6.687-2.75 1.455-.707 2.334-1.686 2.547-1.984.212-.298.111-.746.137-.767.043-.035.32-.085.48-.429.858-1.847 2.32-5.644
+2.435-6.329.113-.682.163-1.348.214-1.745.03-.23-.147-.865-.125-.924.031-.082.305-.265.36-.515.267-1.198.09-2.191-.125-3.609-.214-1.417-.983-4.622-1.637-5.476-.659-.862-1.223-1.011-1.748-1-.208.27.137.262.163.312.68.05.934.369 1.42.897s1.221 3.85 1.358 5.301.19 2.86-.088 3.469c-.278.608-.723.517-1.016.583.531.186.67.125.732.969.058.813-.134 1.64-.52 2.806-.392 1.18-1.846 4.35-2.286 4.598-.452.256-.731.27-1.067.14z" enable-background="new" filter="url(#ho)" opacity=".25"/>
+ <path d="m988.75-263.84c1.912 0.634 4.55 1.758 6.125 2.813 1.575 1.054 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.062 2.47 1.132 5.752 2.155 9.531 3.938-1.207-1.259-7.139-3.365-9.031-4.188s-4.128-1.93-6.938-3.781-3.622-2.482-6-3.719c-2.377-1.237-4.08-1.95-6.53-2.5z" enable-background="new" filter="url(#hn)" opacity=".25"/>
+ <path d="M957.5-260.78c1.91.618 4.583 1.71 6.156 2.75 1.574 1.04 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.063 2.47 1.131 5.752 2.154 9.531 3.937-1.207-1.258-7.201-3.396-9.094-4.219-1.892-.823-4.096-1.93-6.906-3.781-2.81-1.85-3.593-2.44-5.969-3.656s-4.113-1.939-6.562-2.469z" enable-background="new" filter="url(#hm)" opacity=".25"/>
+ <path d="M926.09-257.38c1.908.597 4.553 1.664 6.125 2.688 1.571 1.023 2.87 1.44 5.5 3.28 2.603 1.823 5.029 2.973 7.313 4 2.467 1.111 5.755 2.094 9.53 3.845-1.205-1.249-7.171-3.319-9.062-4.125s-4.102-1.891-6.906-3.688c-2.804-1.796-3.627-2.402-6-3.594-2.373-1.191-4.054-1.903-6.5-2.406z" enable-background="new" filter="url(#hl)" opacity=".25"/>
+ <path d="M894.91-253.56c1.902.554 4.587 1.589 6.156 2.594s2.874 1.408 5.5 3.219c2.6 1.791 5 2.871 7.281 3.875 2.465 1.083 5.76 2.04 9.532 3.75-1.205-1.236-7.175-3.245-9.063-4.032-1.888-.786-4.075-1.83-6.875-3.593s-3.6-2.369-5.969-3.532c-2.37-1.163-4.123-1.834-6.562-2.28z" enable-background="new" filter="url(#hk)" opacity=".25"/>
+ <path d="M863.72-248.66c1.88.43 4.504 1.38 6.063 2.313 1.558.932 2.852 1.257 5.468 3 2.59 1.724 4.981 2.708 7.25 3.625 2.452.99 5.74 1.877 9.5 3.5-1.201-1.208-7.152-3.067-9.03-3.782-1.88-.715-4.086-1.684-6.876-3.375s-3.585-2.228-5.937-3.28-4.026-1.713-6.438-2z" enable-background="new" filter="url(#hj)" opacity=".25"/>
+ <path d="m833.16-241.38c1.848 0.296 4.47 0.976 6 1.781s2.814 1.056 5.375 2.531c2.535 1.46 4.89 2.326 7.125 3.063 2.414 0.797 5.657 1.467 9.375 2.844-1.188-1.129-7.088-2.59-8.938-3.156-1.85-0.567-4.003-1.374-6.75-2.844-2.746-1.47-3.5-1.92-5.812-2.781-2.311-0.861-4.005-1.32-6.375-1.438z" enable-background="new" filter="url(#hi)" opacity=".25"/>
+ <path d="m802.91-232.31c1.822 0.211 4.366 0.8 5.875 1.531 1.51 0.73 2.756 0.93 5.281 2.281 2.5 1.338 4.832 2.049 7.031 2.657 2.377 0.656 5.565 1.073 9.22 2.187-1.168-1.045-6.93-2.103-8.75-2.562-1.822-0.46-3.953-1.127-6.657-2.438s-3.471-1.72-5.75-2.469-3.913-1.179-6.25-1.187z" enable-background="new" filter="url(#hh)" opacity=".25"/>
+ <path d="M773.19-222.19c1.811.179 4.32.665 5.813 1.344 1.491.678 2.753.798 5.25 2.062 2.47 1.252 4.79 1.896 6.968 2.438 2.354.585 5.492.897 9.094 1.844-1.15-.992-6.852-1.784-8.656-2.188s-3.916-1.021-6.594-2.25c-2.678-1.229-3.403-1.61-5.656-2.281-2.253-.67-3.896-1.002-6.219-.969z" enable-background="new" filter="url(#hg)" opacity=".25"/>
+ <path d="M743.56-211.19c1.793.13 4.273.55 5.75 1.188s2.716.741 5.188 1.937c2.446 1.184 4.72 1.747 6.874 2.219 2.328.51 5.42.68 9 1.562-1.143-.97-6.747-1.59-8.53-1.937-1.784-.347-3.884-.888-6.532-2.031-2.648-1.144-3.395-1.517-5.625-2.125-2.23-.61-3.826-.91-6.125-.813z" enable-background="new" filter="url(#hf)" opacity=".25"/>
+ </g>
+ </g>
+ <path d="M912.45 671.2c1.642-3.218 3.518-5.735 4.861-9.849.8-3.658 3.312-2.03 7.26-8.397 1.403-2.24 5.477.391 8.966-2.399 1.27-.803 2.885-.404 4.483-.063 3.765 1.319 5.825 3.704 8.333 5.808 6.14 5.97 20.534 7.944 23.486 6.314 1.434-2.905 7.882-5.41 12.374-11.112.749-1.123 11.73-8.745 14.647-6.566" enable-background="new" fill="none" stroke="#000"/>
+ <path d="M937.07 660.78c7.363-3.233 13.811-8.908 20.708-13.385 3.31-1.97 6.87 3.216 10.796 3.599 2.298-.218 3.713 1.202 5.682 1.641 5.157 1.318 2.398 3.865 9.975 6.44 6.156 1.72 8.908-6.799 14.9-7.324 4.878-.503 8.1-.316 11.617-.252 3.927.139 4.079-3.498 6.061-5.304 2.98-2.805 7.156-1.85 10.145-4.74 1.018-1.385 1.955-3.011 2.735-5.109.882-2 3.04.306 4.798 1.263" enable-background="new" fill="none" stroke="#000"/>
+ <g fill-rule="evenodd">
+ <path transform="translate(48.571 195.53)" d="m403.28 1056.3l56.569-42.426 72.125 14.142-46.669 52.326-53.74 7.071-28.284-31.113z" enable-background="accumulate" filter="url(#he)" opacity=".25"/>
+ <path d="m590.84 1256.1c-1.407 18.801-1.145 32.751 2.082 49.303 3.226 16.552 16.406 45.907 20.334 63.184 3.926 17.267 2.694 38.31-12.46 51.148-15.317 12.977-42.05 21.599-67.831 15.734s-69.55-49.223-88.59-70.228c-19.112-21.083-63.761-93.851-77.94-124.28-14.177-30.425-12.66-36.719-8.119-45.53-9.367-24.52-12.414-50.067-33.712-75.577 30.325 3.114 43.88 26.956 60.126 47.14-5.53-48.076-18.055-64.416-28.374-90.724 29.994 6.082 50.579 31.872 63.98 72.712 9.554-3.918 18.238-9.373 30.187-9.061-11.298-41.696-17.949-69.916-36.687-101.07 53.442 5.67 83.657 80.639 78.971 87.96 9.978-2.243 19.006-6.53 30.437-5.65-11.249-38.348-21.048-76.869-3.66-118.65 0 0 48.287 65.436 54.39 85.805 6.103 20.37 1.52 38.701 1.52 38.701s16.96 31.085 20.293 51.094c3.373 20.241-3.533 59.103-4.946 77.983z" enable-background="new" fill="#ada469"/>
+ <path transform="matrix(-.90453 .25066 .25066 .90453 1043.9 219.06)" d="M719.5 738.7l18.312 15.432 44.411-15.388L805.5 713.2l11.464 19.221 30.672 12.784 25.097 5.728L892 723.2l16.023 23.826L947 752.2l10.245-6.198L964 754.7l25.5 11 2-40.5-35.551-14.538-32.493-21.527-40.452-11.466-21.307-15.533L840 685.2l-84.971-46.583-33.03 38.083-2.5 62z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#o)"/>
+ <path transform="matrix(-.90453 .25066 .25066 .90453 870.86 206.47)" d="M584 696.5l-6.563 17.156s-7.811 20.365-15.688 43.656c-3.938 11.646-7.883 24.041-10.938 35.125s-5.335 20.38-5.5 28.281c-.398 19.162 5.747 34.888 8.938 41.75-.772 3.555-1.991 9.454-3.344 18.094-1.92 12.268-3.718 27.154-2.375 39.875 1.382 13.088 6.812 28.188 12.594 43.031s12.054 29.227 15.22 38.031c6.631 18.452 9.992 31.576 11.311 48.5.582 7.456-.242 20.336-1.25 33.375s-2.186 26.301-1.687 36.969c.989 21.14 9.328 46.835 33.375 57.937 22.775 10.515 55.327 11.702 83.438-3.437 16.16-8.704 30.076-27.098 43.375-46.906s24.969-41.053 31.938-54.906c15.353-30.521 39.394-115.46 45.625-152.72 3.018-18.047 3.921-29.066 2.625-38.031-.979-6.766-3.828-12.147-6.875-16.22 2.042-27.507-.732-51.368 11.969-79.405l10.562-23.281-23.812 9.312c-17.49 6.838-28.902 19.045-36.594 32.062-.323.546-.563 1.108-.875 1.656.222-22.515 4.408-37.638
+6.594-58.688l1.968-19-17.03 8.656c-30.595 15.556-45.696 48.193-49.72 90.22-4.245-.626-8.831-1.02-13.812-.844-.291-39.18-.396-67.037 8.594-99.375l5.594-20.125-19.438 7.656c-30.91 12.204-47.86 41.931-56.625 68.375-4.383 13.222-6.746 25.801-7.594 35.938a92.19 92.19 0 0 0-.312 7.719c-3.242-.037-6.42.136-10.062.5.041-39.005-3.485-79.754-32.281-116.5L584 696.498zm5.813 43.812c16.807 30.644 17.475 63.967 16.938 99.75l-.22 15.062 12.036-6.54c8.662-3.132 19.56-.227 31.934-.835l14.675 9.357-6.331-25.794c-.09-.23-.22-.417-.25-.72-.2-2.039-.222-5.472.125-9.624.694-8.304 2.79-19.585 6.625-31.156 5.155-15.553 13.488-31.192 25.125-42.531-4.684 28.638-3.216 60.259-3.012 95.805l-2.766 13.262 15.496-7.598c9.03-2.758 17.19-.35 29.281 1.094l13.246 9.444L741.094 840c1.448-30.972 8.222-53.678 20.719-68.875-2.987 19.779-5.43 41.785.313 78.344l1.065 6.373-2.938 11.517 10.617-8.168 9.19 10.222-1.549-10.464
+3.427-6.95c5.7-13.21 10.173-26.212 16.344-36.655.96-1.624 2.031-3.065 3.062-4.563-3.68 21.155-2.427 40.208-4.093 57.781l-4.68 7.807 7.398.225c3.22 3.483 3.868 3.85 4.563 8.656s.318 14.4-2.563 31.625c-5.568 33.288-31.846 77.84-43.74 101.49-6.605 13.13-18.528 57.486-31.123 76.246s-28.53 39.767-37.172 44.42c-21.49 11.575-44.556 25.507-60.619 18.09-14.375-6.636-23.04-21.192-23.814-37.742-.383-8.188.613-21.31 1.625-34.406 1.013-13.097 11.29-22.571 15.423-36.563 5.373-18.181-1.447-36.594-12.5-53.937-6.486-10.178-23.977-24.258-29.548-38.562s-10.368-29.003-11.28-37.656c-.927-8.771.422-23.025 2.218-34.5 1.796-11.475 3.844-20.281 3.844-20.281l9.423-3.615-10.485-3.885s-8.5-15.31-8.094-34.812c.071-3.423 1.836-12.728 4.719-23.188s6.764-22.553 10.625-33.97c3.044-9.002 5.78-16.602 8.344-23.687z" clip-path="url(#am)" enable-background="new" filter="url(#ds)" opacity=".588"/>
+ <g transform="translate(324.57 331.53)" clip-path="url(#is)" enable-background="new" fill="#fff">
+ <path transform="matrix(-.90453 .25066 .25066 .90453 -52.2 74.097)" d="m-15.668 843.49l-49.497-15.556-26.87 52.326 41.012 45.255 49.497-38.184z" enable-background="accumulate" filter="url(#dr)"/>
+ <path transform="matrix(-.90453 .25066 .25066 .90453 -46.928 75.511)" d="m118.71 859.93l-55.154-46.669-43.841 36.77 33.941 53.74-13.597 85.462-39.445 28.292-41.012 11.314-2.828 46.669 56.569 25.456 18.944-69.65 23.457-58.857 46.348-72.615 16.62-39.912z" enable-background="accumulate" filter="url(#dq)"/>
+ </g>
+ <path transform="matrix(-.90453 .25066 .25066 .90453 277.64 407.04)" d="m-70.822 932.58l60.811-26.87 100.41 31.113-63.64 31.113-82.024-16.971-15.556-18.385z" enable-background="accumulate" filter="url(#cy)" opacity=".25"/>
+ <path transform="matrix(-.90453 .25066 .25066 .90453 870.86 206.47)" d="M583.06 715.75c-12.106 34.45-26.714 68.533-31.75 104.84-.832 14.929 4.59 29.159 8.844 43.062-5.916 27.201-10.137 56.9 1.156 83.125 13.517 38.161 35.001 75.682 32.423 117.47-.948 29.294-9.014 60.994 5.39 88.282 10.199 19.335 33.14 27.312 53.968 27.668 27.862 1.174 56.463-11.622 72-35.261 22.596-29.372 41.802-61.497 55.24-96.06 16.89-45.506 29.672-92.561 37.934-140.4 1.824-12.941 3.1-27.47-4.58-38.823-3.43-7.336.043-15.56-.684-23.31.674-24.995 4.013-50.664 16.653-72.596-17.733 6.445-35.073 16.56-44.003 33.864-3.935 6.71-7.605 13.574-11.372 20.386-3.55-30.014 3.72-59.648 6.781-89.281-20.166 9.055-36.877 25.655-44.175 46.682-6.304 15.58-8.802 32.317-10.263 49.037-8.253-1.52-16.684-2.102-25.062-1.5-.963-38.698-.467-79.407 10.97-115.91-18.682 6.218-35.167 18.736-45.629 35.387-13.853 20.88-21.26 45.754-23.059 70.613.586
+4.325-.06 11.84-6.343 9.875-5.332.018-10.63.679-15.938 1.094 1.147-39.381-3.342-81.628-27.062-114.22-3.061-3.637-5.637-7.685-8.625-11.344l-2.813 7.312zm7.75 13.844c18.565 29.296 22.482 64.82 22.125 98.875.204 5.175-.517 11.829.125 16.062 12.319-6.103 26.739-2.44 39.781-2.187 2.317 1.223 3.192 1.652 1.906-1.407-4.164-13.953-1.848-28.613 1.805-42.408 6.367-26.29 20.628-51.088 42.82-67.03-8.617 37.237-5.716 76.562-6.094 113.97 12.253-6.91 27.28-3.446 40.031-.25 3.393 3.535 2.29-.73 2.188-3.812-.483-21.371 4.131-43.07 13.688-62.156 5.963-10.687 14.243-19.804 22.438-28.875-7.872 33.838-9.203 69.336-2.719 103.5 1.725-1.411 4.607-.454 5.656-.375 9.684-21.237 16.351-45.381 34.89-60.742 1.874-.371-1.448 8.525-1.484 11.898-3.535 21.846-7.175 44.142-8.784 66.219-8.784 2.342 2.849 2.323 3.469 4.062 7.923 10.566 4.663 24.405 3.632 36.353-7.064 45.034-22.142 87.362-35.954 130.68-12.075 32.95-27.374
+58.852-47.888 87.202-10.953 13.551-23.245 27.851-40.844 32.5-20.156 6.242-44.207 10.877-62.6.046-17.29-12.34-21.024-35.709-19.262-55.686.048-15.826 4.938-28.512 4.41-43.492-.538-15.263-2.291-30.565-6.542-46.866-4.252-16.302-9.044-24.918-16.12-41.573-7.24-17.045-15.07-36.749-18.204-56.288-1.75-18.627 2.891-37.123 5.78-55.25 3.297-2.837-1.597-5.196-2.312-8.187-7.6-17.015-8.407-36.775-2.742-54.56 7.13-25.072 15.761-49.632 24.68-74.128l2.125 3.906z" clip-path="url(#cj)" enable-background="new" filter="url(#ir)" opacity=".588"/>
+ <path transform="matrix(-.90453 .25066 .25066 .90453 1043.9 219.06)" d="m735.06 733.04l2.755 21.089 44.411-15.388 4.851-22.39-3.936-22.052-22.452-36.593-8.28 30.305-17.35 45.029z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#bz)"/>
+ <path transform="matrix(-.90453 .25066 .25066 .90453 1043.9 219.06)" d="m831.81 730.29l15.822 14.905 20.855 2.9-1.59-39.926 8.325-30.508-7.165-6.341-21.697 20.942-14.55 38.028z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#by)"/>
+ </g>
+ <g transform="translate(324.57 331.53)" clip-path="url(#iq)" enable-background="new" filter="url(#ip)">
+ <path d="M36.494 811.806l-14.799 11.372-17.47-31.162 14.663.65 17.606 19.14z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
+ <path d="M-55 757.2h182v177H-55z" enable-background="accumulate" fill="none"/>
+ </g>
+ <g transform="translate(324.57 331.53)" clip-path="url(#io)" enable-background="new" filter="url(#in)">
+ <path d="m83.111 790.72l-28.201 12.855-5.658-21.687-13.943-25.046 6.325-6.88 26.384 18.51 15.094 22.249z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
+ <path d="M-22 696.2h165v176H-22z" enable-background="accumulate" fill="none"/>
+ </g>
+ <g fill-rule="evenodd">
+ <path d="m1084.8 1267.3c6.794 18.903 10.494 33.3 11.89 51.212 1.397 17.912-3.783 51.801-2.9 70.656 0.881 18.845 8.133 40.099 27.345 48.969 19.419 8.966 49.319 10.211 74.12-3.146 24.8-13.357 57.4-70.326 70.973-97.309 13.624-27.084 38.761-114.5 44.661-149.77s2.551-41.3-4.617-49.055c2.64-27.84-1.5-54.935 13.11-87.186-30.249 11.826-37.382 40.161-48.319 65.505-8-50.933 0.21-71.273 3.319-101.22-29.065 14.778-42.862 47.114-45 92.857-10.924-1.304-21.391-4.434-33.571-0.714-0.264-46.023-1.464-76.889 8.91-114.21-53.254 21.027-62.946 106.59-56.053 112.78-10.883 0.535-21.371-1.297-32.857 2.857 0.638-42.57-0.26-84.909-30-122.86 0 0-30.958 80.922-31.43 103.57-0.47 22.65 9.452 40.166 9.452 40.166s-8.568 36.741-6.298 58.232c2.295 21.741 20.443 59.676 27.266 78.658z" enable-background="new" fill="#ada469"/>
+ <path transform="translate(324.57 331.53)" d="M719.5 738.7l18.312 15.432 44.411-15.388L805.5 713.2l11.464 19.221 30.672 12.784 25.097 5.728L892 723.2l16.023 23.826L947 752.2l10.245-6.198L964 754.7l25.5 11 2-40.5-35.551-14.538-32.493-21.527-40.452-11.466-21.307-15.533L840 685.2l-84.971-46.583-33.03 38.083-2.5 62z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#o)"/>
+ <path transform="translate(498.6 269.37)" d="M584 696.5l-6.563 17.156s-7.811 20.365-15.688 43.656c-3.938 11.646-7.883 24.041-10.938 35.125s-5.335 20.38-5.5 28.281c-.398 19.162 5.747 34.888 8.938 41.75-.772 3.555-1.991 9.454-3.344 18.094-1.92 12.268-3.718 27.154-2.375 39.875 1.382 13.088 6.812 28.188 12.594 43.031s12.054 29.227 15.22 38.031c6.631 18.452 9.992 31.576 11.311 48.5.582 7.456-.242 20.336-1.25 33.375s-2.186 26.301-1.687 36.969c.989 21.14 9.328 46.835 33.375 57.937 22.775 10.515 55.327 11.702 83.438-3.437 16.16-8.704 30.076-27.098 43.375-46.906s24.969-41.053 31.938-54.906c15.353-30.521 39.394-115.46 45.625-152.72 3.018-18.047 3.921-29.066 2.625-38.031-.979-6.766-3.828-12.147-6.875-16.22 2.042-27.507-.732-51.368 11.969-79.405l10.562-23.281-23.812 9.312c-17.49 6.838-28.902 19.045-36.594 32.062-.323.546-.563 1.108-.875 1.656.222-22.515 4.408-37.638 6.594-58.688l1.968-19-17.03
+8.656c-30.595 15.556-45.696 48.193-49.72 90.22-4.245-.626-8.831-1.02-13.812-.844-.291-39.18-.396-67.037 8.594-99.375l5.594-20.125-19.438 7.656c-30.91 12.204-47.86 41.931-56.625 68.375-4.383 13.222-6.746 25.801-7.594 35.938a92.19 92.19 0 0 0-.312 7.719c-3.242-.037-6.42.136-10.062.5.041-39.005-3.485-79.754-32.281-116.5L584 696.498zm5.813 43.812c16.807 30.644 17.475 63.967 16.938 99.75l-.22 15.062 12.036-6.54c8.662-3.132 19.56-.227 31.934-.835l14.675 9.357-6.331-25.794c-.09-.23-.22-.417-.25-.72-.2-2.039-.222-5.472.125-9.624.694-8.304 2.79-19.585 6.625-31.156 5.155-15.553 13.488-31.192 25.125-42.531-4.684 28.638-3.216 60.259-3.012 95.805l-2.766 13.262 15.496-7.598c9.03-2.758 17.19-.35 29.281 1.094l13.246 9.444L741.094 840c1.448-30.972 8.222-53.678 20.719-68.875-2.987 19.779-5.43 41.785.313 78.344l1.065 6.373-2.938 11.517 10.617-8.168 9.19 10.222-1.549-10.464 3.427-6.95c5.7-13.21
+10.173-26.212 16.344-36.655.96-1.624 2.031-3.065 3.062-4.563-3.68 21.155-2.427 40.208-4.093 57.781l-4.68 7.807 7.398.225c3.22 3.483 3.868 3.85 4.563 8.656s.318 14.4-2.563 31.625c-5.568 33.288-31.793 123.17-43.688 146.81-6.605 13.13-18.03 33.896-30.625 52.656s-27.359 35.534-36 40.187c-21.49 11.574-48.78 10.26-64.844 2.844-14.375-6.637-20.538-23.45-21.312-40-.383-8.188.613-21.31 1.625-34.406 1.013-13.097 11.29-22.571 15.423-36.563 5.373-18.181-1.447-36.594-12.5-53.937-6.486-10.178-23.977-24.258-29.548-38.562s-10.368-29.003-11.28-37.656c-.927-8.771.422-23.025 2.218-34.5 1.796-11.475 3.844-20.281 3.844-20.281l9.423-3.616-10.485-3.884s-8.5-15.31-8.094-34.812c.071-3.424 1.836-12.728 4.719-23.188s6.764-22.553 10.625-33.97c3.044-9.002 5.78-16.602 8.344-23.687z" clip-path="url(#am)" enable-background="new" filter="url(#ds)" opacity=".588"/>
+ <g transform="translate(324.57 331.53)" clip-path="url(#im)" fill="#fff">
+ <path d="m824.49 818.48l-49.497-15.556-26.87 52.326 41.012 45.255 49.497-38.184z" enable-background="accumulate" filter="url(#dr)"/>
+ <path d="m964.49 855.25l-55.154-46.669-43.841 36.77 33.941 53.74 7.071 66.468-50.912 35.355-41.012 11.314-2.828 46.669 56.569 25.456 63.64-76.368 24.042-94.752 8.485-57.983z" enable-background="accumulate" filter="url(#dq)"/>
+ </g>
+ <path transform="translate(48.571 195.53)" d="m1045.3 1043.6l60.811-26.87 100.41 31.113-63.64 31.113-82.024-16.971-15.556-18.385z" enable-background="accumulate" filter="url(#cy)" opacity=".25"/>
+ <path transform="translate(498.6 269.37)" d="M583.06 715.75c-12.106 34.45-26.714 68.533-31.75 104.84-.832 14.929 4.59 29.159 8.844 43.062-5.916 27.201-10.137 56.9 1.156 83.125 13.517 38.161 35.001 75.682 32.423 117.47-.948 29.294-9.014 60.994 5.39 88.282 10.199 19.335 33.14 27.312 53.968 27.668 27.862 1.174 56.463-11.622 72-35.261 22.596-29.372 41.802-61.497 55.24-96.06 16.89-45.506 29.672-92.561 37.934-140.4 1.824-12.941 3.1-27.47-4.58-38.823-3.43-7.336.043-15.56-.684-23.31.674-24.995 4.013-50.664 16.653-72.596-17.733 6.445-35.073 16.56-44.003 33.864-3.935 6.71-7.605 13.574-11.372 20.386-3.55-30.014 3.72-59.648 6.781-89.281-20.166 9.055-36.877 25.655-44.175 46.682-6.304 15.58-8.802 32.317-10.263 49.037-8.253-1.52-16.684-2.102-25.062-1.5-.963-38.698-.467-79.407 10.97-115.91-18.682 6.218-35.167 18.736-45.629 35.387-13.853 20.88-21.26 45.754-23.059 70.613.586 4.325-.06 11.84-6.343
+9.875-5.332.018-10.63.679-15.938 1.094 1.147-39.381-3.342-81.628-27.062-114.22-3.061-3.637-5.637-7.685-8.625-11.344l-2.813 7.312zm7.75 13.844c18.565 29.296 22.482 64.82 22.125 98.875.204 5.175-.517 11.829.125 16.062 12.319-6.103 26.739-2.44 39.781-2.187 2.317 1.223 3.192 1.652 1.906-1.407-4.164-13.953-1.848-28.613 1.805-42.408 6.367-26.29 20.628-51.088 42.82-67.03-8.617 37.237-5.716 76.562-6.094 113.97 12.253-6.91 27.28-3.446 40.031-.25 3.393 3.535 2.29-.73 2.188-3.812-.483-21.371 4.131-43.07 13.688-62.156 5.963-10.687 14.243-19.804 22.438-28.875-7.872 33.838-9.203 69.336-2.719 103.5 1.725-1.411 4.607-.454 5.656-.375 9.684-21.237 16.351-45.381 34.89-60.742 1.874-.371-1.448 8.525-1.484 11.898-3.535 21.846-3.297 44.173-4.906 66.25-1.312 1.377 2.849 2.323 3.469 4.062 7.923 10.566 3.123 24.831 2.092 36.78-7.064 45.034-21.766 88.38-35.577 131.7-12.075 32.95-30.72 63.08-51.234 91.43-10.953
+13.55-23.245 27.85-40.844 32.5-20.156 6.24-43.576 5.174-61.97-5.657-17.29-12.34-21.023-35.709-19.261-55.686.048-15.826 2.372-27.8 7.917-42.805s2.471-31.332-1.78-47.633-12.18-26.26-21.822-42.204-17.637-36.037-20.772-55.577c-1.75-18.627 2.892-37.123 5.781-55.25 3.296-2.837-1.598-5.196-2.312-8.187-7.602-17.015-8.408-36.775-2.743-54.56 7.13-25.072 15.761-49.632 24.68-74.128l2.125 3.906z" clip-path="url(#cj)" enable-background="new" filter="url(#il)" opacity=".588"/>
+ <path transform="translate(324.57 331.53)" d="m735.06 733.04l2.755 21.089 44.411-15.388 4.851-22.39-3.936-22.052-22.452-36.593-8.28 30.305-17.35 45.029z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#bz)"/>
+ <path transform="translate(324.57 331.53)" d="m831.81 730.29l15.822 14.905 20.855 2.9-1.59-39.926 8.325-30.508-7.165-6.341-21.697 20.942-14.55 38.028z" clip-path="url(#e)" enable-background="accumulate" fill="#fff" filter="url(#by)"/>
+ </g>
+ <g transform="translate(324.57 331.53)" clip-path="url(#ik)" filter="url(#ij)">
+ <path d="M910.14 746.31l32.613 5.174-.361-23.876 7.188-29.682-8.45-5.264-21.823 26.511-9.167 27.137z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
+ <path d="M877.52 650.19h123.04v172.53H877.52z" enable-background="accumulate" fill="none"/>
+ </g>
+ <g transform="translate(324.57 331.53)" clip-path="url(#ii)" filter="url(#ih)">
+ <path d="M964 754.69l18.429 7.465 9.071-36.964-14.87 4.839L964 754.69z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
+ <path d="M924.9 677.06h142.13v125.16H924.9z" enable-background="accumulate" fill="none"/>
+ </g>
+ <g stroke-miterlimit="1">
+ <path d="m596.57 400.85h440v376h-440z" fill="none" stroke="#f8d615" stroke-width="18"/>
+ <path d="m104.57 248.85h1684v1292h-1684z" fill="none" stroke="#f83615" stroke-width="18"/>
+ <path d="M3407.4 296.46h522.57v1182.5H3407.4z" fill="url(#ig)" stroke="#f815bb" stroke-width="13.347"/>
+ </g>
+ <g transform="matrix(1.0057 0 0 2.3995 3452.3 -18.515)" clip-path="url(#if)" enable-background="new">
+ <g filter="url(#aq)">
+ <g transform="translate(-174.03 62.156)" filter="url(#g)">
+ <path d="m1268.3 663.77s-0.296 26.161 4.643 37.857 20.038 26.487 28.572 31.429 18.929 8.571 18.929 8.571l117.86-115 17.857-75.714-96.43 38.571-91.428 74.286z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+ <path d="M1197.8 486.14h333.75v309.71H1197.8z" enable-background="accumulate" fill="none"/>
+ </g>
+ </g>
+ <g transform="translate(-174.03 62.156)" enable-background="new" filter="url(#g)" opacity=".18">
+ <path d="m1268.3 663.77s-0.296 26.161 4.643 37.857 20.038 26.487 28.572 31.429 18.929 8.571 18.929 8.571l117.86-115 17.857-75.714-96.43 38.571-91.428 74.286z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+ <path d="M1197.8 486.14h333.75v309.71H1197.8z" enable-background="accumulate" fill="none"/>
+ </g>
+ </g>
+ <path d="M3492.3 296.46H3930v902.66h-437.7z" fill="#fff" stroke="#f8d615" stroke-miterlimit="1" stroke-width="18"/>
+ <g transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" clip-path="url(#ie)" enable-background="new" filter="url(#id)">
+ <path d="M36.494 811.806l-14.799 11.372-17.47-31.162 14.663.65 17.606 19.14z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
+ <path d="M-55 757.2h182v177H-55z" enable-background="accumulate" fill="none"/>
+ </g>
+ <g transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" clip-path="url(#ic)" enable-background="new" filter="url(#gd)">
+ <path d="m83.111 790.72l-28.201 12.855-5.658-21.687-13.943-25.046 6.325-6.88 26.384 18.51 15.094 22.249z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
+ <path d="M-22 696.2h165v176H-22z" enable-background="accumulate" fill="none"/>
+ </g>
+ <path transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" d="m332.34 898.39l-32.732-61.3-37.617 45.106c2.177 1.317 5.774-20.856 45.6-64.417l24.749 80.61z" clip-path="url(#gc)" enable-background="accumulate" fill="#fff" fill-rule="evenodd" filter="url(#gb)" opacity=".5"/>
+ <g clip-path="url(#ga)">
+ <g fill-rule="evenodd">
+ <g enable-background="new">
+ <path transform="matrix(.71488 -.46488 .26446 2.3151 3478.4 126.16)" d="m245.12 100.05s-47.128-31.647-67.215-35.801c-20.038-4.144-38.473-3.318-51.934 13.607s-12.077 61.265-13.536 86.97 2.55 70.177 17.605 88.666c15.055 18.488 45.886 13.585 49.927 21.414 2.213 4.287 65.152-174.86 65.152-174.86z" enable-background="accumulate" fill="url(#r)"/>
+ <path transform="matrix(.71488 -.46488 .26446 2.3151 3478.4 126.16)" d="M135.38 82.018s26.344 1.939 37.633 13.903c11.415 12.097 13.735 21.332 15.296 37.735 1.563 16.425-.85 28.418-7.814 36.037s-1.004 19.583-25.916 12.071-27.032-27.783-26.515-46.305c.517-18.529 7.316-53.441 7.316-53.441z" enable-background="accumulate" fill="url(#q)"/>
+ <path transform="matrix(.71488 -.46488 .26446 2.3151 3478.4 126.16)" d="M135.65 81.927s-4.645 16.365.588 28.563c5.488 12.793 27.224 44.26 27.224 54.656l22.656-5c2.542-6.966 3.21-15.752 2.188-26.5-1.562-16.403-3.867-25.621-15.281-37.719-9.655-10.232-31.593-13.375-37.375-14z" enable-background="new" fill="url(#p)"/>
+ </g>
+ <g enable-background="new">
+ <path d="M4043.297 824.626l-.09-.006c-1.489 1.728-6.783 2.02-7.718 20.884-.878 17.694 13.035 44.859 15.06 47.837 1.636 2.403 3.427 4.343 5.205 5.58l1.41.916c1.894 1.031 3.7 1.38 5.163 1.19 3.177-.414 5.214-.812 7.238-1.183 2.025-.372 2.592-1.8 3.707-2.078 1.156-.288 2.255.9 6.345-.372 4.09-1.271 5.587-1.894 6.324-2.566.765-.698 1.86-1.592 2.549-2.999 1.962.51 3.823.346 5.31-.58 3.08-1.92 5.084-3.12 6.998-4.722 1.536-1.285 2.513-3.421 2.759-4.073.246-.653.183-1.71.211-1.754.047-.072.351-.13.55-.906 1.07-4.167 2.968-12.778
+3.16-14.38.193-1.594.324-3.178.42-4.11.056-.54-.046-2.136-.017-2.27.04-.187.317-.518.401-1.098.404-2.783.343-5.237.292-8.675-.05-3.438-.44-11.267-.995-13.482-.356-1.423-.708-2.109-1.051-2.478-.065-.06-.119-.145-.18-.2-.02-.015-.043-.004-.062-.017-.303-.265-.59-.545-1.13-.839-.972-.527-2.393-1.283-3.937-1.684-.514-.134-1.041-.17-1.572-.205-3.591-.231-9.115-.108-10.396 1.072-1.593-1.244-3.874-2.542-5.879-2.746-3.086-.313-5.002-.546-6.953-.776-1.952-.23-1.73.464-2.958.32-1.328-.155-1.76-1.022-5.568-1.302-3.577-.262-9.087-.095-10.397 1.072-1.593-1.245-3.872-2.542-5.878-2.746-3.087-.313-5.006-.472-6.958-.702-.663-.078-1.055.01-1.364.079z" enable-background="new" fill="#bcb786"/>
+ <g transform="matrix(1.0047 .1075 -.04506 2.3971 3818.4 1782.9)" clip-path="url(#fz)" enable-background="new" filter="url(#fy)">
+ <path d="M229.94-409.12c-3.558.05-9.024.36-10.303.904-1.606-.447-3.903-.881-5.9-.877a979.03 979.03 0 0 1-6.907 0c-.66-.003-1.048.068-1.353.11v1.096c.12-.18.393-.69.95-.767.747-.103 5.17-.151 7.31-.11 1.775.035 4.455.274 6.39.96.32.113.618.273.891.41 1.964.987 7.944 4.302 7.944 4.302s-6.633-3.948-7.483-4.439c-.203-.117-.575-.258-1.036-.41 1.22-.449 5.076-.62 7.828-.713 3.024-.102 3.348-.09 5.41.192 2.13.29 3.34.602 3.34.602s-.08-.64 1.035-.794c.748-.103 5.17-.152 7.31-.11 2.07.04 5.366.407 7.282 1.37 1.003.504 3.035 1.569 4.795 2.536l.096-.02s-3.58-2.162-4.43-2.653c-.204-.117-.575-.258-1.037-.411 1.22-.448 5.047-.62 7.8-.712 3.024-.102 3.347-.09 5.41.191 1.954.267 3.013.53 3.195.576l-.027-.312a8.503 8.503 0 0 0-1.4-.357c-1.301-.235-3.4-.602-5.51-.564-3.571.064-9.052.356-10.302.904-1.606-.447-3.877-.881-5.871-.877-3.072.007-4.994.01-6.936
+0-1.943-.009-1.713.28-2.936.274-1.322-.005-1.766-.354-5.555-.301M206.2-407.48c1.92.817 4.577 2.193 6.159 3.397s2.908 1.774 5.555 3.918c.885.718 1.748 1.35 2.591 1.922l.541-.19a57.511 57.511 0 0 1-2.269-1.622c-2.822-2.12-3.627-2.81-6.015-4.274s-4.1-2.366-6.562-3.15" enable-background="new"/>
+ <path d="M237.8-407.48c1.92.817 4.606 2.193 6.188 3.397.813.62 1.558 1.07 2.45 1.654l.65-.116a40.414 40.414 0 0 0-2.697-1.784c-2.389-1.465-4.128-2.366-6.59-3.151" enable-background="new"/>
</g>
- <rect
- id="rect6247"
- width="440"
- height="376"
- x="548"
- y="205.32275"
- style="opacity:1;fill:none;fill-opacity:1;stroke:#f8d615;stroke-width:18;stroke-linejoin:miter;stroke-miterlimit:1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
- <rect
- style="opacity:1;fill:none;fill-opacity:1;stroke:#f83615;stroke-width:18;stroke-linejoin:miter;stroke-miterlimit:1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="rect6676"
- width="1684"
- height="1292"
- x="56"
- y="53.322754" />
- <rect
- style="opacity:1;fill:url(#pattern5557);fill-opacity:1;stroke:#f815bb;stroke-width:13.34657478;stroke-linejoin:miter;stroke-miterlimit:1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="rect6731"
- width="522.56604"
- height="1182.4679"
- x="3493.3721"
- y="87.178711" />
- <g
- id="g7477"
- transform="matrix(0.53474256,0,0,1,1882.7509,3.0962157)">
- <rect
- y="99.705269"
- x="3039.4895"
- height="902.66437"
- width="818.51605"
- id="rect6979"
- style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#f8d615;stroke-width:18;stroke-linejoin:miter;stroke-miterlimit:1;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
- <g
- clip-path="url(#clipPath6975)"
- id="g4303-9"
- style="display:inline;enable-background:new"
- transform="matrix(1.8806916,0,0,2.3994874,1997.8763,-394.32602)">
- <path
- inkscape:connector-curvature="0"
- style="display:inline;opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter11361-3);enable-background:new"
- d="m 304.64285,526.6479 c -10,0.35715 -18.21428,2.85714 -18.21428,2.85714 l 7.5,6.07143 10.35714,3.57143 16.07143,0.35714 22.5,-5.35714 7.85714,1.07143 20.35715,-2.14286 -10.35715,6.78572 c 5.45923,-1.02361 17.39329,3.56911 9.64286,5.35714 -1.74,0.40142 13.92857,-4.64285 13.92857,-4.64285 l 2.5,-4.64287 3.57143,-9.28571 11.42857,0 18.21428,-4.64286 3.57144,-4.99999 -16.07144,1.07142 -12.14285,2.14286 -14.64286,-5 -70.6921,16.70774 -5.37933,-5.27917 z"
- id="path10326-6"
- sodipodi:nodetypes="cccccccccsccccccccccc"
- transform="matrix(10.726753,0,0,10.726753,-2882.1235,-4565.4583)"
- inkscape:export-filename="/home/cheeseness/Documents/LCA09/mascot/tuz_new.png"
- inkscape:export-xdpi="142.10527"
- inkscape:export-ydpi="142.10527" />
- <g
- style="display:inline;opacity:1;enable-background:new"
- id="g7882-9"
- transform="matrix(0.71084,-0.1937433,0.262963,0.9648058,503.68027,136.48399)">
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="czzzzcc"
- id="path7876-3"
- d="m 245.12255,100.05344 c 0,0 -47.12811,-31.646921 -67.21465,-35.800939 -20.03792,-4.143963 -38.4729,-3.317578 -51.93364,13.607323 -13.46074,16.924901 -12.07739,61.265196 -13.53554,86.969546 -1.45815,25.70435 2.54945,70.17701 17.6046,88.66552 15.05516,18.4885 45.88634,13.58502 49.92695,21.4137 2.21283,4.28736 65.15228,-174.85515 65.15228,-174.85515 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient7904-7);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="czzzzzc"
- id="path7878-3"
- d="m 135.37935,82.017807 c 0,0 26.34355,1.938783 37.63307,13.903188 11.41494,12.097335 13.73457,21.331515 15.29586,37.734585 1.56337,16.42499 -0.84957,28.41812 -7.81382,36.03734 -6.96425,7.61922 -1.00429,19.58332 -25.91605,12.07107 -24.91176,-7.51225 -27.03224,-27.78298 -26.51523,-46.30475 0.51721,-18.52898 7.31617,-53.441433 7.31617,-53.441433 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient7906-6);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="czccssc"
- id="path7880-8"
- d="m 135.648,81.927211 c 0,0 -4.64465,16.365075 0.58825,28.563099 5.48794,12.79254 27.22425,44.26007 27.22425,54.65565 l 22.65625,-5 c 2.54218,-6.96644 3.21052,-15.75206 2.1875,-26.5 -1.56129,-16.40307 -3.8663,-25.62141 -15.28125,-37.718749 -9.65488,-10.232047 -31.59311,-13.374857 -37.375,-14 z"
- style="display:inline;opacity:1;fill:url(#radialGradient7908-0);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- </g>
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 845.03125,1154.7776 c -4.28571,0.7143 -27.62815,3.6181 -57.85714,10 -30.22899,6.3819 -57.31395,4.9661 -135.78608,17.3296 -79.85178,12.5808 -94.06436,42.5423 -108.12225,47.0643 -14.70014,4.7286 -145.37739,-65.8225 -145.37739,-65.8225 l 4.28572,-94.2857 c 0,0 85.88551,-16.2009 112.14285,-33.5714 26.25735,-17.3705 45.58238,-49.66602 59.28572,-71.42861 13.70334,-21.76259 32.85714,-71.42858 32.85714,-71.42858 l 238.57143,262.14289 z"
- id="path7917-0"
- sodipodi:nodetypes="czzzcczzcc" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8888-6);enable-background:accumulate"
- d="m 332.34019,898.38549 -32.73181,-61.29956 -37.61734,45.10646 c 2.17675,1.31711 5.77425,-20.85603 45.6004,-64.41708 l 24.74875,80.61018 z"
- id="path7919-5"
- clip-path="url(#clipPath8658-06)"
- sodipodi:nodetypes="ccccc"
- transform="translate(276,136)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient6951);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8892-7);enable-background:accumulate"
- d="m 200.81833,863.03015 146.3711,-51.61879 243.95184,226.27414 -241.83052,140.0072 -181.01934,-87.6813 32.52692,-226.98125 z"
- id="path7923-6"
- clip-path="url(#clipPath2833-2)"
- sodipodi:nodetypes="cccccc"
- transform="translate(276,136)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#0f0f0f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 642.88839,640.13471 c 0,0 -29.55406,40.57305 -47.85714,74.28571 -18.30309,33.71267 -58.62109,126.35694 -70.35714,171.07143 -11.7594,44.80344 -62.5,123.57145 -62.5,123.57145 l 76.07143,18.2143 c 0,0 11.80712,-12.8234 31.07142,-46.07146 19.2643,-33.24808 60.35715,-138.57143 60.35715,-138.57143 l 13.21428,-202.5 z"
- id="path7921-6"
- sodipodi:nodetypes="czzcczcc" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.4;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8856-2);enable-background:accumulate"
- d="m 430.28131,381.94122 c -7.07106,2.82843 -236.18124,32.15181 -236.18124,32.15181 l -39.63961,359.83304 90.19849,92.63961 52.3259,-114.5513 100.46804,-186.39192 32.82842,-183.68124 z"
- id="path7925-4"
- sodipodi:nodetypes="ccccccc"
- clip-path="url(#clipPath3665-9)"
- transform="translate(276,136)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 969.67051,1164.0346 c 0,0 23.25628,11.3937 36.06779,20.4761 12.6974,9.0015 29.4724,24.6491 41.6924,37.3605 12.3055,12.8002 20.1127,22.5987 41.5327,24.1608 21.4322,1.5629 53.2824,-8.7876 73.296,-24.6642 20.0135,-15.8766 45.6469,-69.2328 45.6469,-69.2328 l -127.1608,-143.0717"
- id="path7927-0"
- sodipodi:nodetypes="czzzzcc" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.75;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8860-3);enable-background:accumulate"
- d="M 331.34019,641.50471 216.17367,835.36467 260.2153,925.96265 357.79603,732.21539 331.34019,641.50471 Z"
- id="path7929-0"
- clip-path="url(#clipPath8642-9)"
- sodipodi:nodetypes="ccccc"
- transform="translate(276,136)" />
- <g
- style="display:inline;opacity:1;enable-background:new"
- id="g7931-4"
- transform="matrix(0.9934486,0.1142802,-0.1142802,0.9934486,-9.24324,588.09054)"
- inkscape:transform-center-x="-347.89063"
- inkscape:transform-center-y="-28.255779">
- <path
- inkscape:connector-curvature="0"
- style="display:inline;opacity:1;fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 1049.205,-282.26672 -0.09,0.008 c -1.3874,0.88445 -6.6033,1.6072 -6.629,9.52344 -0.024,7.42525 15.0129,17.09146 17.1563,18.09375 1.7302,0.80909 3.5916,1.40876 5.4063,1.71875 l 1.4374,0.21875 c 1.9197,0.21194 3.72,0.15141 5.1563,-0.0937 3.1191,-0.5324 5.1116,-0.92861 7.0937,-1.3125 1.9821,-0.38387 2.4743,-1.03965 3.5626,-1.28125 1.1287,-0.25066 2.2702,0.11629 6.25,-0.875 3.9795,-0.99128 5.4294,-1.4193 6.125,-1.78125 0.7222,-0.37601 1.7617,-0.87058 2.375,-1.53125 1.9629,-0.012 3.7937,-0.29105 5.2187,-0.84375 2.9512,-1.14461 4.8732,-1.86942 6.6875,-2.75 1.4557,-0.70653 2.3191,-1.70203 2.5312,-2 0.2123,-0.29796 0.099,-0.72855 0.125,-0.75 0.043,-0.0352 0.3405,-0.094 0.5,-0.4375 0.859,-1.84708 2.3232,-5.62764 2.4376,-6.3125 0.1137,-0.68215 0.168,-1.35277 0.2187,-1.75 0.029,-0.22951 -0.1471,-0.8789 -0.125,-0.9375 0.031,-0.082 0.2883,-0.25057 0.3437,-0.5 0.2663,-1.19832 0.089,-2.20736 -0.125,-3.625 -0.2139,-1.41764 -0.9716,-4.61463 -1.625,-5.46875 -0.4194,-0.54857 -0.7993,-0.7925 -1.1562,-0.90625 -0.067,-0.0173 -0.1239,-0.0467 -0.1875,-0.0625 -0.021,-0.004 -0.042,0.003 -0.062,0 -0.3116,-0.0755 -0.6085,-0.15867 -1.1562,-0.21875 -0.9855,-0.10812 -2.4247,-0.2594 -3.9688,-0.25 -0.5147,0.003 -1.0371,0.0476 -1.5625,0.0937 -3.5589,0.31228 -9.0098,0.99108 -10.2187,1.625 -1.6331,-0.33402 -3.9482,-0.61223 -5.9376,-0.46875 -3.064,0.22097 -4.9677,0.34219 -6.9062,0.46875 -1.9384,0.12655 -1.6861,0.38864 -2.9062,0.46875 -1.3191,0.0866 -1.7869,-0.22325 -5.5626,0.0937 -3.5457,0.29772 -8.9806,0.99317 -10.2187,1.625 -1.6334,-0.33451 -3.9459,-0.61239 -5.9375,-0.46875 -3.0642,0.22098 -4.9678,0.37344 -6.9062,0.5 -0.6592,0.043 -1.0424,0.12393 -1.3438,0.1875 z"
- id="path7933-6" />
- <g
- clip-path="url(#clipPath7616-1)"
- style="display:inline;filter:url(#filter7610-9);enable-background:new"
- id="g7935-2"
- transform="matrix(0.9975712,-0.06965428,0.06965428,0.9975712,872.72062,140.02502)">
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccssscsssscscsscsssccscssccsscssscc"
- id="path7937-6"
- d="m 229.94262,-409.12268 c -3.55781,0.05 -9.0242,0.36009 -10.30334,0.90414 -1.60609,-0.44747 -3.90316,-0.88131 -5.89995,-0.87674 -3.07199,0.007 -4.96469,0.009 -6.90727,0 -0.66047,-0.003 -1.04759,0.0672 -1.35267,0.10959 0,0 0,1.09593 0,1.09593 0.11972,-0.17947 0.39252,-0.69046 0.94975,-0.76715 0.74758,-0.10289 5.16928,-0.15123 7.31019,-0.1096 1.7746,0.0345 4.45523,0.27427 6.38921,0.95895 0.3214,0.11378 0.61925,0.27378 0.89219,0.41097 1.96342,0.98693 7.94336,4.30154 7.94336,4.30154 0,0 -6.63275,-3.94768 -7.48287,-4.43853 -0.20331,-0.11739 -0.57464,-0.25769 -1.03609,-0.41098 1.22063,-0.44779 5.07597,-0.61971 7.82823,-0.71235 3.0245,-0.10182 3.34776,-0.0896 5.41069,0.19179 2.12931,0.29043 3.33851,0.60276 3.33851,0.60276 -1e-5,0 -0.0784,-0.64118 1.03609,-0.79455 0.74757,-0.10289 5.16929,-0.15123 7.31019,-0.1096 2.0695,0.0403 5.36605,0.40716 7.2814,1.36992 1.00332,0.50433 3.03564,1.56863 4.79535,2.53571 l 0.0956,-0.0194 c 0,0 -3.58034,-2.16242 -4.43047,-2.65327 -0.20331,-0.11739 -0.57463,-0.25769 -1.03609,-0.41098 1.22062,-0.44779 5.04719,-0.61971 7.79945,-0.71235 3.0245,-0.10182 3.34775,-0.0896 5.41069,0.19179 1.95316,0.2664 3.01292,0.53006 3.19461,0.57536 0,0 -0.0271,-0.31146 -0.0271,-0.31146 -0.40903,-0.13645 -0.71424,-0.23335 -1.40038,-0.35748 -1.30081,-0.23533 -3.39912,-0.60156 -5.50857,-0.56398 -3.57195,0.0636 -9.05328,0.35596 -10.30334,0.90414 -1.60583,-0.44695 -3.87662,-0.8813 -5.87117,-0.87674 -3.07199,0.007 -4.99348,0.009 -6.93605,0 -1.94256,-0.009 -1.71268,0.27907 -2.93558,0.27398 -1.32191,-0.005 -1.76612,-0.35463 -5.55459,-0.30138 0,0 0,0 0,0"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path7939-7"
- d="m 206.1989,-407.47878 c 1.92021,0.81706 4.57715,2.19283 6.15897,3.39739 1.58184,1.20456 2.90757,1.77368 5.55459,3.91795 0.88557,0.71738 1.74865,1.34985 2.59193,1.92174 l 0.54057,-0.19011 c -0.71323,-0.48339 -1.46776,-1.02031 -2.26909,-1.62203 -2.82223,-2.11921 -3.62655,-2.80973 -6.01507,-4.27414 -2.38854,-1.4644 -4.09948,-2.36576 -6.5619,-3.1508 0,0 0,0 0,0"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- sodipodi:nodetypes="cssccsscc" />
- <path
- inkscape:connector-curvature="0"
- id="path7941-5"
- d="m 237.79963,-407.47878 c 1.92021,0.81706 4.60594,2.19283 6.18775,3.39739 0.81307,0.61916 1.55849,1.07042 2.45046,1.65401 l 0.649,-0.11666 c -0.79831,-0.57637 -1.57177,-1.09435 -2.69653,-1.78394 -2.38854,-1.4644 -4.12826,-2.36576 -6.59068,-3.1508 0,0 0,0 0,0"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- sodipodi:nodetypes="csccscc" />
- </g>
- <g
- clip-path="url(#clipPath7606-1)"
- id="g7943-6">
- <path
- inkscape:connector-curvature="0"
- style="display:inline;opacity:0.75;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7578-4);enable-background:new"
- d="m 1056.25,-278.80481 c 4.1446,-1.47877 10,3.125 10,3.125 0.899,0.28092 2.7251,-0.89447 2.6243,-1.68614 0,0 -1.5503,-1.86062 -0.3743,-2.93886 1.176,-1.07824 5.296,1.50738 7.5,1.625 2.204,0.11762 5.5621,-0.22941 7,-0.75 1.4379,-0.52059 1.1129,-1.42459 2.625,-1.75 1.5121,-0.32541 5.1189,1.03754 7.0605,1.16883 1.9416,0.13129 4.6481,0.33427 5.8145,-0.16883 1.1664,-0.5031 0.1782,-1.15921 1.875,-1.875 1.6968,-0.71579 7.7602,-0.95662 9.625,-0.125 1.8648,0.83162 1.8099,0.5192 2.625,3 0.8151,2.4808 7.4398,5.16285 -1.125,13.375 -8.5648,8.21215 -59.3779,13.78594 -65.625,2.75 -6.2471,-11.03594 6.2304,-14.27123 10.375,-15.75 z"
- id="path7945-9"
- sodipodi:nodetypes="czzzzzzzzzzzzzz" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;opacity:0.75;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7594-8);enable-background:new"
- d="m 1058.5,-275.42981 c 4.1446,-1.47877 10,3.125 10,3.125 0.899,0.28092 2.7251,-0.89447 2.6243,-1.68614 0,0 -1.5503,-1.86062 -0.3743,-2.93886 1.176,-1.07824 5.296,1.50738 7.5,1.625 2.204,0.11762 5.5621,-0.22941 7,-0.75 1.4379,-0.52059 1.1129,-1.42459 2.625,-1.75 1.5121,-0.32541 5.1189,1.03754 7.0605,1.16883 1.9416,0.13129 4.6481,0.33427 5.8145,-0.16883 1.1664,-0.5031 0.1782,-1.15921 1.875,-1.875 1.6968,-0.71579 7.7602,-0.95662 9.625,-0.125 1.8648,0.83162 1.8099,0.5192 2.625,3 0.8151,2.4808 7.4398,5.16285 -1.125,13.375 -8.5648,8.21215 -59.3779,13.78594 -65.625,2.75 -6.2471,-11.03594 6.2304,-14.27123 10.375,-15.75 z"
- id="path7947-8"
- sodipodi:nodetypes="czzzzzzzzzzzzzz" />
- </g>
- </g>
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#101414;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 628.24553,347.99185 c -3.80443,-25.26423 -16.80972,-50.63802 -17.1568,-75.52523 -0.18626,-13.35552 3.27285,-26.57091 13.75553,-39.55405 36.34702,-65.29583 116.94091,-84.69468 185.93466,-91.46542 86.92239,-11.0168 184.91267,17.94007 233.37138,95.40128 54.124,75.7333 56.6747,172.53912 80.612,259.52795 29.4378,127.1276 54.7791,256.21414 60.3922,386.85035 -3.0634,78.18185 -8.4263,165.18417 -60.5032,228.13417 -48.0265,50.3574 -122.7864,50.053 -187.06985,59.0023 -90.55539,4.655 -184.35153,-16.1458 -261.7839,-64.1982 -64.77564,-37.94 -95.73019,-113.47867 -97.2794,-186.01962 -8.38917,-79.87516 26.39152,-153.80851 51.6204,-227.15961 7.47061,-82.76107 9.41286,-166.24775 9.65334,-249.38484 -0.83682,-32.19544 -7.08953,-63.81733 -11.54636,-95.60908 z"
- id="path7949-7"
- sodipodi:nodetypes="cscccccccccccc" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8940-3);enable-background:accumulate"
- d="m 311.83409,415.43155 9.8995,121.62237 -60.10408,136.47161 15.55635,174.65537 c 15.61326,61.8792 32.18545,98.66905 74.37615,117.05383 4.31911,-36.23998 -38.61152,-142.95988 -39.24264,-189.11984 -0.63145,-46.18445 10.83034,-108.60786 30.67767,-158.29647 20.04835,-50.19188 36.89674,-44.84642 42.12489,-92.59293 5.22815,-47.74651 -17.4264,-149.39192 -17.4264,-149.39192 l -55.86144,39.59798 z"
- id="path7951-2"
- sodipodi:nodetypes="ccccczzzcc"
- clip-path="url(#clipPath8616-5)"
- transform="translate(276,136)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient6953);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 1010.0312,655.49186 c 0,0 16.7552,37.01806 28.7015,53.95395 11.9462,16.93589 52.7271,56.04605 52.7271,56.04605 l 52.5972,-127.58975"
- id="path7953-8"
- sodipodi:nodetypes="czcc" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.07999998;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8822-2);enable-background:accumulate"
- d="m 730.31998,536.56864 c 0,8.48528 42.54774,58.46803 42.54774,58.46803 l 12.60659,-28.76954 -55.15433,-29.69849 z"
- id="path7955-2"
- sodipodi:nodetypes="cccc"
- clip-path="url(#clipPath8209-6)"
- transform="translate(276,136)" />
- <g
- transform="translate(450.03125,73.843964)"
- style="display:inline;opacity:1;enable-background:new"
- id="g7957-9"
- clip-path="url(#clipPath3998-6)">
- <g
- transform="translate(-174.03125,62.156036)"
- style="filter:url(#filter3677-5)"
- id="g7959-9">
- <g
- id="g7961-6"
- style="filter:url(#filter3785-4)">
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="czzzzzzzzzz"
- id="path7963-0"
- d="m 425.88244,476.99186 c 10.80543,-1.47866 24.74401,3.35451 44.64286,3.21428 19.89885,-0.14023 57.45322,-16.91122 82.14285,-17.14286 24.68963,-0.23164 62.7517,12.28406 79.28572,15 16.53402,2.71594 22.84832,-0.15852 27.49999,7.85715 4.65167,8.01567 1.92671,10.74724 -10.35714,20.71429 -12.28385,9.96705 -40.78968,12.63632 -66.07143,12.85714 -25.28234,0.22082 -70.38129,7.07852 -95.35714,3.92856 -24.97585,-3.14996 -56.93756,-7.82267 -68.92857,-17.85714 -11.99101,-10.03447 -19.85084,-16.73182 -17.5,-23.92857 2.35084,-7.19675 13.83743,-3.16419 24.64286,-4.64285 z"
- style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <rect
- y="412.60312"
- x="343.6539"
- height="181.01935"
- width="381.83765"
- id="rect7965-2"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- </g>
- <g
- id="g7967-7"
- style="filter:url(#filter3785-4)">
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="czzzcc"
- id="path7969-6"
- d="m 687.14286,452.36218 c -10.46169,9.71443 -86.9796,19.00514 -100.71429,29.28572 -13.73469,10.28058 -14.75252,12.88826 -12.14286,20 2.60966,7.11174 6.54527,9.40572 25.71429,8.57142 19.16902,-0.8343 98.57143,-27.62172 98.57143,-21.42857 l -11.42857,-36.42857 z"
- style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- transform="translate(174.03125,-62.156036)" />
- <rect
- y="344.82138"
- x="702.86414"
- height="162.63455"
- width="207.8894"
- id="rect7971-1"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- </g>
- </g>
- <g
- transform="translate(-174.03125,62.156036)"
- style="display:inline;opacity:0.18000004;enable-background:new"
- id="g7973-3">
- <g
- id="g7975-2"
- style="filter:url(#filter3785-4)">
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="czzzzzzzzzz"
- id="path7977-1"
- d="m 425.88244,476.99186 c 10.80543,-1.47866 24.74401,3.35451 44.64286,3.21428 19.89885,-0.14023 57.45322,-16.91122 82.14285,-17.14286 24.68963,-0.23164 62.7517,12.28406 79.28572,15 16.53402,2.71594 22.84832,-0.15852 27.49999,7.85715 4.65167,8.01567 1.92671,10.74724 -10.35714,20.71429 -12.28385,9.96705 -40.78968,12.63632 -66.07143,12.85714 -25.28234,0.22082 -70.38129,7.07852 -95.35714,3.92856 -24.97585,-3.14996 -56.93756,-7.82267 -68.92857,-17.85714 -11.99101,-10.03447 -19.85084,-16.73182 -17.5,-23.92857 2.35084,-7.19675 13.83743,-3.16419 24.64286,-4.64285 z"
- style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <rect
- y="412.60312"
- x="343.6539"
- height="181.01935"
- width="381.83765"
- id="rect7979-5"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- </g>
- <g
- id="g7981-9"
- style="filter:url(#filter3785-4)">
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="czzzcc"
- id="path7983-9"
- d="m 687.14286,452.36218 c -10.46169,9.71443 -86.9796,19.00514 -100.71429,29.28572 -13.73469,10.28058 -14.75252,12.88826 -12.14286,20 2.60966,7.11174 6.54527,9.40572 25.71429,8.57142 19.16902,-0.8343 98.57143,-27.62172 98.57143,-21.42857 l -11.42857,-36.42857 z"
- style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- transform="translate(174.03125,-62.156036)" />
- <rect
- y="344.82138"
- x="702.86414"
- height="162.63455"
- width="207.8894"
- id="rect7985-1"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- </g>
- </g>
- </g>
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.75;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8802-7);enable-background:accumulate"
- d="M 582.65599,-7.4183011 695.79307,78.848726 804.68752,337.64981 842.87128,545.5392 963.07944,637.46308 c 0,0 -12.72793,-287.08535 -19.799,-313.95541 C 936.20938,296.63761 793.37381,-69.643698 793.37381,-69.643698 L 582.65599,-7.4183011 Z"
- id="path7987-4"
- clip-path="url(#clipPath8604-69)"
- sodipodi:nodetypes="cccccscc"
- transform="translate(276,136)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient6955);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 964.13839,239.599 c 0,0 8.67732,10.89662 24.10715,11.96428 15.42986,1.06766 49.72166,-39.95267 70.17856,-52.14285 20.4793,-12.20353 47.0464,-26.60225 63.9286,-20.35714 16.8821,6.2451 22.1578,26.43609 27.8571,48.03571 5.6994,21.59961 6.7186,61.81389 -2.6785,92.85715 -9.3972,31.04325 -50.5033,73.10375 -65.3572,103.39285 -14.8539,30.2891 -11.6071,39.82143 -11.6071,39.82143"
- id="path7989-9"
- sodipodi:nodetypes="czzzzzzc" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;opacity:1;fill:url(#radialGradient3315-5);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 1124.4955,207.63471 c -15.8928,-0.89286 -49.7188,12.10583 -66.0714,24.28572 -16.4386,12.2439 -29.2209,24.1144 -29.2857,52.14285 -0.065,28.20604 13.1191,39.07641 29.1071,46.96429 15.988,7.88789 33.6862,7.11928 51.9643,-11.78571 18.2782,-18.905 14.2857,-111.60715 14.2857,-111.60715 z"
- id="path7991-1"
- sodipodi:nodetypes="czzzzc" />
- <ellipse
- ry="73.928574"
- rx="86.428574"
- cy="237.00504"
- cx="385"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.75;fill:url(#radialGradient3543-4);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter4120-7);enable-background:accumulate"
- id="path7993-0"
- transform="matrix(0.9434749,-0.1239943,0.1440089,1.0957669,451.94827,134.5988)"
- clip-path="url(#clipPath4100-3)" />
- <path
- inkscape:connector-curvature="0"
- transform="translate(450.03125,73.843964)"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient3915-6);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 527.60588,407.44884 c 0,0 -122.04144,38.40348 -187.51434,9.63181 -65.47289,-28.77166 -74.37725,-124.71847 -74.37725,-124.71847 0,0 73.38158,-80.50393 129.92078,-83.61476 55.82705,-3.07164 90.57386,20.14332 114.87001,65.85171 24.352,45.81348 17.1008,132.84971 17.1008,132.84971 z"
- id="path7995-7"
- sodipodi:nodetypes="csczzc"
- mask="url(#mask3684-3)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient6957);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 772.17411,393.349 c 0,0 36.21754,-27.38247 51.60714,-35.89286 15.17734,-8.39301 25.71428,-11.60714 35.89285,-11.60714 l -15.53571,66.96428"
- id="path7997-5"
- sodipodi:nodetypes="czcc" />
- <circle
- r="36.25"
- cy="306.64789"
- cx="409.28571"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient3933-8);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="path7999-8"
- transform="translate(449.49554,74.915393)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8806-6);enable-background:accumulate"
- d="m 311.83409,415.43155 9.8995,121.62237 -60.10408,136.47161 15.55635,174.65537 c 15.61326,61.8792 32.18545,98.66905 74.37615,117.05383 4.31911,-36.23998 8.68161,-72.36764 -31.24264,-223.11984 l 17.67767,-69.29647 72.12489,-138.59293 -42.4264,-158.39192 -55.86144,39.59798 z"
- id="path8001-7"
- sodipodi:nodetypes="cccccccccc"
- clip-path="url(#clipPath8616-5)"
- transform="translate(276,136)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8826-9);enable-background:accumulate"
- d="m 635.21025,581.13004 c -14.14214,12.72792 39.23347,34.58015 76.36753,24.04163 37.13406,-10.53852 104.64487,-35.56437 103.23759,-79.19596 -1.40728,-43.63158 -76.36753,-128.69343 -76.36753,-128.69343 L 635.21025,581.13004 Z"
- id="path8003-0"
- sodipodi:nodetypes="czzcc" />
- <circle
- r="23.214285"
- cy="306.64789"
- cx="410"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient3991-0);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="path8005-4"
- transform="translate(449.67411,74.915393)" />
- <circle
- r="7.5"
- cy="303.07648"
- cx="414.28571"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter3981-7);enable-background:accumulate"
- id="path8007-8"
- transform="translate(451.99554,73.486821)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient4112-7);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 789.31696,478.349 c 0,0 7.02281,19.56859 -1.07143,35 -8.09424,15.43141 -42.32317,38.98822 -67.49999,50 -25.30972,11.06991 -85.473,32.96393 -101.78572,41.96428 -16.46148,9.08243 -18.21428,12.67857 -18.21428,12.67857 0,0 -7.14693,-19.06441 28.74999,-51.7857 36.17211,-32.97214 142.02712,-48.0495 159.82143,-87.85715 z"
- id="path8009-0"
- sodipodi:nodetypes="czzzczc" />
- <g
- style="display:inline;opacity:1;enable-background:new"
- id="g8011-4"
- transform="translate(780.74553,74.55825)">
- <path
- inkscape:connector-curvature="0"
- transform="translate(-329.81481,0)"
- clip-path="url(#clipPath3999-0)"
- sodipodi:nodetypes="czzczzzszc"
- id="path8013-2"
- d="m 179.64286,267.36218 c -22.41044,39.70292 -60.6161,115.78029 -69.28571,149.64286 -8.64721,33.7751 -8.77199,66.41654 -0.35715,86.42858 8.3602,19.88213 26.16398,35.6328 40.71428,41.42856 -0.59638,-14.37587 14.37295,-43.28583 72.85715,-72.5 58.62627,-29.28514 78.38163,-27.13086 103.57142,-47.14286 25.63006,-20.36176 8.20587,-79.64664 3.21429,-93.92857 -4.99158,-14.28193 -1.23663,-3.37974 -1.94602,-5.09301 -10.68928,-25.81592 -34.21432,-54.4303 -64.48255,-64.54984 -30.26823,-10.11954 -65.01776,-4.84837 -84.28571,5.71428 z"
- style="display:inline;opacity:1;fill:url(#radialGradient3585-2);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <ellipse
- ry="134.00607"
- rx="64.715881"
- cy="338.07648"
- cx="183.57143"
- transform="matrix(0.8823874,0.4705236,-0.4705236,0.8823874,-166.62245,2.387362)"
- id="path8015-9"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient4060-5);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- <ellipse
- ry="134.00607"
- rx="64.715881"
- cy="338.07648"
- cx="183.57143"
- transform="matrix(0.8823874,0.4705236,-0.4705236,0.8823874,-162.19388,-18.755495)"
- id="path8017-6"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient4062-9);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- transform="translate(-329.81481,3e-7)"
- clip-path="url(#clipPath3999-0)"
- sodipodi:nodetypes="czzczzzszc"
- id="path8019-1"
- d="m 179.64286,267.36218 c -22.41044,39.70292 -60.6161,115.78029 -69.28571,149.64286 -8.64721,33.7751 -8.77199,66.41654 -0.35715,86.42858 8.3602,19.88213 26.16398,35.6328 40.71428,41.42856 -0.59638,-14.37587 14.37295,-43.28583 72.85715,-72.5 58.62627,-29.28514 78.38163,-27.13086 103.57142,-47.14286 25.63006,-20.36176 8.20587,-79.64664 3.21429,-93.92857 -4.99158,-14.28193 -1.23663,-3.37974 -1.94602,-5.09301 -10.68928,-25.81592 -34.21432,-54.4303 -64.48255,-64.54984 -30.26823,-10.11954 -65.01776,-4.84837 -84.28571,5.71428 z"
- style="display:inline;opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient6959);stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4079-1);enable-background:new" />
- </g>
- <circle
- r="19.704132"
- cy="398.07648"
- cx="310.71429"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="path8021-0"
- transform="translate(452.55663,72.581273)" />
- <circle
- r="19.704132"
- cy="398.07648"
- cx="310.71429"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient4056-5);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient6961);stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter4083-9);enable-background:accumulate"
- id="path8023-4"
- transform="translate(450.55663,72.581273)" />
- <circle
- r="19.704132"
- cy="398.07648"
- cx="310.71429"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient4119-7);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- id="path8025-2"
- transform="translate(450.55663,72.581273)" />
- <ellipse
- ry="44.547726"
- rx="72.079735"
- cy="377.42877"
- cx="429.56738"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient4868-3);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter4002-6);enable-background:accumulate"
- id="path8027-2"
- transform="matrix(0.9969564,-0.07796167,0.07796167,0.9969564,436.61877,125.29509)"
- inkscape:transform-center-x="-47.231976"
- inkscape:transform-center-y="-3.6935079" />
- <ellipse
- ry="22.627417"
- rx="36.611931"
- cy="391.21735"
- cx="437.6991"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient4876-9);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter4010-1);enable-background:accumulate"
- id="path8029-2"
- transform="matrix(1.4357951,-0.06999104,0.06999104,1.4357951,235.18065,-63.86546)"
- inkscape:transform-center-x="-20.955902"
- inkscape:transform-center-y="-13.056625" />
- <g
- transform="translate(450.03125,73.843964)"
- id="g8031-0"
- style="display:inline;opacity:1;filter:url(#filter4053-9);enable-background:new">
- <circle
- r="3.2142856"
- cy="401.82648"
- cx="413.66071"
- id="path8033-5"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient6963);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- <circle
- r="3.2142856"
- cy="401.82648"
- cx="413.66071"
- transform="translate(13.125009,8.1249913)"
- id="path8035-5"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient6965);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- <circle
- r="3.2142856"
- cy="401.82648"
- cx="413.66071"
- transform="translate(32.946437,7.4999913)"
- id="path8037-2"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient6967);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- <circle
- r="3.2142856"
- cy="401.82648"
- cx="413.66071"
- transform="translate(24.910723,-10.267866)"
- id="path8039-9"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient6969);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- <circle
- r="3.2142856"
- cy="401.82648"
- cx="413.66071"
- transform="translate(47.589294,-0.6250087)"
- id="path8041-0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient6971);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- </g>
- <path
- inkscape:connector-curvature="0"
- style="display:inline;opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 896.20301,482.92837 c 0.98509,4.35008 4.53707,6.17948 7.38673,7.89182 4.46068,2.51292 6.52016,1.52211 9.15451,-0.75761 1.60195,-1.92117 10.68311,-4.69865 15.59423,-7.07107 4.32961,-1.45891 8.9033,-5.35873 13.38452,-8.33376 3.39514,-1.62724 5.34664,0.35464 7.82868,1.01015 2.94412,0.71661 4.41117,2.17175 6.06092,3.53554 2.39616,1.17519 -0.9279,3.14313 3.283,4.29314 1.19091,0.21794 2.41695,0.57645 3.28299,-0.50507"
- id="path8043-2"
- sodipodi:nodetypes="ccccccccc" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 910.85021,475.35223 c 2.31494,-0.032 3.17778,0.64253 5.49271,-0.82075 3.45564,-3.08113 5.40254,-3.14477 7.95495,-4.41942 3.02657,-1.31523 6.5357,8.15169 10.10153,9.84899 2.39509,-0.82142 1.28914,1.79379 1.45209,2.65165 0.0571,2.64684 2.80694,3.67806 4.35628,5.42957 3.31604,2.25549 7.37523,6.29546 11.11168,5.3033 6.44525,-2.93107 10.27922,-1.28146 16.28871,-7.38674 0.70405,-1.18134 -0.58425,-6.8946 3.09359,-7.19734 2.52399,0.25338 4.16667,0.0502 6.06092,0.56822 5.441,2.11719 7.73778,6.45 14.71034,7.95495 6.1829,0.96639 7.61264,3.79426 13.88959,5.05076"
- id="path8045-8"
- sodipodi:nodetypes="cccccccccccc" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 876.98133,483.52197 c 2.39858,-0.7938 6.10613,4.1921 8.17313,7.04568 0.59281,2.67952 1.15377,5.48645 0.75761,12.12183 0.78513,2.41754 2.68049,3.03095 4.79823,3.283 3.11745,-0.53678 5.87669,-1.3243 7.3236,-3.03046 1.8716,-1.94167 5.31253,2.39394 8.08122,4.04061 3.61009,1.91209 7.77378,1.97886 11.8693,2.27284 1.70358,-0.23064 2.3704,4.51515 3.28299,8.08123 0.38414,4.37806 -0.88544,6.89569 -1.76776,9.84898 -0.2943,2.49655 2.9885,3.52974 6.31345,4.54569 3.18244,0.74124 6.54424,1.66184 9.09137,1.76777 5.14186,0.87491 8.08874,2.69052 12.12183,4.04061 2.23914,0.81655 3.26019,2.24216 4.54569,3.53553"
- id="path8047-3"
- sodipodi:nodetypes="ccccccccccccc" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter8814-5);enable-background:new"
- d="m 332,187.69519 c 0,0 57.5,-25.5 57.5,-28 0,-2.5 5.5,-52 5.5,-52 0,0 91,-48.500001 91.5,-50.500001 0.5,-2 86,-62.0000004 86,-62.0000004 L 386.5,17.195189 311,123.19519 l 21,64.5 z"
- id="path8049-8"
- clip-path="url(#clipPath8514-8)"
- transform="translate(276,136)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 1697.2846,722.5514 c 0,0 -115.9655,73.5391 -123.0365,77.78174 -7.0711,4.24264 -230.5169,137.17872 -230.5169,137.17872 l 4.2427,39.59798 216.3747,-100.40917 117.3797,-101.82337 15.5563,-52.3259 z"
- id="path8051-0" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8810-3);enable-background:accumulate"
- d="m 528.91587,556.85291 c -5.65685,-1.41421 -181.01933,74.95332 -181.01933,74.95332 l -33.94113,181.01934 51.09546,193.94823 257.2031,67.6813 c 0,0 206.47518,152.735 212.13203,148.4924 5.65686,-4.2426 168.2914,-193.7473 168.2914,-193.7473 L 842.87128,845.35248 796.20224,667.16157 528.91587,556.85291 Z"
- id="path8053-4"
- clip-path="url(#clipPath8610-9)"
- sodipodi:nodetypes="cccccscccc"
- transform="translate(276,136)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;opacity:1;fill:#0c0c0c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 1097.6433,613.88997 c 0,0 22.6195,-6.50681 35.7427,-5.87273 13.1233,0.63409 30.6416,1.93862 43.7089,12.18619 13.0673,10.24756 25.0677,27.14007 34.1124,58.36965 9.0446,31.22958 1.6983,99.25201 -6.1761,143.34735 -7.8743,44.09534 -28.2651,106.11298 -45,140 -16.7348,33.88702 -49.7977,77.49517 -60.5694,89.87617 -11.3642,13.062 -56.2059,36.4262 -79.4306,42.2667 5.3034,-10.6066 48.8998,-50.5889 35,-60.7143 -14.0189,-10.2123 -45.76,45.9824 -84.2931,29.0332 21.38231,-13.1321 41.7794,-51.1861 34.0406,-66.59448 -7.84024,-15.61039 -30.70492,48.75758 -93.53553,37.01288 30.05204,-27.5267 55.40706,-70.90401 41.2627,-82.9797 -14.41516,-12.30687 -60.46175,54.2932 -60.46175,54.2932 0,0 -2.8219,-41.70123 13.7732,-68.60737 16.63935,-26.97787 79.65297,-81.61527 99.55308,-111.70342 19.9002,-30.08814 33.6126,-66.00902 42.1355,-92.51794 8.5228,-26.50892 15.8009,-77.09954 15.8009,-77.09954"
- id="path8055-0"
- sodipodi:nodetypes="czzzzzzczczczczzzc" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8818-1);enable-background:accumulate"
- d="m 770.74639,609.17881 -50.91169,97.58074 -79.90307,111.01576 34.64824,71.41778 42.42641,79.19597 72.12489,-45.25484 14.14214,-192.33305 21.2132,-138.59292 -14.14214,-90.15612 -39.59798,107.12668 z"
- id="path8057-9"
- clip-path="url(#clipPath8622-5)"
- sodipodi:nodetypes="cccccccccc"
- transform="translate(276,136)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter8810-3);enable-background:accumulate"
- d="m 295,846.19519 6.64488,-68.92285 c 0,0 90.31951,89.00457 162.35512,122.92285 72.03561,33.91828 308,62 308,62 l 154,-26 -36,162.00001 -286,26 -298,-89 -11,-189.00001 z"
- id="path8059-1"
- clip-path="url(#clipPath8906-9)"
- sodipodi:nodetypes="cczcccccc"
- transform="translate(276,136)" />
- <path
- inkscape:connector-curvature="0"
- transform="translate(450.03125,73.843964)"
- style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3587-1);enable-background:new"
- d="m 405.79629,845.99023 74.95332,65.05383 2.49963,16.8804 19.40336,10.15891 6.49204,23.05109 31.70905,-8.3711 14.84924,48.08324 c 12.25652,12.7279 89.79344,-113.1097 55.86143,38.1838 l -60.81118,16.2635 -89.20292,-94.69286 -62.82503,-53.79963 7.07106,-60.81118 z"
- id="path8061-9"
- sodipodi:nodetypes="cccccccccccc"
- clip-path="url(#clipPath3602-4)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#121212;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
- d="m 1159.317,918.349 c 54.2857,-1.42857 126.035,-15.05199 170,-26.78572 44.0527,-11.75714 125.8863,-36.34724 175.357,-57.85714 49.3393,-21.45272 113.6038,-59.2816 154.2859,-92.14285 40.5081,-32.72069 52.3899,-55.81981 60.7142,-33.57143 8.3691,22.36779 -16.4069,56.32562 -37.8571,81.07143 -21.6042,24.9234 -52.7314,52.70533 -98.9287,89.28571 -46.1973,36.58038 -156.0825,101.58463 -212.8571,128.5714 -57.066,27.1254 -128.2033,58.2385 -172.1428,72.5001 -43.9395,14.2616 -131.4286,31.0714 -131.4286,31.0714 L 1159.317,918.349 Z"
- id="path8063-6"
- sodipodi:nodetypes="czzzzzzzzcc" />
- <path
- inkscape:connector-curvature="0"
- transform="translate(450.03125,73.843964)"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.5;fill:url(#linearGradient6973);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter3779-4);enable-background:accumulate"
- d="m 1241.5965,652.95007 c 0,0 -64.7215,54.33706 -145.6639,98.99494 -82.0244,45.25484 -284.25704,93.3381 -284.25704,93.3381 0,0 -15.10137,21.05196 45.25489,28.28428 60.35626,7.23232 224.08195,-53.30069 278.60015,-96.16654 54.5182,-42.86585 120.2081,-111.72286 120.2081,-111.72286 l -14.1422,-12.72792 z"
- id="path8065-2"
- sodipodi:nodetypes="czczzcc"
- clip-path="url(#clipPath3992-4)" />
- <g
- transform="translate(450.03125,73.843964)"
- style="display:inline;opacity:1;enable-background:new"
- id="g8067-5"
- clip-path="url(#clipPath3986-7)">
- <g
- transform="translate(-174.03125,62.156036)"
- style="filter:url(#filter3677-5)"
- id="g8069-4">
- <g
- style="filter:url(#filter3785-4)"
- id="g8071-4">
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="czzccccc"
- id="path8073-9"
- d="m 1094.2857,725.93361 c 0,0 -0.2961,26.16091 4.6428,37.85715 4.9389,11.69624 20.0381,26.48665 28.5715,31.42857 8.5334,4.94192 18.9286,8.57142 18.9286,8.57142 l 117.8571,-115 17.8572,-75.71428 -96.4286,38.57143 -91.4286,74.28571 z"
- style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- transform="translate(174.03125,-62.156036)" />
- <rect
- y="486.14224"
- x="1197.8389"
- height="309.71277"
- width="333.75412"
- id="rect8075-9"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- </g>
- </g>
- <g
- transform="translate(-174.03125,62.156036)"
- style="display:inline;opacity:0.18000004;enable-background:new"
- id="g8077-3">
- <g
- style="filter:url(#filter3785-4)"
- id="g8079-6">
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="czzccccc"
- id="path8081-0"
- d="m 1094.2857,725.93361 c 0,0 -0.2961,26.16091 4.6428,37.85715 4.9389,11.69624 20.0381,26.48665 28.5715,31.42857 8.5334,4.94192 18.9286,8.57142 18.9286,8.57142 l 117.8571,-115 17.8572,-75.71428 -96.4286,38.57143 -91.4286,74.28571 z"
- style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- transform="translate(174.03125,-62.156036)" />
- <rect
- y="486.14224"
- x="1197.8389"
- height="309.71277"
- width="333.75412"
- id="rect8083-5"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- </g>
- </g>
- </g>
- <path
- inkscape:connector-curvature="0"
- transform="translate(450.03125,73.843964)"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.83300003;fill:#050505;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:15;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;filter:url(#filter8225-7);enable-background:accumulate"
- d="m 1264.1875,605 c -4.4911,0.73268 -8.157,3.45509 -11.9375,6.40625 -10.0813,7.86976 -28.1695,34.42524 -48.0312,50.46875 -39.8674,32.20316 -103.996,69.97701 -152.5626,91.09375 -48.614,21.13738 -130.54122,45.81801 -174.31245,57.5 -43.39821,11.58246 -115.04403,25.13107 -168.25,26.53125 l -4.5625,0.125 -2,4.125 -92.84375,192.125 -6.5,13.4688 14.65625,-2.8438 c 0,0 87.26968,-16.6514 132.34375,-31.2812 44.7252,-14.51667 115.79086,-45.66683 173.03125,-72.87505 C 980.82199,912.46306 1090.1551,847.86412 1137.5,810.375 c 46.3608,-36.70982 77.8049,-64.71682 99.9375,-90.25 10.9011,-12.576 22.7448,-27.53144 31.0313,-42.75 8.2864,-15.21856 19.1597,-44.21808 13.6874,-58.84375 -1.2177,-3.25474 -2.5514,-6.0613 -4.5937,-8.5 -2.0423,-2.4387 -8.4747,-1.57199 -8.5625,-5.03125 -0.2098,-8.26482 -3.3155,-0.24423 -4.8125,0 z m 2.1563,15.21875 c 0.4148,0.58574 1.0311,1.55766 1.7812,3.5625 2.8968,7.74213 -1.4407,31.89875 -8.8125,45.4375 -7.3718,13.53875 -22.6384,28.92394 -33.1875,41.09375 -21.0754,24.31356 -51.9037,51.86156 -97.9375,88.3125 -45.0496,35.67159 -155.46033,101.09459 -211.40625,127.6875 -56.89173,27.04249 -128.09616,58.1184 -171.25,72.125 -36.36491,11.8031 -95.84471,23.8338 -115.71875,27.7813 L 714.09375,851.75 c 54.70691,-2.0493 123.79259,-15.21635 167.125,-26.78125 44.33422,-11.83225 126.07865,-36.33633 176.40625,-58.21875 50.112,-21.78871 112.5344,-61.16816 154.0312,-94.6875 20.6464,-16.67721 41.7449,-42.54588 49.8126,-48.84375 2.437,-1.90242 4.0806,-2.6358 4.875,-3 z"
- id="path8085-0"
- clip-path="url(#clipPath3722-3)"
- sodipodi:nodetypes="cssssccccccssssssssccssssssccssssc" />
- <g
- style="display:inline;opacity:1;enable-background:new"
- id="g8087-2"
- mask="url(#mask7704-9)"
- transform="matrix(0.9934486,0.1142802,-0.1142802,0.9934486,-9.24324,588.09054)"
- inkscape:transform-center-x="-185.09603"
- inkscape:transform-center-y="-12.859654">
- <path
- inkscape:connector-curvature="0"
- transform="translate(0.08004571,-0.03125)"
- style="display:inline;fill:#bcb786;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 1111.4062,-285.9375 -3.9374,1.875 c -0.041,0.0102 -0.1,0.0205 -0.125,0.0312 -0.4188,0.21285 -0.1647,0.10058 -0.6563,0.3125 -0.4861,0.20956 -1.7376,0.58419 -4.0937,1.46875 -3.3312,1.25058 -5.8043,2.14984 -7,3.0625 -1.5362,0.0213 -3.7205,0.23331 -5.6563,0.71875 -2.9815,0.74767 -4.8552,1.17401 -6.75,1.59375 -1.8948,0.41973 -1.6755,0.64219 -2.875,0.875 -1.2966,0.25167 -1.7214,-0.009 -5.4375,0.78125 -3.4899,0.74215 -8.8948,1.93107 -10.1562,2.6875 -1.584,-0.18078 -3.8675,-0.32178 -5.8438,-0.0312 -3.0404,0.44696 -4.9162,0.67276 -6.8438,0.90625 -0.6554,0.0794 -1.041,0.20078 -1.3437,0.28125 -0.4262,0.13166 -0.6858,0.26002 -1.375,0.34375 -1.3116,0.15937 -1.7622,-0.15683 -5.5313,0.28125 -3.5539,0.41309 -9.0054,1.27282 -10.25,1.9375 -1.599,-0.29729 -3.8577,-0.53419 -5.8437,-0.34375 -3.0588,0.29332 -4.972,0.48399 -6.9063,0.65625 -1.9342,0.17227 -1.6886,0.42237 -2.9062,0.53125 -1.3162,0.1177 -1.7598,-0.16363 -5.5312,0.25 -3.5421,0.38845 -9.0079,1.20927 -10.2813,1.875 -1.5989,-0.29469 -3.8872,-0.50701 -5.875,-0.3125 -3.05829,0.29925 -4.9412,0.48024 -6.875,0.65625 -0.65749,0.0598 -1.04005,0.17856 -1.34375,0.25 -0.4277,0.11896 -0.6835,0.21807 -1.375,0.28125 -1.316,0.12026 -1.75975,-0.19488 -5.53125,0.21875 -3.55619,0.39002 -9.0056,1.23916 -10.25,1.90625 -1.59869,-0.29418 -3.85985,-0.52372 -5.84375,-0.3125 -3.0557,0.32533 -4.97405,0.52624 -6.90625,0.71875 -1.93219,0.19251 -1.68975,0.44088 -2.90625,0.5625 -1.31488,0.13147 -1.76305,-0.16454 -5.53125,0.28125 -3.53889,0.41866 -8.9777,1.29217 -10.25,1.96875 -1.59759,-0.28104 -3.85995,-0.42043 -5.84375,-0.1875 -3.05198,0.35837 -4.945,0.56786 -6.875,0.78125 -0.65618,0.0726 -1.04065,0.17269 -1.34375,0.25 -0.42679,0.12723 -0.6849,0.2672 -1.375,0.34375 -1.31339,0.14569 -1.76735,-0.17402 -5.53125,0.3125 -3.54888,0.45876 -8.97865,1.41902 -10.21875,2.125 -1.59309,-0.24424 -3.8338,-0.38135 -5.8125,-0.125 -3.04759,0.39482 -4.9507,0.64845 -6.875,0.90625 -1.92429,0.25779 -1.7261,0.49353 -2.9375,0.65625 -1.30949,0.1759 -1.7472,-0.10438 -5.5,0.46875 -3.52429,0.53824 -8.9232,1.69917 -10.1875,2.4375 -1.58749,-0.20354 -3.8455,-0.25473 -5.8125,0.0937 -3.02619,0.53612 -4.8989,0.86169 -6.8125,1.1875 -0.65059,0.11077 -1.0137,0.27094 -1.3125,0.375 -0.42069,0.16488 -0.66345,0.3313 -1.34375,0.46875 -1.2947,0.26159 -1.7271,-0.006 -5.4375,0.8125 -3.49848,0.77195 -8.8459,2.38293 -10.0625,3.21875 -1.5629,-0.0774 -3.7575,0.0853 -5.6875,0.59375 -2.97238,0.78313 -4.8177,1.23209 -6.6875,1.75 -1.87,0.5179 -1.66665,0.76728 -2.84375,1.09375 -1.27249,0.3529 -1.69705,0.10709 -5.34375,1.1875 -3.42468,1.01463 -8.6494,2.93317 -9.875,3.84375 -1.53878,0.0127 -3.7198,0.27222 -5.625,0.875 -2.93098,0.92734 -4.75035,1.45842 -6.59375,2.0625 -0.62679,0.20538 -0.99165,0.39258 -1.28125,0.53125 -0.40758,0.21361 -0.6533,0.40875 -1.3125,0.625 -1.2545,0.41154 -1.68615,0.18904 -5.28125,1.4375 -3.38989,1.17717 -8.59495,3.2137 -9.78125,4.15625 -1.52388,0.0597 -3.65005,0.39487 -5.53125,1.0625 -2.89739,1.02829 -4.69905,1.67548 -6.53125,2.3125 -1.8322,0.63701 -1.62785,0.84854 -2.78125,1.25 -1.24679,0.43396 -1.66355,0.19972 -5.21875,1.5625 -3.3387,1.2798 -8.4871,3.48255 -9.6875,4.46875 -1.50718,0.10769 -3.6357,0.4988 -5.5,1.21875 -2.86818,1.1076 -4.6239,1.78156 -6.4375,2.46875 -0.6167,0.23363 -0.99645,0.44203 -1.28125,0.59375 10e-6,0 0,0.0295 0,0.0312 l -8,3.1875 -12.4759,3.49189 7.92966,19.27772 c -0.59163,1.97357 12.54624,-4.73836 12.54624,-4.73836 0.22641,-0.14468 0.44895,-0.27261 0.71875,-0.375 1.08052,-0.40998 2.1716,-0.21577 6,-1.6875 3.82852,-1.47174 5.22405,-2.00498 5.90625,-2.40625 0.67961,-0.39978 1.61175,-0.87937 2.21875,-1.53125 1.82692,-0.13775 3.5708,-0.49323 4.9375,-1 2.968,-1.10052 4.87535,-1.80619 6.78125,-2.46875 1.90581,-0.66254 2.35415,-1.41487 3.40625,-1.78125 1.09162,-0.38011 2.1951,-0.16538 6.0625,-1.53125 3.8674,-1.36586 5.28315,-1.82708 5.96875,-2.21875 0.70111,-0.40052 1.7008,-0.93298 2.3125,-1.59375 1.97081,-0.0547 3.81695,-0.38463 5.28125,-0.875 3.00152,-1.00508 4.92615,-1.62171 6.84375,-2.25 1.53861,-0.5041 2.17415,-1.04677 2.90625,-1.4375 0.23022,-0.13431 0.4759,-0.25373 0.75,-0.34375 1.09832,-0.36048 2.18145,-0.0814 6.09375,-1.3125 3.91231,-1.23113 5.366,-1.67295 6.0625,-2.03125 0.69391,-0.35697 1.6301,-0.79261 2.25,-1.40625 1.86521,-0.0227 3.63585,-0.26683 5.03125,-0.6875 3.0304,-0.91354 4.9924,-1.4301 6.9375,-1.96875 1.94512,-0.53864 2.4262,-1.26452 3.5,-1.5625 1.11402,-0.30915 2.22,0.007 6.1875,-1.03125 3.9675,-1.03863 5.4175,-1.43273 6.125,-1.75 0.7348,-0.32959 1.8139,-0.75372 2.4375,-1.375 1.99782,0.116 3.85745,-0.0201 5.34375,-0.375 3.07811,-0.735 5.0834,-1.10094 7.0625,-1.5 1.58791,-0.32018 2.2443,-0.79055 3,-1.09375 0.23751,-0.1068 0.4669,-0.19276 0.75,-0.25 1.13341,-0.22919 2.30465,0.20893 6.34375,-0.5 4.03942,-0.70893 5.50025,-0.92709 6.21875,-1.1875 0.71581,-0.25944 1.70435,-0.56724 2.34375,-1.09375 1.9242,0.23949 3.7479,0.22453 5.1875,0 3.12642,-0.48762 5.15455,-0.70067 7.15625,-0.96875 2.00171,-0.26807 2.48875,-0.94514 3.59375,-1.09375 1.14642,-0.15418 2.27585,0.30157 6.34375,-0.21875 4.06781,-0.52032 5.56025,-0.69573 6.28125,-0.9375 0.73712,-0.24714 1.7981,-0.58623 2.4375,-1.125 2.05,0.33553 3.9737,0.39796 5.5,0.21875 3.1422,-0.36896 5.18,-0.55936 7.1875,-0.78125 1.61082,-0.17802 2.26465,-0.6082 3.03125,-0.84375 0.24091,-0.0855 0.49405,-0.1556 0.78125,-0.1875 1.1497,-0.12772 2.3013,0.34665 6.375,-0.125 4.0737,-0.47165 5.55905,-0.6106 6.28125,-0.84375 0.71941,-0.23227 1.70025,-0.47346 2.34375,-0.96875 1.9363,0.33346 3.77005,0.40424 5.21875,0.25 3.14601,-0.33495 5.1775,-0.51859 7.1875,-0.71875 2.00991,-0.20014 2.48415,-0.82639 3.59375,-0.9375 1.1511,-0.11528 2.2965,0.36506 6.375,-0.0625 4.0785,-0.42756 5.5889,-0.56209 6.3125,-0.78125 0.73922,-0.22386 1.7956,-0.51325 2.4375,-1.03125 2.057,0.39867 4.00185,0.4934 5.53125,0.34375 3.14871,-0.3081 5.1758,-0.47325 7.1875,-0.65625 1.61401,-0.14682 2.26305,-0.56055 3.03125,-0.78125 0.2413,-0.0809 0.49355,-0.12991 0.78125,-0.15625 1.15211,-0.10545 2.2929,0.39275 6.375,0 4.08211,-0.39275 5.5889,-0.53084 6.3125,-0.75 0.7209,-0.21833 1.6996,-0.4477 2.3437,-0.9375 1.9381,0.34999 3.7689,0.45438 5.2188,0.3125 3.1487,-0.3081 5.1758,-0.47325 7.1875,-0.65625 2.0116,-0.18299 2.5142,-0.83802 3.625,-0.9375 1.1523,-0.10323 2.2922,0.38483 6.375,0 4.0829,-0.38482 5.5887,-0.501 6.3125,-0.71875 0.7393,-0.22243 1.7956,-0.51449 2.4375,-1.03125 2.0574,0.40177 4.0029,0.50333 5.5313,0.34375 3.1465,-0.32852 5.177,-0.5227 7.1874,-0.71875 1.613,-0.15729 2.2657,-0.63148 3.0313,-0.875 0.2407,-0.088 0.4632,-0.12137 0.75,-0.15625 1.1483,-0.1397 2.3167,0.33991 6.375,-0.25 4.0583,-0.58992 5.5618,-0.77714 6.2813,-1.03125 0.7166,-0.25316 1.6746,-0.55807 2.3124,-1.09375 1.9197,0.21194 3.72,0.15141 5.1563,-0.0937 3.1191,-0.5324 5.1116,-0.92861 7.0937,-1.3125 1.9821,-0.38387 2.4743,-1.03965 3.5626,-1.28125 1.1287,-0.25066 2.2702,0.11629 6.25,-0.875 3.9795,-0.99127 5.4295,-1.4193 6.125,-1.78125 0.7222,-0.376 1.7617,-0.87058 2.375,-1.53125 1.9629,-0.012 3.7937,-0.29105 5.2187,-0.84375 2.9512,-1.1446 4.8732,-1.86942 6.6875,-2.75 1.4557,-0.70652 2.3191,-1.70203 2.5312,-2 0.2123,-0.29795 0.099,-0.72855 0.125,-0.75 0.043,-0.0352 0.3404,-0.094 0.5,-0.4375 0.859,-1.84707 2.3232,-5.62764 2.4376,-6.3125 0.1137,-0.68214 0.168,-1.35277 0.2187,-1.75 0.029,-0.2295 -0.1471,-0.8789 -0.125,-0.9375 0.031,-0.082 0.2883,-0.25057 0.3437,-0.5 0.2663,-1.19831 0.089,-2.20736 -0.125,-3.625 -0.2139,-1.41763 -0.9716,-4.61463 -1.625,-5.46875 -0.6589,-0.86172 -1.2248,-1.01051 -1.75,-1 z"
- id="path8089-9"
- sodipodi:nodetypes="ccssscsssscssssscsssscssssscsssscssssscsssscssssscsssscssssscsssscssscccccssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsssssssssssc" />
- <g
- clip-path="url(#clipPath7421-7)"
- id="g8091-4">
- <path
- inkscape:connector-curvature="0"
- id="path8093-3"
- d="m 1107.409,-284.04961 c -0.4187,0.21283 -0.1556,0.0939 -0.6472,0.30581 -0.4861,0.20954 -1.7234,0.57439 -4.0796,1.45895 -3.3311,1.25057 -5.8302,2.15344 -7.0259,3.0661 -1.5361,0.0213 -3.7205,0.23331 -5.6563,0.71875 -2.9815,0.74766 -4.8552,1.17401 -6.75,1.59375 -1.8948,0.41972 -1.6755,0.64219 -2.875,0.875 -1.2966,0.25166 -1.7214,-0.009 -5.4375,0.78125 -3.4899,0.74214 -8.8948,1.93107 -10.1562,2.6875 -1.5839,-0.18079 -3.8675,-0.32178 -5.8438,-0.0312 -3.0404,0.44695 -4.9162,0.67276 -6.8437,0.90625 -0.6554,0.0794 -1.0411,0.20078 -1.3438,0.28125 -0.4262,0.13165 -0.6858,0.26002 -1.375,0.34375 -1.3116,0.15936 -1.7622,-0.15683 -5.5312,0.28125 -3.5539,0.41308 -9.0054,1.27282 -10.25,1.9375 -1.599,-0.2973 -3.8578,-0.53419 -5.8438,-0.34375 -3.0588,0.29331 -4.972,0.48399 -6.9062,0.65625 -1.9343,0.17226 -1.6887,0.42237 -2.9063,0.53125 -1.3162,0.11769 -1.7598,-0.16363 -5.5312,0.25 -3.5419,0.38844 -9.0079,1.20927 -10.2813,1.875 -1.5989,-0.2947 -3.88717,-0.50701 -5.875,-0.3125 -3.05824,0.29924 -4.94113,0.48024 -6.875,0.65625 -0.65749,0.0598 -1.04004,0.17856 -1.34375,0.25 -0.42765,0.11895 -0.68351,0.21807 -1.375,0.28125 -1.31596,0.12025 -1.75976,-0.19488 -5.53125,0.21875 -3.55614,0.39001 -9.00554,1.23916 -10.25,1.90625 -1.59863,-0.29419 -3.85984,-0.52372 -5.84375,-0.3125 -3.0556,0.32532 -4.97404,0.52624 -6.90625,0.71875 -1.93221,0.1925 -1.68987,0.44088 -2.90625,0.5625 -1.31488,0.13146 -1.76298,-0.16454 -5.53125,0.28125 -3.53887,0.41865 -8.97768,1.29217 -10.25,1.96875 -1.59755,-0.28105 -3.85996,-0.42043 -5.84375,-0.1875 -3.05198,0.35836 -4.94508,0.56786 -6.875,0.78125 -0.6562,0.0725 -1.04066,0.17269 -1.34375,0.25 -0.42677,0.12722 -0.68491,0.2672 -1.375,0.34375 -1.31333,0.14568 -1.76746,-0.17402 -5.53125,0.3125 -3.54889,0.45875 -8.97863,1.41902 -10.21875,2.125 -1.59305,-0.24424 -3.83381,-0.38135 -5.8125,-0.125 -3.04759,0.39481 -4.95071,0.64845 -6.875,0.90625 -1.92428,0.25779 -1.72611,0.49353 -2.9375,0.65625 -1.30946,0.1759 -1.74719,-0.10438 -5.5,0.46875 -3.52429,0.53824 -8.92315,1.69917 -10.1875,2.4375 -1.5875,-0.20354 -3.8455,-0.25473 -5.8125,0.0937 -3.02617,0.53612 -4.89889,0.86169 -6.8125,1.1875 -0.65061,0.11077 -1.01371,0.27094 -1.3125,0.375 -0.42067,0.16488 -0.66345,0.3313 -1.34375,0.46875 -1.29465,0.26159 -1.72712,-0.006 -5.4375,0.8125 -3.49853,0.77195 -8.84595,2.38293 -10.0625,3.21875 -1.56278,-0.0774 -3.75758,0.0853 -5.6875,0.59375 -2.97244,0.78313 -4.81761,1.23209 -6.6875,1.75 -1.86988,0.5179 -1.6666,0.76728 -2.84375,1.09375 -1.27246,0.3529 -1.69703,0.10709 -5.34375,1.1875 -3.4247,1.01463 -8.64944,2.93317 -9.875,3.84375 -1.53883,0.0127 -3.71983,0.27222 -5.625,0.875 -2.93106,0.92734 -4.75031,1.45842 -6.59375,2.0625 -0.62676,0.20538 -0.99173,0.39258 -1.28125,0.53125 -0.40763,0.21361 -0.65334,0.40875 -1.3125,0.625 -1.25446,0.41154 -1.68611,0.18904 -5.28125,1.4375 -3.38985,1.17717 -8.59498,3.2137 -9.78125,4.15625 -1.52389,0.0597 -3.65005,0.39487 -5.53125,1.0625 -2.89739,1.02829 -4.69908,1.67548 -6.53125,2.3125 -1.83217,0.63701 -1.62785,0.84854 -2.78125,1.25 -1.24678,0.43396 -1.66361,0.19972 -5.21875,1.5625 -3.33867,1.2798 -8.48715,3.48255 -9.6875,4.46875 -1.50718,0.10769 -3.63569,0.4988 -5.5,1.21875 -2.86818,1.1076 -4.6238,1.78156 -6.4375,2.46875 -0.61666,0.23363 -0.99641,0.44203 -1.28125,0.59375 0,0 0,1.09375 0,1.09375 0.11178,-0.22236 0.38599,-0.81743 0.90625,-1.09375 0.69797,-0.37072 4.81363,-1.99337 6.8125,-2.71875 1.65686,-0.60125 4.15389,-1.32868 5.96875,-1.3125 0.30162,0.003 0.58762,0.0509 0.84375,0.0937 1.84249,0.30825 7.46875,1.5625 7.46875,1.5625 -10e-6,0 -6.23349,-1.64675 -7.03125,-1.84375 -0.19079,-0.0471 -0.53572,-0.0687 -0.96875,-0.0625 1.14546,-0.86971 4.761,-2.39351 7.34375,-3.4375 2.83822,-1.14727 3.11681,-1.25182 5.0625,-1.65625 2.0083,-0.41744 3.15625,-0.5 3.15625,-0.5 0,10e-6 -0.0824,-0.60114 0.96875,-1.125 0.7051,-0.35141 4.88702,-1.8924 6.90625,-2.5625 1.9519,-0.64773 5.0574,-1.3585 6.875,-1 1.86323,0.3675 7.53125,1.8125 7.53125,1.8125 10e-6,0 -6.287,-1.87111 -7.09375,-2.09375 -0.19292,-0.0532 -0.53084,-0.086 -0.96875,-0.0937 1.15834,-0.83288 4.79444,-2.19532 7.40625,-3.15625 2.87016,-1.05601 3.16734,-1.1618 5.125,-1.53125 1.85349,-0.34979 2.85884,-0.42548 3.03125,-0.4375 0.1136,-0.21724 0.37745,-0.81002 0.90625,-1.0625 0.70944,-0.33874 4.92607,-1.71275 6.96875,-2.3125 1.69317,-0.49711 4.24077,-1.03677 6.09375,-0.90625 0.30795,0.0217 0.61349,0.0973 0.875,0.15625 1.88118,0.42432 7.59375,2.03125 7.59375,2.03125 10e-6,0 -6.34174,-2.06525 -7.15625,-2.3125 -0.19479,-0.0591 -0.55788,-0.10394 -1,-0.125 1.16949,-0.79755 4.86302,-2.05622 7.5,-2.9375 2.89781,-0.96847 3.23301,-1.00332 5.21875,-1.28125 2.04965,-0.28689 3.1875,-0.3125 3.1875,-0.3125 -2e-5,0 -0.0728,-0.60697 1,-1.0625 0.7196,-0.30557 4.99098,-1.50075 7.0625,-2 2.00244,-0.48258 5.19849,-0.92829 7.0625,-0.40625 1.91078,0.53515 7.71875,2.5 7.71875,2.5 0,0 -6.42266,-2.42351 -7.25,-2.71875 -0.19784,-0.0706 -0.58216,-0.14039 -1.03125,-0.1875 1.1879,-0.72865 4.91527,-1.77408 7.59375,-2.5 2.94342,-0.79775 3.29208,-0.77083 5.3125,-0.90625 1.91289,-0.12823 2.94705,-0.0711 3.125,-0.0625 0.11728,-0.20366 0.39176,-0.77948 0.9375,-0.96875 0.73219,-0.25394 5.07852,-1.04789 7.1875,-1.375 1.74813,-0.27111 4.40088,-0.4847 6.3125,-0.0937 0.31766,0.065 0.60522,0.18551 0.875,0.28125 1.94074,0.68873 7.84375,3.09375 7.84375,3.09375 10e-6,0 -6.53471,-2.95077 -7.375,-3.3125 -0.20097,-0.0865 -0.57513,-0.16679 -1.03125,-0.25 1.2065,-0.63318 5.02956,-1.3956 7.75,-1.90625 2.98953,-0.56119 3.30023,-0.52954 5.34375,-0.53125 2.10926,-0.002 3.3125,0.125 3.3125,0.125 0,1e-5 -0.0727,-0.63119 1.03125,-0.9375 0.74052,-0.20547 5.12612,-0.83387 7.25,-1.0625 2.05302,-0.22099 5.31863,-0.25222 7.21875,0.46875 1.94779,0.73907 7.84375,3.375 7.84375,3.375 2e-5,0 -6.56288,-3.17897 -7.40625,-3.5625 -0.20168,-0.0917 -0.54221,-0.18621 -1,-0.28125 1.21092,-0.60188 4.98442,-1.24884 7.71875,-1.65625 3.0048,-0.44772 3.32551,-0.4517 5.375,-0.40625 1.94045,0.043 3.00699,0.19423 3.1875,0.21875 0.11892,-0.19316 0.3839,-0.76583 0.9375,-0.90625 0.74271,-0.18838 5.15429,-0.73428 7.28125,-0.9375 1.76303,-0.16842 4.42009,-0.23429 6.34375,0.25 0.31968,0.0805 0.60351,0.20359 0.875,0.3125 1.95293,0.78349 7.90625,3.46875 7.90625,3.46875 -2e-5,0 -6.59191,-3.25348 -7.4375,-3.65625 -0.20222,-0.0963 -0.57226,-0.20703 -1.03125,-0.3125 1.21414,-0.57427 5.04366,-1.12219 7.78125,-1.5 3.00838,-0.4152 3.32307,-0.44263 5.375,-0.375 2.11798,0.0698 3.3125,0.25 3.3125,0.25 -2e-5,0 -0.0773,-0.63741 1.03125,-0.90625 0.74362,-0.18035 5.15176,-0.66355 7.28125,-0.84375 2.05847,-0.17417 5.34324,-0.12432 7.25,0.65625 1.95459,0.80016 7.875,3.53125 7.875,3.53125 -2e-5,0 -6.55993,-3.30876 -7.40625,-3.71875 -0.20237,-0.0981 -0.57186,-0.2031 -1.03125,-0.3125 1.21517,-0.5639 5.01008,-1.1143 7.75,-1.46875 3.01091,-0.38952 3.32131,-0.39765 5.375,-0.3125 1.94439,0.0806 3.00663,0.25324 3.1875,0.28125 0.11916,-0.19086 0.38277,-0.74531 0.9375,-0.875 0.74426,-0.174 5.14993,-0.65047 7.28125,-0.8125 1.76662,-0.13427 4.4497,-0.12571 6.375,0.375 0.32,0.0832 0.6033,0.20127 0.875,0.3125 1.9546,0.80016 7.9063,3.5625 7.9063,3.5625 -10e-5,0 -6.5912,-3.34001 -7.4375,-3.75 -0.2024,-0.0981 -0.5719,-0.20311 -1.0313,-0.3125 1.2151,-0.5639 5.0413,-1.08306 7.7813,-1.4375 3.0109,-0.38953 3.3525,-0.4289 5.4062,-0.34375 2.1197,0.0879 3.3125,0.3125 3.3125,0.3125 0,0 -0.078,-0.64902 1.0313,-0.90625 0.7443,-0.17256 5.1495,-0.62336 7.2812,-0.78125 2.0606,-0.1526 5.3429,-0.0968 7.25,0.6875 1.955,0.80395 7.875,3.5 7.875,3.5 0,0 -6.5598,-3.27587 -7.4062,-3.6875 -0.2025,-0.0984 -0.5718,-0.20222 -1.0313,-0.3125 1.2154,-0.56154 5.0119,-1.12778 7.75,-1.5 3.009,-0.40905 3.3227,-0.41558 5.375,-0.34375 1.9431,0.068 3.0072,0.16485 3.1875,0.1875 0.1188,-0.1944 0.3846,-0.72881 0.9375,-0.875 0.7418,-0.19612 5.1311,-0.82878 7.25,-1.09375 1.7564,-0.21961 4.4053,-0.33231 6.3125,0.0312 0.3169,0.0604 0.6058,0.18938 0.875,0.28125 1.9362,0.66092 7.8438,2.9375 7.8438,2.9375 -1e-4,0 -6.5367,-2.80655 -7.375,-3.15625 -0.2005,-0.0836 -0.5762,-0.17333 -1.0313,-0.25 1.2037,-0.65046 5.0191,-1.37195 7.7188,-2 2.9667,-0.6902 3.2889,-0.75507 5.3125,-0.875 2.0886,-0.1238 3.2812,-0.0312 3.2812,-0.0312 0,1e-5 -0.087,-0.63205 1,-1.03125 0.7292,-0.2678 5.0472,-1.33797 7.125,-1.8125 2.0085,-0.45869 5.1679,-1.0293 7,-0.625 1.8781,0.41446 13.5782,3.01563 13.5782,3.01563 0,0 -12.3275,-3.02266 -13.1407,-3.26563 -0.1945,-0.0581 -0.5586,-0.10626 -1,-0.125 1.1676,-0.80369 3.5142,-1.6873 6.1094,-2.70312 1.6814,-0.65818 0.9237,-0.37659 2.7759,-1.0036 1.7536,-0.59366 2.4854,-1.01071 2.6304,-1.11299 0.3461,-0.20651 -0.356,-0.12188 -0.5442,-0.0424 z"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7001-5);enable-background:new"
- sodipodi:nodetypes="czscsssscssssscsssscssssscsssscssssscsssscssssscsssscssssscsssscssccsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscc" />
- <path
- inkscape:connector-curvature="0"
- id="path8095-5"
- d="m 1082.625,-275.125 c 1.873,0.39348 4.4961,1.14555 6.0313,1.96875 1.5352,0.82319 2.8222,1.056 5.375,2.5 2.5266,1.42926 4.7958,2.00696 6.9687,2.53125 2.3476,0.56642 5.4354,0.71523 8.8438,1.1875 -1.0889,-0.83975 -6.6074,-1.17245 -8.4063,-1.5625 -1.7989,-0.39006 -3.8941,-1.01616 -6.5937,-2.3125 -2.6997,-1.29634 -3.4944,-1.79896 -5.8125,-2.6875 -2.3182,-0.88854 -4.0044,-1.38314 -6.4063,-1.625 z"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6949-4);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8097-1"
- d="m 1051.4688,-270 c 1.9053,0.57759 4.5281,1.61572 6.0937,2.59375 1.5656,0.97802 2.8802,1.35981 5.5,3.125 2.593,1.74716 4.9859,2.70927 7.25,3.59375 2.4461,0.95557 5.6826,1.65713 9.4063,3.0625 -1.1896,-1.13784 -7.0631,-2.68675 -8.9375,-3.375 -1.8745,-0.68825 -4.0818,-1.5662 -6.875,-3.28125 -2.7933,-1.71504 -3.5736,-2.2839 -5.9375,-3.40625 -2.3641,-1.12234 -4.0567,-1.83455 -6.5,-2.3125 z"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6961-8);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8099-7"
- d="m 1020.2188,-266.84375 c 1.9119,0.63811 4.5812,1.75536 6.1562,2.8125 1.5751,1.05715 2.8956,1.50867 5.5313,3.40625 2.6086,1.87821 5.0284,3.03003 7.3125,4.0625 2.4677,1.11545 5.7645,2.1733 9.5312,3.84375 -1.2033,-1.22253 -7.2028,-3.31423 -9.0937,-4.125 -1.891,-0.81077 -4.0649,-1.89379 -6.875,-3.75 -2.8102,-1.8562 -3.6218,-2.47693 -6,-3.71875 -2.3783,-1.2418 -4.1107,-1.97569 -6.5625,-2.53125 z"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6957-9);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8101-4"
- d="m 1110.1719,-266.89063 c 0.1508,0.0486 0.688,0.631 0.1094,1.48438 -0.8101,1.19459 -5.7049,3.32429 -8.5625,4.125 -2.8449,0.79712 -6.2901,0.97774 -10.5625,-0.375 -4.3016,-1.36195 -5.4697,-2.46872 -10.6563,-4.3125 4.664,2.11517 6.1953,3.95233 10.125,5.34375 1.6207,0.57387 3.3671,0.9396 5.0625,1.03125 -0.4451,0.32563 -1.5303,0.9833 -3.5625,1.59375 -2.7955,0.83969 -6.6491,1.53378 -8.25,1.625 -1.5146,0.0863 -3.142,-0.51249 -3.4375,-0.625 0.1667,0.10308 0.3732,0.37734 -0.25,1.03125 -0.8993,0.94363 -6.1474,1.923 -9.125,2.25 -2.9643,0.32555 -6.5216,-0.016 -10.9062,-1.90625 -3.978,-1.71497 -5.339,-2.91536 -9.4063,-4.75 0,0 0,0.15625 0,0.15625 3.6431,2.09529 5.284,3.88327 8.875,5.5625 1.7302,0.80909 3.5917,1.40876 5.4063,1.71875 -0.5349,0.28676 -1.5578,0.71151 -3.4375,1.03125 -2.869,0.48796 -6.809,0.81614 -8.4375,0.75 -0.8507,-0.0345 -1.7286,-0.18437 -2.4063,-0.40625 -0.6848,-0.21488 -1.1897,-0.44467 -1.3125,-0.5 0.1694,0.10721 0.4311,0.40288 -0.2187,1.03125 -0.9097,0.87962 -6.2461,1.33638 -9.25,1.46875 -2.9905,0.13179 -6.5889,-0.45063 -11,-2.5625 -4.4412,-2.12626 -5.6415,-3.4016 -10.9063,-5.78125 4.7343,2.59704 6.2865,4.6291 10.3438,6.71875 1.6733,0.86185 3.4852,1.49425 5.25,1.9375 -0.4633,0.23332 -1.5894,0.68814 -3.6875,0.9375 -2.8863,0.34298 -6.8346,0.49288 -8.4688,0.375 -1.5462,-0.1115 -3.2312,-0.85696 -3.5312,-1 0.1691,0.12029 0.4138,0.41048 -0.2188,1 -0.9128,0.85073 -6.2441,1.26212 -9.25,1.375 -2.9925,0.11237 -6.5897,-0.49043 -11,-2.59375 -4.00125,-1.90823 -5.38803,-3.13783 -9.46875,-5.09375 -3e-5,0 0,0.15625 0,0.15625 3.65506,2.20392 5.29421,4.05255 8.90625,5.90625 1.74029,0.89315 3.637,1.52827 5.4688,1.96875 -0.54,0.2483 -1.5781,0.61533 -3.4688,0.84375 -2.88568,0.34858 -6.86605,0.52095 -8.5,0.40625 -0.85345,-0.0599 -1.72631,-0.25791 -2.40625,-0.5 -0.6871,-0.2353 -1.18935,-0.47226 -1.3125,-0.53125 0.16998,0.11227 0.46448,0.42225 -0.1875,1.03125 -0.91265,0.8525 -6.27533,1.29337 -9.28125,1.40625 -2.99246,0.11237 -6.59346,-0.52805 -11,-2.59375 -4.43653,-2.07978 -5.64688,-3.33171 -10.90625,-5.65625 4.72938,2.54749 6.29074,4.5778 10.34375,6.625 1.67155,0.84433 3.48554,1.46643 5.25,1.90625 -0.46323,0.23422 -1.5897,0.68407 -3.6875,0.9375 -2.88569,0.34858 -6.8362,0.56952 -8.46875,0.46875 -1.54456,-0.0953 -3.20031,-0.82885 -3.5,-0.96875 0.16899,0.11853 0.38192,0.40385 -0.25,1 -0.91186,0.86028 -6.24665,1.33025 -9.25,1.46875 -2.98995,0.1379 -6.56745,-0.45068 -10.96875,-2.46875 -3.99308,-1.83089 -5.36511,-3.0292 -9.4375,-4.90625 -2e-5,0 0,0.15625 0,0.15625 3.64761,2.13327 5.27033,3.93487 8.875,5.71875 1.73675,0.85951 3.60727,1.45014 5.4375,1.875 -0.53947,0.2529 -1.55063,0.64129 -3.4375,0.90625 -2.87978,0.40436 -6.83813,0.64562 -8.46875,0.5625 -0.85172,-0.0434 -1.7277,-0.20855 -2.40625,-0.4375 -0.68569,-0.22201 -1.1896,-0.44339 -1.3125,-0.5 0.16959,0.10899 0.4319,0.40965 -0.21875,1.03125 -0.91079,0.87014 -6.25021,1.39152 -9.25,1.5625 -2.98633,0.17021 -6.57381,-0.31577 -10.96875,-2.28125 -4.42489,-1.97888 -5.60596,-3.22819 -10.84375,-5.375 4.70997,2.38767 6.27017,4.38873 10.3125,6.34375 1.66715,0.80631 3.46043,1.39658 5.21875,1.78125 -0.46163,0.2487 -1.597,0.71225 -3.6875,1.03125 -2.8756,0.43876 -6.7804,0.7331 -8.40625,0.6875 -1.53823,-0.0431 -3.2328,-0.74522 -3.53125,-0.875 0.16833,0.11282 0.41057,0.41375 -0.21875,1.03125 -0.90812,0.8911 -6.20295,1.52825 -9.1875,1.8125 -2.97118,0.28298 -6.57342,-0.1758 -10.9375,-1.9375 -3.95934,-1.59831 -5.32915,-2.79487 -9.34375,-4.3125 3e-5,0 0,0.15625 0,0.15625 3.5959,1.81135 5.23831,3.58233 8.8125,5.15625 1.72207,0.75835 3.58748,1.28895 5.40625,1.625 -0.53609,0.27908 -1.56658,0.68763 -3.4375,1.0625 -2.85539,0.5721 -6.78942,1.01939 -8.40625,1.03125 -0.84451,0.006 -1.70608,-0.0809 -2.375,-0.25 -0.67591,-0.16151 -1.16009,-0.32923 -1.28125,-0.375 0.16722,0.094 0.42267,0.38348 -0.21875,1.0625 -0.89787,0.95052 -6.18648,1.91708 -9.125,2.4375 -2.92534,0.51809 -6.43215,0.37424 -10.71875,-1.03125 -4.3158,-1.41507 -5.47277,-2.52994 -10.5625,-3.96875 4.57685,1.75101 6.08855,3.56006 10.03125,5 1.62608,0.59389 3.36885,0.95565 5.09375,1.15625 -0.45285,0.29702 -1.55478,0.88339 -3.59375,1.46875 -2.80472,0.80517 -6.63886,1.57583 -8.21875,1.75 -1.49475,0.1648 -3.11623,-0.31681 -3.40625,-0.40625 0.16356,0.0901 0.39278,0.35993 -0.21875,1.0625 -0.88247,1.01385 -6.04452,2.37165 -8.9375,3.0625 -2.88002,0.68778 -6.3356,0.76002 -10.5625,-0.4375 -3.83485,-1.08645 -5.17258,-2.07237 -9.0625,-3.125 -10e-6,0 0,0.15625 0,0.15625 3.48418,1.39485 5.06941,2.9194 8.53125,4.03125 1.66793,0.53572 3.45578,0.78674 5.21875,0.875 -0.51964,0.35212 -1.50039,0.91452 -3.3125,1.53125 -2.76566,0.94125 -6.59024,1.93537 -8.15625,2.15625 -0.81794,0.11539 -1.6331,0.12283 -2.28125,0.0312 -0.65496,-0.0832 -1.1326,-0.21827 -1.25,-0.25 0.16204,0.0746 0.43399,0.34044 -0.1875,1.09375 -0.87,1.05453 -6.00963,2.65925 -8.875,3.4375 -2.85253,0.77476 -6.25912,0.9582 -10.4375,-0.0937 -4.20683,-1.05913 -5.35669,-2.04166 -10.34375,-3.15625 4.48454,1.45946 5.96935,3.13523 9.8125,4.25 1.58504,0.45977 3.28679,0.63825 4.96875,0.6875 -0.44157,0.33676 -1.51251,1.02773 -3.5,1.78125 -2.73393,1.03649 -6.45198,2.16269 -8,2.4375 -1.46462,0.26002 -3.05958,-0.11654 -3.34375,-0.1875 0.16025,0.0796 0.38044,0.32098 -0.21875,1.0625 -0.86466,1.07006 -5.91652,2.81815 -8.75,3.6875 -2.8208,0.86547 -6.2075,1.15631 -10.34375,0.21875 -3.75259,-0.85061 -5.04785,-1.71647 -8.875,-2.59375 0,0 0,0.15625 0,0.15625 3.42796,1.23779 4.98741,2.6323 8.375,3.53125 1.63216,0.43314 3.36704,0.58301 5.09375,0.5625 -0.50893,0.38417 -1.47675,1.02182 -3.25,1.75 -2.70634,1.11134 -6.43633,2.30781 -7.96875,2.625 -0.8004,0.16569 -1.61231,0.21862 -2.25,0.15625 0,0 0,0.51552 0,0.92229 0,0.26507 0,0.48396 0,0.48396 0.22645,-0.14468 0.44891,-0.27261 0.71875,-0.375 1.08052,-0.40998 2.17161,-0.21577 6,-1.6875 3.82843,-1.47174 5.22412,-2.00498 5.90625,-2.40625 0.6796,-0.39978 1.61165,-0.87937 2.21875,-1.53125 1.82685,-0.13775 3.57075,-0.49323 4.9375,-1 2.96812,-1.10052 4.87537,-1.80619 6.78125,-2.46875 1.90586,-0.66254 2.35409,-1.41487 3.40625,-1.78125 1.09155,-0.38011 2.19511,-0.16538 6.0625,-1.53125 3.86745,-1.36586 5.28316,-1.82708 5.96875,-2.21875 0.70109,-0.40052 1.70081,-0.93298 2.3125,-1.59375 1.9708,-0.0547 3.81685,-0.38463 5.28125,-0.875 3.00148,-1.00508 4.92615,-1.62171 6.84375,-2.25 1.5386,-0.5041 2.17402,-1.04677 2.90625,-1.4375 0.23016,-0.13431 0.47574,-0.25373 0.75,-0.34375 1.09823,-0.36048 2.18145,-0.0814 6.09375,-1.3125 3.91233,-1.23113 5.36605,-1.67295 6.0625,-2.03125 0.69388,-0.35697 1.63015,-0.79261 2.25,-1.40625 1.86521,-0.0227 3.63581,-0.26683 5.03125,-0.6875 3.03043,-0.91354 4.99238,-1.4301 6.9375,-1.96875 1.94511,-0.53864 2.42618,-1.26452 3.5,-1.5625 1.11401,-0.30915 2.21994,0.007 6.1875,-1.03125 3.96761,-1.03863 5.41758,-1.43273 6.125,-1.75 0.73487,-0.32959 1.81383,-0.75372 2.4375,-1.375 1.99774,0.116 3.85743,-0.0201 5.34375,-0.375 3.07811,-0.735 5.08344,-1.10094 7.0625,-1.5 1.58792,-0.32018 2.24429,-0.79055 3,-1.09375 0.23757,-0.1068 0.46695,-0.19276 0.75,-0.25 1.13347,-0.22919 2.30448,0.20893 6.34375,-0.5 4.03933,-0.70893 5.50025,-0.92709 6.21875,-1.1875 0.71586,-0.25944 1.70428,-0.56724 2.34375,-1.09375 1.92427,0.23949 3.74788,0.22453 5.1875,0 3.12633,-0.48762 5.15455,-0.70067 7.15625,-0.96875 2.00171,-0.26807 2.48869,-0.94514 3.59375,-1.09375 1.14639,-0.15418 2.27592,0.30157 6.34375,-0.21875 4.06784,-0.52032 5.56013,-0.69573 6.28125,-0.9375 0.7371,-0.24714 1.79809,-0.58623 2.4375,-1.125 2.05007,0.33553 3.97378,0.39796 5.5,0.21875 3.14231,-0.36896 5.17994,-0.55936 7.1875,-0.78125 1.61076,-0.17802 2.26467,-0.6082 3.03125,-0.84375 0.24094,-0.0855 0.49412,-0.1556 0.78125,-0.1875 1.14978,-0.12772 2.30129,0.34665 6.375,-0.125 4.07374,-0.47165 5.55909,-0.6106 6.28125,-0.84375 0.71946,-0.23227 1.70024,-0.47346 2.34375,-0.96875 1.93637,0.33346 3.77006,0.40424 5.21875,0.25 3.14602,-0.33495 5.17756,-0.51859 7.1875,-0.71875 2.00996,-0.20014 2.48414,-0.82639 3.59375,-0.9375 1.15114,-0.11528 2.29643,0.36506 6.375,-0.0625 4.07861,-0.42756 5.58886,-0.56209 6.3125,-0.78125 0.73915,-0.22386 1.79572,-0.51325 2.4375,-1.03125 2.0571,0.39867 4.00187,0.4934 5.53125,0.34375 3.14873,-0.3081 5.17584,-0.47325 7.1875,-0.65625 1.61407,-0.14682 2.2631,-0.56055 3.03125,-0.78125 0.24142,-0.0809 0.49353,-0.12991 0.78125,-0.15625 1.15211,-0.10545 2.29296,0.39275 6.375,0 4.08208,-0.39275 5.5889,-0.53084 6.3125,-0.75 0.7209,-0.21833 1.6997,-0.4477 2.3438,-0.9375 1.938,0.34999 3.7688,0.45438 5.2187,0.3125 3.1487,-0.3081 5.1758,-0.47325 7.1875,-0.65625 2.0116,-0.18299 2.5142,-0.83802 3.625,-0.9375 1.1523,-0.10323 2.2922,0.38483 6.375,0 4.0829,-0.38482 5.5887,-0.501 6.3125,-0.71875 0.7393,-0.22243 1.7956,-0.51449 2.4375,-1.03125 2.0574,0.40177 4.0029,0.50333 5.5313,0.34375 3.1466,-0.32852 5.1771,-0.5227 7.1875,-0.71875 1.613,-0.15729 2.2656,-0.63148 3.0312,-0.875 0.2407,-0.088 0.4632,-0.12137 0.75,-0.15625 1.1483,-0.1397 2.3167,0.33991 6.375,-0.25 4.0583,-0.58992 5.5618,-0.77714 6.2813,-1.03125 0.7167,-0.25316 1.6745,-0.55807 2.3125,-1.09375 1.9197,0.21194 3.7199,0.15141 5.1562,-0.0937 3.1191,-0.5324 5.1116,-0.92861 7.0938,-1.3125 1.9821,-0.38387 2.4743,-1.03965 3.5625,-1.28125 1.1288,-0.25066 2.2703,0.11629 6.25,-0.875 3.9796,-0.99128 5.4296,-1.4193 6.125,-1.78125 0.7223,-0.37601 1.7619,-0.87058 2.375,-1.53125 1.963,-0.012 3.7937,-0.29105 5.2187,-0.84375 2.9512,-1.14461 4.8732,-1.86942 6.6875,-2.75 1.4557,-0.70653 2.3348,-1.68641 2.5469,-1.98438 0.2122,-0.29796 0.1118,-0.7453 0.1379,-0.76675 0.043,-0.0352 0.3193,-0.085 0.479,-0.42844 0.8589,-1.84708 2.321,-5.64459 2.4352,-6.32945 0.1137,-0.68216 0.1638,-1.34774 0.2145,-1.74497 0.029,-0.22952 -0.1467,-0.86544 -0.1246,-0.92404 0.031,-0.0821 0.3045,-0.26528 0.3599,-0.51471 0.2663,-1.19833 0.089,-2.19129 -0.1251,-3.60893 -0.214,-1.41764 -0.9837,-4.62214 -1.6369,-5.47626 -0.6589,-0.86172 -1.2229,-1.01117 -1.7479,-1.00066 -0.2086,0.26976 0.1368,0.26309 0.1626,0.31261 0.6806,0.0508 0.934,0.36864 1.4192,0.89662 0.4852,0.52798 1.4428,3.93956 1.5794,5.38995 0.1366,1.45039 0.19,2.8602 -0.088,3.46864 -0.2781,0.60845 -0.9442,0.42864 -1.2366,0.49452 0.531,0.18589 0.8908,0.21322 0.9524,1.05768 0.059,0.81338 -0.1332,1.63969 -0.5198,2.80562 -0.3912,1.18001 -1.8452,4.34998 -2.2857,4.59877 -0.4523,0.25551 -0.9524,0.18199 -1.288,0.0511 z"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6997-5);enable-background:new"
- sodipodi:nodetypes="cssscscsscsssccscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssccscsscscssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsszsszssszzcczzzczzzc" />
- <path
- inkscape:connector-curvature="0"
- id="path8103-3"
- d="m 988.75,-263.84375 c 1.91161,0.6344 4.55027,1.75841 6.125,2.8125 1.57477,1.05409 2.8961,1.48252 5.5313,3.375 2.6082,1.87314 5.0269,3.01522 7.3125,4.0625 2.4693,1.13147 5.7521,2.15474 9.5312,3.9375 -1.2072,-1.2584 -7.139,-3.36445 -9.0312,-4.1875 -1.8922,-0.82304 -4.128,-1.93049 -6.9375,-3.78125 -2.80961,-1.85075 -3.62224,-2.48154 -6.00005,-3.71875 -2.37782,-1.23719 -4.07988,-1.9492 -6.53125,-2.5 z"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6953-8);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8105-1"
- d="m 957.5,-260.78125 c 1.91,0.6181 4.58288,1.70934 6.15625,2.75 1.57339,1.04066 2.89608,1.48252 5.53125,3.375 2.60823,1.87315 5.02692,3.01521 7.3125,4.0625 2.46931,1.13147 5.75213,2.15475 9.53125,3.9375 -1.20728,-1.2584 -7.20154,-3.3957 -9.09375,-4.21875 -1.89217,-0.82304 -4.09666,-1.9305 -6.90625,-3.78125 -2.80958,-1.85075 -3.59295,-2.43932 -5.96875,-3.65625 -2.37578,-1.21691 -4.11321,-1.93885 -6.5625,-2.46875 z"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6993-3);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8107-4"
- d="m 926.09375,-257.375 c 1.90772,0.59745 4.55348,1.66384 6.125,2.6875 1.5715,1.02365 2.87022,1.43971 5.5,3.28125 2.60291,1.82273 5.02887,2.9722 7.3125,4 2.4672,1.11041 5.75535,2.09323 9.53125,3.84375 -1.20623,-1.2481 -7.1719,-3.31809 -9.0625,-4.125 -1.89058,-0.8069 -4.10242,-1.89104 -6.90625,-3.6875 -2.80385,-1.79644 -3.62704,-2.40251 -6,-3.59375 -2.37297,-1.19124 -4.05362,-1.90283 -6.5,-2.40625 z"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6989-8);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8109-6"
- d="m 894.90625,-253.5625 c 1.90213,0.55355 4.58701,1.58887 6.15625,2.59375 1.56923,1.00487 2.87401,1.40864 5.5,3.21875 2.59912,1.79164 5.00034,2.87189 7.28125,3.875 2.46428,1.08374 5.75984,2.04029 9.53125,3.75 -1.2048,-1.23507 -7.17416,-3.24478 -9.0625,-4.03125 -1.88832,-0.78647 -4.0752,-1.8308 -6.875,-3.59375 -2.79977,-1.76294 -3.59919,-2.36836 -5.96875,-3.53125 -2.36957,-1.16288 -4.12325,-1.83412 -6.5625,-2.28125 z"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6985-6);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8111-9"
- d="m 863.71875,-248.65625 c 1.88062,0.42909 4.50427,1.38038 6.0625,2.3125 1.55823,0.93211 2.85233,1.25776 5.46875,3 2.58971,1.72444 4.98067,2.70802 7.25,3.625 2.45176,0.99069 5.73959,1.87707 9.5,3.5 -1.20131,-1.20734 -7.15249,-3.06609 -9.03125,-3.78125 -1.87875,-0.71517 -4.0854,-1.68442 -6.875,-3.375 -2.78963,-1.69057 -3.58461,-2.22822 -5.9375,-3.28125 -2.35292,-1.05301 -4.02584,-1.71248 -6.4375,-2 z"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6965-3);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8113-4"
- d="m 833.15625,-241.375 c 1.84836,0.29644 4.46945,0.97632 6,1.78125 1.53058,0.80493 2.81374,1.05573 5.375,2.53125 2.53504,1.46046 4.89068,2.32509 7.125,3.0625 2.41399,0.79668 5.65711,1.46689 9.375,2.84375 -1.18771,-1.12873 -7.08772,-2.58975 -8.9375,-3.15625 -1.84977,-0.5665 -4.00342,-1.37392 -6.75,-2.84375 -2.74657,-1.46983 -3.50136,-1.92028 -5.8125,-2.78125 -2.31115,-0.86095 -4.00471,-1.32009 -6.375,-1.4375 z"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6981-3);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8115-2"
- d="m 802.90625,-232.3125 c 1.8222,0.21127 4.36576,0.80057 5.875,1.53125 1.50925,0.73066 2.75568,0.92998 5.28125,2.28125 2.49976,1.33746 4.83154,2.04843 7.03125,2.65625 2.37653,0.65667 5.56464,1.07288 9.21875,2.1875 -1.16735,-1.04496 -6.92888,-2.10329 -8.75,-2.5625 -1.82111,-0.45921 -3.95225,-1.12696 -6.65625,-2.4375 -2.70403,-1.31052 -3.47106,-1.7199 -5.75,-2.46875 -2.27895,-0.74883 -3.91325,-1.17931 -6.25,-1.1875 z"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6977-6);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8117-2"
- d="m 773.1875,-222.1875 c 1.81109,0.1787 4.32059,0.66506 5.8125,1.34375 1.49194,0.67869 2.7534,0.79822 5.25,2.0625 2.47107,1.25138 4.79005,1.89614 6.96875,2.4375 2.35387,0.58488 5.49134,0.89752 9.09375,1.84375 -1.15084,-0.99116 -6.85251,-1.7833 -8.65625,-2.1875 -1.80372,-0.4042 -3.91553,-1.02116 -6.59375,-2.25 -2.67818,-1.22884 -3.40345,-1.61089 -5.65625,-2.28125 -2.25279,-0.67034 -3.89627,-1.00232 -6.21875,-0.96875 z"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6973-4);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8119-6"
- d="m 743.5625,-211.1875 c 1.79281,0.12911 4.27313,0.54965 5.75,1.1875 1.4769,0.63785 2.7161,0.74156 5.1875,1.9375 2.44618,1.18372 4.72054,1.74666 6.875,2.21875 2.32767,0.51003 5.4196,0.68064 9,1.5625 -1.14379,-0.9706 -6.74759,-1.59065 -8.53125,-1.9375 -1.78367,-0.34684 -3.88285,-0.88756 -6.53125,-2.03125 -2.64841,-1.14368 -3.39495,-1.51631 -5.625,-2.125 -2.23008,-0.60868 -3.82594,-0.90966 -6.125,-0.8125 z"
- style="display:inline;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter6969-8);enable-background:new" />
- <g
- id="g8121-4"
- style="fill:#ffffff;fill-opacity:1;filter:url(#filter7345-9)">
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="czzzczzc"
- id="path8123-1"
- d="m 744.9375,-212.11731 c 0,0 7.22229,-3.22318 9.0625,-3.5 1.84021,-0.27682 3.35225,-0.003 6,0.5625 2.64775,0.56573 8.7357,2.21518 11.1875,3.375 2.4518,1.15982 5.3125,3.5625 5.3125,3.5625 0,0 -7.14644,-2.78019 -10.1875,-3.5625 -3.04106,-0.78231 -7.64461,-2.08374 -10.375,-2.3125 -2.73039,-0.22876 -11,1.875 -11,1.875 z"
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="czzzczzc"
- id="path8125-2"
- d="m 735.46875,-206.95416 c 0,0 3.65979,-2.22318 5.5,-2.5 1.84021,-0.27682 3.66475,0.24677 6.3125,0.8125 2.64775,0.56573 8.7357,2.21518 11.1875,3.375 2.4518,1.15982 6.5625,2.125 6.5625,2.125 0,0 -8.39644,-1.34269 -11.4375,-2.125 -3.04106,-0.78231 -7.95711,-2.33374 -10.6875,-2.5625 -2.73039,-0.22876 -7.4375,0.875 -7.4375,0.875 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="czzzczzc"
- id="path8127-8"
- d="m 759.85042,-217.61116 c 0,0 8.5437,-3.29857 10.39778,-3.45786 1.85409,-0.1593 3.64166,0.4792 6.2481,1.21208 2.60644,0.73288 8.57724,2.76594 10.95036,4.07925 2.37312,1.31331 6.41417,2.53782 6.41417,2.53782 0,0 -8.29413,-1.87365 -11.27931,-2.84767 -2.98519,-0.97402 -7.79269,-2.83478 -10.50302,-3.23662 -2.71033,-0.40184 -12.22808,1.713 -12.22808,1.713 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="czzzczzc"
- id="path8129-8"
- d="m 775.19813,-223.2266 c 0,0 7.77133,-2.78244 9.62831,-2.90349 1.85697,-0.12104 3.631,0.55417 6.22178,1.34062 2.59077,0.78645 8.5184,2.94217 10.86394,4.30412 2.34555,1.36195 6.36049,2.6695 6.36049,2.6695 0,0 -8.25373,-2.04423 -11.21821,-3.07958 -2.96447,-1.03535 -7.73259,-2.99481 -10.43406,-3.45243 -2.70147,-0.45763 -11.42225,1.12126 -11.42225,1.12126 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-4.3190906"
- inkscape:transform-center-x="13.852145"
- sodipodi:nodetypes="czzzczzc"
- id="path8131-9"
- d="m 789.64298,-227.95417 c 0,0 8.68256,-3.52031 10.54154,-3.60535 1.85897,-0.085 3.61958,0.62442 6.19463,1.46093 2.57505,0.83649 8.45979,3.10666 10.77851,4.5138 2.31872,1.40715 6.30757,2.79224 6.30757,2.79224 0,0 -8.21257,-2.20377 -11.15643,-3.29636 -2.94386,-1.09259 -7.67312,-3.14408 -10.36522,-3.65397 -2.69209,-0.50988 -12.3006,1.78871 -12.3006,1.78871 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-4.3190906"
- inkscape:transform-center-x="13.852145"
- sodipodi:nodetypes="czzzczzc"
- id="path8133-2"
- d="m 804.49513,-233.32948 c 0,0 7.80756,-2.58281 9.66654,-2.66785 1.85897,-0.085 3.61958,0.62442 6.19463,1.46093 2.57505,0.83649 8.45979,3.10666 10.77851,4.5138 2.31872,1.40715 6.30757,2.79224 6.30757,2.79224 0,0 -8.21257,-2.20377 -11.15643,-3.29636 -2.94386,-1.09259 -7.67312,-3.14408 -10.36522,-3.65397 -2.69209,-0.50988 -11.4256,0.85121 -11.4256,0.85121 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-4.3190906"
- inkscape:transform-center-x="13.852145"
- sodipodi:nodetypes="czzzczzc"
- id="path8135-8"
- d="m 819.55763,-237.57948 c 0,0 8.55756,-2.58281 10.41654,-2.66785 1.85897,-0.085 3.61958,0.62442 6.19463,1.46093 2.57505,0.83649 8.45979,3.10666 10.77851,4.5138 2.31872,1.40715 6.30757,2.79224 6.30757,2.79224 0,0 -8.21257,-2.20377 -11.15643,-3.29636 -2.94386,-1.09259 -7.67312,-3.14408 -10.36522,-3.65397 -2.69209,-0.50988 -12.1756,0.85121 -12.1756,0.85121 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-4.9269042"
- inkscape:transform-center-x="13.64141"
- sodipodi:nodetypes="czzzczzc"
- id="path8137-8"
- d="m 836.23395,-242.60125 c 0,0 6.96702,-1.98723 8.82784,-1.96757 1.86081,0.0197 3.57873,0.82702 6.10265,1.80705 2.52393,0.98 8.27166,3.57758 10.50756,5.11291 2.2359,1.53535 6.14053,3.14261 6.14053,3.14261 0,0 -8.07561,-2.66222 -10.95336,-3.91866 -2.87774,-1.25645 -7.48412,-3.5707 -10.14328,-4.23121 -2.65915,-0.66049 -10.48194,0.0549 -10.48194,0.0549 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-5.1542119"
- inkscape:transform-center-x="13.55068"
- sodipodi:nodetypes="czzzczzc"
- id="path8139-8"
- d="m 850.73028,-246.00461 c 0,0 7.68784,-2.02768 9.54782,-1.96854 1.85997,0.0592 3.56038,0.90279 6.06293,1.93616 2.50255,1.03334 8.19387,3.75232 10.39668,5.33475 2.20282,1.58245 6.07245,3.2722 6.07245,3.2722 0,0 -8.01729,-2.83298 -10.86772,-4.15022 -2.85043,-1.31723 -7.40666,-3.72872 -10.0512,-4.4455 -2.64454,-0.71678 -11.16096,0.0211 -11.16096,0.0211 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-5.4740887"
- inkscape:transform-center-x="13.41151"
- sodipodi:nodetypes="czzzczzc"
- id="path8141-6"
- d="m 864.82496,-249.21081 c 0,0 8.16952,-1.96906 10.02688,-1.85396 1.85735,0.11512 3.53158,1.00956 6.0019,2.11779 2.47031,1.10821 8.0772,3.99727 10.23138,5.64531 2.15418,1.64804 5.9712,3.45352 5.9712,3.45352 0,0 -7.92839,-3.07306 -10.73787,-4.4755 -2.80949,-1.40244 -7.29106,-3.94999 -9.91283,-4.74606 -2.62176,-0.79606 -11.58066,-0.1411 -11.58066,-0.1411 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-5.79376"
- inkscape:transform-center-x="13.258805"
- sodipodi:nodetypes="czzzczzc"
- id="path8143-8"
- d="m 881.38485,-251.60282 c 0,0 8.08536,-1.90809 9.93837,-1.73664 1.853,0.17147 3.4993,1.11633 5.93482,2.29908 2.43553,1.18271 7.95209,4.2407 10.05523,5.95339 2.10314,1.7127 5.86357,3.63326 5.86357,3.63326 0,0 -7.8314,-3.3124 -10.597,-4.7995 -2.76561,-1.48712 -7.16775,-4.16959 -9.76414,-5.04491 -2.59637,-0.87531 -11.43085,-0.30468 -11.43085,-0.30468 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-5.7433893"
- inkscape:transform-center-x="13.28378"
- sodipodi:nodetypes="czzzczzc"
- id="path8145-3"
- d="m 896.58415,-254.34724 c 0,0 7.64166,-1.4277 9.49547,-1.26515 1.8538,0.16256 3.50462,1.0995 5.94579,2.27053 2.44118,1.171 7.97238,4.20246 10.08372,5.90502 2.11134,1.70258 5.88096,3.60505 5.88096,3.60505 0,0 -7.84723,-3.27474 -10.61995,-4.74855 -2.77271,-1.4738 -7.18769,-4.13509 -9.78825,-4.99793 -2.60055,-0.86282 -10.99774,-0.76897 -10.99774,-0.76897 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-5.7433893"
- inkscape:transform-center-x="13.28378"
- sodipodi:nodetypes="czzzczzc"
- id="path8147-8"
- d="m 911.45328,-255.98544 c 0,0 8.64166,-1.5527 10.49547,-1.39015 1.8538,0.16256 3.50462,1.0995 5.94579,2.27053 2.44118,1.171 7.97238,4.20246 10.08372,5.90502 2.11134,1.70258 5.88096,3.60505 5.88096,3.60505 0,0 -7.84723,-3.27474 -10.61995,-4.74855 -2.77271,-1.4738 -7.18769,-4.13509 -9.78825,-4.99793 -2.60055,-0.86282 -11.99774,-0.64397 -11.99774,-0.64397 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-5.7433893"
- inkscape:transform-center-x="13.28378"
- sodipodi:nodetypes="czzzczzc"
- id="path8149-3"
- d="m 927.70328,-258.29794 c 0,0 7.64166,-0.8652 9.49547,-0.70265 1.8538,0.16256 3.50462,1.0995 5.94579,2.27053 2.44118,1.171 7.97238,4.20246 10.08372,5.90502 2.11134,1.70258 5.88096,3.60505 5.88096,3.60505 0,0 -7.84723,-3.27474 -10.61995,-4.74855 -2.77271,-1.4738 -7.18769,-4.13509 -9.78825,-4.99793 -2.60055,-0.86282 -10.99774,-1.33147 -10.99774,-1.33147 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-5.7433893"
- inkscape:transform-center-x="13.28378"
- sodipodi:nodetypes="czzzczzc"
- id="path8151-3"
- d="m 942.82828,-259.48544 c 0,0 8.57916,-1.4902 10.43297,-1.32765 1.8538,0.16256 3.50462,1.0995 5.94579,2.27053 2.44118,1.171 7.97238,4.20246 10.08372,5.90502 2.11134,1.70258 5.88096,3.60505 5.88096,3.60505 0,0 -7.84723,-3.27474 -10.61995,-4.74855 -2.77271,-1.4738 -7.18769,-4.13509 -9.78825,-4.99793 -2.60055,-0.86282 -11.93524,-0.70647 -11.93524,-0.70647 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-5.7433893"
- inkscape:transform-center-x="13.28378"
- sodipodi:nodetypes="czzzczzc"
- id="path8153-3"
- d="m 959.07828,-261.54794 c 0,0 7.82916,-0.8027 9.68297,-0.64015 1.8538,0.16256 3.50462,1.0995 5.94579,2.27053 2.44118,1.171 7.97238,4.20246 10.08372,5.90502 2.11134,1.70258 5.88096,3.60505 5.88096,3.60505 0,0 -7.84723,-3.27474 -10.61995,-4.74855 -2.77271,-1.4738 -7.18769,-4.13509 -9.78825,-4.99793 -2.60055,-0.86282 -11.18524,-1.39397 -11.18524,-1.39397 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-5.7433893"
- inkscape:transform-center-x="13.28378"
- sodipodi:nodetypes="czzzczzc"
- id="path8155-8"
- d="m 974.45328,-262.79794 c 0,0 8.39166,-1.1777 10.24547,-1.01515 1.8538,0.16256 3.50462,1.0995 5.94579,2.27053 2.44118,1.171 7.97238,4.20246 10.08376,5.90502 2.1113,1.70258 5.8809,3.60505 5.8809,3.60505 0,0 -7.84721,-3.27474 -10.61993,-4.74855 -2.77271,-1.4738 -7.18769,-4.13509 -9.78825,-4.99793 -2.60055,-0.86282 -11.74774,-1.01897 -11.74774,-1.01897 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-5.7433893"
- inkscape:transform-center-x="13.28378"
- sodipodi:nodetypes="czzzczzc"
- id="path8157-0"
- d="m 990.64078,-264.86044 c 0,0 6.89166,-0.9902 8.74547,-0.82765 1.85385,0.16256 3.50465,1.0995 5.94575,2.27053 2.4412,1.171 7.9724,4.20246 10.0838,5.90502 2.1113,1.70258 5.8809,3.60505 5.8809,3.60505 0,0 -7.8472,-3.27474 -10.6199,-4.74855 -2.7727,-1.4738 -7.1877,-4.13509 -9.7883,-4.99793 -2.60053,-0.86282 -10.24772,-1.20647 -10.24772,-1.20647 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-5.7433893"
- inkscape:transform-center-x="13.28378"
- sodipodi:nodetypes="czzzczzc"
- id="path8159-4"
- d="m 1007.7658,-265.79794 c 0,0 6.8291,-1.1777 8.683,-1.01515 1.8538,0.16256 3.5046,1.0995 5.9457,2.27053 2.4412,1.171 7.9724,4.20246 10.0838,5.90502 2.1113,1.70258 5.8809,3.60505 5.8809,3.60505 0,0 -7.8472,-3.27474 -10.6199,-4.74855 -2.7727,-1.4738 -7.1877,-4.13509 -9.7883,-4.99793 -2.6005,-0.86282 -10.1852,-1.01897 -10.1852,-1.01897 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-5.7433893"
- inkscape:transform-center-x="13.28378"
- sodipodi:nodetypes="czzzczzc"
- id="path8161-7"
- d="m 1023.8908,-267.79794 c 0,0 6.0791,-0.4277 7.933,-0.26515 1.8538,0.16256 3.5046,1.0995 5.9457,2.27053 2.4412,1.171 7.9724,4.20246 10.0838,5.90502 2.1113,1.70258 5.8809,3.60505 5.8809,3.60505 0,0 -7.8472,-3.27474 -10.6199,-4.74855 -2.7727,-1.4738 -7.1877,-4.13509 -9.7883,-4.99793 -2.6005,-0.86282 -9.4352,-1.76897 -9.4352,-1.76897 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-5.7433893"
- inkscape:transform-center-x="13.28378"
- sodipodi:nodetypes="czzzczzc"
- id="path8163-6"
- d="m 1039.7033,-269.17294 c 0,0 6.4541,-0.6777 8.308,-0.51515 1.8538,0.16256 3.5046,1.0995 5.9457,2.27053 2.4412,1.171 7.9724,4.20246 10.0838,5.90502 2.1113,1.70258 5.8809,3.60505 5.8809,3.60505 0,0 -7.8472,-3.27474 -10.6199,-4.74855 -2.7727,-1.4738 -7.1877,-4.13509 -9.7883,-4.99793 -2.6005,-0.86282 -9.8102,-1.51897 -9.8102,-1.51897 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-5.1360724"
- inkscape:transform-center-x="13.55813"
- sodipodi:nodetypes="czzzczzc"
- id="path8165-8"
- d="m 1055.2718,-271.03319 c 0,0 5.4976,-0.90945 7.3578,-0.85348 1.8601,0.056 3.5619,0.89674 6.0661,1.92586 2.5044,1.0291 8.2003,3.7384 10.4058,5.31709 2.2055,1.57871 6.078,3.2619 6.078,3.2619 0,0 -8.022,-2.81939 -10.8748,-4.13178 -2.8526,-1.31238 -7.4129,-3.71613 -10.0587,-4.42843 -2.6457,-0.71228 -8.9742,-1.09116 -8.9742,-1.09116 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-4.6370147"
- inkscape:transform-center-x="13.74758"
- sodipodi:nodetypes="czzzczzc"
- id="path8167-9"
- d="m 1072.7007,-273.48537 c 0,0 4.5472,-1.15581 6.408,-1.18621 1.8607,-0.0304 3.5996,0.73049 6.1489,1.64231 2.5494,0.91177 8.3649,3.35386 10.6414,4.8285 2.2763,1.47468 6.2227,2.97636 6.2227,2.97636 0,0 -8.1442,-2.44411 -11.0547,-3.62272 -2.9105,-1.1786 -7.5774,-3.36815 -10.2534,-3.95691 -2.6759,-0.58875 -8.1129,-0.68133 -8.1129,-0.68133 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- inkscape:transform-center-y="-4.4842392"
- inkscape:transform-center-x="13.79933"
- sodipodi:nodetypes="czzzczzc"
- id="path8169-0"
- d="m 1087.1585,-276.5244 c 0,0 5.96,-1.77355 7.8202,-1.83024 1.86,-0.0567 3.6096,0.67955 6.1715,1.55525 2.562,0.87566 2.5226,0.85713 5.3335,1.49015 2.7969,0.62986 7.0767,1.51313 7.0767,1.51313 0,0 -3.6155,-0.0163 -6.7923,-0.46614 -3.1155,-0.44119 -7.3743,-1.69825 -10.0584,-2.24913 -2.6839,-0.55088 -9.5512,-0.013 -9.5512,-0.013 z"
- style="display:inline;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="czczc"
- id="path8171-6"
- d="m 1099.25,-279.92981 c 0.1612,0.26862 11.2081,-4.60046 12.1875,-4.6875 0.9794,-0.087 2,3.125 2,3.125 0,0 -0.7751,-1.50434 -2.875,-1.0625 -2.0999,0.44184 -11.3009,2.67141 -11.3125,2.625 z"
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- </g>
- <path
- inkscape:connector-curvature="0"
- id="path8173-8"
- d="m 1107.4532,-284.0938 c -0.4187,0.21283 -0.1556,0.0939 -0.6472,0.30581 -0.4861,0.20954 -1.7234,0.57439 -4.0796,1.45895 -3.3311,1.25057 -5.8302,2.15344 -7.0259,3.0661 -1.5361,0.0213 -3.7205,0.23331 -5.6563,0.71875 -2.9815,0.74766 -4.8552,1.17401 -6.75,1.59375 -1.8948,0.41972 -1.6755,0.64219 -2.875,0.875 -1.2966,0.25166 -1.7214,-0.009 -5.4375,0.78125 -3.4899,0.74214 -8.8948,1.93107 -10.1562,2.6875 -1.5839,-0.18079 -3.8675,-0.32178 -5.8438,-0.0312 -3.0404,0.44695 -4.9162,0.67276 -6.8437,0.90625 -0.6554,0.0794 -1.0411,0.20078 -1.3438,0.28125 -0.4262,0.13165 -0.6858,0.26002 -1.375,0.34375 -1.3116,0.15936 -1.7622,-0.15683 -5.5312,0.28125 -3.5539,0.41308 -9.0054,1.27282 -10.25,1.9375 -1.599,-0.2973 -3.8578,-0.53419 -5.8438,-0.34375 -3.0588,0.29331 -4.972,0.48399 -6.9062,0.65625 -1.9343,0.17226 -1.6887,0.42237 -2.9063,0.53125 -1.3162,0.11769 -1.7598,-0.16363 -5.5312,0.25 -3.5419,0.38844 -9.0079,1.20927 -10.2813,1.875 -1.5989,-0.2947 -3.88718,-0.50701 -5.87501,-0.3125 -3.05824,0.29924 -4.94113,0.48024 -6.875,0.65625 -0.65749,0.0598 -1.04004,0.17856 -1.34375,0.25 -0.42765,0.11895 -0.68351,0.21807 -1.375,0.28125 -1.31596,0.12025 -1.75976,-0.19488 -5.53125,0.21875 -3.55614,0.39001 -9.00554,1.23916 -10.25,1.90625 -1.59863,-0.29419 -3.85984,-0.52372 -5.84375,-0.3125 -3.0556,0.32532 -4.97404,0.52624 -6.90625,0.71875 -1.93221,0.1925 -1.68987,0.44088 -2.90625,0.5625 -1.31488,0.13146 -1.76298,-0.16454 -5.53125,0.28125 -3.53887,0.41865 -8.97768,1.29217 -10.25,1.96875 -1.59755,-0.28105 -3.85996,-0.42043 -5.84375,-0.1875 -3.05198,0.35836 -4.94508,0.56786 -6.875,0.78125 -0.6562,0.0726 -1.04066,0.17269 -1.34375,0.25 -0.42677,0.12722 -0.68491,0.2672 -1.375,0.34375 -1.31333,0.14568 -1.76746,-0.17402 -5.53125,0.3125 -3.54889,0.45875 -8.97863,1.41902 -10.21875,2.125 -1.59305,-0.24424 -3.83381,-0.38135 -5.8125,-0.125 -3.04759,0.39481 -4.95071,0.64845 -6.875,0.90625 -1.92428,0.25779 -1.72611,0.49353 -2.9375,0.65625 -1.30946,0.1759 -1.74719,-0.10438 -5.5,0.46875 -3.52429,0.53824 -8.92315,1.69917 -10.1875,2.4375 -1.5875,-0.20354 -3.8455,-0.25473 -5.8125,0.0937 -3.02617,0.53612 -4.89889,0.86169 -6.8125,1.1875 -0.65061,0.11077 -1.01371,0.27094 -1.3125,0.375 -0.42067,0.16488 -0.66345,0.3313 -1.34375,0.46875 -1.29465,0.26159 -1.72712,-0.006 -5.4375,0.8125 -3.49853,0.77195 -8.84595,2.38293 -10.0625,3.21875 -1.56278,-0.0775 -3.75758,0.0853 -5.6875,0.59375 -2.97244,0.78313 -4.81761,1.23209 -6.6875,1.75 -1.86988,0.5179 -1.6666,0.76728 -2.84375,1.09375 -1.27246,0.3529 -1.69703,0.10709 -5.34375,1.1875 -3.4247,1.01463 -8.64944,2.93317 -9.875,3.84375 -1.53883,0.0127 -3.71983,0.27222 -5.625,0.875 -2.93106,0.92734 -4.75031,1.45842 -6.59375,2.0625 -0.62676,0.20538 -0.99173,0.39258 -1.28125,0.53125 -0.40763,0.21361 -0.65334,0.40875 -1.3125,0.625 -1.25446,0.41154 -1.68611,0.18904 -5.28125,1.4375 -3.38985,1.17717 -8.59498,3.2137 -9.78125,4.15625 -1.52389,0.0597 -3.65005,0.39487 -5.53125,1.0625 -2.89739,1.02829 -4.69908,1.67548 -6.53125,2.3125 -1.83217,0.63701 -1.62785,0.84854 -2.78125,1.25 -1.24678,0.43396 -1.66361,0.19972 -5.21875,1.5625 -3.33867,1.2798 -8.48715,3.48255 -9.6875,4.46875 -1.50718,0.10769 -3.63569,0.4988 -5.5,1.21875 -2.86818,1.1076 -4.6238,1.78156 -6.4375,2.46875 -0.61666,0.23363 -0.99641,0.44203 -1.28125,0.59375 0,0 0,1.09375 0,1.09375 0.11178,-0.22236 0.38599,-0.81743 0.90625,-1.09375 0.69797,-0.37072 4.81363,-1.99337 6.8125,-2.71875 1.65686,-0.60125 4.15389,-1.32868 5.96875,-1.3125 0.30162,0.003 0.58762,0.0509 0.84375,0.0937 1.84249,0.30825 7.46875,1.5625 7.46875,1.5625 -10e-6,0 -6.23349,-1.64675 -7.03125,-1.84375 -0.19079,-0.0471 -0.53572,-0.0687 -0.96875,-0.0625 1.14546,-0.86971 4.761,-2.39351 7.34375,-3.4375 2.83822,-1.14727 3.11681,-1.25182 5.0625,-1.65625 2.0083,-0.41744 3.15625,-0.5 3.15625,-0.5 0,1e-5 -0.0824,-0.60114 0.96875,-1.125 0.7051,-0.35141 4.88702,-1.8924 6.90625,-2.5625 1.9519,-0.64773 5.0574,-1.3585 6.875,-1 1.86323,0.3675 7.53125,1.8125 7.53125,1.8125 1e-5,0 -6.287,-1.87111 -7.09375,-2.09375 -0.19292,-0.0533 -0.53084,-0.086 -0.96875,-0.0937 1.15834,-0.83288 4.79444,-2.19532 7.40625,-3.15625 2.87016,-1.05601 3.16734,-1.1618 5.125,-1.53125 1.85349,-0.34979 2.85884,-0.42548 3.03125,-0.4375 0.1136,-0.21724 0.37745,-0.81002 0.90625,-1.0625 0.70944,-0.33874 4.92607,-1.71275 6.96875,-2.3125 1.69317,-0.49711 4.24077,-1.03677 6.09375,-0.90625 0.30795,0.0217 0.61349,0.0973 0.875,0.15625 1.88118,0.42432 7.59375,2.03125 7.59375,2.03125 1e-5,0 -6.34174,-2.06525 -7.15625,-2.3125 -0.19479,-0.0591 -0.55788,-0.10394 -1,-0.125 1.16949,-0.79755 4.86302,-2.05622 7.5,-2.9375 2.89781,-0.96847 3.23301,-1.00332 5.21875,-1.28125 2.04965,-0.28689 3.1875,-0.3125 3.1875,-0.3125 -2e-5,0 -0.0727,-0.60697 1,-1.0625 0.7196,-0.30557 4.99098,-1.50075 7.0625,-2 2.00244,-0.48258 5.19849,-0.92829 7.0625,-0.40625 1.91078,0.53515 7.71875,2.5 7.71875,2.5 0,0 -6.42266,-2.42351 -7.25,-2.71875 -0.19784,-0.0706 -0.58216,-0.14039 -1.03125,-0.1875 1.1879,-0.72865 4.91527,-1.77408 7.59375,-2.5 2.94342,-0.79775 3.29208,-0.77083 5.3125,-0.90625 1.91289,-0.12823 2.94705,-0.0711 3.125,-0.0625 0.11728,-0.20366 0.39176,-0.77948 0.9375,-0.96875 0.73219,-0.25394 5.07852,-1.04789 7.1875,-1.375 1.74813,-0.27111 4.40088,-0.4847 6.3125,-0.0937 0.31766,0.065 0.60522,0.18551 0.875,0.28125 1.94074,0.68873 7.84375,3.09375 7.84375,3.09375 1e-5,0 -6.53471,-2.95077 -7.375,-3.3125 -0.20097,-0.0865 -0.57513,-0.16679 -1.03125,-0.25 1.2065,-0.63318 5.02956,-1.3956 7.75,-1.90625 2.98953,-0.56119 3.30023,-0.52954 5.34375,-0.53125 2.10926,-0.002 3.3125,0.125 3.3125,0.125 0,1e-5 -0.0727,-0.63119 1.03125,-0.9375 0.74052,-0.20547 5.12612,-0.83387 7.25,-1.0625 2.05302,-0.22099 5.31863,-0.25222 7.21875,0.46875 1.94779,0.73907 7.84375,3.375 7.84375,3.375 2e-5,0 -6.56288,-3.17897 -7.40625,-3.5625 -0.20168,-0.0917 -0.54221,-0.18621 -1,-0.28125 1.21092,-0.60188 4.98442,-1.24884 7.71875,-1.65625 3.0048,-0.44772 3.32551,-0.4517 5.375,-0.40625 1.94045,0.043 3.00699,0.19423 3.1875,0.21875 0.11892,-0.19316 0.3839,-0.76583 0.9375,-0.90625 0.74271,-0.18838 5.15429,-0.73428 7.28125,-0.9375 1.76303,-0.16842 4.42009,-0.23429 6.34375,0.25 0.31968,0.0805 0.60351,0.20359 0.875,0.3125 1.95293,0.78349 7.90625,3.46875 7.90625,3.46875 -2e-5,0 -6.59191,-3.25348 -7.4375,-3.65625 -0.20222,-0.0963 -0.57226,-0.20703 -1.03125,-0.3125 1.21414,-0.57427 5.04366,-1.12219 7.78125,-1.5 3.00838,-0.4152 3.32307,-0.44263 5.375,-0.375 2.11798,0.0698 3.3125,0.25 3.3125,0.25 -2e-5,0 -0.0772,-0.63741 1.03125,-0.90625 0.74362,-0.18035 5.15176,-0.66355 7.28125,-0.84375 2.05847,-0.17417 5.34324,-0.12432 7.25,0.65625 1.95459,0.80016 7.875,3.53125 7.875,3.53125 -2e-5,0 -6.55993,-3.30876 -7.40625,-3.71875 -0.20237,-0.0981 -0.57186,-0.2031 -1.03125,-0.3125 1.21517,-0.5639 5.01008,-1.1143 7.75,-1.46875 3.01091,-0.38952 3.32131,-0.39765 5.375,-0.3125 1.94439,0.0806 3.00663,0.25324 3.1875,0.28125 0.11916,-0.19086 0.38277,-0.74531 0.9375,-0.875 0.74426,-0.174 5.14993,-0.65047 7.28125,-0.8125 1.76662,-0.13427 4.44971,-0.12571 6.37501,0.375 0.32,0.0832 0.6033,0.20127 0.875,0.3125 1.9546,0.80016 7.9063,3.5625 7.9063,3.5625 -1e-4,0 -6.5912,-3.34001 -7.4375,-3.75 -0.2024,-0.0981 -0.5719,-0.20311 -1.0313,-0.3125 1.2151,-0.5639 5.0413,-1.08306 7.7813,-1.4375 3.0109,-0.38953 3.3525,-0.4289 5.4062,-0.34375 2.1197,0.0879 3.3125,0.3125 3.3125,0.3125 0,0 -0.078,-0.64902 1.0313,-0.90625 0.7443,-0.17256 5.1495,-0.62336 7.2812,-0.78125 2.0606,-0.1526 5.3429,-0.0968 7.25,0.6875 1.955,0.80395 7.875,3.5 7.875,3.5 0,0 -6.5598,-3.27587 -7.4062,-3.6875 -0.2025,-0.0984 -0.5718,-0.20222 -1.0313,-0.3125 1.2154,-0.56154 5.0119,-1.12778 7.75,-1.5 3.009,-0.40905 3.3227,-0.41558 5.375,-0.34375 1.9431,0.068 3.0072,0.16485 3.1875,0.1875 0.1188,-0.1944 0.3846,-0.72881 0.9375,-0.875 0.7418,-0.19612 5.1311,-0.82878 7.25,-1.09375 1.7564,-0.21961 4.4053,-0.33231 6.3125,0.0312 0.3169,0.0604 0.6058,0.18938 0.875,0.28125 1.9362,0.66092 7.8438,2.9375 7.8438,2.9375 -10e-5,0 -6.5367,-2.80655 -7.375,-3.15625 -0.2005,-0.0836 -0.5762,-0.17333 -1.0313,-0.25 1.2037,-0.65046 5.0191,-1.37195 7.7188,-2 2.9667,-0.6902 3.2889,-0.75507 5.3125,-0.875 2.0886,-0.1238 3.2812,-0.0312 3.2812,-0.0312 0,1e-5 -0.087,-0.63205 1,-1.03125 0.7292,-0.2678 5.0472,-1.33797 7.125,-1.8125 2.0085,-0.45869 5.1679,-1.0293 7,-0.625 1.8781,0.41446 13.5782,3.01563 13.5782,3.01563 0,0 -12.3275,-3.02266 -13.1407,-3.26563 -0.1945,-0.0581 -0.5586,-0.10626 -1,-0.125 1.1676,-0.80369 3.5142,-1.6873 6.1094,-2.70312 1.6814,-0.65818 0.9237,-0.37659 2.7759,-1.0036 1.7536,-0.59366 2.4854,-1.01071 2.6304,-1.11299 0.3461,-0.20651 -0.356,-0.12188 -0.5442,-0.0424 z"
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7333-7);enable-background:new"
- sodipodi:nodetypes="czscsssscssssscsssscssssscsssscssssscsssscssssscsssscssssscsssscssccsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscsssscscsscssscscsscc" />
- <path
- inkscape:connector-curvature="0"
- id="path8175-7"
- d="m 1082.625,-275.125 c 1.873,0.39348 4.4961,1.14555 6.0313,1.96875 1.5352,0.82319 2.8222,1.056 5.375,2.5 2.5266,1.42926 4.7958,2.00696 6.9687,2.53125 2.3476,0.56642 5.4354,0.71523 8.8438,1.1875 -1.0889,-0.83975 -6.6074,-1.17245 -8.4063,-1.5625 -1.7989,-0.39006 -3.8941,-1.01616 -6.5937,-2.3125 -2.6997,-1.29634 -3.4944,-1.79896 -5.8125,-2.6875 -2.3182,-0.88854 -4.0044,-1.38314 -6.4063,-1.625 z"
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7285-4);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8177-9"
- d="m 1051.4688,-270 c 1.9053,0.57759 4.5281,1.61572 6.0937,2.59375 1.5656,0.97802 2.8802,1.35981 5.5,3.125 2.593,1.74716 4.9859,2.70927 7.25,3.59375 2.4461,0.95557 5.6826,1.65713 9.4063,3.0625 -1.1896,-1.13784 -7.0631,-2.68675 -8.9375,-3.375 -1.8745,-0.68825 -4.0818,-1.5662 -6.875,-3.28125 -2.7933,-1.71504 -3.5736,-2.2839 -5.9375,-3.40625 -2.3641,-1.12234 -4.0567,-1.83455 -6.5,-2.3125 z"
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7289-0);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8179-0"
- d="m 1020.2188,-266.84375 c 1.9119,0.63811 4.5812,1.75536 6.1562,2.8125 1.5751,1.05715 2.8956,1.50867 5.5313,3.40625 2.6086,1.87821 5.0284,3.03003 7.3125,4.0625 2.4677,1.11545 5.7645,2.1733 9.5312,3.84375 -1.2033,-1.22253 -7.2028,-3.31423 -9.0937,-4.125 -1.891,-0.81077 -4.0649,-1.89379 -6.875,-3.75 -2.8102,-1.8562 -3.6218,-2.47693 -6,-3.71875 -2.3783,-1.2418 -4.1107,-1.97569 -6.5625,-2.53125 z"
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7293-0);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8181-3"
- d="m 1110.1719,-266.89063 c 0.1508,0.0486 0.688,0.631 0.1094,1.48438 -0.8101,1.19459 -5.7049,3.32429 -8.5625,4.125 -2.8449,0.79712 -6.2901,0.97774 -10.5625,-0.375 -4.3016,-1.36195 -5.4697,-2.46872 -10.6563,-4.3125 4.664,2.11517 6.1953,3.95233 10.125,5.34375 1.6207,0.57387 3.3671,0.9396 5.0625,1.03125 -0.4451,0.32563 -1.5303,0.9833 -3.5625,1.59375 -2.7955,0.83969 -6.6491,1.53378 -8.25,1.625 -1.5146,0.0863 -3.142,-0.51249 -3.4375,-0.625 0.1667,0.10308 0.3732,0.37734 -0.25,1.03125 -0.8993,0.94363 -6.1474,1.923 -9.125,2.25 -2.9643,0.32555 -6.5216,-0.016 -10.9062,-1.90625 -3.978,-1.71497 -5.339,-2.91536 -9.4063,-4.75 0,0 0,0.15625 0,0.15625 3.6431,2.09529 5.284,3.88327 8.875,5.5625 1.7302,0.80909 3.5917,1.40876 5.4063,1.71875 -0.5349,0.28676 -1.5578,0.71151 -3.4375,1.03125 -2.869,0.48796 -6.809,0.81614 -8.4375,0.75 -0.8507,-0.0345 -1.7286,-0.18437 -2.4063,-0.40625 -0.6848,-0.21488 -1.1897,-0.44467 -1.3125,-0.5 0.1694,0.10721 0.4311,0.40288 -0.2187,1.03125 -0.9097,0.87962 -6.2461,1.33638 -9.25,1.46875 -2.9905,0.13179 -6.5889,-0.45063 -11,-2.5625 -4.4412,-2.12626 -5.6415,-3.4016 -10.9063,-5.78125 4.7343,2.59704 6.2865,4.6291 10.3438,6.71875 1.6733,0.86185 3.4852,1.49425 5.25,1.9375 -0.4633,0.23332 -1.5894,0.68814 -3.6875,0.9375 -2.8863,0.34298 -6.8346,0.49288 -8.4688,0.375 -1.5462,-0.1115 -3.2312,-0.85696 -3.5312,-1 0.1691,0.12029 0.4138,0.41048 -0.2188,1 -0.9128,0.85073 -6.2441,1.26212 -9.25,1.375 -2.9925,0.11237 -6.5897,-0.49043 -11,-2.59375 -4.00125,-1.90823 -5.38803,-3.13783 -9.46875,-5.09375 -3e-5,0 0,0.15625 0,0.15625 3.65506,2.20392 5.29421,4.05255 8.90625,5.90625 1.74029,0.89315 3.637,1.52827 5.4688,1.96875 -0.54,0.2483 -1.5781,0.61533 -3.4688,0.84375 -2.88568,0.34858 -6.86605,0.52095 -8.5,0.40625 -0.85345,-0.0599 -1.72631,-0.25791 -2.40625,-0.5 -0.6871,-0.2353 -1.18935,-0.47226 -1.3125,-0.53125 0.16998,0.11227 0.46448,0.42225 -0.1875,1.03125 -0.91265,0.8525 -6.27533,1.29337 -9.28125,1.40625 -2.99246,0.11237 -6.59346,-0.52805 -11,-2.59375 -4.43653,-2.07978 -5.64688,-3.33171 -10.90625,-5.65625 4.72938,2.54749 6.29074,4.5778 10.34375,6.625 1.67155,0.84433 3.48554,1.46643 5.25,1.90625 -0.46323,0.23422 -1.5897,0.68407 -3.6875,0.9375 -2.88569,0.34858 -6.8362,0.56952 -8.46875,0.46875 -1.54456,-0.0953 -3.20031,-0.82885 -3.5,-0.96875 0.16899,0.11853 0.38192,0.40385 -0.25,1 -0.91186,0.86028 -6.24665,1.33025 -9.25,1.46875 -2.98995,0.1379 -6.56745,-0.45068 -10.96875,-2.46875 -3.99308,-1.83089 -5.36511,-3.0292 -9.4375,-4.90625 -2e-5,0 0,0.15625 0,0.15625 3.64761,2.13327 5.27033,3.93487 8.875,5.71875 1.73675,0.85951 3.60727,1.45014 5.4375,1.875 -0.53947,0.2529 -1.55063,0.64129 -3.4375,0.90625 -2.87978,0.40436 -6.83813,0.64562 -8.46875,0.5625 -0.85172,-0.0434 -1.7277,-0.20855 -2.40625,-0.4375 -0.68569,-0.22201 -1.1896,-0.44339 -1.3125,-0.5 0.16959,0.10899 0.4319,0.40965 -0.21875,1.03125 -0.91079,0.87014 -6.25021,1.39152 -9.25,1.5625 -2.98633,0.17021 -6.57381,-0.31577 -10.96875,-2.28125 -4.42489,-1.97888 -5.60596,-3.22819 -10.84375,-5.375 4.70997,2.38767 6.27017,4.38873 10.3125,6.34375 1.66715,0.80631 3.46043,1.39658 5.21875,1.78125 -0.46163,0.2487 -1.597,0.71225 -3.6875,1.03125 -2.8756,0.43876 -6.7804,0.7331 -8.40625,0.6875 -1.53823,-0.0431 -3.2328,-0.74522 -3.53125,-0.875 0.16833,0.11282 0.41057,0.41375 -0.21875,1.03125 -0.90812,0.8911 -6.20295,1.52825 -9.1875,1.8125 -2.97118,0.28298 -6.57342,-0.1758 -10.9375,-1.9375 -3.95934,-1.59831 -5.32915,-2.79487 -9.34375,-4.3125 3e-5,0 0,0.15625 0,0.15625 3.5959,1.81135 5.23831,3.58233 8.8125,5.15625 1.72207,0.75835 3.58748,1.28895 5.40625,1.625 -0.53609,0.27908 -1.56658,0.68763 -3.4375,1.0625 -2.85539,0.5721 -6.78942,1.01939 -8.40625,1.03125 -0.84451,0.006 -1.70608,-0.0809 -2.375,-0.25 -0.67591,-0.16151 -1.16009,-0.32923 -1.28125,-0.375 0.16722,0.094 0.42267,0.38348 -0.21875,1.0625 -0.89787,0.95052 -6.18648,1.91708 -9.125,2.4375 -2.92534,0.51809 -6.43215,0.37424 -10.71875,-1.03125 -4.3158,-1.41507 -5.47277,-2.52994 -10.5625,-3.96875 4.57685,1.75101 6.08855,3.56006 10.03125,5 1.62608,0.59389 3.36885,0.95565 5.09375,1.15625 -0.45285,0.29702 -1.55478,0.88339 -3.59375,1.46875 -2.80472,0.80517 -6.63886,1.57583 -8.21875,1.75 -1.49475,0.1648 -3.11623,-0.31681 -3.40625,-0.40625 0.16356,0.0901 0.39278,0.35993 -0.21875,1.0625 -0.88247,1.01385 -6.04452,2.37165 -8.9375,3.0625 -2.88002,0.68778 -6.3356,0.76002 -10.5625,-0.4375 -3.83485,-1.08645 -5.17258,-2.07237 -9.0625,-3.125 -10e-6,0 0,0.15625 0,0.15625 3.48418,1.39485 5.06941,2.9194 8.53125,4.03125 1.66793,0.53572 3.45578,0.78674 5.21875,0.875 -0.51964,0.35212 -1.50039,0.91452 -3.3125,1.53125 -2.76566,0.94125 -6.59024,1.93537 -8.15625,2.15625 -0.81794,0.11539 -1.6331,0.12283 -2.28125,0.0312 -0.65496,-0.0832 -1.1326,-0.21827 -1.25,-0.25 0.16204,0.0746 0.43399,0.34044 -0.1875,1.09375 -0.87,1.05453 -6.00963,2.65925 -8.875,3.4375 -2.85253,0.77476 -6.25912,0.9582 -10.4375,-0.0937 -4.20683,-1.05913 -5.35669,-2.04166 -10.34375,-3.15625 4.48454,1.45946 5.96935,3.13523 9.8125,4.25 1.58504,0.45977 3.28679,0.63825 4.96875,0.6875 -0.44157,0.33676 -1.51251,1.02773 -3.5,1.78125 -2.73393,1.03649 -6.45198,2.16269 -8,2.4375 -1.46462,0.26002 -3.05958,-0.11654 -3.34375,-0.1875 0.16025,0.0796 0.38044,0.32098 -0.21875,1.0625 -0.86466,1.07006 -5.91652,2.81815 -8.75,3.6875 -2.8208,0.86547 -6.2075,1.15631 -10.34375,0.21875 -3.75259,-0.85061 -5.04785,-1.71647 -8.875,-2.59375 0,0 0,0.15625 0,0.15625 3.42796,1.23779 4.98741,2.6323 8.375,3.53125 1.63216,0.43314 3.36704,0.58301 5.09375,0.5625 -0.50893,0.38417 -1.47675,1.02182 -3.25,1.75 -2.70634,1.11134 -6.43633,2.30781 -7.96875,2.625 -0.8004,0.16569 -1.61231,0.21862 -2.25,0.15625 0,0 0,0.51552 0,0.92229 0,0.26507 0,0.48396 0,0.48396 0.22645,-0.14468 0.44891,-0.27261 0.71875,-0.375 1.08052,-0.40998 2.17161,-0.21577 6,-1.6875 3.82843,-1.47174 5.22412,-2.00498 5.90625,-2.40625 0.6796,-0.39978 1.61165,-0.87937 2.21875,-1.53125 1.82685,-0.13775 3.57075,-0.49323 4.9375,-1 2.96812,-1.10052 4.87537,-1.80619 6.78125,-2.46875 1.90586,-0.66254 2.35409,-1.41487 3.40625,-1.78125 1.09155,-0.38011 2.19511,-0.16538 6.0625,-1.53125 3.86745,-1.36586 5.28316,-1.82708 5.96875,-2.21875 0.70109,-0.40052 1.70081,-0.93298 2.3125,-1.59375 1.9708,-0.0547 3.81685,-0.38463 5.28125,-0.875 3.00148,-1.00508 4.92615,-1.62171 6.84375,-2.25 1.5386,-0.5041 2.17402,-1.04677 2.90625,-1.4375 0.23016,-0.13431 0.47574,-0.25373 0.75,-0.34375 1.09823,-0.36048 2.18145,-0.0814 6.09375,-1.3125 3.91233,-1.23113 5.36605,-1.67295 6.0625,-2.03125 0.69388,-0.35697 1.63015,-0.79261 2.25,-1.40625 1.86521,-0.0227 3.63581,-0.26683 5.03125,-0.6875 3.03043,-0.91354 4.99238,-1.4301 6.9375,-1.96875 1.94511,-0.53864 2.42618,-1.26452 3.5,-1.5625 1.11401,-0.30915 2.21994,0.007 6.1875,-1.03125 3.96761,-1.03863 5.41758,-1.43273 6.125,-1.75 0.73487,-0.32959 1.81383,-0.75372 2.4375,-1.375 1.99774,0.116 3.85743,-0.0201 5.34375,-0.375 3.07811,-0.735 5.08344,-1.10094 7.0625,-1.5 1.58792,-0.32018 2.24429,-0.79055 3,-1.09375 0.23757,-0.1068 0.46695,-0.19276 0.75,-0.25 1.13347,-0.22919 2.30448,0.20893 6.34375,-0.5 4.03933,-0.70893 5.50025,-0.92709 6.21875,-1.1875 0.71586,-0.25944 1.70428,-0.56724 2.34375,-1.09375 1.92427,0.23949 3.74788,0.22453 5.1875,0 3.12633,-0.48762 5.15455,-0.70067 7.15625,-0.96875 2.00171,-0.26807 2.48869,-0.94514 3.59375,-1.09375 1.14639,-0.15418 2.27592,0.30157 6.34375,-0.21875 4.06784,-0.52032 5.56013,-0.69573 6.28125,-0.9375 0.7371,-0.24714 1.79809,-0.58623 2.4375,-1.125 2.05007,0.33553 3.97378,0.39796 5.5,0.21875 3.14231,-0.36896 5.17994,-0.55936 7.1875,-0.78125 1.61076,-0.17802 2.26467,-0.6082 3.03125,-0.84375 0.24094,-0.0855 0.49412,-0.1556 0.78125,-0.1875 1.14978,-0.12772 2.30129,0.34665 6.375,-0.125 4.07374,-0.47165 5.55909,-0.6106 6.28125,-0.84375 0.71946,-0.23227 1.70024,-0.47346 2.34375,-0.96875 1.93637,0.33346 3.77006,0.40424 5.21875,0.25 3.14602,-0.33495 5.17756,-0.51859 7.1875,-0.71875 2.00996,-0.20014 2.48414,-0.82639 3.59375,-0.9375 1.15114,-0.11528 2.29643,0.36506 6.375,-0.0625 4.07861,-0.42756 5.58886,-0.56209 6.3125,-0.78125 0.73915,-0.22386 1.79572,-0.51325 2.4375,-1.03125 2.0571,0.39867 4.00187,0.4934 5.53125,0.34375 3.14873,-0.3081 5.17584,-0.47325 7.1875,-0.65625 1.61407,-0.14682 2.2631,-0.56055 3.03125,-0.78125 0.24142,-0.0809 0.49353,-0.12991 0.78125,-0.15625 1.15211,-0.10545 2.29296,0.39275 6.375,0 4.08208,-0.39275 5.5889,-0.53084 6.3125,-0.75 0.7209,-0.21833 1.6997,-0.4477 2.3438,-0.9375 1.938,0.34999 3.7688,0.45438 5.2187,0.3125 3.1487,-0.3081 5.1758,-0.47325 7.1875,-0.65625 2.0116,-0.18299 2.5142,-0.83802 3.625,-0.9375 1.1523,-0.10323 2.2922,0.38483 6.375,0 4.0829,-0.38482 5.5887,-0.501 6.3125,-0.71875 0.7393,-0.22243 1.7956,-0.51449 2.4375,-1.03125 2.0574,0.40177 4.0029,0.50333 5.5313,0.34375 3.1466,-0.32852 5.1771,-0.5227 7.1875,-0.71875 1.613,-0.15729 2.2656,-0.63148 3.0312,-0.875 0.2407,-0.088 0.4632,-0.12137 0.75,-0.15625 1.1483,-0.1397 2.3167,0.33991 6.375,-0.25 4.0583,-0.58992 5.5618,-0.77714 6.2813,-1.03125 0.7167,-0.25316 1.6745,-0.55807 2.3125,-1.09375 1.9197,0.21194 3.7199,0.15141 5.1562,-0.0937 3.1191,-0.5324 5.1116,-0.92861 7.0938,-1.3125 1.9821,-0.38387 2.4743,-1.03965 3.5625,-1.28125 1.1288,-0.25066 2.2703,0.11629 6.25,-0.875 3.9796,-0.99128 5.4296,-1.4193 6.125,-1.78125 0.7223,-0.37601 1.7619,-0.87058 2.375,-1.53125 1.963,-0.012 3.7937,-0.29105 5.2187,-0.84375 2.9512,-1.14461 4.8732,-1.86942 6.6875,-2.75 1.4557,-0.70653 2.3348,-1.68641 2.5469,-1.98438 0.2122,-0.29796 0.1118,-0.7453 0.1379,-0.76675 0.043,-0.0352 0.3193,-0.085 0.479,-0.42844 0.8589,-1.84708 2.321,-5.64459 2.4352,-6.32945 0.1137,-0.68216 0.1638,-1.34774 0.2145,-1.74497 0.029,-0.22952 -0.1467,-0.86544 -0.1246,-0.92404 0.031,-0.0821 0.3045,-0.26528 0.3599,-0.51471 0.2663,-1.19833 0.089,-2.19129 -0.1251,-3.60893 -0.214,-1.41764 -0.9837,-4.62214 -1.6369,-5.47626 -0.6589,-0.86172 -1.2229,-1.01117 -1.7479,-1.00066 -0.2086,0.26976 0.1368,0.26309 0.1626,0.31261 0.6806,0.0508 0.934,0.36864 1.4192,0.89662 0.4852,0.52798 1.2218,3.85117 1.3584,5.30156 0.1366,1.45039 0.19,2.8602 -0.088,3.46864 -0.2781,0.60845 -0.7232,0.51703 -1.0156,0.58291 0.531,0.18589 0.6698,0.12483 0.7314,0.96929 0.059,0.81338 -0.1332,1.63969 -0.5198,2.80562 -0.3912,1.18001 -1.8452,4.34998 -2.2857,4.59877 -0.4523,0.25551 -0.7314,0.27038 -1.067,0.13944 z"
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7337-2);enable-background:new"
- sodipodi:nodetypes="cssscscsscsssccscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssscscssssssscscsscsssccscsscscssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsssssscssssscsszsszssszzcczzzczzzc" />
- <path
- inkscape:connector-curvature="0"
- id="path8183-3"
- d="m 988.75,-263.84375 c 1.91161,0.6344 4.55027,1.75841 6.125,2.8125 1.57477,1.05409 2.8961,1.48252 5.5313,3.375 2.6082,1.87314 5.0269,3.01522 7.3125,4.0625 2.4693,1.13147 5.7521,2.15474 9.5312,3.9375 -1.2072,-1.2584 -7.139,-3.36445 -9.0312,-4.1875 -1.8922,-0.82304 -4.128,-1.93049 -6.9375,-3.78125 -2.80961,-1.85075 -3.62224,-2.48154 -6.00005,-3.71875 -2.37782,-1.23719 -4.07988,-1.9492 -6.53125,-2.5 z"
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7297-4);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8185-3"
- d="m 957.5,-260.78125 c 1.91,0.6181 4.58288,1.70934 6.15625,2.75 1.57339,1.04066 2.89608,1.48252 5.53125,3.375 2.60823,1.87315 5.02692,3.01521 7.3125,4.0625 2.46931,1.13147 5.75213,2.15475 9.53125,3.9375 -1.20728,-1.2584 -7.20154,-3.3957 -9.09375,-4.21875 -1.89217,-0.82304 -4.09666,-1.9305 -6.90625,-3.78125 -2.80958,-1.85075 -3.59295,-2.43932 -5.96875,-3.65625 -2.37578,-1.21691 -4.11321,-1.93885 -6.5625,-2.46875 z"
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7301-5);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8187-7"
- d="m 926.09375,-257.375 c 1.90772,0.59745 4.55348,1.66384 6.125,2.6875 1.5715,1.02365 2.87022,1.43971 5.5,3.28125 2.60291,1.82273 5.02887,2.9722 7.3125,4 2.4672,1.11041 5.75535,2.09323 9.53125,3.84375 -1.20623,-1.2481 -7.1719,-3.31809 -9.0625,-4.125 -1.89058,-0.8069 -4.10242,-1.89104 -6.90625,-3.6875 -2.80385,-1.79644 -3.62704,-2.40251 -6,-3.59375 -2.37297,-1.19124 -4.05362,-1.90283 -6.5,-2.40625 z"
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7305-4);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8189-3"
- d="m 894.90625,-253.5625 c 1.90213,0.55355 4.58701,1.58887 6.15625,2.59375 1.56923,1.00487 2.87401,1.40864 5.5,3.21875 2.59912,1.79164 5.00034,2.87189 7.28125,3.875 2.46428,1.08374 5.75984,2.04029 9.53125,3.75 -1.2048,-1.23507 -7.17416,-3.24478 -9.0625,-4.03125 -1.88832,-0.78647 -4.0752,-1.8308 -6.875,-3.59375 -2.79977,-1.76294 -3.59919,-2.36836 -5.96875,-3.53125 -2.36957,-1.16288 -4.12325,-1.83412 -6.5625,-2.28125 z"
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7309-9);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8191-2"
- d="m 863.71875,-248.65625 c 1.88062,0.42909 4.50427,1.38038 6.0625,2.3125 1.55823,0.93211 2.85233,1.25776 5.46875,3 2.58971,1.72444 4.98067,2.70802 7.25,3.625 2.45176,0.99069 5.73959,1.87707 9.5,3.5 -1.20131,-1.20734 -7.15249,-3.06609 -9.03125,-3.78125 -1.87875,-0.71517 -4.0854,-1.68442 -6.875,-3.375 -2.78963,-1.69057 -3.58461,-2.22822 -5.9375,-3.28125 -2.35292,-1.05301 -4.02584,-1.71248 -6.4375,-2 z"
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7313-2);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8193-6"
- d="m 833.15625,-241.375 c 1.84836,0.29644 4.46945,0.97632 6,1.78125 1.53058,0.80493 2.81374,1.05573 5.375,2.53125 2.53504,1.46046 4.89068,2.32509 7.125,3.0625 2.41399,0.79668 5.65711,1.46689 9.375,2.84375 -1.18771,-1.12873 -7.08772,-2.58975 -8.9375,-3.15625 -1.84977,-0.5665 -4.00342,-1.37392 -6.75,-2.84375 -2.74657,-1.46983 -3.50136,-1.92028 -5.8125,-2.78125 -2.31115,-0.86095 -4.00471,-1.32009 -6.375,-1.4375 z"
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7317-7);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8195-5"
- d="m 802.90625,-232.3125 c 1.8222,0.21127 4.36576,0.80057 5.875,1.53125 1.50925,0.73066 2.75568,0.92998 5.28125,2.28125 2.49976,1.33746 4.83154,2.04843 7.03125,2.65625 2.37653,0.65667 5.56464,1.07288 9.21875,2.1875 -1.16735,-1.04496 -6.92888,-2.10329 -8.75,-2.5625 -1.82111,-0.45921 -3.95225,-1.12696 -6.65625,-2.4375 -2.70403,-1.31052 -3.47106,-1.7199 -5.75,-2.46875 -2.27895,-0.74883 -3.91325,-1.17931 -6.25,-1.1875 z"
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7321-5);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8197-2"
- d="m 773.1875,-222.1875 c 1.81109,0.1787 4.32059,0.66506 5.8125,1.34375 1.49194,0.67869 2.7534,0.79822 5.25,2.0625 2.47107,1.25138 4.79005,1.89614 6.96875,2.4375 2.35387,0.58488 5.49134,0.89752 9.09375,1.84375 -1.15084,-0.99116 -6.85251,-1.7833 -8.65625,-2.1875 -1.80372,-0.4042 -3.91553,-1.02116 -6.59375,-2.25 -2.67818,-1.22884 -3.40345,-1.61089 -5.65625,-2.28125 -2.25279,-0.67034 -3.89627,-1.00232 -6.21875,-0.96875 z"
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7329-8);enable-background:new" />
- <path
- inkscape:connector-curvature="0"
- id="path8199-6"
- d="m 743.5625,-211.1875 c 1.79281,0.12911 4.27313,0.54965 5.75,1.1875 1.4769,0.63785 2.7161,0.74156 5.1875,1.9375 2.44618,1.18372 4.72054,1.74666 6.875,2.21875 2.32767,0.51003 5.4196,0.68064 9,1.5625 -1.14379,-0.9706 -6.74759,-1.59065 -8.53125,-1.9375 -1.78367,-0.34684 -3.88285,-0.88756 -6.53125,-2.03125 -2.64841,-1.14368 -3.39495,-1.51631 -5.625,-2.125 -2.23008,-0.60868 -3.82594,-0.90966 -6.125,-0.8125 z"
- style="display:inline;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter7325-2);enable-background:new" />
- </g>
- </g>
- <path
- inkscape:connector-curvature="0"
- style="display:inline;opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 863.87812,475.6679 c 1.64212,-3.218 3.51781,-5.73529 4.86136,-9.84898 0.79872,-3.65789 3.31204,-2.03073 7.26047,-8.3969 1.40193,-2.2395 5.47653,0.39136 8.9651,-2.39911 1.27072,-0.80319 2.88488,-0.40431 4.48256,-0.0631 3.76539,1.31896 5.82576,3.70355 8.33376,5.80837 6.13906,5.97023 20.53414,7.94327 23.48604,6.31346 1.43405,-2.90474 7.88128,-5.40888 12.37437,-11.11168 0.74811,-1.12267 11.72936,-8.74446 14.64721,-6.56599"
- id="path8201-5"
- sodipodi:nodetypes="ccccccccc" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;opacity:1;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 888.50059,465.25071 c 7.36341,-3.23297 13.8109,-8.9084 20.70813,-13.38452 3.31057,-1.96954 6.86983,3.21601 10.796,3.59866 2.29773,-0.21813 3.7129,1.20259 5.68211,1.6415 5.15636,1.31779 2.39793,3.86488 9.97526,6.43972 6.15561,1.7204 8.9074,-6.79847 14.89975,-7.3236 4.87739,-0.50299 8.09892,-0.31603 11.61675,-0.25254 3.92696,0.13889 4.07855,-3.4976 6.06092,-5.3033 2.98056,-2.80522 7.15561,-1.84972 10.14485,-4.7409 1.01754,-1.38468 1.95458,-3.01085 2.73459,-5.10809 0.88201,-2.00034 3.04006,0.30598 4.79823,1.26269"
- id="path8203-8"
- sodipodi:nodetypes="ccccccccccc" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter9048-9);enable-background:accumulate"
- d="m 403.27922,1056.3058 56.56854,-42.4264 72.12489,14.1421 -46.66904,52.3259 -53.74012,7.0711 -28.28427,-31.1127 z"
- id="path8994-7" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 542.27183,1060.5719 c -1.40727,18.8012 -1.1449,32.751 2.08174,49.3033 3.22666,16.5523 16.40609,45.9073 20.33441,63.1837 3.92621,17.2671 2.69413,38.3097 -12.45944,51.1483 -15.31761,12.9774 -42.05128,21.5989 -67.83231,15.7337 -25.78105,-5.8652 -69.54907,-49.2234 -88.59019,-70.2283 -19.11214,-21.0833 -63.76086,-93.8506 -77.93853,-124.2758 -14.17767,-30.4251 -12.65961,-36.7186 -8.11972,-45.52972 -9.36672,-24.5205 -12.41371,-50.06681 -33.71245,-75.57664 30.32547,3.11444 43.88028,26.95633 60.12568,47.13975 -5.52989,-48.07603 -18.05471,-64.4165 -28.37395,-90.7243 29.9943,6.08165 50.57936,31.87239 63.97979,72.7125 9.55415,-3.91791 18.23776,-9.37294 30.18741,-9.0612 -11.2975,-41.6958 -17.94946,-69.91584 -36.68725,-101.06994 53.44196,5.67033 83.65702,80.63932 78.97142,87.9608 9.97797,-2.24399 19.00565,-6.53038 30.43653,-5.65167 -11.24897,-38.34702 -21.04781,-76.8679 -3.65971,-118.64819 0,0 48.28678,65.43688 54.38966,85.80578 6.10287,20.3689 1.51881,38.70051 1.51881,38.70051 0,0 16.95957,31.0853 20.29392,51.09414 3.3731,20.24138 -3.53269,59.10328 -4.94582,77.98328 z"
- id="path4189-9"
- sodipodi:nodetypes="czzzzzzcccccccccczczz" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter3587-1);enable-background:accumulate"
- d="m 719.5,738.69519 18.31177,15.43196 44.41103,-15.38821 23.2772,-25.54375 11.46397,19.22065 30.67161,12.78354 25.09737,5.72837 L 892,723.19519 908.02309,747.02126 947,752.19519 l 10.24541,-6.19852 6.75471,8.6982 25.49988,11.00032 2,-40.5 L 955.94866,710.6576 923.45591,689.1305 883.0038,677.66492 861.69668,662.13148 840,685.19519 755.02878,638.61208 722,676.69519 l -2.5,62 z"
- id="path4191-6"
- sodipodi:nodetypes="cccccccccccccccccccccc"
- clip-path="url(#clipPath3631-6)"
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,995.28646,23.53493)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;opacity:0.58775509;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3898-1);enable-background:new"
- d="m 584,696.5 -6.5625,17.15625 c 0,0 -7.81152,20.36488 -15.6875,43.65625 -3.93799,11.64568 -7.88302,24.04145 -10.9375,35.125 -3.05448,11.08355 -5.33586,20.37986 -5.5,28.28125 -0.39807,19.16196 5.74653,34.8883 8.9375,41.75 -0.77153,3.55523 -1.99137,9.45432 -3.34375,18.09375 -1.92042,12.26821 -3.71827,27.15441 -2.375,39.875 1.38209,13.08835 6.81222,28.18765 12.59375,43.03125 5.78153,14.8436 12.05435,29.22711 15.21875,38.03125 6.63206,18.4519 9.99296,31.5763 11.3125,48.5 0.58135,7.4561 -0.24227,20.336 -1.25,33.375 -1.00773,13.039 -2.18661,26.3014 -1.6875,36.9688 0.98911,21.1398 9.32798,46.8347 33.375,57.9374 22.77483,10.5154 55.32682,11.7022 83.4375,-3.4374 16.15992,-8.7034 30.07634,-27.0976 43.375,-46.9063 13.29866,-19.8087 24.96917,-41.0534 31.9375,-54.9063 15.35292,-30.5212 39.39353,-115.46418 45.625,-152.7187 3.01859,-18.04653 3.92166,-29.06555 2.625,-38.03125 -0.97853,-6.76604 -3.82819,-12.1474 -6.875,-16.21875 2.04274,-27.50791 -0.73207,-51.36878 11.96875,-79.40625 L 840.75,763.375 l -23.8125,9.3125 c -17.48975,6.83753 -28.90164,19.04536 -36.59375,32.0625 -0.32251,0.54577 -0.56314,1.10776 -0.875,1.65625 0.22203,-22.51521 4.40784,-37.63759 6.59375,-58.6875 l 1.96875,-19 L 771,737.375 c -30.59449,15.55571 -45.69489,48.19321 -49.71875,90.21875 -4.24532,-0.62547 -8.8314,-1.01965 -13.8125,-0.84375 -0.29149,-39.18036 -0.39629,-67.03685 8.59375,-99.375 l 5.59375,-20.125 -19.4375,7.65625 c -30.90937,12.20394 -47.85954,41.93073 -56.625,68.375 -4.38273,13.22214 -6.74582,25.80121 -7.59375,35.9375 -0.23203,2.77373 -0.31106,5.31132 -0.3125,7.71875 -3.24187,-0.0364 -6.42052,0.13589 -10.0625,0.5 0.0416,-39.00473 -3.48424,-79.75415 -32.28125,-116.5 L 584,696.5 Z m 5.8125,43.8125 c 16.80691,30.64383 17.47451,63.96728 16.9375,99.75 l -0.21875,15.0625 12.03493,-6.53921 c 8.66205,-3.13302 19.56058,-0.22752 31.93382,-0.83579 l 14.67465,9.3566 -6.3309,-25.7941 c -0.0897,-0.22997 -0.22046,-0.41669 -0.25,-0.71875 -0.19951,-2.03986 -0.22232,-5.47307 0.125,-9.625 0.69464,-8.30386 2.78957,-19.58524 6.625,-31.15625 5.15532,-15.55294 13.48801,-31.19248 25.125,-42.53125 -4.68381,28.63798 -3.21559,60.25934 -3.01164,95.80514 l -2.76593,13.26164 15.49632,-7.59803 c 9.0294,-2.75771 17.18897,-0.34996 29.28125,1.09375 l 13.24632,9.44423 L 741.09375,840 c 1.44793,-30.97177 8.22149,-53.67808 20.71875,-68.875 -2.98688,19.77884 -5.43043,41.7848 0.3125,78.34375 l 1.06552,6.37318 -2.93815,11.51685 10.61711,-8.16818 9.18973,10.22198 -1.54828,-10.4636 L 781.9375,852 c 5.70102,-13.21149 10.17282,-26.21337 16.34375,-36.65625 0.95986,-1.62434 2.03153,-3.06436 3.0625,-4.5625 -3.68066,21.15535 -2.42716,40.20815 -4.09375,57.78125 l -4.68014,7.80698 7.39889,0.22427 c 3.22005,3.48361 3.8675,3.85068 4.5625,8.65625 0.695,4.80557 0.31862,14.40035 -2.5625,31.625 -5.56799,33.28792 -31.84562,77.83981 -43.7404,101.4864 -6.60491,13.1304 -18.52833,57.4859 -31.12335,76.2465 -12.59502,18.7605 -28.53137,39.7673 -37.17204,44.4209 -21.49052,11.5742 -44.55594,25.5059 -60.61889,18.0895 -14.37486,-6.637 -23.03969,-21.1927 -23.81407,-37.7433 -0.38311,-8.188 0.61279,-21.3092 1.625,-34.4062 1.01221,-13.0971 11.28891,-22.5708 15.42339,-36.5626 5.37229,-18.1808 -1.44687,-36.5944 -12.5,-53.93745 -6.48655,-10.17778 -23.9768,-24.2579 -29.54839,-38.5625 -5.57159,-14.3046 -10.36751,-29.00315 -11.28125,-37.65625 -0.92621,-8.77113 0.4225,-23.02502 2.21875,-34.5 1.79625,-11.47497 3.84375,-20.28125 3.84375,-20.28125 l 9.42278,-3.6152 -10.48528,-3.8848 c 0,0 -8.49889,-15.3101 -8.09375,-34.8125 0.0711,-3.42316 1.83626,-12.72805 4.71875,-23.1875 2.88249,-10.45945 6.76466,-22.55271 10.625,-33.96875 3.04439,-9.00308 5.78063,-16.60345 8.34375,-23.6875 z"
- id="path4193-0"
- clip-path="url(#clipPath3677-0)"
- sodipodi:nodetypes="ccssscsssssssssssssccccscccccccccsscccccccccccssscccccccccccccccsccccssssssssssssscccsssc"
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,822.28931,10.93589)" />
- <g
- style="display:inline;enable-background:new"
- id="g3617-4"
- clip-path="url(#clipPath3622-5)"
- transform="translate(276,136)">
- <path
- inkscape:connector-curvature="0"
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,-52.200498,74.09707)"
- id="path4195-1"
- d="m -15.66751,843.48852 -49.49748,-15.55635 -26.87005,52.3259 41.01219,45.25484 49.49747,-38.18377 -14.14213,-43.84062 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter9024-1);enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccccccccccc"
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,-46.92842,75.511284)"
- id="path4197-0"
- d="m 118.70648,859.93048 -55.154328,-46.66904 -43.84062,36.76955 33.94113,53.74011 -13.596814,85.46203 -39.44536579,28.29217 -41.01220021,11.3137 -2.82842,46.669 56.56854,25.4559 18.943987,-69.65 23.45655,-58.85663 46.347541,-72.61491 16.62,-39.91188 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter9020-8);enable-background:accumulate" />
- </g>
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter9044-0);enable-background:accumulate"
- d="m -70.82184,932.58397 60.81118,-26.87005 100.40916,31.1127 -63.63961,31.11269 -82.02438,-16.97056 -15.55635,-18.38478 z"
- id="path4199-4"
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,229.07158,211.51128)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;opacity:0.58775509;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4105-2);enable-background:new"
- d="m 583.0625,715.75 c -12.10609,34.44974 -26.7145,68.53333 -31.75,104.84375 -0.83208,14.92867 4.58915,29.15943 8.84375,43.0625 -5.91624,27.20126 -10.13681,56.89995 1.15625,83.125 13.51717,38.16085 35.00147,75.68215 32.42279,117.46825 -0.9483,29.2942 -9.01444,60.9941 5.38971,88.2817 10.19864,19.3348 33.13956,27.3117 53.96785,27.6676 27.86219,1.1741 56.46261,-11.6216 72.0009,-35.2613 22.59549,-29.3717 41.80051,-61.4973 55.23865,-96.0598 16.89053,-45.506 29.6718,-92.56072 37.93402,-140.3989 1.8244,-12.94106 3.10108,-27.46985 -4.57892,-38.82255 -3.43115,-7.33632 0.0421,-15.56014 -0.68457,-23.30977 0.674,-24.99466 4.01232,-50.66376 16.65332,-72.59648 -17.73313,6.4446 -35.07268,16.55971 -44.00307,33.86425 -3.93508,6.70955 -7.60482,13.57413 -11.37193,20.38575 -3.54999,-30.01408 3.71963,-59.64828 6.78125,-89.28125 -20.16604,9.05463 -36.87672,25.65522 -44.17495,46.682 -6.30463,15.58003 -8.80222,32.31718 -10.26255,49.03675 -8.25334,-1.51925 -16.68447,-2.10155 -25.0625,-1.5 -0.96308,-38.69787 -0.46696,-79.40715 10.96875,-115.90625 -18.68113,6.21776 -35.16621,18.73551 -45.62803,35.38723 -13.85254,20.87979 -21.2614,45.75395 -23.05947,70.61277 0.58534,4.32454 -0.0613,11.84009 -6.34375,9.875 -5.33118,0.0176 -10.62908,0.67883 -15.9375,1.09375 1.14784,-39.38148 -3.34144,-81.6282 -27.0625,-114.21875 -3.06071,-3.63717 -5.63685,-7.68438 -8.625,-11.34375 -0.9375,2.4375 -1.875,4.875 -2.8125,7.3125 z m 7.75,13.84375 c 18.56527,29.29629 22.4825,64.82012 22.125,98.875 0.20409,5.17526 -0.51656,11.8292 0.125,16.0625 12.31856,-6.10275 26.73912,-2.4399 39.78125,-2.1875 2.31712,1.22325 3.1921,1.65243 1.90625,-1.40625 -4.16455,-13.95285 -1.84828,-28.613 1.80504,-42.40764 6.36687,-26.29064 20.62828,-51.08798 42.81996,-67.02986 -8.61709,37.23706 -5.71658,76.56161 -6.09375,113.96875 12.25344,-6.9099 27.27879,-3.44613 40.03125,-0.25 3.39222,3.5348 2.28935,-0.72948 2.1875,-3.8125 -0.48309,-21.37058 4.13133,-43.06963 13.6875,-62.15625 5.96266,-10.68727 14.24338,-19.80379 22.4375,-28.875 -7.87156,33.8381 -9.2029,69.33593 -2.71875,103.5 1.72485,-1.41118 4.60681,-0.45414 5.65625,-0.375 9.68369,-21.23682 16.35112,-45.38062 34.89016,-60.74185 1.87329,-0.37122 -1.44818,8.52495 -1.48391,11.8981 -3.53488,21.84581 -7.17516,44.14234 -8.78421,66.21911 -8.78379,2.34171 2.84835,2.32354 3.46875,4.0625 7.92311,10.5658 4.66299,24.40472 3.63165,36.35334 -7.06405,45.03355 -22.14231,87.36194 -35.95355,130.6798 -12.07476,32.9493 -27.3742,58.8525 -47.88808,87.2015 -10.95257,13.5514 -23.24472,27.8513 -40.84375,32.5 -20.15601,6.2413 -44.20676,10.8769 -62.59956,0.046 -17.28966,-12.3414 -21.02393,-35.7089 -19.26226,-55.6864 0.0488,-15.8262 4.93886,-28.5121 4.4106,-43.4918 -0.53824,-15.2629 -2.29135,-30.5647 -6.54261,-46.8663 -4.25126,-16.30162 -9.04325,-24.91794 -16.11906,-41.57338 -7.24111,-17.04456 -15.07015,-36.74863 -18.20542,-56.28842 -1.74948,-18.62714 2.89171,-37.12262 5.78125,-55.25 3.29623,-2.83696 -1.59799,-5.19659 -2.3125,-8.1875 -7.60113,-17.01508 -8.40747,-36.7749 -2.74234,-54.55998 7.1302,-25.0723 15.76087,-49.63241 24.67984,-74.12752 0.70833,1.30208 1.41667,2.60417 2.125,3.90625 z"
- id="path4201-8"
- sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccczzzcccccc"
- clip-path="url(#clipPath4177-4)"
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,822.28931,10.93589)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter4130-8);enable-background:accumulate"
- d="m 735.05635,733.03834 2.75542,21.08881 44.41103,-15.38821 4.85063,-22.38975 -3.93617,-22.05222 -22.45163,-36.59301 -8.28004,30.30494 -17.34924,45.02944 z"
- id="path4203-7"
- sodipodi:nodetypes="cccccccc"
- clip-path="url(#clipPath3631-6)"
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,995.28646,23.53493)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter4141-2);enable-background:accumulate"
- d="m 831.81321,730.29452 15.82237,14.90486 20.85473,2.89994 -1.59029,-39.92598 8.32561,-30.50842 -7.16499,-6.34106 -21.69669,20.9424 -14.55074,38.02826 z"
- id="path4205-0"
- sodipodi:nodetypes="cccccccc"
- clip-path="url(#clipPath3631-6)"
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,995.28646,23.53493)" />
- <g
- id="g8317-8"
- style="display:inline;filter:url(#filter8333-2);enable-background:new"
- clip-path="url(#clipPath8338-4)"
- transform="translate(276,136)">
- <path
- inkscape:connector-curvature="0"
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,719.28646,-112.46507)"
- clip-path="none"
- sodipodi:nodetypes="ccccc"
- id="path4209-6"
- d="m 964.00012,754.69487 18.42881,7.46479 9.07107,-36.96447 -14.87031,4.83886 -12.62957,24.66082 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- <rect
- y="757.19519"
- x="-55"
- height="177"
- width="182"
- id="rect8315-2"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- </g>
- <g
- id="g8346-4"
- style="display:inline;filter:url(#filter8354-2);enable-background:new"
- clip-path="url(#clipPath8359-0)"
- transform="translate(276,136)">
- <path
- inkscape:connector-curvature="0"
- transform="matrix(-0.9045327,0.2506626,0.2506626,0.9045327,719.28646,-112.46507)"
- clip-path="none"
- sodipodi:nodetypes="ccccccc"
- id="path4207-7"
- d="m 910.14441,746.31415 32.61295,5.17393 -0.36119,-23.87619 7.18853,-29.68221 -8.45112,-5.26365 -21.82194,26.51077 -9.16723,27.13735 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- <rect
- y="696.19519"
- x="-22"
- height="176"
- width="165"
- id="rect8344-9"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- </g>
- <path
- inkscape:connector-curvature="0"
- style="display:inline;opacity:1;fill:#ada469;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- d="m 1036.164,1071.8338 c 6.7941,18.9028 10.4937,33.2997 11.8903,51.2119 1.3966,17.9123 -3.7827,51.8008 -2.9005,70.6561 0.8818,18.8452 8.1337,40.099 27.3446,48.9689 19.4189,8.9658 49.3193,10.2113 74.1199,-3.1456 24.8006,-13.357 57.401,-70.3255 70.9742,-97.3087 13.6239,-27.0839 38.7611,-114.4974 44.6608,-149.76859 5.8998,-35.27121 2.5506,-41.30077 -4.6174,-49.05549 2.6403,-27.84015 -1.4998,-54.93543 13.1096,-87.18618 -30.249,11.8257 -37.3823,40.1607 -48.3189,65.50508 -8.0009,-50.93293 0.2092,-71.27319 3.3189,-101.21936 -29.0647,14.77791 -42.8615,47.11402 -45,92.85714 -10.9239,-1.3042 -21.3914,-4.43423 -33.5714,-0.71429 -0.264,-46.02334 -1.4635,-76.88941 8.9106,-114.20649 -53.2554,21.02686 -62.9472,106.5941 -56.0535,112.77792 -10.8828,0.535 -21.371,-1.2973 -32.8571,2.85715 0.6389,-42.57135 -0.2605,-84.90861 -30,-122.85715 0,0 -30.958,80.92234 -31.4286,103.57143 -0.4705,22.64909 9.4516,40.16588 9.4516,40.16588 0,0 -8.568,36.74051 -6.2986,58.23223 2.2959,21.74142 20.4429,59.67622 27.2655,78.65812 z"
- id="path8848-3"
- sodipodi:nodetypes="czzzzzzcccccccccczczz" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter3587-1);enable-background:accumulate"
- d="m 719.5,738.69519 18.31177,15.43196 44.41103,-15.38821 23.2772,-25.54375 11.46397,19.22065 30.67161,12.78354 25.09737,5.72837 L 892,723.19519 908.02309,747.02126 947,752.19519 l 10.24541,-6.19852 6.75471,8.6982 25.49988,11.00032 2,-40.5 L 955.94866,710.6576 923.45591,689.1305 883.0038,677.66492 861.69668,662.13148 840,685.19519 755.02878,638.61208 722,676.69519 l -2.5,62 z"
- id="path3635-9"
- sodipodi:nodetypes="cccccccccccccccccccccc"
- clip-path="url(#clipPath3631-6)"
- transform="translate(276,136)" />
- <path
- inkscape:connector-curvature="0"
- transform="translate(450.03125,73.843964)"
- style="display:inline;opacity:0.58775509;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3898-1);enable-background:new"
- d="m 584,696.5 -6.5625,17.15625 c 0,0 -7.81152,20.36488 -15.6875,43.65625 -3.93799,11.64568 -7.88302,24.04145 -10.9375,35.125 -3.05448,11.08355 -5.33586,20.37986 -5.5,28.28125 -0.39807,19.16196 5.74653,34.8883 8.9375,41.75 -0.77153,3.55523 -1.99137,9.45432 -3.34375,18.09375 -1.92042,12.26821 -3.71827,27.15441 -2.375,39.875 1.38209,13.08835 6.81222,28.18765 12.59375,43.03125 5.78153,14.8436 12.05435,29.22711 15.21875,38.03125 6.63206,18.4519 9.99296,31.5763 11.3125,48.5 0.58135,7.4561 -0.24227,20.336 -1.25,33.375 -1.00773,13.039 -2.18661,26.3014 -1.6875,36.9688 0.98911,21.1398 9.32798,46.8347 33.375,57.9374 22.77483,10.5154 55.32682,11.7022 83.4375,-3.4374 16.15992,-8.7034 30.07634,-27.0976 43.375,-46.9063 13.29866,-19.8087 24.96917,-41.0534 31.9375,-54.9063 15.35292,-30.5212 39.39353,-115.46418 45.625,-152.7187 3.01859,-18.04653 3.92166,-29.06555 2.625,-38.03125 -0.97853,-6.76604 -3.82819,-12.1474 -6.875,-16.21875 2.04274,-27.50791 -0.73207,-51.36878 11.96875,-79.40625 L 840.75,763.375 l -23.8125,9.3125 c -17.48975,6.83753 -28.90164,19.04536 -36.59375,32.0625 -0.32251,0.54577 -0.56314,1.10776 -0.875,1.65625 0.22203,-22.51521 4.40784,-37.63759 6.59375,-58.6875 l 1.96875,-19 L 771,737.375 c -30.59449,15.55571 -45.69489,48.19321 -49.71875,90.21875 -4.24532,-0.62547 -8.8314,-1.01965 -13.8125,-0.84375 -0.29149,-39.18036 -0.39629,-67.03685 8.59375,-99.375 l 5.59375,-20.125 -19.4375,7.65625 c -30.90937,12.20394 -47.85954,41.93073 -56.625,68.375 -4.38273,13.22214 -6.74582,25.80121 -7.59375,35.9375 -0.23203,2.77373 -0.31106,5.31132 -0.3125,7.71875 -3.24187,-0.0364 -6.42052,0.13589 -10.0625,0.5 0.0416,-39.00473 -3.48424,-79.75415 -32.28125,-116.5 L 584,696.5 Z m 5.8125,43.8125 c 16.80691,30.64383 17.47451,63.96728 16.9375,99.75 l -0.21875,15.0625 12.03493,-6.53921 c 8.66205,-3.13302 19.56058,-0.22752 31.93382,-0.83579 l 14.67465,9.3566 -6.3309,-25.7941 c -0.0897,-0.22997 -0.22046,-0.41669 -0.25,-0.71875 -0.19951,-2.03986 -0.22232,-5.47307 0.125,-9.625 0.69464,-8.30386 2.78957,-19.58524 6.625,-31.15625 5.15532,-15.55294 13.48801,-31.19248 25.125,-42.53125 -4.68381,28.63798 -3.21559,60.25934 -3.01164,95.80514 l -2.76593,13.26164 15.49632,-7.59803 c 9.0294,-2.75771 17.18897,-0.34996 29.28125,1.09375 l 13.24632,9.44423 L 741.09375,840 c 1.44793,-30.97177 8.22149,-53.67808 20.71875,-68.875 -2.98688,19.77884 -5.43043,41.7848 0.3125,78.34375 l 1.06552,6.37318 -2.93815,11.51685 10.61711,-8.16818 9.18973,10.22198 -1.54828,-10.4636 L 781.9375,852 c 5.70102,-13.21149 10.17282,-26.21337 16.34375,-36.65625 0.95986,-1.62434 2.03153,-3.06436 3.0625,-4.5625 -3.68066,21.15535 -2.42716,40.20815 -4.09375,57.78125 l -4.68014,7.80698 7.39889,0.22427 c 3.22005,3.48361 3.8675,3.85068 4.5625,8.65625 0.695,4.80557 0.31862,14.40035 -2.5625,31.625 -5.56799,33.28792 -31.79272,123.1659 -43.6875,146.8125 -6.60491,13.1304 -18.02998,33.8957 -30.625,52.6563 -12.59502,18.7605 -27.35933,35.5338 -36,40.1874 -21.49052,11.5742 -48.7808,10.2602 -64.84375,2.8438 -14.37486,-6.637 -20.53812,-23.4494 -21.3125,-40 -0.38311,-8.188 0.61279,-21.3092 1.625,-34.4062 1.01221,-13.0971 11.28891,-22.5708 15.42339,-36.5626 5.37229,-18.1808 -1.44687,-36.5944 -12.5,-53.93745 -6.48655,-10.17778 -23.9768,-24.2579 -29.54839,-38.5625 -5.57159,-14.3046 -10.36751,-29.00315 -11.28125,-37.65625 -0.92621,-8.77113 0.4225,-23.02502 2.21875,-34.5 1.79625,-11.47497 3.84375,-20.28125 3.84375,-20.28125 l 9.42278,-3.6152 -10.48528,-3.8848 c 0,0 -8.49889,-15.3101 -8.09375,-34.8125 0.0711,-3.42316 1.83626,-12.72805 4.71875,-23.1875 2.88249,-10.45945 6.76466,-22.55271 10.625,-33.96875 3.04439,-9.00308 5.78063,-16.60345 8.34375,-23.6875 z"
- id="path3669-2"
- clip-path="url(#clipPath3677-0)"
- sodipodi:nodetypes="ccssscsssssssssssssccccscccccccccsscccccccccccssscccccccccccccccsccccssssssssssssscccsssc" />
- <g
- id="g3628-8"
- clip-path="url(#clipPath3636-90)"
- transform="translate(276,136)">
- <path
- inkscape:connector-curvature="0"
- id="path8988-3"
- d="m 824.48651,818.48242 -49.49748,-15.55635 -26.87005,52.3259 41.01219,45.25484 49.49747,-38.18377 -14.14213,-43.84062 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter9024-1);enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- id="path8990-0"
- d="m 964.49365,855.25197 -55.15433,-46.66904 -43.84062,36.76955 33.94113,53.74011 7.07106,66.46804 -50.91168,35.35537 -41.0122,11.3137 -2.82842,46.669 56.56854,25.4559 63.63961,-76.3676 24.04163,-94.75227 8.48528,-57.98276 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter9020-8);enable-background:accumulate" />
- </g>
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter9044-0);enable-background:accumulate"
- d="m 1045.3322,1043.5779 60.8112,-26.8701 100.4091,31.1127 -63.6396,31.1127 -82.0244,-16.9706 -15.5563,-18.3847 z"
- id="path8992-1" />
- <path
- inkscape:connector-curvature="0"
- transform="translate(450.03125,73.843964)"
- style="display:inline;opacity:0.58775509;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:20.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4185-1);enable-background:new"
- d="m 583.0625,715.75 c -12.10609,34.44974 -26.7145,68.53333 -31.75,104.84375 -0.83208,14.92867 4.58915,29.15943 8.84375,43.0625 -5.91624,27.20126 -10.13681,56.89995 1.15625,83.125 13.51717,38.16085 35.00147,75.68215 32.42279,117.46825 -0.9483,29.2942 -9.01444,60.9941 5.38971,88.2817 10.19864,19.3348 33.13956,27.3117 53.96785,27.6676 27.86219,1.1741 56.46261,-11.6216 72.0009,-35.2613 22.59549,-29.3717 41.80051,-61.4973 55.23865,-96.0598 16.89053,-45.506 29.6718,-92.56072 37.93402,-140.3989 1.8244,-12.94106 3.10108,-27.46985 -4.57892,-38.82255 -3.43115,-7.33632 0.0421,-15.56014 -0.68457,-23.30977 0.674,-24.99466 4.01232,-50.66376 16.65332,-72.59648 -17.73313,6.4446 -35.07268,16.55971 -44.00307,33.86425 -3.93508,6.70955 -7.60482,13.57413 -11.37193,20.38575 -3.54999,-30.01408 3.71963,-59.64828 6.78125,-89.28125 -20.16604,9.05463 -36.87672,25.65522 -44.17495,46.682 -6.30463,15.58003 -8.80222,32.31718 -10.26255,49.03675 -8.25334,-1.51925 -16.68447,-2.10155 -25.0625,-1.5 -0.96308,-38.69787 -0.46696,-79.40715 10.96875,-115.90625 -18.68113,6.21776 -35.16621,18.73551 -45.62803,35.38723 -13.85254,20.87979 -21.2614,45.75395 -23.05947,70.61277 0.58534,4.32454 -0.0613,11.84009 -6.34375,9.875 -5.33118,0.0176 -10.62908,0.67883 -15.9375,1.09375 1.14784,-39.38148 -3.34144,-81.6282 -27.0625,-114.21875 -3.06071,-3.63717 -5.63685,-7.68438 -8.625,-11.34375 -0.9375,2.4375 -1.875,4.875 -2.8125,7.3125 z m 7.75,13.84375 c 18.56527,29.29629 22.4825,64.82012 22.125,98.875 0.20409,5.17526 -0.51656,11.8292 0.125,16.0625 12.31856,-6.10275 26.73912,-2.4399 39.78125,-2.1875 2.31712,1.22325 3.1921,1.65243 1.90625,-1.40625 -4.16455,-13.95285 -1.84828,-28.613 1.80504,-42.40764 6.36687,-26.29064 20.62828,-51.08798 42.81996,-67.02986 -8.61709,37.23706 -5.71658,76.56161 -6.09375,113.96875 12.25344,-6.9099 27.27879,-3.44613 40.03125,-0.25 3.39222,3.5348 2.28935,-0.72948 2.1875,-3.8125 -0.48309,-21.37058 4.13133,-43.06963 13.6875,-62.15625 5.96266,-10.68727 14.24338,-19.80379 22.4375,-28.875 -7.87156,33.8381 -9.2029,69.33593 -2.71875,103.5 1.72485,-1.41118 4.60681,-0.45414 5.65625,-0.375 9.68369,-21.23682 16.35112,-45.38062 34.89016,-60.74185 1.87329,-0.37122 -1.44818,8.52495 -1.48391,11.8981 -3.53488,21.84581 -3.2972,44.17323 -4.90625,66.25 -1.31238,1.37679 2.84835,2.32354 3.46875,4.0625 7.92311,10.5658 3.12294,24.83149 2.0916,36.78011 -7.06405,45.03355 -21.76553,88.37934 -35.57677,131.69714 -12.07476,32.9493 -30.7197,63.08 -51.23358,91.429 -10.95257,13.5514 -23.24472,27.8513 -40.84375,32.5 -20.15601,6.2413 -43.57595,5.1744 -61.96875,-5.6562 -17.28966,-12.3414 -21.02393,-35.7089 -19.26226,-55.6864 0.0488,-15.8262 2.37211,-27.8008 7.91747,-42.8053 5.54535,-15.0045 2.47105,-31.3317 -1.78021,-47.6333 -4.25126,-16.3016 -12.17903,-26.26002 -21.82158,-42.20417 -9.64255,-15.94415 -17.6369,-36.03734 -20.77217,-55.57713 -1.74948,-18.62714 2.89171,-37.12262 5.78125,-55.25 3.29623,-2.83696 -1.59799,-5.19659 -2.3125,-8.1875 -7.60113,-17.01508 -8.40747,-36.7749 -2.74234,-54.55998 7.1302,-25.0723 15.76087,-49.63241 24.67984,-74.12752 0.70833,1.30208 1.41667,2.60417 2.125,3.90625 z"
- id="path4149-7"
- sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccczzzcccccc"
- clip-path="url(#clipPath4177-4)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter4130-8);enable-background:accumulate"
- d="m 735.05635,733.03834 2.75542,21.08881 44.41103,-15.38821 4.85063,-22.38975 -3.93617,-22.05222 -22.45163,-36.59301 -8.28004,30.30494 -17.34924,45.02944 z"
- id="path3902-8"
- sodipodi:nodetypes="cccccccc"
- clip-path="url(#clipPath3631-6)"
- transform="translate(276,136)" />
- <path
- inkscape:connector-curvature="0"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;filter:url(#filter4141-2);enable-background:accumulate"
- d="m 831.81321,730.29452 15.82237,14.90486 20.85473,2.89994 -1.59029,-39.92598 8.32561,-30.50842 -7.16499,-6.34106 -21.69669,20.9424 -14.55074,38.02826 z"
- id="path4135-9"
- sodipodi:nodetypes="cccccccc"
- clip-path="url(#clipPath3631-6)"
- transform="translate(276,136)" />
- <g
- id="g8367-1"
- style="filter:url(#filter8379-0)"
- clip-path="url(#clipPath8392-1)"
- transform="translate(276,136)">
- <path
- inkscape:connector-curvature="0"
- clip-path="none"
- sodipodi:nodetypes="ccccccc"
- id="path4145-5"
- d="m 910.14441,746.31415 32.61295,5.17393 -0.36119,-23.87619 7.18853,-29.68221 -8.45112,-5.26365 -21.82194,26.51077 -9.16723,27.13735 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- <rect
- y="650.19098"
- x="877.51953"
- height="172.53406"
- width="123.03658"
- id="rect8365-4"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- </g>
- <g
- id="g8400-9"
- style="filter:url(#filter8404-9)"
- clip-path="url(#clipPath8417-4)"
- transform="translate(276,136)">
- <path
- inkscape:connector-curvature="0"
- clip-path="none"
- sodipodi:nodetypes="ccccc"
- id="path4147-2"
- d="m 964.00012,754.69487 18.42881,7.46479 9.07107,-36.96447 -14.87031,4.83886 -12.62957,24.66082 z"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- <rect
- y="677.06104"
- x="924.89569"
- height="125.1579"
- width="142.12846"
- id="rect8398-5"
- style="display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate" />
- </g>
- </g>
+ <g transform="matrix(.9991 .27421 -.11493 2.3838 2962.6 1209.8)" clip-path="url(#fx)">
+ <path d="M1056.2-278.8c4.145-1.479 10 3.125 10 3.125.899.28 2.725-.894 2.624-1.686 0 0-1.55-1.86-.374-2.939s5.296 1.507 7.5 1.625 5.562-.23 7-.75 1.113-1.425 2.625-1.75 5.119 1.038 7.06 1.169 4.649.334 5.815-.169.178-1.16 1.875-1.875 7.76-.957 9.625-.125 1.81.52 2.625 3 7.44 5.163-1.125 13.375-59.378 13.786-65.625 2.75 6.23-14.271 10.375-15.75z" enable-background="new" filter="url(#fw)" opacity=".75"/>
+ <path d="M1058.5-275.43c4.145-1.479 10 3.125 10 3.125.899.28 2.725-.894 2.624-1.686 0 0-1.55-1.86-.374-2.939s5.296 1.507 7.5 1.625 5.562-.23 7-.75 1.113-1.425 2.625-1.75 5.119 1.038 7.06 1.169 4.649.334 5.815-.169.178-1.16 1.875-1.875 7.76-.957 9.625-.125 1.81.52 2.625 3 7.44 5.163-1.125 13.375-59.378 13.786-65.625 2.75 6.23-14.271 10.375-15.75z" enable-background="new" filter="url(#fv)" opacity=".75"/>
</g>
- <path
- style="fill:#f8d615;fill-opacity:1;fill-rule:evenodd;stroke:#f8d615;stroke-width:17.84425545;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send)"
- d="M 544.23337,203.09259 3443.746,100.92806"
- id="path7167"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <path
- style="display:inline;fill:#f8d615;fill-opacity:1;fill-rule:evenodd;stroke:#f8d615;stroke-width:18;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Send-4);enable-background:new"
- d="M 527.91203,584.39421 3442.4188,1000.8355"
- id="path7167-9"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#f83615;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="80.219048"
- y="107.38741"
- id="text8200"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan8202"
- x="80.219048"
- y="107.38741"
- style="font-size:50px;fill:#f83615;fill-opacity:1">CROP_DEFAULT</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:45.31394196px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#f80000;fill-opacity:0;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- x="3861.3669"
- y="1281.7198"
- id="text8200-4"
- sodipodi:linespacing="125%"
- transform="scale(0.96105877,1.0405191)"><tspan
- sodipodi:role="line"
- id="tspan8202-5"
- x="3861.3669"
- y="1281.7198"
- style="font-size:56.64243317px;fill:#f80000;fill-opacity:0">COMPOSE_PADDED</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:45.31394196px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#f8d615;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- x="3615.1545"
- y="49.156631"
- id="text8200-4-9"
- sodipodi:linespacing="125%"
- transform="scale(0.96105877,1.0405191)"><tspan
- sodipodi:role="line"
- id="tspan8202-5-3"
- x="3615.1545"
- y="49.156631"
- style="font-size:50px;fill:#f8d615;fill-opacity:1">COMPOSE_ACTIVE</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:45.31394196px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#f83615;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- x="2429.1526"
- y="-3.1657715"
- id="text8200-4-5"
- sodipodi:linespacing="125%"
- transform="scale(0.96105878,1.0405191)"><tspan
- sodipodi:role="line"
- id="tspan8202-5-7"
- x="2429.1526"
- y="-3.1657715"
- style="font-size:49.99999958px;fill:#f83615;fill-opacity:1">COMPOSE_DEFAULT</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:45.31394196px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#f815bb;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- x="3681.5449"
- y="1289.9539"
- id="text8200-4-9-3"
- sodipodi:linespacing="125%"
- transform="scale(0.96105877,1.0405191)"><tspan
- sodipodi:role="line"
- id="tspan8202-5-3-6"
- x="3681.5449"
- y="1289.9539"
- style="font-size:50px;fill:#f815bb;fill-opacity:1">COMPOSE_PADDED</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:50px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new;"
- x="2438.0618"
- y="1368.4291"
- id="text8200-4-9-3-5"
- sodipodi:linespacing="125%"
- transform="scale(0.96105877,1.0405191)"><tspan
- sodipodi:role="line"
- id="tspan8202-5-3-6-3"
- x="2438.0618"
- y="1368.4291"
- style="font-size:50px;fill:#000000;fill-opacity:1;">COMPOSE_BONDS</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- x="8.0815096"
- y="1438.8961"
- id="text8200-4-9-3-5-6"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan8202-5-3-6-3-2"
- x="8.0815096"
- y="1438.8961"
- style="font-size:50px;fill:#000000;fill-opacity:1">CROP_BONDS</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- x="1455.4426"
- y="-26.808125"
- id="text8200-4-9-3-5-6-9"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan8202-5-3-6-3-2-1"
- x="1455.4426"
- y="-26.808125"
- style="font-size:50px;fill:#000000;fill-opacity:1">overscan area</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#f8d615;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- x="179.63055"
- y="385.38785"
- id="text8200-4-9-2"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan8202-5-3-7"
- x="179.63055"
- y="385.38785"
- style="font-size:50px;fill:#f8d615;fill-opacity:1">CROP_ACTIVE</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- x="636.67419"
- y="-138.84549"
- id="text8200-4-9-3-5-6-0"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan8202-5-3-6-3-2-9"
- x="636.67419"
- y="-138.84549"
- style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:70px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#000000;fill-opacity:1">DATA SOURCE</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:45.31394196px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;enable-background:new"
- x="3178.7151"
- y="-129.06131"
- id="text8200-4-9-3-5-6-0-3"
- sodipodi:linespacing="125%"
- transform="scale(0.96105877,1.0405191)"><tspan
- sodipodi:role="line"
- id="tspan8202-5-3-6-3-2-9-6"
- x="3178.7151"
- y="-129.06131"
- style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:69.99999978px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#000000;fill-opacity:1">DATA SINK</tspan></text>
- <flowRoot
- xml:space="preserve"
- id="flowRoot7469"
- style="fill:black;stroke:none;stroke-opacity:1;stroke-width:1px;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;font-family:sans-serif;font-style:normal;font-weight:normal;font-size:57.5px;line-height:125%;letter-spacing:0px;word-spacing:0px;"><flowRegion
- id="flowRegion7471"><rect
- id="rect7473"
- width="4297.5474"
- height="1851.537"
- x="-52.635666"
- y="70.623535"
- style="font-size:57.5px;" /></flowRegion><flowPara
- id="flowPara7475"></flowPara></flowRoot> </g>
+ </g>
+ <path d="M3603.7 633.68c-3.826-60.621-16.906-121.51-17.254-181.22-.187-32.048 3.291-63.757 13.834-94.91 36.554-156.68 117.6-203.23 186.99-219.47 87.416-26.435 185.96 43.047 234.7 228.91 54.432 181.72 56.997 414.01 81.07 622.74 29.605 305.05 55.09 614.78 60.735 928.25-3.08 187.6-8.474 396.35-60.847 547.4-48.299 120.83-123.49 120.1-188.13 141.58-91.07 11.17-185.4-38.742-263.27-154.04-65.144-91.037-96.274-272.3-97.832-446.36-8.437-191.66 26.542-369.07 51.914-545.07 7.513-198.58 9.466-398.92 9.708-598.39-.841-77.252-7.13-153.13-11.612-229.41z" enable-background="accumulate" fill="#101414"/>
+ <path transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" d="M311.83 415.43l9.9 121.62-60.105 136.47 15.556 174.66c15.613 61.879 32.185 98.669 74.376 117.05 4.32-36.24-38.612-142.96-39.243-189.12-.631-46.184 10.83-108.61 30.678-158.3 20.048-50.192 36.897-44.846 42.125-92.593s-17.426-149.39-17.426-149.39l-55.86 39.598z" clip-path="url(#y)" enable-background="accumulate" fill="#fff" filter="url(#fu)" opacity=".25"/>
+ <path d="m3987.6 1371.5s16.85 88.825 28.865 129.46c12.014 40.638 53.027 134.48 53.027 134.48l52.896-306.15" enable-background="accumulate" fill="url(#ft)"/>
+ <path transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" d="m730.32 536.57c0 8.485 42.548 58.468 42.548 58.468l12.607-28.77-55.154-29.698z" clip-path="url(#fs)" enable-background="accumulate" fill="#fff" filter="url(#fr)" opacity=".08"/>
+ </g>
+ <g transform="matrix(1.0057 0 0 2.3995 3424.4 -24.137)" clip-path="url(#fq)" enable-background="new">
+ <g transform="translate(-174.03 62.156)" filter="url(#aq)">
+ <g filter="url(#g)">
+ <path d="M425.88 476.99c10.805-1.479 24.744 3.354 44.643 3.214s57.453-16.91 82.143-17.143 62.752 12.284 79.286 15 22.848-.158 27.5 7.857 1.927 10.747-10.357 20.714-40.79 12.636-66.071 12.857c-25.282.221-70.381 7.079-95.357 3.93s-56.938-7.824-68.929-17.858-19.851-16.732-17.5-23.929 13.837-3.164 24.643-4.643z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+ <path d="M343.65 412.6h381.84v181.02H343.65z" enable-background="accumulate" fill="none"/>
+ </g>
+ <g filter="url(#g)">
+ <path d="m861.17 390.2c-10.462 9.714-86.98 19.005-100.71 29.286s-14.753 12.888-12.143 20 6.545 9.406 25.714 8.571 98.571-27.622 98.571-21.429l-11.429-36.429z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+ <path d="M702.86 344.82h207.89v162.63H702.86z" enable-background="accumulate" fill="none"/>
+ </g>
+ </g>
+ <g enable-background="new" opacity=".18">
+ <g transform="translate(-174.03 62.156)" filter="url(#g)">
+ <path d="M425.88 476.99c10.805-1.479 24.744 3.354 44.643 3.214s57.453-16.91 82.143-17.143 62.752 12.284 79.286 15 22.848-.158 27.5 7.857 1.927 10.747-10.357 20.714-40.79 12.636-66.071 12.857c-25.282.221-70.381 7.079-95.357 3.93s-56.938-7.824-68.929-17.858-19.851-16.732-17.5-23.929 13.837-3.164 24.643-4.643z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+ <path d="M343.65 412.6h381.84v181.02H343.65z" enable-background="accumulate" fill="none"/>
+ </g>
+ <g transform="translate(-174.03 62.156)" filter="url(#g)">
+ <path d="m861.17 390.2c-10.462 9.714-86.98 19.005-100.71 29.286s-14.753 12.888-12.143 20 6.545 9.406 25.714 8.571 98.571-27.622 98.571-21.429l-11.429-36.429z" enable-background="new" fill="#fff" fill-rule="evenodd"/>
+ <path d="M702.86 344.82h207.89v162.63H702.86z" enable-background="accumulate" fill="none"/>
+ </g>
+ </g>
+ </g>
+ <g transform="matrix(1.0057 0 0 2.3995 2971.9 -201.33)" fill-rule="evenodd">
+ <path transform="translate(276 136)" d="m582.66-7.418l113.14 86.267 108.89 258.8 38.184 207.89 120.21 91.924s-12.728-287.09-19.799-313.96-149.91-393.15-149.91-393.15l-210.72 62.225z" clip-path="url(#fp)" enable-background="accumulate" filter="url(#fo)" opacity=".75"/>
+ <path d="m964.14 239.6s8.677 10.897 24.107 11.964c15.43 1.068 49.722-39.953 70.179-52.143 20.479-12.204 47.046-26.602 63.929-20.357 16.882 6.245 22.158 26.436 27.857 48.036 5.7 21.6 6.719 61.814-2.679 92.857-9.397 31.043-50.502 73.104-65.356 103.39s-11.607 39.821-11.607 39.821" enable-background="accumulate" fill="url(#el)"/>
+ <path d="m1124.5 207.63c-15.893-0.893-49.719 12.106-66.071 24.286-16.439 12.244-29.221 24.114-29.286 52.143-0.065 28.206 13.119 39.076 29.107 46.964s33.686 7.12 51.964-11.786c18.278-18.905 14.286-111.61 14.286-111.61z" enable-background="new" fill="url(#ek)"/>
+ <ellipse transform="matrix(.94347 -.12399 .14401 1.0958 451.95 134.6)" cx="385" cy="237.01" rx="86.429" ry="73.929" clip-path="url(#fn)" enable-background="accumulate" fill="url(#ef)" filter="url(#fm)" opacity=".75"/>
+ <path transform="translate(450.03 73.844)" d="m527.61 407.45s-122.04 38.403-187.51 9.632c-65.473-28.772-74.377-124.72-74.377-124.72s73.382-80.504 129.92-83.615c55.827-3.072 90.574 20.143 114.87 65.852 24.352 45.813 17.101 132.85 17.101 132.85z" enable-background="accumulate" fill="url(#fl)" mask="url(#fk)"/>
+ <path d="m772.17 393.35s36.218-27.382 51.607-35.893c15.177-8.393 25.714-11.607 35.893-11.607l-15.536 66.964" enable-background="accumulate" fill="url(#ee)"/>
+ <circle transform="translate(449.5 74.915)" cx="409.29" cy="306.65" r="36.25" enable-background="accumulate" fill="url(#ed)"/>
+ <path transform="translate(276 136)" d="m311.83 415.43l9.9 121.62-60.105 136.47 15.556 174.66c15.613 61.879 32.185 98.669 74.376 117.05 4.32-36.24 8.682-72.368-31.243-223.12l17.678-69.296 72.125-138.59-42.426-158.39-55.86 39.598z" clip-path="url(#y)" enable-background="accumulate" fill="#fff" filter="url(#fj)" opacity=".3"/>
+ <path d="m635.21 581.13c-14.142 12.728 39.233 34.58 76.368 24.042s104.64-35.564 103.24-79.196c-1.407-43.632-76.368-128.69-76.368-128.69l-103.24 183.85z" enable-background="accumulate" filter="url(#fi)" opacity=".5"/>
+ <circle transform="translate(449.67 74.915)" cx="410" cy="306.65" r="23.214" enable-background="accumulate" fill="url(#ec)"/>
+ <circle transform="translate(452 73.487)" cx="414.29" cy="303.08" r="7.5" enable-background="accumulate" fill="#fff" filter="url(#fh)" stroke="#000" stroke-linejoin="bevel"/>
+ <path d="m789.32 478.35s7.023 19.569-1.071 35-42.323 38.988-67.5 50c-25.31 11.07-85.473 32.964-101.79 41.964-16.461 9.082-18.214 12.679-18.214 12.679s-7.147-19.064 28.75-51.786c36.172-32.972 142.03-48.05 159.82-87.857z" enable-background="accumulate" fill="url(#eb)"/>
+ </g>
+ <g enable-background="new">
+ <g transform="matrix(1.0057 0 0 2.3995 3757 -22.424)" fill-rule="evenodd">
+ <path transform="translate(-329.81)" d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 8.206-79.647 3.214-93.929s-1.236-3.38-1.946-5.093c-10.689-25.816-34.214-54.43-64.483-64.55s-65.018-4.848-84.286 5.714z" clip-path="url(#x)" fill="url(#m)"/>
+ <ellipse transform="rotate(28.068 -88.085 -332.1)" cx="183.57" cy="338.08" rx="64.716" ry="134.01" enable-background="accumulate" fill="url(#dz)"/>
+ <ellipse transform="rotate(28.068 -43.578 -333.81)" cx="183.57" cy="338.08" rx="64.716" ry="134.01" enable-background="accumulate" fill="url(#fg)"/>
+ </g>
+ <path transform="matrix(1.0057 0 0 2.3995 3425.3 -22.424)" d="M179.64 267.36c-22.41 39.703-60.616 115.78-69.286 149.64-8.647 33.775-8.772 66.417-.357 86.429 8.36 19.882 26.164 35.633 40.714 41.429-.597-14.376 14.373-43.286 72.857-72.5 58.626-29.285 78.382-27.131 103.57-47.143 25.63-20.362 8.206-79.647 3.214-93.929s-1.236-3.38-1.946-5.093c-10.689-25.816-34.214-54.43-64.483-64.55s-65.018-4.848-84.286 5.714z" clip-path="url(#x)" enable-background="new" fill="none" filter="url(#hd)" stroke="url(#l)" stroke-width="20.8"/>
+ </g>
+ <g transform="matrix(1.0057 0 0 2.3995 2971.9 -201.33)" fill-rule="evenodd">
+ <circle transform="translate(452.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" stroke="#000" stroke-linejoin="bevel"/>
+ <circle transform="translate(450.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" fill="url(#m)" filter="url(#hc)" stroke="url(#l)" stroke-width="20.8"/>
+ <circle transform="translate(450.56 72.581)" cx="310.71" cy="398.08" r="19.704" enable-background="accumulate" fill="url(#dy)"/>
+ <ellipse transform="rotate(-4.471 1823.1 -5529.2)" cx="429.57" cy="377.43" rx="72.08" ry="44.548" enable-background="accumulate" fill="url(#dx)" filter="url(#hb)"/>
+ <ellipse transform="matrix(1.4358 -.07 .07 1.4358 235.18 -63.865)" cx="437.7" cy="391.22" rx="36.612" ry="22.627" enable-background="accumulate" fill="url(#dw)" filter="url(#ha)"/>
+ <g transform="translate(450.03 73.844)" enable-background="new" filter="url(#gz)">
+ <circle cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#dv)"/>
+ <circle transform="translate(13.125 8.125)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#du)"/>
+ <circle transform="translate(32.946 7.5)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#ej)"/>
+ <circle transform="translate(24.911 -10.268)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#ei)"/>
+ <circle transform="translate(47.589 -.625)" cx="413.66" cy="401.83" r="3.214" enable-background="accumulate" stroke="url(#eh)"/>
+ </g>
+ </g>
+ <g fill="none" stroke="#000">
+ <path transform="matrix(1.0057 0 0 2.3995 2971.9 -201.33)" d="M896.2 482.93c.985 4.35 4.537 6.18 7.387 7.892 4.46 2.513 6.52 1.522 9.154-.758 1.602-1.921 10.683-4.698 15.594-7.07 4.33-1.46 8.904-5.36 13.385-8.335 3.395-1.627 5.347.355 7.829 1.01 2.944.717 4.411 2.172 6.06 3.536 2.397 1.175-.927 3.143 3.284 4.293 1.19.218 2.417.577 3.283-.505" enable-background="new"/>
+ <path transform="matrix(1.0057 0 0 2.3995 2971.9 -201.33)" d="M910.85 475.35c2.315-.032 3.178.643 5.493-.82 3.455-3.082 5.402-3.146 7.955-4.42 3.026-1.315 6.535 8.152 10.102 9.849 2.395-.822 1.289 1.794 1.452 2.651.057 2.647 2.807 3.679 4.356 5.43 3.316 2.256 7.375 6.296 11.112 5.303 6.445-2.93 10.28-1.281 16.29-7.386.703-1.182-.585-6.895 3.093-7.198 2.524.254 4.166.05 6.06.569 5.442 2.117 7.738 6.45 14.71 7.955 6.184.966 7.613 3.794 13.89 5.05M876.98 483.52c2.399-.794 6.106 4.192 8.173 7.046.593 2.68 1.154 5.486.758 12.122.785 2.417 2.68 3.03 4.798 3.283 3.117-.537 5.877-1.325 7.324-3.03 1.871-1.942 5.312 2.393 8.08 4.04 3.61 1.912 7.775 1.979 11.87 2.273 1.703-.231 2.37 4.515 3.283 8.08.384 4.379-.886 6.897-1.768 9.85-.294 2.496 2.988 3.53 6.313 4.546 3.183.74 6.545 1.661 9.092 1.767 5.142.875 8.088 2.69 12.122 4.04 2.239.817 3.26 2.243 4.545 3.536" enable-background="new"/>
+ </g>
+ <g transform="matrix(.9991 .27421 -.11493 2.3838 2962.6 1209.8)" enable-background="new" fill-rule="evenodd" mask="url(#gy)">
+ <path d="M1111.48-285.971l-3.937 1.875c-.041.01-.1.02-.125.031-.42.213-.165.1-.657.312-.486.21-1.737.585-4.093 1.47-3.332 1.25-5.805 2.15-7 3.062-1.537.021-3.72.233-5.657.719a227.677 227.677 0 0 1-6.75 1.593c-1.894.42-1.675.642-2.875.875-1.296.252-1.721-.009-5.437.782-3.49.742-8.895 1.93-10.156 2.687-1.584-.18-3.868-.322-5.844-.031-3.04.447-4.916.673-6.844.906-.655.08-1.04.2-1.343.281-.427.132-.686.26-1.375.344-1.312.16-1.763-.157-5.532.281-3.554.413-9.005 1.273-10.25 1.938-1.599-.297-3.857-.534-5.843-.344-3.06.293-4.972.484-6.907.656-1.934.173-1.688.423-2.906.532-1.316.117-1.76-.164-5.531.25-3.542.388-9.008 1.209-10.281 1.875-1.6-.295-3.887-.507-5.875-.313-3.058.3-4.941.48-6.875.656-.658.06-1.04.179-1.344.25-.428.12-.683.218-1.375.282-1.316.12-1.76-.195-5.531.218-3.556.39-9.006 1.24-10.25
+1.907-1.599-.295-3.86-.524-5.844-.313-3.056.325-4.974.526-6.906.719s-1.69.44-2.906.562c-1.315.132-1.763-.164-5.532.282-3.538.418-8.977 1.292-10.25 1.968-1.597-.28-3.86-.42-5.843-.187-3.052.358-4.945.568-6.875.781-.657.073-1.041.173-1.344.25-.427.127-.685.267-1.375.344-1.314.146-1.768-.174-5.531.312-3.55.46-8.979 1.42-10.22 2.125-1.592-.244-3.833-.381-5.812-.125-3.047.395-4.95.649-6.875.907-1.924.257-1.726.493-2.937.656-1.31.176-1.748-.105-5.5.469-3.525.538-8.924 1.699-10.188 2.437-1.588-.203-3.846-.255-5.813.094-3.026.536-4.899.861-6.812 1.187-.65.111-1.014.271-1.313.375-.42.165-.663.332-1.344.469-1.294.262-1.727-.006-5.437.813-3.499.771-8.846 2.382-10.062 3.218-1.563-.077-3.758.086-5.688.594-2.972.783-4.817 1.232-6.687 1.75s-1.667.767-2.844 1.094c-1.272.353-1.697.107-5.344 1.187-3.424 1.015-8.65 2.934-9.875 3.844-1.539.013-3.72.272-5.625.875-2.93.928-4.75 1.459-6.594
+2.063-.626.205-.991.392-1.28.53-.408.215-.654.41-1.313.626-1.255.411-1.686.189-5.281 1.437-3.39 1.178-8.595 3.214-9.782 4.157-1.524.06-3.65.395-5.53 1.062-2.898 1.028-4.7 1.676-6.532 2.313-1.832.637-1.628.848-2.781 1.25-1.247.434-1.664.2-5.22 1.562-3.338 1.28-8.486 3.483-9.687 4.469-1.507.108-3.635.499-5.5 1.219a1047.26 1047.26 0 0 1-6.437 2.469c-.617.233-.997.442-1.281.593v.031l-8 3.188-12.476 3.492 7.93 19.278c-.592 1.973 12.545-4.739 12.545-4.739.227-.144.45-.272.72-.375 1.08-.41 2.17-.215 6-1.687 3.828-1.472 5.223-2.005 5.905-2.406.68-.4 1.612-.88 2.22-1.531 1.826-.138 3.57-.494 4.937-1 2.968-1.1 4.875-1.807 6.78-2.47 1.907-.662 2.355-1.414 3.407-1.78 1.092-.38 2.195-.166 6.063-1.532 3.867-1.366 5.283-1.827 5.968-2.218.702-.4 1.701-.933 2.313-1.594 1.97-.055 3.817-.385 5.281-.875 3.002-1.005 4.926-1.622 6.844-2.25 1.538-.504 2.174-1.047 2.906-1.438.23-.134.476-.253.75-.343 1.098-.36
+2.181-.082 6.094-1.313 3.912-1.231 5.366-1.673 6.062-2.031.694-.357 1.63-.793 2.25-1.406 1.866-.023 3.636-.267 5.032-.688 3.03-.913 4.992-1.43 6.937-1.969 1.945-.538 2.426-1.264 3.5-1.562 1.114-.31 2.22.007 6.188-1.031 3.967-1.039 5.417-1.433 6.125-1.75.734-.33 1.813-.754 2.437-1.375 1.998.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101 7.062-1.5 1.588-.32 2.245-.79 3-1.094a3.4 3.4 0 0 1 .75-.25c1.134-.23 2.305.209 6.344-.5 4.04-.71 5.5-.927 6.219-1.188.716-.26 1.704-.567 2.344-1.093 1.924.239 3.748.224 5.187 0 3.127-.488 5.155-.701 7.156-.97 2.002-.267 2.49-.944 3.594-1.093 1.147-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.281-.937.737-.247 1.798-.586 2.438-1.125 2.05.335 3.973.398 5.5.218 3.142-.368 5.18-.559 7.187-.78 1.611-.179 2.265-.609 3.031-.845.241-.085.495-.155.782-.187 1.15-.128 2.301.347 6.375-.125s5.559-.61 6.28-.844c.72-.232 1.701-.473 2.345-.969 1.936.334 3.77.405
+5.219.25 3.146-.334 5.177-.518 7.187-.718 2.01-.2 2.484-.827 3.594-.938 1.15-.115 2.296.365 6.375-.062s5.589-.562 6.312-.782c.74-.223 1.796-.513 2.438-1.03 2.057.398 4.002.493 5.531.343 3.149-.308 5.176-.473 7.188-.656 1.614-.147 2.263-.56 3.03-.781.242-.081.494-.13.782-.157 1.152-.105 2.293.393 6.375 0s5.589-.53 6.312-.75c.721-.218 1.7-.447 2.344-.937 1.938.35 3.769.454 5.219.312 3.149-.308 5.176-.473 7.187-.656 2.012-.183 2.515-.838 3.625-.937 1.153-.104 2.293.384 6.375 0 4.083-.385 5.59-.501 6.313-.72.74-.222 1.796-.514 2.437-1.03 2.058.401 4.003.503 5.532.343 3.146-.328 5.177-.522 7.187-.718 1.613-.158 2.266-.632 3.031-.875.241-.088.464-.122.75-.157 1.149-.14 2.317.34 6.375-.25 4.059-.59 5.562-.777 6.282-1.03.716-.254 1.674-.559 2.312-1.095 1.92.212 3.72.152 5.156-.093 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.563-1.281 1.128-.25 2.27.116 6.25-.875s5.43-1.42
+6.125-1.781c.722-.376 1.761-.87 2.375-1.531 1.963-.012 3.793-.292 5.218-.844 2.952-1.145 4.874-1.87 6.688-2.75 1.456-.707 2.32-1.702 2.531-2 .212-.298.1-.729.125-.75.043-.035.34-.094.5-.438.86-1.847 2.323-5.627 2.438-6.312.113-.682.168-1.353.218-1.75.03-.23-.147-.88-.125-.938.031-.082.289-.25.344-.5.266-1.198.09-2.207-.125-3.625-.214-1.417-.972-4.614-1.625-5.469-.659-.861-1.225-1.01-1.75-1z" enable-background="new" fill="#bcb786"/>
+ <g clip-path="url(#gx)">
+ <path d="M1107.4-284.05c-.419.213-.156.094-.647.306-.486.21-1.724.574-4.08 1.459-3.33 1.25-5.83 2.153-7.026 3.066-1.536.021-3.72.233-5.656.719a227.709 227.709 0 0 1-6.75 1.593c-1.895.42-1.676.643-2.875.875-1.297.252-1.721-.009-5.438.782-3.49.742-8.894 1.93-10.156 2.687-1.583-.18-3.867-.322-5.843-.031-3.04.447-4.917.673-6.844.906-.655.08-1.041.201-1.344.282-.426.131-.686.26-1.375.343-1.311.16-1.762-.157-5.531.282-3.554.413-9.005 1.272-10.25 1.937-1.599-.297-3.858-.534-5.844-.344-3.059.294-4.972.484-6.906.657-1.934.172-1.689.422-2.906.53-1.317.118-1.76-.163-5.532.25-3.541.39-9.007 1.21-10.28 1.876-1.6-.295-3.888-.507-5.876-.313-3.058.3-4.94.48-6.875.657-.657.06-1.04.178-1.343.25-.428.118-.684.218-1.375.28-1.316.121-1.76-.194-5.532.22-3.556.39-9.005 1.239-10.25
+1.906-1.598-.294-3.86-.524-5.843-.313-3.056.326-4.974.526-6.907.719-1.932.192-1.69.44-2.906.562-1.315.132-1.763-.164-5.53.282-3.54.418-8.979 1.292-10.25 1.969-1.599-.282-3.86-.42-5.845-.188-3.052.358-4.945.568-6.875.781-.656.073-1.04.173-1.344.25-.426.127-.684.267-1.375.344-1.313.146-1.767-.174-5.53.313-3.55.458-8.98 1.419-10.22 2.125-1.593-.245-3.834-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.925.258-1.726.493-2.938.656-1.31.176-1.747-.104-5.5.469-3.524.538-8.923 1.699-10.188 2.437-1.587-.203-3.845-.254-5.812.094-3.026.536-4.9.862-6.813 1.187-.65.111-1.013.271-1.312.375-.42.165-.664.332-1.344.47-1.295.26-1.727-.007-5.438.812-3.498.772-8.846 2.383-10.062 3.219-1.562-.078-3.757.085-5.687.593-2.972.783-4.818 1.232-6.688 1.75s-1.666.768-2.843 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.931.928-4.75 1.459-6.594
+2.063-.627.205-.992.392-1.281.531-.408.214-.653.409-1.313.625-1.254.412-1.686.19-5.28 1.438-3.39 1.177-8.596 3.213-9.782 4.156-1.524.06-3.65.395-5.531 1.062-2.898 1.029-4.7 1.676-6.531 2.313-1.833.637-1.628.848-2.782 1.25-1.246.434-1.663.2-5.218 1.562-3.34 1.28-8.488 3.483-9.688 4.47-1.507.107-3.636.498-5.5 1.218a1044.752 1044.752 0 0 1-6.437 2.469c-.617.233-.997.442-1.282.593v1.094c.112-.222.386-.817.907-1.094.698-.37 4.813-1.993 6.812-2.718 1.657-.602 4.154-1.329 5.969-1.313.302.003.588.051.844.094 1.842.308 7.468 1.562 7.468 1.562s-6.233-1.646-7.03-1.843c-.191-.048-.536-.07-.97-.063 1.146-.87 4.762-2.393 7.344-3.437 2.839-1.148 3.117-1.252 5.063-1.657 2.008-.417 3.156-.5 3.156-.5s-.082-.6.969-1.125c.705-.351 4.887-1.892 6.906-2.562 1.952-.648 5.057-1.359 6.875-1 1.863.367 7.531 1.812 7.531 1.812s-6.287-1.87-7.094-2.093c-.193-.054-.53-.086-.968-.094 1.158-.833 4.794-2.195 7.406-3.156
+2.87-1.056 3.167-1.162 5.125-1.532 1.853-.35 2.859-.425 3.031-.437.114-.217.377-.81.906-1.063.71-.338 4.926-1.712 6.97-2.312 1.692-.497 4.24-1.037 6.093-.906.308.021.613.097.875.156 1.881.424 7.594 2.031 7.594 2.031s-6.342-2.065-7.157-2.312c-.194-.06-.557-.104-1-.125 1.17-.798 4.863-2.057 7.5-2.938 2.898-.968 3.233-1.003 5.22-1.281 2.049-.287 3.187-.313 3.187-.313s-.073-.607 1-1.062c.72-.306 4.99-1.5 7.062-2 2.003-.483 5.199-.928 7.063-.406 1.91.535 7.719 2.5 7.719 2.5s-6.423-2.424-7.25-2.72c-.198-.07-.583-.14-1.032-.187 1.188-.728 4.916-1.774 7.594-2.5 2.944-.797 3.292-.77 5.313-.906 1.913-.128 2.947-.07 3.125-.062.117-.204.391-.78.937-.97.732-.253 5.079-1.047 7.188-1.374 1.748-.271 4.4-.485 6.312-.094.318.065.605.186.875.281 1.94.69 7.844 3.094 7.844 3.094s-6.535-2.95-7.375-3.312c-.201-.087-.575-.167-1.031-.25 1.206-.633 5.03-1.396 7.75-1.906 2.99-.562 3.3-.53 5.344-.532 2.109-.002
+3.312.125 3.312.125s-.073-.63 1.031-.937c.74-.206 5.126-.834 7.25-1.063 2.053-.22 5.319-.252 7.22.47 1.947.738 7.843 3.374 7.843 3.374s-6.563-3.179-7.406-3.562c-.202-.092-.543-.187-1-.282 1.21-.602 4.984-1.248 7.718-1.656 3.005-.448 3.326-.452 5.375-.406 1.94.043 3.007.194 3.188.219.119-.194.384-.766.937-.907.743-.188 5.155-.734 7.282-.937 1.763-.169 4.42-.234 6.343.25.32.08.604.203.875.312 1.953.784 7.907 3.47 7.907 3.47s-6.592-3.254-7.438-3.657c-.202-.096-.572-.207-1.031-.313 1.214-.574 5.044-1.122 7.781-1.5 3.009-.415 3.323-.442 5.375-.375 2.118.07 3.313.25 3.313.25s-.078-.637 1.03-.906c.745-.18 5.153-.663 7.282-.844 2.059-.174 5.343-.124 7.25.657 1.955.8 7.875 3.53 7.875 3.53s-6.56-3.308-7.406-3.718c-.202-.098-.572-.203-1.031-.312 1.215-.564 5.01-1.115 7.75-1.47 3.01-.389 3.321-.397 5.375-.312 1.944.08 3.006.254 3.187.282.12-.191.383-.746.938-.875.744-.174 5.15-.65 7.28-.813
+1.767-.134 4.45-.126 6.376.375.32.083.603.201.875.313 1.954.8 7.906 3.562 7.906 3.562s-6.591-3.34-7.437-3.75c-.203-.098-.572-.203-1.032-.312 1.215-.564 5.042-1.084 7.782-1.438 3.01-.39 3.352-.429 5.406-.344 2.12.088 3.312.313 3.312.313s-.078-.65 1.032-.906c.744-.173 5.15-.624 7.28-.782 2.061-.152 5.344-.096 7.25.688 1.956.804 7.876 3.5 7.876 3.5s-6.56-3.276-7.406-3.688c-.203-.098-.572-.202-1.032-.312 1.216-.562 5.012-1.128 7.75-1.5 3.01-.41 3.323-.416 5.375-.344 1.943.068 3.008.165 3.188.188.119-.195.384-.73.937-.875.742-.197 5.131-.83 7.25-1.094 1.757-.22 4.406-.333 6.313.031.317.06.606.19.875.281 1.936.661 7.844 2.938 7.844 2.938s-6.537-2.807-7.375-3.156c-.2-.084-.577-.174-1.032-.25 1.204-.651 5.02-1.372 7.72-2 2.966-.69 3.288-.756 5.312-.875 2.088-.124 3.28-.032 3.28-.032s-.086-.632 1-1.03c.73-.269 5.048-1.339 7.126-1.813 2.008-.46 5.168-1.03 7-.625 1.878.414 13.578 3.015 13.578
+3.015s-12.328-3.022-13.141-3.265c-.195-.058-.559-.107-1-.125 1.167-.804 3.514-1.688 6.11-2.703 1.68-.659.923-.377 2.775-1.004 1.754-.594 2.486-1.01 2.63-1.113.347-.207-.355-.122-.544-.042z" enable-background="new" filter="url(#gw)"/>
+ <path d="m1082.6-275.12c1.873 0.393 4.496 1.146 6.031 1.969s2.822 1.056 5.375 2.5c2.527 1.43 4.796 2.007 6.969 2.531 2.348 0.566 5.435 0.715 8.844 1.188-1.09-0.84-6.608-1.173-8.406-1.563-1.8-0.39-3.895-1.016-6.594-2.313-2.7-1.296-3.495-1.799-5.813-2.687-2.318-0.889-4.004-1.383-6.406-1.625z" enable-background="new" filter="url(#gv)"/>
+ <path d="M1051.5-270c1.905.578 4.528 1.616 6.094 2.594 1.565.978 2.88 1.36 5.5 3.125 2.593 1.747 4.986 2.71 7.25 3.594 2.446.955 5.682 1.657 9.406 3.062-1.19-1.138-7.063-2.687-8.938-3.375-1.874-.688-4.081-1.566-6.874-3.281-2.794-1.715-3.574-2.284-5.938-3.406-2.364-1.123-4.057-1.835-6.5-2.313z" enable-background="new" filter="url(#gu)"/>
+ <path d="m1020.2-266.84c1.912 0.638 4.581 1.755 6.156 2.813 1.575 1.057 2.896 1.508 5.531 3.406 2.61 1.878 5.029 3.03 7.313 4.062 2.468 1.116 5.764 2.174 9.531 3.844-1.203-1.222-7.203-3.314-9.094-4.125-1.89-0.81-4.064-1.894-6.874-3.75s-3.622-2.477-6-3.719c-2.379-1.242-4.111-1.975-6.563-2.531z" enable-background="new" filter="url(#gt)"/>
+ <path d="M1110.2-266.89c.15.049.688.631.11 1.484-.81 1.195-5.705 3.325-8.563 4.125-2.845.798-6.29.978-10.562-.375-4.302-1.362-5.47-2.468-10.656-4.312 4.664 2.115 6.195 3.952 10.125 5.344 1.62.574 3.367.94 5.062 1.03-.445.327-1.53.984-3.562 1.595-2.796.84-6.65 1.534-8.25 1.625-1.515.086-3.142-.513-3.438-.625.167.103.374.377-.25 1.03-.899.945-6.147 1.924-9.125 2.25-2.964.326-6.521-.015-10.906-1.905-3.978-1.715-5.339-2.916-9.406-4.75v.156c3.643 2.095 5.284 3.883 8.875 5.562 1.73.81 3.592 1.41 5.406 1.72-.534.286-1.557.71-3.437 1.03-2.87.488-6.81.817-8.438.75-.85-.034-1.728-.184-2.406-.406-.685-.215-1.19-.444-1.312-.5.169.107.43.403-.22 1.031-.909.88-6.245 1.337-9.25 1.47-2.99.131-6.588-.451-11-2.563-4.44-2.127-5.64-3.402-10.905-5.782 4.734 2.597 6.286 4.63 10.344 6.72 1.673.861 3.485 1.493 5.25
+1.937-.463.233-1.59.688-3.688.937-2.886.343-6.834.493-8.468.375-1.547-.111-3.232-.857-3.532-1 .17.12.414.41-.218 1-.913.851-6.244 1.262-9.25 1.375-2.993.113-6.59-.49-11-2.594-4.002-1.908-5.388-3.137-9.47-5.093v.156c3.656 2.204 5.295 4.053 8.907 5.906 1.74.893 3.637 1.528 5.469 1.969-.54.248-1.578.615-3.469.844-2.886.348-6.866.52-8.5.406a9.446 9.446 0 0 1-2.406-.5 12.532 12.532 0 0 1-1.313-.531c.17.112.465.422-.187 1.03-.913.853-6.275 1.294-9.281 1.407-2.993.112-6.594-.528-11-2.594-4.437-2.08-5.647-3.331-10.906-5.656 4.729 2.548 6.29 4.578 10.344 6.625 1.671.844 3.485 1.467 5.25 1.906-.464.235-1.59.684-3.688.938-2.886.348-6.836.57-8.469.469-1.544-.096-3.2-.83-3.5-.97.17.12.382.405-.25 1-.912.861-6.246 1.331-9.25 1.47-2.99.138-6.567-.451-10.969-2.47-3.993-1.83-5.365-3.028-9.437-4.905v.156c3.647 2.133 5.27 3.935 8.875 5.719 1.737.86 3.607 1.45 5.437
+1.875-.54.253-1.55.64-3.437.906-2.88.404-6.838.646-8.469.562a9.36 9.36 0 0 1-2.406-.437 12.971 12.971 0 0 1-1.313-.5c.17.109.432.41-.218 1.031-.911.87-6.25 1.392-9.25 1.563-2.987.17-6.574-.316-10.97-2.282-4.424-1.978-5.605-3.228-10.843-5.375 4.71 2.388 6.27 4.39 10.312 6.344a23.73 23.73 0 0 0 5.218 1.781c-.461.25-1.597.713-3.687 1.032-2.876.438-6.78.733-8.406.687-1.539-.043-3.233-.745-3.532-.875.169.113.411.414-.218 1.031-.908.891-6.203 1.529-9.188 1.813-2.971.283-6.573-.176-10.938-1.938-3.96-1.598-5.329-2.795-9.344-4.312v.156c3.596 1.811 5.239 3.582 8.813 5.156 1.722.759 3.587 1.29 5.406 1.625-.536.28-1.566.688-3.437 1.063-2.856.572-6.79 1.02-8.407 1.031-.844.006-1.706-.08-2.375-.25-.676-.162-1.16-.33-1.28-.375.166.094.422.383-.22 1.062-.897.951-6.186 1.918-9.125 2.438-2.925.518-6.432.374-10.719-1.031-4.315-1.415-5.472-2.53-10.562-3.969 4.577 1.751 6.09 3.56 10.031 5 1.627.594 3.37.956
+5.094 1.156-.453.297-1.555.884-3.594 1.469-2.804.805-6.638 1.576-8.218 1.75-1.495.165-3.117-.317-3.407-.406.164.09.393.36-.218 1.062-.883 1.014-6.045 2.372-8.938 3.063-2.88.687-6.335.76-10.562-.438-3.835-1.086-5.172-2.072-9.062-3.125v.156c3.484 1.395 5.07 2.92 8.53 4.032 1.669.535 3.457.786 5.22.875-.52.352-1.5.914-3.313 1.53-2.765.942-6.59 1.936-8.156 2.157-.818.115-1.633.123-2.281.031-.655-.083-1.133-.218-1.25-.25.162.075.434.34-.188 1.094-.87 1.055-6.01 2.66-8.875 3.438-2.852.774-6.259.958-10.438-.094-4.206-1.06-5.356-2.042-10.344-3.156 4.485 1.46 5.97 3.135 9.813 4.25 1.585.46 3.287.638 4.969.687-.442.337-1.513 1.028-3.5 1.781-2.734 1.037-6.452 2.163-8 2.438-1.465.26-3.06-.117-3.344-.188.16.08.38.321-.219 1.063-.865 1.07-5.916 2.818-8.75 3.687-2.82.866-6.207 1.157-10.344.22-3.753-.852-5.048-1.717-8.875-2.595v.157c3.428 1.237 4.987 2.632 8.375 3.53 1.632.434 3.367.584
+5.094.563-.51.384-1.477 1.022-3.25 1.75-2.706 1.112-6.436 2.308-7.969 2.625-.8.166-1.612.219-2.25.157v1.406c.227-.145.449-.273.719-.375 1.08-.41 2.171-.216 6-1.688 3.828-1.471 5.224-2.005 5.906-2.406.68-.4 1.612-.88 2.219-1.531 1.827-.138 3.57-.493 4.937-1 2.968-1.1 4.876-1.806 6.782-2.469 1.905-.663 2.354-1.415 3.406-1.781 1.091-.38 2.195-.166 6.062-1.531 3.868-1.366 5.283-1.827 5.969-2.22.701-.4 1.7-.932 2.313-1.593 1.97-.055 3.816-.385 5.28-.875 3.002-1.005 4.927-1.622 6.845-2.25 1.538-.504 2.174-1.047 2.906-1.437.23-.135.475-.254.75-.344 1.098-.36 2.181-.082 6.094-1.313 3.912-1.23 5.366-1.673 6.062-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.636-.267 5.031-.688 3.03-.913 4.993-1.43 6.938-1.968 1.945-.54 2.426-1.265 3.5-1.563 1.114-.31 2.22.007 6.187-1.031 3.968-1.039 5.418-1.433 6.125-1.75.735-.33 1.814-.754 2.438-1.375 1.997.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101
+7.062-1.5 1.588-.32 2.244-.79 3-1.094.238-.107.467-.193.75-.25 1.134-.23 2.305.209 6.344-.5s5.5-.927 6.219-1.187c.715-.26 1.704-.568 2.343-1.094 1.925.24 3.748.224 5.188 0 3.126-.488 5.155-.7 7.156-.969 2.002-.268 2.489-.945 3.594-1.094 1.146-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.28-.937.738-.247 1.799-.586 2.438-1.125 2.05.335 3.974.398 5.5.219 3.143-.37 5.18-.56 7.188-.782 1.61-.178 2.265-.608 3.031-.843a3.43 3.43 0 0 1 .781-.188c1.15-.128 2.302.347 6.375-.125s5.56-.61 6.282-.844c.719-.232 1.7-.473 2.343-.968 1.937.333 3.77.404 5.22.25 3.145-.335 5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.593-.938 1.152-.115 2.297.366 6.375-.062s5.59-.562 6.313-.781c.74-.224 1.796-.514 2.437-1.031 2.058.398 4.002.493 5.532.343 3.148-.308 5.175-.473 7.187-.656 1.614-.147 2.263-.56 3.031-.781.242-.081.494-.13.782-.156 1.152-.106 2.293.392 6.375 0 4.082-.393 5.589-.531 6.312-.75.721-.219
+1.7-.448 2.344-.938 1.938.35 3.769.454 5.219.313 3.148-.309 5.175-.474 7.187-.657 2.012-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.589-.501 6.313-.719c.739-.222 1.795-.514 2.437-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.178-.523 7.188-.72 1.613-.156 2.266-.63 3.031-.874.24-.088.463-.122.75-.156 1.148-.14 2.317.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.313-1.093 1.92.211 3.72.151 5.156-.094 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.562-1.28 1.13-.252 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.723-.376 1.762-.87 2.375-1.531 1.963-.012 3.794-.291 5.22-.844 2.95-1.145 4.872-1.87 6.687-2.75 1.455-.707 2.334-1.686 2.547-1.984.212-.298.111-.746.137-.767.043-.035.32-.085.48-.429.858-1.847 2.32-5.644
+2.435-6.329.113-.682.163-1.348.214-1.745.03-.23-.147-.865-.125-.924.031-.082.305-.265.36-.515.267-1.198.09-2.191-.125-3.609-.214-1.417-.983-4.622-1.637-5.476-.659-.862-1.223-1.011-1.748-1-.208.27.137.262.163.312.68.05.934.369 1.42.897s1.442 3.94 1.579 5.39.19 2.86-.088 3.468c-.278.609-.944.429-1.237.495.531.186.89.213.953 1.057.058.814-.134 1.64-.52 2.806-.391 1.18-1.845 4.35-2.286 4.599-.452.255-.952.182-1.288.05z" enable-background="new" filter="url(#gs)"/>
+ <path d="m988.75-263.84c1.912 0.634 4.55 1.758 6.125 2.813 1.575 1.054 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.062 2.47 1.132 5.752 2.155 9.531 3.938-1.207-1.259-7.139-3.365-9.031-4.188s-4.128-1.93-6.938-3.781-3.622-2.482-6-3.719c-2.377-1.237-4.08-1.95-6.53-2.5z" enable-background="new" filter="url(#gr)"/>
+ <path d="M957.5-260.78c1.91.618 4.583 1.71 6.156 2.75 1.574 1.04 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.063 2.47 1.131 5.752 2.154 9.531 3.937-1.207-1.258-7.201-3.396-9.094-4.219-1.892-.823-4.096-1.93-6.906-3.781-2.81-1.85-3.593-2.44-5.969-3.656s-4.113-1.939-6.562-2.469z" enable-background="new" filter="url(#gq)"/>
+ <path d="M926.09-257.38c1.908.597 4.553 1.664 6.125 2.688 1.571 1.023 2.87 1.44 5.5 3.28 2.603 1.823 5.029 2.973 7.313 4 2.467 1.111 5.755 2.094 9.53 3.845-1.205-1.249-7.171-3.319-9.062-4.125s-4.102-1.891-6.906-3.688c-2.804-1.796-3.627-2.402-6-3.594-2.373-1.191-4.054-1.903-6.5-2.406z" enable-background="new" filter="url(#gp)"/>
+ <path d="M894.91-253.56c1.902.554 4.587 1.589 6.156 2.594s2.874 1.408 5.5 3.219c2.6 1.791 5 2.871 7.281 3.875 2.465 1.083 5.76 2.04 9.532 3.75-1.205-1.236-7.175-3.245-9.063-4.032-1.888-.786-4.075-1.83-6.875-3.593s-3.6-2.369-5.969-3.532c-2.37-1.163-4.123-1.834-6.562-2.28z" enable-background="new" filter="url(#go)"/>
+ <path d="M863.72-248.66c1.88.43 4.504 1.38 6.063 2.313 1.558.932 2.852 1.257 5.468 3 2.59 1.724 4.981 2.708 7.25 3.625 2.452.99 5.74 1.877 9.5 3.5-1.201-1.208-7.152-3.067-9.03-3.782-1.88-.715-4.086-1.684-6.876-3.375s-3.585-2.228-5.937-3.28-4.026-1.713-6.438-2z" enable-background="new" filter="url(#gn)"/>
+ <path d="m833.16-241.38c1.848 0.296 4.47 0.976 6 1.781s2.814 1.056 5.375 2.531c2.535 1.46 4.89 2.326 7.125 3.063 2.414 0.797 5.657 1.467 9.375 2.844-1.188-1.129-7.088-2.59-8.938-3.156-1.85-0.567-4.003-1.374-6.75-2.844-2.746-1.47-3.5-1.92-5.812-2.781-2.311-0.861-4.005-1.32-6.375-1.438z" enable-background="new" filter="url(#gm)"/>
+ <path d="m802.91-232.31c1.822 0.211 4.366 0.8 5.875 1.531 1.51 0.73 2.756 0.93 5.281 2.281 2.5 1.338 4.832 2.049 7.031 2.657 2.377 0.656 5.565 1.073 9.22 2.187-1.168-1.045-6.93-2.103-8.75-2.562-1.822-0.46-3.953-1.127-6.657-2.438s-3.471-1.72-5.75-2.469-3.913-1.179-6.25-1.187z" enable-background="new" filter="url(#gl)"/>
+ <path d="M773.19-222.19c1.811.179 4.32.665 5.813 1.344 1.491.678 2.753.798 5.25 2.062 2.47 1.252 4.79 1.896 6.968 2.438 2.354.585 5.492.897 9.094 1.844-1.15-.992-6.852-1.784-8.656-2.188s-3.916-1.021-6.594-2.25c-2.678-1.229-3.403-1.61-5.656-2.281-2.253-.67-3.896-1.002-6.219-.969z" enable-background="new" filter="url(#gk)"/>
+ <path d="M743.56-211.19c1.793.13 4.273.55 5.75 1.188s2.716.741 5.188 1.937c2.446 1.184 4.72 1.747 6.874 2.219 2.328.51 5.42.68 9 1.562-1.143-.97-6.747-1.59-8.53-1.937-1.784-.347-3.884-.888-6.532-2.031-2.648-1.144-3.395-1.517-5.625-2.125-2.23-.61-3.826-.91-6.125-.813z" enable-background="new" filter="url(#gj)"/>
+ <g fill="#fff" filter="url(#gi)">
+ <path d="M744.94-212.12s7.222-3.223 9.063-3.5 3.352-.003 6 .563c2.647.565 8.735 2.215 11.188 3.374s5.312 3.563 5.312 3.563-7.146-2.78-10.188-3.563-7.645-2.083-10.375-2.312-11 1.875-11 1.875z"/>
+ <path d="m735.47-206.95s3.66-2.223 5.5-2.5 3.665 0.247 6.313 0.813 8.735 2.215 11.188 3.375 6.562 2.125 6.562 2.125-8.396-1.343-11.438-2.125-7.957-2.334-10.688-2.563-7.438 0.875-7.438 0.875zm24.38-10.66s8.544-3.299 10.398-3.458c1.854-0.16 3.642 0.48 6.248 1.212s8.577 2.766 10.95 4.08 6.414 2.537 6.414 2.537-8.294-1.873-11.279-2.848c-2.985-0.974-7.792-2.834-10.503-3.236s-12.228 1.713-12.228 1.713zm15.35-5.62s7.771-2.782 9.628-2.904c1.857-0.12 3.631 0.555 6.222 1.341 2.59 0.787 8.519 2.942 10.864 4.304 2.346 1.362 6.36 2.67 6.36 2.67s-8.253-2.045-11.217-3.08c-2.965-1.035-7.733-2.995-10.434-3.452-2.702-0.458-11.422 1.121-11.422 1.121zm14.44-4.72s8.683-3.52 10.542-3.605 3.62 0.624 6.195 1.46c2.575 0.837 8.46 3.107 10.779 4.514 2.318 1.408 6.307 2.793 6.307 2.793s-8.212-2.204-11.156-3.297-7.673-3.144-10.365-3.654-12.3 1.789-12.3 1.789zm14.86-5.38s7.808-2.583 9.666-2.668c1.86-0.085 3.62
+0.625 6.195 1.461 2.575 0.837 8.46 3.107 10.78 4.514 2.318 1.407 6.307 2.792 6.307 2.792s-8.213-2.204-11.156-3.296-7.673-3.144-10.365-3.654-11.426 0.85-11.426 0.85zm15.06-4.25s8.558-2.583 10.417-2.668 3.62 0.625 6.195 1.461c2.575 0.837 8.46 3.107 10.779 4.514 2.318 1.407 6.307 2.792 6.307 2.792s-8.212-2.204-11.156-3.296-7.673-3.144-10.365-3.654-12.176 0.85-12.176 0.85zm16.67-5.02s6.967-1.987 8.828-1.968c1.86 0.02 3.579 0.827 6.102 1.807 2.524 0.98 8.272 3.578 10.508 5.113 2.236 1.536 6.14 3.143 6.14 3.143s-8.075-2.662-10.952-3.919c-2.878-1.256-7.484-3.57-10.143-4.231-2.66-0.66-10.482 0.055-10.482 0.055zm14.5-3.4s7.688-2.028 9.548-1.968 3.56 0.902 6.063 1.936c2.502 1.033 8.194 3.752 10.397 5.335 2.203 1.582 6.072 3.272 6.072 3.272s-8.017-2.833-10.868-4.15c-2.85-1.318-7.407-3.73-10.05-4.446s-11.162 0.021-11.162 0.021zm14.09-3.21s8.17-1.97 10.027-1.854c1.857 0.115 3.532 1.01 6.002
+2.118s8.077 3.997 10.23 5.645 5.972 3.454 5.972 3.454-7.928-3.074-10.738-4.476-7.291-3.95-9.913-4.746c-2.621-0.796-11.58-0.141-11.58-0.141zm16.56-2.39s8.085-1.908 9.938-1.737c1.853 0.172 3.5 1.117 5.935 2.3 2.436 1.182 7.952 4.24 10.055 5.953s5.864 3.633 5.864 3.633-7.832-3.312-10.597-4.8-7.168-4.169-9.764-5.044c-2.597-0.876-11.431-0.305-11.431-0.305zm15.2-2.75s7.642-1.428 9.495-1.265c1.854 0.162 3.505 1.1 5.946 2.27s7.973 4.203 10.084 5.905c2.112 1.703 5.881 3.605 5.881 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-10.998-0.77-10.998-0.77zm14.87-1.64s8.642-1.553 10.495-1.39c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.846-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.863-11.998-0.644-11.998-0.644zm16.25-2.31s7.642-0.865 9.495-0.703c1.854 0.163 3.505 1.1 5.946 2.27s7.973 4.203 10.084
+5.906c2.112 1.702 5.881 3.605 5.881 3.605s-7.847-3.275-10.62-4.749c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.862-10.998-1.331-10.998-1.331zm15.13-1.19s8.58-1.49 10.433-1.328c1.854 0.163 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.906c2.111 1.702 5.88 3.605 5.88 3.605s-7.846-3.275-10.62-4.749c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.862-11.935-0.706-11.935-0.706zm16.25-2.06s7.83-0.803 9.683-0.64c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.846-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.787-4.998-2.601-0.863-11.185-1.394-11.185-1.394zm15.37-1.25s8.392-1.178 10.245-1.015c1.854 0.162 3.505 1.1 5.946 2.27s7.972 4.203 10.084 5.905c2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-11.748-1.02-11.748-1.02zm16.19-2.06s6.892-0.99 8.745-0.828c1.854 0.163 3.505 1.1 5.946 2.27s7.973 4.203
+10.084 5.906c2.112 1.702 5.881 3.605 5.881 3.605s-7.847-3.275-10.62-4.749-7.188-4.135-9.788-4.998c-2.6-0.862-10.248-1.206-10.248-1.206zm17.16-0.94s6.83-1.178 8.683-1.015c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-10.185-1.02-10.185-1.02zm16.1-2s6.08-0.428 7.933-0.265c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-9.435-1.77-9.435-1.77zm15.8-1.37s6.454-0.678 8.308-0.515c1.854 0.162 3.505 1.1 5.946 2.27 2.44 1.171 7.972 4.203 10.084 5.905 2.111 1.703 5.88 3.605 5.88 3.605s-7.847-3.274-10.62-4.748c-2.772-1.474-7.187-4.135-9.788-4.998-2.6-0.863-9.81-1.52-9.81-1.52zm15.6-1.86s5.498-0.91 7.358-0.853c1.86 0.056 3.562 0.896 6.066 1.925
+2.504 1.03 8.2 3.739 10.406 5.318 2.205 1.578 6.078 3.261 6.078 3.261s-8.022-2.819-10.875-4.131c-2.853-1.313-7.413-3.716-10.06-4.429-2.645-0.712-8.973-1.091-8.973-1.091zm17.4-2.46s4.547-1.156 6.408-1.186c1.86-0.03 3.6 0.73 6.149 1.642 2.55 0.912 8.365 3.354 10.64 4.829 2.277 1.474 6.224 2.976 6.224 2.976s-8.145-2.444-11.055-3.623c-2.91-1.178-7.578-3.368-10.253-3.957-2.676-0.588-8.113-0.68-8.113-0.68zm14.5-3.03s5.96-1.774 7.82-1.83c1.86-0.057 3.61 0.68 6.172 1.555 2.562 0.876 2.522 0.857 5.333 1.49 2.797 0.63 7.077 1.513 7.077 1.513s-3.616-0.016-6.792-0.466c-3.116-0.441-7.375-1.698-10.058-2.249-2.684-0.55-9.552-0.013-9.552-0.013z" enable-background="new"/>
+ <path d="M1099.2-279.93c.161.269 11.208-4.6 12.188-4.688.98-.087 2 3.125 2 3.125s-.775-1.504-2.875-1.062-11.301 2.671-11.312 2.625z"/>
+ </g>
+ <path d="M1107.5-284.09c-.419.213-.156.094-.647.306-.486.21-1.724.574-4.08 1.459-3.33 1.25-5.83 2.153-7.026 3.066-1.536.021-3.72.233-5.656.719a227.709 227.709 0 0 1-6.75 1.593c-1.895.42-1.676.643-2.875.875-1.297.252-1.721-.009-5.438.782-3.49.742-8.894 1.93-10.156 2.687-1.583-.18-3.867-.322-5.843-.031-3.04.447-4.917.673-6.844.906-.655.08-1.041.201-1.344.282-.426.131-.686.26-1.375.343-1.311.16-1.762-.157-5.531.282-3.554.413-9.005 1.272-10.25 1.937-1.599-.297-3.858-.534-5.844-.344-3.059.294-4.972.484-6.906.657-1.934.172-1.689.422-2.906.53-1.317.118-1.76-.163-5.532.25-3.541.39-9.007 1.21-10.28 1.876-1.6-.295-3.888-.507-5.876-.313-3.058.3-4.94.48-6.875.657-.657.06-1.04.178-1.343.25-.428.118-.684.218-1.375.28-1.316.121-1.76-.194-5.532.22-3.556.39-9.005 1.239-10.25
+1.906-1.598-.294-3.86-.524-5.843-.313-3.056.326-4.974.526-6.907.719-1.932.192-1.69.44-2.906.562-1.315.132-1.763-.164-5.53.282-3.54.418-8.979 1.292-10.25 1.969-1.599-.282-3.86-.42-5.845-.188-3.052.358-4.945.568-6.875.781-.656.073-1.04.173-1.344.25-.426.127-.684.267-1.375.344-1.313.146-1.767-.174-5.53.313-3.55.458-8.98 1.419-10.22 2.125-1.593-.245-3.834-.382-5.812-.125-3.048.394-4.95.648-6.875.906-1.925.258-1.726.493-2.938.656-1.31.176-1.747-.104-5.5.469-3.524.538-8.923 1.699-10.188 2.437-1.587-.203-3.845-.254-5.812.094-3.026.536-4.9.862-6.813 1.187-.65.111-1.013.271-1.312.375-.42.165-.664.332-1.344.47-1.295.26-1.727-.007-5.438.812-3.498.772-8.846 2.383-10.062 3.219-1.562-.078-3.757.085-5.687.593-2.972.783-4.818 1.232-6.688 1.75s-1.666.768-2.843 1.094c-1.273.353-1.697.107-5.344 1.188-3.425 1.014-8.65 2.933-9.875 3.843-1.539.013-3.72.273-5.625.875-2.931.928-4.75 1.459-6.594
+2.063-.627.205-.992.392-1.281.531-.408.214-.653.409-1.313.625-1.254.412-1.686.19-5.28 1.438-3.39 1.177-8.596 3.213-9.782 4.156-1.524.06-3.65.395-5.531 1.062-2.898 1.029-4.7 1.676-6.531 2.313-1.833.637-1.628.848-2.782 1.25-1.246.434-1.663.2-5.218 1.562-3.34 1.28-8.488 3.483-9.688 4.47-1.507.107-3.636.498-5.5 1.218a1044.752 1044.752 0 0 1-6.437 2.469c-.617.233-.997.442-1.282.593v1.094c.112-.222.386-.817.907-1.094.698-.37 4.813-1.993 6.812-2.718 1.657-.602 4.154-1.329 5.969-1.313.302.003.588.051.844.094 1.842.308 7.468 1.562 7.468 1.562s-6.233-1.646-7.03-1.843c-.191-.048-.536-.07-.97-.063 1.146-.87 4.762-2.393 7.344-3.437 2.839-1.148 3.117-1.252 5.063-1.657 2.008-.417 3.156-.5 3.156-.5s-.082-.6.969-1.125c.705-.351 4.887-1.892 6.906-2.562 1.952-.648 5.057-1.359 6.875-1 1.863.367 7.531 1.812 7.531 1.812s-6.287-1.87-7.094-2.093c-.193-.054-.53-.086-.968-.094 1.158-.833 4.794-2.195 7.406-3.156
+2.87-1.056 3.167-1.162 5.125-1.532 1.853-.35 2.859-.425 3.031-.437.114-.217.377-.81.906-1.063.71-.338 4.926-1.712 6.97-2.312 1.692-.497 4.24-1.037 6.093-.906.308.021.613.097.875.156 1.881.424 7.594 2.031 7.594 2.031s-6.342-2.065-7.157-2.312c-.194-.06-.557-.104-1-.125 1.17-.798 4.863-2.057 7.5-2.938 2.898-.968 3.233-1.003 5.22-1.281 2.049-.287 3.187-.313 3.187-.313s-.073-.607 1-1.062c.72-.306 4.99-1.5 7.062-2 2.003-.483 5.199-.928 7.063-.406 1.91.535 7.719 2.5 7.719 2.5s-6.423-2.424-7.25-2.72c-.198-.07-.583-.14-1.032-.187 1.188-.728 4.916-1.774 7.594-2.5 2.944-.797 3.292-.77 5.313-.906 1.913-.128 2.947-.07 3.125-.062.117-.204.391-.78.937-.97.732-.253 5.079-1.047 7.188-1.374 1.748-.271 4.4-.485 6.312-.094.318.065.605.186.875.281 1.94.69 7.844 3.094 7.844 3.094s-6.535-2.95-7.375-3.312c-.201-.087-.575-.167-1.031-.25 1.206-.633 5.03-1.396 7.75-1.906 2.99-.562 3.3-.53 5.344-.532 2.109-.002
+3.312.125 3.312.125s-.073-.63 1.031-.937c.74-.206 5.126-.834 7.25-1.063 2.053-.22 5.319-.252 7.22.47 1.947.738 7.843 3.374 7.843 3.374s-6.563-3.179-7.406-3.562c-.202-.092-.543-.187-1-.282 1.21-.602 4.984-1.248 7.718-1.656 3.005-.448 3.326-.452 5.375-.406 1.94.043 3.007.194 3.188.219.119-.194.384-.766.937-.907.743-.188 5.155-.734 7.282-.937 1.763-.169 4.42-.234 6.343.25.32.08.604.203.875.312 1.953.784 7.907 3.47 7.907 3.47s-6.592-3.254-7.438-3.657c-.202-.096-.572-.207-1.031-.313 1.214-.574 5.044-1.122 7.781-1.5 3.009-.415 3.323-.442 5.375-.375 2.118.07 3.313.25 3.313.25s-.078-.637 1.03-.906c.745-.18 5.153-.663 7.282-.844 2.059-.174 5.343-.124 7.25.657 1.955.8 7.875 3.53 7.875 3.53s-6.56-3.308-7.406-3.718c-.202-.098-.572-.203-1.031-.312 1.215-.564 5.01-1.115 7.75-1.47 3.01-.389 3.321-.397 5.375-.312 1.944.08 3.006.254 3.187.282.12-.191.383-.746.938-.875.744-.174 5.15-.65 7.28-.813
+1.767-.134 4.45-.126 6.376.375.32.083.603.201.875.313 1.954.8 7.906 3.562 7.906 3.562s-6.591-3.34-7.437-3.75c-.203-.098-.572-.203-1.032-.312 1.215-.564 5.042-1.084 7.782-1.438 3.01-.39 3.352-.429 5.406-.344 2.12.088 3.312.313 3.312.313s-.078-.65 1.032-.906c.744-.173 5.15-.624 7.28-.782 2.061-.152 5.344-.096 7.25.688 1.956.804 7.876 3.5 7.876 3.5s-6.56-3.276-7.406-3.688c-.203-.098-.572-.202-1.032-.312 1.216-.562 5.012-1.128 7.75-1.5 3.01-.41 3.323-.416 5.375-.344 1.943.068 3.008.165 3.188.188.119-.195.384-.73.937-.875.742-.197 5.131-.83 7.25-1.094 1.757-.22 4.406-.333 6.313.031.317.06.606.19.875.281 1.936.661 7.844 2.938 7.844 2.938s-6.537-2.807-7.375-3.156c-.2-.084-.577-.174-1.032-.25 1.204-.651 5.02-1.372 7.72-2 2.966-.69 3.288-.756 5.312-.875 2.088-.124 3.28-.032 3.28-.032s-.086-.632 1-1.03c.73-.269 5.048-1.339 7.126-1.813 2.008-.46 5.168-1.03 7-.625 1.878.414 13.578 3.015 13.578
+3.015s-12.328-3.022-13.141-3.265c-.195-.058-.559-.107-1-.125 1.167-.804 3.514-1.688 6.11-2.703 1.68-.659.923-.377 2.775-1.004 1.754-.594 2.486-1.01 2.63-1.113.347-.207-.355-.122-.544-.042z" enable-background="new" filter="url(#gh)" opacity=".25"/>
+ <path d="m1082.6-275.12c1.873 0.393 4.496 1.146 6.031 1.969s2.822 1.056 5.375 2.5c2.527 1.43 4.796 2.007 6.969 2.531 2.348 0.566 5.435 0.715 8.844 1.188-1.09-0.84-6.608-1.173-8.406-1.563-1.8-0.39-3.895-1.016-6.594-2.313-2.7-1.296-3.495-1.799-5.813-2.687-2.318-0.889-4.004-1.383-6.406-1.625z" enable-background="new" filter="url(#gg)" opacity=".25"/>
+ <path d="M1051.5-270c1.905.578 4.528 1.616 6.094 2.594 1.565.978 2.88 1.36 5.5 3.125 2.593 1.747 4.986 2.71 7.25 3.594 2.446.955 5.682 1.657 9.406 3.062-1.19-1.138-7.063-2.687-8.938-3.375-1.874-.688-4.081-1.566-6.874-3.281-2.794-1.715-3.574-2.284-5.938-3.406-2.364-1.123-4.057-1.835-6.5-2.313z" enable-background="new" filter="url(#gf)" opacity=".25"/>
+ <path d="m1020.2-266.84c1.912 0.638 4.581 1.755 6.156 2.813 1.575 1.057 2.896 1.508 5.531 3.406 2.61 1.878 5.029 3.03 7.313 4.062 2.468 1.116 5.764 2.174 9.531 3.844-1.203-1.222-7.203-3.314-9.094-4.125-1.89-0.81-4.064-1.894-6.874-3.75s-3.622-2.477-6-3.719c-2.379-1.242-4.111-1.975-6.563-2.531z" enable-background="new" filter="url(#ge)" opacity=".25"/>
+ <path d="M1110.2-266.89c.15.049.688.631.11 1.484-.81 1.195-5.705 3.325-8.563 4.125-2.845.798-6.29.978-10.562-.375-4.302-1.362-5.47-2.468-10.656-4.312 4.664 2.115 6.195 3.952 10.125 5.344 1.62.574 3.367.94 5.062 1.03-.445.327-1.53.984-3.562 1.595-2.796.84-6.65 1.534-8.25 1.625-1.515.086-3.142-.513-3.438-.625.167.103.374.377-.25 1.03-.899.945-6.147 1.924-9.125 2.25-2.964.326-6.521-.015-10.906-1.905-3.978-1.715-5.339-2.916-9.406-4.75v.156c3.643 2.095 5.284 3.883 8.875 5.562 1.73.81 3.592 1.41 5.406 1.72-.534.286-1.557.71-3.437 1.03-2.87.488-6.81.817-8.438.75-.85-.034-1.728-.184-2.406-.406-.685-.215-1.19-.444-1.312-.5.169.107.43.403-.22 1.031-.909.88-6.245 1.337-9.25 1.47-2.99.131-6.588-.451-11-2.563-4.44-2.127-5.64-3.402-10.905-5.782 4.734 2.597 6.286 4.63 10.344 6.72 1.673.861 3.485 1.493 5.25
+1.937-.463.233-1.59.688-3.688.937-2.886.343-6.834.493-8.468.375-1.547-.111-3.232-.857-3.532-1 .17.12.414.41-.218 1-.913.851-6.244 1.262-9.25 1.375-2.993.113-6.59-.49-11-2.594-4.002-1.908-5.388-3.137-9.47-5.093v.156c3.656 2.204 5.295 4.053 8.907 5.906 1.74.893 3.637 1.528 5.469 1.969-.54.248-1.578.615-3.469.844-2.886.348-6.866.52-8.5.406a9.446 9.446 0 0 1-2.406-.5 12.532 12.532 0 0 1-1.313-.531c.17.112.465.422-.187 1.03-.913.853-6.275 1.294-9.281 1.407-2.993.112-6.594-.528-11-2.594-4.437-2.08-5.647-3.331-10.906-5.656 4.729 2.548 6.29 4.578 10.344 6.625 1.671.844 3.485 1.467 5.25 1.906-.464.235-1.59.684-3.688.938-2.886.348-6.836.57-8.469.469-1.544-.096-3.2-.83-3.5-.97.17.12.382.405-.25 1-.912.861-6.246 1.331-9.25 1.47-2.99.138-6.567-.451-10.969-2.47-3.993-1.83-5.365-3.028-9.437-4.905v.156c3.647 2.133 5.27 3.935 8.875 5.719 1.737.86 3.607 1.45 5.437
+1.875-.54.253-1.55.64-3.437.906-2.88.404-6.838.646-8.469.562a9.36 9.36 0 0 1-2.406-.437 12.971 12.971 0 0 1-1.313-.5c.17.109.432.41-.218 1.031-.911.87-6.25 1.392-9.25 1.563-2.987.17-6.574-.316-10.97-2.282-4.424-1.978-5.605-3.228-10.843-5.375 4.71 2.388 6.27 4.39 10.312 6.344a23.73 23.73 0 0 0 5.218 1.781c-.461.25-1.597.713-3.687 1.032-2.876.438-6.78.733-8.406.687-1.539-.043-3.233-.745-3.532-.875.169.113.411.414-.218 1.031-.908.891-6.203 1.529-9.188 1.813-2.971.283-6.573-.176-10.938-1.938-3.96-1.598-5.329-2.795-9.344-4.312v.156c3.596 1.811 5.239 3.582 8.813 5.156 1.722.759 3.587 1.29 5.406 1.625-.536.28-1.566.688-3.437 1.063-2.856.572-6.79 1.02-8.407 1.031-.844.006-1.706-.08-2.375-.25-.676-.162-1.16-.33-1.28-.375.166.094.422.383-.22 1.062-.897.951-6.186 1.918-9.125 2.438-2.925.518-6.432.374-10.719-1.031-4.315-1.415-5.472-2.53-10.562-3.969 4.577 1.751 6.09 3.56 10.031 5 1.627.594 3.37.956
+5.094 1.156-.453.297-1.555.884-3.594 1.469-2.804.805-6.638 1.576-8.218 1.75-1.495.165-3.117-.317-3.407-.406.164.09.393.36-.218 1.062-.883 1.014-6.045 2.372-8.938 3.063-2.88.687-6.335.76-10.562-.438-3.835-1.086-5.172-2.072-9.062-3.125v.156c3.484 1.395 5.07 2.92 8.53 4.032 1.669.535 3.457.786 5.22.875-.52.352-1.5.914-3.313 1.53-2.765.942-6.59 1.936-8.156 2.157-.818.115-1.633.123-2.281.031-.655-.083-1.133-.218-1.25-.25.162.075.434.34-.188 1.094-.87 1.055-6.01 2.66-8.875 3.438-2.852.774-6.259.958-10.438-.094-4.206-1.06-5.356-2.042-10.344-3.156 4.485 1.46 5.97 3.135 9.813 4.25 1.585.46 3.287.638 4.969.687-.442.337-1.513 1.028-3.5 1.781-2.734 1.037-6.452 2.163-8 2.438-1.465.26-3.06-.117-3.344-.188.16.08.38.321-.219 1.063-.865 1.07-5.916 2.818-8.75 3.687-2.82.866-6.207 1.157-10.344.22-3.753-.852-5.048-1.717-8.875-2.595v.157c3.428 1.237 4.987 2.632 8.375 3.53 1.632.434 3.367.584
+5.094.563-.51.384-1.477 1.022-3.25 1.75-2.706 1.112-6.436 2.308-7.969 2.625-.8.166-1.612.219-2.25.157v1.406c.227-.145.449-.273.719-.375 1.08-.41 2.171-.216 6-1.688 3.828-1.471 5.224-2.005 5.906-2.406.68-.4 1.612-.88 2.219-1.531 1.827-.138 3.57-.493 4.937-1 2.968-1.1 4.876-1.806 6.782-2.469 1.905-.663 2.354-1.415 3.406-1.781 1.091-.38 2.195-.166 6.062-1.531 3.868-1.366 5.283-1.827 5.969-2.22.701-.4 1.7-.932 2.313-1.593 1.97-.055 3.816-.385 5.28-.875 3.002-1.005 4.927-1.622 6.845-2.25 1.538-.504 2.174-1.047 2.906-1.437.23-.135.475-.254.75-.344 1.098-.36 2.181-.082 6.094-1.313 3.912-1.23 5.366-1.673 6.062-2.03.694-.358 1.63-.794 2.25-1.407 1.865-.023 3.636-.267 5.031-.688 3.03-.913 4.993-1.43 6.938-1.968 1.945-.54 2.426-1.265 3.5-1.563 1.114-.31 2.22.007 6.187-1.031 3.968-1.039 5.418-1.433 6.125-1.75.735-.33 1.814-.754 2.438-1.375 1.997.116 3.857-.02 5.344-.375 3.078-.735 5.083-1.101
+7.062-1.5 1.588-.32 2.244-.79 3-1.094.238-.107.467-.193.75-.25 1.134-.23 2.305.209 6.344-.5s5.5-.927 6.219-1.187c.715-.26 1.704-.568 2.343-1.094 1.925.24 3.748.224 5.188 0 3.126-.488 5.155-.7 7.156-.969 2.002-.268 2.489-.945 3.594-1.094 1.146-.154 2.276.302 6.344-.219 4.068-.52 5.56-.695 6.28-.937.738-.247 1.799-.586 2.438-1.125 2.05.335 3.974.398 5.5.219 3.143-.37 5.18-.56 7.188-.782 1.61-.178 2.265-.608 3.031-.843a3.43 3.43 0 0 1 .781-.188c1.15-.128 2.302.347 6.375-.125s5.56-.61 6.282-.844c.719-.232 1.7-.473 2.343-.968 1.937.333 3.77.404 5.22.25 3.145-.335 5.177-.519 7.187-.719 2.01-.2 2.484-.826 3.593-.938 1.152-.115 2.297.366 6.375-.062s5.59-.562 6.313-.781c.74-.224 1.796-.514 2.437-1.031 2.058.398 4.002.493 5.532.343 3.148-.308 5.175-.473 7.187-.656 1.614-.147 2.263-.56 3.031-.781.242-.081.494-.13.782-.156 1.152-.106 2.293.392 6.375 0 4.082-.393 5.589-.531 6.312-.75.721-.219
+1.7-.448 2.344-.938 1.938.35 3.769.454 5.219.313 3.148-.309 5.175-.474 7.187-.657 2.012-.183 2.514-.838 3.625-.937 1.152-.103 2.292.385 6.375 0s5.589-.501 6.313-.719c.739-.222 1.795-.514 2.437-1.031 2.057.402 4.003.503 5.531.344 3.147-.329 5.178-.523 7.188-.72 1.613-.156 2.266-.63 3.031-.874.24-.088.463-.122.75-.156 1.148-.14 2.317.34 6.375-.25 4.058-.59 5.562-.778 6.281-1.032.717-.253 1.675-.558 2.313-1.093 1.92.211 3.72.151 5.156-.094 3.12-.533 5.112-.929 7.094-1.313 1.982-.384 2.474-1.04 3.562-1.28 1.13-.252 2.27.115 6.25-.876s5.43-1.42 6.125-1.781c.723-.376 1.762-.87 2.375-1.531 1.963-.012 3.794-.291 5.22-.844 2.95-1.145 4.872-1.87 6.687-2.75 1.455-.707 2.334-1.686 2.547-1.984.212-.298.111-.746.137-.767.043-.035.32-.085.48-.429.858-1.847 2.32-5.644
+2.435-6.329.113-.682.163-1.348.214-1.745.03-.23-.147-.865-.125-.924.031-.082.305-.265.36-.515.267-1.198.09-2.191-.125-3.609-.214-1.417-.983-4.622-1.637-5.476-.659-.862-1.223-1.011-1.748-1-.208.27.137.262.163.312.68.05.934.369 1.42.897s1.221 3.85 1.358 5.301.19 2.86-.088 3.469c-.278.608-.723.517-1.016.583.531.186.67.125.732.969.058.813-.134 1.64-.52 2.806-.392 1.18-1.846 4.35-2.286 4.598-.452.256-.731.27-1.067.14z" enable-background="new" filter="url(#ff)" opacity=".25"/>
+ <path d="m988.75-263.84c1.912 0.634 4.55 1.758 6.125 2.813 1.575 1.054 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.062 2.47 1.132 5.752 2.155 9.531 3.938-1.207-1.259-7.139-3.365-9.031-4.188s-4.128-1.93-6.938-3.781-3.622-2.482-6-3.719c-2.377-1.237-4.08-1.95-6.53-2.5z" enable-background="new" filter="url(#fe)" opacity=".25"/>
+ <path d="M957.5-260.78c1.91.618 4.583 1.71 6.156 2.75 1.574 1.04 2.896 1.482 5.531 3.375 2.609 1.873 5.027 3.015 7.313 4.063 2.47 1.131 5.752 2.154 9.531 3.937-1.207-1.258-7.201-3.396-9.094-4.219-1.892-.823-4.096-1.93-6.906-3.781-2.81-1.85-3.593-2.44-5.969-3.656s-4.113-1.939-6.562-2.469z" enable-background="new" filter="url(#fd)" opacity=".25"/>
+ <path d="M926.09-257.38c1.908.597 4.553 1.664 6.125 2.688 1.571 1.023 2.87 1.44 5.5 3.28 2.603 1.823 5.029 2.973 7.313 4 2.467 1.111 5.755 2.094 9.53 3.845-1.205-1.249-7.171-3.319-9.062-4.125s-4.102-1.891-6.906-3.688c-2.804-1.796-3.627-2.402-6-3.594-2.373-1.191-4.054-1.903-6.5-2.406z" enable-background="new" filter="url(#fc)" opacity=".25"/>
+ <path d="M894.91-253.56c1.902.554 4.587 1.589 6.156 2.594s2.874 1.408 5.5 3.219c2.6 1.791 5 2.871 7.281 3.875 2.465 1.083 5.76 2.04 9.532 3.75-1.205-1.236-7.175-3.245-9.063-4.032-1.888-.786-4.075-1.83-6.875-3.593s-3.6-2.369-5.969-3.532c-2.37-1.163-4.123-1.834-6.562-2.28z" enable-background="new" filter="url(#fb)" opacity=".25"/>
+ <path d="M863.72-248.66c1.88.43 4.504 1.38 6.063 2.313 1.558.932 2.852 1.257 5.468 3 2.59 1.724 4.981 2.708 7.25 3.625 2.452.99 5.74 1.877 9.5 3.5-1.201-1.208-7.152-3.067-9.03-3.782-1.88-.715-4.086-1.684-6.876-3.375s-3.585-2.228-5.937-3.28-4.026-1.713-6.438-2z" enable-background="new" filter="url(#fa)" opacity=".25"/>
+ <path d="m833.16-241.38c1.848 0.296 4.47 0.976 6 1.781s2.814 1.056 5.375 2.531c2.535 1.46 4.89 2.326 7.125 3.063 2.414 0.797 5.657 1.467 9.375 2.844-1.188-1.129-7.088-2.59-8.938-3.156-1.85-0.567-4.003-1.374-6.75-2.844-2.746-1.47-3.5-1.92-5.812-2.781-2.311-0.861-4.005-1.32-6.375-1.438z" enable-background="new" filter="url(#ez)" opacity=".25"/>
+ <path d="m802.91-232.31c1.822 0.211 4.366 0.8 5.875 1.531 1.51 0.73 2.756 0.93 5.281 2.281 2.5 1.338 4.832 2.049 7.031 2.657 2.377 0.656 5.565 1.073 9.22 2.187-1.168-1.045-6.93-2.103-8.75-2.562-1.822-0.46-3.953-1.127-6.657-2.438s-3.471-1.72-5.75-2.469-3.913-1.179-6.25-1.187z" enable-background="new" filter="url(#ey)" opacity=".25"/>
+ <path d="M773.19-222.19c1.811.179 4.32.665 5.813 1.344 1.491.678 2.753.798 5.25 2.062 2.47 1.252 4.79 1.896 6.968 2.438 2.354.585 5.492.897 9.094 1.844-1.15-.992-6.852-1.784-8.656-2.188s-3.916-1.021-6.594-2.25c-2.678-1.229-3.403-1.61-5.656-2.281-2.253-.67-3.896-1.002-6.219-.969z" enable-background="new" filter="url(#ex)" opacity=".25"/>
+ <path d="M743.56-211.19c1.793.13 4.273.55 5.75 1.188s2.716.741 5.188 1.937c2.446 1.184 4.72 1.747 6.874 2.219 2.328.51 5.42.68 9 1.562-1.143-.97-6.747-1.59-8.53-1.937-1.784-.347-3.884-.888-6.532-2.031-2.648-1.144-3.395-1.517-5.625-2.125-2.23-.61-3.826-.91-6.125-.813z" enable-background="new" filter="url(#ew)" opacity=".25"/>
+ </g>
+ </g>
+ <path d="M3840.7 940.04c1.651-7.722 3.538-13.762 4.889-23.633.803-8.777 3.33-4.873 7.302-20.148 1.41-5.374 5.507.94 9.016-5.757 1.278-1.927 2.901-.97 4.508-.151 3.787 3.165 5.859 8.887 8.381 13.937 6.174 14.326 20.651 19.06 23.62 15.149 1.442-6.97 7.926-12.979 12.444-26.663.752-2.694 11.796-20.982 14.73-15.755" enable-background="new" fill="none" stroke="#000"/>
+ <path d="M3865.4 915.04c7.405-7.758 13.89-21.376 20.826-32.117 3.33-4.726 6.909 7.717 10.857 8.635 2.31-.523 3.734 2.886 5.714 3.939 5.186 3.162 2.412 9.274 10.032 15.452 6.191 4.128 8.958-16.313 14.985-17.573 4.906-1.207 8.145-.758 11.683-.606 3.95.333 4.102-8.393 6.096-12.725 2.997-6.731 7.196-4.438 10.203-11.376 1.023-3.323 1.965-7.224 2.75-12.257.887-4.8 3.057.734 4.825 3.03" enable-background="new" fill="none" stroke="#000"/>
+ <g transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" clip-path="url(#ev)" filter="url(#eu)">
+ <path d="M910.14 746.31l32.613 5.174-.361-23.876 7.188-29.682-8.45-5.264-21.823 26.511-9.167 27.137z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
+ <path d="M877.52 650.19h123.04v172.53H877.52z" enable-background="accumulate" fill="none"/>
+ </g>
+ <g transform="matrix(1.0057 0 0 2.3995 3249.4 125.01)" clip-path="url(#et)" filter="url(#es)">
+ <path d="M964 754.69l18.429 7.465 9.071-36.964-14.87 4.839L964 754.69z" enable-background="accumulate" fill="#fff" fill-rule="evenodd"/>
+ <path d="M924.9 677.06h142.13v125.16H924.9z" enable-background="accumulate" fill="none"/>
+ </g>
+ </g>
+ <path d="m592.8 398.62l2899.5-102.16" fill="#f8d615" fill-rule="evenodd" marker-end="url(#er)" stroke="#f8d615" stroke-width="17.844"/>
+ <path d="m576.48 779.92l2914.5 416.44" enable-background="new" fill="#f8d615" fill-rule="evenodd" marker-end="url(#eq)" stroke="#f8d615" stroke-width="18"/>
+ <g font-family="sans-serif" letter-spacing="0" word-spacing="0">
+ <text transform="translate(48.571 195.53)" x="80.219" y="107.387" fill="#f83615" font-size="40" style="line-height:125%">
+ <tspan x="80.219" y="107.387" font-size="50">CROP_DEFAULT</tspan>
+ </text>
+ <g font-size="45.314">
+ <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="3861.367" y="1281.72" enable-background="new" fill="#f80000" fill-opacity="0" style="line-height:125%">
+ <tspan x="3861.367" y="1281.72" font-size="56.642">COMPOSE_PADDED</tspan>
+ </text>
+ <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="3615.155" y="49.157" enable-background="new" fill="#f8d615" style="line-height:125%">
+ <tspan x="3615.155" y="49.157" font-size="50">COMPOSE_ACTIVE</tspan>
+ </text>
+ <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="2429.153" y="-3.166" enable-background="new" fill="#f83615" style="line-height:125%">
+ <tspan x="2429.153" y="-3.166" font-size="50">COMPOSE_DEFAULT</tspan>
+ </text>
+ <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="3681.545" y="1289.954" enable-background="new" fill="#f815bb" style="line-height:125%">
+ <tspan x="3681.545" y="1289.954" font-size="50">COMPOSE_PADDED</tspan>
+ </text>
+ </g>
+ <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="2438.062" y="1368.429" enable-background="new" font-size="50" style="line-height:125%">
+ <tspan x="2438.062" y="1368.429">COMPOSE_BONDS</tspan>
+ </text>
+ <g font-size="40">
+ <text transform="translate(48.571 195.53)" x="8.082" y="1438.896" enable-background="new" style="line-height:125%">
+ <tspan x="8.082" y="1438.896" font-size="50">CROP_BONDS</tspan>
+ </text>
+ <text transform="translate(48.571 195.53)" x="1455.443" y="-26.808" enable-background="new" style="line-height:125%">
+ <tspan x="1455.443" y="-26.808" font-size="50">overscan area</tspan>
+ </text>
+ <text transform="translate(48.571 195.53)" x="179.631" y="385.388" enable-background="new" fill="#f8d615" style="line-height:125%">
+ <tspan x="179.631" y="385.388" font-size="50">CROP_ACTIVE</tspan>
+ </text>
+ <text transform="translate(48.571 195.53)" x="636.674" y="-138.845" enable-background="new" style="line-height:125%">
+ <tspan x="636.674" y="-138.845" font-size="70" font-weight="bold">DATA SOURCE</tspan>
+ </text>
+ </g>
+ <text transform="matrix(.96106 0 0 1.0405 48.571 195.53)" x="3178.715" y="-129.061" enable-background="new" font-size="45.314" style="line-height:125%">
+ <tspan x="3178.715" y="-129.061" font-size="70" font-weight="bold">DATA SINK</tspan>
+ </text>
+ </g>
</svg>
diff --git a/Documentation/media/uapi/v4l/subdev-image-processing-crop.svg b/Documentation/media/uapi/v4l/subdev-image-processing-crop.svg
index 1903dd3846c2..ee1df49f83e8 100644
--- a/Documentation/media/uapi/v4l/subdev-image-processing-crop.svg
+++ b/Documentation/media/uapi/v4l/subdev-image-processing-crop.svg
@@ -18,11 +18,11 @@
id="metadata100">
<rdf:RDF>
<cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
diff --git a/Documentation/media/uapi/v4l/subdev-image-processing-full.svg b/Documentation/media/uapi/v4l/subdev-image-processing-full.svg
index 91cf51832c12..c10d222b9ea9 100644
--- a/Documentation/media/uapi/v4l/subdev-image-processing-full.svg
+++ b/Documentation/media/uapi/v4l/subdev-image-processing-full.svg
@@ -18,11 +18,11 @@
id="metadata260">
<rdf:RDF>
<cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
diff --git a/Documentation/media/uapi/v4l/subdev-image-processing-scaling-multi-source.svg b/Documentation/media/uapi/v4l/subdev-image-processing-scaling-multi-source.svg
index cedcbf598923..3cb68bf9fc04 100644
--- a/Documentation/media/uapi/v4l/subdev-image-processing-scaling-multi-source.svg
+++ b/Documentation/media/uapi/v4l/subdev-image-processing-scaling-multi-source.svg
@@ -18,11 +18,11 @@
id="metadata186">
<rdf:RDF>
<cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
diff --git a/Documentation/media/uapi/v4l/vbi_525.svg b/Documentation/media/uapi/v4l/vbi_525.svg
index b05f7777ccf8..643aec8d0ba2 100644
--- a/Documentation/media/uapi/v4l/vbi_525.svg
+++ b/Documentation/media/uapi/v4l/vbi_525.svg
@@ -42,19 +42,21 @@
inkscape:current-layer="g10"
units="mm" /><metadata
id="metadata8"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs6"><clipPath
id="clipPath20"
clipPathUnits="userSpaceOnUse"><path
- inkscape:connector-curvature="0"
- id="path22"
- d="m 0,0 5950,0 0,3922 L 0,3922 0,0 Z m 0,3922 5950,0 0,1 -5950,0 0,-1 z m 0,1 1359,0 0,1 -1359,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1363,0 0,1 -1363,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1367,0 0,1 -1367,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1371,0 0,1 -1371,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1375,0 0,1 -1375,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1379,0 0,1 -1379,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1383,0 0,1 -1383,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1387,0 0,1 -1387,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1391,0 0,1 -1391,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1390,0 0,1 -1390,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1386,0 0,1 -1386,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1382,0 0,1 -1382,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1378,0 0,1 -1378,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1374,0 0,1 -1374,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1370,0 0,1 -1370,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1366,0 0,1 -1366,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1362,0 0,1 -1362,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1358,0 0,1 -1358,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 5950,0 0,1 -5950,0 0,-1 z m 0,1 5950,0 0,4478 -5950,0 0,-4478 z" /></clipPath><clipPath
+ inkscape:connector-curvature="0"
+ id="path22"
+ d="m 0,0 5950,0 0,3922 L 0,3922 0,0 Z m 0,3922 5950,0 0,1 -5950,0 0,-1 z m 0,1 1359,0 0,1 -1359,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1363,0 0,1 -1363,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1367,0 0,1 -1367,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1371,0 0,1 -1371,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1375,0 0,1 -1375,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1379,0 0,1 -1379,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1383,0 0,1 -1383,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1387,0 0,1 -1387,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1391,0 0,1 -1391,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1390,0 0,1 -1390,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1386,0 0,1 -1386,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1382,0 0,1 -1382,0 0,-1 z m
+1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1378,0 0,1 -1378,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1374,0 0,1 -1374,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1370,0 0,1 -1370,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1366,0 0,1 -1366,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1362,0 0,1 -1362,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1358,0 0,1 -1358,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 5950,0 0,1 -5950,0 0,-1 z m 0,1 5950,0 0,4478 -5950,0 0,-4478 z" /></clipPath><clipPath
id="clipPath98"
clipPathUnits="userSpaceOnUse"><path
- inkscape:connector-curvature="0"
- id="path100"
- d="m 0,0 5950,0 0,4546 L 0,4546 0,0 Z m 0,4546 5950,0 0,1 -5950,0 0,-1 z m 0,1 1360,0 0,1 -1360,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1364,0 0,1 -1364,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1368,0 0,1 -1368,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1372,0 0,1 -1372,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1376,0 0,1 -1376,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1380,0 0,1 -1380,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1384,0 0,1 -1384,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1388,0 0,1 -1388,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1391,0 0,1 -1391,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1389,0 0,1 -1389,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1385,0 0,1 -1385,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1381,0 0,1 -1381,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1377,0 0,1 -1377,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1373,0 0,1 -1373,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1369,0 0,1 -1369,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1365,0 0,1 -1365,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1361,0 0,1 -1361,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1357,0 0,1 -1357,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 5950,0 0,1 -5950,0 0,-1 z m 0,1 5950,0 0,3854 -5950,0 0,-3854 z" /></clipPath></defs><g
+ inkscape:connector-curvature="0"
+ id="path100"
+ d="m 0,0 5950,0 0,4546 L 0,4546 0,0 Z m 0,4546 5950,0 0,1 -5950,0 0,-1 z m 0,1 1360,0 0,1 -1360,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1364,0 0,1 -1364,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1368,0 0,1 -1368,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1372,0 0,1 -1372,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1376,0 0,1 -1376,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1380,0 0,1 -1380,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1384,0 0,1 -1384,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1388,0 0,1 -1388,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1391,0 0,1 -1391,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1389,0 0,1 -1389,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1385,0 0,1 -1385,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1381,0 0,1 -1381,0 0,-1 z m
+1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1377,0 0,1 -1377,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1373,0 0,1 -1373,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1369,0 0,1 -1369,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1365,0 0,1 -1365,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1361,0 0,1 -1361,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 1357,0 0,1 -1357,0 0,-1 z m 1399,0 4551,0 0,1 -4551,0 0,-1 z m -1399,1 5950,0 0,1 -5950,0 0,-1 z m 0,1 5950,0 0,3854 -5950,0 0,-3854 z" /></clipPath></defs><g
transform="matrix(0.125,0,0,-0.125,-87.571875,638.05691)"
inkscape:label="vbi_525"
inkscape:groupmode="layer"
@@ -62,165 +64,165 @@
transform="matrix(1.3000026,0,0,1.3000026,-210.17435,-1094.2823)"
id="g12"
style=""><path
- inkscape:connector-curvature="0"
- id="path14"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 1281.75,3974.45 0,-85.05" /></g><g
+ inkscape:connector-curvature="0"
+ id="path14"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 1281.75,3974.45 0,-85.05" /></g><g
transform="matrix(1.3000026,0,0,1.3000026,-210.17435,-1094.2823)"
id="g16"
style=""><g
- clip-path="url(#clipPath20)"
- id="g18"
- style=""><path
- inkscape:connector-curvature="0"
- id="path24"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 1281.75,3931.93 113.4,0" /></g></g><g
+ clip-path="url(#clipPath20)"
+ id="g18"
+ style=""><path
+ inkscape:connector-curvature="0"
+ id="path24"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 1281.75,3931.93 113.4,0" /></g></g><g
transform="matrix(1.3000026,0,0,1.3000026,-210.17435,-1094.2823)"
id="g26"
style=""><path
- inkscape:connector-curvature="0"
- id="path28"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 1352.31,3922.48 37.8,9.45 -37.8,9.45 0,-18.9" /><path
- inkscape:connector-curvature="0"
- id="path30"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 1352.31,3922.48 37.8,9.45 -37.8,9.45 0,-18.9 z" /><path
- inkscape:connector-curvature="0"
- id="path32"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 4683.75,4059.5 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path34"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 4400.25,4059.5 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path36"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 4116.75,4059.5 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path38"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 3833.25,4059.5 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path40"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 3549.75,4059.5 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path42"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 3266.25,4059.5 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path44"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 2982.75,4059.5 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path46"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 2699.25,4059.5 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path48"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 2415.75,4059.5 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path50"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 2132.25,4059.5 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path52"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 1848.75,4059.5 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path54"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 1565.25,4059.5 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path56"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 1281.75,4059.5 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path58"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 998.25,4059.5 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path60"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 714.75,4059.5 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path62"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 4683.75,4144.55 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path64"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 4400.25,4144.55 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path66"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 4116.75,4144.55 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path68"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 3833.25,4144.55 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path70"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 3549.75,4144.55 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path72"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 3266.25,4144.55 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path74"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 2982.75,4144.55 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path76"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 2699.25,4144.55 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path78"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 2415.75,4144.55 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path80"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 2132.25,4144.55 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path82"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 1848.75,4144.55 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path84"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 1565.25,4144.55 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path86"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 1281.75,4144.55 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path88"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 998.25,4144.55 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path90"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 714.75,4144.55 0,-56.7" /><path
- inkscape:connector-curvature="0"
- id="path92"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 1281.75,4598.15 0,-85.05" /></g><g
+ inkscape:connector-curvature="0"
+ id="path28"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 1352.31,3922.48 37.8,9.45 -37.8,9.45 0,-18.9" /><path
+ inkscape:connector-curvature="0"
+ id="path30"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 1352.31,3922.48 37.8,9.45 -37.8,9.45 0,-18.9 z" /><path
+ inkscape:connector-curvature="0"
+ id="path32"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 4683.75,4059.5 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path34"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 4400.25,4059.5 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path36"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 4116.75,4059.5 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path38"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 3833.25,4059.5 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path40"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 3549.75,4059.5 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path42"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 3266.25,4059.5 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path44"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 2982.75,4059.5 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path46"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 2699.25,4059.5 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path48"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 2415.75,4059.5 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path50"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 2132.25,4059.5 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path52"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 1848.75,4059.5 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path54"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 1565.25,4059.5 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path56"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 1281.75,4059.5 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path58"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 998.25,4059.5 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path60"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 714.75,4059.5 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path62"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 4683.75,4144.55 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path64"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 4400.25,4144.55 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path66"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 4116.75,4144.55 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path68"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 3833.25,4144.55 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path70"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 3549.75,4144.55 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path72"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 3266.25,4144.55 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path74"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 2982.75,4144.55 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path76"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 2699.25,4144.55 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path78"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 2415.75,4144.55 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path80"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 2132.25,4144.55 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path82"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 1848.75,4144.55 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path84"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 1565.25,4144.55 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path86"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 1281.75,4144.55 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path88"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 998.25,4144.55 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path90"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 714.75,4144.55 0,-56.7" /><path
+ inkscape:connector-curvature="0"
+ id="path92"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 1281.75,4598.15 0,-85.05" /></g><g
transform="matrix(1.3000026,0,0,1.3000026,-210.17435,-1094.2823)"
id="g94"
style=""><g
- clip-path="url(#clipPath98)"
- id="g96"
- style=""><path
- inkscape:connector-curvature="0"
- id="path102"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 1281.75,4555.63 113.4,0" /></g></g><path
+ clip-path="url(#clipPath98)"
+ id="g96"
+ style=""><path
+ inkscape:connector-curvature="0"
+ id="path102"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 1281.75,4555.63 113.4,0" /></g></g><path
d="m 1547.8322,4815.7637 49.1401,12.2851 -49.1401,12.285 0,-24.5701"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="path106"
@@ -546,266 +548,266 @@
id="text268"
style="font-variant:normal;font-weight:normal;font-size:61.42512512px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan270"
- sodipodi:role="line"
- y="-4035.6582"
- x="1621.9453 1642.3999 1676.5522">(1)</tspan></text>
+ id="tspan270"
+ sodipodi:role="line"
+ y="-4035.6582"
+ x="1621.9453 1642.3999 1676.5522">(1)</tspan></text>
<text
y="-4127.7959"
x="4199.7334"
id="text272"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan274"
- sodipodi:role="line"
- y="-4127.7959"
- x="4199.7334 3831.1829 2725.5305 3112.509 3462.6321 4568.2842 4916.3442 4957.3271 5653.4458 5694.4287 5284.895 5325.8779 2356.9773 1988.4264 1210.3424 1251.3252 1292.3081 1619.8759 841.79163 882.77454 923.75732">874569101211322631262</tspan><tspan
- id="tspan276"
- sodipodi:role="line"
- y="-4238.3613"
- x="4158.748 4199.7314 4240.7144 3790.1975 3831.1807 3872.1633 2684.5457 2725.5283 2766.5112 3071.5237 3112.5063 3153.4895 3421.647 3462.6299 3503.6125 4527.2988 4568.2822 4609.2646 4895.8496 4936.833 4977.8154 5632.9517 5673.9341 5714.917 5264.4009 5305.3833 5346.3662 2315.9946 2356.9775 2397.9604 1947.444 1988.4269 2029.4097 1210.3424 1251.3252 1292.3081 1578.8931 1619.876 1660.8589 841.79163 882.77454 923.75732">271270267268269272273275274266265263264262</tspan><tspan
- id="tspan278"
- sodipodi:role="line"
- y="-5049.1729"
- x="2725.5347 4568.2881 1988.4331 2356.9839 1619.8822 3094.0852 3462.636 4916.3506 4957.334 5284.9019 5325.8843 5653.4526 5694.4351 3812.7656 4181.3164">492315610111278</tspan><tspan
- id="tspan280"
- sodipodi:role="line"
- y="-4938.6074"
- x="2725.5474 4568.3013 1988.446 2356.9966 1619.8953 3094.0981 3462.6489 4916.3638 4957.3472 5284.9146 5325.8975 5653.4653 5694.4482 3812.7788 4181.3296">492315610111278</tspan><tspan
- id="tspan282"
- sodipodi:role="line"
- y="-5049.1729"
- x="841.81781 882.8006 923.78326">524</tspan><tspan
- id="tspan284"
- sodipodi:role="line"
- y="-4938.6074"
- x="841.81781 882.8006 923.78326">261</tspan><tspan
- id="tspan286"
- sodipodi:role="line"
- y="-5049.1729"
- x="1210.3684 1251.3512 1292.3342">525</tspan><tspan
- id="tspan288"
- sodipodi:role="line"
- y="-4938.6074"
- x="1210.3684 1251.3512 1292.3342">262</tspan><tspan
- id="tspan290"
- sodipodi:role="line"
- y="-5049.1729"
- x="6022.0161 6062.999">22</tspan><tspan
- id="tspan292"
- sodipodi:role="line"
- y="-4938.6074"
- x="6022.0161 6062.999">22</tspan><tspan
- id="tspan294"
- sodipodi:role="line"
- y="-5049.1729"
- x="6390.5669 6431.5498">23</tspan><tspan
- id="tspan296"
- sodipodi:role="line"
- y="-4938.6074"
- x="6390.5669 6431.5498">23</tspan><tspan
- id="tspan298"
- sodipodi:role="line"
- y="-4238.3623"
- x="6001.5244 6042.5068 6083.4902">285</tspan><tspan
- id="tspan300"
- sodipodi:role="line"
- y="-4127.7964"
- x="6022.0156 6062.9985">22</tspan><tspan
- id="tspan302"
- sodipodi:role="line"
- y="-4238.3623"
- x="6370.0747 6411.0571 6452.04">286</tspan><tspan
- id="tspan304"
- sodipodi:role="line"
- y="-4127.7964"
- x="6390.5664 6431.5493">23</tspan><tspan
- id="tspan306"
- sodipodi:role="line"
- y="-4459.4922"
- x="3540.4146 3581.3972 3618.2522 3638.7437 3659.2354 3679.7266 3696.0901 3737.073 3753.4365">1st field</tspan><tspan
- id="tspan308"
- sodipodi:role="line"
- y="-3648.6809"
- x="3528.1047 3569.0876 3610.0703 3651.0532 3671.5447 3692.0361 3708.3999 3749.3826 3765.7463">2nd field</tspan></text>
+ id="tspan274"
+ sodipodi:role="line"
+ y="-4127.7959"
+ x="4199.7334 3831.1829 2725.5305 3112.509 3462.6321 4568.2842 4916.3442 4957.3271 5653.4458 5694.4287 5284.895 5325.8779 2356.9773 1988.4264 1210.3424 1251.3252 1292.3081 1619.8759 841.79163 882.77454 923.75732">874569101211322631262</tspan><tspan
+ id="tspan276"
+ sodipodi:role="line"
+ y="-4238.3613"
+ x="4158.748 4199.7314 4240.7144 3790.1975 3831.1807 3872.1633 2684.5457 2725.5283 2766.5112 3071.5237 3112.5063 3153.4895 3421.647 3462.6299 3503.6125 4527.2988 4568.2822 4609.2646 4895.8496 4936.833 4977.8154 5632.9517 5673.9341 5714.917 5264.4009 5305.3833 5346.3662 2315.9946 2356.9775 2397.9604 1947.444 1988.4269 2029.4097 1210.3424 1251.3252 1292.3081 1578.8931 1619.876 1660.8589 841.79163 882.77454 923.75732">271270267268269272273275274266265263264262</tspan><tspan
+ id="tspan278"
+ sodipodi:role="line"
+ y="-5049.1729"
+ x="2725.5347 4568.2881 1988.4331 2356.9839 1619.8822 3094.0852 3462.636 4916.3506 4957.334 5284.9019 5325.8843 5653.4526 5694.4351 3812.7656 4181.3164">492315610111278</tspan><tspan
+ id="tspan280"
+ sodipodi:role="line"
+ y="-4938.6074"
+ x="2725.5474 4568.3013 1988.446 2356.9966 1619.8953 3094.0981 3462.6489 4916.3638 4957.3472 5284.9146 5325.8975 5653.4653 5694.4482 3812.7788 4181.3296">492315610111278</tspan><tspan
+ id="tspan282"
+ sodipodi:role="line"
+ y="-5049.1729"
+ x="841.81781 882.8006 923.78326">524</tspan><tspan
+ id="tspan284"
+ sodipodi:role="line"
+ y="-4938.6074"
+ x="841.81781 882.8006 923.78326">261</tspan><tspan
+ id="tspan286"
+ sodipodi:role="line"
+ y="-5049.1729"
+ x="1210.3684 1251.3512 1292.3342">525</tspan><tspan
+ id="tspan288"
+ sodipodi:role="line"
+ y="-4938.6074"
+ x="1210.3684 1251.3512 1292.3342">262</tspan><tspan
+ id="tspan290"
+ sodipodi:role="line"
+ y="-5049.1729"
+ x="6022.0161 6062.999">22</tspan><tspan
+ id="tspan292"
+ sodipodi:role="line"
+ y="-4938.6074"
+ x="6022.0161 6062.999">22</tspan><tspan
+ id="tspan294"
+ sodipodi:role="line"
+ y="-5049.1729"
+ x="6390.5669 6431.5498">23</tspan><tspan
+ id="tspan296"
+ sodipodi:role="line"
+ y="-4938.6074"
+ x="6390.5669 6431.5498">23</tspan><tspan
+ id="tspan298"
+ sodipodi:role="line"
+ y="-4238.3623"
+ x="6001.5244 6042.5068 6083.4902">285</tspan><tspan
+ id="tspan300"
+ sodipodi:role="line"
+ y="-4127.7964"
+ x="6022.0156 6062.9985">22</tspan><tspan
+ id="tspan302"
+ sodipodi:role="line"
+ y="-4238.3623"
+ x="6370.0747 6411.0571 6452.04">286</tspan><tspan
+ id="tspan304"
+ sodipodi:role="line"
+ y="-4127.7964"
+ x="6390.5664 6431.5493">23</tspan><tspan
+ id="tspan306"
+ sodipodi:role="line"
+ y="-4459.4922"
+ x="3540.4146 3581.3972 3618.2522 3638.7437 3659.2354 3679.7266 3696.0901 3737.073 3753.4365">1st field</tspan><tspan
+ id="tspan308"
+ sodipodi:role="line"
+ y="-3648.6809"
+ x="3528.1047 3569.0876 3610.0703 3651.0532 3671.5447 3692.0361 3708.3999 3749.3826 3765.7463">2nd field</tspan></text>
<text
y="-4127.7959"
x="4199.7334 3831.1829 2725.5305 3112.509 3462.6321 4568.2842 4916.3442 4957.3271 5653.4458 5694.4287 5284.895 5325.8779 2356.9773 1988.4264 1210.3424 1251.3252 1292.3081 1619.8759 841.79163 882.77454 923.75732"
id="text3632"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3634"
- sodipodi:role="line"
- y="-4127.7959"
- x="4199.7334 3831.1829 2725.5305 3112.509 3462.6321 4568.2842 4916.3442 4957.3271 5653.4458 5694.4287 5284.895 5325.8779 2356.9773 1988.4264 1210.3424 1251.3252 1292.3081 1619.8759 841.79163 882.77454 923.75732">874569101211322631262</tspan></text>
+ id="tspan3634"
+ sodipodi:role="line"
+ y="-4127.7959"
+ x="4199.7334 3831.1829 2725.5305 3112.509 3462.6321 4568.2842 4916.3442 4957.3271 5653.4458 5694.4287 5284.895 5325.8779 2356.9773 1988.4264 1210.3424 1251.3252 1292.3081 1619.8759 841.79163 882.77454 923.75732">874569101211322631262</tspan></text>
<text
y="-4238.3613"
x="4158.748 4199.7314 4240.7144 3790.1975 3831.1807 3872.1633 2684.5457 2725.5283 2766.5112 3071.5237 3112.5063 3153.4895 3421.647 3462.6299 3503.6125 4527.2988 4568.2822 4609.2646 4895.8496 4936.833 4977.8154 5632.9517 5673.9341 5714.917 5264.4009 5305.3833 5346.3662 2315.9946 2356.9775 2397.9604 1947.444 1988.4269 2029.4097 1210.3424 1251.3252 1292.3081 1578.8931 1619.876 1660.8589 841.79163 882.77454 923.75732"
id="text3636"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3638"
- sodipodi:role="line"
- y="-4238.3613"
- x="4158.748 4199.7314 4240.7144 3790.1975 3831.1807 3872.1633 2684.5457 2725.5283 2766.5112 3071.5237 3112.5063 3153.4895 3421.647 3462.6299 3503.6125 4527.2988 4568.2822 4609.2646 4895.8496 4936.833 4977.8154 5632.9517 5673.9341 5714.917 5264.4009 5305.3833 5346.3662 2315.9946 2356.9775 2397.9604 1947.444 1988.4269 2029.4097 1210.3424 1251.3252 1292.3081 1578.8931 1619.876 1660.8589 841.79163 882.77454 923.75732">271270267268269272273275274266265263264262</tspan></text>
+ id="tspan3638"
+ sodipodi:role="line"
+ y="-4238.3613"
+ x="4158.748 4199.7314 4240.7144 3790.1975 3831.1807 3872.1633 2684.5457 2725.5283 2766.5112 3071.5237 3112.5063 3153.4895 3421.647 3462.6299 3503.6125 4527.2988 4568.2822 4609.2646 4895.8496 4936.833 4977.8154 5632.9517 5673.9341 5714.917 5264.4009 5305.3833 5346.3662 2315.9946 2356.9775 2397.9604 1947.444 1988.4269 2029.4097 1210.3424 1251.3252 1292.3081 1578.8931 1619.876 1660.8589 841.79163 882.77454 923.75732">271270267268269272273275274266265263264262</tspan></text>
<text
y="-5049.1729"
x="2725.5347 4568.2881 1988.4331 2356.9839 1619.8822 3094.0852 3462.636 4916.3506 4957.334 5284.9019 5325.8843 5653.4526 5694.4351 3812.7656 4181.3164"
id="text3640"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3642"
- sodipodi:role="line"
- y="-5049.1729"
- x="2725.5347 4568.2881 1988.4331 2356.9839 1619.8822 3094.0852 3462.636 4916.3506 4957.334 5284.9019 5325.8843 5653.4526 5694.4351 3812.7656 4181.3164">492315610111278</tspan></text>
+ id="tspan3642"
+ sodipodi:role="line"
+ y="-5049.1729"
+ x="2725.5347 4568.2881 1988.4331 2356.9839 1619.8822 3094.0852 3462.636 4916.3506 4957.334 5284.9019 5325.8843 5653.4526 5694.4351 3812.7656 4181.3164">492315610111278</tspan></text>
<text
y="-4938.6074"
x="2725.5474 4568.3013 1988.446 2356.9966 1619.8953 3094.0981 3462.6489 4916.3638 4957.3472 5284.9146 5325.8975 5653.4653 5694.4482 3812.7788 4181.3296"
id="text3644"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3646"
- sodipodi:role="line"
- y="-4938.6074"
- x="2725.5474 4568.3013 1988.446 2356.9966 1619.8953 3094.0981 3462.6489 4916.3638 4957.3472 5284.9146 5325.8975 5653.4653 5694.4482 3812.7788 4181.3296">492315610111278</tspan></text>
+ id="tspan3646"
+ sodipodi:role="line"
+ y="-4938.6074"
+ x="2725.5474 4568.3013 1988.446 2356.9966 1619.8953 3094.0981 3462.6489 4916.3638 4957.3472 5284.9146 5325.8975 5653.4653 5694.4482 3812.7788 4181.3296">492315610111278</tspan></text>
<text
y="-5049.1729"
x="841.81781 882.8006 923.78326"
id="text3648"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3650"
- sodipodi:role="line"
- y="-5049.1729"
- x="841.81781 882.8006 923.78326">524</tspan></text>
+ id="tspan3650"
+ sodipodi:role="line"
+ y="-5049.1729"
+ x="841.81781 882.8006 923.78326">524</tspan></text>
<text
y="-4938.6074"
x="841.81781 882.8006 923.78326"
id="text3652"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3654"
- sodipodi:role="line"
- y="-4938.6074"
- x="841.81781 882.8006 923.78326">261</tspan></text>
+ id="tspan3654"
+ sodipodi:role="line"
+ y="-4938.6074"
+ x="841.81781 882.8006 923.78326">261</tspan></text>
<text
y="-5049.1729"
x="1210.3684 1251.3512 1292.3342"
id="text3656"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3658"
- sodipodi:role="line"
- y="-5049.1729"
- x="1210.3684 1251.3512 1292.3342">525</tspan></text>
+ id="tspan3658"
+ sodipodi:role="line"
+ y="-5049.1729"
+ x="1210.3684 1251.3512 1292.3342">525</tspan></text>
<text
y="-4938.6074"
x="1210.3684 1251.3512 1292.3342"
id="text3660"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3662"
- sodipodi:role="line"
- y="-4938.6074"
- x="1210.3684 1251.3512 1292.3342">262</tspan></text>
+ id="tspan3662"
+ sodipodi:role="line"
+ y="-4938.6074"
+ x="1210.3684 1251.3512 1292.3342">262</tspan></text>
<text
y="-5049.1729"
x="6022.0161 6062.999"
id="text3664"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3666"
- sodipodi:role="line"
- y="-5049.1729"
- x="6022.0161 6062.999">22</tspan></text>
+ id="tspan3666"
+ sodipodi:role="line"
+ y="-5049.1729"
+ x="6022.0161 6062.999">22</tspan></text>
<text
y="-4938.6074"
x="6022.0161 6062.999"
id="text3668"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3670"
- sodipodi:role="line"
- y="-4938.6074"
- x="6022.0161 6062.999">22</tspan></text>
+ id="tspan3670"
+ sodipodi:role="line"
+ y="-4938.6074"
+ x="6022.0161 6062.999">22</tspan></text>
<text
y="-5049.1729"
x="6390.5669 6431.5498"
id="text3672"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3674"
- sodipodi:role="line"
- y="-5049.1729"
- x="6390.5669 6431.5498">23</tspan></text>
+ id="tspan3674"
+ sodipodi:role="line"
+ y="-5049.1729"
+ x="6390.5669 6431.5498">23</tspan></text>
<text
y="-4938.6074"
x="6390.5669 6431.5498"
id="text3676"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3678"
- sodipodi:role="line"
- y="-4938.6074"
- x="6390.5669 6431.5498">23</tspan></text>
+ id="tspan3678"
+ sodipodi:role="line"
+ y="-4938.6074"
+ x="6390.5669 6431.5498">23</tspan></text>
<text
y="-4238.3623"
x="6001.5244 6042.5068 6083.4902"
id="text3680"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3682"
- sodipodi:role="line"
- y="-4238.3623"
- x="6001.5244 6042.5068 6083.4902">285</tspan></text>
+ id="tspan3682"
+ sodipodi:role="line"
+ y="-4238.3623"
+ x="6001.5244 6042.5068 6083.4902">285</tspan></text>
<text
y="-4127.7964"
x="6022.0156 6062.9985"
id="text3684"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3686"
- sodipodi:role="line"
- y="-4127.7964"
- x="6022.0156 6062.9985">22</tspan></text>
+ id="tspan3686"
+ sodipodi:role="line"
+ y="-4127.7964"
+ x="6022.0156 6062.9985">22</tspan></text>
<text
y="-4238.3623"
x="6370.0747 6411.0571 6452.04"
id="text3688"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3690"
- sodipodi:role="line"
- y="-4238.3623"
- x="6370.0747 6411.0571 6452.04">286</tspan></text>
+ id="tspan3690"
+ sodipodi:role="line"
+ y="-4238.3623"
+ x="6370.0747 6411.0571 6452.04">286</tspan></text>
<text
y="-4127.7964"
x="6390.5664 6431.5493"
id="text3692"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3694"
- sodipodi:role="line"
- y="-4127.7964"
- x="6390.5664 6431.5493">23</tspan></text>
+ id="tspan3694"
+ sodipodi:role="line"
+ y="-4127.7964"
+ x="6390.5664 6431.5493">23</tspan></text>
<text
y="-4459.4922"
x="3540.4146 3581.3972 3618.2522 3638.7437 3659.2354 3679.7266 3696.0901 3737.073 3753.4365"
id="text3696"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3698"
- sodipodi:role="line"
- y="-4459.4922"
- x="3540.4146 3581.3972 3618.2522 3638.7437 3659.2354 3679.7266 3696.0901 3737.073 3753.4365">1st field</tspan></text>
+ id="tspan3698"
+ sodipodi:role="line"
+ y="-4459.4922"
+ x="3540.4146 3581.3972 3618.2522 3638.7437 3659.2354 3679.7266 3696.0901 3737.073 3753.4365">1st field</tspan></text>
<text
y="-3648.6809"
x="3528.1047 3569.0876 3610.0703 3651.0532 3671.5447 3692.0361 3708.3999 3749.3826 3765.7463"
id="text3700"
style="font-variant:normal;font-weight:normal;font-size:73.71015167px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"><tspan
- id="tspan3702"
- sodipodi:role="line"
- y="-3648.6809"
- x="3528.1047 3569.0876 3610.0703 3651.0532 3671.5447 3692.0361 3708.3999 3749.3826 3765.7463">2nd field</tspan></text>
+ id="tspan3702"
+ sodipodi:role="line"
+ y="-3648.6809"
+ x="3528.1047 3569.0876 3610.0703 3651.0532 3671.5447 3692.0361 3708.3999 3749.3826 3765.7463">2nd field</tspan></text>
</g></svg> \ No newline at end of file
diff --git a/Documentation/media/uapi/v4l/vbi_625.svg b/Documentation/media/uapi/v4l/vbi_625.svg
index c117ddb7bf7e..9b18243c0a06 100644
--- a/Documentation/media/uapi/v4l/vbi_625.svg
+++ b/Documentation/media/uapi/v4l/vbi_625.svg
@@ -42,19 +42,21 @@
inkscape:current-layer="g10"
units="mm" /><metadata
id="metadata8"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs6"><clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath20"><path
- d="m 0,0 5950,0 0,4546 L 0,4546 0,0 Z m 0,4546 5950,0 0,1 -5950,0 0,-1 z m 0,1 2211,0 0,1 -2211,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2215,0 0,1 -2215,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2219,0 0,1 -2219,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2223,0 0,1 -2223,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2227,0 0,1 -2227,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2231,0 0,1 -2231,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2235,0 0,1 -2235,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2239,0 0,1 -2239,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2241,0 0,1 -2241,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2240,0 0,1 -2240,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2236,0 0,1 -2236,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2232,0 0,1 -2232,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2228,0 0,1 -2228,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2224,0 0,1 -2224,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2220,0 0,1 -2220,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2216,0 0,1 -2216,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2212,0 0,1 -2212,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2208,0 0,1 -2208,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 5950,0 0,1 -5950,0 0,-1 z m 0,1 5950,0 0,3854 -5950,0 0,-3854 z"
- id="path22"
- inkscape:connector-curvature="0" /></clipPath><clipPath
+ d="m 0,0 5950,0 0,4546 L 0,4546 0,0 Z m 0,4546 5950,0 0,1 -5950,0 0,-1 z m 0,1 2211,0 0,1 -2211,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2215,0 0,1 -2215,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2219,0 0,1 -2219,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2223,0 0,1 -2223,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2227,0 0,1 -2227,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2231,0 0,1 -2231,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2235,0 0,1 -2235,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2239,0 0,1 -2239,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2241,0 0,1 -2241,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2240,0 0,1 -2240,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2236,0 0,1 -2236,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2232,0 0,1 -2232,0 0,-1 z m
+2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2228,0 0,1 -2228,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2224,0 0,1 -2224,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2220,0 0,1 -2220,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2216,0 0,1 -2216,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2212,0 0,1 -2212,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2208,0 0,1 -2208,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 5950,0 0,1 -5950,0 0,-1 z m 0,1 5950,0 0,3854 -5950,0 0,-3854 z"
+ id="path22"
+ inkscape:connector-curvature="0" /></clipPath><clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath98"><path
- d="m 0,0 5950,0 0,3922 L 0,3922 0,0 Z m 0,3922 5950,0 0,1 -5950,0 0,-1 z m 0,1 2209,0 0,1 -2209,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2213,0 0,1 -2213,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2217,0 0,1 -2217,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2221,0 0,1 -2221,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2225,0 0,1 -2225,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2229,0 0,1 -2229,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2233,0 0,1 -2233,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2237,0 0,1 -2237,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2241,0 0,1 -2241,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2241,0 0,1 -2241,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2237,0 0,1 -2237,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2233,0 0,1 -2233,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2229,0 0,1 -2229,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2225,0 0,1 -2225,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2221,0 0,1 -2221,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2217,0 0,1 -2217,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2213,0 0,1 -2213,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2209,0 0,1 -2209,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 5950,0 0,1 -5950,0 0,-1 z m 0,1 5950,0 0,4478 -5950,0 0,-4478 z"
- id="path100"
- inkscape:connector-curvature="0" /></clipPath></defs><g
+ d="m 0,0 5950,0 0,3922 L 0,3922 0,0 Z m 0,3922 5950,0 0,1 -5950,0 0,-1 z m 0,1 2209,0 0,1 -2209,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2213,0 0,1 -2213,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2217,0 0,1 -2217,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2221,0 0,1 -2221,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2225,0 0,1 -2225,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2229,0 0,1 -2229,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2233,0 0,1 -2233,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2237,0 0,1 -2237,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2241,0 0,1 -2241,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2241,0 0,1 -2241,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2237,0 0,1 -2237,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2233,0 0,1 -2233,0 0,-1 z m
+2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2229,0 0,1 -2229,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2225,0 0,1 -2225,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2221,0 0,1 -2221,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2217,0 0,1 -2217,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2213,0 0,1 -2213,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 2209,0 0,1 -2209,0 0,-1 z m 2250,0 3700,0 0,1 -3700,0 0,-1 z m -2250,1 5950,0 0,1 -5950,0 0,-1 z m 0,1 5950,0 0,4478 -5950,0 0,-4478 z"
+ id="path100"
+ inkscape:connector-curvature="0" /></clipPath></defs><g
id="g10"
inkscape:groupmode="layer"
inkscape:label="vbi_625"
@@ -62,20 +64,20 @@
id="g12"
transform="matrix(1.3045828,0,0,1.3045828,-213.38312,-1110.9872)"
style=""><path
- d="m 2132.25,4598.15 0,-85.05"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- id="path14"
- inkscape:connector-curvature="0" /></g><g
+ d="m 2132.25,4598.15 0,-85.05"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ id="path14"
+ inkscape:connector-curvature="0" /></g><g
id="g16"
transform="matrix(1.3045828,0,0,1.3045828,-213.38312,-1110.9872)"
style=""><g
- id="g18"
- clip-path="url(#clipPath20)"
- style=""><path
- d="m 2132.25,4555.63 113.4,0"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- id="path24"
- inkscape:connector-curvature="0" /></g></g><path
+ id="g18"
+ clip-path="url(#clipPath20)"
+ style=""><path
+ d="m 2132.25,4555.63 113.4,0"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ id="path24"
+ inkscape:connector-curvature="0" /></g></g><path
inkscape:connector-curvature="0"
id="path28"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
@@ -211,13 +213,13 @@
id="g94"
transform="matrix(1.3045828,0,0,1.3045828,-213.38312,-1110.9872)"
style=""><g
- id="g96"
- clip-path="url(#clipPath98)"
- style=""><path
- d="m 2132.25,3931.93 113.4,0"
- style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- id="path102"
- inkscape:connector-curvature="0" /></g></g><path
+ id="g96"
+ clip-path="url(#clipPath98)"
+ style=""><path
+ d="m 2132.25,3931.93 113.4,0"
+ style="fill:none;stroke:#000000;stroke-width:2.36249995;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ id="path102"
+ inkscape:connector-curvature="0" /></g></g><path
inkscape:connector-curvature="0"
id="path106"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
@@ -385,7 +387,8 @@
inkscape:connector-curvature="0"
id="path188"
style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 1162.8865,4739.7407 18.486,0 0,92.4688 18.499,-18.499 18.4859,36.9849 18.499,-36.9849 18.4859,36.9849 18.499,-55.4708 18.4859,55.4708 18.499,-18.4859 18.486,55.4708 18.499,-55.4708 18.4859,18.4859 18.499,36.9849 18.4859,-73.9698 18.499,36.9849 18.4859,-55.4708 0,-55.4839 18.499,0 0,-110.9548 36.985,0 0,110.9548 18.4859,0 0,55.4839 18.499,36.9849 18.4859,-36.9849 18.499,55.4708 18.4859,-18.4859 18.499,55.4708 18.486,-18.4859 0,-129.4537 18.4989,0 0,-110.9548 18.486,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 147.9397,0 0,110.9548 36.9849,0 0,-110.9548 147.9397,0 0,110.9548 36.985,0 0,-110.9548 147.9397,0 0,110.9548 36.9849,0 0,-110.9548 147.9397,0 0,110.9548 36.9849,0 0,-110.9548 147.9397,0 0,110.9548 36.9849,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.486,0 0,110.9548 166.4386,0 0,-110.9548 18.486,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 36.9849,0 0,110.9548 332.8643,0 0,-110.9548 36.9849,0 0,110.9548 18.486,0" /><path
+ d="m 1162.8865,4739.7407 18.486,0 0,92.4688 18.499,-18.499 18.4859,36.9849 18.499,-36.9849 18.4859,36.9849 18.499,-55.4708 18.4859,55.4708 18.499,-18.4859 18.486,55.4708 18.499,-55.4708 18.4859,18.4859 18.499,36.9849 18.4859,-73.9698 18.499,36.9849 18.4859,-55.4708 0,-55.4839 18.499,0 0,-110.9548 36.985,0 0,110.9548 18.4859,0 0,55.4839 18.499,36.9849 18.4859,-36.9849 18.499,55.4708 18.4859,-18.4859 18.499,55.4708 18.486,-18.4859 0,-129.4537 18.4989,0 0,-110.9548 18.486,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 147.9397,0 0,110.9548 36.9849,0 0,-110.9548 147.9397,0 0,110.9548 36.985,0 0,-110.9548 147.9397,0 0,110.9548 36.9849,0 0,-110.9548 147.9397,0 0,110.9548 36.9849,0 0,-110.9548 147.9397,0 0,110.9548 36.9849,0
+0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.486,0 0,110.9548 166.4386,0 0,-110.9548 18.486,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 18.4859,0 0,110.9548 166.4387,0 0,-110.9548 36.9849,0 0,110.9548 332.8643,0 0,-110.9548 36.9849,0 0,110.9548 18.486,0" /><path
inkscape:connector-curvature="0"
id="path190"
style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
@@ -409,7 +412,8 @@
inkscape:connector-curvature="0"
id="path200"
style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 1162.8865,3926.0723 18.486,0 0,55.4839 18.499,92.4558 18.4859,-55.4708 36.9849,36.9849 18.499,-55.4839 18.4859,18.499 18.499,-36.985 18.486,55.4709 18.499,-18.4859 18.4859,-36.985 18.499,18.486 18.4859,36.9849 18.499,-36.9849 18.4859,36.9849 0,-110.9548 18.499,0 0,-110.9547 18.486,0 0,110.9547 166.4386,0 0,-110.9547 18.486,0 0,110.9547 166.4387,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 147.9397,0 0,110.9547 36.9849,0 0,-110.9547 147.9397,0 0,110.9547 36.9849,0 0,-110.9547 147.9397,0 0,110.9547 36.985,0 0,-110.9547 147.9397,0 0,110.9547 36.9849,0 0,-110.9547 147.9397,0 0,110.9547 36.9849,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 18.486,0 0,110.9547 166.4386,0 0,-110.9547 18.486,0 0,110.9547 166.4387,0 0,-110.9547 18.4859,0 0,110.9547 351.3633,0 0,-110.9547 36.9849,0 0,110.9547 18.486,0" /><path
+ d="m 1162.8865,3926.0723 18.486,0 0,55.4839 18.499,92.4558 18.4859,-55.4708 36.9849,36.9849 18.499,-55.4839 18.4859,18.499 18.499,-36.985 18.486,55.4709 18.499,-18.4859 18.4859,-36.985 18.499,18.486 18.4859,36.9849 18.499,-36.9849 18.4859,36.9849 0,-110.9548 18.499,0 0,-110.9547 18.486,0 0,110.9547 166.4386,0 0,-110.9547 18.486,0 0,110.9547 166.4387,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 147.9397,0 0,110.9547 36.9849,0 0,-110.9547 147.9397,0 0,110.9547 36.9849,0 0,-110.9547 147.9397,0 0,110.9547 36.985,0 0,-110.9547 147.9397,0 0,110.9547 36.9849,0 0,-110.9547 147.9397,0 0,110.9547 36.9849,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 18.4859,0 0,110.9547 166.4387,0 0,-110.9547 18.486,0 0,110.9547 166.4386,0 0,-110.9547 18.486,0 0,110.9547 166.4387,0 0,-110.9547
+18.4859,0 0,110.9547 351.3633,0 0,-110.9547 36.9849,0 0,110.9547 18.486,0" /><path
inkscape:connector-curvature="0"
id="path202"
style="fill:none;stroke:#000000;stroke-width:3.08207679;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
@@ -559,300 +563,300 @@
id="text276"
x="3550.4165"
y="-4462.3472"><tspan
- x="3550.4165 3591.5437 3628.5286 3649.0923 3669.656 3690.2195 3706.6409 3747.7681 3764.1895"
- y="-4462.3472"
- sodipodi:role="line"
- id="tspan278">1st field</tspan><tspan
- x="2732.6792 3823.7344 4193.5835 4581.9253 4951.7744 5321.6235 3472.3777 3102.5283 2321.7029 2362.8303 2403.9575 1951.8538 1992.981 2034.1083 1582.0045 1623.132 1664.259 5670.9062 5712.0337"
- y="-4943.1509"
- sodipodi:role="line"
- id="tspan280">1456783231231131022</tspan><tspan
- x="2732.6726 3823.7278 4193.5771 4581.9189 4951.7681 5321.6172 3472.3711 3102.522 2321.6965 2362.8237 2403.9509 1951.8473 1992.9745 2034.1018 1581.998 1623.1254 1664.2524 5670.8999 5712.0269"
- y="-5054.1064"
- sodipodi:role="line"
- id="tspan282">1456783262562462322</tspan><tspan
- x="842.29962 883.42694 924.55408"
- y="-4943.1509"
- sodipodi:role="line"
- id="tspan284">308</tspan><tspan
- x="842.29962 883.42694 924.55408"
- y="-5054.1064"
- sodipodi:role="line"
- id="tspan286">621</tspan><tspan
- x="1212.1489 1253.276 1294.4033"
- y="-4943.1509"
- sodipodi:role="line"
- id="tspan288">309</tspan><tspan
- x="1212.1489 1253.276 1294.4033"
- y="-5054.1064"
- sodipodi:role="line"
- id="tspan290">622</tspan><tspan
- x="3538.0635 3579.1907 3620.3179 3661.4451 3682.0088 3702.5723 3718.9937 3760.1208 3776.5422"
- y="-3648.6792"
- sodipodi:role="line"
- id="tspan292">2nd field</tspan></text>
+ x="3550.4165 3591.5437 3628.5286 3649.0923 3669.656 3690.2195 3706.6409 3747.7681 3764.1895"
+ y="-4462.3472"
+ sodipodi:role="line"
+ id="tspan278">1st field</tspan><tspan
+ x="2732.6792 3823.7344 4193.5835 4581.9253 4951.7744 5321.6235 3472.3777 3102.5283 2321.7029 2362.8303 2403.9575 1951.8538 1992.981 2034.1083 1582.0045 1623.132 1664.259 5670.9062 5712.0337"
+ y="-4943.1509"
+ sodipodi:role="line"
+ id="tspan280">1456783231231131022</tspan><tspan
+ x="2732.6726 3823.7278 4193.5771 4581.9189 4951.7681 5321.6172 3472.3711 3102.522 2321.6965 2362.8237 2403.9509 1951.8473 1992.9745 2034.1018 1581.998 1623.1254 1664.2524 5670.8999 5712.0269"
+ y="-5054.1064"
+ sodipodi:role="line"
+ id="tspan282">1456783262562462322</tspan><tspan
+ x="842.29962 883.42694 924.55408"
+ y="-4943.1509"
+ sodipodi:role="line"
+ id="tspan284">308</tspan><tspan
+ x="842.29962 883.42694 924.55408"
+ y="-5054.1064"
+ sodipodi:role="line"
+ id="tspan286">621</tspan><tspan
+ x="1212.1489 1253.276 1294.4033"
+ y="-4943.1509"
+ sodipodi:role="line"
+ id="tspan288">309</tspan><tspan
+ x="1212.1489 1253.276 1294.4033"
+ y="-5054.1064"
+ sodipodi:role="line"
+ id="tspan290">622</tspan><tspan
+ x="3538.0635 3579.1907 3620.3179 3661.4451 3682.0088 3702.5723 3718.9937 3760.1208 3776.5422"
+ y="-3648.6792"
+ sodipodi:role="line"
+ id="tspan292">2nd field</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:61.64153671px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text294"
x="2734.751"
y="-4037.021"><tspan
- x="2734.751 2755.2776 2789.5503"
- y="-4037.021"
- sodipodi:role="line"
- id="tspan296">(1)</tspan></text>
+ x="2734.751 2755.2776 2789.5503"
+ y="-4037.021"
+ sodipodi:role="line"
+ id="tspan296">(1)</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text298"
x="4951.772"
y="-4129.4834"><tspan
- x="4951.772 4581.9229 4212.0737 3842.2244 3490.8677 3102.5259 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
- y="-4129.4834"
- sodipodi:role="line"
- id="tspan300">765432313312311</tspan><tspan
- x="6020.1929 6061.3198 6102.4473 5650.3433 5691.4707 5732.5981 5280.4941 5321.6216 5362.7485 4910.645 4951.7725 4992.8994 4540.7959 4581.9229 4623.0503 4170.9468 4212.0737 4253.2012 3801.0974 3842.2246 3883.3518 3449.7405 3490.8677 3531.9951 3061.3989 3102.5261 3143.6533 2691.5496 2732.677 2773.8042 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
- y="-4240.4385"
- sodipodi:role="line"
- id="tspan302">336335321320319318317316315314313312311</tspan><tspan
- x="2732.6765 5321.6211 5670.9062 5712.0337 6040.7554 6081.8828 842.30634 883.43323 924.56055"
- y="-4129.4834"
- sodipodi:role="line"
- id="tspan304">182223309</tspan><tspan
- x="842.30634 883.43323 924.56055"
- y="-4240.4385"
- sodipodi:role="line"
- id="tspan306">309</tspan><tspan
- x="1212.1553 1253.2826 1294.4099"
- y="-4129.4834"
- sodipodi:role="line"
- id="tspan308">310</tspan><tspan
- x="1212.1553 1253.2826 1294.4099"
- y="-4240.4385"
- sodipodi:role="line"
- id="tspan310">310</tspan><tspan
- x="6410.605 6451.7319"
- y="-4129.4834"
- sodipodi:role="line"
- id="tspan312">24</tspan><tspan
- x="6390.041 6431.1685 6472.2954"
- y="-4240.4385"
- sodipodi:role="line"
- id="tspan314">337</tspan><tspan
- x="6040.7559 6081.8833"
- y="-4943.1504"
- sodipodi:role="line"
- id="tspan316">23</tspan><tspan
- x="6040.7559 6081.8833"
- y="-5054.106"
- sodipodi:role="line"
- id="tspan318">23</tspan><tspan
- x="6410.605 6451.7324"
- y="-4943.1504"
- sodipodi:role="line"
- id="tspan320">24</tspan><tspan
- x="6410.605 6451.7324"
- y="-5054.106"
- sodipodi:role="line"
- id="tspan322">24</tspan></text>
+ x="4951.772 4581.9229 4212.0737 3842.2244 3490.8677 3102.5259 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
+ y="-4129.4834"
+ sodipodi:role="line"
+ id="tspan300">765432313312311</tspan><tspan
+ x="6020.1929 6061.3198 6102.4473 5650.3433 5691.4707 5732.5981 5280.4941 5321.6216 5362.7485 4910.645 4951.7725 4992.8994 4540.7959 4581.9229 4623.0503 4170.9468 4212.0737 4253.2012 3801.0974 3842.2246 3883.3518 3449.7405 3490.8677 3531.9951 3061.3989 3102.5261 3143.6533 2691.5496 2732.677 2773.8042 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
+ y="-4240.4385"
+ sodipodi:role="line"
+ id="tspan302">336335321320319318317316315314313312311</tspan><tspan
+ x="2732.6765 5321.6211 5670.9062 5712.0337 6040.7554 6081.8828 842.30634 883.43323 924.56055"
+ y="-4129.4834"
+ sodipodi:role="line"
+ id="tspan304">182223309</tspan><tspan
+ x="842.30634 883.43323 924.56055"
+ y="-4240.4385"
+ sodipodi:role="line"
+ id="tspan306">309</tspan><tspan
+ x="1212.1553 1253.2826 1294.4099"
+ y="-4129.4834"
+ sodipodi:role="line"
+ id="tspan308">310</tspan><tspan
+ x="1212.1553 1253.2826 1294.4099"
+ y="-4240.4385"
+ sodipodi:role="line"
+ id="tspan310">310</tspan><tspan
+ x="6410.605 6451.7319"
+ y="-4129.4834"
+ sodipodi:role="line"
+ id="tspan312">24</tspan><tspan
+ x="6390.041 6431.1685 6472.2954"
+ y="-4240.4385"
+ sodipodi:role="line"
+ id="tspan314">337</tspan><tspan
+ x="6040.7559 6081.8833"
+ y="-4943.1504"
+ sodipodi:role="line"
+ id="tspan316">23</tspan><tspan
+ x="6040.7559 6081.8833"
+ y="-5054.106"
+ sodipodi:role="line"
+ id="tspan318">23</tspan><tspan
+ x="6410.605 6451.7324"
+ y="-4943.1504"
+ sodipodi:role="line"
+ id="tspan320">24</tspan><tspan
+ x="6410.605 6451.7324"
+ y="-5054.106"
+ sodipodi:role="line"
+ id="tspan322">24</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text3671"
x="3550.4165 3591.5437 3628.5286 3649.0923 3669.656 3690.2195 3706.6409 3747.7681 3764.1895"
y="-4462.3472"><tspan
- x="3550.4165 3591.5437 3628.5286 3649.0923 3669.656 3690.2195 3706.6409 3747.7681 3764.1895"
- y="-4462.3472"
- sodipodi:role="line"
- id="tspan3673">1st field</tspan></text>
+ x="3550.4165 3591.5437 3628.5286 3649.0923 3669.656 3690.2195 3706.6409 3747.7681 3764.1895"
+ y="-4462.3472"
+ sodipodi:role="line"
+ id="tspan3673">1st field</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text3675"
x="2732.6792 3823.7344 4193.5835 4581.9253 4951.7744 5321.6235 3472.3777 3102.5283 2321.7029 2362.8303 2403.9575 1951.8538 1992.981 2034.1083 1582.0045 1623.132 1664.259 5670.9062 5712.0337"
y="-4943.1509"><tspan
- x="2732.6792 3823.7344 4193.5835 4581.9253 4951.7744 5321.6235 3472.3777 3102.5283 2321.7029 2362.8303 2403.9575 1951.8538 1992.981 2034.1083 1582.0045 1623.132 1664.259 5670.9062 5712.0337"
- y="-4943.1509"
- sodipodi:role="line"
- id="tspan3677">1456783231231131022</tspan></text>
+ x="2732.6792 3823.7344 4193.5835 4581.9253 4951.7744 5321.6235 3472.3777 3102.5283 2321.7029 2362.8303 2403.9575 1951.8538 1992.981 2034.1083 1582.0045 1623.132 1664.259 5670.9062 5712.0337"
+ y="-4943.1509"
+ sodipodi:role="line"
+ id="tspan3677">1456783231231131022</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text3679"
x="2732.6726 3823.7278 4193.5771 4581.9189 4951.7681 5321.6172 3472.3711 3102.522 2321.6965 2362.8237 2403.9509 1951.8473 1992.9745 2034.1018 1581.998 1623.1254 1664.2524 5670.8999 5712.0269"
y="-5054.1064"><tspan
- x="2732.6726 3823.7278 4193.5771 4581.9189 4951.7681 5321.6172 3472.3711 3102.522 2321.6965 2362.8237 2403.9509 1951.8473 1992.9745 2034.1018 1581.998 1623.1254 1664.2524 5670.8999 5712.0269"
- y="-5054.1064"
- sodipodi:role="line"
- id="tspan3681">1456783262562462322</tspan></text>
+ x="2732.6726 3823.7278 4193.5771 4581.9189 4951.7681 5321.6172 3472.3711 3102.522 2321.6965 2362.8237 2403.9509 1951.8473 1992.9745 2034.1018 1581.998 1623.1254 1664.2524 5670.8999 5712.0269"
+ y="-5054.1064"
+ sodipodi:role="line"
+ id="tspan3681">1456783262562462322</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text3683"
x="842.29962 883.42694 924.55408"
y="-4943.1509"><tspan
- x="842.29962 883.42694 924.55408"
- y="-4943.1509"
- sodipodi:role="line"
- id="tspan3685">308</tspan></text>
+ x="842.29962 883.42694 924.55408"
+ y="-4943.1509"
+ sodipodi:role="line"
+ id="tspan3685">308</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text3687"
x="842.29962 883.42694 924.55408"
y="-5054.1064"><tspan
- x="842.29962 883.42694 924.55408"
- y="-5054.1064"
- sodipodi:role="line"
- id="tspan3689">621</tspan></text>
+ x="842.29962 883.42694 924.55408"
+ y="-5054.1064"
+ sodipodi:role="line"
+ id="tspan3689">621</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text3691"
x="1212.1489 1253.276 1294.4033"
y="-4943.1509"><tspan
- x="1212.1489 1253.276 1294.4033"
- y="-4943.1509"
- sodipodi:role="line"
- id="tspan3693">309</tspan></text>
+ x="1212.1489 1253.276 1294.4033"
+ y="-4943.1509"
+ sodipodi:role="line"
+ id="tspan3693">309</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text3695"
x="1212.1489 1253.276 1294.4033"
y="-5054.1064"><tspan
- x="1212.1489 1253.276 1294.4033"
- y="-5054.1064"
- sodipodi:role="line"
- id="tspan3697">622</tspan></text>
+ x="1212.1489 1253.276 1294.4033"
+ y="-5054.1064"
+ sodipodi:role="line"
+ id="tspan3697">622</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text3699"
x="3538.0635 3579.1907 3620.3179 3661.4451 3682.0088 3702.5723 3718.9937 3760.1208 3776.5422"
y="-3648.6792"><tspan
- x="3538.0635 3579.1907 3620.3179 3661.4451 3682.0088 3702.5723 3718.9937 3760.1208 3776.5422"
- y="-3648.6792"
- sodipodi:role="line"
- id="tspan3701">2nd field</tspan></text>
+ x="3538.0635 3579.1907 3620.3179 3661.4451 3682.0088 3702.5723 3718.9937 3760.1208 3776.5422"
+ y="-3648.6792"
+ sodipodi:role="line"
+ id="tspan3701">2nd field</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text4083"
x="4951.772 4581.9229 4212.0737 3842.2244 3490.8677 3102.5259 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
y="-4129.4834"><tspan
- x="4951.772 4581.9229 4212.0737 3842.2244 3490.8677 3102.5259 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
- y="-4129.4834"
- sodipodi:role="line"
- id="tspan4085">765432313312311</tspan></text>
+ x="4951.772 4581.9229 4212.0737 3842.2244 3490.8677 3102.5259 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
+ y="-4129.4834"
+ sodipodi:role="line"
+ id="tspan4085">765432313312311</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text4087"
x="6020.1929 6061.3198 6102.4473 5650.3433 5691.4707 5732.5981 5280.4941 5321.6216 5362.7485 4910.645 4951.7725 4992.8994 4540.7959 4581.9229 4623.0503 4170.9468 4212.0737 4253.2012 3801.0974 3842.2246 3883.3518 3449.7405 3490.8677 3531.9951 3061.3989 3102.5261 3143.6533 2691.5496 2732.677 2773.8042 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
y="-4240.4385"><tspan
- x="6020.1929 6061.3198 6102.4473 5650.3433 5691.4707 5732.5981 5280.4941 5321.6216 5362.7485 4910.645 4951.7725 4992.8994 4540.7959 4581.9229 4623.0503 4170.9468 4212.0737 4253.2012 3801.0974 3842.2246 3883.3518 3449.7405 3490.8677 3531.9951 3061.3989 3102.5261 3143.6533 2691.5496 2732.677 2773.8042 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
- y="-4240.4385"
- sodipodi:role="line"
- id="tspan4089">336335321320319318317316315314313312311</tspan></text>
+ x="6020.1929 6061.3198 6102.4473 5650.3433 5691.4707 5732.5981 5280.4941 5321.6216 5362.7485 4910.645 4951.7725 4992.8994 4540.7959 4581.9229 4623.0503 4170.9468 4212.0737 4253.2012 3801.0974 3842.2246 3883.3518 3449.7405 3490.8677 3531.9951 3061.3989 3102.5261 3143.6533 2691.5496 2732.677 2773.8042 2321.7004 2362.8276 2403.9551 1951.8512 1992.9785 2034.1057 1582.0022 1623.1293 1664.2563"
+ y="-4240.4385"
+ sodipodi:role="line"
+ id="tspan4089">336335321320319318317316315314313312311</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text4091"
x="2732.6765 5321.6211 5670.9062 5712.0337 6040.7554 6081.8828 842.30634 883.43323 924.56055"
y="-4129.4834"><tspan
- x="2732.6765 5321.6211 5670.9062 5712.0337 6040.7554 6081.8828 842.30634 883.43323 924.56055"
- y="-4129.4834"
- sodipodi:role="line"
- id="tspan4093">182223309</tspan></text>
+ x="2732.6765 5321.6211 5670.9062 5712.0337 6040.7554 6081.8828 842.30634 883.43323 924.56055"
+ y="-4129.4834"
+ sodipodi:role="line"
+ id="tspan4093">182223309</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text4095"
x="842.30634 883.43323 924.56055"
y="-4240.4385"><tspan
- x="842.30634 883.43323 924.56055"
- y="-4240.4385"
- sodipodi:role="line"
- id="tspan4097">309</tspan></text>
+ x="842.30634 883.43323 924.56055"
+ y="-4240.4385"
+ sodipodi:role="line"
+ id="tspan4097">309</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text4099"
x="1212.1553 1253.2826 1294.4099"
y="-4129.4834"><tspan
- x="1212.1553 1253.2826 1294.4099"
- y="-4129.4834"
- sodipodi:role="line"
- id="tspan4101">310</tspan></text>
+ x="1212.1553 1253.2826 1294.4099"
+ y="-4129.4834"
+ sodipodi:role="line"
+ id="tspan4101">310</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text4103"
x="1212.1553 1253.2826 1294.4099"
y="-4240.4385"><tspan
- x="1212.1553 1253.2826 1294.4099"
- y="-4240.4385"
- sodipodi:role="line"
- id="tspan4105">310</tspan></text>
+ x="1212.1553 1253.2826 1294.4099"
+ y="-4240.4385"
+ sodipodi:role="line"
+ id="tspan4105">310</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text4107"
x="6410.605 6451.7319"
y="-4129.4834"><tspan
- x="6410.605 6451.7319"
- y="-4129.4834"
- sodipodi:role="line"
- id="tspan4109">24</tspan></text>
+ x="6410.605 6451.7319"
+ y="-4129.4834"
+ sodipodi:role="line"
+ id="tspan4109">24</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text4111"
x="6390.041 6431.1685 6472.2954"
y="-4240.4385"><tspan
- x="6390.041 6431.1685 6472.2954"
- y="-4240.4385"
- sodipodi:role="line"
- id="tspan4113">337</tspan></text>
+ x="6390.041 6431.1685 6472.2954"
+ y="-4240.4385"
+ sodipodi:role="line"
+ id="tspan4113">337</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text4115"
x="6040.7559 6081.8833"
y="-4943.1504"><tspan
- x="6040.7559 6081.8833"
- y="-4943.1504"
- sodipodi:role="line"
- id="tspan4117">23</tspan></text>
+ x="6040.7559 6081.8833"
+ y="-4943.1504"
+ sodipodi:role="line"
+ id="tspan4117">23</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text4119"
x="6040.7559 6081.8833"
y="-5054.106"><tspan
- x="6040.7559 6081.8833"
- y="-5054.106"
- sodipodi:role="line"
- id="tspan4121">23</tspan></text>
+ x="6040.7559 6081.8833"
+ y="-5054.106"
+ sodipodi:role="line"
+ id="tspan4121">23</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text4123"
x="6410.605 6451.7324"
y="-4943.1504"><tspan
- x="6410.605 6451.7324"
- y="-4943.1504"
- sodipodi:role="line"
- id="tspan4125">24</tspan></text>
+ x="6410.605 6451.7324"
+ y="-4943.1504"
+ sodipodi:role="line"
+ id="tspan4125">24</tspan></text>
<text
transform="scale(1,-1)"
style="font-variant:normal;font-weight:normal;font-size:73.96984863px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
id="text4127"
x="6410.605 6451.7324"
y="-5054.106"><tspan
- x="6410.605 6451.7324"
- y="-5054.106"
- sodipodi:role="line"
- id="tspan4129">24</tspan></text>
+ x="6410.605 6451.7324"
+ y="-5054.106"
+ sodipodi:role="line"
+ id="tspan4129">24</tspan></text>
</g></svg> \ No newline at end of file
diff --git a/Documentation/media/uapi/v4l/vbi_hsync.svg b/Documentation/media/uapi/v4l/vbi_hsync.svg
index 4d5c0b4f146e..e17ff8314e7b 100644
--- a/Documentation/media/uapi/v4l/vbi_hsync.svg
+++ b/Documentation/media/uapi/v4l/vbi_hsync.svg
@@ -42,27 +42,27 @@
fit-margin-right="0"
fit-margin-bottom="0" /><metadata
id="metadata8"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs6"><clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath30"><path
- d="m 0,0 0,1163 1544,0 L 1544,0 0,0 Z m 187.184,836.05 0,-19.278 48.517,0 -38.556,9.639 38.556,9.639 -48.517,0 z m 689.189,-19.278 0,19.278 -48.516,0 38.556,-9.639 -38.556,-9.639 48.516,0 z"
- id="path32"
- inkscape:connector-curvature="0"
- style="clip-rule:evenodd" /></clipPath><clipPath
+ d="m 0,0 0,1163 1544,0 L 1544,0 0,0 Z m 187.184,836.05 0,-19.278 48.517,0 -38.556,9.639 38.556,9.639 -48.517,0 z m 689.189,-19.278 0,19.278 -48.516,0 38.556,-9.639 -38.556,-9.639 48.516,0 z"
+ id="path32"
+ inkscape:connector-curvature="0"
+ style="clip-rule:evenodd" /></clipPath><clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath52"><path
- d="m 0,0 0,1163 1544,0 L 1544,0 0,0 Z m 804.08,79.3887 0,19.2778 -48.516,0 38.556,-9.6389 -38.556,-9.6389 48.516,0 z m -703.647,19.2778 0,-19.2778 48.517,0 -38.556,9.6389 38.556,9.6389 -48.517,0 z"
- id="path54"
- inkscape:connector-curvature="0"
- style="clip-rule:evenodd" /></clipPath><clipPath
+ d="m 0,0 0,1163 1544,0 L 1544,0 0,0 Z m 804.08,79.3887 0,19.2778 -48.516,0 38.556,-9.6389 -38.556,-9.6389 48.516,0 z m -703.647,19.2778 0,-19.2778 48.517,0 -38.556,9.6389 38.556,9.6389 -48.517,0 z"
+ id="path54"
+ inkscape:connector-curvature="0"
+ style="clip-rule:evenodd" /></clipPath><clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath94"><path
- d="m 0,0 0,1163 1544,0 L 1544,0 0,0 Z m 471.535,195.057 0,19.278 -48.516,0 38.555,-9.639 -38.555,-9.639 48.516,0 z m -284.351,19.278 0,-19.278 48.517,0 -38.556,9.639 38.556,9.639 -48.517,0 z"
- id="path96"
- inkscape:connector-curvature="0"
- style="clip-rule:evenodd" /></clipPath></defs><g
+ d="m 0,0 0,1163 1544,0 L 1544,0 0,0 Z m 471.535,195.057 0,19.278 -48.516,0 38.555,-9.639 -38.555,-9.639 48.516,0 z m -284.351,19.278 0,-19.278 48.517,0 -38.556,9.639 38.556,9.639 -48.517,0 z"
+ id="path96"
+ inkscape:connector-curvature="0"
+ style="clip-rule:evenodd" /></clipPath></defs><g
id="g10"
inkscape:groupmode="layer"
inkscape:label="vbi_hsync"
@@ -70,69 +70,69 @@
id="g14"
transform="matrix(0.36030235,0,0,0.36030235,-0.75498483,-1.0743684)"
style=""><path
- inkscape:connector-curvature="0"
- id="path16"
- style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="M 32.9604,580.617 4.04346,493.866" /><path
- inkscape:connector-curvature="0"
- id="path18"
- style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 192.004,855.328 0,-665.091" /><path
- inkscape:connector-curvature="0"
- id="path20"
- style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 466.715,392.656 0,-202.419" /><path
- inkscape:connector-curvature="0"
- id="path22"
- style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 799.261,508.324 0,-433.7549" /><path
- inkscape:connector-curvature="0"
- id="path24"
- style="fill:none;stroke:#000000;stroke-width:4.81949997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 857.095,537.241 231.335,0" /></g><g
+ inkscape:connector-curvature="0"
+ id="path16"
+ style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="M 32.9604,580.617 4.04346,493.866" /><path
+ inkscape:connector-curvature="0"
+ id="path18"
+ style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 192.004,855.328 0,-665.091" /><path
+ inkscape:connector-curvature="0"
+ id="path20"
+ style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 466.715,392.656 0,-202.419" /><path
+ inkscape:connector-curvature="0"
+ id="path22"
+ style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 799.261,508.324 0,-433.7549" /><path
+ inkscape:connector-curvature="0"
+ id="path24"
+ style="fill:none;stroke:#000000;stroke-width:4.81949997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 857.095,537.241 231.335,0" /></g><g
id="g26"
transform="matrix(0.36030235,0,0,0.36030235,-0.75498483,-1.0743684)"
style=""><g
- clip-path="url(#clipPath30)"
- id="g28"
- style=""><path
- inkscape:connector-curvature="0"
- id="path34"
- style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 871.553,826.411 -679.549,0" /></g></g><g
+ clip-path="url(#clipPath30)"
+ id="g28"
+ style=""><path
+ inkscape:connector-curvature="0"
+ id="path34"
+ style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 871.553,826.411 -679.549,0" /></g></g><g
id="g36"
transform="matrix(0.36030235,0,0,0.36030235,-0.75498483,-1.0743684)"
style=""><path
- inkscape:connector-curvature="0"
- id="path38"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 827.857,816.772 38.556,9.639 -38.556,9.639 0,-19.278" /><path
- inkscape:connector-curvature="0"
- id="path40"
- style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 827.857,816.772 38.556,9.639 -38.556,9.639 0,-19.278 z" /><path
- inkscape:connector-curvature="0"
- id="path42"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 235.701,836.05 -38.556,-9.639 38.556,-9.639 0,19.278" /><path
- inkscape:connector-curvature="0"
- id="path44"
- style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 235.701,836.05 -38.556,-9.639 38.556,-9.639 0,19.278 z" /><path
- inkscape:connector-curvature="0"
- id="path46"
- style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 1073.97,493.866 28.92,86.751" /></g><g
+ inkscape:connector-curvature="0"
+ id="path38"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 827.857,816.772 38.556,9.639 -38.556,9.639 0,-19.278" /><path
+ inkscape:connector-curvature="0"
+ id="path40"
+ style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 827.857,816.772 38.556,9.639 -38.556,9.639 0,-19.278 z" /><path
+ inkscape:connector-curvature="0"
+ id="path42"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 235.701,836.05 -38.556,-9.639 38.556,-9.639 0,19.278" /><path
+ inkscape:connector-curvature="0"
+ id="path44"
+ style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 235.701,836.05 -38.556,-9.639 38.556,-9.639 0,19.278 z" /><path
+ inkscape:connector-curvature="0"
+ id="path46"
+ style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 1073.97,493.866 28.92,86.751" /></g><g
id="g48"
transform="matrix(0.36030235,0,0,0.36030235,-0.75498483,-1.0743684)"
style=""><g
- clip-path="url(#clipPath52)"
- id="g50"
- style=""><path
- inkscape:connector-curvature="0"
- id="path56"
- style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 105.253,89.0276 694.008,0" /></g></g><path
+ clip-path="url(#clipPath52)"
+ id="g50"
+ style=""><path
+ inkscape:connector-curvature="0"
+ id="path56"
+ style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 105.253,89.0276 694.008,0" /></g></g><path
d="m 52.91205,34.475403 -13.891817,-3.472918 13.891817,-3.472918 0,6.945836"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="path60"
@@ -196,13 +196,13 @@
id="g90"
transform="matrix(0.36030235,0,0,0.36030235,-0.75498483,-1.0743684)"
style=""><g
- clip-path="url(#clipPath94)"
- id="g92"
- style=""><path
- inkscape:connector-curvature="0"
- id="path98"
- style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
- d="m 192.004,204.696 274.711,0" /></g></g><path
+ clip-path="url(#clipPath94)"
+ id="g92"
+ style=""><path
+ inkscape:connector-curvature="0"
+ id="path98"
+ style="fill:none;stroke:#000000;stroke-width:2.40974998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="m 192.004,204.696 274.711,0" /></g></g><path
d="m 84.168639,76.151036 -13.891817,-3.472955 13.891817,-3.472954 0,6.945909"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="path102"
@@ -224,90 +224,90 @@
transform="scale(1,-1)"
x="438.29504"
y="-187.28558"><tspan
- id="tspan114"
- sodipodi:role="line"
- y="-187.28558"
- x="438.29504 452.19382 456.81979 468.40555 478.82443 489.24329 495.03619 506.62195 518.2077 528.62659 540.21234">Black Level</tspan><tspan
- id="tspan116"
- sodipodi:role="line"
- y="-83.096947"
- x="438.29504 452.19382 462.61267 474.19846 484.61731 490.41019 501.99597 513.58173 524.00061 535.58636">Sync Level</tspan><tspan
- id="tspan118"
- sodipodi:role="line"
- y="-395.66284"
- x="438.29504 457.96585 469.55164 474.17761 479.97049 491.55627 497.34915 508.93494 520.52069 530.93958 542.52533">White Level</tspan></text>
+ id="tspan114"
+ sodipodi:role="line"
+ y="-187.28558"
+ x="438.29504 452.19382 456.81979 468.40555 478.82443 489.24329 495.03619 506.62195 518.2077 528.62659 540.21234">Black Level</tspan><tspan
+ id="tspan116"
+ sodipodi:role="line"
+ y="-83.096947"
+ x="438.29504 452.19382 462.61267 474.19846 484.61731 490.41019 501.99597 513.58173 524.00061 535.58636">Sync Level</tspan><tspan
+ id="tspan118"
+ sodipodi:role="line"
+ y="-395.66284"
+ x="438.29504 457.96585 469.55164 474.17761 479.97049 491.55627 497.34915 508.93494 520.52069 530.93958 542.52533">White Level</tspan></text>
<text
id="text120"
style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"
x="159.88258"
y="-270.63647"><tspan
- id="tspan122"
- sodipodi:role="line"
- y="-270.63647"
- x="159.88258 172.61443 179.55339 186.49236 198.07812 209.66391">offset</tspan></text>
+ id="tspan122"
+ sodipodi:role="line"
+ y="-270.63647"
+ x="159.88258 172.61443 179.55339 186.49236 198.07812 209.66391">offset</tspan></text>
<text
id="text124"
style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"
x="46.973549"
y="-46.630745"><tspan
- id="tspan126"
- sodipodi:role="line"
- y="-46.630745"
- x="46.973549 58.559322 63.185299 74.771072 86.35685 92.149734 102.5686 112.98746 124.57324 134.9921 146.57788 153.51685 159.30972 165.10262 176.68839 188.27417 192.90015 203.319">Line synchr. pulse</tspan><tspan
- id="tspan128"
- sodipodi:role="line"
- y="-4.9552913"
- x="100.80776 112.39354 117.01952 128.60529 140.19107 145.98395 157.56973 162.19569 173.78148 185.36726 195.78612 200.41209 211.99788">Line blanking</tspan></text>
+ id="tspan126"
+ sodipodi:role="line"
+ y="-46.630745"
+ x="46.973549 58.559322 63.185299 74.771072 86.35685 92.149734 102.5686 112.98746 124.57324 134.9921 146.57788 153.51685 159.30972 165.10262 176.68839 188.27417 192.90015 203.319">Line synchr. pulse</tspan><tspan
+ id="tspan128"
+ sodipodi:role="line"
+ y="-4.9552913"
+ x="100.80776 112.39354 117.01952 128.60529 140.19107 145.98395 157.56973 162.19569 173.78148 185.36726 195.78612 200.41209 211.99788">Line blanking</tspan></text>
<text
id="text3473"
style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"
x="46.973549 58.559322 63.185299 74.771072 86.35685 92.149734 102.5686 112.98746 124.57324 134.9921 146.57788 153.51685 159.30972 165.10262 176.68839 188.27417 192.90015 203.319"
y="-46.630745"><tspan
- id="tspan3475"
- sodipodi:role="line"
- y="-46.630745"
- x="46.973549 58.559322 63.185299 74.771072 86.35685 92.149734 102.5686 112.98746 124.57324 134.9921 146.57788 153.51685 159.30972 165.10262 176.68839 188.27417 192.90015 203.319">Line synchr. pulse</tspan></text>
+ id="tspan3475"
+ sodipodi:role="line"
+ y="-46.630745"
+ x="46.973549 58.559322 63.185299 74.771072 86.35685 92.149734 102.5686 112.98746 124.57324 134.9921 146.57788 153.51685 159.30972 165.10262 176.68839 188.27417 192.90015 203.319">Line synchr. pulse</tspan></text>
<text
id="text3477"
style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"
x="100.80776 112.39354 117.01952 128.60529 140.19107 145.98395 157.56973 162.19569 173.78148 185.36726 195.78612 200.41209 211.99788"
y="-4.9552913"><tspan
- id="tspan3479"
- sodipodi:role="line"
- y="-4.9552913"
- x="100.80776 112.39354 117.01952 128.60529 140.19107 145.98395 157.56973 162.19569 173.78148 185.36726 195.78612 200.41209 211.99788">Line blanking</tspan></text>
+ id="tspan3479"
+ sodipodi:role="line"
+ y="-4.9552913"
+ x="100.80776 112.39354 117.01952 128.60529 140.19107 145.98395 157.56973 162.19569 173.78148 185.36726 195.78612 200.41209 211.99788">Line blanking</tspan></text>
<text
id="text3607"
style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"
x="438.29504 452.19382 456.81979 468.40555 478.82443 489.24329 495.03619 506.62195 518.2077 528.62659 540.21234"
y="-187.28558"><tspan
- id="tspan3609"
- sodipodi:role="line"
- y="-187.28558"
- x="438.29504 452.19382 456.81979 468.40555 478.82443 489.24329 495.03619 506.62195 518.2077 528.62659 540.21234">Black Level</tspan></text>
+ id="tspan3609"
+ sodipodi:role="line"
+ y="-187.28558"
+ x="438.29504 452.19382 456.81979 468.40555 478.82443 489.24329 495.03619 506.62195 518.2077 528.62659 540.21234">Black Level</tspan></text>
<text
id="text3611"
style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"
x="438.29504 452.19382 462.61267 474.19846 484.61731 490.41019 501.99597 513.58173 524.00061 535.58636"
y="-83.096947"><tspan
- id="tspan3613"
- sodipodi:role="line"
- y="-83.096947"
- x="438.29504 452.19382 462.61267 474.19846 484.61731 490.41019 501.99597 513.58173 524.00061 535.58636">Sync Level</tspan></text>
+ id="tspan3613"
+ sodipodi:role="line"
+ y="-83.096947"
+ x="438.29504 452.19382 462.61267 474.19846 484.61731 490.41019 501.99597 513.58173 524.00061 535.58636">Sync Level</tspan></text>
<text
id="text3615"
style="font-variant:normal;font-weight:normal;font-size:20.83772659px;font-family:sans-serif;-inkscape-font-specification:sans-serif;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-style:normal;font-stretch:normal;"
transform="scale(1,-1)"
x="438.29504 457.96585 469.55164 474.17761 479.97049 491.55627 497.34915 508.93494 520.52069 530.93958 542.52533"
y="-395.66284"><tspan
- id="tspan3617"
- sodipodi:role="line"
- y="-395.66284"
- x="438.29504 457.96585 469.55164 474.17761 479.97049 491.55627 497.34915 508.93494 520.52069 530.93958 542.52533">White Level</tspan></text>
+ id="tspan3617"
+ sodipodi:role="line"
+ y="-395.66284"
+ x="438.29504 457.96585 469.55164 474.17761 479.97049 491.55627 497.34915 508.93494 520.52069 530.93958 542.52533">White Level</tspan></text>
</g></svg> \ No newline at end of file
diff --git a/Documentation/media/uapi/v4l/vidioc-g-fmt.rst b/Documentation/media/uapi/v4l/vidioc-g-fmt.rst
index b853e48312e2..d082f9a21548 100644
--- a/Documentation/media/uapi/v4l/vidioc-g-fmt.rst
+++ b/Documentation/media/uapi/v4l/vidioc-g-fmt.rst
@@ -147,3 +147,9 @@ appropriately. The generic error codes are described at the
EINVAL
The struct :c:type:`v4l2_format` ``type`` field is
invalid or the requested buffer type not supported.
+
+EBUSY
+ The device is busy and cannot change the format. This could be
+ because or the device is streaming or buffers are allocated or
+ queued to the driver. Relevant for :ref:`VIDIOC_S_FMT
+ <VIDIOC_G_FMT>` only.
diff --git a/Documentation/media/v4l-drivers/imx.rst b/Documentation/media/v4l-drivers/imx.rst
index e0ee0f1aeb05..3c4f58bda178 100644
--- a/Documentation/media/v4l-drivers/imx.rst
+++ b/Documentation/media/v4l-drivers/imx.rst
@@ -607,8 +607,9 @@ References
Authors
-------
-Steve Longerbeam <steve_longerbeam@mentor.com>
-Philipp Zabel <kernel@pengutronix.de>
-Russell King <linux@armlinux.org.uk>
+
+- Steve Longerbeam <steve_longerbeam@mentor.com>
+- Philipp Zabel <kernel@pengutronix.de>
+- Russell King <linux@armlinux.org.uk>
Copyright (C) 2012-2017 Mentor Graphics Inc.
diff --git a/Documentation/media/v4l-drivers/index.rst b/Documentation/media/v4l-drivers/index.rst
index 2e24d6806052..10f2ce42ece2 100644
--- a/Documentation/media/v4l-drivers/index.rst
+++ b/Documentation/media/v4l-drivers/index.rst
@@ -41,6 +41,7 @@ For more details see the file COPYING in the source distribution of Linux.
cx88
davinci-vpbe
fimc
+ imx
ivtv
max2175
meye
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt
index 0fde3dcf077a..625549d4c74a 100644
--- a/Documentation/power/runtime_pm.txt
+++ b/Documentation/power/runtime_pm.txt
@@ -435,7 +435,8 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
PM status to 'suspended' and update its parent's counter of 'active'
children as appropriate (it is only valid to use this function if
'power.runtime_error' is set or 'power.disable_depth' is greater than
- zero)
+ zero); it will fail and return an error code if the device has a child
+ which is active and the 'power.ignore_children' flag is unset
bool pm_runtime_active(struct device *dev);
- return true if the device's runtime PM status is 'active' or its
diff --git a/MAINTAINERS b/MAINTAINERS
index 205d3977ac46..b1387edcca2f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -205,7 +205,6 @@ F: include/net/9p/
F: include/uapi/linux/virtio_9p.h
F: include/trace/events/9p.h
-
A8293 MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
@@ -492,13 +491,6 @@ S: Maintained
F: Documentation/hwmon/adt7475
F: drivers/hwmon/adt7475.c
-ADXL34X THREE-AXIS DIGITAL ACCELEROMETER DRIVER (ADXL345/ADXL346)
-M: Michael Hennerich <michael.hennerich@analog.com>
-W: http://wiki.analog.com/ADXL345
-W: http://ez.analog.com/community/linux-device-drivers
-S: Supported
-F: drivers/input/misc/adxl34x.c
-
ADVANSYS SCSI DRIVER
M: Matthew Wilcox <matthew@wil.cx>
M: Hannes Reinecke <hare@suse.com>
@@ -507,6 +499,13 @@ S: Maintained
F: Documentation/scsi/advansys.txt
F: drivers/scsi/advansys.c
+ADXL34X THREE-AXIS DIGITAL ACCELEROMETER DRIVER (ADXL345/ADXL346)
+M: Michael Hennerich <michael.hennerich@analog.com>
+W: http://wiki.analog.com/ADXL345
+W: http://ez.analog.com/community/linux-device-drivers
+S: Supported
+F: drivers/input/misc/adxl34x.c
+
AEDSP16 DRIVER
M: Riccardo Facchetti <fizban@tin.it>
S: Maintained
@@ -808,6 +807,12 @@ W: http://blackfin.uclinux.org/
S: Supported
F: sound/soc/blackfin/*
+ANALOG DEVICES INC DMA DRIVERS
+M: Lars-Peter Clausen <lars@metafoo.de>
+W: http://ez.analog.com/community/linux-device-drivers
+S: Supported
+F: drivers/dma/dma-axi-dmac.c
+
ANALOG DEVICES INC IIO DRIVERS
M: Lars-Peter Clausen <lars@metafoo.de>
M: Michael Hennerich <Michael.Hennerich@analog.com>
@@ -820,12 +825,6 @@ X: drivers/iio/*/adjd*
F: drivers/staging/iio/*/ad*
F: drivers/staging/iio/trigger/iio-trig-bfin-timer.c
-ANALOG DEVICES INC DMA DRIVERS
-M: Lars-Peter Clausen <lars@metafoo.de>
-W: http://ez.analog.com/community/linux-device-drivers
-S: Supported
-F: drivers/dma/dma-axi-dmac.c
-
ANDROID CONFIG FRAGMENTS
M: Rob Herring <robh@kernel.org>
S: Supported
@@ -872,6 +871,15 @@ F: include/linux/apm_bios.h
F: include/uapi/linux/apm_bios.h
F: drivers/char/apm-emulation.c
+APPARMOR SECURITY MODULE
+M: John Johansen <john.johansen@canonical.com>
+L: apparmor@lists.ubuntu.com (subscribers-only, general discussion)
+W: apparmor.wiki.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jj/apparmor-dev.git
+S: Supported
+F: security/apparmor/
+F: Documentation/admin-guide/LSM/apparmor.rst
+
APPLE BCM5974 MULTITOUCH DRIVER
M: Henrik Rydberg <rydberg@bitmath.org>
L: linux-input@vger.kernel.org
@@ -895,6 +903,18 @@ M: Duc Dang <dhdang@apm.com>
S: Supported
F: arch/arm64/boot/dts/apm/
+APPLIED MICRO (APM) X-GENE SOC EDAC
+M: Loc Ho <lho@apm.com>
+S: Supported
+F: drivers/edac/xgene_edac.c
+F: Documentation/devicetree/bindings/edac/apm-xgene-edac.txt
+
+APPLIED MICRO (APM) X-GENE SOC ETHERNET (V2) DRIVER
+M: Iyappan Subramanian <isubramanian@apm.com>
+M: Keyur Chudgar <kchudgar@apm.com>
+S: Supported
+F: drivers/net/ethernet/apm/xgene-v2/
+
APPLIED MICRO (APM) X-GENE SOC ETHERNET DRIVER
M: Iyappan Subramanian <isubramanian@apm.com>
M: Keyur Chudgar <kchudgar@apm.com>
@@ -905,12 +925,6 @@ F: drivers/net/phy/mdio-xgene.c
F: Documentation/devicetree/bindings/net/apm-xgene-enet.txt
F: Documentation/devicetree/bindings/net/apm-xgene-mdio.txt
-APPLIED MICRO (APM) X-GENE SOC ETHERNET (V2) DRIVER
-M: Iyappan Subramanian <isubramanian@apm.com>
-M: Keyur Chudgar <kchudgar@apm.com>
-S: Supported
-F: drivers/net/ethernet/apm/xgene-v2/
-
APPLIED MICRO (APM) X-GENE SOC PMU
M: Tai Nguyen <ttnguyen@apm.com>
S: Supported
@@ -930,6 +944,12 @@ S: Maintained
F: drivers/video/fbdev/arcfb.c
F: drivers/video/fbdev/core/fb_defio.c
+ARC PGU DRM DRIVER
+M: Alexey Brodkin <abrodkin@synopsys.com>
+S: Supported
+F: drivers/gpu/drm/arc/
+F: Documentation/devicetree/bindings/display/snps,arcpgu.txt
+
ARCNET NETWORK LAYER
M: Michael Grzeschik <m.grzeschik@pengutronix.de>
L: netdev@vger.kernel.org
@@ -937,12 +957,6 @@ S: Maintained
F: drivers/net/arcnet/
F: include/uapi/linux/if_arcnet.h
-ARC PGU DRM DRIVER
-M: Alexey Brodkin <abrodkin@synopsys.com>
-S: Supported
-F: drivers/gpu/drm/arc/
-F: Documentation/devicetree/bindings/display/snps,arcpgu.txt
-
ARM ARCHITECTED TIMER DRIVER
M: Mark Rutland <mark.rutland@arm.com>
M: Marc Zyngier <marc.zyngier@arm.com>
@@ -995,18 +1009,17 @@ S: Maintained
T: git git://git.armlinux.org.uk/~rmk/linux-arm.git
F: arch/arm/
-ARM SUB-ARCHITECTURES
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-F: arch/arm/mach-*/
-F: arch/arm/plat-*/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git
-
ARM PRIMECELL AACI PL041 DRIVER
M: Russell King <linux@armlinux.org.uk>
S: Maintained
F: sound/arm/aaci.*
+ARM PRIMECELL BUS SUPPORT
+M: Russell King <linux@armlinux.org.uk>
+S: Maintained
+F: drivers/amba/
+F: include/linux/amba/bus.h
+
ARM PRIMECELL CLCD PL110 DRIVER
M: Russell King <linux@armlinux.org.uk>
S: Maintained
@@ -1030,11 +1043,22 @@ S: Maintained
F: drivers/tty/serial/amba-pl01*.c
F: include/linux/amba/serial.h
-ARM PRIMECELL BUS SUPPORT
-M: Russell King <linux@armlinux.org.uk>
+ARM SMMU DRIVERS
+M: Will Deacon <will.deacon@arm.com>
+R: Robin Murphy <robin.murphy@arm.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
-F: drivers/amba/
-F: include/linux/amba/bus.h
+F: drivers/iommu/arm-smmu.c
+F: drivers/iommu/arm-smmu-v3.c
+F: drivers/iommu/io-pgtable-arm.c
+F: drivers/iommu/io-pgtable-arm-v7s.c
+
+ARM SUB-ARCHITECTURES
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: arch/arm/mach-*/
+F: arch/arm/plat-*/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git
ARM/ACTIONS SEMI ARCHITECTURE
M: Andreas Färber <afaerber@suse.de>
@@ -1067,6 +1091,11 @@ M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
+ARM/Allwinner SoC Clock Support
+M: Emilio López <emilio@elopez.com.ar>
+S: Maintained
+F: drivers/clk/sunxi/
+
ARM/Allwinner sunXi SoC support
M: Maxime Ripard <maxime.ripard@free-electrons.com>
M: Chen-Yu Tsai <wens@csie.org>
@@ -1081,10 +1110,15 @@ F: drivers/pinctrl/sunxi/
F: drivers/soc/sunxi/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git
-ARM/Allwinner SoC Clock Support
-M: Emilio López <emilio@elopez.com.ar>
+ARM/Amlogic Meson SoC CLOCK FRAMEWORK
+M: Neil Armstrong <narmstrong@baylibre.com>
+M: Jerome Brunet <jbrunet@baylibre.com>
+L: linux-amlogic@lists.infradead.org
S: Maintained
-F: drivers/clk/sunxi/
+F: drivers/clk/meson/
+F: include/dt-bindings/clock/meson*
+F: include/dt-bindings/clock/gxbb*
+F: Documentation/devicetree/bindings/clock/amlogic*
ARM/Amlogic Meson SoC support
M: Carlo Caione <carlo@caione.org>
@@ -1096,20 +1130,10 @@ S: Maintained
F: arch/arm/mach-meson/
F: arch/arm/boot/dts/meson*
F: arch/arm64/boot/dts/amlogic/
-F: drivers/pinctrl/meson/
+F: drivers/pinctrl/meson/
F: drivers/mmc/host/meson*
N: meson
-ARM/Amlogic Meson SoC CLOCK FRAMEWORK
-M: Neil Armstrong <narmstrong@baylibre.com>
-M: Jerome Brunet <jbrunet@baylibre.com>
-L: linux-amlogic@lists.infradead.org
-S: Maintained
-F: drivers/clk/meson/
-F: include/dt-bindings/clock/meson*
-F: include/dt-bindings/clock/gxbb*
-F: Documentation/devicetree/bindings/clock/amlogic*
-
ARM/Annapurna Labs ALPINE ARCHITECTURE
M: Tsahee Zidenberg <tsahee@annapurnalabs.com>
M: Antoine Tenart <antoine.tenart@free-electrons.com>
@@ -1132,25 +1156,30 @@ F: drivers/clk/axis
F: drivers/pinctrl/pinctrl-artpec*
F: Documentation/devicetree/bindings/pinctrl/axis,artpec6-pinctrl.txt
-ARM/ASPEED MACHINE SUPPORT
-M: Joel Stanley <joel@jms.id.au>
-S: Maintained
-F: arch/arm/mach-aspeed/
-F: arch/arm/boot/dts/aspeed-*
-F: drivers/*/*aspeed*
-
ARM/ASPEED I2C DRIVER
M: Brendan Higgins <brendanhiggins@google.com>
R: Benjamin Herrenschmidt <benh@kernel.crashing.org>
R: Joel Stanley <joel@jms.id.au>
L: linux-i2c@vger.kernel.org
-L: openbmc@lists.ozlabs.org
+L: openbmc@lists.ozlabs.org (moderated for non-subscribers)
S: Maintained
F: drivers/irqchip/irq-aspeed-i2c-ic.c
F: drivers/i2c/busses/i2c-aspeed.c
F: Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2400-i2c-ic.txt
F: Documentation/devicetree/bindings/i2c/i2c-aspeed.txt
+ARM/ASPEED MACHINE SUPPORT
+M: Joel Stanley <joel@jms.id.au>
+S: Maintained
+F: arch/arm/mach-aspeed/
+F: arch/arm/boot/dts/aspeed-*
+F: drivers/*/*aspeed*
+
+ARM/ATMEL AT91 Clock Support
+M: Boris Brezillon <boris.brezillon@free-electrons.com>
+S: Maintained
+F: drivers/clk/at91
+
ARM/ATMEL AT91RM9200, AT91SAM9 AND SAMA5 SOC SUPPORT
M: Nicolas Ferre <nicolas.ferre@microchip.com>
M: Alexandre Belloni <alexandre.belloni@free-electrons.com>
@@ -1167,11 +1196,6 @@ F: arch/arm/boot/dts/sama*.dtsi
F: arch/arm/include/debug/at91.S
F: drivers/memory/atmel*
-ARM/ATMEL AT91 Clock Support
-M: Boris Brezillon <boris.brezillon@free-electrons.com>
-S: Maintained
-F: drivers/clk/at91
-
ARM/CALXEDA HIGHBANK ARCHITECTURE
M: Rob Herring <robh@kernel.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1198,6 +1222,11 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Odd Fixes
N: clps711x
+ARM/CIRRUS LOGIC EDB9315A MACHINE SUPPORT
+M: Lennert Buytenhek <kernel@wantstofly.org>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+
ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE
M: Hartley Sweeten <hsweeten@visionengravers.com>
M: Alexander Sverdlin <alexander.sverdlin@gmail.com>
@@ -1206,11 +1235,6 @@ S: Maintained
F: arch/arm/mach-ep93xx/
F: arch/arm/mach-ep93xx/include/mach/
-ARM/CIRRUS LOGIC EDB9315A MACHINE SUPPORT
-M: Lennert Buytenhek <kernel@wantstofly.org>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-
ARM/CLKDEV SUPPORT
M: Russell King <linux@armlinux.org.uk>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1224,6 +1248,13 @@ M: Mike Rapoport <mike@compulab.co.il>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
+ARM/CONEXANT DIGICOLOR MACHINE SUPPORT
+M: Baruch Siach <baruch@tkos.co.il>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: arch/arm/boot/dts/cx92755*
+N: digicolor
+
ARM/CONTEC MICRO9 MACHINE SUPPORT
M: Hubert Feurstein <hubert.feurstein@contec.at>
S: Maintained
@@ -1269,13 +1300,6 @@ F: drivers/clocksource/timer-prima2.c
F: drivers/clocksource/timer-atlas7.c
N: [^a-z]sirf
-ARM/CONEXANT DIGICOLOR MACHINE SUPPORT
-M: Baruch Siach <baruch@tkos.co.il>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-F: arch/arm/boot/dts/cx92755*
-N: digicolor
-
ARM/EBSA110 MACHINE SUPPORT
M: Russell King <linux@armlinux.org.uk>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1389,6 +1413,11 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-pxa/colibri-pxa270-income.c
+ARM/INTEL IOP13XX ARM ARCHITECTURE
+M: Lennert Buytenhek <kernel@wantstofly.org>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+
ARM/INTEL IOP32X ARM ARCHITECTURE
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1398,11 +1427,6 @@ ARM/INTEL IOP33X ARM ARCHITECTURE
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Orphan
-ARM/INTEL IOP13XX ARM ARCHITECTURE
-M: Lennert Buytenhek <kernel@wantstofly.org>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-
ARM/INTEL IQ81342EX MACHINE SUPPORT
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1437,39 +1461,6 @@ M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
-ARM/TEXAS INSTRUMENT KEYSTONE ARCHITECTURE
-M: Santosh Shilimkar <ssantosh@kernel.org>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-F: arch/arm/mach-keystone/
-F: arch/arm/boot/dts/keystone-*
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git
-
-ARM/TEXAS INSTRUMENT KEYSTONE CLOCK FRAMEWORK
-M: Santosh Shilimkar <ssantosh@kernel.org>
-L: linux-kernel@vger.kernel.org
-S: Maintained
-F: drivers/clk/keystone/
-
-ARM/TEXAS INSTRUMENT KEYSTONE ClOCKSOURCE
-M: Santosh Shilimkar <ssantosh@kernel.org>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-L: linux-kernel@vger.kernel.org
-S: Maintained
-F: drivers/clocksource/timer-keystone.c
-
-ARM/TEXAS INSTRUMENT KEYSTONE RESET DRIVER
-M: Santosh Shilimkar <ssantosh@kernel.org>
-L: linux-kernel@vger.kernel.org
-S: Maintained
-F: drivers/power/reset/keystone-reset.c
-
-ARM/TEXAS INSTRUMENT AEMIF/EMIF DRIVERS
-M: Santosh Shilimkar <ssantosh@kernel.org>
-L: linux-kernel@vger.kernel.org
-S: Maintained
-F: drivers/memory/*emif*
-
ARM/LG1K ARCHITECTURE
M: Chanho Min <chanho.min@lge.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1512,24 +1503,6 @@ ARM/MAGICIAN MACHINE SUPPORT
M: Philipp Zabel <philipp.zabel@gmail.com>
S: Maintained
-ARM/Marvell Kirkwood and Armada 370, 375, 38x, 39x, XP, 3700, 7K/8K SOC support
-M: Jason Cooper <jason@lakedaemon.net>
-M: Andrew Lunn <andrew@lunn.ch>
-M: Gregory Clement <gregory.clement@free-electrons.com>
-M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-F: arch/arm/boot/dts/armada*
-F: arch/arm/boot/dts/kirkwood*
-F: arch/arm/configs/mvebu_*_defconfig
-F: arch/arm/mach-mvebu/
-F: arch/arm64/boot/dts/marvell/armada*
-F: drivers/cpufreq/mvebu-cpufreq.c
-F: drivers/irqchip/irq-armada-370-xp.c
-F: drivers/irqchip/irq-mvebu-*
-F: drivers/pinctrl/mvebu/
-F: drivers/rtc/rtc-armada38x.c
-
ARM/Marvell Berlin SoC support
M: Jisheng Zhang <jszhang@marvell.com>
M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
@@ -1539,7 +1512,6 @@ F: arch/arm/mach-berlin/
F: arch/arm/boot/dts/berlin*
F: arch/arm64/boot/dts/marvell/berlin*
-
ARM/Marvell Dove/MV78xx0/Orion SOC support
M: Jason Cooper <jason@lakedaemon.net>
M: Andrew Lunn <andrew@lunn.ch>
@@ -1555,24 +1527,23 @@ F: arch/arm/plat-orion/
F: arch/arm/boot/dts/dove*
F: arch/arm/boot/dts/orion5x*
-
-ARM/Orion SoC/Technologic Systems TS-78xx platform support
-M: Alexander Clouter <alex@digriz.org.uk>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-W: http://www.digriz.org.uk/ts78xx/kernel
-S: Maintained
-F: arch/arm/mach-orion5x/ts78xx-*
-
-ARM/OXNAS platform support
-M: Neil Armstrong <narmstrong@baylibre.com>
+ARM/Marvell Kirkwood and Armada 370, 375, 38x, 39x, XP, 3700, 7K/8K SOC support
+M: Jason Cooper <jason@lakedaemon.net>
+M: Andrew Lunn <andrew@lunn.ch>
+M: Gregory Clement <gregory.clement@free-electrons.com>
+M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-L: linux-oxnas@lists.tuxfamily.org (moderated for non-subscribers)
S: Maintained
-F: arch/arm/mach-oxnas/
-F: arch/arm/boot/dts/ox8*.dtsi
-F: arch/arm/boot/dts/wd-mbwe.dts
-F: arch/arm/boot/dts/cloudengines-pogoplug-series-3.dts
-N: oxnas
+F: arch/arm/boot/dts/armada*
+F: arch/arm/boot/dts/kirkwood*
+F: arch/arm/configs/mvebu_*_defconfig
+F: arch/arm/mach-mvebu/
+F: arch/arm64/boot/dts/marvell/armada*
+F: drivers/cpufreq/mvebu-cpufreq.c
+F: drivers/irqchip/irq-armada-370-xp.c
+F: drivers/irqchip/irq-mvebu-*
+F: drivers/pinctrl/mvebu/
+F: drivers/rtc/rtc-armada38x.c
ARM/Mediatek RTC DRIVER
M: Eddie Huang <eddie.huang@mediatek.com>
@@ -1627,16 +1598,53 @@ F: drivers/pinctrl/nomadik/
F: drivers/i2c/busses/i2c-nomadik.c
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
+ARM/NUVOTON W90X900 ARM ARCHITECTURE
+M: Wan ZongShun <mcuos.com@gmail.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+W: http://www.mcuos.com
+S: Maintained
+F: arch/arm/mach-w90x900/
+F: drivers/input/keyboard/w90p910_keypad.c
+F: drivers/input/touchscreen/w90p910_ts.c
+F: drivers/watchdog/nuc900_wdt.c
+F: drivers/net/ethernet/nuvoton/w90p910_ether.c
+F: drivers/mtd/nand/nuc900_nand.c
+F: drivers/rtc/rtc-nuc900.c
+F: drivers/spi/spi-nuc900.c
+F: drivers/usb/host/ehci-w90x900.c
+F: drivers/video/fbdev/nuc900fb.c
+
ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT
M: Nelson Castillo <arhuaco@freaks-unidos.net>
L: openmoko-kernel@lists.openmoko.org (subscribers-only)
W: http://wiki.openmoko.org/wiki/Neo_FreeRunner
S: Supported
-ARM/TOSA MACHINE SUPPORT
-M: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
-M: Dirk Opfer <dirk@opfer-online.de>
+ARM/Orion SoC/Technologic Systems TS-78xx platform support
+M: Alexander Clouter <alex@digriz.org.uk>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+W: http://www.digriz.org.uk/ts78xx/kernel
+S: Maintained
+F: arch/arm/mach-orion5x/ts78xx-*
+
+ARM/OXNAS platform support
+M: Neil Armstrong <narmstrong@baylibre.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L: linux-oxnas@lists.tuxfamily.org (moderated for non-subscribers)
S: Maintained
+F: arch/arm/mach-oxnas/
+F: arch/arm/boot/dts/ox8*.dtsi
+F: arch/arm/boot/dts/wd-mbwe.dts
+F: arch/arm/boot/dts/cloudengines-pogoplug-series-3.dts
+N: oxnas
+
+ARM/PALM TREO SUPPORT
+M: Tomas Cech <sleep_walker@suse.com>
+L: linux-arm-kernel@lists.infradead.org
+W: http://hackndev.com
+S: Maintained
+F: arch/arm/mach-pxa/include/mach/palmtreo.h
+F: arch/arm/mach-pxa/palmtreo.c
ARM/PALMTX,PALMT5,PALMLD,PALMTE2,PALMTC SUPPORT
M: Marek Vasut <marek.vasut@gmail.com>
@@ -1654,14 +1662,6 @@ F: arch/arm/mach-pxa/palmte2.c
F: arch/arm/mach-pxa/include/mach/palmtc.h
F: arch/arm/mach-pxa/palmtc.c
-ARM/PALM TREO SUPPORT
-M: Tomas Cech <sleep_walker@suse.com>
-L: linux-arm-kernel@lists.infradead.org
-W: http://hackndev.com
-S: Maintained
-F: arch/arm/mach-pxa/include/mach/palmtreo.h
-F: arch/arm/mach-pxa/palmtreo.c
-
ARM/PALMZ72 SUPPORT
M: Sergey Lapin <slapin@ossfans.org>
L: linux-arm-kernel@lists.infradead.org
@@ -1802,17 +1802,6 @@ L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/platform/s5p-g2d/
-ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT
-M: Kyungmin Park <kyungmin.park@samsung.com>
-M: Kamil Debski <kamil@wypas.org>
-M: Jeongtae Park <jtp.park@samsung.com>
-M: Andrzej Hajda <a.hajda@samsung.com>
-L: linux-arm-kernel@lists.infradead.org
-L: linux-media@vger.kernel.org
-S: Maintained
-F: arch/arm/plat-samsung/s5p-dev-mfc.c
-F: drivers/media/platform/s5p-mfc/
-
ARM/SAMSUNG S5P SERIES HDMI CEC SUBSYSTEM SUPPORT
M: Marek Szyprowski <m.szyprowski@samsung.com>
L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
@@ -1829,6 +1818,17 @@ L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/platform/s5p-jpeg/
+ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT
+M: Kyungmin Park <kyungmin.park@samsung.com>
+M: Kamil Debski <kamil@wypas.org>
+M: Jeongtae Park <jtp.park@samsung.com>
+M: Andrzej Hajda <a.hajda@samsung.com>
+L: linux-arm-kernel@lists.infradead.org
+L: linux-media@vger.kernel.org
+S: Maintained
+F: arch/arm/plat-samsung/s5p-dev-mfc.c
+F: drivers/media/platform/s5p-mfc/
+
ARM/SHMOBILE ARM ARCHITECTURE
M: Simon Horman <horms@verge.net.au>
M: Magnus Damm <magnus.damm@gmail.com>
@@ -1922,26 +1922,48 @@ M: "Mark F. Brown" <mark.brown314@gmail.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
+ARM/TEXAS INSTRUMENT AEMIF/EMIF DRIVERS
+M: Santosh Shilimkar <ssantosh@kernel.org>
+L: linux-kernel@vger.kernel.org
+S: Maintained
+F: drivers/memory/*emif*
+
+ARM/TEXAS INSTRUMENT KEYSTONE ARCHITECTURE
+M: Santosh Shilimkar <ssantosh@kernel.org>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: arch/arm/mach-keystone/
+F: arch/arm/boot/dts/keystone-*
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git
+
+ARM/TEXAS INSTRUMENT KEYSTONE CLOCK FRAMEWORK
+M: Santosh Shilimkar <ssantosh@kernel.org>
+L: linux-kernel@vger.kernel.org
+S: Maintained
+F: drivers/clk/keystone/
+
+ARM/TEXAS INSTRUMENT KEYSTONE ClOCKSOURCE
+M: Santosh Shilimkar <ssantosh@kernel.org>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L: linux-kernel@vger.kernel.org
+S: Maintained
+F: drivers/clocksource/timer-keystone.c
+
+ARM/TEXAS INSTRUMENT KEYSTONE RESET DRIVER
+M: Santosh Shilimkar <ssantosh@kernel.org>
+L: linux-kernel@vger.kernel.org
+S: Maintained
+F: drivers/power/reset/keystone-reset.c
+
ARM/THECUS N2100 MACHINE SUPPORT
M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
-ARM/NUVOTON W90X900 ARM ARCHITECTURE
-M: Wan ZongShun <mcuos.com@gmail.com>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-W: http://www.mcuos.com
+ARM/TOSA MACHINE SUPPORT
+M: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+M: Dirk Opfer <dirk@opfer-online.de>
S: Maintained
-F: arch/arm/mach-w90x900/
-F: drivers/input/keyboard/w90p910_keypad.c
-F: drivers/input/touchscreen/w90p910_ts.c
-F: drivers/watchdog/nuc900_wdt.c
-F: drivers/net/ethernet/nuvoton/w90p910_ether.c
-F: drivers/mtd/nand/nuc900_nand.c
-F: drivers/rtc/rtc-nuc900.c
-F: drivers/spi/spi-nuc900.c
-F: drivers/usb/host/ehci-w90x900.c
-F: drivers/video/fbdev/nuc900fb.c
ARM/U300 MACHINE SUPPORT
M: Linus Walleij <linus.walleij@linaro.org>
@@ -2086,16 +2108,6 @@ F: drivers/i2c/busses/i2c-cadence.c
F: drivers/mmc/host/sdhci-of-arasan.c
F: drivers/edac/synopsys_edac.c
-ARM SMMU DRIVERS
-M: Will Deacon <will.deacon@arm.com>
-R: Robin Murphy <robin.murphy@arm.com>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-F: drivers/iommu/arm-smmu.c
-F: drivers/iommu/arm-smmu-v3.c
-F: drivers/iommu/io-pgtable-arm.c
-F: drivers/iommu/io-pgtable-arm-v7s.c
-
ARM64 PORT (AARCH64 ARCHITECTURE)
M: Catalin Marinas <catalin.marinas@arm.com>
M: Will Deacon <will.deacon@arm.com>
@@ -2207,21 +2219,10 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
S: Supported
F: drivers/net/wireless/ath/ath6kl/
-WILOCITY WIL6210 WIRELESS DRIVER
-M: Maya Erez <qca_merez@qca.qualcomm.com>
-L: linux-wireless@vger.kernel.org
-L: wil6210@qca.qualcomm.com
-S: Supported
-W: http://wireless.kernel.org/en/users/Drivers/wil6210
-F: drivers/net/wireless/ath/wil6210/
-F: include/uapi/linux/wil6210_uapi.h
-
-CARL9170 LINUX COMMUNITY WIRELESS DRIVER
-M: Christian Lamparter <chunkeey@googlemail.com>
-L: linux-wireless@vger.kernel.org
-W: http://wireless.kernel.org/en/users/Drivers/carl9170
+ATI_REMOTE2 DRIVER
+M: Ville Syrjala <syrjala@sci.fi>
S: Maintained
-F: drivers/net/wireless/ath/carl9170/
+F: drivers/input/misc/ati_remote2.c
ATK0110 HWMON DRIVER
M: Luca Tettamanti <kronos.it@gmail.com>
@@ -2229,11 +2230,6 @@ L: linux-hwmon@vger.kernel.org
S: Maintained
F: drivers/hwmon/asus_atk0110.c
-ATI_REMOTE2 DRIVER
-M: Ville Syrjala <syrjala@sci.fi>
-S: Maintained
-F: drivers/input/misc/ati_remote2.c
-
ATLX ETHERNET DRIVERS
M: Jay Cliburn <jcliburn@gmail.com>
M: Chris Snook <chris.snook@gmail.com>
@@ -2263,25 +2259,12 @@ M: Nicolas Ferre <nicolas.ferre@microchip.com>
S: Supported
F: drivers/power/reset/at91-sama5d2_shdwc.c
-ATMEL SAMA5D2 ADC DRIVER
-M: Ludovic Desroches <ludovic.desroches@microchip.com>
-L: linux-iio@vger.kernel.org
-S: Supported
-F: drivers/iio/adc/at91-sama5d2_adc.c
-
ATMEL Audio ALSA driver
M: Nicolas Ferre <nicolas.ferre@microchip.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Supported
F: sound/soc/atmel
-ATMEL XDMA DRIVER
-M: Ludovic Desroches <ludovic.desroches@microchip.com>
-L: linux-arm-kernel@lists.infradead.org
-L: dmaengine@vger.kernel.org
-S: Supported
-F: drivers/dma/at_xdmac.c
-
ATMEL I2C DRIVER
M: Ludovic Desroches <ludovic.desroches@microchip.com>
L: linux-i2c@vger.kernel.org
@@ -2307,6 +2290,14 @@ M: Nicolas Ferre <nicolas.ferre@microchip.com>
S: Supported
F: drivers/net/ethernet/cadence/
+ATMEL MAXTOUCH DRIVER
+M: Nick Dyer <nick@shmanahar.org>
+T: git git://github.com/ndyer/linux.git
+S: Maintained
+F: Documentation/devicetree/bindings/input/atmel,maxtouch.txt
+F: drivers/input/touchscreen/atmel_mxt_ts.c
+F: include/linux/platform_data/atmel_mxt_ts.h
+
ATMEL NAND DRIVER
M: Wenyou Yang <wenyou.yang@atmel.com>
M: Josh Wu <rainyfeeling@outlook.com>
@@ -2314,6 +2305,12 @@ L: linux-mtd@lists.infradead.org
S: Supported
F: drivers/mtd/nand/atmel/*
+ATMEL SAMA5D2 ADC DRIVER
+M: Ludovic Desroches <ludovic.desroches@microchip.com>
+L: linux-iio@vger.kernel.org
+S: Supported
+F: drivers/iio/adc/at91-sama5d2_adc.c
+
ATMEL SDMMC DRIVER
M: Ludovic Desroches <ludovic.desroches@microchip.com>
L: linux-mmc@vger.kernel.org
@@ -2353,13 +2350,12 @@ W: http://atmelwlandriver.sourceforge.net/
S: Maintained
F: drivers/net/wireless/atmel/atmel*
-ATMEL MAXTOUCH DRIVER
-M: Nick Dyer <nick@shmanahar.org>
-T: git git://github.com/ndyer/linux.git
-S: Maintained
-F: Documentation/devicetree/bindings/input/atmel,maxtouch.txt
-F: drivers/input/touchscreen/atmel_mxt_ts.c
-F: include/linux/platform_data/atmel_mxt_ts.h
+ATMEL XDMA DRIVER
+M: Ludovic Desroches <ludovic.desroches@microchip.com>
+L: linux-arm-kernel@lists.infradead.org
+L: dmaengine@vger.kernel.org
+S: Supported
+F: drivers/dma/at_xdmac.c
ATOMIC INFRASTRUCTURE
M: Will Deacon <will.deacon@arm.com>
@@ -2413,13 +2409,6 @@ F: include/uapi/linux/ax25.h
F: include/net/ax25.h
F: net/ax25/
-AXENTIA ASOC DRIVERS
-M: Peter Rosin <peda@axentia.se>
-L: alsa-devel@alsa-project.org (moderated for non-subscribers)
-S: Maintained
-F: Documentation/devicetree/bindings/sound/axentia,*
-F: sound/soc/atmel/tse850-pcm5142.c
-
AXENTIA ARM DEVICES
M: Peter Rosin <peda@axentia.se>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -2428,6 +2417,13 @@ F: Documentation/devicetree/bindings/arm/axentia.txt
F: arch/arm/boot/dts/at91-linea.dtsi
F: arch/arm/boot/dts/at91-tse850-3.dts
+AXENTIA ASOC DRIVERS
+M: Peter Rosin <peda@axentia.se>
+L: alsa-devel@alsa-project.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/sound/axentia,*
+F: sound/soc/atmel/tse850-pcm5142.c
+
AZ6007 DVB DRIVER
M: Mauro Carvalho Chehab <mchehab@s-opensource.com>
M: Mauro Carvalho Chehab <mchehab@kernel.org>
@@ -2507,13 +2503,11 @@ W: https://linuxtv.org
S: Supported
F: drivers/media/platform/sti/bdisp
-DELTA ST MEDIA DRIVER
-M: Hugues Fruchet <hugues.fruchet@st.com>
-L: linux-media@vger.kernel.org
-T: git git://linuxtv.org/media_tree.git
-W: https://linuxtv.org
-S: Supported
-F: drivers/media/platform/sti/delta
+BECKHOFF CX5020 ETHERCAT MASTER DRIVER
+M: Dariusz Marcinkiewicz <reksio@newterm.pl>
+L: netdev@vger.kernel.org
+S: Maintained
+F: drivers/net/ethernet/ec_bhf.c
BEFS FILE SYSTEM
M: Luis de Bethencourt <luisbg@kernel.org>
@@ -2523,11 +2517,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/luisbg/linux-befs.git
F: Documentation/filesystems/befs.txt
F: fs/befs/
-BECKHOFF CX5020 ETHERCAT MASTER DRIVER
-M: Dariusz Marcinkiewicz <reksio@newterm.pl>
-L: netdev@vger.kernel.org
+BFQ I/O SCHEDULER
+M: Paolo Valente <paolo.valente@linaro.org>
+M: Jens Axboe <axboe@kernel.dk>
+L: linux-block@vger.kernel.org
S: Maintained
-F: drivers/net/ethernet/ec_bhf.c
+F: block/bfq-*
+F: Documentation/block/bfq-iosched.txt
BFS FILE SYSTEM
M: "Tigran A. Aivazian" <aivazian.tigran@gmail.com>
@@ -2550,6 +2546,22 @@ W: http://blackfin.uclinux.org
S: Supported
F: drivers/net/ethernet/adi/
+BLACKFIN I2C TWI DRIVER
+M: Sonic Zhang <sonic.zhang@analog.com>
+L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
+W: http://blackfin.uclinux.org/
+S: Supported
+F: drivers/i2c/busses/i2c-bfin-twi.c
+
+BLACKFIN MEDIA DRIVER
+M: Scott Jiang <scott.jiang.linux@gmail.com>
+L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
+W: http://blackfin.uclinux.org/
+S: Supported
+F: drivers/media/platform/blackfin/
+F: drivers/media/i2c/adv7183*
+F: drivers/media/i2c/vs6624*
+
BLACKFIN RTC DRIVER
L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
W: http://blackfin.uclinux.org
@@ -2576,22 +2588,6 @@ W: http://blackfin.uclinux.org
S: Supported
F: drivers/watchdog/bfin_wdt.c
-BLACKFIN I2C TWI DRIVER
-M: Sonic Zhang <sonic.zhang@analog.com>
-L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
-W: http://blackfin.uclinux.org/
-S: Supported
-F: drivers/i2c/busses/i2c-bfin-twi.c
-
-BLACKFIN MEDIA DRIVER
-M: Scott Jiang <scott.jiang.linux@gmail.com>
-L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers)
-W: http://blackfin.uclinux.org/
-S: Supported
-F: drivers/media/platform/blackfin/
-F: drivers/media/i2c/adv7183*
-F: drivers/media/i2c/vs6624*
-
BLINKM RGB LED DRIVER
M: Jan-Simon Moeller <jansimon.moeller@gmx.de>
S: Maintained
@@ -2606,14 +2602,6 @@ F: block/
F: kernel/trace/blktrace.c
F: lib/sbitmap.c
-BFQ I/O SCHEDULER
-M: Paolo Valente <paolo.valente@linaro.org>
-M: Jens Axboe <axboe@kernel.dk>
-L: linux-block@vger.kernel.org
-S: Maintained
-F: block/bfq-*
-F: Documentation/block/bfq-iosched.txt
-
BLOCK2MTD DRIVER
M: Joern Engel <joern@lazybastard.org>
L: linux-mtd@lists.infradead.org
@@ -2643,21 +2631,6 @@ S: Maintained
F: net/bluetooth/
F: include/net/bluetooth/
-DMA MAPPING HELPERS
-M: Christoph Hellwig <hch@lst.de>
-M: Marek Szyprowski <m.szyprowski@samsung.com>
-R: Robin Murphy <robin.murphy@arm.com>
-L: linux-kernel@vger.kernel.org
-T: git git://git.infradead.org/users/hch/dma-mapping.git
-W: http://git.infradead.org/users/hch/dma-mapping.git
-S: Supported
-F: lib/dma-debug.c
-F: lib/dma-noop.c
-F: lib/dma-virt.c
-F: drivers/base/dma-mapping.c
-F: drivers/base/dma-coherent.c
-F: include/linux/dma-mapping.h
-
BONDING DRIVER
M: Jay Vosburgh <j.vosburgh@gmail.com>
M: Veaceslav Falico <vfalico@gmail.com>
@@ -2705,35 +2678,6 @@ S: Supported
F: drivers/net/dsa/b53/*
F: include/linux/platform_data/b53.h
-BROADCOM GENET ETHERNET DRIVER
-M: Florian Fainelli <f.fainelli@gmail.com>
-L: netdev@vger.kernel.org
-S: Supported
-F: drivers/net/ethernet/broadcom/genet/
-
-BROADCOM BNX2 GIGABIT ETHERNET DRIVER
-M: Rasesh Mody <rasesh.mody@cavium.com>
-M: Harish Patil <harish.patil@cavium.com>
-M: Dept-GELinuxNICDev@cavium.com
-L: netdev@vger.kernel.org
-S: Supported
-F: drivers/net/ethernet/broadcom/bnx2.*
-F: drivers/net/ethernet/broadcom/bnx2_*
-
-BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER
-M: Yuval Mintz <Yuval.Mintz@cavium.com>
-M: Ariel Elior <ariel.elior@cavium.com>
-M: everest-linux-l2@cavium.com
-L: netdev@vger.kernel.org
-S: Supported
-F: drivers/net/ethernet/broadcom/bnx2x/
-
-BROADCOM BNXT_EN 50 GIGABIT ETHERNET DRIVER
-M: Michael Chan <michael.chan@broadcom.com>
-L: netdev@vger.kernel.org
-S: Supported
-F: drivers/net/ethernet/broadcom/bnxt/
-
BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITECTURE
M: Florian Fainelli <f.fainelli@gmail.com>
M: Ray Jui <rjui@broadcom.com>
@@ -2812,6 +2756,13 @@ F: arch/arm/boot/dts/bcm7*.dts*
F: drivers/bus/brcmstb_gisb.c
N: brcmstb
+BROADCOM BMIPS CPUFREQ DRIVER
+M: Markus Mayer <mmayer@broadcom.com>
+M: bcm-kernel-feedback-list@broadcom.com
+L: linux-pm@vger.kernel.org
+S: Maintained
+F: drivers/cpufreq/bmips-cpufreq.c
+
BROADCOM BMIPS MIPS ARCHITECTURE
M: Kevin Cernekee <cernekee@gmail.com>
M: Florian Fainelli <f.fainelli@gmail.com>
@@ -2828,20 +2779,40 @@ F: drivers/irqchip/irq-brcmstb*
F: include/linux/bcm963xx_nvram.h
F: include/linux/bcm963xx_tag.h
-BROADCOM BMIPS CPUFREQ DRIVER
-M: Markus Mayer <mmayer@broadcom.com>
-M: bcm-kernel-feedback-list@broadcom.com
-L: linux-pm@vger.kernel.org
-S: Maintained
-F: drivers/cpufreq/bmips-cpufreq.c
+BROADCOM BNX2 GIGABIT ETHERNET DRIVER
+M: Rasesh Mody <rasesh.mody@cavium.com>
+M: Harish Patil <harish.patil@cavium.com>
+M: Dept-GELinuxNICDev@cavium.com
+L: netdev@vger.kernel.org
+S: Supported
+F: drivers/net/ethernet/broadcom/bnx2.*
+F: drivers/net/ethernet/broadcom/bnx2_*
-BROADCOM TG3 GIGABIT ETHERNET DRIVER
-M: Siva Reddy Kallam <siva.kallam@broadcom.com>
-M: Prashant Sreedharan <prashant@broadcom.com>
-M: Michael Chan <mchan@broadcom.com>
+BROADCOM BNX2FC 10 GIGABIT FCOE DRIVER
+M: QLogic-Storage-Upstream@qlogic.com
+L: linux-scsi@vger.kernel.org
+S: Supported
+F: drivers/scsi/bnx2fc/
+
+BROADCOM BNX2I 1/10 GIGABIT iSCSI DRIVER
+M: QLogic-Storage-Upstream@qlogic.com
+L: linux-scsi@vger.kernel.org
+S: Supported
+F: drivers/scsi/bnx2i/
+
+BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER
+M: Yuval Mintz <Yuval.Mintz@cavium.com>
+M: Ariel Elior <ariel.elior@cavium.com>
+M: everest-linux-l2@cavium.com
L: netdev@vger.kernel.org
S: Supported
-F: drivers/net/ethernet/broadcom/tg3.*
+F: drivers/net/ethernet/broadcom/bnx2x/
+
+BROADCOM BNXT_EN 50 GIGABIT ETHERNET DRIVER
+M: Michael Chan <michael.chan@broadcom.com>
+L: netdev@vger.kernel.org
+S: Supported
+F: drivers/net/ethernet/broadcom/bnxt/
BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
M: Arend van Spriel <arend.vanspriel@broadcom.com>
@@ -2855,17 +2826,18 @@ L: brcm80211-dev-list@cypress.com
S: Supported
F: drivers/net/wireless/broadcom/brcm80211/
-BROADCOM BNX2FC 10 GIGABIT FCOE DRIVER
-M: QLogic-Storage-Upstream@qlogic.com
-L: linux-scsi@vger.kernel.org
+BROADCOM BRCMSTB GPIO DRIVER
+M: Gregory Fong <gregory.0xf0@gmail.com>
+L: bcm-kernel-feedback-list@broadcom.com
S: Supported
-F: drivers/scsi/bnx2fc/
+F: drivers/gpio/gpio-brcmstb.c
+F: Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
-BROADCOM BNX2I 1/10 GIGABIT iSCSI DRIVER
-M: QLogic-Storage-Upstream@qlogic.com
-L: linux-scsi@vger.kernel.org
+BROADCOM GENET ETHERNET DRIVER
+M: Florian Fainelli <f.fainelli@gmail.com>
+L: netdev@vger.kernel.org
S: Supported
-F: drivers/scsi/bnx2i/
+F: drivers/net/ethernet/broadcom/genet/
BROADCOM IPROC ARM ARCHITECTURE
M: Ray Jui <rjui@broadcom.com>
@@ -2892,13 +2864,6 @@ F: arch/arm64/boot/dts/broadcom/ns2*
F: drivers/clk/bcm/clk-ns*
F: drivers/pinctrl/bcm/pinctrl-ns*
-BROADCOM BRCMSTB GPIO DRIVER
-M: Gregory Fong <gregory.0xf0@gmail.com>
-L: bcm-kernel-feedback-list@broadcom.com
-S: Supported
-F: drivers/gpio/gpio-brcmstb.c
-F: Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.txt
-
BROADCOM KONA GPIO DRIVER
M: Ray Jui <rjui@broadcom.com>
L: bcm-kernel-feedback-list@broadcom.com
@@ -2906,19 +2871,29 @@ S: Supported
F: drivers/gpio/gpio-bcm-kona.c
F: Documentation/devicetree/bindings/gpio/brcm,kona-gpio.txt
+BROADCOM NETXTREME-E ROCE DRIVER
+M: Selvin Xavier <selvin.xavier@broadcom.com>
+M: Devesh Sharma <devesh.sharma@broadcom.com>
+M: Somnath Kotur <somnath.kotur@broadcom.com>
+M: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
+L: linux-rdma@vger.kernel.org
+W: http://www.broadcom.com
+S: Supported
+F: drivers/infiniband/hw/bnxt_re/
+F: include/uapi/rdma/bnxt_re-abi.h
+
BROADCOM NVRAM DRIVER
M: Rafał Miłecki <zajec5@gmail.com>
L: linux-mips@linux-mips.org
S: Maintained
F: drivers/firmware/broadcom/*
-BROADCOM STB NAND FLASH DRIVER
-M: Brian Norris <computersforpeace@gmail.com>
-M: Kamal Dasu <kdasu.kdev@gmail.com>
-L: linux-mtd@lists.infradead.org
-L: bcm-kernel-feedback-list@broadcom.com
+BROADCOM SPECIFIC AMBA DRIVER (BCMA)
+M: Rafał Miłecki <zajec5@gmail.com>
+L: linux-wireless@vger.kernel.org
S: Maintained
-F: drivers/mtd/nand/brcmnand/
+F: drivers/bcma/
+F: include/linux/bcma/
BROADCOM STB AVS CPUFREQ DRIVER
M: Markus Mayer <mmayer@broadcom.com>
@@ -2928,12 +2903,13 @@ S: Maintained
F: Documentation/devicetree/bindings/cpufreq/brcm,stb-avs-cpu-freq.txt
F: drivers/cpufreq/brcmstb*
-BROADCOM SPECIFIC AMBA DRIVER (BCMA)
-M: Rafał Miłecki <zajec5@gmail.com>
-L: linux-wireless@vger.kernel.org
+BROADCOM STB NAND FLASH DRIVER
+M: Brian Norris <computersforpeace@gmail.com>
+M: Kamal Dasu <kdasu.kdev@gmail.com>
+L: linux-mtd@lists.infradead.org
+L: bcm-kernel-feedback-list@broadcom.com
S: Maintained
-F: drivers/bcma/
-F: include/linux/bcma/
+F: drivers/mtd/nand/brcmnand/
BROADCOM SYSTEMPORT ETHERNET DRIVER
M: Florian Fainelli <f.fainelli@gmail.com>
@@ -2941,16 +2917,13 @@ L: netdev@vger.kernel.org
S: Supported
F: drivers/net/ethernet/broadcom/bcmsysport.*
-BROADCOM NETXTREME-E ROCE DRIVER
-M: Selvin Xavier <selvin.xavier@broadcom.com>
-M: Devesh Sharma <devesh.sharma@broadcom.com>
-M: Somnath Kotur <somnath.kotur@broadcom.com>
-M: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
-L: linux-rdma@vger.kernel.org
-W: http://www.broadcom.com
+BROADCOM TG3 GIGABIT ETHERNET DRIVER
+M: Siva Reddy Kallam <siva.kallam@broadcom.com>
+M: Prashant Sreedharan <prashant@broadcom.com>
+M: Michael Chan <mchan@broadcom.com>
+L: netdev@vger.kernel.org
S: Supported
-F: drivers/infiniband/hw/bnxt_re/
-F: include/uapi/rdma/bnxt_re-abi.h
+F: drivers/net/ethernet/broadcom/tg3.*
BROCADE BFA FC SCSI DRIVER
M: Anil Gurumurthy <anil.gurumurthy@qlogic.com>
@@ -3013,6 +2986,15 @@ S: Odd fixes
F: Documentation/media/v4l-drivers/bttv*
F: drivers/media/pci/bt8xx/bttv*
+BUS FREQUENCY DRIVER FOR SAMSUNG EXYNOS
+M: Chanwoo Choi <cw00.choi@samsung.com>
+L: linux-pm@vger.kernel.org
+L: linux-samsung-soc@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq.git
+S: Maintained
+F: drivers/devfreq/exynos-bus.c
+F: Documentation/devicetree/bindings/devfreq/exynos-bus.txt
+
BUSLOGIC SCSI DRIVER
M: Khalid Aziz <khalid@gonehiking.org>
L: linux-scsi@vger.kernel.org
@@ -3087,6 +3069,21 @@ F: arch/x86/kernel/tce_64.c
F: arch/x86/include/asm/calgary.h
F: arch/x86/include/asm/tce.h
+CAN NETWORK DRIVERS
+M: Wolfgang Grandegger <wg@grandegger.com>
+M: Marc Kleine-Budde <mkl@pengutronix.de>
+L: linux-can@vger.kernel.org
+W: https://github.com/linux-can
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git
+S: Maintained
+F: Documentation/devicetree/bindings/net/can/
+F: drivers/net/can/
+F: include/linux/can/dev.h
+F: include/linux/can/platform/
+F: include/uapi/linux/can/error.h
+F: include/uapi/linux/can/netlink.h
+
CAN NETWORK LAYER
M: Oliver Hartkopp <socketcan@hartkopp.net>
M: Marc Kleine-Budde <mkl@pengutronix.de>
@@ -3103,21 +3100,6 @@ F: include/uapi/linux/can/bcm.h
F: include/uapi/linux/can/raw.h
F: include/uapi/linux/can/gw.h
-CAN NETWORK DRIVERS
-M: Wolfgang Grandegger <wg@grandegger.com>
-M: Marc Kleine-Budde <mkl@pengutronix.de>
-L: linux-can@vger.kernel.org
-W: https://github.com/linux-can
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git
-S: Maintained
-F: Documentation/devicetree/bindings/net/can/
-F: drivers/net/can/
-F: include/linux/can/dev.h
-F: include/linux/can/platform/
-F: include/uapi/linux/can/error.h
-F: include/uapi/linux/can/netlink.h
-
CAPABILITIES
M: Serge Hallyn <serge@hallyn.com>
L: linux-security-module@vger.kernel.org
@@ -3132,12 +3114,12 @@ M: Kevin Tsai <ktsai@capellamicro.com>
S: Maintained
F: drivers/iio/light/cm*
-CAVIUM THUNDERX2 ARM64 SOC
-M: Jayachandran C <jnair@caviumnetworks.com>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+CARL9170 LINUX COMMUNITY WIRELESS DRIVER
+M: Christian Lamparter <chunkeey@googlemail.com>
+L: linux-wireless@vger.kernel.org
+W: http://wireless.kernel.org/en/users/Drivers/carl9170
S: Maintained
-F: arch/arm64/boot/dts/cavium/thunder2-99xx*
-F: Documentation/devicetree/bindings/arm/cavium-thunder2.txt
+F: drivers/net/wireless/ath/carl9170/
CAVIUM I2C DRIVER
M: Jan Glauber <jglauber@cavium.com>
@@ -3147,6 +3129,16 @@ S: Supported
F: drivers/i2c/busses/i2c-octeon*
F: drivers/i2c/busses/i2c-thunderx*
+CAVIUM LIQUIDIO NETWORK DRIVER
+M: Derek Chickles <derek.chickles@caviumnetworks.com>
+M: Satanand Burla <satananda.burla@caviumnetworks.com>
+M: Felix Manlunas <felix.manlunas@caviumnetworks.com>
+M: Raghu Vatsavayi <raghu.vatsavayi@caviumnetworks.com>
+L: netdev@vger.kernel.org
+W: http://www.cavium.com
+S: Supported
+F: drivers/net/ethernet/cavium/liquidio/
+
CAVIUM MMC DRIVER
M: Jan Glauber <jglauber@cavium.com>
M: David Daney <david.daney@cavium.com>
@@ -3155,16 +3147,6 @@ W: http://www.cavium.com
S: Supported
F: drivers/mmc/host/cavium*
-CAVIUM LIQUIDIO NETWORK DRIVER
-M: Derek Chickles <derek.chickles@caviumnetworks.com>
-M: Satanand Burla <satananda.burla@caviumnetworks.com>
-M: Felix Manlunas <felix.manlunas@caviumnetworks.com>
-M: Raghu Vatsavayi <raghu.vatsavayi@caviumnetworks.com>
-L: netdev@vger.kernel.org
-W: http://www.cavium.com
-S: Supported
-F: drivers/net/ethernet/cavium/liquidio/
-
CAVIUM OCTEON-TX CRYPTO DRIVER
M: George Cherian <george.cherian@cavium.com>
L: linux-crypto@vger.kernel.org
@@ -3172,6 +3154,13 @@ W: http://www.cavium.com
S: Supported
F: drivers/crypto/cavium/cpt/
+CAVIUM THUNDERX2 ARM64 SOC
+M: Jayachandran C <jnair@caviumnetworks.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: arch/arm64/boot/dts/cavium/thunder2-99xx*
+F: Documentation/devicetree/bindings/arm/cavium-thunder2.txt
+
CC2520 IEEE-802.15.4 RADIO DRIVER
M: Varka Bhadram <varkabhadram@gmail.com>
L: linux-wpan@vger.kernel.org
@@ -3260,12 +3249,6 @@ F: drivers/usb/host/whci/
F: drivers/usb/wusbcore/
F: include/linux/usb/wusb*
-HT16K33 LED CONTROLLER DRIVER
-M: Robin van der Gracht <robin@protonic.nl>
-S: Maintained
-F: drivers/auxdisplay/ht16k33.c
-F: Documentation/devicetree/bindings/display/ht16k33.txt
-
CFAG12864B LCD DRIVER
M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com>
W: http://miguelojeda.es/auxdisplay.htm
@@ -3337,6 +3320,34 @@ S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/bleung/chrome-platform.git
F: drivers/platform/chrome/
+CIRRUS LOGIC AUDIO CODEC DRIVERS
+M: Brian Austin <brian.austin@cirrus.com>
+M: Paul Handrigan <Paul.Handrigan@cirrus.com>
+L: alsa-devel@alsa-project.org (moderated for non-subscribers)
+S: Maintained
+F: sound/soc/codecs/cs*
+
+CIRRUS LOGIC EP93XX ETHERNET DRIVER
+M: Hartley Sweeten <hsweeten@visionengravers.com>
+L: netdev@vger.kernel.org
+S: Maintained
+F: drivers/net/ethernet/cirrus/ep93xx_eth.c
+
+CISCO FCOE HBA DRIVER
+M: Satish Kharat <satishkh@cisco.com>
+M: Sesidhar Baddela <sebaddel@cisco.com>
+M: Karan Tilak Kumar <kartilak@cisco.com>
+L: linux-scsi@vger.kernel.org
+S: Supported
+F: drivers/scsi/fnic/
+
+CISCO SCSI HBA DRIVER
+M: Karan Tilak Kumar <kartilak@cisco.com>
+M: Sesidhar Baddela <sebaddel@cisco.com>
+L: linux-scsi@vger.kernel.org
+S: Supported
+F: drivers/scsi/snic/
+
CISCO VIC ETHERNET NIC DRIVER
M: Christian Benvenuti <benve@cisco.com>
M: Govindarajulu Varadarajan <_govind@gmx.com>
@@ -3350,19 +3361,6 @@ M: Dave Goodell <dgoodell@cisco.com>
S: Supported
F: drivers/infiniband/hw/usnic/
-CIRRUS LOGIC EP93XX ETHERNET DRIVER
-M: Hartley Sweeten <hsweeten@visionengravers.com>
-L: netdev@vger.kernel.org
-S: Maintained
-F: drivers/net/ethernet/cirrus/ep93xx_eth.c
-
-CIRRUS LOGIC AUDIO CODEC DRIVERS
-M: Brian Austin <brian.austin@cirrus.com>
-M: Paul Handrigan <Paul.Handrigan@cirrus.com>
-L: alsa-devel@alsa-project.org (moderated for non-subscribers)
-S: Maintained
-F: sound/soc/codecs/cs*
-
CLEANCACHE API
M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
L: linux-kernel@vger.kernel.org
@@ -3384,21 +3382,6 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core
S: Supported
F: drivers/clocksource
-CISCO FCOE HBA DRIVER
-M: Satish Kharat <satishkh@cisco.com>
-M: Sesidhar Baddela <sebaddel@cisco.com>
-M: Karan Tilak Kumar <kartilak@cisco.com>
-L: linux-scsi@vger.kernel.org
-S: Supported
-F: drivers/scsi/fnic/
-
-CISCO SCSI HBA DRIVER
-M: Karan Tilak Kumar <kartilak@cisco.com>
-M: Sesidhar Baddela <sebaddel@cisco.com>
-L: linux-scsi@vger.kernel.org
-S: Supported
-F: drivers/scsi/snic/
-
CMPC ACPI DRIVER
M: Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
M: Daniel Oliveira Nascimento <don@syst.com.br>
@@ -3474,17 +3457,17 @@ L: linux-pci@vger.kernel.org
S: Maintained
F: drivers/pci/hotplug/cpci_hotplug*
-COMPACTPCI HOTPLUG ZIATECH ZT5550 DRIVER
+COMPACTPCI HOTPLUG GENERIC DRIVER
M: Scott Murray <scott@spiteful.org>
L: linux-pci@vger.kernel.org
S: Maintained
-F: drivers/pci/hotplug/cpcihp_zt5550.*
+F: drivers/pci/hotplug/cpcihp_generic.c
-COMPACTPCI HOTPLUG GENERIC DRIVER
+COMPACTPCI HOTPLUG ZIATECH ZT5550 DRIVER
M: Scott Murray <scott@spiteful.org>
L: linux-pci@vger.kernel.org
S: Maintained
-F: drivers/pci/hotplug/cpcihp_generic.c
+F: drivers/pci/hotplug/cpcihp_zt5550.*
COMPAL LAPTOP SUPPORT
M: Cezary Jackiewicz <cezary.jackiewicz@gmail.com>
@@ -3587,6 +3570,18 @@ F: drivers/cpufreq/arm_big_little.h
F: drivers/cpufreq/arm_big_little.c
F: drivers/cpufreq/arm_big_little_dt.c
+CPU POWER MONITORING SUBSYSTEM
+M: Thomas Renninger <trenn@suse.com>
+L: linux-pm@vger.kernel.org
+S: Maintained
+F: tools/power/cpupower/
+
+CPUID/MSR DRIVER
+M: "H. Peter Anvin" <hpa@zytor.com>
+S: Maintained
+F: arch/x86/kernel/cpuid.c
+F: arch/x86/kernel/msr.c
+
CPUIDLE DRIVER - ARM BIG LITTLE
M: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
M: Daniel Lezcano <daniel.lezcano@linaro.org>
@@ -3616,18 +3611,6 @@ B: https://bugzilla.kernel.org
F: drivers/cpuidle/*
F: include/linux/cpuidle.h
-CPUID/MSR DRIVER
-M: "H. Peter Anvin" <hpa@zytor.com>
-S: Maintained
-F: arch/x86/kernel/cpuid.c
-F: arch/x86/kernel/msr.c
-
-CPU POWER MONITORING SUBSYSTEM
-M: Thomas Renninger <trenn@suse.com>
-L: linux-pm@vger.kernel.org
-S: Maintained
-F: tools/power/cpupower/
-
CRAMFS FILESYSTEM
W: http://sourceforge.net/projects/cramfs/
S: Orphan / Obsolete
@@ -3757,6 +3740,13 @@ S: Supported
F: drivers/infiniband/hw/cxgb3/
F: include/uapi/rdma/cxgb3-abi.h
+CXGB4 CRYPTO DRIVER (chcr)
+M: Harsh Jain <harsh@chelsio.com>
+L: linux-crypto@vger.kernel.org
+W: http://www.chelsio.com
+S: Supported
+F: drivers/crypto/chelsio
+
CXGB4 ETHERNET DRIVER (CXGB4)
M: Ganesh Goudar <ganeshgr@chelsio.com>
L: netdev@vger.kernel.org
@@ -3779,13 +3769,6 @@ S: Supported
F: drivers/infiniband/hw/cxgb4/
F: include/uapi/rdma/cxgb4-abi.h
-CXGB4 CRYPTO DRIVER (chcr)
-M: Harsh Jain <harsh@chelsio.com>
-L: linux-crypto@vger.kernel.org
-W: http://www.chelsio.com
-S: Supported
-F: drivers/crypto/chelsio
-
CXGB4VF ETHERNET DRIVER (CXGB4VF)
M: Casey Leedom <leedom@chelsio.com>
L: netdev@vger.kernel.org
@@ -3815,14 +3798,6 @@ F: drivers/scsi/cxlflash/
F: include/uapi/scsi/cxlflash_ioctls.h
F: Documentation/powerpc/cxlflash.txt
-STMMAC ETHERNET DRIVER
-M: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-M: Alexandre Torgue <alexandre.torgue@st.com>
-L: netdev@vger.kernel.org
-W: http://www.stlinux.com
-S: Supported
-F: drivers/net/ethernet/stmicro/stmmac/
-
CYBERPRO FB DRIVER
M: Russell King <linux@armlinux.org.uk>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -3946,15 +3921,15 @@ L: platform-driver-x86@vger.kernel.org
S: Maintained
F: drivers/platform/x86/dell-laptop.c
-DELL LAPTOP RBTN DRIVER
+DELL LAPTOP FREEFALL DRIVER
M: Pali Rohár <pali.rohar@gmail.com>
S: Maintained
-F: drivers/platform/x86/dell-rbtn.*
+F: drivers/platform/x86/dell-smo8800.c
-DELL LAPTOP FREEFALL DRIVER
+DELL LAPTOP RBTN DRIVER
M: Pali Rohár <pali.rohar@gmail.com>
S: Maintained
-F: drivers/platform/x86/dell-smo8800.c
+F: drivers/platform/x86/dell-rbtn.*
DELL LAPTOP SMM DRIVER
M: Pali Rohár <pali.rohar@gmail.com>
@@ -3974,6 +3949,14 @@ M: Pali Rohár <pali.rohar@gmail.com>
S: Maintained
F: drivers/platform/x86/dell-wmi.c
+DELTA ST MEDIA DRIVER
+M: Hugues Fruchet <hugues.fruchet@st.com>
+L: linux-media@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+W: https://linuxtv.org
+S: Supported
+F: drivers/media/platform/sti/delta
+
DENALI NAND DRIVER
M: Masahiro Yamada <yamada.masahiro@socionext.com>
L: linux-mtd@lists.infradead.org
@@ -4028,15 +4011,6 @@ F: drivers/devfreq/devfreq-event.c
F: include/linux/devfreq-event.h
F: Documentation/devicetree/bindings/devfreq/event/
-BUS FREQUENCY DRIVER FOR SAMSUNG EXYNOS
-M: Chanwoo Choi <cw00.choi@samsung.com>
-L: linux-pm@vger.kernel.org
-L: linux-samsung-soc@vger.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq.git
-S: Maintained
-F: drivers/devfreq/exynos-bus.c
-F: Documentation/devicetree/bindings/devfreq/exynos-bus.txt
-
DEVICE NUMBER REGISTRY
M: Torben Mathiasen <device@lanana.org>
W: http://lanana.org/docs/device-list/index.html
@@ -4186,20 +4160,6 @@ F: include/linux/*fence.h
F: Documentation/driver-api/dma-buf.rst
T: git git://anongit.freedesktop.org/drm/drm-misc
-SYNC FILE FRAMEWORK
-M: Sumit Semwal <sumit.semwal@linaro.org>
-R: Gustavo Padovan <gustavo@padovan.org>
-S: Maintained
-L: linux-media@vger.kernel.org
-L: dri-devel@lists.freedesktop.org
-F: drivers/dma-buf/sync_*
-F: drivers/dma-buf/dma-fence*
-F: drivers/dma-buf/sw_sync.c
-F: include/linux/sync_file.h
-F: include/uapi/linux/sync_file.h
-F: Documentation/sync_file.txt
-T: git git://anongit.freedesktop.org/drm/drm-misc
-
DMA GENERIC OFFLOAD ENGINE SUBSYSTEM
M: Vinod Koul <vinod.koul@intel.com>
L: dmaengine@vger.kernel.org
@@ -4211,6 +4171,21 @@ F: Documentation/devicetree/bindings/dma/
F: Documentation/dmaengine/
T: git git://git.infradead.org/users/vkoul/slave-dma.git
+DMA MAPPING HELPERS
+M: Christoph Hellwig <hch@lst.de>
+M: Marek Szyprowski <m.szyprowski@samsung.com>
+R: Robin Murphy <robin.murphy@arm.com>
+L: linux-kernel@vger.kernel.org
+T: git git://git.infradead.org/users/hch/dma-mapping.git
+W: http://git.infradead.org/users/hch/dma-mapping.git
+S: Supported
+F: lib/dma-debug.c
+F: lib/dma-noop.c
+F: lib/dma-virt.c
+F: drivers/base/dma-mapping.c
+F: drivers/base/dma-coherent.c
+F: include/linux/dma-mapping.h
+
DME1737 HARDWARE MONITOR DRIVER
M: Juerg Haefliger <juergh@gmail.com>
L: linux-hwmon@vger.kernel.org
@@ -4241,6 +4216,13 @@ X: Documentation/spi
X: Documentation/media
T: git git://git.lwn.net/linux.git docs-next
+DONGWOON DW9714 LENS VOICE COIL DRIVER
+M: Sakari Ailus <sakari.ailus@linux.intel.com>
+L: linux-media@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: drivers/media/i2c/dw9714.c
+
DOUBLETALK DRIVER
M: "James R. Van Zandt" <jrv@vanzandt.mv.com>
L: blinux-list@redhat.com
@@ -4292,36 +4274,13 @@ F: include/linux/debugfs.h
F: include/linux/kobj*
F: lib/kobj*
-DRM DRIVERS
-M: David Airlie <airlied@linux.ie>
-L: dri-devel@lists.freedesktop.org
-T: git git://people.freedesktop.org/~airlied/linux
-B: https://bugs.freedesktop.org/
-C: irc://chat.freenode.net/dri-devel
-S: Maintained
-F: drivers/gpu/drm/
-F: drivers/gpu/vga/
-F: Documentation/devicetree/bindings/display/
-F: Documentation/devicetree/bindings/gpu/
-F: Documentation/devicetree/bindings/video/
-F: Documentation/gpu/
-F: include/drm/
-F: include/uapi/drm/
-F: include/linux/vga*
-
-DRM DRIVERS AND MISC GPU PATCHES
-M: Daniel Vetter <daniel.vetter@intel.com>
-M: Jani Nikula <jani.nikula@linux.intel.com>
-M: Sean Paul <seanpaul@chromium.org>
-W: https://01.org/linuxgraphics/gfx-docs/maintainer-tools/drm-misc.html
+DRIVERS FOR ADAPTIVE VOLTAGE SCALING (AVS)
+M: Kevin Hilman <khilman@kernel.org>
+M: Nishanth Menon <nm@ti.com>
S: Maintained
-T: git git://anongit.freedesktop.org/drm/drm-misc
-F: Documentation/gpu/
-F: drivers/gpu/vga/
-F: drivers/gpu/drm/*
-F: include/drm/drm*
-F: include/uapi/drm/drm*
-F: include/linux/vga*
+F: drivers/power/avs/
+F: include/linux/power/smartreflex.h
+L: linux-pm@vger.kernel.org
DRM DRIVER FOR ARM PL111 CLCD
M: Eric Anholt <eric@anholt.net>
@@ -4334,14 +4293,6 @@ M: Dave Airlie <airlied@redhat.com>
S: Odd Fixes
F: drivers/gpu/drm/ast/
-DRM DRIVERS FOR BRIDGE CHIPS
-M: Archit Taneja <architt@codeaurora.org>
-M: Andrzej Hajda <a.hajda@samsung.com>
-R: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
-S: Maintained
-T: git git://anongit.freedesktop.org/drm/drm-misc
-F: drivers/gpu/drm/bridge/
-
DRM DRIVER FOR BOCHS VIRTUAL GPU
M: Gerd Hoffmann <kraxel@redhat.com>
L: virtualization@lists.linux-foundation.org
@@ -4349,6 +4300,47 @@ T: git git://anongit.freedesktop.org/drm/drm-misc
S: Maintained
F: drivers/gpu/drm/bochs/
+DRM DRIVER FOR INTEL I810 VIDEO CARDS
+S: Orphan / Obsolete
+F: drivers/gpu/drm/i810/
+F: include/uapi/drm/i810_drm.h
+
+DRM DRIVER FOR MATROX G200/G400 GRAPHICS CARDS
+S: Orphan / Obsolete
+F: drivers/gpu/drm/mga/
+F: include/uapi/drm/mga_drm.h
+
+DRM DRIVER FOR MGA G200 SERVER GRAPHICS CHIPS
+M: Dave Airlie <airlied@redhat.com>
+S: Odd Fixes
+F: drivers/gpu/drm/mgag200/
+
+DRM DRIVER FOR MI0283QT
+M: Noralf Trønnes <noralf@tronnes.org>
+S: Maintained
+F: drivers/gpu/drm/tinydrm/mi0283qt.c
+F: Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
+
+DRM DRIVER FOR MSM ADRENO GPU
+M: Rob Clark <robdclark@gmail.com>
+L: linux-arm-msm@vger.kernel.org
+L: dri-devel@lists.freedesktop.org
+L: freedreno@lists.freedesktop.org
+T: git git://people.freedesktop.org/~robclark/linux
+S: Maintained
+F: drivers/gpu/drm/msm/
+F: include/uapi/drm/msm_drm.h
+F: Documentation/devicetree/bindings/display/msm/
+
+DRM DRIVER FOR NVIDIA GEFORCE/QUADRO GPUS
+M: Ben Skeggs <bskeggs@redhat.com>
+L: dri-devel@lists.freedesktop.org
+L: nouveau@lists.freedesktop.org
+T: git git://github.com/skeggsb/linux
+S: Supported
+F: drivers/gpu/drm/nouveau/
+F: include/uapi/drm/nouveau_drm.h
+
DRM DRIVER FOR QEMU'S CIRRUS DEVICE
M: Dave Airlie <airlied@redhat.com>
M: Gerd Hoffmann <kraxel@redhat.com>
@@ -4358,59 +4350,92 @@ S: Obsolete
W: https://www.kraxel.org/blog/2014/10/qemu-using-cirrus-considered-harmful/
F: drivers/gpu/drm/cirrus/
-RADEON and AMDGPU DRM DRIVERS
-M: Alex Deucher <alexander.deucher@amd.com>
-M: Christian König <christian.koenig@amd.com>
-L: amd-gfx@lists.freedesktop.org
-T: git git://people.freedesktop.org/~agd5f/linux
-S: Supported
-F: drivers/gpu/drm/radeon/
-F: include/uapi/drm/radeon_drm.h
-F: drivers/gpu/drm/amd/
-F: include/uapi/drm/amdgpu_drm.h
+DRM DRIVER FOR QXL VIRTUAL GPU
+M: Dave Airlie <airlied@redhat.com>
+M: Gerd Hoffmann <kraxel@redhat.com>
+L: virtualization@lists.linux-foundation.org
+T: git git://anongit.freedesktop.org/drm/drm-misc
+S: Maintained
+F: drivers/gpu/drm/qxl/
+F: include/uapi/drm/qxl_drm.h
-DRM PANEL DRIVERS
-M: Thierry Reding <thierry.reding@gmail.com>
-L: dri-devel@lists.freedesktop.org
-T: git git://anongit.freedesktop.org/tegra/linux.git
+DRM DRIVER FOR PERVASIVE DISPLAYS REPAPER PANELS
+M: Noralf Trønnes <noralf@tronnes.org>
S: Maintained
-F: drivers/gpu/drm/drm_panel.c
-F: drivers/gpu/drm/panel/
-F: include/drm/drm_panel.h
-F: Documentation/devicetree/bindings/display/panel/
+F: drivers/gpu/drm/tinydrm/repaper.c
+F: Documentation/devicetree/bindings/display/repaper.txt
-INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets)
-M: Daniel Vetter <daniel.vetter@intel.com>
-M: Jani Nikula <jani.nikula@linux.intel.com>
-L: intel-gfx@lists.freedesktop.org
-W: https://01.org/linuxgraphics/
-B: https://01.org/linuxgraphics/documentation/how-report-bugs
-C: irc://chat.freenode.net/intel-gfx
-Q: http://patchwork.freedesktop.org/project/intel-gfx/
-T: git git://anongit.freedesktop.org/drm-intel
-S: Supported
-F: drivers/gpu/drm/i915/
-F: include/drm/i915*
-F: include/uapi/drm/i915_drm.h
-F: Documentation/gpu/i915.rst
+DRM DRIVER FOR RAGE 128 VIDEO CARDS
+S: Orphan / Obsolete
+F: drivers/gpu/drm/r128/
+F: include/uapi/drm/r128_drm.h
-INTEL GVT-g DRIVERS (Intel GPU Virtualization)
-M: Zhenyu Wang <zhenyuw@linux.intel.com>
-M: Zhi Wang <zhi.a.wang@intel.com>
-L: intel-gvt-dev@lists.freedesktop.org
-L: intel-gfx@lists.freedesktop.org
-W: https://01.org/igvt-g
-T: git https://github.com/01org/gvt-linux.git
-S: Supported
-F: drivers/gpu/drm/i915/gvt/
+DRM DRIVER FOR SAVAGE VIDEO CARDS
+S: Orphan / Obsolete
+F: drivers/gpu/drm/savage/
+F: include/uapi/drm/savage_drm.h
-DRM DRIVERS FOR ATMEL HLCDC
-M: Boris Brezillon <boris.brezillon@free-electrons.com>
+DRM DRIVER FOR SIS VIDEO CARDS
+S: Orphan / Obsolete
+F: drivers/gpu/drm/sis/
+F: include/uapi/drm/sis_drm.h
+
+DRM DRIVER FOR SITRONIX ST7586 PANELS
+M: David Lechner <david@lechnology.com>
+S: Maintained
+F: drivers/gpu/drm/tinydrm/st7586.c
+F: Documentation/devicetree/bindings/display/st7586.txt
+
+DRM DRIVER FOR TDFX VIDEO CARDS
+S: Orphan / Obsolete
+F: drivers/gpu/drm/tdfx/
+
+DRM DRIVER FOR USB DISPLAYLINK VIDEO ADAPTERS
+M: Dave Airlie <airlied@redhat.com>
+S: Odd Fixes
+F: drivers/gpu/drm/udl/
+
+DRM DRIVER FOR VMWARE VIRTUAL GPU
+M: "VMware Graphics" <linux-graphics-maintainer@vmware.com>
+M: Sinclair Yeh <syeh@vmware.com>
+M: Thomas Hellstrom <thellstrom@vmware.com>
L: dri-devel@lists.freedesktop.org
+T: git git://people.freedesktop.org/~syeh/repos_linux
+T: git git://people.freedesktop.org/~thomash/linux
S: Supported
-F: drivers/gpu/drm/atmel-hlcdc/
-F: Documentation/devicetree/bindings/drm/atmel/
+F: drivers/gpu/drm/vmwgfx/
+F: include/uapi/drm/vmwgfx_drm.h
+
+DRM DRIVERS
+M: David Airlie <airlied@linux.ie>
+L: dri-devel@lists.freedesktop.org
+T: git git://people.freedesktop.org/~airlied/linux
+B: https://bugs.freedesktop.org/
+C: irc://chat.freenode.net/dri-devel
+S: Maintained
+F: drivers/gpu/drm/
+F: drivers/gpu/vga/
+F: Documentation/devicetree/bindings/display/
+F: Documentation/devicetree/bindings/gpu/
+F: Documentation/devicetree/bindings/video/
+F: Documentation/gpu/
+F: include/drm/
+F: include/uapi/drm/
+F: include/linux/vga*
+
+DRM DRIVERS AND MISC GPU PATCHES
+M: Daniel Vetter <daniel.vetter@intel.com>
+M: Jani Nikula <jani.nikula@linux.intel.com>
+M: Sean Paul <seanpaul@chromium.org>
+W: https://01.org/linuxgraphics/gfx-docs/maintainer-tools/drm-misc.html
+S: Maintained
T: git git://anongit.freedesktop.org/drm/drm-misc
+F: Documentation/gpu/
+F: drivers/gpu/vga/
+F: drivers/gpu/drm/*
+F: include/drm/drm*
+F: include/uapi/drm/drm*
+F: include/linux/vga*
DRM DRIVERS FOR ALLWINNER A10
M: Maxime Ripard <maxime.ripard@free-electrons.com>
@@ -4432,6 +4457,22 @@ F: Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.txt
F: Documentation/gpu/meson.rst
T: git git://anongit.freedesktop.org/drm/drm-misc
+DRM DRIVERS FOR ATMEL HLCDC
+M: Boris Brezillon <boris.brezillon@free-electrons.com>
+L: dri-devel@lists.freedesktop.org
+S: Supported
+F: drivers/gpu/drm/atmel-hlcdc/
+F: Documentation/devicetree/bindings/drm/atmel/
+T: git git://anongit.freedesktop.org/drm/drm-misc
+
+DRM DRIVERS FOR BRIDGE CHIPS
+M: Archit Taneja <architt@codeaurora.org>
+M: Andrzej Hajda <a.hajda@samsung.com>
+R: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
+S: Maintained
+T: git git://anongit.freedesktop.org/drm/drm-misc
+F: drivers/gpu/drm/bridge/
+
DRM DRIVERS FOR EXYNOS
M: Inki Dae <inki.dae@samsung.com>
M: Joonyoung Shim <jy0922.shim@samsung.com>
@@ -4480,11 +4521,6 @@ S: Maintained
F: drivers/gpu/drm/hisilicon/
F: Documentation/devicetree/bindings/display/hisilicon/
-DRM DRIVER FOR INTEL I810 VIDEO CARDS
-S: Orphan / Obsolete
-F: drivers/gpu/drm/i810/
-F: include/uapi/drm/i810_drm.h
-
DRM DRIVERS FOR MEDIATEK
M: CK Hu <ck.hu@mediatek.com>
M: Philipp Zabel <p.zabel@pengutronix.de>
@@ -4493,32 +4529,6 @@ S: Supported
F: drivers/gpu/drm/mediatek/
F: Documentation/devicetree/bindings/display/mediatek/
-DRM DRIVER FOR MI0283QT
-M: Noralf Trønnes <noralf@tronnes.org>
-S: Maintained
-F: drivers/gpu/drm/tinydrm/mi0283qt.c
-F: Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
-
-DRM DRIVER FOR MSM ADRENO GPU
-M: Rob Clark <robdclark@gmail.com>
-L: linux-arm-msm@vger.kernel.org
-L: dri-devel@lists.freedesktop.org
-L: freedreno@lists.freedesktop.org
-T: git git://people.freedesktop.org/~robclark/linux
-S: Maintained
-F: drivers/gpu/drm/msm/
-F: include/uapi/drm/msm_drm.h
-F: Documentation/devicetree/bindings/display/msm/
-
-DRM DRIVER FOR NVIDIA GEFORCE/QUADRO GPUS
-M: Ben Skeggs <bskeggs@redhat.com>
-L: dri-devel@lists.freedesktop.org
-L: nouveau@lists.freedesktop.org
-T: git git://github.com/skeggsb/linux
-S: Supported
-F: drivers/gpu/drm/nouveau/
-F: include/uapi/drm/nouveau_drm.h
-
DRM DRIVERS FOR NVIDIA TEGRA
M: Thierry Reding <thierry.reding@gmail.com>
L: dri-devel@lists.freedesktop.org
@@ -4531,21 +4541,6 @@ F: include/linux/host1x.h
F: include/uapi/drm/tegra_drm.h
F: Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
-DRM DRIVER FOR MATROX G200/G400 GRAPHICS CARDS
-S: Orphan / Obsolete
-F: drivers/gpu/drm/mga/
-F: include/uapi/drm/mga_drm.h
-
-DRM DRIVER FOR MGA G200 SERVER GRAPHICS CHIPS
-M: Dave Airlie <airlied@redhat.com>
-S: Odd Fixes
-F: drivers/gpu/drm/mgag200/
-
-DRM DRIVER FOR RAGE 128 VIDEO CARDS
-S: Orphan / Obsolete
-F: drivers/gpu/drm/r128/
-F: include/uapi/drm/r128_drm.h
-
DRM DRIVERS FOR RENESAS
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: dri-devel@lists.freedesktop.org
@@ -4558,15 +4553,6 @@ F: include/linux/platform_data/shmob_drm.h
F: Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt
F: Documentation/devicetree/bindings/display/renesas,du.txt
-DRM DRIVER FOR QXL VIRTUAL GPU
-M: Dave Airlie <airlied@redhat.com>
-M: Gerd Hoffmann <kraxel@redhat.com>
-L: virtualization@lists.linux-foundation.org
-T: git git://anongit.freedesktop.org/drm/drm-misc
-S: Maintained
-F: drivers/gpu/drm/qxl/
-F: include/uapi/drm/qxl_drm.h
-
DRM DRIVERS FOR ROCKCHIP
M: Mark Yao <mark.yao@rock-chips.com>
L: dri-devel@lists.freedesktop.org
@@ -4575,16 +4561,6 @@ F: drivers/gpu/drm/rockchip/
F: Documentation/devicetree/bindings/display/rockchip/
T: git git://anongit.freedesktop.org/drm/drm-misc
-DRM DRIVER FOR SAVAGE VIDEO CARDS
-S: Orphan / Obsolete
-F: drivers/gpu/drm/savage/
-F: include/uapi/drm/savage_drm.h
-
-DRM DRIVER FOR SIS VIDEO CARDS
-S: Orphan / Obsolete
-F: drivers/gpu/drm/sis/
-F: include/uapi/drm/sis_drm.h
-
DRM DRIVERS FOR STI
M: Benjamin Gaignard <benjamin.gaignard@linaro.org>
M: Vincent Abriou <vincent.abriou@st.com>
@@ -4605,36 +4581,20 @@ S: Maintained
F: drivers/gpu/drm/stm
F: Documentation/devicetree/bindings/display/st,stm32-ltdc.txt
-DRM DRIVER FOR TDFX VIDEO CARDS
-S: Orphan / Obsolete
-F: drivers/gpu/drm/tdfx/
-
-DRM DRIVER FOR USB DISPLAYLINK VIDEO ADAPTERS
-M: Dave Airlie <airlied@redhat.com>
-S: Odd Fixes
-F: drivers/gpu/drm/udl/
-
-DRM DRIVERS FOR VIVANTE GPU IP
-M: Lucas Stach <l.stach@pengutronix.de>
-R: Russell King <linux+etnaviv@armlinux.org.uk>
-R: Christian Gmeiner <christian.gmeiner@gmail.com>
-L: etnaviv@lists.freedesktop.org
+DRM DRIVERS FOR TI LCDC
+M: Jyri Sarha <jsarha@ti.com>
+R: Tomi Valkeinen <tomi.valkeinen@ti.com>
L: dri-devel@lists.freedesktop.org
S: Maintained
-F: drivers/gpu/drm/etnaviv/
-F: include/uapi/drm/etnaviv_drm.h
-F: Documentation/devicetree/bindings/display/etnaviv/
+F: drivers/gpu/drm/tilcdc/
+F: Documentation/devicetree/bindings/display/tilcdc/
-DRM DRIVER FOR VMWARE VIRTUAL GPU
-M: "VMware Graphics" <linux-graphics-maintainer@vmware.com>
-M: Sinclair Yeh <syeh@vmware.com>
-M: Thomas Hellstrom <thellstrom@vmware.com>
+DRM DRIVERS FOR TI OMAP
+M: Tomi Valkeinen <tomi.valkeinen@ti.com>
L: dri-devel@lists.freedesktop.org
-T: git git://people.freedesktop.org/~syeh/repos_linux
-T: git git://people.freedesktop.org/~thomash/linux
-S: Supported
-F: drivers/gpu/drm/vmwgfx/
-F: include/uapi/drm/vmwgfx_drm.h
+S: Maintained
+F: drivers/gpu/drm/omapdrm/
+F: Documentation/devicetree/bindings/display/ti/
DRM DRIVERS FOR VC4
M: Eric Anholt <eric@anholt.net>
@@ -4645,20 +4605,16 @@ F: include/uapi/drm/vc4_drm.h
F: Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt
T: git git://anongit.freedesktop.org/drm/drm-misc
-DRM DRIVERS FOR TI OMAP
-M: Tomi Valkeinen <tomi.valkeinen@ti.com>
-L: dri-devel@lists.freedesktop.org
-S: Maintained
-F: drivers/gpu/drm/omapdrm/
-F: Documentation/devicetree/bindings/display/ti/
-
-DRM DRIVERS FOR TI LCDC
-M: Jyri Sarha <jsarha@ti.com>
-R: Tomi Valkeinen <tomi.valkeinen@ti.com>
+DRM DRIVERS FOR VIVANTE GPU IP
+M: Lucas Stach <l.stach@pengutronix.de>
+R: Russell King <linux+etnaviv@armlinux.org.uk>
+R: Christian Gmeiner <christian.gmeiner@gmail.com>
+L: etnaviv@lists.freedesktop.org
L: dri-devel@lists.freedesktop.org
S: Maintained
-F: drivers/gpu/drm/tilcdc/
-F: Documentation/devicetree/bindings/display/tilcdc/
+F: drivers/gpu/drm/etnaviv/
+F: include/uapi/drm/etnaviv_drm.h
+F: Documentation/devicetree/bindings/display/etnaviv/
DRM DRIVERS FOR ZTE ZX
M: Shawn Guo <shawnguo@kernel.org>
@@ -4668,6 +4624,24 @@ F: drivers/gpu/drm/zte/
F: Documentation/devicetree/bindings/display/zte,vou.txt
T: git git://anongit.freedesktop.org/drm/drm-misc
+DRM PANEL DRIVERS
+M: Thierry Reding <thierry.reding@gmail.com>
+L: dri-devel@lists.freedesktop.org
+T: git git://anongit.freedesktop.org/tegra/linux.git
+S: Maintained
+F: drivers/gpu/drm/drm_panel.c
+F: drivers/gpu/drm/panel/
+F: include/drm/drm_panel.h
+F: Documentation/devicetree/bindings/display/panel/
+
+DRM TINYDRM DRIVERS
+M: Noralf Trønnes <noralf@tronnes.org>
+W: https://github.com/notro/tinydrm/wiki/Development
+T: git git://anongit.freedesktop.org/drm/drm-misc
+S: Maintained
+F: drivers/gpu/drm/tinydrm/
+F: include/drm/tinydrm/
+
DSBR100 USB FM RADIO DRIVER
M: Alexey Klimov <klimov.linux@gmail.com>
L: linux-media@vger.kernel.org
@@ -4799,13 +4773,6 @@ S: Maintained
F: drivers/media/usb/dvb-usb-v2/dvb_usb*
F: drivers/media/usb/dvb-usb-v2/usb_urb.c
-DONGWOON DW9714 LENS VOICE COIL DRIVER
-M: Sakari Ailus <sakari.ailus@linux.intel.com>
-L: linux-media@vger.kernel.org
-T: git git://linuxtv.org/media_tree.git
-S: Maintained
-F: drivers/media/i2c/dw9714.c
-
DYNAMIC DEBUG
M: Jason Baron <jbaron@akamai.com>
S: Maintained
@@ -4861,19 +4828,6 @@ S: Supported
F: Documentation/filesystems/ecryptfs.txt
F: fs/ecryptfs/
-EDAC-CORE
-M: Borislav Petkov <bp@alien8.de>
-M: Mauro Carvalho Chehab <mchehab@s-opensource.com>
-M: Mauro Carvalho Chehab <mchehab@kernel.org>
-L: linux-edac@vger.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git for-next
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-edac.git linux_next
-S: Supported
-F: Documentation/admin-guide/ras.rst
-F: Documentation/driver-api/edac.rst
-F: drivers/edac/
-F: include/linux/edac.h
-
EDAC-AMD64
M: Borislav Petkov <bp@alien8.de>
L: linux-edac@vger.kernel.org
@@ -4895,6 +4849,19 @@ S: Supported
F: drivers/edac/octeon_edac*
F: drivers/edac/thunderx_edac*
+EDAC-CORE
+M: Borislav Petkov <bp@alien8.de>
+M: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+M: Mauro Carvalho Chehab <mchehab@kernel.org>
+L: linux-edac@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git for-next
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-edac.git linux_next
+S: Supported
+F: Documentation/admin-guide/ras.rst
+F: Documentation/driver-api/edac.rst
+F: drivers/edac/
+F: include/linux/edac.h
+
EDAC-E752X
M: Mark Gross <mark.gross@intel.com>
L: linux-edac@vger.kernel.org
@@ -4919,12 +4886,6 @@ L: linux-edac@vger.kernel.org
S: Maintained
F: drivers/edac/ghes_edac.c
-EDAC-I82443BXGX
-M: Tim Small <tim@buttersideup.com>
-L: linux-edac@vger.kernel.org
-S: Maintained
-F: drivers/edac/i82443bxgx_edac.c
-
EDAC-I3000
L: linux-edac@vger.kernel.org
S: Orphan
@@ -4956,6 +4917,12 @@ L: linux-edac@vger.kernel.org
S: Maintained
F: drivers/edac/i7core_edac.c
+EDAC-I82443BXGX
+M: Tim Small <tim@buttersideup.com>
+L: linux-edac@vger.kernel.org
+S: Maintained
+F: drivers/edac/i82443bxgx_edac.c
+
EDAC-I82975X
M: Ranganathan Desikan <ravi@jetztechnologies.com>
M: "Arvind R." <arvino55@gmail.com>
@@ -4975,18 +4942,18 @@ L: linux-edac@vger.kernel.org
S: Maintained
F: drivers/edac/mpc85xx_edac.[ch]
-EDAC-PND2
-M: Tony Luck <tony.luck@intel.com>
-L: linux-edac@vger.kernel.org
-S: Maintained
-F: drivers/edac/pnd2_edac.[ch]
-
EDAC-PASEMI
M: Egor Martovetsky <egor@pasemi.com>
L: linux-edac@vger.kernel.org
S: Maintained
F: drivers/edac/pasemi_edac.c
+EDAC-PND2
+M: Tony Luck <tony.luck@intel.com>
+L: linux-edac@vger.kernel.org
+S: Maintained
+F: drivers/edac/pnd2_edac.[ch]
+
EDAC-R82600
M: Tim Small <tim@buttersideup.com>
L: linux-edac@vger.kernel.org
@@ -5006,13 +4973,6 @@ L: linux-edac@vger.kernel.org
S: Maintained
F: drivers/edac/skx_edac.c
-EDAC-XGENE
-APPLIED MICRO (APM) X-GENE SOC EDAC
-M: Loc Ho <lho@apm.com>
-S: Supported
-F: drivers/edac/xgene_edac.c
-F: Documentation/devicetree/bindings/edac/apm-xgene-edac.txt
-
EDIROL UA-101/UA-1000 DRIVER
M: Clemens Ladisch <clemens@ladisch.de>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
@@ -5020,21 +4980,12 @@ T: git git://git.alsa-project.org/alsa-kernel.git
S: Maintained
F: sound/usb/misc/ua101.c
-EXTENSIBLE FIRMWARE INTERFACE (EFI)
-M: Matt Fleming <matt@codeblueprint.co.uk>
-M: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+EFI TEST DRIVER
L: linux-efi@vger.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git
+M: Ivan Hu <ivan.hu@canonical.com>
+M: Matt Fleming <matt@codeblueprint.co.uk>
S: Maintained
-F: Documentation/efi-stub.txt
-F: arch/*/kernel/efi.c
-F: arch/x86/boot/compressed/eboot.[ch]
-F: arch/*/include/asm/efi.h
-F: arch/x86/platform/efi/
-F: drivers/firmware/efi/
-F: include/linux/efi*.h
-F: arch/arm/boot/compressed/efi-header.S
-F: arch/arm64/kernel/efi-entry.S
+F: drivers/firmware/efi/test/
EFI VARIABLE FILESYSTEM
M: Matthew Garrett <matthew.garrett@nebula.com>
@@ -5051,13 +5002,6 @@ M: Peter Jones <pjones@redhat.com>
S: Maintained
F: drivers/video/fbdev/efifb.c
-EFI TEST DRIVER
-L: linux-efi@vger.kernel.org
-M: Ivan Hu <ivan.hu@canonical.com>
-M: Matt Fleming <matt@codeblueprint.co.uk>
-S: Maintained
-F: drivers/firmware/efi/test/
-
EFS FILESYSTEM
W: http://aeschi.ch.eu.org/efs/
S: Orphan
@@ -5086,6 +5030,34 @@ M: David Woodhouse <dwmw2@infradead.org>
L: linux-embedded@vger.kernel.org
S: Maintained
+Emulex 10Gbps iSCSI - OneConnect DRIVER
+M: Subbu Seetharaman <subbu.seetharaman@broadcom.com>
+M: Ketan Mukadam <ketan.mukadam@broadcom.com>
+M: Jitendra Bhivare <jitendra.bhivare@broadcom.com>
+L: linux-scsi@vger.kernel.org
+W: http://www.broadcom.com
+S: Supported
+F: drivers/scsi/be2iscsi/
+
+Emulex 10Gbps NIC BE2, BE3-R, Lancer, Skyhawk-R DRIVER (be2net)
+M: Sathya Perla <sathya.perla@broadcom.com>
+M: Ajit Khaparde <ajit.khaparde@broadcom.com>
+M: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
+M: Somnath Kotur <somnath.kotur@broadcom.com>
+L: netdev@vger.kernel.org
+W: http://www.emulex.com
+S: Supported
+F: drivers/net/ethernet/emulex/benet/
+
+EMULEX ONECONNECT ROCE DRIVER
+M: Selvin Xavier <selvin.xavier@broadcom.com>
+M: Devesh Sharma <devesh.sharma@broadcom.com>
+L: linux-rdma@vger.kernel.org
+W: http://www.broadcom.com
+S: Odd Fixes
+F: drivers/infiniband/hw/ocrdma/
+F: include/uapi/rdma/ocrdma-abi.h
+
EMULEX/BROADCOM LPFC FC/FCOE SCSI DRIVER
M: James Smart <james.smart@broadcom.com>
M: Dick Kennedy <dick.kennedy@broadcom.com>
@@ -5138,12 +5110,20 @@ M: Andrew Lunn <andrew@lunn.ch>
M: Florian Fainelli <f.fainelli@gmail.com>
L: netdev@vger.kernel.org
S: Maintained
-F: include/linux/phy.h
-F: include/linux/phy_fixed.h
-F: drivers/net/phy/
+F: Documentation/ABI/testing/sysfs-bus-mdio
+F: Documentation/devicetree/bindings/net/mdio*
F: Documentation/networking/phy.txt
+F: drivers/net/phy/
F: drivers/of/of_mdio.c
F: drivers/of/of_net.c
+F: include/linux/*mdio*.h
+F: include/linux/of_net.h
+F: include/linux/phy.h
+F: include/linux/phy_fixed.h
+F: include/linux/platform_data/mdio-gpio.h
+F: include/trace/events/mdio.h
+F: include/uapi/linux/mdio.h
+F: include/uapi/linux/mii.h
EXT2 FILE SYSTEM
M: Jan Kara <jack@suse.com>
@@ -5171,6 +5151,22 @@ L: linux-security-module@vger.kernel.org
S: Supported
F: security/integrity/evm/
+EXTENSIBLE FIRMWARE INTERFACE (EFI)
+M: Matt Fleming <matt@codeblueprint.co.uk>
+M: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+L: linux-efi@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git
+S: Maintained
+F: Documentation/efi-stub.txt
+F: arch/*/kernel/efi.c
+F: arch/x86/boot/compressed/eboot.[ch]
+F: arch/*/include/asm/efi.h
+F: arch/x86/platform/efi/
+F: drivers/firmware/efi/
+F: include/linux/efi*.h
+F: arch/arm/boot/compressed/efi-header.S
+F: arch/arm64/kernel/efi-entry.S
+
EXTERNAL CONNECTOR SUBSYSTEM (EXTCON)
M: MyungJoo Ham <myungjoo.ham@samsung.com>
M: Chanwoo Choi <cw00.choi@samsung.com>
@@ -5201,6 +5197,19 @@ S: Supported
F: arch/arc/plat-eznps
F: arch/arc/boot/dts/eznps.dts
+F2FS FILE SYSTEM
+M: Jaegeuk Kim <jaegeuk@kernel.org>
+M: Chao Yu <yuchao0@huawei.com>
+L: linux-f2fs-devel@lists.sourceforge.net
+W: https://f2fs.wiki.kernel.org/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git
+S: Maintained
+F: Documentation/filesystems/f2fs.txt
+F: Documentation/ABI/testing/sysfs-fs-f2fs
+F: fs/f2fs/
+F: include/linux/f2fs_fs.h
+F: include/trace/events/f2fs.h
+
F71805F HARDWARE MONITORING DRIVER
M: Jean Delvare <jdelvare@suse.com>
L: linux-hwmon@vger.kernel.org
@@ -5208,23 +5217,6 @@ S: Maintained
F: Documentation/hwmon/f71805f
F: drivers/hwmon/f71805f.c
-FC0011 TUNER DRIVER
-M: Michael Buesch <m@bues.ch>
-L: linux-media@vger.kernel.org
-S: Maintained
-F: drivers/media/tuners/fc0011.h
-F: drivers/media/tuners/fc0011.c
-
-FC2580 MEDIA DRIVER
-M: Antti Palosaari <crope@iki.fi>
-L: linux-media@vger.kernel.org
-W: https://linuxtv.org
-W: http://palosaari.fi/linux/
-Q: http://patchwork.linuxtv.org/project/linux-media/list/
-T: git git://linuxtv.org/anttip/media_tree.git
-S: Maintained
-F: drivers/media/tuners/fc2580*
-
FANOTIFY
M: Eric Paris <eparis@redhat.com>
S: Maintained
@@ -5249,6 +5241,23 @@ M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
S: Maintained
F: drivers/staging/fbtft/
+FC0011 TUNER DRIVER
+M: Michael Buesch <m@bues.ch>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: drivers/media/tuners/fc0011.h
+F: drivers/media/tuners/fc0011.c
+
+FC2580 MEDIA DRIVER
+M: Antti Palosaari <crope@iki.fi>
+L: linux-media@vger.kernel.org
+W: https://linuxtv.org
+W: http://palosaari.fi/linux/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/anttip/media_tree.git
+S: Maintained
+F: drivers/media/tuners/fc2580*
+
FCOE SUBSYSTEM (libfc, libfcoe, fcoe)
M: Johannes Thumshirn <jth@kernel.org>
L: fcoe-devel@open-fcoe.org
@@ -5408,6 +5417,14 @@ L: linuxppc-dev@lists.ozlabs.org
S: Maintained
F: drivers/dma/fsldma.*
+FREESCALE eTSEC ETHERNET DRIVER (GIANFAR)
+M: Claudiu Manoil <claudiu.manoil@freescale.com>
+L: netdev@vger.kernel.org
+S: Maintained
+F: drivers/net/ethernet/freescale/gianfar*
+X: drivers/net/ethernet/freescale/gianfar_ptp.c
+F: Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
+
FREESCALE GPMI NAND DRIVER
M: Han Xu <han.xu@nxp.com>
L: linux-mtd@lists.infradead.org
@@ -5421,6 +5438,15 @@ L: linux-i2c@vger.kernel.org
S: Maintained
F: drivers/i2c/busses/i2c-cpm.c
+FREESCALE IMX / MXC FEC DRIVER
+M: Fugang Duan <fugang.duan@nxp.com>
+L: netdev@vger.kernel.org
+S: Maintained
+F: drivers/net/ethernet/freescale/fec_main.c
+F: drivers/net/ethernet/freescale/fec_ptp.c
+F: drivers/net/ethernet/freescale/fec.h
+F: Documentation/devicetree/bindings/net/fsl-fec.txt
+
FREESCALE IMX / MXC FRAMEBUFFER DRIVER
M: Sascha Hauer <kernel@pengutronix.de>
L: linux-fbdev@vger.kernel.org
@@ -5429,29 +5455,11 @@ S: Maintained
F: include/linux/platform_data/video-imxfb.h
F: drivers/video/fbdev/imxfb.c
-FREESCALE QUAD SPI DRIVER
-M: Han Xu <han.xu@nxp.com>
-L: linux-mtd@lists.infradead.org
-S: Maintained
-F: drivers/mtd/spi-nor/fsl-quadspi.c
-
-FREESCALE SOC FS_ENET DRIVER
-M: Pantelis Antoniou <pantelis.antoniou@gmail.com>
-M: Vitaly Bordug <vbordug@ru.mvista.com>
-L: linuxppc-dev@lists.ozlabs.org
-L: netdev@vger.kernel.org
-S: Maintained
-F: drivers/net/ethernet/freescale/fs_enet/
-F: include/linux/fs_enet_pd.h
-
-FREESCALE IMX / MXC FEC DRIVER
-M: Fugang Duan <fugang.duan@nxp.com>
+FREESCALE QORIQ DPAA ETHERNET DRIVER
+M: Madalin Bucur <madalin.bucur@nxp.com>
L: netdev@vger.kernel.org
S: Maintained
-F: drivers/net/ethernet/freescale/fec_main.c
-F: drivers/net/ethernet/freescale/fec_ptp.c
-F: drivers/net/ethernet/freescale/fec.h
-F: Documentation/devicetree/bindings/net/fsl-fec.txt
+F: drivers/net/ethernet/freescale/dpaa
FREESCALE QORIQ DPAA FMAN DRIVER
M: Madalin Bucur <madalin.bucur@nxp.com>
@@ -5460,20 +5468,11 @@ S: Maintained
F: drivers/net/ethernet/freescale/fman
F: Documentation/devicetree/bindings/powerpc/fsl/fman.txt
-FREESCALE QORIQ DPAA ETHERNET DRIVER
-M: Madalin Bucur <madalin.bucur@nxp.com>
-L: netdev@vger.kernel.org
-S: Maintained
-F: drivers/net/ethernet/freescale/dpaa
-
-FREESCALE SOC DRIVERS
-M: Li Yang <leoyang.li@nxp.com>
-L: linuxppc-dev@lists.ozlabs.org
-L: linux-arm-kernel@lists.infradead.org
+FREESCALE QUAD SPI DRIVER
+M: Han Xu <han.xu@nxp.com>
+L: linux-mtd@lists.infradead.org
S: Maintained
-F: Documentation/devicetree/bindings/soc/fsl/
-F: drivers/soc/fsl/
-F: include/linux/fsl/
+F: drivers/mtd/spi-nor/fsl-quadspi.c
FREESCALE QUICC ENGINE LIBRARY
M: Qiang Zhao <qiang.zhao@nxp.com>
@@ -5483,13 +5482,6 @@ F: drivers/soc/fsl/qe/
F: include/soc/fsl/*qe*.h
F: include/soc/fsl/*ucc*.h
-FREESCALE USB PERIPHERAL DRIVERS
-M: Li Yang <leoyang.li@nxp.com>
-L: linux-usb@vger.kernel.org
-L: linuxppc-dev@lists.ozlabs.org
-S: Maintained
-F: drivers/usb/gadget/udc/fsl*
-
FREESCALE QUICC ENGINE UCC ETHERNET DRIVER
M: Li Yang <leoyang.li@nxp.com>
L: netdev@vger.kernel.org
@@ -5497,14 +5489,6 @@ L: linuxppc-dev@lists.ozlabs.org
S: Maintained
F: drivers/net/ethernet/freescale/ucc_geth*
-FREESCALE eTSEC ETHERNET DRIVER (GIANFAR)
-M: Claudiu Manoil <claudiu.manoil@freescale.com>
-L: netdev@vger.kernel.org
-S: Maintained
-F: drivers/net/ethernet/freescale/gianfar*
-X: drivers/net/ethernet/freescale/gianfar_ptp.c
-F: Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
-
FREESCALE QUICC ENGINE UCC HDLC DRIVER
M: Zhao Qiang <qiang.zhao@nxp.com>
L: netdev@vger.kernel.org
@@ -5518,6 +5502,24 @@ L: linuxppc-dev@lists.ozlabs.org
S: Maintained
F: drivers/tty/serial/ucc_uart.c
+FREESCALE SOC DRIVERS
+M: Li Yang <leoyang.li@nxp.com>
+L: linuxppc-dev@lists.ozlabs.org
+L: linux-arm-kernel@lists.infradead.org
+S: Maintained
+F: Documentation/devicetree/bindings/soc/fsl/
+F: drivers/soc/fsl/
+F: include/linux/fsl/
+
+FREESCALE SOC FS_ENET DRIVER
+M: Pantelis Antoniou <pantelis.antoniou@gmail.com>
+M: Vitaly Bordug <vbordug@ru.mvista.com>
+L: linuxppc-dev@lists.ozlabs.org
+L: netdev@vger.kernel.org
+S: Maintained
+F: drivers/net/ethernet/freescale/fs_enet/
+F: include/linux/fs_enet_pd.h
+
FREESCALE SOC SOUND DRIVERS
M: Timur Tabi <timur@tabi.org>
M: Nicolin Chen <nicoleotsuka@gmail.com>
@@ -5530,6 +5532,13 @@ F: sound/soc/fsl/fsl*
F: sound/soc/fsl/imx*
F: sound/soc/fsl/mpc8610_hpcd.c
+FREESCALE USB PERIPHERAL DRIVERS
+M: Li Yang <leoyang.li@nxp.com>
+L: linux-usb@vger.kernel.org
+L: linuxppc-dev@lists.ozlabs.org
+S: Maintained
+F: drivers/usb/gadget/udc/fsl*
+
FREEVXFS FILESYSTEM
M: Christoph Hellwig <hch@infradead.org>
W: ftp://ftp.openlinux.org/pub/people/hch/vxfs
@@ -5570,19 +5579,6 @@ S: Supported
F: fs/crypto/
F: include/linux/fscrypt*.h
-F2FS FILE SYSTEM
-M: Jaegeuk Kim <jaegeuk@kernel.org>
-M: Chao Yu <yuchao0@huawei.com>
-L: linux-f2fs-devel@lists.sourceforge.net
-W: https://f2fs.wiki.kernel.org/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git
-S: Maintained
-F: Documentation/filesystems/f2fs.txt
-F: Documentation/ABI/testing/sysfs-fs-f2fs
-F: fs/f2fs/
-F: include/linux/f2fs_fs.h
-F: include/trace/events/f2fs.h
-
FUJITSU FR-V (FRV) PORT
S: Orphan
F: arch/frv/
@@ -5656,6 +5652,12 @@ S: Maintained
F: kernel/gcov/
F: Documentation/dev-tools/gcov.rst
+GDB KERNEL DEBUGGING HELPER SCRIPTS
+M: Jan Kiszka <jan.kiszka@siemens.com>
+M: Kieran Bingham <kieran@bingham.xyz>
+S: Supported
+F: scripts/gdb/
+
GDT SCSI DISK ARRAY CONTROLLER DRIVER
M: Achim Leubner <achim_leubner@adaptec.com>
L: linux-scsi@vger.kernel.org
@@ -5663,12 +5665,6 @@ W: http://www.icp-vortex.com/
S: Supported
F: drivers/scsi/gdt*
-GDB KERNEL DEBUGGING HELPER SCRIPTS
-M: Jan Kiszka <jan.kiszka@siemens.com>
-M: Kieran Bingham <kieran@bingham.xyz>
-S: Supported
-F: scripts/gdb/
-
GEMTEK FM RADIO RECEIVER DRIVER
M: Hans Verkuil <hverkuil@xs4all.nl>
L: linux-media@vger.kernel.org
@@ -5735,17 +5731,17 @@ L: kvm@vger.kernel.org
S: Supported
F: drivers/uio/uio_pci_generic.c
-GET_MAINTAINER SCRIPT
-M: Joe Perches <joe@perches.com>
-S: Maintained
-F: scripts/get_maintainer.pl
-
GENWQE (IBM Generic Workqueue Card)
M: Frank Haverkamp <haver@linux.vnet.ibm.com>
M: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
S: Supported
F: drivers/misc/genwqe/
+GET_MAINTAINER SCRIPT
+M: Joe Perches <joe@perches.com>
+S: Maintained
+F: scripts/get_maintainer.pl
+
GFS2 FILE SYSTEM
M: Steven Whitehouse <swhiteho@redhat.com>
M: Bob Peterson <rpeterso@redhat.com>
@@ -5778,6 +5774,15 @@ L: linux-input@vger.kernel.org
S: Maintained
F: drivers/input/touchscreen/goodix.c
+GPIO ACPI SUPPORT
+M: Mika Westerberg <mika.westerberg@linux.intel.com>
+M: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+L: linux-gpio@vger.kernel.org
+L: linux-acpi@vger.kernel.org
+S: Maintained
+F: Documentation/acpi/gpio-properties.txt
+F: drivers/gpio/gpiolib-acpi.c
+
GPIO MOCKUP DRIVER
M: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
L: linux-gpio@vger.kernel.org
@@ -5801,15 +5806,6 @@ F: include/asm-generic/gpio.h
F: include/uapi/linux/gpio.h
F: tools/gpio/
-GPIO ACPI SUPPORT
-M: Mika Westerberg <mika.westerberg@linux.intel.com>
-M: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-L: linux-gpio@vger.kernel.org
-L: linux-acpi@vger.kernel.org
-S: Maintained
-F: Documentation/acpi/gpio-properties.txt
-F: drivers/gpio/gpiolib-acpi.c
-
GRE DEMULTIPLEXER DRIVER
M: Dmitry Kozlov <xeb@mail.ru>
L: netdev@vger.kernel.org
@@ -5824,14 +5820,6 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/aeroflex/
-GREYBUS SUBSYSTEM
-M: Johan Hovold <johan@kernel.org>
-M: Alex Elder <elder@kernel.org>
-M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-S: Maintained
-F: drivers/staging/greybus/
-L: greybus-dev@lists.linaro.org (moderated for non-subscribers)
-
GREYBUS AUDIO PROTOCOLS DRIVERS
M: Vaibhav Agarwal <vaibhav.sr@gmail.com>
M: Mark Greer <mgreer@animalcreek.com>
@@ -5849,24 +5837,7 @@ F: drivers/staging/greybus/audio_manager_sysfs.c
F: drivers/staging/greybus/audio_module.c
F: drivers/staging/greybus/audio_topology.c
-GREYBUS PROTOCOLS DRIVERS
-M: Rui Miguel Silva <rmfrfs@gmail.com>
-S: Maintained
-F: drivers/staging/greybus/sdio.c
-F: drivers/staging/greybus/light.c
-F: drivers/staging/greybus/gpio.c
-F: drivers/staging/greybus/power_supply.c
-F: drivers/staging/greybus/spi.c
-F: drivers/staging/greybus/spilib.c
-
-GREYBUS PROTOCOLS DRIVERS
-M: Bryan O'Donoghue <pure.logic@nexus-software.ie>
-S: Maintained
-F: drivers/staging/greybus/loopback.c
-F: drivers/staging/greybus/timesync.c
-F: drivers/staging/greybus/timesync_platform.c
-
-GREYBUS PROTOCOLS DRIVERS
+GREYBUS FW/HID/SPI PROTOCOLS DRIVERS
M: Viresh Kumar <vireshk@kernel.org>
S: Maintained
F: drivers/staging/greybus/authentication.c
@@ -5883,11 +5854,12 @@ F: drivers/staging/greybus/spi.c
F: drivers/staging/greybus/spilib.c
F: drivers/staging/greybus/spilib.h
-GREYBUS PROTOCOLS DRIVERS
-M: David Lin <dtwlin@gmail.com>
+GREYBUS LOOPBACK/TIME PROTOCOLS DRIVERS
+M: Bryan O'Donoghue <pure.logic@nexus-software.ie>
S: Maintained
-F: drivers/staging/greybus/uart.c
-F: drivers/staging/greybus/log.c
+F: drivers/staging/greybus/loopback.c
+F: drivers/staging/greybus/timesync.c
+F: drivers/staging/greybus/timesync_platform.c
GREYBUS PLATFORM DRIVERS
M: Vaibhav Hiremath <hvaibhav.linux@gmail.com>
@@ -5896,6 +5868,30 @@ F: drivers/staging/greybus/arche-platform.c
F: drivers/staging/greybus/arche-apb-ctrl.c
F: drivers/staging/greybus/arche_platform.h
+GREYBUS SDIO/GPIO/SPI PROTOCOLS DRIVERS
+M: Rui Miguel Silva <rmfrfs@gmail.com>
+S: Maintained
+F: drivers/staging/greybus/sdio.c
+F: drivers/staging/greybus/light.c
+F: drivers/staging/greybus/gpio.c
+F: drivers/staging/greybus/power_supply.c
+F: drivers/staging/greybus/spi.c
+F: drivers/staging/greybus/spilib.c
+
+GREYBUS SUBSYSTEM
+M: Johan Hovold <johan@kernel.org>
+M: Alex Elder <elder@kernel.org>
+M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+S: Maintained
+F: drivers/staging/greybus/
+L: greybus-dev@lists.linaro.org (moderated for non-subscribers)
+
+GREYBUS UART PROTOCOLS DRIVERS
+M: David Lin <dtwlin@gmail.com>
+S: Maintained
+F: drivers/staging/greybus/uart.c
+F: drivers/staging/greybus/log.c
+
GS1662 VIDEO SERIALIZER
M: Charles-Antoine Couret <charles-antoine.couret@nexvision.fr>
L: linux-media@vger.kernel.org
@@ -5966,13 +5962,6 @@ L: linux-efi@vger.kernel.org
S: Maintained
F: block/partitions/efi.*
-STK1160 USB VIDEO CAPTURE DRIVER
-M: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
-L: linux-media@vger.kernel.org
-T: git git://linuxtv.org/media_tree.git
-S: Maintained
-F: drivers/media/usb/stk1160/
-
H8/300 ARCHITECTURE
M: Yoshinori Sato <ysato@users.sourceforge.jp>
L: uclinux-h8-devel@lists.sourceforge.jp (moderated for non-subscribers)
@@ -5984,33 +5973,6 @@ F: drivers/clocksource/h8300_*.c
F: drivers/clk/h8300/
F: drivers/irqchip/irq-renesas-h8*.c
-HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
-M: Frank Seidel <frank@f-seidel.de>
-L: platform-driver-x86@vger.kernel.org
-W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/
-S: Maintained
-F: drivers/platform/x86/hdaps.c
-
-HDPVR USB VIDEO ENCODER DRIVER
-M: Hans Verkuil <hverkuil@xs4all.nl>
-L: linux-media@vger.kernel.org
-T: git git://linuxtv.org/media_tree.git
-W: https://linuxtv.org
-S: Odd Fixes
-F: drivers/media/usb/hdpvr/
-
-HWPOISON MEMORY FAILURE HANDLING
-M: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
-L: linux-mm@kvack.org
-S: Maintained
-F: mm/memory-failure.c
-F: mm/hwpoison-inject.c
-
-HYPERVISOR VIRTUAL CONSOLE DRIVER
-L: linuxppc-dev@lists.ozlabs.org
-S: Odd Fixes
-F: drivers/tty/hvc/
-
HACKRF MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
@@ -6021,6 +5983,13 @@ T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained
F: drivers/media/usb/hackrf/
+HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
+M: Frank Seidel <frank@f-seidel.de>
+L: platform-driver-x86@vger.kernel.org
+W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/
+S: Maintained
+F: drivers/platform/x86/hdaps.c
+
HARDWARE MONITORING
M: Jean Delvare <jdelvare@suse.com>
M: Guenter Roeck <linux@roeck-us.net>
@@ -6059,6 +6028,14 @@ L: linux-parisc@vger.kernel.org
S: Maintained
F: sound/parisc/harmony.*
+HDPVR USB VIDEO ENCODER DRIVER
+M: Hans Verkuil <hverkuil@xs4all.nl>
+L: linux-media@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+W: https://linuxtv.org
+S: Odd Fixes
+F: drivers/media/usb/hdpvr/
+
HEWLETT PACKARD ENTERPRISE ILO NMI WATCHDOG DRIVER
M: Jimmy Vance <jimmy.vance@hpe.com>
S: Supported
@@ -6085,13 +6062,6 @@ F: drivers/block/cciss*
F: include/linux/cciss_ioctl.h
F: include/uapi/linux/cciss_ioctl.h
-OPA-VNIC DRIVER
-M: Dennis Dalessandro <dennis.dalessandro@intel.com>
-M: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
-L: linux-rdma@vger.kernel.org
-S: Supported
-F: drivers/infiniband/ulp/opa_vnic
-
HFI1 DRIVER
M: Mike Marciniszyn <mike.marciniszyn@intel.com>
M: Dennis Dalessandro <dennis.dalessandro@intel.com>
@@ -6269,6 +6239,12 @@ L: netdev@vger.kernel.org
S: Maintained
F: net/hsr/
+HT16K33 LED CONTROLLER DRIVER
+M: Robin van der Gracht <robin@protonic.nl>
+S: Maintained
+F: drivers/auxdisplay/ht16k33.c
+F: Documentation/devicetree/bindings/display/ht16k33.txt
+
HTCPEN TOUCHSCREEN DRIVER
M: Pau Oliva Fora <pof@eslack.org>
L: linux-input@vger.kernel.org
@@ -6288,6 +6264,13 @@ W: https://linuxtv.org
S: Supported
F: drivers/media/platform/sti/hva
+HWPOISON MEMORY FAILURE HANDLING
+M: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
+L: linux-mm@kvack.org
+S: Maintained
+F: mm/memory-failure.c
+F: mm/hwpoison-inject.c
+
Hyper-V CORE AND DRIVERS
M: "K. Y. Srinivasan" <kys@microsoft.com>
M: Haiyang Zhang <haiyangz@microsoft.com>
@@ -6310,6 +6293,18 @@ F: include/linux/hyperv.h
F: tools/hv/
F: Documentation/ABI/stable/sysfs-bus-vmbus
+HYPERVISOR VIRTUAL CONSOLE DRIVER
+L: linuxppc-dev@lists.ozlabs.org
+S: Odd Fixes
+F: drivers/tty/hvc/
+
+I2C ACPI SUPPORT
+M: Mika Westerberg <mika.westerberg@linux.intel.com>
+L: linux-i2c@vger.kernel.org
+L: linux-acpi@vger.kernel.org
+S: Maintained
+F: drivers/i2c/i2c-core-acpi.c
+
I2C MUXES
M: Peter Rosin <peda@axentia.se>
L: linux-i2c@vger.kernel.org
@@ -6332,6 +6327,36 @@ F: Documentation/i2c/busses/i2c-parport-light
F: drivers/i2c/busses/i2c-parport.c
F: drivers/i2c/busses/i2c-parport-light.c
+I2C SUBSYSTEM
+M: Wolfram Sang <wsa@the-dreams.de>
+L: linux-i2c@vger.kernel.org
+W: https://i2c.wiki.kernel.org/
+Q: https://patchwork.ozlabs.org/project/linux-i2c/list/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git
+S: Maintained
+F: Documentation/devicetree/bindings/i2c/
+F: Documentation/i2c/
+F: drivers/i2c/
+F: drivers/i2c/*/
+F: include/linux/i2c.h
+F: include/linux/i2c-*.h
+F: include/uapi/linux/i2c.h
+F: include/uapi/linux/i2c-*.h
+
+I2C-TAOS-EVM DRIVER
+M: Jean Delvare <jdelvare@suse.com>
+L: linux-i2c@vger.kernel.org
+S: Maintained
+F: Documentation/i2c/busses/i2c-taos-evm
+F: drivers/i2c/busses/i2c-taos-evm.c
+
+I2C-TINY-USB DRIVER
+M: Till Harbaum <till@harbaum.org>
+L: linux-i2c@vger.kernel.org
+W: http://www.harbaum.org/till/i2c_tiny_usb
+S: Maintained
+F: drivers/i2c/busses/i2c-tiny-usb.c
+
I2C/SMBUS CONTROLLER DRIVERS FOR PC
M: Jean Delvare <jdelvare@suse.com>
L: linux-i2c@vger.kernel.org
@@ -6379,43 +6404,6 @@ L: linux-i2c@vger.kernel.org
S: Maintained
F: drivers/i2c/i2c-stub.c
-I2C SUBSYSTEM
-M: Wolfram Sang <wsa@the-dreams.de>
-L: linux-i2c@vger.kernel.org
-W: https://i2c.wiki.kernel.org/
-Q: https://patchwork.ozlabs.org/project/linux-i2c/list/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git
-S: Maintained
-F: Documentation/devicetree/bindings/i2c/
-F: Documentation/i2c/
-F: drivers/i2c/
-F: drivers/i2c/*/
-F: include/linux/i2c.h
-F: include/linux/i2c-*.h
-F: include/uapi/linux/i2c.h
-F: include/uapi/linux/i2c-*.h
-
-I2C ACPI SUPPORT
-M: Mika Westerberg <mika.westerberg@linux.intel.com>
-L: linux-i2c@vger.kernel.org
-L: linux-acpi@vger.kernel.org
-S: Maintained
-F: drivers/i2c/i2c-core-acpi.c
-
-I2C-TAOS-EVM DRIVER
-M: Jean Delvare <jdelvare@suse.com>
-L: linux-i2c@vger.kernel.org
-S: Maintained
-F: Documentation/i2c/busses/i2c-taos-evm
-F: drivers/i2c/busses/i2c-taos-evm.c
-
-I2C-TINY-USB DRIVER
-M: Till Harbaum <till@harbaum.org>
-L: linux-i2c@vger.kernel.org
-W: http://www.harbaum.org/till/i2c_tiny_usb
-S: Maintained
-F: drivers/i2c/busses/i2c-tiny-usb.c
-
i386 BOOT CODE
M: "H. Peter Anvin" <hpa@zytor.com>
S: Maintained
@@ -6434,17 +6422,15 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux.git
S: Maintained
F: arch/ia64/
-IBM Power VMX Cryptographic instructions
-M: Leonidas S. Barbosa <leosilva@linux.vnet.ibm.com>
-M: Paulo Flabiano Smorigo <pfsmorigo@linux.vnet.ibm.com>
-L: linux-crypto@vger.kernel.org
+IBM Power 842 compression accelerator
+M: Haren Myneni <haren@us.ibm.com>
S: Supported
-F: drivers/crypto/vmx/Makefile
-F: drivers/crypto/vmx/Kconfig
-F: drivers/crypto/vmx/vmx.c
-F: drivers/crypto/vmx/aes*
-F: drivers/crypto/vmx/ghash*
-F: drivers/crypto/vmx/ppc-xlate.pl
+F: drivers/crypto/nx/Makefile
+F: drivers/crypto/nx/Kconfig
+F: drivers/crypto/nx/nx-842*
+F: include/linux/sw842.h
+F: crypto/842.c
+F: lib/842/
IBM Power in-Nest Crypto Acceleration
M: Leonidas S. Barbosa <leosilva@linux.vnet.ibm.com>
@@ -6459,33 +6445,29 @@ F: drivers/crypto/nx/nx.*
F: drivers/crypto/nx/nx_csbcpb.h
F: drivers/crypto/nx/nx_debugfs.h
-IBM Power 842 compression accelerator
-M: Haren Myneni <haren@us.ibm.com>
-S: Supported
-F: drivers/crypto/nx/Makefile
-F: drivers/crypto/nx/Kconfig
-F: drivers/crypto/nx/nx-842*
-F: include/linux/sw842.h
-F: crypto/842.c
-F: lib/842/
-
IBM Power Linux RAID adapter
M: Brian King <brking@us.ibm.com>
S: Supported
F: drivers/scsi/ipr.*
-IBM Power Virtual Ethernet Device Driver
+IBM Power SRIOV Virtual NIC Device Driver
M: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
+M: John Allen <jallen@linux.vnet.ibm.com>
L: netdev@vger.kernel.org
S: Supported
-F: drivers/net/ethernet/ibm/ibmveth.*
+F: drivers/net/ethernet/ibm/ibmvnic.*
-IBM Power SRIOV Virtual NIC Device Driver
+IBM Power Virtual Ethernet Device Driver
M: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
-M: John Allen <jallen@linux.vnet.ibm.com>
L: netdev@vger.kernel.org
S: Supported
-F: drivers/net/ethernet/ibm/ibmvnic.*
+F: drivers/net/ethernet/ibm/ibmveth.*
+
+IBM Power Virtual FC Device Drivers
+M: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
+L: linux-scsi@vger.kernel.org
+S: Supported
+F: drivers/scsi/ibmvscsi/ibmvfc*
IBM Power Virtual SCSI Device Drivers
M: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
@@ -6502,11 +6484,17 @@ L: target-devel@vger.kernel.org
S: Supported
F: drivers/scsi/ibmvscsi_tgt/
-IBM Power Virtual FC Device Drivers
-M: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
-L: linux-scsi@vger.kernel.org
+IBM Power VMX Cryptographic instructions
+M: Leonidas S. Barbosa <leosilva@linux.vnet.ibm.com>
+M: Paulo Flabiano Smorigo <pfsmorigo@linux.vnet.ibm.com>
+L: linux-crypto@vger.kernel.org
S: Supported
-F: drivers/scsi/ibmvscsi/ibmvfc*
+F: drivers/crypto/vmx/Makefile
+F: drivers/crypto/vmx/Kconfig
+F: drivers/crypto/vmx/vmx.c
+F: drivers/crypto/vmx/aes*
+F: drivers/crypto/vmx/ghash*
+F: drivers/crypto/vmx/ppc-xlate.pl
IBM ServeRAID RAID DRIVER
S: Orphan
@@ -6518,11 +6506,6 @@ S: Maintained
F: drivers/mfd/lpc_ich.c
F: drivers/gpio/gpio-ich.c
-IDT VersaClock 5 CLOCK DRIVER
-M: Marek Vasut <marek.vasut@gmail.com>
-S: Maintained
-F: drivers/clk/clk-versaclock5.c
-
IDE SUBSYSTEM
M: "David S. Miller" <davem@davemloft.net>
L: linux-ide@vger.kernel.org
@@ -6533,6 +6516,13 @@ F: Documentation/ide/
F: drivers/ide/
F: include/linux/ide.h
+IDE/ATAPI DRIVERS
+M: Borislav Petkov <bp@alien8.de>
+L: linux-ide@vger.kernel.org
+S: Maintained
+F: Documentation/cdrom/ide-cd
+F: drivers/ide/ide-cd*
+
IDEAPAD LAPTOP EXTRAS DRIVER
M: Ike Panhc <ike.pan@canonical.com>
L: platform-driver-x86@vger.kernel.org
@@ -6547,12 +6537,10 @@ W: https://github.com/o2genum/ideapad-slidebar
S: Maintained
F: drivers/input/misc/ideapad_slidebar.c
-IDE/ATAPI DRIVERS
-M: Borislav Petkov <bp@alien8.de>
-L: linux-ide@vger.kernel.org
+IDT VersaClock 5 CLOCK DRIVER
+M: Marek Vasut <marek.vasut@gmail.com>
S: Maintained
-F: Documentation/cdrom/ide-cd
-F: drivers/ide/ide-cd*
+F: drivers/clk/clk-versaclock5.c
IEEE 802.15.4 SUBSYSTEM
M: Alexander Aring <alex.aring@gmail.com>
@@ -6642,6 +6630,16 @@ S: Maintained
F: Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt
F: drivers/auxdisplay/img-ascii-lcd.c
+IMGTEC IR DECODER DRIVER
+M: James Hogan <james.hogan@imgtec.com>
+S: Maintained
+F: drivers/media/rc/img-ir/
+
+IMS TWINTURBO FRAMEBUFFER DRIVER
+L: linux-fbdev@vger.kernel.org
+S: Orphan
+F: drivers/video/fbdev/imsttfb.c
+
INA209 HARDWARE MONITOR DRIVER
M: Guenter Roeck <linux@roeck-us.net>
L: linux-hwmon@vger.kernel.org
@@ -6667,37 +6665,6 @@ W: http://industrypack.sourceforge.net
S: Maintained
F: drivers/ipack/
-INGENIC JZ4780 DMA Driver
-M: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
-S: Maintained
-F: drivers/dma/dma-jz4780.c
-
-INGENIC JZ4780 NAND DRIVER
-M: Harvey Hunt <harveyhuntnexus@gmail.com>
-L: linux-mtd@lists.infradead.org
-S: Maintained
-F: drivers/mtd/nand/jz4780_*
-
-INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
-M: Mimi Zohar <zohar@linux.vnet.ibm.com>
-M: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
-L: linux-ima-devel@lists.sourceforge.net
-L: linux-ima-user@lists.sourceforge.net
-L: linux-security-module@vger.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git
-S: Supported
-F: security/integrity/ima/
-
-IMGTEC IR DECODER DRIVER
-M: James Hogan <james.hogan@imgtec.com>
-S: Maintained
-F: drivers/media/rc/img-ir/
-
-IMS TWINTURBO FRAMEBUFFER DRIVER
-L: linux-fbdev@vger.kernel.org
-S: Orphan
-F: drivers/video/fbdev/imsttfb.c
-
INFINIBAND SUBSYSTEM
M: Doug Ledford <dledford@redhat.com>
M: Sean Hefty <sean.hefty@intel.com>
@@ -6714,6 +6681,17 @@ F: include/uapi/linux/if_infiniband.h
F: include/uapi/rdma/
F: include/rdma/
+INGENIC JZ4780 DMA Driver
+M: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
+S: Maintained
+F: drivers/dma/dma-jz4780.c
+
+INGENIC JZ4780 NAND DRIVER
+M: Harvey Hunt <harveyhuntnexus@gmail.com>
+L: linux-mtd@lists.infradead.org
+S: Maintained
+F: drivers/mtd/nand/jz4780_*
+
INOTIFY
M: John McCutchan <john@johnmccutchan.com>
M: Robert Love <rlove@rlove.org>
@@ -6752,6 +6730,22 @@ F: drivers/crypto/inside-secure/
S: Maintained
L: linux-crypto@vger.kernel.org
+INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
+M: Mimi Zohar <zohar@linux.vnet.ibm.com>
+M: Dmitry Kasatkin <dmitry.kasatkin@gmail.com>
+L: linux-ima-devel@lists.sourceforge.net
+L: linux-ima-user@lists.sourceforge.net
+L: linux-security-module@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git
+S: Supported
+F: security/integrity/ima/
+
+INTEL 810/815 FRAMEBUFFER DRIVER
+M: Antonino Daplas <adaplas@gmail.com>
+L: linux-fbdev@vger.kernel.org
+S: Maintained
+F: drivers/video/fbdev/i810/
+
INTEL ASoC BDW/HSW DRIVERS
M: Jie Yang <yang.jie@linux.intel.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
@@ -6769,17 +6763,75 @@ T: git git://git.code.sf.net/p/intel-sas/isci
S: Supported
F: drivers/scsi/isci/
+INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets)
+M: Jani Nikula <jani.nikula@linux.intel.com>
+M: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+M: Rodrigo Vivi <rodrigo.vivi@intel.com>
+L: intel-gfx@lists.freedesktop.org
+W: https://01.org/linuxgraphics/
+B: https://01.org/linuxgraphics/documentation/how-report-bugs
+C: irc://chat.freenode.net/intel-gfx
+Q: http://patchwork.freedesktop.org/project/intel-gfx/
+T: git git://anongit.freedesktop.org/drm-intel
+S: Supported
+F: drivers/gpu/drm/i915/
+F: include/drm/i915*
+F: include/uapi/drm/i915_drm.h
+F: Documentation/gpu/i915.rst
+
+INTEL ETHERNET DRIVERS
+M: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+L: intel-wired-lan@lists.osuosl.org (moderated for non-subscribers)
+W: http://www.intel.com/support/feedback.htm
+W: http://e1000.sourceforge.net/
+Q: http://patchwork.ozlabs.org/project/intel-wired-lan/list/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-queue.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue.git
+S: Supported
+F: Documentation/networking/e100.txt
+F: Documentation/networking/e1000.txt
+F: Documentation/networking/e1000e.txt
+F: Documentation/networking/igb.txt
+F: Documentation/networking/igbvf.txt
+F: Documentation/networking/ixgb.txt
+F: Documentation/networking/ixgbe.txt
+F: Documentation/networking/ixgbevf.txt
+F: Documentation/networking/i40e.txt
+F: Documentation/networking/i40evf.txt
+F: drivers/net/ethernet/intel/
+F: drivers/net/ethernet/intel/*/
+F: include/linux/avf/virtchnl.h
+
+INTEL FRAMEBUFFER DRIVER (excluding 810 and 815)
+M: Maik Broemme <mbroemme@libmpq.org>
+L: linux-fbdev@vger.kernel.org
+S: Maintained
+F: Documentation/fb/intelfb.txt
+F: drivers/video/fbdev/intelfb/
+
+INTEL GVT-g DRIVERS (Intel GPU Virtualization)
+M: Zhenyu Wang <zhenyuw@linux.intel.com>
+M: Zhi Wang <zhi.a.wang@intel.com>
+L: intel-gvt-dev@lists.freedesktop.org
+L: intel-gfx@lists.freedesktop.org
+W: https://01.org/igvt-g
+T: git https://github.com/01org/gvt-linux.git
+S: Supported
+F: drivers/gpu/drm/i915/gvt/
+
INTEL HID EVENT DRIVER
M: Alex Hung <alex.hung@canonical.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
F: drivers/platform/x86/intel-hid.c
-INTEL VIRTUAL BUTTON DRIVER
-M: AceLan Kao <acelan.kao@canonical.com>
-L: platform-driver-x86@vger.kernel.org
-S: Maintained
-F: drivers/platform/x86/intel-vbtn.c
+INTEL I/OAT DMA DRIVER
+M: Dave Jiang <dave.jiang@intel.com>
+R: Dan Williams <dan.j.williams@intel.com>
+L: dmaengine@vger.kernel.org
+Q: https://patchwork.kernel.org/project/linux-dmaengine/list/
+S: Supported
+F: drivers/dma/ioat*
INTEL IDLE DRIVER
M: Jacob Pan <jacob.jun.pan@linux.intel.com>
@@ -6797,41 +6849,6 @@ L: linux-input@vger.kernel.org
S: Maintained
F: drivers/hid/intel-ish-hid/
-INTEL PSTATE DRIVER
-M: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
-M: Len Brown <lenb@kernel.org>
-L: linux-pm@vger.kernel.org
-S: Supported
-F: drivers/cpufreq/intel_pstate.c
-
-INTEL FRAMEBUFFER DRIVER (excluding 810 and 815)
-M: Maik Broemme <mbroemme@libmpq.org>
-L: linux-fbdev@vger.kernel.org
-S: Maintained
-F: Documentation/fb/intelfb.txt
-F: drivers/video/fbdev/intelfb/
-
-INTEL 810/815 FRAMEBUFFER DRIVER
-M: Antonino Daplas <adaplas@gmail.com>
-L: linux-fbdev@vger.kernel.org
-S: Maintained
-F: drivers/video/fbdev/i810/
-
-INTEL MENLOW THERMAL DRIVER
-M: Sujith Thomas <sujith.thomas@intel.com>
-L: platform-driver-x86@vger.kernel.org
-W: https://01.org/linux-acpi
-S: Supported
-F: drivers/platform/x86/intel_menlow.c
-
-INTEL I/OAT DMA DRIVER
-M: Dave Jiang <dave.jiang@intel.com>
-R: Dan Williams <dan.j.williams@intel.com>
-L: dmaengine@vger.kernel.org
-Q: https://patchwork.kernel.org/project/linux-dmaengine/list/
-S: Supported
-F: drivers/dma/ioat*
-
INTEL IOMMU (VT-d)
M: David Woodhouse <dwmw2@infradead.org>
L: iommu@lists.linux-foundation.org
@@ -6860,35 +6877,23 @@ M: Deepak Saxena <dsaxena@plexity.net>
S: Maintained
F: drivers/char/hw_random/ixp4xx-rng.c
-INTEL ETHERNET DRIVERS
-M: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-L: intel-wired-lan@lists.osuosl.org (moderated for non-subscribers)
-W: http://www.intel.com/support/feedback.htm
-W: http://e1000.sourceforge.net/
-Q: http://patchwork.ozlabs.org/project/intel-wired-lan/list/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-queue.git
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue.git
+INTEL MANAGEMENT ENGINE (mei)
+M: Tomas Winkler <tomas.winkler@intel.com>
+L: linux-kernel@vger.kernel.org
S: Supported
-F: Documentation/networking/e100.txt
-F: Documentation/networking/e1000.txt
-F: Documentation/networking/e1000e.txt
-F: Documentation/networking/igb.txt
-F: Documentation/networking/igbvf.txt
-F: Documentation/networking/ixgb.txt
-F: Documentation/networking/ixgbe.txt
-F: Documentation/networking/ixgbevf.txt
-F: Documentation/networking/i40e.txt
-F: Documentation/networking/i40evf.txt
-F: drivers/net/ethernet/intel/
-F: drivers/net/ethernet/intel/*/
-F: include/linux/avf/virtchnl.h
+F: include/uapi/linux/mei.h
+F: include/linux/mei_cl_bus.h
+F: drivers/misc/mei/*
+F: drivers/watchdog/mei_wdt.c
+F: Documentation/misc-devices/mei/*
+F: samples/mei/*
-INTEL RDMA RNIC DRIVER
-M: Faisal Latif <faisal.latif@intel.com>
-M: Shiraz Saleem <shiraz.saleem@intel.com>
-L: linux-rdma@vger.kernel.org
-S: Supported
-F: drivers/infiniband/hw/i40iw/
+INTEL MENLOW THERMAL DRIVER
+M: Sujith Thomas <sujith.thomas@intel.com>
+L: platform-driver-x86@vger.kernel.org
+W: https://01.org/linux-acpi
+S: Supported
+F: drivers/platform/x86/intel_menlow.c
INTEL MERRIFIELD GPIO DRIVER
M: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
@@ -6896,11 +6901,38 @@ L: linux-gpio@vger.kernel.org
S: Maintained
F: drivers/gpio/gpio-merrifield.c
-INTEL-MID GPIO DRIVER
-M: David Cohen <david.a.cohen@linux.intel.com>
-L: linux-gpio@vger.kernel.org
+INTEL MIC DRIVERS (mic)
+M: Sudeep Dutt <sudeep.dutt@intel.com>
+M: Ashutosh Dixit <ashutosh.dixit@intel.com>
+S: Supported
+W: https://github.com/sudeepdutt/mic
+W: http://software.intel.com/en-us/mic-developer
+F: include/linux/mic_bus.h
+F: include/linux/scif.h
+F: include/uapi/linux/mic_common.h
+F: include/uapi/linux/mic_ioctl.h
+F: include/uapi/linux/scif_ioctl.h
+F: drivers/misc/mic/
+F: drivers/dma/mic_x100_dma.c
+F: drivers/dma/mic_x100_dma.h
+F: Documentation/mic/
+
+INTEL PMC CORE DRIVER
+M: Rajneesh Bhardwaj <rajneesh.bhardwaj@intel.com>
+M: Vishwanath Somayaji <vishwanath.somayaji@intel.com>
+L: platform-driver-x86@vger.kernel.org
S: Maintained
-F: drivers/gpio/gpio-intel-mid.c
+F: arch/x86/include/asm/pmc_core.h
+F: drivers/platform/x86/intel_pmc_core*
+
+INTEL PMC/P-Unit IPC DRIVER
+M: Zha Qipeng<qipeng.zha@intel.com>
+L: platform-driver-x86@vger.kernel.org
+S: Maintained
+F: drivers/platform/x86/intel_pmc_ipc.c
+F: drivers/platform/x86/intel_punit_ipc.c
+F: arch/x86/include/asm/intel_pmc_ipc.h
+F: arch/x86/include/asm/intel_punit_ipc.h
INTEL PRO/WIRELESS 2100, 2200BG, 2915ABG NETWORK CONNECTION SUPPORT
M: Stanislav Yakovlev <stas.yakovlev@gmail.com>
@@ -6910,31 +6942,32 @@ F: Documentation/networking/README.ipw2100
F: Documentation/networking/README.ipw2200
F: drivers/net/wireless/intel/ipw2x00/
-INTEL(R) TRACE HUB
-M: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+INTEL PSTATE DRIVER
+M: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+M: Len Brown <lenb@kernel.org>
+L: linux-pm@vger.kernel.org
S: Supported
-F: Documentation/trace/intel_th.txt
-F: drivers/hwtracing/intel_th/
+F: drivers/cpufreq/intel_pstate.c
-INTEL(R) TRUSTED EXECUTION TECHNOLOGY (TXT)
-M: Ning Sun <ning.sun@intel.com>
-L: tboot-devel@lists.sourceforge.net
-W: http://tboot.sourceforge.net
-T: hg http://tboot.hg.sourceforge.net:8000/hgroot/tboot/tboot
+INTEL RDMA RNIC DRIVER
+M: Faisal Latif <faisal.latif@intel.com>
+M: Shiraz Saleem <shiraz.saleem@intel.com>
+L: linux-rdma@vger.kernel.org
S: Supported
-F: Documentation/intel_txt.txt
-F: include/linux/tboot.h
-F: arch/x86/kernel/tboot.c
+F: drivers/infiniband/hw/i40iw/
-INTEL WIRELESS WIMAX CONNECTION 2400
-M: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
-M: linux-wimax@intel.com
-L: wimax@linuxwimax.org (subscribers-only)
-S: Supported
-W: http://linuxwimax.org
-F: Documentation/wimax/README.i2400m
-F: drivers/net/wimax/i2400m/
-F: include/uapi/linux/wimax/i2400m.h
+INTEL TELEMETRY DRIVER
+M: Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>
+L: platform-driver-x86@vger.kernel.org
+S: Maintained
+F: arch/x86/include/asm/intel_telemetry.h
+F: drivers/platform/x86/intel_telemetry*
+
+INTEL VIRTUAL BUTTON DRIVER
+M: AceLan Kao <acelan.kao@canonical.com>
+L: platform-driver-x86@vger.kernel.org
+S: Maintained
+F: drivers/platform/x86/intel-vbtn.c
INTEL WIRELESS 3945ABG/BG, 4965AGN (iwlegacy)
M: Stanislaw Gruszka <sgruszka@redhat.com>
@@ -6953,56 +6986,37 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi.git
S: Supported
F: drivers/net/wireless/intel/iwlwifi/
-INTEL MANAGEMENT ENGINE (mei)
-M: Tomas Winkler <tomas.winkler@intel.com>
-L: linux-kernel@vger.kernel.org
+INTEL WIRELESS WIMAX CONNECTION 2400
+M: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+M: linux-wimax@intel.com
+L: wimax@linuxwimax.org (subscribers-only)
S: Supported
-F: include/uapi/linux/mei.h
-F: include/linux/mei_cl_bus.h
-F: drivers/misc/mei/*
-F: drivers/watchdog/mei_wdt.c
-F: Documentation/misc-devices/mei/*
-F: samples/mei/*
+W: http://linuxwimax.org
+F: Documentation/wimax/README.i2400m
+F: drivers/net/wimax/i2400m/
+F: include/uapi/linux/wimax/i2400m.h
-INTEL MIC DRIVERS (mic)
-M: Sudeep Dutt <sudeep.dutt@intel.com>
-M: Ashutosh Dixit <ashutosh.dixit@intel.com>
+INTEL(R) TRACE HUB
+M: Alexander Shishkin <alexander.shishkin@linux.intel.com>
S: Supported
-W: https://github.com/sudeepdutt/mic
-W: http://software.intel.com/en-us/mic-developer
-F: include/linux/mic_bus.h
-F: include/linux/scif.h
-F: include/uapi/linux/mic_common.h
-F: include/uapi/linux/mic_ioctl.h
-F: include/uapi/linux/scif_ioctl.h
-F: drivers/misc/mic/
-F: drivers/dma/mic_x100_dma.c
-F: drivers/dma/mic_x100_dma.h
-F: Documentation/mic/
-
-INTEL PMC/P-Unit IPC DRIVER
-M: Zha Qipeng<qipeng.zha@intel.com>
-L: platform-driver-x86@vger.kernel.org
-S: Maintained
-F: drivers/platform/x86/intel_pmc_ipc.c
-F: drivers/platform/x86/intel_punit_ipc.c
-F: arch/x86/include/asm/intel_pmc_ipc.h
-F: arch/x86/include/asm/intel_punit_ipc.h
+F: Documentation/trace/intel_th.txt
+F: drivers/hwtracing/intel_th/
-INTEL TELEMETRY DRIVER
-M: Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>
-L: platform-driver-x86@vger.kernel.org
-S: Maintained
-F: arch/x86/include/asm/intel_telemetry.h
-F: drivers/platform/x86/intel_telemetry*
+INTEL(R) TRUSTED EXECUTION TECHNOLOGY (TXT)
+M: Ning Sun <ning.sun@intel.com>
+L: tboot-devel@lists.sourceforge.net
+W: http://tboot.sourceforge.net
+T: hg http://tboot.hg.sourceforge.net:8000/hgroot/tboot/tboot
+S: Supported
+F: Documentation/intel_txt.txt
+F: include/linux/tboot.h
+F: arch/x86/kernel/tboot.c
-INTEL PMC CORE DRIVER
-M: Rajneesh Bhardwaj <rajneesh.bhardwaj@intel.com>
-M: Vishwanath Somayaji <vishwanath.somayaji@intel.com>
-L: platform-driver-x86@vger.kernel.org
+INTEL-MID GPIO DRIVER
+M: David Cohen <david.a.cohen@linux.intel.com>
+L: linux-gpio@vger.kernel.org
S: Maintained
-F: arch/x86/include/asm/pmc_core.h
-F: drivers/platform/x86/intel_pmc_core*
+F: drivers/gpio/gpio-intel-mid.c
INVENSENSE MPU-3050 GYROSCOPE DRIVER
M: Linus Walleij <linus.walleij@linaro.org>
@@ -7048,13 +7062,6 @@ F: drivers/char/ipmi/
F: include/linux/ipmi*
F: include/uapi/linux/ipmi*
-QCOM AUDIO (ASoC) DRIVERS
-M: Patrick Lai <plai@codeaurora.org>
-M: Banajit Goswami <bgoswami@codeaurora.org>
-L: alsa-devel@alsa-project.org (moderated for non-subscribers)
-S: Supported
-F: sound/soc/qcom/
-
IPS SCSI RAID DRIVER
M: Adaptec OEM Raid Solutions <aacraid@adaptec.com>
L: linux-scsi@vger.kernel.org
@@ -7101,6 +7108,15 @@ F: drivers/net/irda/
F: include/net/irda/
F: net/irda/
+IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY)
+M: Marc Zyngier <marc.zyngier@arm.com>
+S: Maintained
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
+F: Documentation/IRQ-domain.txt
+F: include/linux/irqdomain.h
+F: kernel/irq/irqdomain.c
+F: kernel/irq/msi.c
+
IRQ SUBSYSTEM
M: Thomas Gleixner <tglx@linutronix.de>
L: linux-kernel@vger.kernel.org
@@ -7119,15 +7135,6 @@ T: git git://git.infradead.org/users/jcooper/linux.git irqchip/core
F: Documentation/devicetree/bindings/interrupt-controller/
F: drivers/irqchip/
-IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY)
-M: Marc Zyngier <marc.zyngier@arm.com>
-S: Maintained
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
-F: Documentation/IRQ-domain.txt
-F: include/linux/irqdomain.h
-F: kernel/irq/irqdomain.c
-F: kernel/irq/msi.c
-
ISA
M: William Breathitt Gray <vilhelm.gray@gmail.com>
S: Maintained
@@ -7135,13 +7142,6 @@ F: Documentation/isa.txt
F: drivers/base/isa.c
F: include/linux/isa.h
-ISAPNP
-M: Jaroslav Kysela <perex@perex.cz>
-S: Maintained
-F: Documentation/isapnp.txt
-F: drivers/pnp/isapnp/
-F: include/linux/isapnp.h
-
ISA RADIO MODULE
M: Hans Verkuil <hverkuil@xs4all.nl>
L: linux-media@vger.kernel.org
@@ -7150,11 +7150,12 @@ W: https://linuxtv.org
S: Maintained
F: drivers/media/radio/radio-isa*
-iSCSI BOOT FIRMWARE TABLE (iBFT) DRIVER
-M: Peter Jones <pjones@redhat.com>
-M: Konrad Rzeszutek Wilk <konrad@kernel.org>
+ISAPNP
+M: Jaroslav Kysela <perex@perex.cz>
S: Maintained
-F: drivers/firmware/iscsi_ibft*
+F: Documentation/isapnp.txt
+F: drivers/pnp/isapnp/
+F: include/linux/isapnp.h
ISCSI
M: Lee Duncan <lduncan@suse.com>
@@ -7165,6 +7166,12 @@ S: Maintained
F: drivers/scsi/*iscsi*
F: include/scsi/*iscsi*
+iSCSI BOOT FIRMWARE TABLE (iBFT) DRIVER
+M: Peter Jones <pjones@redhat.com>
+M: Konrad Rzeszutek Wilk <konrad@kernel.org>
+S: Maintained
+F: drivers/firmware/iscsi_ibft*
+
ISCSI EXTENSIONS FOR RDMA (ISER) INITIATOR
M: Or Gerlitz <ogerlitz@mellanox.com>
M: Sagi Grimberg <sagi@grimberg.me>
@@ -7420,27 +7427,6 @@ S: Maintained
F: arch/x86/include/asm/svm.h
F: arch/x86/kvm/svm.c
-KERNEL VIRTUAL MACHINE (KVM) FOR POWERPC
-M: Alexander Graf <agraf@suse.com>
-L: kvm-ppc@vger.kernel.org
-W: http://www.linux-kvm.org/
-T: git git://github.com/agraf/linux-2.6.git
-S: Supported
-F: arch/powerpc/include/asm/kvm*
-F: arch/powerpc/kvm/
-
-KERNEL VIRTUAL MACHINE for s390 (KVM/s390)
-M: Christian Borntraeger <borntraeger@de.ibm.com>
-M: Cornelia Huck <cohuck@redhat.com>
-L: linux-s390@vger.kernel.org
-W: http://www.ibm.com/developerworks/linux/linux390/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git
-S: Supported
-F: Documentation/s390/kvm.txt
-F: arch/s390/include/asm/kvm*
-F: arch/s390/kvm/
-F: arch/s390/mm/gmap.c
-
KERNEL VIRTUAL MACHINE (KVM) FOR ARM
M: Christoffer Dall <christoffer.dall@linaro.org>
M: Marc Zyngier <marc.zyngier@arm.com>
@@ -7455,6 +7441,15 @@ F: arch/arm/kvm/
F: virt/kvm/arm/
F: include/kvm/arm_*
+KERNEL VIRTUAL MACHINE (KVM) FOR POWERPC
+M: Alexander Graf <agraf@suse.com>
+L: kvm-ppc@vger.kernel.org
+W: http://www.linux-kvm.org/
+T: git git://github.com/agraf/linux-2.6.git
+S: Supported
+F: arch/powerpc/include/asm/kvm*
+F: arch/powerpc/kvm/
+
KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64)
M: Christoffer Dall <christoffer.dall@linaro.org>
M: Marc Zyngier <marc.zyngier@arm.com>
@@ -7473,6 +7468,18 @@ F: arch/mips/include/uapi/asm/kvm*
F: arch/mips/include/asm/kvm*
F: arch/mips/kvm/
+KERNEL VIRTUAL MACHINE for s390 (KVM/s390)
+M: Christian Borntraeger <borntraeger@de.ibm.com>
+M: Cornelia Huck <cohuck@redhat.com>
+L: linux-s390@vger.kernel.org
+W: http://www.ibm.com/developerworks/linux/linux390/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git
+S: Supported
+F: Documentation/s390/kvm.txt
+F: arch/s390/include/asm/kvm*
+F: arch/s390/kvm/
+F: arch/s390/mm/gmap.c
+
KERNFS
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
M: Tejun Heo <tj@kernel.org>
@@ -7490,17 +7497,15 @@ F: include/linux/kexec.h
F: include/uapi/linux/kexec.h
F: kernel/kexec*
-KEYS/KEYRINGS:
-M: David Howells <dhowells@redhat.com>
+KEYS-ENCRYPTED
+M: Mimi Zohar <zohar@linux.vnet.ibm.com>
+M: David Safford <safford@us.ibm.com>
+L: linux-security-module@vger.kernel.org
L: keyrings@vger.kernel.org
-S: Maintained
-F: Documentation/security/keys/core.rst
-F: include/linux/key.h
-F: include/linux/key-type.h
-F: include/linux/keyctl.h
-F: include/uapi/linux/keyctl.h
-F: include/keys/
-F: security/keys/
+S: Supported
+F: Documentation/security/keys/trusted-encrypted.rst
+F: include/keys/encrypted-type.h
+F: security/keys/encrypted-keys/
KEYS-TRUSTED
M: David Safford <safford@us.ibm.com>
@@ -7513,15 +7518,17 @@ F: include/keys/trusted-type.h
F: security/keys/trusted.c
F: security/keys/trusted.h
-KEYS-ENCRYPTED
-M: Mimi Zohar <zohar@linux.vnet.ibm.com>
-M: David Safford <safford@us.ibm.com>
-L: linux-security-module@vger.kernel.org
+KEYS/KEYRINGS:
+M: David Howells <dhowells@redhat.com>
L: keyrings@vger.kernel.org
-S: Supported
-F: Documentation/security/keys/trusted-encrypted.rst
-F: include/keys/encrypted-type.h
-F: security/keys/encrypted-keys/
+S: Maintained
+F: Documentation/security/keys/core.rst
+F: include/linux/key.h
+F: include/linux/key-type.h
+F: include/linux/keyctl.h
+F: include/uapi/linux/keyctl.h
+F: include/keys/
+F: security/keys/
KGDB / KDB /debug_core
M: Jason Wessel <jason.wessel@windriver.com>
@@ -7665,16 +7672,6 @@ F: drivers/lguest/
F: include/linux/lguest*.h
F: tools/lguest/
-LIBATA SUBSYSTEM (Serial and Parallel ATA drivers)
-M: Tejun Heo <tj@kernel.org>
-L: linux-ide@vger.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
-S: Maintained
-F: drivers/ata/
-F: include/linux/ata.h
-F: include/linux/libata.h
-F: Documentation/devicetree/bindings/ata/
-
LIBATA PATA ARASAN COMPACT FLASH CONTROLLER
M: Viresh Kumar <vireshk@kernel.org>
L: linux-ide@vger.kernel.org
@@ -7718,22 +7715,21 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
S: Maintained
F: drivers/ata/sata_promise.*
+LIBATA SUBSYSTEM (Serial and Parallel ATA drivers)
+M: Tejun Heo <tj@kernel.org>
+L: linux-ide@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
+S: Maintained
+F: drivers/ata/
+F: include/linux/ata.h
+F: include/linux/libata.h
+F: Documentation/devicetree/bindings/ata/
+
LIBLOCKDEP
M: Sasha Levin <alexander.levin@verizon.com>
S: Maintained
F: tools/lib/lockdep/
-LIBNVDIMM: NON-VOLATILE MEMORY DEVICE SUBSYSTEM
-M: Dan Williams <dan.j.williams@intel.com>
-L: linux-nvdimm@lists.01.org
-Q: https://patchwork.kernel.org/project/linux-nvdimm/list/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git
-S: Supported
-F: drivers/nvdimm/*
-F: include/linux/nd.h
-F: include/linux/libnvdimm.h
-F: include/uapi/linux/ndctl.h
-
LIBNVDIMM BLK: MMIO-APERTURE DRIVER
M: Ross Zwisler <ross.zwisler@linux.intel.com>
L: linux-nvdimm@lists.01.org
@@ -7741,7 +7737,6 @@ Q: https://patchwork.kernel.org/project/linux-nvdimm/list/
S: Supported
F: drivers/nvdimm/blk.c
F: drivers/nvdimm/region_devs.c
-F: drivers/acpi/nfit*
LIBNVDIMM BTT: BLOCK TRANSLATION TABLE
M: Vishal Verma <vishal.l.verma@intel.com>
@@ -7757,6 +7752,18 @@ Q: https://patchwork.kernel.org/project/linux-nvdimm/list/
S: Supported
F: drivers/nvdimm/pmem*
+LIBNVDIMM: NON-VOLATILE MEMORY DEVICE SUBSYSTEM
+M: Dan Williams <dan.j.williams@intel.com>
+L: linux-nvdimm@lists.01.org
+Q: https://patchwork.kernel.org/project/linux-nvdimm/list/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git
+S: Supported
+F: drivers/nvdimm/*
+F: drivers/acpi/nfit/*
+F: include/linux/nd.h
+F: include/linux/libnvdimm.h
+F: include/uapi/linux/ndctl.h
+
LIGHTNVM PLATFORM SUPPORT
M: Matias Bjorling <mb@lightnvm.io>
W: http://github/OpenChannelSSD
@@ -7766,6 +7773,14 @@ F: drivers/lightnvm/
F: include/linux/lightnvm.h
F: include/uapi/linux/lightnvm.h
+LINUX FOR POWER MACINTOSH
+M: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+W: http://www.penguinppc.org/
+L: linuxppc-dev@lists.ozlabs.org
+S: Maintained
+F: arch/powerpc/platforms/powermac/
+F: drivers/macintosh/
+
LINUX FOR POWERPC (32-BIT AND 64-BIT)
M: Benjamin Herrenschmidt <benh@kernel.crashing.org>
M: Paul Mackerras <paulus@samba.org>
@@ -7799,14 +7814,6 @@ N: powernv
N: [^a-z0-9]ps3
N: pseries
-LINUX FOR POWER MACINTOSH
-M: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-W: http://www.penguinppc.org/
-L: linuxppc-dev@lists.ozlabs.org
-S: Maintained
-F: arch/powerpc/platforms/powermac/
-F: drivers/macintosh/
-
LINUX FOR POWERPC EMBEDDED MPC5XXX
M: Anatolij Gustschin <agust@denx.de>
L: linuxppc-dev@lists.ozlabs.org
@@ -7824,19 +7831,6 @@ S: Maintained
F: arch/powerpc/platforms/40x/
F: arch/powerpc/platforms/44x/
-LINUX FOR POWERPC EMBEDDED XILINX VIRTEX
-L: linuxppc-dev@lists.ozlabs.org
-S: Orphan
-F: arch/powerpc/*/*virtex*
-F: arch/powerpc/*/*/*virtex*
-
-LINUX FOR POWERPC EMBEDDED PPC8XX
-M: Vitaly Bordug <vitb@kernel.crashing.org>
-W: http://www.penguinppc.org/
-L: linuxppc-dev@lists.ozlabs.org
-S: Maintained
-F: arch/powerpc/platforms/8xx/
-
LINUX FOR POWERPC EMBEDDED PPC83XX AND PPC85XX
M: Scott Wood <oss@buserror.net>
M: Kumar Gala <galak@kernel.crashing.org>
@@ -7848,6 +7842,19 @@ F: arch/powerpc/platforms/83xx/
F: arch/powerpc/platforms/85xx/
F: Documentation/devicetree/bindings/powerpc/fsl/
+LINUX FOR POWERPC EMBEDDED PPC8XX
+M: Vitaly Bordug <vitb@kernel.crashing.org>
+W: http://www.penguinppc.org/
+L: linuxppc-dev@lists.ozlabs.org
+S: Maintained
+F: arch/powerpc/platforms/8xx/
+
+LINUX FOR POWERPC EMBEDDED XILINX VIRTEX
+L: linuxppc-dev@lists.ozlabs.org
+S: Orphan
+F: arch/powerpc/*/*virtex*
+F: arch/powerpc/*/*/*virtex*
+
LINUX FOR POWERPC PA SEMI PWRFICIENT
L: linuxppc-dev@lists.ozlabs.org
S: Orphan
@@ -7855,6 +7862,11 @@ F: arch/powerpc/platforms/pasemi/
F: drivers/*/*pasemi*
F: drivers/*/*/*pasemi*
+LINUX KERNEL DUMP TEST MODULE (LKDTM)
+M: Kees Cook <keescook@chromium.org>
+S: Maintained
+F: drivers/misc/lkdtm*
+
LINUX SECURITY MODULE (LSM) FRAMEWORK
M: Chris Wright <chrisw@sous-sol.org>
L: linux-security-module@vger.kernel.org
@@ -7884,11 +7896,6 @@ F: samples/livepatch/
L: live-patching@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/livepatching.git
-LINUX KERNEL DUMP TEST MODULE (LKDTM)
-M: Kees Cook <keescook@chromium.org>
-S: Maintained
-F: drivers/misc/lkdtm*
-
LLC (802.2)
L: netdev@vger.kernel.org
S: Odd fixes
@@ -7941,6 +7948,13 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/
S: Maintained
F: drivers/media/usb/dvb-usb-v2/lmedm04*
+LOADPIN SECURITY MODULE
+M: Kees Cook <keescook@chromium.org>
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git lsm/loadpin
+S: Supported
+F: security/loadpin/
+F: Documentation/admin-guide/LSM/LoadPin.rst
+
LOCKING PRIMITIVES
M: Peter Zijlstra <peterz@infradead.org>
M: Ingo Molnar <mingo@redhat.com>
@@ -8231,14 +8245,6 @@ S: Maintained
F: Documentation/devicetree/bindings/sound/max9860.txt
F: sound/soc/codecs/max9860.*
-MAXIM MUIC CHARGER DRIVERS FOR EXYNOS BASED BOARDS
-M: Krzysztof Kozlowski <krzk@kernel.org>
-M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-L: linux-pm@vger.kernel.org
-S: Supported
-F: drivers/power/supply/max14577_charger.c
-F: drivers/power/supply/max77693_charger.c
-
MAXIM MAX77802 PMIC REGULATOR DEVICE DRIVER
M: Javier Martinez Canillas <javier@dowhile0.org>
L: linux-kernel@vger.kernel.org
@@ -8247,6 +8253,14 @@ F: drivers/regulator/max77802-regulator.c
F: Documentation/devicetree/bindings/*/*max77802.txt
F: include/dt-bindings/*/*max77802.h
+MAXIM MUIC CHARGER DRIVERS FOR EXYNOS BASED BOARDS
+M: Krzysztof Kozlowski <krzk@kernel.org>
+M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+L: linux-pm@vger.kernel.org
+S: Supported
+F: drivers/power/supply/max14577_charger.c
+F: drivers/power/supply/max77693_charger.c
+
MAXIM PMIC AND MUIC DRIVERS FOR EXYNOS BASED BOARDS
M: Chanwoo Choi <cw00.choi@samsung.com>
M: Krzysztof Kozlowski <krzk@kernel.org>
@@ -8289,14 +8303,25 @@ L: linux-iio@vger.kernel.org
S: Maintained
F: drivers/iio/dac/cio-dac.c
-MEDIA DRIVERS FOR RENESAS - DRIF
-M: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>
+MEDIA DRIVERS FOR ASCOT2E
+M: Sergey Kozlov <serjk@netup.ru>
+M: Abylay Ospan <aospan@netup.ru>
L: linux-media@vger.kernel.org
-L: linux-renesas-soc@vger.kernel.org
+W: https://linuxtv.org
+W: http://netup.tv/
T: git git://linuxtv.org/media_tree.git
S: Supported
-F: Documentation/devicetree/bindings/media/renesas,drif.txt
-F: drivers/media/platform/rcar_drif.c
+F: drivers/media/dvb-frontends/ascot2e*
+
+MEDIA DRIVERS FOR CXD2841ER
+M: Sergey Kozlov <serjk@netup.ru>
+M: Abylay Ospan <aospan@netup.ru>
+L: linux-media@vger.kernel.org
+W: https://linuxtv.org
+W: http://netup.tv/
+T: git git://linuxtv.org/media_tree.git
+S: Supported
+F: drivers/media/dvb-frontends/cxd2841er*
MEDIA DRIVERS FOR FREESCALE IMX
M: Steve Longerbeam <slongerbeam@gmail.com>
@@ -8310,43 +8335,6 @@ F: drivers/staging/media/imx/
F: include/linux/imx-media.h
F: include/media/imx.h
-MEDIA DRIVERS FOR RENESAS - FCP
-M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-L: linux-media@vger.kernel.org
-L: linux-renesas-soc@vger.kernel.org
-T: git git://linuxtv.org/media_tree.git
-S: Supported
-F: Documentation/devicetree/bindings/media/renesas,fcp.txt
-F: drivers/media/platform/rcar-fcp.c
-F: include/media/rcar-fcp.h
-
-MEDIA DRIVERS FOR RENESAS - FDP1
-M: Kieran Bingham <kieran@bingham.xyz>
-L: linux-media@vger.kernel.org
-L: linux-renesas-soc@vger.kernel.org
-T: git git://linuxtv.org/media_tree.git
-S: Supported
-F: Documentation/devicetree/bindings/media/renesas,fdp1.txt
-F: drivers/media/platform/rcar_fdp1.c
-
-MEDIA DRIVERS FOR RENESAS - VIN
-M: Niklas Söderlund <niklas.soderlund@ragnatech.se>
-L: linux-media@vger.kernel.org
-L: linux-renesas-soc@vger.kernel.org
-T: git git://linuxtv.org/media_tree.git
-S: Supported
-F: Documentation/devicetree/bindings/media/rcar_vin.txt
-F: drivers/media/platform/rcar-vin/
-
-MEDIA DRIVERS FOR RENESAS - VSP1
-M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-L: linux-media@vger.kernel.org
-L: linux-renesas-soc@vger.kernel.org
-T: git git://linuxtv.org/media_tree.git
-S: Supported
-F: Documentation/devicetree/bindings/media/renesas,vsp1.txt
-F: drivers/media/platform/vsp1/
-
MEDIA DRIVERS FOR HELENE
M: Abylay Ospan <aospan@netup.ru>
L: linux-media@vger.kernel.org
@@ -8356,7 +8344,7 @@ T: git git://linuxtv.org/media_tree.git
S: Supported
F: drivers/media/dvb-frontends/helene*
-MEDIA DRIVERS FOR ASCOT2E
+MEDIA DRIVERS FOR HORUS3A
M: Sergey Kozlov <serjk@netup.ru>
M: Abylay Ospan <aospan@netup.ru>
L: linux-media@vger.kernel.org
@@ -8364,9 +8352,9 @@ W: https://linuxtv.org
W: http://netup.tv/
T: git git://linuxtv.org/media_tree.git
S: Supported
-F: drivers/media/dvb-frontends/ascot2e*
+F: drivers/media/dvb-frontends/horus3a*
-MEDIA DRIVERS FOR CXD2841ER
+MEDIA DRIVERS FOR LNBH25
M: Sergey Kozlov <serjk@netup.ru>
M: Abylay Ospan <aospan@netup.ru>
L: linux-media@vger.kernel.org
@@ -8374,9 +8362,9 @@ W: https://linuxtv.org
W: http://netup.tv/
T: git git://linuxtv.org/media_tree.git
S: Supported
-F: drivers/media/dvb-frontends/cxd2841er*
+F: drivers/media/dvb-frontends/lnbh25*
-MEDIA DRIVERS FOR HORUS3A
+MEDIA DRIVERS FOR NETUP PCI UNIVERSAL DVB devices
M: Sergey Kozlov <serjk@netup.ru>
M: Abylay Ospan <aospan@netup.ru>
L: linux-media@vger.kernel.org
@@ -8384,27 +8372,53 @@ W: https://linuxtv.org
W: http://netup.tv/
T: git git://linuxtv.org/media_tree.git
S: Supported
-F: drivers/media/dvb-frontends/horus3a*
+F: drivers/media/pci/netup_unidvb/*
-MEDIA DRIVERS FOR LNBH25
-M: Sergey Kozlov <serjk@netup.ru>
-M: Abylay Ospan <aospan@netup.ru>
+MEDIA DRIVERS FOR RENESAS - DRIF
+M: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>
L: linux-media@vger.kernel.org
-W: https://linuxtv.org
-W: http://netup.tv/
+L: linux-renesas-soc@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
S: Supported
-F: drivers/media/dvb-frontends/lnbh25*
+F: Documentation/devicetree/bindings/media/renesas,drif.txt
+F: drivers/media/platform/rcar_drif.c
-MEDIA DRIVERS FOR NETUP PCI UNIVERSAL DVB devices
-M: Sergey Kozlov <serjk@netup.ru>
-M: Abylay Ospan <aospan@netup.ru>
+MEDIA DRIVERS FOR RENESAS - FCP
+M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org
-W: https://linuxtv.org
-W: http://netup.tv/
+L: linux-renesas-soc@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
S: Supported
-F: drivers/media/pci/netup_unidvb/*
+F: Documentation/devicetree/bindings/media/renesas,fcp.txt
+F: drivers/media/platform/rcar-fcp.c
+F: include/media/rcar-fcp.h
+
+MEDIA DRIVERS FOR RENESAS - FDP1
+M: Kieran Bingham <kieran@bingham.xyz>
+L: linux-media@vger.kernel.org
+L: linux-renesas-soc@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+S: Supported
+F: Documentation/devicetree/bindings/media/renesas,fdp1.txt
+F: drivers/media/platform/rcar_fdp1.c
+
+MEDIA DRIVERS FOR RENESAS - VIN
+M: Niklas Söderlund <niklas.soderlund@ragnatech.se>
+L: linux-media@vger.kernel.org
+L: linux-renesas-soc@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+S: Supported
+F: Documentation/devicetree/bindings/media/rcar_vin.txt
+F: drivers/media/platform/rcar-vin/
+
+MEDIA DRIVERS FOR RENESAS - VSP1
+M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+L: linux-media@vger.kernel.org
+L: linux-renesas-soc@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+S: Supported
+F: Documentation/devicetree/bindings/media/renesas,vsp1.txt
+F: drivers/media/platform/vsp1/
MEDIA INPUT INFRASTRUCTURE (V4L/DVB)
M: Mauro Carvalho Chehab <mchehab@s-opensource.com>
@@ -8443,15 +8457,6 @@ S: Supported
F: drivers/media/platform/mtk-jpeg/
F: Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
-MEDIATEK MEDIA DRIVER
-M: Tiffany Lin <tiffany.lin@mediatek.com>
-M: Andrew-CT Chen <andrew-ct.chen@mediatek.com>
-S: Supported
-F: drivers/media/platform/mtk-vcodec/
-F: drivers/media/platform/mtk-vpu/
-F: Documentation/devicetree/bindings/media/mediatek-vcodec.txt
-F: Documentation/devicetree/bindings/media/mediatek-vpu.txt
-
MEDIATEK MDP DRIVER
M: Minghsiu Tsai <minghsiu.tsai@mediatek.com>
M: Houlong Wei <houlong.wei@mediatek.com>
@@ -8461,6 +8466,15 @@ F: drivers/media/platform/mtk-mdp/
F: drivers/media/platform/mtk-vpu/
F: Documentation/devicetree/bindings/media/mediatek-mdp.txt
+MEDIATEK MEDIA DRIVER
+M: Tiffany Lin <tiffany.lin@mediatek.com>
+M: Andrew-CT Chen <andrew-ct.chen@mediatek.com>
+S: Supported
+F: drivers/media/platform/mtk-vcodec/
+F: drivers/media/platform/mtk-vpu/
+F: Documentation/devicetree/bindings/media/mediatek-vcodec.txt
+F: Documentation/devicetree/bindings/media/mediatek-vpu.txt
+
MEDIATEK MT7601U WIRELESS LAN DRIVER
M: Jakub Kicinski <kubakici@wp.pl>
L: linux-wireless@vger.kernel.org
@@ -8468,9 +8482,9 @@ S: Maintained
F: drivers/net/wireless/mediatek/mt7601u/
MEDIATEK RANDOM NUMBER GENERATOR SUPPORT
-M: Sean Wang <sean.wang@mediatek.com>
-S: Maintained
-F: drivers/char/hw_random/mtk-rng.c
+M: Sean Wang <sean.wang@mediatek.com>
+S: Maintained
+F: drivers/char/hw_random/mtk-rng.c
MEGACHIPS STDPXXXX-GE-B850V3-FW LVDS/DP++ BRIDGES
M: Peter Senna Tschudin <peter.senna@collabora.com>
@@ -8492,6 +8506,13 @@ F: Documentation/scsi/megaraid.txt
F: drivers/scsi/megaraid.*
F: drivers/scsi/megaraid/
+MELEXIS MLX90614 DRIVER
+M: Crt Mori <cmo@melexis.com>
+L: linux-iio@vger.kernel.org
+W: http://www.melexis.com
+S: Supported
+F: drivers/iio/temperature/mlx90614.c
+
MELFAS MIP4 TOUCHSCREEN DRIVER
M: Sangwon Jee <jeesw@melfas.com>
W: http://www.melfas.com
@@ -8552,6 +8573,56 @@ W: http://www.mellanox.com
Q: http://patchwork.ozlabs.org/project/netdev/list/
F: drivers/net/ethernet/mellanox/mlxfw/
+MELLANOX MLX CPLD HOTPLUG DRIVER
+M: Vadim Pasternak <vadimp@mellanox.com>
+L: platform-driver-x86@vger.kernel.org
+S: Supported
+F: drivers/platform/x86/mlxcpld-hotplug.c
+F: include/linux/platform_data/mlxcpld-hotplug.h
+
+MELLANOX MLX4 core VPI driver
+M: Tariq Toukan <tariqt@mellanox.com>
+L: netdev@vger.kernel.org
+L: linux-rdma@vger.kernel.org
+W: http://www.mellanox.com
+Q: http://patchwork.ozlabs.org/project/netdev/list/
+S: Supported
+F: drivers/net/ethernet/mellanox/mlx4/
+F: include/linux/mlx4/
+
+MELLANOX MLX4 IB driver
+M: Yishai Hadas <yishaih@mellanox.com>
+L: linux-rdma@vger.kernel.org
+W: http://www.mellanox.com
+Q: http://patchwork.kernel.org/project/linux-rdma/list/
+S: Supported
+F: drivers/infiniband/hw/mlx4/
+F: include/linux/mlx4/
+F: include/uapi/rdma/mlx4-abi.h
+
+MELLANOX MLX5 core VPI driver
+M: Saeed Mahameed <saeedm@mellanox.com>
+M: Matan Barak <matanb@mellanox.com>
+M: Leon Romanovsky <leonro@mellanox.com>
+L: netdev@vger.kernel.org
+L: linux-rdma@vger.kernel.org
+W: http://www.mellanox.com
+Q: http://patchwork.ozlabs.org/project/netdev/list/
+S: Supported
+F: drivers/net/ethernet/mellanox/mlx5/core/
+F: include/linux/mlx5/
+
+MELLANOX MLX5 IB driver
+M: Matan Barak <matanb@mellanox.com>
+M: Leon Romanovsky <leonro@mellanox.com>
+L: linux-rdma@vger.kernel.org
+W: http://www.mellanox.com
+Q: http://patchwork.kernel.org/project/linux-rdma/list/
+S: Supported
+F: drivers/infiniband/hw/mlx5/
+F: include/linux/mlx5/
+F: include/uapi/rdma/mlx5-abi.h
+
MELLANOX MLXCPLD I2C AND MUX DRIVER
M: Vadim Pasternak <vadimp@mellanox.com>
M: Michael Shych <michaelsh@mellanox.com>
@@ -8569,26 +8640,10 @@ F: drivers/leds/leds-mlxcpld.c
F: Documentation/leds/leds-mlxcpld.txt
MELLANOX PLATFORM DRIVER
-M: Vadim Pasternak <vadimp@mellanox.com>
-L: platform-driver-x86@vger.kernel.org
-S: Supported
-F: drivers/platform/x86/mlx-platform.c
-
-MELLANOX MLX CPLD HOTPLUG DRIVER
M: Vadim Pasternak <vadimp@mellanox.com>
L: platform-driver-x86@vger.kernel.org
S: Supported
-F: drivers/platform/x86/mlxcpld-hotplug.c
-F: include/linux/platform_data/mlxcpld-hotplug.h
-
-SOFT-ROCE DRIVER (rxe)
-M: Moni Shoua <monis@mellanox.com>
-L: linux-rdma@vger.kernel.org
-S: Supported
-W: https://github.com/SoftRoCE/rxe-dev/wiki/rxe-dev:-Home
-Q: http://patchwork.kernel.org/project/linux-rdma/list/
-F: drivers/infiniband/sw/rxe/
-F: include/uapi/rdma/rdma_user_rxe.h
+F: drivers/platform/x86/mlx-platform.c
MEMBARRIER SUPPORT
M: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
@@ -8710,6 +8765,18 @@ S: Maintained
F: drivers/usb/misc/usb251xb.c
F: Documentation/devicetree/bindings/usb/usb251xb.txt
+MICROSEMI SMART ARRAY SMARTPQI DRIVER (smartpqi)
+M: Don Brace <don.brace@microsemi.com>
+L: esc.storagedev@microsemi.com
+L: linux-scsi@vger.kernel.org
+S: Supported
+F: drivers/scsi/smartpqi/smartpqi*.[ch]
+F: drivers/scsi/smartpqi/Kconfig
+F: drivers/scsi/smartpqi/Makefile
+F: include/linux/cciss*.h
+F: include/uapi/linux/cciss*.h
+F: Documentation/scsi/smartpqi.txt
+
MICROSOFT SURFACE PRO 3 BUTTON DRIVER
M: Chen Yu <yu.c.chen@intel.com>
L: platform-driver-x86@vger.kernel.org
@@ -8732,6 +8799,16 @@ F: Documentation/devicetree/bindings/mips/
F: Documentation/mips/
F: arch/mips/
+MIPS BOSTON DEVELOPMENT BOARD
+M: Paul Burton <paul.burton@imgtec.com>
+L: linux-mips@linux-mips.org
+S: Maintained
+F: Documentation/devicetree/bindings/clock/img,boston-clock.txt
+F: arch/mips/boot/dts/img/boston.dts
+F: arch/mips/configs/generic/board-boston.config
+F: drivers/clk/imgtec/clk-boston.c
+F: include/dt-bindings/clock/boston-clock.h
+
MIPS GENERIC PLATFORM
M: Paul Burton <paul.burton@imgtec.com>
L: linux-mips@linux-mips.org
@@ -8747,16 +8824,6 @@ F: arch/mips/include/asm/mach-loongson32/
F: drivers/*/*loongson1*
F: drivers/*/*/*loongson1*
-MIPS BOSTON DEVELOPMENT BOARD
-M: Paul Burton <paul.burton@imgtec.com>
-L: linux-mips@linux-mips.org
-S: Maintained
-F: Documentation/devicetree/bindings/clock/img,boston-clock.txt
-F: arch/mips/boot/dts/img/boston.dts
-F: arch/mips/configs/generic/board-boston.config
-F: drivers/clk/imgtec/clk-boston.c
-F: include/dt-bindings/clock/boston-clock.h
-
MIROSOUND PCM20 FM RADIO RECEIVER DRIVER
M: Hans Verkuil <hverkuil@xs4all.nl>
L: linux-media@vger.kernel.org
@@ -8765,67 +8832,15 @@ W: https://linuxtv.org
S: Odd Fixes
F: drivers/media/radio/radio-miropcm20*
-MELLANOX MLX4 core VPI driver
-M: Tariq Toukan <tariqt@mellanox.com>
-L: netdev@vger.kernel.org
-L: linux-rdma@vger.kernel.org
-W: http://www.mellanox.com
-Q: http://patchwork.ozlabs.org/project/netdev/list/
-S: Supported
-F: drivers/net/ethernet/mellanox/mlx4/
-F: include/linux/mlx4/
-
-MELLANOX MLX4 IB driver
-M: Yishai Hadas <yishaih@mellanox.com>
-L: linux-rdma@vger.kernel.org
-W: http://www.mellanox.com
-Q: http://patchwork.kernel.org/project/linux-rdma/list/
-S: Supported
-F: drivers/infiniband/hw/mlx4/
-F: include/linux/mlx4/
-F: include/uapi/rdma/mlx4-abi.h
-
-MELLANOX MLX5 core VPI driver
-M: Saeed Mahameed <saeedm@mellanox.com>
-M: Matan Barak <matanb@mellanox.com>
-M: Leon Romanovsky <leonro@mellanox.com>
-L: netdev@vger.kernel.org
-L: linux-rdma@vger.kernel.org
-W: http://www.mellanox.com
-Q: http://patchwork.ozlabs.org/project/netdev/list/
-S: Supported
-F: drivers/net/ethernet/mellanox/mlx5/core/
-F: include/linux/mlx5/
-
-MELLANOX MLX5 IB driver
-M: Matan Barak <matanb@mellanox.com>
-M: Leon Romanovsky <leonro@mellanox.com>
-L: linux-rdma@vger.kernel.org
-W: http://www.mellanox.com
-Q: http://patchwork.kernel.org/project/linux-rdma/list/
-S: Supported
-F: drivers/infiniband/hw/mlx5/
-F: include/linux/mlx5/
-F: include/uapi/rdma/mlx5-abi.h
-
-MELEXIS MLX90614 DRIVER
-M: Crt Mori <cmo@melexis.com>
-L: linux-iio@vger.kernel.org
-W: http://www.melexis.com
-S: Supported
-F: drivers/iio/temperature/mlx90614.c
-
-MICROSEMI SMART ARRAY SMARTPQI DRIVER (smartpqi)
-M: Don Brace <don.brace@microsemi.com>
-L: esc.storagedev@microsemi.com
-L: linux-scsi@vger.kernel.org
-S: Supported
-F: drivers/scsi/smartpqi/smartpqi*.[ch]
-F: drivers/scsi/smartpqi/Kconfig
-F: drivers/scsi/smartpqi/Makefile
-F: include/linux/cciss*.h
-F: include/uapi/linux/cciss*.h
-F: Documentation/scsi/smartpqi.txt
+MMP SUPPORT
+M: Eric Miao <eric.y.miao@gmail.com>
+M: Haojian Zhuang <haojian.zhuang@gmail.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+T: git git://github.com/hzhuang1/linux.git
+T: git git://git.linaro.org/people/ycmiao/pxa-linux.git
+S: Maintained
+F: arch/arm/boot/dts/mmp*
+F: arch/arm/mach-mmp/
MN88472 MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
@@ -8959,6 +8974,11 @@ F: drivers/mfd/
F: include/linux/mfd/
F: include/dt-bindings/mfd/
+MULTIMEDIA CARD (MMC) ETC. OVER SPI
+S: Orphan
+F: drivers/mmc/host/mmc_spi.c
+F: include/linux/spi/mmc_spi.h
+
MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM
M: Ulf Hansson <ulf.hansson@linaro.org>
L: linux-mmc@vger.kernel.org
@@ -8969,11 +8989,6 @@ F: drivers/mmc/
F: include/linux/mmc/
F: include/uapi/linux/mmc/
-MULTIMEDIA CARD (MMC) ETC. OVER SPI
-S: Orphan
-F: drivers/mmc/host/mmc_spi.c
-F: include/linux/spi/mmc_spi.h
-
MULTIPLEXER SUBSYSTEM
M: Peter Rosin <peda@axentia.se>
S: Maintained
@@ -9036,10 +9051,6 @@ S: Maintained
F: drivers/mtd/nand/
F: include/linux/mtd/nand*.h
-NATSEMI ETHERNET DRIVER (DP8381x)
-S: Orphan
-F: drivers/net/ethernet/natsemi/natsemi.c
-
NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER
M: Daniel Mack <zonque@gmail.com>
S: Maintained
@@ -9047,6 +9058,10 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers)
W: http://www.native-instruments.com
F: sound/usb/caiaq/
+NATSEMI ETHERNET DRIVER (DP8381x)
+S: Orphan
+F: drivers/net/ethernet/natsemi/natsemi.c
+
NCP FILESYSTEM
M: Petr Vandrovec <petr@vandrovec.name>
S: Odd Fixes
@@ -9166,6 +9181,35 @@ S: Maintained
W: https://fedorahosted.org/dropwatch/
F: net/core/drop_monitor.c
+NETWORKING DRIVERS
+L: netdev@vger.kernel.org
+W: http://www.linuxfoundation.org/en/Net
+Q: http://patchwork.ozlabs.org/project/netdev/list/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
+S: Odd Fixes
+F: Documentation/devicetree/bindings/net/
+F: drivers/net/
+F: include/linux/if_*
+F: include/linux/netdevice.h
+F: include/linux/etherdevice.h
+F: include/linux/fcdevice.h
+F: include/linux/fddidevice.h
+F: include/linux/hippidevice.h
+F: include/linux/inetdevice.h
+F: include/uapi/linux/if_*
+F: include/uapi/linux/netdevice.h
+
+NETWORKING DRIVERS (WIRELESS)
+M: Kalle Valo <kvalo@codeaurora.org>
+L: linux-wireless@vger.kernel.org
+Q: http://patchwork.kernel.org/project/linux-wireless/list/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git
+S: Maintained
+F: Documentation/devicetree/bindings/net/wireless/
+F: drivers/net/wireless/
+
NETWORKING [DSA]
M: Andrew Lunn <andrew@lunn.ch>
M: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
@@ -9197,28 +9241,6 @@ F: tools/net/
F: tools/testing/selftests/net/
F: lib/random32.c
-NETWORKING [IPv4/IPv6]
-M: "David S. Miller" <davem@davemloft.net>
-M: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
-M: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
-L: netdev@vger.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
-S: Maintained
-F: net/ipv4/
-F: net/ipv6/
-F: include/net/ip*
-F: arch/x86/net/*
-
-NETWORKING [TLS]
-M: Ilya Lesokhin <ilyal@mellanox.com>
-M: Aviad Yehezkel <aviadye@mellanox.com>
-M: Dave Watson <davejwatson@fb.com>
-L: netdev@vger.kernel.org
-S: Maintained
-F: net/tls/*
-F: include/uapi/linux/tls.h
-F: include/net/tls.h
-
NETWORKING [IPSEC]
M: Steffen Klassert <steffen.klassert@secunet.com>
M: Herbert Xu <herbert@gondor.apana.org.au>
@@ -9243,43 +9265,36 @@ F: net/ipv6/ip6_vti.c
F: include/uapi/linux/xfrm.h
F: include/net/xfrm.h
+NETWORKING [IPv4/IPv6]
+M: "David S. Miller" <davem@davemloft.net>
+M: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+M: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
+L: netdev@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
+S: Maintained
+F: net/ipv4/
+F: net/ipv6/
+F: include/net/ip*
+F: arch/x86/net/*
+
NETWORKING [LABELED] (NetLabel, CIPSO, Labeled IPsec, SECMARK)
M: Paul Moore <paul@paul-moore.com>
L: netdev@vger.kernel.org
S: Maintained
-NETWORKING [WIRELESS]
-L: linux-wireless@vger.kernel.org
-Q: http://patchwork.kernel.org/project/linux-wireless/list/
-
-NETWORKING DRIVERS
+NETWORKING [TLS]
+M: Ilya Lesokhin <ilyal@mellanox.com>
+M: Aviad Yehezkel <aviadye@mellanox.com>
+M: Dave Watson <davejwatson@fb.com>
L: netdev@vger.kernel.org
-W: http://www.linuxfoundation.org/en/Net
-Q: http://patchwork.ozlabs.org/project/netdev/list/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
-S: Odd Fixes
-F: Documentation/devicetree/bindings/net/
-F: drivers/net/
-F: include/linux/if_*
-F: include/linux/netdevice.h
-F: include/linux/etherdevice.h
-F: include/linux/fcdevice.h
-F: include/linux/fddidevice.h
-F: include/linux/hippidevice.h
-F: include/linux/inetdevice.h
-F: include/uapi/linux/if_*
-F: include/uapi/linux/netdevice.h
+S: Maintained
+F: net/tls/*
+F: include/uapi/linux/tls.h
+F: include/net/tls.h
-NETWORKING DRIVERS (WIRELESS)
-M: Kalle Valo <kvalo@codeaurora.org>
+NETWORKING [WIRELESS]
L: linux-wireless@vger.kernel.org
Q: http://patchwork.kernel.org/project/linux-wireless/list/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers.git
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git
-S: Maintained
-F: Documentation/devicetree/bindings/net/wireless/
-F: drivers/net/wireless/
NETXEN (1/10) GbE SUPPORT
M: Manish Chopra <manish.chopra@cavium.com>
@@ -9373,14 +9388,6 @@ S: Maintained
F: drivers/media/i2c/et8ek8
F: drivers/media/i2c/ad5820.c
-NOKIA N900 CAMERA SUPPORT (ET8EK8 SENSOR, AD5820 FOCUS)
-M: Pavel Machek <pavel@ucw.cz>
-M: Sakari Ailus <sakari.ailus@iki.fi>
-L: linux-media@vger.kernel.org
-S: Maintained
-F: drivers/media/i2c/et8ek8
-F: drivers/media/i2c/ad5820.c
-
NOKIA N900 POWER SUPPLY DRIVERS
R: Pali Rohár <pali.rohar@gmail.com>
F: include/linux/power/bq2415x_charger.h
@@ -9392,6 +9399,12 @@ F: drivers/power/supply/bq27xxx_battery_i2c.c
F: drivers/power/supply/isp1704_charger.c
F: drivers/power/supply/rx51_battery.c
+NTB AMD DRIVER
+M: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
+L: linux-ntb@googlegroups.com
+S: Supported
+F: drivers/ntb/hw/amd/
+
NTB DRIVER CORE
M: Jon Mason <jdmason@kudzu.us>
M: Dave Jiang <dave.jiang@intel.com>
@@ -9421,12 +9434,6 @@ W: https://github.com/jonmason/ntb/wiki
T: git git://github.com/jonmason/ntb.git
F: drivers/ntb/hw/intel/
-NTB AMD DRIVER
-M: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
-L: linux-ntb@googlegroups.com
-S: Supported
-F: drivers/ntb/hw/amd/
-
NTFS FILESYSTEM
M: Anton Altaparmakov <anton@tuxera.com>
L: linux-ntfs-dev@lists.sourceforge.net
@@ -9456,15 +9463,6 @@ F: drivers/nvme/host/
F: include/linux/nvme.h
F: include/uapi/linux/nvme_ioctl.h
-NVM EXPRESS TARGET DRIVER
-M: Christoph Hellwig <hch@lst.de>
-M: Sagi Grimberg <sagi@grimberg.me>
-L: linux-nvme@lists.infradead.org
-T: git://git.infradead.org/nvme.git
-W: http://git.infradead.org/nvme.git
-S: Supported
-F: drivers/nvme/target/
-
NVM EXPRESS FC TRANSPORT DRIVERS
M: James Smart <james.smart@broadcom.com>
L: linux-nvme@lists.infradead.org
@@ -9475,6 +9473,15 @@ F: drivers/nvme/host/fc.c
F: drivers/nvme/target/fc.c
F: drivers/nvme/target/fcloop.c
+NVM EXPRESS TARGET DRIVER
+M: Christoph Hellwig <hch@lst.de>
+M: Sagi Grimberg <sagi@grimberg.me>
+L: linux-nvme@lists.infradead.org
+T: git://git.infradead.org/nvme.git
+W: http://git.infradead.org/nvme.git
+S: Supported
+F: drivers/nvme/target/
+
NVMEM FRAMEWORK
M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
S: Maintained
@@ -9483,13 +9490,6 @@ F: Documentation/devicetree/bindings/nvmem/
F: include/linux/nvmem-consumer.h
F: include/linux/nvmem-provider.h
-NXP-NCI NFC DRIVER
-M: Clément Perrochaud <clement.perrochaud@effinnov.com>
-R: Charles Gorand <charles.gorand@effinnov.com>
-L: linux-nfc@lists.01.org (moderated for non-subscribers)
-S: Supported
-F: drivers/nfc/nxp-nci
-
NXP TDA998X DRM DRIVER
M: Russell King <linux@armlinux.org.uk>
S: Supported
@@ -9504,55 +9504,31 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Maintained
F: sound/soc/codecs/tfa9879*
+NXP-NCI NFC DRIVER
+M: Clément Perrochaud <clement.perrochaud@effinnov.com>
+R: Charles Gorand <charles.gorand@effinnov.com>
+L: linux-nfc@lists.01.org (moderated for non-subscribers)
+S: Supported
+F: drivers/nfc/nxp-nci
+
OBJTOOL
M: Josh Poimboeuf <jpoimboe@redhat.com>
S: Supported
F: tools/objtool/
-OMAP1 SUPPORT
-M: Aaro Koskinen <aaro.koskinen@iki.fi>
-M: Tony Lindgren <tony@atomide.com>
+OMAP AUDIO SUPPORT
+M: Peter Ujfalusi <peter.ujfalusi@ti.com>
+M: Jarkko Nikula <jarkko.nikula@bitmer.com>
+L: alsa-devel@alsa-project.org (moderated for non-subscribers)
L: linux-omap@vger.kernel.org
-Q: http://patchwork.kernel.org/project/linux-omap/list/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git
S: Maintained
-F: arch/arm/mach-omap1/
-F: arch/arm/plat-omap/
-F: arch/arm/configs/omap1_defconfig
-F: drivers/i2c/busses/i2c-omap.c
-F: include/linux/i2c-omap.h
+F: sound/soc/omap/
-OMAP2+ SUPPORT
-M: Tony Lindgren <tony@atomide.com>
+OMAP CLOCK FRAMEWORK SUPPORT
+M: Paul Walmsley <paul@pwsan.com>
L: linux-omap@vger.kernel.org
-W: http://www.muru.com/linux/omap/
-W: http://linux.omap.com/
-Q: http://patchwork.kernel.org/project/linux-omap/list/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git
S: Maintained
-F: arch/arm/mach-omap2/
-F: arch/arm/plat-omap/
-F: arch/arm/configs/omap2plus_defconfig
-F: drivers/i2c/busses/i2c-omap.c
-F: drivers/irqchip/irq-omap-intc.c
-F: drivers/mfd/*omap*.c
-F: drivers/mfd/menelaus.c
-F: drivers/mfd/palmas.c
-F: drivers/mfd/tps65217.c
-F: drivers/mfd/tps65218.c
-F: drivers/mfd/tps65910.c
-F: drivers/mfd/twl-core.[ch]
-F: drivers/mfd/twl4030*.c
-F: drivers/mfd/twl6030*.c
-F: drivers/mfd/twl6040*.c
-F: drivers/regulator/palmas-regulator*.c
-F: drivers/regulator/pbias-regulator.c
-F: drivers/regulator/tps65217-regulator.c
-F: drivers/regulator/tps65218-regulator.c
-F: drivers/regulator/tps65910-regulator.c
-F: drivers/regulator/twl-regulator.c
-F: drivers/regulator/twl6030-regulator.c
-F: include/linux/i2c-omap.h
+F: arch/arm/*omap*/*clock*
OMAP DEVICE TREE SUPPORT
M: Benoît Cousson <bcousson@baylibre.com>
@@ -9566,33 +9542,20 @@ F: arch/arm/boot/dts/*am4*
F: arch/arm/boot/dts/*am5*
F: arch/arm/boot/dts/*dra7*
-OMAP CLOCK FRAMEWORK SUPPORT
-M: Paul Walmsley <paul@pwsan.com>
-L: linux-omap@vger.kernel.org
-S: Maintained
-F: arch/arm/*omap*/*clock*
-
-OMAP POWER MANAGEMENT SUPPORT
-M: Kevin Hilman <khilman@kernel.org>
-L: linux-omap@vger.kernel.org
-S: Maintained
-F: arch/arm/*omap*/*pm*
-F: drivers/cpufreq/omap-cpufreq.c
-
-OMAP POWERDOMAIN SOC ADAPTATION LAYER SUPPORT
-M: Rajendra Nayak <rnayak@codeaurora.org>
-M: Paul Walmsley <paul@pwsan.com>
+OMAP DISPLAY SUBSYSTEM and FRAMEBUFFER SUPPORT (DSS2)
+M: Tomi Valkeinen <tomi.valkeinen@ti.com>
L: linux-omap@vger.kernel.org
+L: linux-fbdev@vger.kernel.org
S: Maintained
-F: arch/arm/mach-omap2/prm*
+F: drivers/video/fbdev/omap2/
+F: Documentation/arm/OMAP/DSS
-OMAP AUDIO SUPPORT
-M: Peter Ujfalusi <peter.ujfalusi@ti.com>
-M: Jarkko Nikula <jarkko.nikula@bitmer.com>
-L: alsa-devel@alsa-project.org (moderated for non-subscribers)
+OMAP FRAMEBUFFER SUPPORT
+M: Tomi Valkeinen <tomi.valkeinen@ti.com>
+L: linux-fbdev@vger.kernel.org
L: linux-omap@vger.kernel.org
S: Maintained
-F: sound/soc/omap/
+F: drivers/video/fbdev/omap/
OMAP GENERAL PURPOSE MEMORY CONTROLLER SUPPORT
M: Roger Quadros <rogerq@ti.com>
@@ -9602,20 +9565,14 @@ S: Maintained
F: drivers/memory/omap-gpmc.c
F: arch/arm/mach-omap2/*gpmc*
-OMAP FRAMEBUFFER SUPPORT
-M: Tomi Valkeinen <tomi.valkeinen@ti.com>
-L: linux-fbdev@vger.kernel.org
-L: linux-omap@vger.kernel.org
-S: Maintained
-F: drivers/video/fbdev/omap/
-
-OMAP DISPLAY SUBSYSTEM and FRAMEBUFFER SUPPORT (DSS2)
-M: Tomi Valkeinen <tomi.valkeinen@ti.com>
+OMAP GPIO DRIVER
+M: Grygorii Strashko <grygorii.strashko@ti.com>
+M: Santosh Shilimkar <ssantosh@kernel.org>
+M: Kevin Hilman <khilman@kernel.org>
L: linux-omap@vger.kernel.org
-L: linux-fbdev@vger.kernel.org
S: Maintained
-F: drivers/video/fbdev/omap2/
-F: Documentation/arm/OMAP/DSS
+F: Documentation/devicetree/bindings/gpio/gpio-omap.txt
+F: drivers/gpio/gpio-omap.c
OMAP HARDWARE SPINLOCK SUPPORT
M: Ohad Ben-Cohen <ohad@wizery.com>
@@ -9623,30 +9580,12 @@ L: linux-omap@vger.kernel.org
S: Maintained
F: drivers/hwspinlock/omap_hwspinlock.c
-OMAP MMC SUPPORT
-M: Jarkko Lavinen <jarkko.lavinen@nokia.com>
-L: linux-omap@vger.kernel.org
-S: Maintained
-F: drivers/mmc/host/omap.c
-
OMAP HS MMC SUPPORT
L: linux-mmc@vger.kernel.org
L: linux-omap@vger.kernel.org
S: Orphan
F: drivers/mmc/host/omap_hsmmc.c
-OMAP RANDOM NUMBER GENERATOR SUPPORT
-M: Deepak Saxena <dsaxena@plexity.net>
-S: Maintained
-F: drivers/char/hw_random/omap-rng.c
-
-OMAP HWMOD SUPPORT
-M: Benoît Cousson <bcousson@baylibre.com>
-M: Paul Walmsley <paul@pwsan.com>
-L: linux-omap@vger.kernel.org
-S: Maintained
-F: arch/arm/mach-omap2/omap_hwmod.*
-
OMAP HWMOD DATA
M: Paul Walmsley <paul@pwsan.com>
L: linux-omap@vger.kernel.org
@@ -9659,6 +9598,13 @@ L: linux-omap@vger.kernel.org
S: Maintained
F: arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+OMAP HWMOD SUPPORT
+M: Benoît Cousson <bcousson@baylibre.com>
+M: Paul Walmsley <paul@pwsan.com>
+L: linux-omap@vger.kernel.org
+S: Maintained
+F: arch/arm/mach-omap2/omap_hwmod.*
+
OMAP IMAGING SUBSYSTEM (OMAP3 ISP and OMAP4 ISS)
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org
@@ -9667,6 +9613,31 @@ F: Documentation/devicetree/bindings/media/ti,omap3isp.txt
F: drivers/media/platform/omap3isp/
F: drivers/staging/media/omap4iss/
+OMAP MMC SUPPORT
+M: Jarkko Lavinen <jarkko.lavinen@nokia.com>
+L: linux-omap@vger.kernel.org
+S: Maintained
+F: drivers/mmc/host/omap.c
+
+OMAP POWER MANAGEMENT SUPPORT
+M: Kevin Hilman <khilman@kernel.org>
+L: linux-omap@vger.kernel.org
+S: Maintained
+F: arch/arm/*omap*/*pm*
+F: drivers/cpufreq/omap-cpufreq.c
+
+OMAP POWERDOMAIN SOC ADAPTATION LAYER SUPPORT
+M: Rajendra Nayak <rnayak@codeaurora.org>
+M: Paul Walmsley <paul@pwsan.com>
+L: linux-omap@vger.kernel.org
+S: Maintained
+F: arch/arm/mach-omap2/prm*
+
+OMAP RANDOM NUMBER GENERATOR SUPPORT
+M: Deepak Saxena <dsaxena@plexity.net>
+S: Maintained
+F: drivers/char/hw_random/omap-rng.c
+
OMAP USB SUPPORT
L: linux-usb@vger.kernel.org
L: linux-omap@vger.kernel.org
@@ -9674,21 +9645,57 @@ S: Orphan
F: drivers/usb/*/*omap*
F: arch/arm/*omap*/usb*
-OMAP GPIO DRIVER
-M: Grygorii Strashko <grygorii.strashko@ti.com>
-M: Santosh Shilimkar <ssantosh@kernel.org>
-M: Kevin Hilman <khilman@kernel.org>
-L: linux-omap@vger.kernel.org
-S: Maintained
-F: Documentation/devicetree/bindings/gpio/gpio-omap.txt
-F: drivers/gpio/gpio-omap.c
-
OMAP/NEWFLOW NANOBONE MACHINE SUPPORT
M: Mark Jackson <mpfj@newflow.co.uk>
L: linux-omap@vger.kernel.org
S: Maintained
F: arch/arm/boot/dts/am335x-nano.dts
+OMAP1 SUPPORT
+M: Aaro Koskinen <aaro.koskinen@iki.fi>
+M: Tony Lindgren <tony@atomide.com>
+L: linux-omap@vger.kernel.org
+Q: http://patchwork.kernel.org/project/linux-omap/list/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git
+S: Maintained
+F: arch/arm/mach-omap1/
+F: arch/arm/plat-omap/
+F: arch/arm/configs/omap1_defconfig
+F: drivers/i2c/busses/i2c-omap.c
+F: include/linux/i2c-omap.h
+
+OMAP2+ SUPPORT
+M: Tony Lindgren <tony@atomide.com>
+L: linux-omap@vger.kernel.org
+W: http://www.muru.com/linux/omap/
+W: http://linux.omap.com/
+Q: http://patchwork.kernel.org/project/linux-omap/list/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git
+S: Maintained
+F: arch/arm/mach-omap2/
+F: arch/arm/plat-omap/
+F: arch/arm/configs/omap2plus_defconfig
+F: drivers/i2c/busses/i2c-omap.c
+F: drivers/irqchip/irq-omap-intc.c
+F: drivers/mfd/*omap*.c
+F: drivers/mfd/menelaus.c
+F: drivers/mfd/palmas.c
+F: drivers/mfd/tps65217.c
+F: drivers/mfd/tps65218.c
+F: drivers/mfd/tps65910.c
+F: drivers/mfd/twl-core.[ch]
+F: drivers/mfd/twl4030*.c
+F: drivers/mfd/twl6030*.c
+F: drivers/mfd/twl6040*.c
+F: drivers/regulator/palmas-regulator*.c
+F: drivers/regulator/pbias-regulator.c
+F: drivers/regulator/tps65217-regulator.c
+F: drivers/regulator/tps65218-regulator.c
+F: drivers/regulator/tps65910-regulator.c
+F: drivers/regulator/twl-regulator.c
+F: drivers/regulator/twl6030-regulator.c
+F: include/linux/i2c-omap.h
+
OMFS FILESYSTEM
M: Bob Copeland <me@bobcopeland.com>
L: linux-karma-devel@lists.sourceforge.net
@@ -9708,6 +9715,13 @@ M: Harald Welte <laforge@gnumonks.org>
S: Maintained
F: drivers/char/pcmcia/cm4040_cs.*
+OMNIVISION OV13858 SENSOR DRIVER
+M: Sakari Ailus <sakari.ailus@linux.intel.com>
+L: linux-media@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: drivers/media/i2c/ov13858.c
+
OMNIVISION OV5640 SENSOR DRIVER
M: Steve Longerbeam <slongerbeam@gmail.com>
L: linux-media@vger.kernel.org
@@ -9730,13 +9744,6 @@ S: Maintained
F: drivers/media/i2c/ov7670.c
F: Documentation/devicetree/bindings/media/i2c/ov7670.txt
-OMNIVISION OV13858 SENSOR DRIVER
-M: Sakari Ailus <sakari.ailus@linux.intel.com>
-L: linux-media@vger.kernel.org
-T: git git://linuxtv.org/media_tree.git
-S: Maintained
-F: drivers/media/i2c/ov13858.c
-
ONENAND FLASH DRIVER
M: Kyungmin Park <kyungmin.park@samsung.com>
L: linux-mtd@lists.infradead.org
@@ -9754,12 +9761,26 @@ F: drivers/scsi/osst.*
F: drivers/scsi/osst_*.h
F: drivers/scsi/st.h
-OPENCORES I2C BUS DRIVER
-M: Peter Korsgaard <jacmet@sunsite.dk>
-L: linux-i2c@vger.kernel.org
+OP-TEE DRIVER
+M: Jens Wiklander <jens.wiklander@linaro.org>
S: Maintained
-F: Documentation/i2c/busses/i2c-ocores
-F: drivers/i2c/busses/i2c-ocores.c
+F: drivers/tee/optee/
+
+OPA-VNIC DRIVER
+M: Dennis Dalessandro <dennis.dalessandro@intel.com>
+M: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
+L: linux-rdma@vger.kernel.org
+S: Supported
+F: drivers/infiniband/ulp/opa_vnic
+
+OPEN FIRMWARE AND DEVICE TREE OVERLAYS
+M: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+L: devicetree@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/dynamic-resolution-notes.txt
+F: Documentation/devicetree/overlay-notes.txt
+F: drivers/of/overlay.c
+F: drivers/of/resolver.c
OPEN FIRMWARE AND FLATTENED DEVICE TREE
M: Rob Herring <robh+dt@kernel.org>
@@ -9784,14 +9805,12 @@ F: Documentation/devicetree/
F: arch/*/boot/dts/
F: include/dt-bindings/
-OPEN FIRMWARE AND DEVICE TREE OVERLAYS
-M: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
-L: devicetree@vger.kernel.org
+OPENCORES I2C BUS DRIVER
+M: Peter Korsgaard <jacmet@sunsite.dk>
+L: linux-i2c@vger.kernel.org
S: Maintained
-F: Documentation/devicetree/dynamic-resolution-notes.txt
-F: Documentation/devicetree/overlay-notes.txt
-F: drivers/of/overlay.c
-F: drivers/of/resolver.c
+F: Documentation/i2c/busses/i2c-ocores
+F: drivers/i2c/busses/i2c-ocores.c
OPENRISC ARCHITECTURE
M: Jonas Bonn <jonas@southpole.se>
@@ -9840,11 +9859,6 @@ F: arch/*/oprofile/
F: drivers/oprofile/
F: include/linux/oprofile.h
-OP-TEE DRIVER
-M: Jens Wiklander <jens.wiklander@linaro.org>
-S: Maintained
-F: drivers/tee/optee/
-
ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
M: Mark Fasheh <mfasheh@versity.com>
M: Joel Becker <jlbec@evilplan.org>
@@ -9855,6 +9869,14 @@ F: Documentation/filesystems/ocfs2.txt
F: Documentation/filesystems/dlmfs.txt
F: fs/ocfs2/
+ORANGEFS FILESYSTEM
+M: Mike Marshall <hubcap@omnibond.com>
+L: pvfs2-developers@beowulf-underground.org (subscribers-only)
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/hubcap/linux.git
+S: Supported
+F: fs/orangefs/
+F: Documentation/filesystems/orangefs.txt
+
ORINOCO DRIVER
L: linux-wireless@vger.kernel.org
W: http://wireless.kernel.org/en/users/Drivers/orinoco
@@ -9869,6 +9891,16 @@ F: drivers/scsi/osd/
F: include/scsi/osd_*
F: fs/exofs/
+OV2659 OMNIVISION SENSOR DRIVER
+M: "Lad, Prabhakar" <prabhakar.csengg@gmail.com>
+L: linux-media@vger.kernel.org
+W: https://linuxtv.org
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
+S: Maintained
+F: drivers/media/i2c/ov2659.c
+F: include/media/i2c/ov2659.h
+
OVERLAY FILESYSTEM
M: Miklos Szeredi <miklos@szeredi.hu>
L: linux-unionfs@vger.kernel.org
@@ -9877,14 +9909,6 @@ S: Supported
F: fs/overlayfs/
F: Documentation/filesystems/overlayfs.txt
-ORANGEFS FILESYSTEM
-M: Mike Marshall <hubcap@omnibond.com>
-L: pvfs2-developers@beowulf-underground.org (subscribers-only)
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/hubcap/linux.git
-S: Supported
-F: fs/orangefs/
-F: Documentation/filesystems/orangefs.txt
-
P54 WIRELESS DRIVER
M: Christian Lamparter <chunkeey@googlemail.com>
L: linux-wireless@vger.kernel.org
@@ -9925,11 +9949,11 @@ F: Documentation/mn10300/
F: arch/mn10300/
PARALLEL LCD/KEYPAD PANEL DRIVER
-M: Willy Tarreau <willy@haproxy.com>
-M: Ksenija Stanojevic <ksenija.stanojevic@gmail.com>
-S: Odd Fixes
-F: Documentation/misc-devices/lcd-panel-cgram.txt
-F: drivers/misc/panel.c
+M: Willy Tarreau <willy@haproxy.com>
+M: Ksenija Stanojevic <ksenija.stanojevic@gmail.com>
+S: Odd Fixes
+F: Documentation/misc-devices/lcd-panel-cgram.txt
+F: drivers/misc/panel.c
PARALLEL PORT SUBSYSTEM
M: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
@@ -10025,42 +10049,13 @@ M: Khalid Aziz <khalid@gonehiking.org>
S: Maintained
F: drivers/firmware/pcdp.*
-PCI ERROR RECOVERY
-M: Linas Vepstas <linasvepstas@gmail.com>
-L: linux-pci@vger.kernel.org
-S: Supported
-F: Documentation/PCI/pci-error-recovery.txt
-
-PCI ENHANCED ERROR HANDLING (EEH) FOR POWERPC
-M: Russell Currey <ruscur@russell.cc>
-L: linuxppc-dev@lists.ozlabs.org
-S: Supported
-F: Documentation/powerpc/eeh-pci-error-recovery.txt
-F: arch/powerpc/kernel/eeh*.c
-F: arch/powerpc/platforms/*/eeh*.c
-F: arch/powerpc/include/*/eeh*.h
-
-PCI SUBSYSTEM
-M: Bjorn Helgaas <bhelgaas@google.com>
-L: linux-pci@vger.kernel.org
-Q: http://patchwork.ozlabs.org/project/linux-pci/list/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git
-S: Supported
-F: Documentation/devicetree/bindings/pci/
-F: Documentation/PCI/
-F: drivers/pci/
-F: include/linux/pci*
-F: arch/x86/pci/
-F: arch/x86/kernel/quirks.c
-
-PCI ENDPOINT SUBSYSTEM
-M: Kishon Vijay Abraham I <kishon@ti.com>
+PCI DRIVER FOR AARDVARK (Marvell Armada 3700)
+M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
L: linux-pci@vger.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/kishon/pci-endpoint.git
-S: Supported
-F: drivers/pci/endpoint/
-F: drivers/misc/pci_endpoint_test.c
-F: tools/pci/
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/pci/aardvark-pci.txt
+F: drivers/pci/host/pci-aardvark.c
PCI DRIVER FOR ALTERA PCIE IP
M: Ley Foon Tan <lftan@altera.com>
@@ -10070,6 +10065,14 @@ S: Supported
F: Documentation/devicetree/bindings/pci/altera-pcie.txt
F: drivers/pci/host/pcie-altera.c
+PCI DRIVER FOR APPLIEDMICRO XGENE
+M: Tanmay Inamdar <tinamdar@apm.com>
+L: linux-pci@vger.kernel.org
+L: linux-arm-kernel@lists.infradead.org
+S: Maintained
+F: Documentation/devicetree/bindings/pci/xgene-pci.txt
+F: drivers/pci/host/pci-xgene.c
+
PCI DRIVER FOR ARM VERSATILE PLATFORM
M: Rob Herring <robh@kernel.org>
L: linux-pci@vger.kernel.org
@@ -10086,14 +10089,6 @@ S: Maintained
F: Documentation/devicetree/bindings/pci/pci-armada8k.txt
F: drivers/pci/dwc/pcie-armada8k.c
-PCI DRIVER FOR APPLIEDMICRO XGENE
-M: Tanmay Inamdar <tinamdar@apm.com>
-L: linux-pci@vger.kernel.org
-L: linux-arm-kernel@lists.infradead.org
-S: Maintained
-F: Documentation/devicetree/bindings/pci/xgene-pci.txt
-F: drivers/pci/host/pci-xgene.c
-
PCI DRIVER FOR FREESCALE LAYERSCAPE
M: Minghuan Lian <minghuan.Lian@freescale.com>
M: Mingkai Hu <mingkai.hu@freescale.com>
@@ -10104,6 +10099,15 @@ L: linux-arm-kernel@lists.infradead.org
S: Maintained
F: drivers/pci/dwc/*layerscape*
+PCI DRIVER FOR GENERIC OF HOSTS
+M: Will Deacon <will.deacon@arm.com>
+L: linux-pci@vger.kernel.org
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: Documentation/devicetree/bindings/pci/host-generic-pci.txt
+F: drivers/pci/host/pci-host-common.c
+F: drivers/pci/host/pci-host-generic.c
+
PCI DRIVER FOR IMX6
M: Richard Zhu <hongxing.zhu@nxp.com>
M: Lucas Stach <l.stach@pengutronix.de>
@@ -10113,28 +10117,11 @@ S: Maintained
F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
F: drivers/pci/dwc/*imx6*
-PCI DRIVER FOR TI KEYSTONE
-M: Murali Karicheri <m-karicheri2@ti.com>
-L: linux-pci@vger.kernel.org
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-F: drivers/pci/dwc/*keystone*
-
-PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support)
-M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
-M: Jason Cooper <jason@lakedaemon.net>
-L: linux-pci@vger.kernel.org
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-F: drivers/pci/host/*mvebu*
-
-PCI DRIVER FOR AARDVARK (Marvell Armada 3700)
-M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD)
+M: Keith Busch <keith.busch@intel.com>
L: linux-pci@vger.kernel.org
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-F: Documentation/devicetree/bindings/pci/aardvark-pci.txt
-F: drivers/pci/host/pci-aardvark.c
+S: Supported
+F: drivers/pci/host/vmd.c
PCI DRIVER FOR MICROSEMI SWITCHTEC
M: Kurt Schwemmer <kurt.schwemmer@microsemi.com>
@@ -10147,6 +10134,14 @@ F: Documentation/ABI/testing/sysfs-class-switchtec
F: drivers/pci/switch/switchtec*
F: include/uapi/linux/switchtec_ioctl.h
+PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support)
+M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+M: Jason Cooper <jason@lakedaemon.net>
+L: linux-pci@vger.kernel.org
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Maintained
+F: drivers/pci/host/*mvebu*
+
PCI DRIVER FOR NVIDIA TEGRA
M: Thierry Reding <thierry.reding@gmail.com>
L: linux-tegra@vger.kernel.org
@@ -10155,14 +10150,6 @@ S: Supported
F: Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
F: drivers/pci/host/pci-tegra.c
-PCI DRIVER FOR TI DRA7XX
-M: Kishon Vijay Abraham I <kishon@ti.com>
-L: linux-omap@vger.kernel.org
-L: linux-pci@vger.kernel.org
-S: Supported
-F: Documentation/devicetree/bindings/pci/ti-pci.txt
-F: drivers/pci/dwc/pci-dra7xx.c
-
PCI DRIVER FOR RENESAS R-CAR
M: Simon Horman <horms@verge.net.au>
L: linux-pci@vger.kernel.org
@@ -10186,26 +10173,44 @@ S: Maintained
F: Documentation/devicetree/bindings/pci/designware-pcie.txt
F: drivers/pci/dwc/*designware*
-PCI DRIVER FOR GENERIC OF HOSTS
-M: Will Deacon <will.deacon@arm.com>
+PCI DRIVER FOR TI DRA7XX
+M: Kishon Vijay Abraham I <kishon@ti.com>
+L: linux-omap@vger.kernel.org
+L: linux-pci@vger.kernel.org
+S: Supported
+F: Documentation/devicetree/bindings/pci/ti-pci.txt
+F: drivers/pci/dwc/pci-dra7xx.c
+
+PCI DRIVER FOR TI KEYSTONE
+M: Murali Karicheri <m-karicheri2@ti.com>
L: linux-pci@vger.kernel.org
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
-F: Documentation/devicetree/bindings/pci/host-generic-pci.txt
-F: drivers/pci/host/pci-host-common.c
-F: drivers/pci/host/pci-host-generic.c
+F: drivers/pci/dwc/*keystone*
-PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD)
-M: Keith Busch <keith.busch@intel.com>
+PCI ENDPOINT SUBSYSTEM
+M: Kishon Vijay Abraham I <kishon@ti.com>
L: linux-pci@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/kishon/pci-endpoint.git
S: Supported
-F: drivers/pci/host/vmd.c
+F: drivers/pci/endpoint/
+F: drivers/misc/pci_endpoint_test.c
+F: tools/pci/
-PCIE DRIVER FOR ST SPEAR13XX
-M: Pratyush Anand <pratyush.anand@gmail.com>
+PCI ENHANCED ERROR HANDLING (EEH) FOR POWERPC
+M: Russell Currey <ruscur@russell.cc>
+L: linuxppc-dev@lists.ozlabs.org
+S: Supported
+F: Documentation/powerpc/eeh-pci-error-recovery.txt
+F: arch/powerpc/kernel/eeh*.c
+F: arch/powerpc/platforms/*/eeh*.c
+F: arch/powerpc/include/*/eeh*.h
+
+PCI ERROR RECOVERY
+M: Linas Vepstas <linasvepstas@gmail.com>
L: linux-pci@vger.kernel.org
-S: Maintained
-F: drivers/pci/dwc/*spear*
+S: Supported
+F: Documentation/PCI/pci-error-recovery.txt
PCI MSI DRIVER FOR ALTERA MSI IP
M: Ley Foon Tan <lftan@altera.com>
@@ -10223,6 +10228,19 @@ S: Maintained
F: Documentation/devicetree/bindings/pci/xgene-pci-msi.txt
F: drivers/pci/host/pci-xgene-msi.c
+PCI SUBSYSTEM
+M: Bjorn Helgaas <bhelgaas@google.com>
+L: linux-pci@vger.kernel.org
+Q: http://patchwork.ozlabs.org/project/linux-pci/list/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git
+S: Supported
+F: Documentation/devicetree/bindings/pci/
+F: Documentation/PCI/
+F: drivers/pci/
+F: include/linux/pci*
+F: arch/x86/pci/
+F: arch/x86/kernel/quirks.c
+
PCIE DRIVER FOR AXIS ARTPEC
M: Niklas Cassel <niklas.cassel@axis.com>
M: Jesper Nilsson <jesper.nilsson@axis.com>
@@ -10232,6 +10250,14 @@ S: Maintained
F: Documentation/devicetree/bindings/pci/axis,artpec*
F: drivers/pci/dwc/*artpec*
+PCIE DRIVER FOR CAVIUM THUNDERX
+M: David Daney <david.daney@cavium.com>
+L: linux-pci@vger.kernel.org
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S: Supported
+F: Documentation/devicetree/bindings/pci/pci-thunder-*
+F: drivers/pci/host/pci-thunder-*
+
PCIE DRIVER FOR HISILICON
M: Zhou Wang <wangzhou1@hisilicon.com>
M: Gabriele Paoloni <gabriele.paoloni@huawei.com>
@@ -10248,6 +10274,21 @@ S: Maintained
F: Documentation/devicetree/bindings/pci/pcie-kirin.txt
F: drivers/pci/dwc/pcie-kirin.c
+PCIE DRIVER FOR MEDIATEK
+M: Ryder Lee <ryder.lee@mediatek.com>
+L: linux-pci@vger.kernel.org
+L: linux-mediatek@lists.infradead.org
+S: Supported
+F: Documentation/devicetree/bindings/pci/mediatek*
+F: drivers/pci/host/*mediatek*
+
+PCIE DRIVER FOR QUALCOMM MSM
+M: Stanimir Varbanov <svarbanov@mm-sol.com>
+L: linux-pci@vger.kernel.org
+L: linux-arm-msm@vger.kernel.org
+S: Maintained
+F: drivers/pci/dwc/*qcom*
+
PCIE DRIVER FOR ROCKCHIP
M: Shawn Lin <shawn.lin@rock-chips.com>
L: linux-pci@vger.kernel.org
@@ -10256,28 +10297,11 @@ S: Maintained
F: Documentation/devicetree/bindings/pci/rockchip-pcie.txt
F: drivers/pci/host/pcie-rockchip.c
-PCIE DRIVER FOR QUALCOMM MSM
-M: Stanimir Varbanov <svarbanov@mm-sol.com>
-L: linux-pci@vger.kernel.org
-L: linux-arm-msm@vger.kernel.org
-S: Maintained
-F: drivers/pci/dwc/*qcom*
-
-PCIE DRIVER FOR CAVIUM THUNDERX
-M: David Daney <david.daney@cavium.com>
+PCIE DRIVER FOR ST SPEAR13XX
+M: Pratyush Anand <pratyush.anand@gmail.com>
L: linux-pci@vger.kernel.org
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Supported
-F: Documentation/devicetree/bindings/pci/pci-thunder-*
-F: drivers/pci/host/pci-thunder-*
-
-PCIE DRIVER FOR MEDIATEK
-M: Ryder Lee <ryder.lee@mediatek.com>
-L: linux-pci@vger.kernel.org
-L: linux-mediatek@lists.infradead.org
-S: Supported
-F: Documentation/devicetree/bindings/pci/mediatek*
-F: drivers/pci/host/*mediatek*
+S: Maintained
+F: drivers/pci/dwc/*spear*
PCMCIA SUBSYSTEM
P: Linux PCMCIA Team
@@ -10380,7 +10404,7 @@ L: linux-gpio@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git
S: Maintained
F: Documentation/devicetree/bindings/pinctrl/
-F: Documentation/pinctrl.txt
+F: Documentation/driver-api/pinctl.rst
F: drivers/pinctrl/
F: include/linux/pinctrl/
@@ -10446,14 +10470,14 @@ S: Maintained
F: drivers/pinctrl/spear/
PISTACHIO SOC SUPPORT
-M: James Hartley <james.hartley@imgtec.com>
-M: Ionela Voinescu <ionela.voinescu@imgtec.com>
-L: linux-mips@linux-mips.org
-S: Maintained
-F: arch/mips/pistachio/
-F: arch/mips/include/asm/mach-pistachio/
-F: arch/mips/boot/dts/img/pistachio*
-F: arch/mips/configs/pistachio*_defconfig
+M: James Hartley <james.hartley@imgtec.com>
+M: Ionela Voinescu <ionela.voinescu@imgtec.com>
+L: linux-mips@linux-mips.org
+S: Maintained
+F: arch/mips/pistachio/
+F: arch/mips/include/asm/mach-pistachio/
+F: arch/mips/boot/dts/img/pistachio*
+F: arch/mips/configs/pistachio*_defconfig
PKTCDVD DRIVER
S: Orphan
@@ -10496,6 +10520,11 @@ L: linux-scsi@vger.kernel.org
S: Supported
F: drivers/scsi/pm8001/
+PNP SUPPORT
+M: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+S: Maintained
+F: drivers/pnp/
+
POSIX CLOCKS and TIMERS
M: Thomas Gleixner <tglx@linutronix.de>
L: linux-kernel@vger.kernel.org
@@ -10517,15 +10546,6 @@ F: include/linux/pm_*
F: include/linux/powercap.h
F: drivers/powercap/
-POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS
-M: Sebastian Reichel <sre@kernel.org>
-L: linux-pm@vger.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git
-S: Maintained
-F: Documentation/devicetree/bindings/power/supply/
-F: include/linux/power_supply.h
-F: drivers/power/supply/
-
POWER STATE COORDINATION INTERFACE (PSCI)
M: Mark Rutland <mark.rutland@arm.com>
M: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
@@ -10535,23 +10555,21 @@ F: drivers/firmware/psci*.c
F: include/linux/psci.h
F: include/uapi/linux/psci.h
+POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS
+M: Sebastian Reichel <sre@kernel.org>
+L: linux-pm@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git
+S: Maintained
+F: Documentation/devicetree/bindings/power/supply/
+F: include/linux/power_supply.h
+F: drivers/power/supply/
+
POWERNV OPERATOR PANEL LCD DISPLAY DRIVER
M: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
L: linuxppc-dev@lists.ozlabs.org
S: Maintained
F: drivers/char/powernv-op-panel.c
-PNP SUPPORT
-M: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
-S: Maintained
-F: drivers/pnp/
-
-PPP PROTOCOL DRIVERS AND COMPRESSORS
-M: Paul Mackerras <paulus@samba.org>
-L: linux-ppp@vger.kernel.org
-S: Maintained
-F: drivers/net/ppp/ppp_*
-
PPP OVER ATM (RFC 2364)
M: Mitchell Blank Jr <mitch@sfgoth.com>
S: Maintained
@@ -10571,6 +10589,12 @@ F: net/l2tp/l2tp_ppp.c
F: include/linux/if_pppol2tp.h
F: include/uapi/linux/if_pppol2tp.h
+PPP PROTOCOL DRIVERS AND COMPRESSORS
+M: Paul Mackerras <paulus@samba.org>
+L: linux-ppp@vger.kernel.org
+S: Maintained
+F: drivers/net/ppp/ppp_*
+
PPS SUPPORT
M: Rodolfo Giometti <giometti@enneenne.com>
W: http://wiki.enneenne.com/index.php/LinuxPPS_support
@@ -10684,7 +10708,6 @@ F: drivers/ptp/*
F: include/linux/ptp_cl*
PTRACE SUPPORT
-M: Roland McGrath <roland@hack.frob.com>
M: Oleg Nesterov <oleg@redhat.com>
S: Maintained
F: include/asm-generic/syscall.h
@@ -10692,7 +10715,12 @@ F: include/linux/ptrace.h
F: include/linux/regset.h
F: include/linux/tracehook.h
F: include/uapi/linux/ptrace.h
+F: include/uapi/linux/ptrace.h
+F: include/asm-generic/ptrace.h
F: kernel/ptrace.c
+F: arch/*/ptrace*.c
+F: arch/*/*/ptrace*.c
+F: arch/*/include/asm/ptrace*.h
PULSE8-CEC DRIVER
M: Hans Verkuil <hverkuil@xs4all.nl>
@@ -10741,6 +10769,20 @@ F: include/linux/pwm_backlight.h
F: drivers/gpio/gpio-mvebu.c
F: Documentation/devicetree/bindings/gpio/gpio-mvebu.txt
+PXA GPIO DRIVER
+M: Robert Jarzmik <robert.jarzmik@free.fr>
+L: linux-gpio@vger.kernel.org
+S: Maintained
+F: drivers/gpio/gpio-pxa.c
+
+PXA MMCI DRIVER
+S: Orphan
+
+PXA RTC DRIVER
+M: Robert Jarzmik <robert.jarzmik@free.fr>
+L: linux-rtc@vger.kernel.org
+S: Maintained
+
PXA2xx/PXA3xx SUPPORT
M: Daniel Mack <daniel@zonque.org>
M: Haojian Zhuang <haojian.zhuang@gmail.com>
@@ -10760,36 +10802,12 @@ F: include/sound/pxa2xx-lib.h
F: sound/arm/pxa*
F: sound/soc/pxa/
-PXA GPIO DRIVER
-M: Robert Jarzmik <robert.jarzmik@free.fr>
-L: linux-gpio@vger.kernel.org
-S: Maintained
-F: drivers/gpio/gpio-pxa.c
-
PXA3xx NAND FLASH DRIVER
M: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
L: linux-mtd@lists.infradead.org
S: Maintained
F: drivers/mtd/nand/pxa3xx_nand.c
-MMP SUPPORT
-M: Eric Miao <eric.y.miao@gmail.com>
-M: Haojian Zhuang <haojian.zhuang@gmail.com>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-T: git git://github.com/hzhuang1/linux.git
-T: git git://git.linaro.org/people/ycmiao/pxa-linux.git
-S: Maintained
-F: arch/arm/boot/dts/mmp*
-F: arch/arm/mach-mmp/
-
-PXA MMCI DRIVER
-S: Orphan
-
-PXA RTC DRIVER
-M: Robert Jarzmik <robert.jarzmik@free.fr>
-L: linux-rtc@vger.kernel.org
-S: Maintained
-
QAT DRIVER
M: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
M: Salvatore Benedetto <salvatore.benedetto@intel.com>
@@ -10797,12 +10815,56 @@ L: qat-linux@intel.com
S: Supported
F: drivers/crypto/qat/
+QCOM AUDIO (ASoC) DRIVERS
+M: Patrick Lai <plai@codeaurora.org>
+M: Banajit Goswami <bgoswami@codeaurora.org>
+L: alsa-devel@alsa-project.org (moderated for non-subscribers)
+S: Supported
+F: sound/soc/qcom/
+
+QEMU MACHINE EMULATOR AND VIRTUALIZER SUPPORT
+M: Gabriel Somlo <somlo@cmu.edu>
+M: "Michael S. Tsirkin" <mst@redhat.com>
+L: qemu-devel@nongnu.org
+S: Maintained
+F: drivers/firmware/qemu_fw_cfg.c
+
QIB DRIVER
M: Mike Marciniszyn <infinipath@intel.com>
L: linux-rdma@vger.kernel.org
S: Supported
F: drivers/infiniband/hw/qib/
+QLOGIC QL41xxx FCOE DRIVER
+M: QLogic-Storage-Upstream@cavium.com
+L: linux-scsi@vger.kernel.org
+S: Supported
+F: drivers/scsi/qedf/
+
+QLOGIC QL41xxx ISCSI DRIVER
+M: QLogic-Storage-Upstream@cavium.com
+L: linux-scsi@vger.kernel.org
+S: Supported
+F: drivers/scsi/qedi/
+
+QLOGIC QL4xxx ETHERNET DRIVER
+M: Yuval Mintz <Yuval.Mintz@cavium.com>
+M: Ariel Elior <Ariel.Elior@cavium.com>
+M: everest-linux-l2@cavium.com
+L: netdev@vger.kernel.org
+S: Supported
+F: drivers/net/ethernet/qlogic/qed/
+F: include/linux/qed/
+F: drivers/net/ethernet/qlogic/qede/
+
+QLOGIC QL4xxx RDMA DRIVER
+M: Ram Amrani <Ram.Amrani@cavium.com>
+M: Ariel Elior <Ariel.Elior@cavium.com>
+L: linux-rdma@vger.kernel.org
+S: Supported
+F: drivers/infiniband/hw/qedr/
+F: include/uapi/rdma/qedr-abi.h
+
QLOGIC QLA1280 SCSI DRIVER
M: Michael Reed <mdr@sgi.com>
L: linux-scsi@vger.kernel.org
@@ -10816,13 +10878,6 @@ S: Supported
F: Documentation/scsi/LICENSE.qla2xxx
F: drivers/scsi/qla2xxx/
-QLOGIC QLA4XXX iSCSI DRIVER
-M: QLogic-Storage-Upstream@qlogic.com
-L: linux-scsi@vger.kernel.org
-S: Supported
-F: Documentation/scsi/LICENSE.qla4xxx
-F: drivers/scsi/qla4xxx/
-
QLOGIC QLA3XXX NETWORK DRIVER
M: Dept-GELinuxNICDev@cavium.com
L: netdev@vger.kernel.org
@@ -10830,6 +10885,13 @@ S: Supported
F: Documentation/networking/LICENSE.qla3xxx
F: drivers/net/ethernet/qlogic/qla3xxx.*
+QLOGIC QLA4XXX iSCSI DRIVER
+M: QLogic-Storage-Upstream@qlogic.com
+L: linux-scsi@vger.kernel.org
+S: Supported
+F: Documentation/scsi/LICENSE.qla4xxx
+F: drivers/scsi/qla4xxx/
+
QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER
M: Harish Patil <harish.patil@cavium.com>
M: Manish Chopra <manish.chopra@cavium.com>
@@ -10846,28 +10908,6 @@ L: netdev@vger.kernel.org
S: Supported
F: drivers/net/ethernet/qlogic/qlge/
-QLOGIC QL4xxx ETHERNET DRIVER
-M: Yuval Mintz <Yuval.Mintz@cavium.com>
-M: Ariel Elior <Ariel.Elior@cavium.com>
-M: everest-linux-l2@cavium.com
-L: netdev@vger.kernel.org
-S: Supported
-F: drivers/net/ethernet/qlogic/qed/
-F: include/linux/qed/
-F: drivers/net/ethernet/qlogic/qede/
-
-QLOGIC QL41xxx ISCSI DRIVER
-M: QLogic-Storage-Upstream@cavium.com
-L: linux-scsi@vger.kernel.org
-S: Supported
-F: drivers/scsi/qedi/
-
-QLOGIC QL41xxx FCOE DRIVER
-M: QLogic-Storage-Upstream@cavium.com
-L: linux-scsi@vger.kernel.org
-S: Supported
-F: drivers/scsi/qedf/
-
QNX4 FILESYSTEM
M: Anders Larsen <al@alarsen.net>
W: http://www.alarsen.net/linux/qnx4fs/
@@ -10894,13 +10934,6 @@ T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained
F: drivers/media/tuners/qt1010*
-QUALCOMM ATHEROS ATH9K WIRELESS DRIVER
-M: QCA ath9k Development <ath9k-devel@qca.qualcomm.com>
-L: linux-wireless@vger.kernel.org
-W: http://wireless.kernel.org/en/users/Drivers/ath9k
-S: Supported
-F: drivers/net/wireless/ath/ath9k/
-
QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
M: Kalle Valo <kvalo@qca.qualcomm.com>
L: ath10k@lists.infradead.org
@@ -10909,6 +10942,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
S: Supported
F: drivers/net/wireless/ath/ath10k/
+QUALCOMM ATHEROS ATH9K WIRELESS DRIVER
+M: QCA ath9k Development <ath9k-devel@qca.qualcomm.com>
+L: linux-wireless@vger.kernel.org
+W: http://wireless.kernel.org/en/users/Drivers/ath9k
+S: Supported
+F: drivers/net/wireless/ath/ath9k/
+
QUALCOMM EMAC GIGABIT ETHERNET DRIVER
M: Timur Tabi <timur@codeaurora.org>
L: netdev@vger.kernel.org
@@ -10938,33 +10978,24 @@ T: git git://github.com/KrasnikovEugene/wcn36xx.git
S: Supported
F: drivers/net/wireless/ath/wcn36xx/
-QEMU MACHINE EMULATOR AND VIRTUALIZER SUPPORT
-M: Gabriel Somlo <somlo@cmu.edu>
-M: "Michael S. Tsirkin" <mst@redhat.com>
-L: qemu-devel@nongnu.org
-S: Maintained
-F: drivers/firmware/qemu_fw_cfg.c
-
QUANTENNA QTNFMAC WIRELESS DRIVER
-M: Igor Mitsyanko <imitsyanko@quantenna.com>
-M: Avinash Patil <avinashp@quantenna.com>
-M: Sergey Matyukevich <smatyukevich@quantenna.com>
-L: linux-wireless@vger.kernel.org
-S: Maintained
-F: drivers/net/wireless/quantenna
+M: Igor Mitsyanko <imitsyanko@quantenna.com>
+M: Avinash Patil <avinashp@quantenna.com>
+M: Sergey Matyukevich <smatyukevich@quantenna.com>
+L: linux-wireless@vger.kernel.org
+S: Maintained
+F: drivers/net/wireless/quantenna
-RADOS BLOCK DEVICE (RBD)
-M: Ilya Dryomov <idryomov@gmail.com>
-M: Sage Weil <sage@redhat.com>
-M: Alex Elder <elder@kernel.org>
-L: ceph-devel@vger.kernel.org
-W: http://ceph.com/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git
-T: git git://github.com/ceph/ceph-client.git
+RADEON and AMDGPU DRM DRIVERS
+M: Alex Deucher <alexander.deucher@amd.com>
+M: Christian König <christian.koenig@amd.com>
+L: amd-gfx@lists.freedesktop.org
+T: git git://people.freedesktop.org/~agd5f/linux
S: Supported
-F: Documentation/ABI/testing/sysfs-bus-rbd
-F: drivers/block/rbd.c
-F: drivers/block/rbd_types.h
+F: drivers/gpu/drm/radeon/
+F: include/uapi/drm/radeon_drm.h
+F: drivers/gpu/drm/amd/
+F: include/uapi/drm/amdgpu_drm.h
RADEON FRAMEBUFFER DISPLAY DRIVER
M: Benjamin Herrenschmidt <benh@kernel.crashing.org>
@@ -10988,6 +11019,19 @@ S: Maintained
F: drivers/media/radio/radio-shark2.c
F: drivers/media/radio/radio-tea5777.c
+RADOS BLOCK DEVICE (RBD)
+M: Ilya Dryomov <idryomov@gmail.com>
+M: Sage Weil <sage@redhat.com>
+M: Alex Elder <elder@kernel.org>
+L: ceph-devel@vger.kernel.org
+W: http://ceph.com/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git
+T: git git://github.com/ceph/ceph-client.git
+S: Supported
+F: Documentation/ABI/testing/sysfs-bus-rbd
+F: drivers/block/rbd.c
+F: drivers/block/rbd_types.h
+
RAGE128 FRAMEBUFFER DISPLAY DRIVER
M: Paul Mackerras <paulus@samba.org>
L: linux-fbdev@vger.kernel.org
@@ -11067,6 +11111,12 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/rdc/r6040.c
+RDMAVT - RDMA verbs software
+M: Dennis Dalessandro <dennis.dalessandro@intel.com>
+L: linux-rdma@vger.kernel.org
+S: Supported
+F: drivers/infiniband/sw/rdmavt
+
RDS - RELIABLE DATAGRAM SOCKETS
M: Santosh Shilimkar <santosh.shilimkar@oracle.com>
L: netdev@vger.kernel.org
@@ -11077,12 +11127,6 @@ S: Supported
F: net/rds/
F: Documentation/networking/rds.txt
-RDMAVT - RDMA verbs software
-M: Dennis Dalessandro <dennis.dalessandro@intel.com>
-L: linux-rdma@vger.kernel.org
-S: Supported
-F: drivers/infiniband/sw/rdmavt
-
RDT - RESOURCE ALLOCATION
M: Fenghua Yu <fenghua.yu@intel.com>
L: linux-kernel@vger.kernel.org
@@ -11131,11 +11175,6 @@ S: Maintained
F: sound/soc/codecs/rt*
F: include/sound/rt*.h
-REISERFS FILE SYSTEM
-L: reiserfs-devel@vger.kernel.org
-S: Supported
-F: fs/reiserfs/
-
REGISTER MAP ABSTRACTION
M: Mark Brown <broonie@kernel.org>
L: linux-kernel@vger.kernel.org
@@ -11145,6 +11184,11 @@ F: Documentation/devicetree/bindings/regmap/
F: drivers/base/regmap/
F: include/linux/regmap.h
+REISERFS FILE SYSTEM
+L: reiserfs-devel@vger.kernel.org
+S: Supported
+F: fs/reiserfs/
+
REMOTE PROCESSOR (REMOTEPROC) SUBSYSTEM
M: Ohad Ben-Cohen <ohad@wizery.com>
M: Bjorn Andersson <bjorn.andersson@linaro.org>
@@ -11220,16 +11264,16 @@ S: Maintained
F: lib/rhashtable.c
F: include/linux/rhashtable.h
-RICOH SMARTMEDIA/XD DRIVER
+RICOH R5C592 MEMORYSTICK DRIVER
M: Maxim Levitsky <maximlevitsky@gmail.com>
S: Maintained
-F: drivers/mtd/nand/r852.c
-F: drivers/mtd/nand/r852.h
+F: drivers/memstick/host/r592.*
-RICOH R5C592 MEMORYSTICK DRIVER
+RICOH SMARTMEDIA/XD DRIVER
M: Maxim Levitsky <maximlevitsky@gmail.com>
S: Maintained
-F: drivers/memstick/host/r592.*
+F: drivers/mtd/nand/r852.c
+F: drivers/mtd/nand/r852.h
ROCCAT DRIVERS
M: Stefan Achatz <erazor_de@users.sourceforge.net>
@@ -11366,6 +11410,23 @@ S: Supported
F: drivers/s390/block/dasd*
F: block/partitions/ibm.c
+S390 IOMMU (PCI)
+M: Gerald Schaefer <gerald.schaefer@de.ibm.com>
+L: linux-s390@vger.kernel.org
+W: http://www.ibm.com/developerworks/linux/linux390/
+S: Supported
+F: drivers/iommu/s390-iommu.c
+
+S390 IUCV NETWORK LAYER
+M: Julian Wiedmann <jwi@linux.vnet.ibm.com>
+M: Ursula Braun <ubraun@linux.vnet.ibm.com>
+L: linux-s390@vger.kernel.org
+W: http://www.ibm.com/developerworks/linux/linux390/
+S: Supported
+F: drivers/s390/net/*iucv*
+F: include/net/iucv/
+F: net/iucv/
+
S390 NETWORK DRIVERS
M: Julian Wiedmann <jwi@linux.vnet.ibm.com>
M: Ursula Braun <ubraun@linux.vnet.ibm.com>
@@ -11383,6 +11444,16 @@ S: Supported
F: arch/s390/pci/
F: drivers/pci/hotplug/s390_pci_hpc.c
+S390 VFIO-CCW DRIVER
+M: Cornelia Huck <cohuck@redhat.com>
+M: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
+L: linux-s390@vger.kernel.org
+L: kvm@vger.kernel.org
+S: Supported
+F: drivers/s390/cio/vfio_ccw*
+F: Documentation/s390/vfio-ccw.txt
+F: include/uapi/linux/vfio_ccw.h
+
S390 ZCRYPT DRIVER
M: Harald Freudenberger <freude@de.ibm.com>
L: linux-s390@vger.kernel.org
@@ -11397,33 +11468,6 @@ W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
F: drivers/s390/scsi/zfcp_*
-S390 IUCV NETWORK LAYER
-M: Julian Wiedmann <jwi@linux.vnet.ibm.com>
-M: Ursula Braun <ubraun@linux.vnet.ibm.com>
-L: linux-s390@vger.kernel.org
-W: http://www.ibm.com/developerworks/linux/linux390/
-S: Supported
-F: drivers/s390/net/*iucv*
-F: include/net/iucv/
-F: net/iucv/
-
-S390 IOMMU (PCI)
-M: Gerald Schaefer <gerald.schaefer@de.ibm.com>
-L: linux-s390@vger.kernel.org
-W: http://www.ibm.com/developerworks/linux/linux390/
-S: Supported
-F: drivers/iommu/s390-iommu.c
-
-S390 VFIO-CCW DRIVER
-M: Cornelia Huck <cohuck@redhat.com>
-M: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
-L: linux-s390@vger.kernel.org
-L: kvm@vger.kernel.org
-S: Supported
-F: drivers/s390/cio/vfio_ccw*
-F: Documentation/s390/vfio-ccw.txt
-F: include/uapi/linux/vfio_ccw.h
-
S3C24XX SD/MMC Driver
M: Ben Dooks <ben-linux@fluff.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -11457,12 +11501,6 @@ F: drivers/media/common/saa7146/
F: drivers/media/pci/saa7146/
F: include/media/saa7146*
-SAMSUNG LAPTOP DRIVER
-M: Corentin Chary <corentin.chary@gmail.com>
-L: platform-driver-x86@vger.kernel.org
-S: Maintained
-F: drivers/platform/x86/samsung-laptop.c
-
SAMSUNG AUDIO (ASoC) DRIVERS
M: Krzysztof Kozlowski <krzk@kernel.org>
M: Sangbeom Kim <sbkim73@samsung.com>
@@ -11485,6 +11523,12 @@ L: linux-fbdev@vger.kernel.org
S: Maintained
F: drivers/video/fbdev/s3c-fb.c
+SAMSUNG LAPTOP DRIVER
+M: Corentin Chary <corentin.chary@gmail.com>
+L: platform-driver-x86@vger.kernel.org
+S: Maintained
+F: drivers/platform/x86/samsung-laptop.c
+
SAMSUNG MULTIFUNCTION PMIC DEVICE DRIVERS
M: Sangbeom Kim <sbkim73@samsung.com>
M: Krzysztof Kozlowski <krzk@kernel.org>
@@ -11503,22 +11547,6 @@ F: Documentation/devicetree/bindings/regulator/samsung,s2m*.txt
F: Documentation/devicetree/bindings/regulator/samsung,s5m*.txt
F: Documentation/devicetree/bindings/clock/samsung,s2mps11.txt
-SAMSUNG S5P Security SubSystem (SSS) DRIVER
-M: Krzysztof Kozlowski <krzk@kernel.org>
-M: Vladimir Zapolskiy <vz@mleia.com>
-L: linux-crypto@vger.kernel.org
-L: linux-samsung-soc@vger.kernel.org
-S: Maintained
-F: drivers/crypto/s5p-sss.c
-
-SAMSUNG S5P/EXYNOS4 SOC SERIES CAMERA SUBSYSTEM DRIVERS
-M: Kyungmin Park <kyungmin.park@samsung.com>
-M: Sylwester Nawrocki <s.nawrocki@samsung.com>
-L: linux-media@vger.kernel.org
-Q: https://patchwork.linuxtv.org/project/linux-media/list/
-S: Supported
-F: drivers/media/platform/exynos4-is/
-
SAMSUNG S3C24XX/S3C64XX SOC SERIES CAMIF DRIVER
M: Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
L: linux-media@vger.kernel.org
@@ -11527,6 +11555,13 @@ S: Maintained
F: drivers/media/platform/s3c-camif/
F: include/media/drv-intf/s3c_camif.h
+SAMSUNG S3FWRN5 NFC DRIVER
+M: Robert Baldyga <r.baldyga@samsung.com>
+M: Krzysztof Opasiak <k.opasiak@samsung.com>
+L: linux-nfc@lists.01.org (moderated for non-subscribers)
+S: Supported
+F: drivers/nfc/s3fwrn5
+
SAMSUNG S5C73M3 CAMERA DRIVER
M: Kyungmin Park <kyungmin.park@samsung.com>
M: Andrzej Hajda <a.hajda@samsung.com>
@@ -11541,12 +11576,21 @@ L: linux-media@vger.kernel.org
S: Supported
F: drivers/media/i2c/s5k5baf.c
-SAMSUNG S3FWRN5 NFC DRIVER
-M: Robert Baldyga <r.baldyga@samsung.com>
-M: Krzysztof Opasiak <k.opasiak@samsung.com>
-L: linux-nfc@lists.01.org (moderated for non-subscribers)
+SAMSUNG S5P Security SubSystem (SSS) DRIVER
+M: Krzysztof Kozlowski <krzk@kernel.org>
+M: Vladimir Zapolskiy <vz@mleia.com>
+L: linux-crypto@vger.kernel.org
+L: linux-samsung-soc@vger.kernel.org
+S: Maintained
+F: drivers/crypto/s5p-sss.c
+
+SAMSUNG S5P/EXYNOS4 SOC SERIES CAMERA SUBSYSTEM DRIVERS
+M: Kyungmin Park <kyungmin.park@samsung.com>
+M: Sylwester Nawrocki <s.nawrocki@samsung.com>
+L: linux-media@vger.kernel.org
+Q: https://patchwork.linuxtv.org/project/linux-media/list/
S: Supported
-F: drivers/nfc/s3fwrn5
+F: drivers/media/platform/exynos4-is/
SAMSUNG SOC CLOCK DRIVERS
M: Sylwester Nawrocki <s.nawrocki@samsung.com>
@@ -11599,126 +11643,6 @@ F: drivers/phy/samsung/phy-s5pv210-usb2.c
F: drivers/phy/samsung/phy-samsung-usb2.c
F: drivers/phy/samsung/phy-samsung-usb2.h
-SERIAL DRIVERS
-M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-L: linux-serial@vger.kernel.org
-S: Maintained
-F: Documentation/devicetree/bindings/serial/
-F: drivers/tty/serial/
-
-SERIAL DEVICE BUS
-M: Rob Herring <robh@kernel.org>
-L: linux-serial@vger.kernel.org
-S: Maintained
-F: Documentation/devicetree/bindings/serial/slave-device.txt
-F: drivers/tty/serdev/
-F: include/linux/serdev.h
-
-SERIAL IR RECEIVER
-M: Sean Young <sean@mess.org>
-L: linux-media@vger.kernel.org
-S: Maintained
-F: drivers/media/rc/serial_ir.c
-
-STI CEC DRIVER
-M: Benjamin Gaignard <benjamin.gaignard@linaro.org>
-S: Maintained
-F: drivers/staging/media/st-cec/
-F: Documentation/devicetree/bindings/media/stih-cec.txt
-
-SHARED MEMORY COMMUNICATIONS (SMC) SOCKETS
-M: Ursula Braun <ubraun@linux.vnet.ibm.com>
-L: linux-s390@vger.kernel.org
-W: http://www.ibm.com/developerworks/linux/linux390/
-S: Supported
-F: net/smc/
-
-SYNOPSYS DESIGNWARE DMAC DRIVER
-M: Viresh Kumar <vireshk@kernel.org>
-M: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-S: Maintained
-F: include/linux/dma/dw.h
-F: include/linux/platform_data/dma-dw.h
-F: drivers/dma/dw/
-
-SYNOPSYS DESIGNWARE ENTERPRISE ETHERNET DRIVER
-M: Jie Deng <jiedeng@synopsys.com>
-L: netdev@vger.kernel.org
-S: Supported
-F: drivers/net/ethernet/synopsys/
-
-SYNOPSYS DESIGNWARE I2C DRIVER
-M: Jarkko Nikula <jarkko.nikula@linux.intel.com>
-R: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-R: Mika Westerberg <mika.westerberg@linux.intel.com>
-L: linux-i2c@vger.kernel.org
-S: Maintained
-F: drivers/i2c/busses/i2c-designware-*
-F: include/linux/platform_data/i2c-designware.h
-
-SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER
-M: Jaehoon Chung <jh80.chung@samsung.com>
-L: linux-mmc@vger.kernel.org
-S: Maintained
-F: drivers/mmc/host/dw_mmc*
-
-SYSTEM TRACE MODULE CLASS
-M: Alexander Shishkin <alexander.shishkin@linux.intel.com>
-S: Maintained
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/ash/stm.git
-F: Documentation/trace/stm.txt
-F: drivers/hwtracing/stm/
-F: include/linux/stm.h
-F: include/uapi/linux/stm.h
-
-TEE SUBSYSTEM
-M: Jens Wiklander <jens.wiklander@linaro.org>
-S: Maintained
-F: include/linux/tee_drv.h
-F: include/uapi/linux/tee.h
-F: drivers/tee/
-F: Documentation/tee.txt
-
-THUNDERBOLT DRIVER
-M: Andreas Noever <andreas.noever@gmail.com>
-M: Michael Jamet <michael.jamet@intel.com>
-M: Mika Westerberg <mika.westerberg@linux.intel.com>
-M: Yehezkel Bernat <yehezkel.bernat@intel.com>
-S: Maintained
-F: drivers/thunderbolt/
-
-TI BQ27XXX POWER SUPPLY DRIVER
-R: Andrew F. Davis <afd@ti.com>
-F: include/linux/power/bq27xxx_battery.h
-F: drivers/power/supply/bq27xxx_battery.c
-F: drivers/power/supply/bq27xxx_battery_i2c.c
-
-TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER
-M: John Stultz <john.stultz@linaro.org>
-M: Thomas Gleixner <tglx@linutronix.de>
-R: Stephen Boyd <sboyd@codeaurora.org>
-L: linux-kernel@vger.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core
-S: Supported
-F: include/linux/clocksource.h
-F: include/linux/time.h
-F: include/linux/timex.h
-F: include/uapi/linux/time.h
-F: include/uapi/linux/timex.h
-F: kernel/time/clocksource.c
-F: kernel/time/time*.c
-F: kernel/time/alarmtimer.c
-F: kernel/time/ntp.c
-F: tools/testing/selftests/timers/
-
-TI TRF7970A NFC DRIVER
-M: Mark Greer <mgreer@animalcreek.com>
-L: linux-wireless@vger.kernel.org
-L: linux-nfc@lists.01.org (moderated for non-subscribers)
-S: Supported
-F: drivers/nfc/trf7970a.c
-F: Documentation/devicetree/bindings/net/nfc/trf7970a.txt
-
SC1200 WDT DRIVER
M: Zwane Mwaikambo <zwanem@gmail.com>
S: Maintained
@@ -11747,16 +11671,6 @@ M: Lubomir Rintel <lkundrak@v3.sk>
S: Supported
F: drivers/char/pcmcia/scr24x_cs.c
-SYSTEM CONTROL & POWER INTERFACE (SCPI) Message Protocol drivers
-M: Sudeep Holla <sudeep.holla@arm.com>
-L: linux-arm-kernel@lists.infradead.org
-S: Maintained
-F: Documentation/devicetree/bindings/arm/arm,scpi.txt
-F: drivers/clk/clk-scpi.c
-F: drivers/cpufreq/scpi-cpufreq.c
-F: drivers/firmware/arm_scpi.c
-F: include/linux/scpi_protocol.h
-
SCSI CDROM DRIVER
M: Jens Axboe <axboe@kernel.dk>
L: linux-scsi@vger.kernel.org
@@ -11841,14 +11755,6 @@ L: sdricohcs-devel@lists.sourceforge.net (subscribers-only)
S: Maintained
F: drivers/mmc/host/sdricoh_cs.c
-SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER
-M: Adrian Hunter <adrian.hunter@intel.com>
-L: linux-mmc@vger.kernel.org
-T: git git://git.infradead.org/users/ahunter/linux-sdhci.git
-S: Maintained
-F: drivers/mmc/host/sdhci*
-F: include/linux/mmc/sdhci*
-
SECURE COMPUTING
M: Kees Cook <keescook@chromium.org>
R: Andy Lutomirski <luto@amacapital.net>
@@ -11871,6 +11777,14 @@ L: bcm-kernel-feedback-list@broadcom.com
S: Maintained
F: drivers/mmc/host/sdhci-brcmstb*
+SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER
+M: Adrian Hunter <adrian.hunter@intel.com>
+L: linux-mmc@vger.kernel.org
+T: git git://git.infradead.org/users/ahunter/linux-sdhci.git
+S: Maintained
+F: drivers/mmc/host/sdhci*
+F: include/linux/mmc/sdhci*
+
SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) SAMSUNG DRIVER
M: Ben Dooks <ben-linux@fluff.org>
M: Jaehoon Chung <jh80.chung@samsung.com>
@@ -11895,6 +11809,10 @@ F: block/opal_proto.h
F: include/linux/sed*
F: include/uapi/linux/sed*
+SECURITY CONTACT
+M: Security Officers <security@kernel.org>
+S: Supported
+
SECURITY SUBSYSTEM
M: James Morris <james.l.morris@oracle.com>
M: "Serge E. Hallyn" <serge@hallyn.com>
@@ -11904,10 +11822,6 @@ W: http://kernsec.org/
S: Supported
F: security/
-SECURITY CONTACT
-M: Security Officers <security@kernel.org>
-S: Supported
-
SELINUX SECURITY MODULE
M: Paul Moore <paul@paul-moore.com>
M: Stephen Smalley <sds@tycho.nsa.gov>
@@ -11921,62 +11835,32 @@ F: security/selinux/
F: scripts/selinux/
F: Documentation/admin-guide/LSM/SELinux.rst
-APPARMOR SECURITY MODULE
-M: John Johansen <john.johansen@canonical.com>
-L: apparmor@lists.ubuntu.com (subscribers-only, general discussion)
-W: apparmor.wiki.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/jj/apparmor-dev.git
-S: Supported
-F: security/apparmor/
-F: Documentation/admin-guide/LSM/apparmor.rst
-
-LOADPIN SECURITY MODULE
-M: Kees Cook <keescook@chromium.org>
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git lsm/loadpin
-S: Supported
-F: security/loadpin/
-F: Documentation/admin-guide/LSM/LoadPin.rst
-
-YAMA SECURITY MODULE
-M: Kees Cook <keescook@chromium.org>
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git yama/tip
-S: Supported
-F: security/yama/
-F: Documentation/admin-guide/LSM/Yama.rst
-
SENSABLE PHANTOM
M: Jiri Slaby <jirislaby@gmail.com>
S: Maintained
F: drivers/misc/phantom.c
F: include/uapi/linux/phantom.h
-Emulex 10Gbps iSCSI - OneConnect DRIVER
-M: Subbu Seetharaman <subbu.seetharaman@broadcom.com>
-M: Ketan Mukadam <ketan.mukadam@broadcom.com>
-M: Jitendra Bhivare <jitendra.bhivare@broadcom.com>
-L: linux-scsi@vger.kernel.org
-W: http://www.broadcom.com
-S: Supported
-F: drivers/scsi/be2iscsi/
+SERIAL DEVICE BUS
+M: Rob Herring <robh@kernel.org>
+L: linux-serial@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/serial/slave-device.txt
+F: drivers/tty/serdev/
+F: include/linux/serdev.h
-Emulex 10Gbps NIC BE2, BE3-R, Lancer, Skyhawk-R DRIVER (be2net)
-M: Sathya Perla <sathya.perla@broadcom.com>
-M: Ajit Khaparde <ajit.khaparde@broadcom.com>
-M: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
-M: Somnath Kotur <somnath.kotur@broadcom.com>
-L: netdev@vger.kernel.org
-W: http://www.emulex.com
-S: Supported
-F: drivers/net/ethernet/emulex/benet/
+SERIAL DRIVERS
+M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+L: linux-serial@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/serial/
+F: drivers/tty/serial/
-EMULEX ONECONNECT ROCE DRIVER
-M: Selvin Xavier <selvin.xavier@broadcom.com>
-M: Devesh Sharma <devesh.sharma@broadcom.com>
-L: linux-rdma@vger.kernel.org
-W: http://www.broadcom.com
-S: Odd Fixes
-F: drivers/infiniband/hw/ocrdma/
-F: include/uapi/rdma/ocrdma-abi.h
+SERIAL IR RECEIVER
+M: Sean Young <sean@mess.org>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: drivers/media/rc/serial_ir.c
SFC NETWORK DRIVER
M: Solarflare linux maintainers <linux-net-drivers@solarflare.com>
@@ -12005,6 +11889,24 @@ M: Robin Holt <robinmholt@gmail.com>
S: Maintained
F: drivers/misc/sgi-xp/
+SHARED MEMORY COMMUNICATIONS (SMC) SOCKETS
+M: Ursula Braun <ubraun@linux.vnet.ibm.com>
+L: linux-s390@vger.kernel.org
+W: http://www.ibm.com/developerworks/linux/linux390/
+S: Supported
+F: net/smc/
+
+SH_VEU V4L2 MEM2MEM DRIVER
+L: linux-media@vger.kernel.org
+S: Orphan
+F: drivers/media/platform/sh_veu.c
+
+SH_VOU V4L2 OUTPUT DRIVER
+L: linux-media@vger.kernel.org
+S: Orphan
+F: drivers/media/platform/sh_vou.c
+F: include/media/drv-intf/sh_vou.h
+
SI2157 MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
@@ -12087,24 +11989,14 @@ S: Maintained
F: drivers/input/touchscreen/silead.c
F: drivers/platform/x86/silead_dmi.c
-SIMPLEFB FB DRIVER
-M: Hans de Goede <hdegoede@redhat.com>
+SILICON MOTION SM712 FRAME BUFFER DRIVER
+M: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+M: Teddy Wang <teddy.wang@siliconmotion.com>
+M: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
L: linux-fbdev@vger.kernel.org
S: Maintained
-F: Documentation/devicetree/bindings/display/simple-framebuffer.txt
-F: drivers/video/fbdev/simplefb.c
-F: include/linux/platform_data/simplefb.h
-
-SH_VEU V4L2 MEM2MEM DRIVER
-L: linux-media@vger.kernel.org
-S: Orphan
-F: drivers/media/platform/sh_veu.c
-
-SH_VOU V4L2 OUTPUT DRIVER
-L: linux-media@vger.kernel.org
-S: Orphan
-F: drivers/media/platform/sh_vou.c
-F: include/media/drv-intf/sh_vou.h
+F: drivers/video/fbdev/sm712*
+F: Documentation/fb/sm712fb.txt
SIMPLE FIRMWARE INTERFACE (SFI)
M: Len Brown <lenb@kernel.org>
@@ -12116,6 +12008,14 @@ F: arch/x86/platform/sfi/
F: drivers/sfi/
F: include/linux/sfi*.h
+SIMPLEFB FB DRIVER
+M: Hans de Goede <hdegoede@redhat.com>
+L: linux-fbdev@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/display/simple-framebuffer.txt
+F: drivers/video/fbdev/simplefb.c
+F: include/linux/platform_data/simplefb.h
+
SIMTEC EB110ATX (Chalice CATS)
P: Ben Dooks
P: Vincent Sanders <vince@simtec.co.uk>
@@ -12140,61 +12040,6 @@ F: lib/siphash.c
F: lib/test_siphash.c
F: include/linux/siphash.h
-TI DAVINCI MACHINE SUPPORT
-M: Sekhar Nori <nsekhar@ti.com>
-M: Kevin Hilman <khilman@kernel.org>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci.git
-S: Supported
-F: arch/arm/mach-davinci/
-F: drivers/i2c/busses/i2c-davinci.c
-F: arch/arm/boot/dts/da850*
-
-TI DAVINCI SERIES MEDIA DRIVER
-M: "Lad, Prabhakar" <prabhakar.csengg@gmail.com>
-L: linux-media@vger.kernel.org
-W: https://linuxtv.org
-Q: http://patchwork.linuxtv.org/project/linux-media/list/
-T: git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
-S: Maintained
-F: drivers/media/platform/davinci/
-F: include/media/davinci/
-
-TI DAVINCI SERIES GPIO DRIVER
-M: Keerthy <j-keerthy@ti.com>
-L: linux-gpio@vger.kernel.org
-S: Maintained
-F: Documentation/devicetree/bindings/gpio/gpio-davinci.txt
-F: drivers/gpio/gpio-davinci.c
-
-TI AM437X VPFE DRIVER
-M: "Lad, Prabhakar" <prabhakar.csengg@gmail.com>
-L: linux-media@vger.kernel.org
-W: https://linuxtv.org
-Q: http://patchwork.linuxtv.org/project/linux-media/list/
-T: git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
-S: Maintained
-F: drivers/media/platform/am437x/
-
-OV2659 OMNIVISION SENSOR DRIVER
-M: "Lad, Prabhakar" <prabhakar.csengg@gmail.com>
-L: linux-media@vger.kernel.org
-W: https://linuxtv.org
-Q: http://patchwork.linuxtv.org/project/linux-media/list/
-T: git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
-S: Maintained
-F: drivers/media/i2c/ov2659.c
-F: include/media/i2c/ov2659.h
-
-SILICON MOTION SM712 FRAME BUFFER DRIVER
-M: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
-M: Teddy Wang <teddy.wang@siliconmotion.com>
-M: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
-L: linux-fbdev@vger.kernel.org
-S: Maintained
-F: drivers/video/fbdev/sm712*
-F: Documentation/fb/sm712fb.txt
-
SIS 190 ETHERNET DRIVER
M: Francois Romieu <romieu@fr.zoreil.com>
L: netdev@vger.kernel.org
@@ -12255,14 +12100,6 @@ S: Maintained
F: Documentation/admin-guide/LSM/Smack.rst
F: security/smack/
-DRIVERS FOR ADAPTIVE VOLTAGE SCALING (AVS)
-M: Kevin Hilman <khilman@kernel.org>
-M: Nishanth Menon <nm@ti.com>
-S: Maintained
-F: drivers/power/avs/
-F: include/linux/power/smartreflex.h
-L: linux-pm@vger.kernel.org
-
SMC91x ETHERNET DRIVER
M: Nicolas Pitre <nico@fluxnic.net>
S: Odd Fixes
@@ -12300,6 +12137,12 @@ S: Supported
F: Documentation/hwmon/sch5627
F: drivers/hwmon/sch5627.c
+SMSC UFX6000 and UFX7000 USB to VGA DRIVER
+M: Steve Glendinning <steve.glendinning@shawell.net>
+L: linux-fbdev@vger.kernel.org
+S: Maintained
+F: drivers/video/fbdev/smscufx.c
+
SMSC47B397 HARDWARE MONITOR DRIVER
M: Jean Delvare <jdelvare@suse.com>
L: linux-hwmon@vger.kernel.org
@@ -12320,12 +12163,6 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/smsc/smsc9420.*
-SMSC UFX6000 and UFX7000 USB to VGA DRIVER
-M: Steve Glendinning <steve.glendinning@shawell.net>
-L: linux-fbdev@vger.kernel.org
-S: Maintained
-F: drivers/video/fbdev/smscufx.c
-
SOC-CAMERA V4L2 SUBSYSTEM
M: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
L: linux-media@vger.kernel.org
@@ -12340,6 +12177,15 @@ M: Chris Boot <bootc@bootc.net>
S: Maintained
F: drivers/leds/leds-net48xx.c
+SOFT-ROCE DRIVER (rxe)
+M: Moni Shoua <monis@mellanox.com>
+L: linux-rdma@vger.kernel.org
+S: Supported
+W: https://github.com/SoftRoCE/rxe-dev/wiki/rxe-dev:-Home
+Q: http://patchwork.kernel.org/project/linux-rdma/list/
+F: drivers/infiniband/sw/rxe/
+F: include/uapi/rdma/rdma_user_rxe.h
+
SOFTLOGIC 6x10 MPEG CODEC
M: Bluecherry Maintainers <maintainers@bluecherrydvr.com>
M: Anton Sviridenko <anton@corp.bluecherry.net>
@@ -12372,16 +12218,6 @@ S: Maintained
F: drivers/ssb/
F: include/linux/ssb/
-SONY VAIO CONTROL DEVICE DRIVER
-M: Mattia Dongili <malattia@linux.it>
-L: platform-driver-x86@vger.kernel.org
-W: http://www.linux.it/~malattia/wiki/index.php/Sony_drivers
-S: Maintained
-F: Documentation/laptops/sony-laptop.txt
-F: drivers/char/sonypi.c
-F: drivers/platform/x86/sony-laptop.c
-F: include/linux/sony-laptop.h
-
SONY MEMORYSTICK CARD SUPPORT
M: Alex Dubov <oakad@yahoo.com>
W: http://tifmxx.berlios.de/
@@ -12393,6 +12229,16 @@ M: Maxim Levitsky <maximlevitsky@gmail.com>
S: Maintained
F: drivers/memstick/core/ms_block.*
+SONY VAIO CONTROL DEVICE DRIVER
+M: Mattia Dongili <malattia@linux.it>
+L: platform-driver-x86@vger.kernel.org
+W: http://www.linux.it/~malattia/wiki/index.php/Sony_drivers
+S: Maintained
+F: Documentation/laptops/sony-laptop.txt
+F: drivers/char/sonypi.c
+F: drivers/platform/x86/sony-laptop.c
+F: include/linux/sony-laptop.h
+
SOUND
M: Jaroslav Kysela <perex@perex.cz>
M: Takashi Iwai <tiwai@suse.com>
@@ -12418,6 +12264,13 @@ F: include/uapi/sound/compress_*
F: sound/core/compress_offload.c
F: sound/soc/soc-compress.c
+SOUND - DMAENGINE HELPERS
+M: Lars-Peter Clausen <lars@metafoo.de>
+S: Supported
+F: include/sound/dmaengine_pcm.h
+F: sound/core/pcm_dmaengine.c
+F: sound/soc/soc-generic-dmaengine-pcm.c
+
SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC)
M: Liam Girdwood <lgirdwood@gmail.com>
M: Mark Brown <broonie@kernel.org>
@@ -12430,13 +12283,6 @@ F: Documentation/sound/alsa/soc/
F: sound/soc/
F: include/sound/soc*
-SOUND - DMAENGINE HELPERS
-M: Lars-Peter Clausen <lars@metafoo.de>
-S: Supported
-F: include/sound/dmaengine_pcm.h
-F: sound/core/pcm_dmaengine.c
-F: sound/soc/soc-generic-dmaengine-pcm.c
-
SP2 MEDIA DRIVER
M: Olli Salonen <olli.salonen@iki.fi>
L: linux-media@vger.kernel.org
@@ -12479,21 +12325,21 @@ T: git git://git.kernel.org/pub/scm/devel/sparse/chrisl/sparse.git
S: Maintained
F: include/linux/compiler.h
-SPEAR PLATFORM SUPPORT
+SPEAR CLOCK FRAMEWORK SUPPORT
M: Viresh Kumar <vireshk@kernel.org>
-M: Shiraz Hashim <shiraz.linux.kernel@gmail.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
W: http://www.st.com/spear
S: Maintained
-F: arch/arm/boot/dts/spear*
-F: arch/arm/mach-spear/
+F: drivers/clk/spear/
-SPEAR CLOCK FRAMEWORK SUPPORT
+SPEAR PLATFORM SUPPORT
M: Viresh Kumar <vireshk@kernel.org>
+M: Shiraz Hashim <shiraz.linux.kernel@gmail.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
W: http://www.st.com/spear
S: Maintained
-F: drivers/clk/spear/
+F: arch/arm/boot/dts/spear*
+F: arch/arm/mach-spear/
SPI NOR SUBSYSTEM
M: Cyrille Pitchen <cyrille.pitchen@wedev4u.fr>
@@ -12527,6 +12373,15 @@ S: Supported
F: Documentation/networking/spider_net.txt
F: drivers/net/ethernet/toshiba/spider_net*
+SPMI SUBSYSTEM
+R: Stephen Boyd <sboyd@codeaurora.org>
+L: linux-arm-msm@vger.kernel.org
+F: Documentation/devicetree/bindings/spmi/
+F: drivers/spmi/
+F: include/dt-bindings/spmi/spmi.h
+F: include/linux/spmi.h
+F: include/trace/events/spmi.h
+
SPU FILE SYSTEM
M: Jeremy Kerr <jk@ozlabs.org>
L: linuxppc-dev@lists.ozlabs.org
@@ -12555,13 +12410,6 @@ L: stable@vger.kernel.org
S: Supported
F: Documentation/process/stable-kernel-rules.rst
-STAGING SUBSYSTEM
-M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
-L: devel@driverdev.osuosl.org
-S: Supported
-F: drivers/staging/
-
STAGING - COMEDI
M: Ian Abbott <abbotti@mev.co.uk>
M: H Hartley Sweeten <hsweeten@visionengravers.com>
@@ -12651,11 +12499,39 @@ M: Arnaud Patard <arnaud.patard@rtp-net.org>
S: Odd Fixes
F: drivers/staging/xgifb/
+STAGING SUBSYSTEM
+M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
+L: devel@driverdev.osuosl.org
+S: Supported
+F: drivers/staging/
+
STARFIRE/DURALAN NETWORK DRIVER
M: Ion Badulescu <ionut@badula.org>
S: Odd Fixes
F: drivers/net/ethernet/adaptec/starfire*
+STI CEC DRIVER
+M: Benjamin Gaignard <benjamin.gaignard@linaro.org>
+S: Maintained
+F: drivers/staging/media/st-cec/
+F: Documentation/devicetree/bindings/media/stih-cec.txt
+
+STK1160 USB VIDEO CAPTURE DRIVER
+M: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+L: linux-media@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: drivers/media/usb/stk1160/
+
+STMMAC ETHERNET DRIVER
+M: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+M: Alexandre Torgue <alexandre.torgue@st.com>
+L: netdev@vger.kernel.org
+W: http://www.stlinux.com
+S: Supported
+F: drivers/net/ethernet/stmicro/stmmac/
+
SUN3/3X
M: Sam Creasey <sammy@sammy.net>
W: http://sammy.net/sun3/
@@ -12727,6 +12603,20 @@ S: Supported
F: net/switchdev/
F: include/net/switchdev.h
+SYNC FILE FRAMEWORK
+M: Sumit Semwal <sumit.semwal@linaro.org>
+R: Gustavo Padovan <gustavo@padovan.org>
+S: Maintained
+L: linux-media@vger.kernel.org
+L: dri-devel@lists.freedesktop.org
+F: drivers/dma-buf/sync_*
+F: drivers/dma-buf/dma-fence*
+F: drivers/dma-buf/sw_sync.c
+F: include/linux/sync_file.h
+F: include/uapi/linux/sync_file.h
+F: Documentation/sync_file.txt
+T: git git://anongit.freedesktop.org/drm/drm-misc
+
SYNOPSYS ARC ARCHITECTURE
M: Vineet Gupta <vgupta@synopsys.com>
L: linux-snps-arc@lists.infradead.org
@@ -12745,6 +12635,35 @@ F: arch/arc/plat-axs10x
F: arch/arc/boot/dts/ax*
F: Documentation/devicetree/bindings/arc/axs10*
+SYNOPSYS DESIGNWARE DMAC DRIVER
+M: Viresh Kumar <vireshk@kernel.org>
+M: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+S: Maintained
+F: include/linux/dma/dw.h
+F: include/linux/platform_data/dma-dw.h
+F: drivers/dma/dw/
+
+SYNOPSYS DESIGNWARE ENTERPRISE ETHERNET DRIVER
+M: Jie Deng <jiedeng@synopsys.com>
+L: netdev@vger.kernel.org
+S: Supported
+F: drivers/net/ethernet/synopsys/
+
+SYNOPSYS DESIGNWARE I2C DRIVER
+M: Jarkko Nikula <jarkko.nikula@linux.intel.com>
+R: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+R: Mika Westerberg <mika.westerberg@linux.intel.com>
+L: linux-i2c@vger.kernel.org
+S: Maintained
+F: drivers/i2c/busses/i2c-designware-*
+F: include/linux/platform_data/i2c-designware.h
+
+SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER
+M: Jaehoon Chung <jh80.chung@samsung.com>
+L: linux-mmc@vger.kernel.org
+S: Maintained
+F: drivers/mmc/host/dw_mmc*
+
SYSTEM CONFIGURATION (SYSCON)
M: Lee Jones <lee.jones@linaro.org>
M: Arnd Bergmann <arnd@arndb.de>
@@ -12752,6 +12671,16 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git
S: Supported
F: drivers/mfd/syscon.c
+SYSTEM CONTROL & POWER INTERFACE (SCPI) Message Protocol drivers
+M: Sudeep Holla <sudeep.holla@arm.com>
+L: linux-arm-kernel@lists.infradead.org
+S: Maintained
+F: Documentation/devicetree/bindings/arm/arm,scpi.txt
+F: drivers/clk/clk-scpi.c
+F: drivers/cpufreq/scpi-cpufreq.c
+F: drivers/firmware/arm_scpi.c
+F: include/linux/scpi_protocol.h
+
SYSTEM RESET/SHUTDOWN DRIVERS
M: Sebastian Reichel <sre@kernel.org>
L: linux-pm@vger.kernel.org
@@ -12760,6 +12689,15 @@ S: Maintained
F: Documentation/devicetree/bindings/power/reset/
F: drivers/power/reset/
+SYSTEM TRACE MODULE CLASS
+M: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+S: Maintained
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/ash/stm.git
+F: Documentation/trace/stm.txt
+F: drivers/hwtracing/stm/
+F: include/linux/stm.h
+F: include/uapi/linux/stm.h
+
SYSV FILESYSTEM
M: Christoph Hellwig <hch@infradead.org>
S: Maintained
@@ -12929,6 +12867,14 @@ L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/rc/ttusbir.c
+TEE SUBSYSTEM
+M: Jens Wiklander <jens.wiklander@linaro.org>
+S: Maintained
+F: include/linux/tee_drv.h
+F: include/uapi/linux/tee.h
+F: drivers/tee/
+F: Documentation/tee.txt
+
TEGRA ARCHITECTURE SUPPORT
M: Thierry Reding <thierry.reding@gmail.com>
M: Jonathan Hunter <jonathanh@nvidia.com>
@@ -13060,6 +13006,23 @@ T: git git://repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git
S: Maintained
F: drivers/platform/x86/thinkpad_acpi.c
+THUNDERBOLT DRIVER
+M: Andreas Noever <andreas.noever@gmail.com>
+M: Michael Jamet <michael.jamet@intel.com>
+M: Mika Westerberg <mika.westerberg@linux.intel.com>
+M: Yehezkel Bernat <yehezkel.bernat@intel.com>
+S: Maintained
+F: drivers/thunderbolt/
+
+TI AM437X VPFE DRIVER
+M: "Lad, Prabhakar" <prabhakar.csengg@gmail.com>
+L: linux-media@vger.kernel.org
+W: https://linuxtv.org
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
+S: Maintained
+F: drivers/media/platform/am437x/
+
TI BANDGAP AND THERMAL DRIVER
M: Eduardo Valentin <edubezval@gmail.com>
M: Keerthy <j-keerthy@ti.com>
@@ -13068,13 +13031,11 @@ L: linux-omap@vger.kernel.org
S: Maintained
F: drivers/thermal/ti-soc-thermal/
-TI VPE/CAL DRIVERS
-M: Benoit Parrot <bparrot@ti.com>
-L: linux-media@vger.kernel.org
-W: http://linuxtv.org/
-Q: http://patchwork.linuxtv.org/project/linux-media/list/
-S: Maintained
-F: drivers/media/platform/ti-vpe/
+TI BQ27XXX POWER SUPPLY DRIVER
+R: Andrew F. Davis <afd@ti.com>
+F: include/linux/power/bq27xxx_battery.h
+F: drivers/power/supply/bq27xxx_battery.c
+F: drivers/power/supply/bq27xxx_battery_i2c.c
TI CDCE706 CLOCK DRIVER
M: Max Filippov <jcmvbkbc@gmail.com>
@@ -13088,6 +13049,33 @@ S: Maintained
F: drivers/clk/ti/
F: include/linux/clk/ti.h
+TI DAVINCI MACHINE SUPPORT
+M: Sekhar Nori <nsekhar@ti.com>
+M: Kevin Hilman <khilman@kernel.org>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci.git
+S: Supported
+F: arch/arm/mach-davinci/
+F: drivers/i2c/busses/i2c-davinci.c
+F: arch/arm/boot/dts/da850*
+
+TI DAVINCI SERIES GPIO DRIVER
+M: Keerthy <j-keerthy@ti.com>
+L: linux-gpio@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/gpio/gpio-davinci.txt
+F: drivers/gpio/gpio-davinci.c
+
+TI DAVINCI SERIES MEDIA DRIVER
+M: "Lad, Prabhakar" <prabhakar.csengg@gmail.com>
+L: linux-media@vger.kernel.org
+W: https://linuxtv.org
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
+S: Maintained
+F: drivers/media/platform/davinci/
+F: include/media/davinci/
+
TI ETHERNET SWITCH DRIVER (CPSW)
R: Grygorii Strashko <grygorii.strashko@ti.com>
L: linux-omap@vger.kernel.org
@@ -13111,7 +13099,6 @@ S: Maintained
F: drivers/soc/ti/*
T: git git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git
-
TI LM49xxx FAMILY ASoC CODEC DRIVERS
M: M R Swami Reddy <mr.swami.reddy@ti.com>
M: Vishwas A Deshpande <vishwas.a.deshpande@ti.com>
@@ -13156,12 +13143,28 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Odd Fixes
F: sound/soc/codecs/tas571x*
+TI TRF7970A NFC DRIVER
+M: Mark Greer <mgreer@animalcreek.com>
+L: linux-wireless@vger.kernel.org
+L: linux-nfc@lists.01.org (moderated for non-subscribers)
+S: Supported
+F: drivers/nfc/trf7970a.c
+F: Documentation/devicetree/bindings/net/nfc/trf7970a.txt
+
TI TWL4030 SERIES SOC CODEC DRIVER
M: Peter Ujfalusi <peter.ujfalusi@ti.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Maintained
F: sound/soc/codecs/twl4030*
+TI VPE/CAL DRIVERS
+M: Benoit Parrot <bparrot@ti.com>
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+S: Maintained
+F: drivers/media/platform/ti-vpe/
+
TI WILINK WIRELESS DRIVERS
L: linux-wireless@vger.kernel.org
W: http://wireless.kernel.org/en/users/Drivers/wl12xx
@@ -13171,16 +13174,6 @@ S: Orphan
F: drivers/net/wireless/ti/
F: include/linux/wl12xx.h
-TIPC NETWORK LAYER
-M: Jon Maloy <jon.maloy@ericsson.com>
-M: Ying Xue <ying.xue@windriver.com>
-L: netdev@vger.kernel.org (core kernel code)
-L: tipc-discussion@lists.sourceforge.net (user apps, general discussion)
-W: http://tipc.sourceforge.net/
-S: Maintained
-F: include/uapi/linux/tipc*.h
-F: net/tipc/
-
TILE ARCHITECTURE
M: Chris Metcalf <cmetcalf@mellanox.com>
W: http://www.mellanox.com/repository/solutions/tile-scm/
@@ -13196,6 +13189,34 @@ F: drivers/tty/serial/tilegx.c
F: drivers/usb/host/*-tilegx.c
F: include/linux/usb/tilegx.h
+TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER
+M: John Stultz <john.stultz@linaro.org>
+M: Thomas Gleixner <tglx@linutronix.de>
+R: Stephen Boyd <sboyd@codeaurora.org>
+L: linux-kernel@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core
+S: Supported
+F: include/linux/clocksource.h
+F: include/linux/time.h
+F: include/linux/timex.h
+F: include/uapi/linux/time.h
+F: include/uapi/linux/timex.h
+F: kernel/time/clocksource.c
+F: kernel/time/time*.c
+F: kernel/time/alarmtimer.c
+F: kernel/time/ntp.c
+F: tools/testing/selftests/timers/
+
+TIPC NETWORK LAYER
+M: Jon Maloy <jon.maloy@ericsson.com>
+M: Ying Xue <ying.xue@windriver.com>
+L: netdev@vger.kernel.org (core kernel code)
+L: tipc-discussion@lists.sourceforge.net (user apps, general discussion)
+W: http://tipc.sourceforge.net/
+S: Maintained
+F: include/uapi/linux/tipc*.h
+F: net/tipc/
+
TLAN NETWORK DRIVER
M: Samuel Chessman <chessman@tux.org>
L: tlan-devel@lists.sourceforge.net (subscribers-only)
@@ -13204,6 +13225,38 @@ S: Maintained
F: Documentation/networking/tlan.txt
F: drivers/net/ethernet/ti/tlan.*
+TM6000 VIDEO4LINUX DRIVER
+M: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+M: Mauro Carvalho Chehab <mchehab@kernel.org>
+L: linux-media@vger.kernel.org
+W: https://linuxtv.org
+T: git git://linuxtv.org/media_tree.git
+S: Odd fixes
+F: drivers/media/usb/tm6000/
+F: Documentation/media/v4l-drivers/tm6000*
+
+TMIO/SDHI MMC DRIVER
+M: Wolfram Sang <wsa+renesas@sang-engineering.com>
+L: linux-mmc@vger.kernel.org
+S: Supported
+F: drivers/mmc/host/tmio_mmc*
+F: drivers/mmc/host/renesas_sdhi*
+F: include/linux/mfd/tmio.h
+
+TMP401 HARDWARE MONITOR DRIVER
+M: Guenter Roeck <linux@roeck-us.net>
+L: linux-hwmon@vger.kernel.org
+S: Maintained
+F: Documentation/hwmon/tmp401
+F: drivers/hwmon/tmp401.c
+
+TMPFS (SHMEM FILESYSTEM)
+M: Hugh Dickins <hughd@google.com>
+L: linux-mm@kvack.org
+S: Maintained
+F: include/linux/shmem_fs.h
+F: mm/shmem.c
+
TOMOYO SECURITY MODULE
M: Kentaro Takeda <takedakn@nttdata.co.jp>
M: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
@@ -13240,12 +13293,6 @@ L: platform-driver-x86@vger.kernel.org
S: Maintained
F: drivers/platform/x86/toshiba_haps.c
-TOSHIBA WMI HOTKEYS DRIVER
-M: Azael Avalos <coproscefalo@gmail.com>
-L: platform-driver-x86@vger.kernel.org
-S: Maintained
-F: drivers/platform/x86/toshiba-wmi.c
-
TOSHIBA SMM DRIVER
M: Jonathan Buzzard <jonathan@buzzard.org.uk>
W: http://www.buzzard.org.uk/toshiba/
@@ -13261,62 +13308,11 @@ S: Maintained
F: drivers/media/i2c/tc358743*
F: include/media/i2c/tc358743.h
-TMIO/SDHI MMC DRIVER
-M: Wolfram Sang <wsa+renesas@sang-engineering.com>
-L: linux-mmc@vger.kernel.org
-S: Supported
-F: drivers/mmc/host/tmio_mmc*
-F: drivers/mmc/host/renesas_sdhi*
-F: include/linux/mfd/tmio.h
-
-TMP401 HARDWARE MONITOR DRIVER
-M: Guenter Roeck <linux@roeck-us.net>
-L: linux-hwmon@vger.kernel.org
-S: Maintained
-F: Documentation/hwmon/tmp401
-F: drivers/hwmon/tmp401.c
-
-TMPFS (SHMEM FILESYSTEM)
-M: Hugh Dickins <hughd@google.com>
-L: linux-mm@kvack.org
-S: Maintained
-F: include/linux/shmem_fs.h
-F: mm/shmem.c
-
-TM6000 VIDEO4LINUX DRIVER
-M: Mauro Carvalho Chehab <mchehab@s-opensource.com>
-M: Mauro Carvalho Chehab <mchehab@kernel.org>
-L: linux-media@vger.kernel.org
-W: https://linuxtv.org
-T: git git://linuxtv.org/media_tree.git
-S: Odd fixes
-F: drivers/media/usb/tm6000/
-F: Documentation/media/v4l-drivers/tm6000*
-
-TW5864 VIDEO4LINUX DRIVER
-M: Bluecherry Maintainers <maintainers@bluecherrydvr.com>
-M: Anton Sviridenko <anton@corp.bluecherry.net>
-M: Andrey Utkin <andrey.utkin@corp.bluecherry.net>
-M: Andrey Utkin <andrey_utkin@fastmail.com>
-L: linux-media@vger.kernel.org
-S: Supported
-F: drivers/media/pci/tw5864/
-
-TW68 VIDEO4LINUX DRIVER
-M: Hans Verkuil <hverkuil@xs4all.nl>
-L: linux-media@vger.kernel.org
-T: git git://linuxtv.org/media_tree.git
-W: https://linuxtv.org
-S: Odd Fixes
-F: drivers/media/pci/tw68/
-
-TW686X VIDEO4LINUX DRIVER
-M: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
-L: linux-media@vger.kernel.org
-T: git git://linuxtv.org/media_tree.git
-W: http://linuxtv.org
+TOSHIBA WMI HOTKEYS DRIVER
+M: Azael Avalos <coproscefalo@gmail.com>
+L: platform-driver-x86@vger.kernel.org
S: Maintained
-F: drivers/media/pci/tw686x/
+F: drivers/platform/x86/toshiba-wmi.c
TPM DEVICE DRIVER
M: Peter Huewe <peterhuewe@gmx.de>
@@ -13418,6 +13414,31 @@ S: Maintained
F: drivers/tc/
F: include/linux/tc.h
+TW5864 VIDEO4LINUX DRIVER
+M: Bluecherry Maintainers <maintainers@bluecherrydvr.com>
+M: Anton Sviridenko <anton@corp.bluecherry.net>
+M: Andrey Utkin <andrey.utkin@corp.bluecherry.net>
+M: Andrey Utkin <andrey_utkin@fastmail.com>
+L: linux-media@vger.kernel.org
+S: Supported
+F: drivers/media/pci/tw5864/
+
+TW68 VIDEO4LINUX DRIVER
+M: Hans Verkuil <hverkuil@xs4all.nl>
+L: linux-media@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+W: https://linuxtv.org
+S: Odd Fixes
+F: drivers/media/pci/tw68/
+
+TW686X VIDEO4LINUX DRIVER
+M: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+L: linux-media@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+W: http://linuxtv.org
+S: Maintained
+F: drivers/media/pci/tw686x/
+
UBI FILE SYSTEM (UBIFS)
M: Richard Weinberger <richard@nod.at>
M: Artem Bityutskiy <dedekind1@gmail.com>
@@ -13467,6 +13488,13 @@ S: Maintained
F: drivers/hid/uhid.c
F: include/uapi/linux/uhid.h
+ULPI BUS
+M: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+L: linux-usb@vger.kernel.org
+S: Maintained
+F: drivers/usb/common/ulpi.c
+F: include/linux/ulpi/
+
ULTRA-WIDEBAND (UWB) SUBSYSTEM:
L: linux-usb@vger.kernel.org
S: Orphan
@@ -13527,6 +13555,14 @@ F: drivers/mtd/ubi/
F: include/linux/mtd/ubi.h
F: include/uapi/mtd/ubi-user.h
+USB "USBNET" DRIVER FRAMEWORK
+M: Oliver Neukum <oneukum@suse.com>
+L: netdev@vger.kernel.org
+W: http://www.linux-usb.org/usbnet
+S: Maintained
+F: drivers/net/usb/usbnet.c
+F: include/linux/usb/usbnet.h
+
USB ACM DRIVER
M: Oliver Neukum <oneukum@suse.com>
L: linux-usb@vger.kernel.org
@@ -13750,14 +13786,6 @@ L: linux-usb@vger.kernel.org
S: Maintained
F: drivers/usb/host/uhci*
-USB "USBNET" DRIVER FRAMEWORK
-M: Oliver Neukum <oneukum@suse.com>
-L: netdev@vger.kernel.org
-W: http://www.linux-usb.org/usbnet
-S: Maintained
-F: drivers/net/usb/usbnet.c
-F: include/linux/usb/usbnet.h
-
USB VIDEO CLASS
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-uvc-devel@lists.sourceforge.net (subscribers-only)
@@ -13812,13 +13840,6 @@ S: Maintained
F: Documentation/media/v4l-drivers/zr364xx*
F: drivers/media/usb/zr364xx/
-ULPI BUS
-M: Heikki Krogerus <heikki.krogerus@linux.intel.com>
-L: linux-usb@vger.kernel.org
-S: Maintained
-F: drivers/usb/common/ulpi.c
-F: include/linux/ulpi/
-
USER-MODE LINUX (UML)
M: Jeff Dike <jdike@addtoit.com>
M: Richard Weinberger <richard@nod.at>
@@ -13912,6 +13933,37 @@ F: drivers/gpu/vga/vga_switcheroo.c
F: include/linux/vga_switcheroo.h
T: git git://anongit.freedesktop.org/drm/drm-misc
+VIA RHINE NETWORK DRIVER
+S: Orphan
+F: drivers/net/ethernet/via/via-rhine.c
+
+VIA SD/MMC CARD CONTROLLER DRIVER
+M: Bruce Chang <brucechang@via.com.tw>
+M: Harald Welte <HaraldWelte@viatech.com>
+S: Maintained
+F: drivers/mmc/host/via-sdmmc.c
+
+VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER
+M: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
+L: linux-fbdev@vger.kernel.org
+S: Maintained
+F: include/linux/via-core.h
+F: include/linux/via-gpio.h
+F: include/linux/via_i2c.h
+F: drivers/video/fbdev/via/
+
+VIA VELOCITY NETWORK DRIVER
+M: Francois Romieu <romieu@fr.zoreil.com>
+L: netdev@vger.kernel.org
+S: Maintained
+F: drivers/net/ethernet/via/via-velocity.*
+
+VIDEO MULTIPLEXER DRIVER
+M: Philipp Zabel <p.zabel@pengutronix.de>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: drivers/media/platform/video-mux.c
+
VIDEOBUF2 FRAMEWORK
M: Pawel Osciak <pawel@osciak.com>
M: Marek Szyprowski <m.szyprowski@samsung.com>
@@ -13921,11 +13973,20 @@ S: Maintained
F: drivers/media/v4l2-core/videobuf2-*
F: include/media/videobuf2-*
-VIDEO MULTIPLEXER DRIVER
-M: Philipp Zabel <p.zabel@pengutronix.de>
+VIMC VIRTUAL MEDIA CONTROLLER DRIVER
+M: Helen Koike <helen.koike@collabora.com>
L: linux-media@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+W: https://linuxtv.org
S: Maintained
-F: drivers/media/platform/video-mux.c
+F: drivers/media/platform/vimc/*
+
+VIRT LIB
+M: Alex Williamson <alex.williamson@redhat.com>
+M: Paolo Bonzini <pbonzini@redhat.com>
+L: kvm@vger.kernel.org
+S: Supported
+F: virt/lib/
VIRTIO AND VHOST VSOCK DRIVER
M: Stefan Hajnoczi <stefanha@redhat.com>
@@ -13943,12 +14004,6 @@ F: drivers/net/vsockmon.c
F: drivers/vhost/vsock.c
F: drivers/vhost/vsock.h
-VIRTUAL SERIO DEVICE DRIVER
-M: Stephen Chandler Paul <thatslyude@gmail.com>
-S: Maintained
-F: drivers/input/serio/userio.c
-F: include/uapi/linux/userio.h
-
VIRTIO CONSOLE DRIVER
M: Amit Shah <amit@kernel.org>
L: virtualization@lists.linux-foundation.org
@@ -13970,6 +14025,15 @@ F: drivers/block/virtio_blk.c
F: include/linux/virtio*.h
F: include/uapi/linux/virtio_*.h
F: drivers/crypto/virtio/
+F: mm/balloon_compaction.c
+
+VIRTIO CRYPTO DRIVER
+M: Gonglei <arei.gonglei@huawei.com>
+L: virtualization@lists.linux-foundation.org
+L: linux-crypto@vger.kernel.org
+S: Maintained
+F: drivers/crypto/virtio/
+F: include/uapi/linux/virtio_crypto.h
VIRTIO DRIVERS FOR S390
M: Cornelia Huck <cohuck@redhat.com>
@@ -14007,45 +14071,11 @@ S: Maintained
F: drivers/virtio/virtio_input.c
F: include/uapi/linux/virtio_input.h
-VIRTIO CRYPTO DRIVER
-M: Gonglei <arei.gonglei@huawei.com>
-L: virtualization@lists.linux-foundation.org
-L: linux-crypto@vger.kernel.org
-S: Maintained
-F: drivers/crypto/virtio/
-F: include/uapi/linux/virtio_crypto.h
-
-VIA RHINE NETWORK DRIVER
-S: Orphan
-F: drivers/net/ethernet/via/via-rhine.c
-
-VIA SD/MMC CARD CONTROLLER DRIVER
-M: Bruce Chang <brucechang@via.com.tw>
-M: Harald Welte <HaraldWelte@viatech.com>
-S: Maintained
-F: drivers/mmc/host/via-sdmmc.c
-
-VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER
-M: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
-L: linux-fbdev@vger.kernel.org
-S: Maintained
-F: include/linux/via-core.h
-F: include/linux/via-gpio.h
-F: include/linux/via_i2c.h
-F: drivers/video/fbdev/via/
-
-VIA VELOCITY NETWORK DRIVER
-M: Francois Romieu <romieu@fr.zoreil.com>
-L: netdev@vger.kernel.org
+VIRTUAL SERIO DEVICE DRIVER
+M: Stephen Chandler Paul <thatslyude@gmail.com>
S: Maintained
-F: drivers/net/ethernet/via/via-velocity.*
-
-VIRT LIB
-M: Alex Williamson <alex.williamson@redhat.com>
-M: Paolo Bonzini <pbonzini@redhat.com>
-L: kvm@vger.kernel.org
-S: Supported
-F: virt/lib/
+F: drivers/input/serio/userio.c
+F: include/uapi/linux/userio.h
VIVID VIRTUAL VIDEO DRIVER
M: Hans Verkuil <hverkuil@xs4all.nl>
@@ -14055,14 +14085,6 @@ W: https://linuxtv.org
S: Maintained
F: drivers/media/platform/vivid/*
-VIMC VIRTUAL MEDIA CONTROLLER DRIVER
-M: Helen Koike <helen.koike@collabora.com>
-L: linux-media@vger.kernel.org
-T: git git://linuxtv.org/media_tree.git
-W: https://linuxtv.org
-S: Maintained
-F: drivers/media/platform/vimc/*
-
VLYNQ BUS
M: Florian Fainelli <f.fainelli@gmail.com>
L: openwrt-devel@lists.openwrt.org (subscribers-only)
@@ -14082,12 +14104,6 @@ F: drivers/staging/vme/
F: drivers/vme/
F: include/linux/vme*
-VMWARE HYPERVISOR INTERFACE
-M: Alok Kataria <akataria@vmware.com>
-L: virtualization@lists.linux-foundation.org
-S: Supported
-F: arch/x86/kernel/cpu/vmware.c
-
VMWARE BALLOON DRIVER
M: Xavier Deguillard <xdeguillard@vmware.com>
M: Philip Moltmann <moltmann@vmware.com>
@@ -14096,6 +14112,27 @@ L: linux-kernel@vger.kernel.org
S: Maintained
F: drivers/misc/vmw_balloon.c
+VMWARE HYPERVISOR INTERFACE
+M: Alok Kataria <akataria@vmware.com>
+L: virtualization@lists.linux-foundation.org
+S: Supported
+F: arch/x86/kernel/cpu/vmware.c
+
+VMWARE PVRDMA DRIVER
+M: Adit Ranadive <aditr@vmware.com>
+M: VMware PV-Drivers <pv-drivers@vmware.com>
+L: linux-rdma@vger.kernel.org
+S: Maintained
+F: drivers/infiniband/hw/vmw_pvrdma/
+
+VMware PVSCSI driver
+M: Jim Gill <jgill@vmware.com>
+M: VMware PV-Drivers <pv-drivers@vmware.com>
+L: linux-scsi@vger.kernel.org
+S: Maintained
+F: drivers/scsi/vmw_pvscsi.c
+F: drivers/scsi/vmw_pvscsi.h
+
VMWARE VMMOUSE SUBDRIVER
M: "VMware Graphics" <linux-graphics-maintainer@vmware.com>
M: "VMware, Inc." <pv-drivers@vmware.com>
@@ -14111,21 +14148,6 @@ L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/vmxnet3/
-VMware PVSCSI driver
-M: Jim Gill <jgill@vmware.com>
-M: VMware PV-Drivers <pv-drivers@vmware.com>
-L: linux-scsi@vger.kernel.org
-S: Maintained
-F: drivers/scsi/vmw_pvscsi.c
-F: drivers/scsi/vmw_pvscsi.h
-
-VMWARE PVRDMA DRIVER
-M: Adit Ranadive <aditr@vmware.com>
-M: VMware PV-Drivers <pv-drivers@vmware.com>
-L: linux-rdma@vger.kernel.org
-S: Maintained
-F: drivers/infiniband/hw/vmw_pvrdma/
-
VOLTAGE AND CURRENT REGULATOR FRAMEWORK
M: Liam Girdwood <lgirdwood@gmail.com>
M: Mark Brown <broonie@kernel.org>
@@ -14218,12 +14240,39 @@ F: drivers/watchdog/
F: include/linux/watchdog.h
F: include/uapi/linux/watchdog.h
+WHISKEYCOVE PMIC GPIO DRIVER
+M: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+L: linux-gpio@vger.kernel.org
+S: Maintained
+F: drivers/gpio/gpio-wcove.c
+
WIIMOTE HID DRIVER
M: David Herrmann <dh.herrmann@googlemail.com>
L: linux-input@vger.kernel.org
S: Maintained
F: drivers/hid/hid-wiimote*
+WILOCITY WIL6210 WIRELESS DRIVER
+M: Maya Erez <qca_merez@qca.qualcomm.com>
+L: linux-wireless@vger.kernel.org
+L: wil6210@qca.qualcomm.com
+S: Supported
+W: http://wireless.kernel.org/en/users/Drivers/wil6210
+F: drivers/net/wireless/ath/wil6210/
+F: include/uapi/linux/wil6210_uapi.h
+
+WIMAX STACK
+M: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+M: linux-wimax@intel.com
+L: wimax@linuxwimax.org (subscribers-only)
+S: Supported
+W: http://linuxwimax.org
+F: Documentation/wimax/README.wimax
+F: include/linux/wimax/debug.h
+F: include/net/wimax.h
+F: include/uapi/linux/wimax.h
+F: net/wimax/
+
WINBOND CIR DRIVER
M: David Härdeman <david@hardeman.nu>
S: Maintained
@@ -14241,18 +14290,6 @@ L: linux-gpio@vger.kernel.org
S: Maintained
F: drivers/gpio/gpio-ws16c48.c
-WIMAX STACK
-M: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
-M: linux-wimax@intel.com
-L: wimax@linuxwimax.org (subscribers-only)
-S: Supported
-W: http://linuxwimax.org
-F: Documentation/wimax/README.wimax
-F: include/linux/wimax/debug.h
-F: include/net/wimax.h
-F: include/uapi/linux/wimax.h
-F: net/wimax/
-
WISTRON LAPTOP BUTTON DRIVER
M: Miloslav Trmac <mitr@volny.cz>
S: Maintained
@@ -14337,15 +14374,6 @@ S: Maintained
F: Documentation/x86/
F: arch/x86/
-X86 PLATFORM DRIVERS
-M: Darren Hart <dvhart@infradead.org>
-M: Andy Shevchenko <andy@infradead.org>
-L: platform-driver-x86@vger.kernel.org
-T: git git://git.infradead.org/users/dvhart/linux-platform-drivers-x86.git
-S: Maintained
-F: drivers/platform/x86/
-F: drivers/platform/olpc/
-
X86 MCE INFRASTRUCTURE
M: Tony Luck <tony.luck@intel.com>
M: Borislav Petkov <bp@alien8.de>
@@ -14358,6 +14386,15 @@ M: Borislav Petkov <bp@alien8.de>
S: Maintained
F: arch/x86/kernel/cpu/microcode/*
+X86 PLATFORM DRIVERS
+M: Darren Hart <dvhart@infradead.org>
+M: Andy Shevchenko <andy@infradead.org>
+L: platform-driver-x86@vger.kernel.org
+T: git git://git.infradead.org/users/dvhart/linux-platform-drivers-x86.git
+S: Maintained
+F: drivers/platform/x86/
+F: drivers/platform/olpc/
+
X86 VDSO
M: Andy Lutomirski <luto@amacapital.net>
L: linux-kernel@vger.kernel.org
@@ -14374,20 +14411,13 @@ T: git git://linuxtv.org/media_tree.git
S: Maintained
F: drivers/media/tuners/tuner-xc2028.*
-XEN HYPERVISOR INTERFACE
-M: Boris Ostrovsky <boris.ostrovsky@oracle.com>
-M: Juergen Gross <jgross@suse.com>
+XEN BLOCK SUBSYSTEM
+M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+M: Roger Pau Monné <roger.pau@citrix.com>
L: xen-devel@lists.xenproject.org (moderated for non-subscribers)
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip.git
S: Supported
-F: arch/x86/xen/
-F: drivers/*/xen-*front.c
-F: drivers/xen/
-F: arch/x86/include/asm/xen/
-F: include/xen/
-F: include/uapi/xen/
-F: Documentation/ABI/stable/sysfs-hypervisor-xen
-F: Documentation/ABI/testing/sysfs-hypervisor-xen
+F: drivers/block/xen-blkback/*
+F: drivers/block/xen*
XEN HYPERVISOR ARM
M: Stefano Stabellini <sstabellini@kernel.org>
@@ -14403,6 +14433,21 @@ S: Maintained
F: arch/arm64/xen/
F: arch/arm64/include/asm/xen/
+XEN HYPERVISOR INTERFACE
+M: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+M: Juergen Gross <jgross@suse.com>
+L: xen-devel@lists.xenproject.org (moderated for non-subscribers)
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip.git
+S: Supported
+F: arch/x86/xen/
+F: drivers/*/xen-*front.c
+F: drivers/xen/
+F: arch/x86/include/asm/xen/
+F: include/xen/
+F: include/uapi/xen/
+F: Documentation/ABI/stable/sysfs-hypervisor-xen
+F: Documentation/ABI/testing/sysfs-hypervisor-xen
+
XEN NETWORK BACKEND DRIVER
M: Wei Liu <wei.liu2@citrix.com>
M: Paul Durrant <paul.durrant@citrix.com>
@@ -14418,14 +14463,6 @@ S: Supported
F: arch/x86/pci/*xen*
F: drivers/pci/*xen*
-XEN BLOCK SUBSYSTEM
-M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-M: Roger Pau Monné <roger.pau@citrix.com>
-L: xen-devel@lists.xenproject.org (moderated for non-subscribers)
-S: Supported
-F: drivers/block/xen-blkback/*
-F: drivers/block/xen*
-
XEN PVSCSI DRIVERS
M: Juergen Gross <jgross@suse.com>
L: xen-devel@lists.xenproject.org (moderated for non-subscribers)
@@ -14502,6 +14539,13 @@ S: Maintained
F: drivers/net/hamradio/yam*
F: include/linux/yam.h
+YAMA SECURITY MODULE
+M: Kees Cook <keescook@chromium.org>
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git yama/tip
+S: Supported
+F: security/yama/
+F: Documentation/admin-guide/LSM/Yama.rst
+
YEALINK PHONE DRIVER
M: Henk Vergonet <Henk.Vergonet@gmail.com>
L: usbb2k-api-dev@nongnu.org
@@ -14536,23 +14580,23 @@ L: zd1211-devs@lists.sourceforge.net (subscribers-only)
S: Maintained
F: drivers/net/wireless/zydas/zd1211rw/
-ZD1301_DEMOD MEDIA DRIVER
+ZD1301 MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
W: https://linuxtv.org/
W: http://palosaari.fi/linux/
Q: https://patchwork.linuxtv.org/project/linux-media/list/
S: Maintained
-F: drivers/media/dvb-frontends/zd1301_demod*
+F: drivers/media/usb/dvb-usb-v2/zd1301*
-ZD1301 MEDIA DRIVER
+ZD1301_DEMOD MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
W: https://linuxtv.org/
W: http://palosaari.fi/linux/
Q: https://patchwork.linuxtv.org/project/linux-media/list/
S: Maintained
-F: drivers/media/usb/dvb-usb-v2/zd1301*
+F: drivers/media/dvb-frontends/zd1301_demod*
ZPOOL COMPRESSED PAGE STORAGE API
M: Dan Streetman <ddstreet@ieee.org>
diff --git a/Makefile b/Makefile
index b4fb9a1d1594..90da7bdc3f45 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 4
PATCHLEVEL = 13
SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc5
NAME = Fearless Coyote
# *DOCUMENTATION*
diff --git a/arch/alpha/include/uapi/asm/ioctls.h b/arch/alpha/include/uapi/asm/ioctls.h
index ff67b8373bf7..1cd7dc7d4870 100644
--- a/arch/alpha/include/uapi/asm/ioctls.h
+++ b/arch/alpha/include/uapi/asm/ioctls.h
@@ -100,7 +100,7 @@
#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
-#define TIOCGPTPEER _IOR('T', 0x41, int) /* Safely open the slave */
+#define TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */
#define TIOCSERCONFIG 0x5453
#define TIOCSERGWILD 0x5454
diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index 2a07e6ecafbd..71d3efff99d3 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -117,7 +117,7 @@ static int arc_dma_mmap(struct device *dev, struct vm_area_struct *vma,
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
+ if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
return ret;
if (off < count && user_count <= (count - off)) {
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a208bfe367b5..61a0cb15067e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -380,7 +380,7 @@ config ARCH_EP93XX
bool "EP93xx-based"
select ARCH_HAS_HOLES_MEMORYMODEL
select ARM_AMBA
- select ARM_PATCH_PHYS_VIRT
+ imply ARM_PATCH_PHYS_VIRT
select ARM_VIC
select AUTO_ZRELADDR
select CLKDEV_LOOKUP
diff --git a/arch/arm/boot/dts/armada-388-gp.dts b/arch/arm/boot/dts/armada-388-gp.dts
index 895fa6cfa15a..563901e0ec07 100644
--- a/arch/arm/boot/dts/armada-388-gp.dts
+++ b/arch/arm/boot/dts/armada-388-gp.dts
@@ -75,7 +75,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pca0_pins>;
interrupt-parent = <&gpio0>;
- interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+ interrupts = <18 IRQ_TYPE_LEVEL_LOW>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -87,7 +87,7 @@
compatible = "nxp,pca9555";
pinctrl-names = "default";
interrupt-parent = <&gpio0>;
- interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+ interrupts = <18 IRQ_TYPE_LEVEL_LOW>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts
index a423e8ebfb37..67e72bc72e80 100644
--- a/arch/arm/boot/dts/da850-evm.dts
+++ b/arch/arm/boot/dts/da850-evm.dts
@@ -301,25 +301,4 @@
pinctrl-names = "default";
pinctrl-0 = <&vpif_capture_pins>, <&vpif_display_pins>;
status = "okay";
-
- /* VPIF capture port */
- port@0 {
- vpif_input_ch0: endpoint@0 {
- reg = <0>;
- bus-width = <8>;
- };
-
- vpif_input_ch1: endpoint@1 {
- reg = <1>;
- bus-width = <8>;
- data-shift = <8>;
- };
- };
-
- /* VPIF display port */
- port@1 {
- vpif_output_ch0: endpoint {
- bus-width = <8>;
- };
- };
};
diff --git a/arch/arm/boot/dts/da850-lcdk.dts b/arch/arm/boot/dts/da850-lcdk.dts
index b837fec70eec..a0f0916156e6 100644
--- a/arch/arm/boot/dts/da850-lcdk.dts
+++ b/arch/arm/boot/dts/da850-lcdk.dts
@@ -318,11 +318,4 @@
pinctrl-names = "default";
pinctrl-0 = <&vpif_capture_pins>;
status = "okay";
-
- /* VPIF capture port */
- port {
- vpif_ch0: endpoint {
- bus-width = <8>;
- };
- };
};
diff --git a/arch/arm/boot/dts/dm8168-evm.dts b/arch/arm/boot/dts/dm8168-evm.dts
index 1865976db5f9..c72a2132aa82 100644
--- a/arch/arm/boot/dts/dm8168-evm.dts
+++ b/arch/arm/boot/dts/dm8168-evm.dts
@@ -68,6 +68,34 @@
DM816X_IOPAD(0x0d08, MUX_MODE0) /* USB1_DRVVBUS */
>;
};
+
+ nandflash_pins: nandflash_pins {
+ pinctrl-single,pins = <
+ DM816X_IOPAD(0x0b38, PULL_UP | MUX_MODE0) /* PINCTRL207 GPMC_CS0*/
+ DM816X_IOPAD(0x0b60, PULL_ENA | MUX_MODE0) /* PINCTRL217 GPMC_ADV_ALE */
+ DM816X_IOPAD(0x0b54, PULL_UP | PULL_ENA | MUX_MODE0) /* PINCTRL214 GPMC_OE_RE */
+ DM816X_IOPAD(0x0b58, PULL_ENA | MUX_MODE0) /* PINCTRL215 GPMC_BE0_CLE */
+ DM816X_IOPAD(0x0b50, PULL_UP | MUX_MODE0) /* PINCTRL213 GPMC_WE */
+ DM816X_IOPAD(0x0b6c, MUX_MODE0) /* PINCTRL220 GPMC_WAIT */
+ DM816X_IOPAD(0x0be4, PULL_ENA | MUX_MODE0) /* PINCTRL250 GPMC_CLK */
+ DM816X_IOPAD(0x0ba4, MUX_MODE0) /* PINCTRL234 GPMC_D0 */
+ DM816X_IOPAD(0x0ba8, MUX_MODE0) /* PINCTRL234 GPMC_D1 */
+ DM816X_IOPAD(0x0bac, MUX_MODE0) /* PINCTRL234 GPMC_D2 */
+ DM816X_IOPAD(0x0bb0, MUX_MODE0) /* PINCTRL234 GPMC_D3 */
+ DM816X_IOPAD(0x0bb4, MUX_MODE0) /* PINCTRL234 GPMC_D4 */
+ DM816X_IOPAD(0x0bb8, MUX_MODE0) /* PINCTRL234 GPMC_D5 */
+ DM816X_IOPAD(0x0bbc, MUX_MODE0) /* PINCTRL234 GPMC_D6 */
+ DM816X_IOPAD(0x0bc0, MUX_MODE0) /* PINCTRL234 GPMC_D7 */
+ DM816X_IOPAD(0x0bc4, MUX_MODE0) /* PINCTRL234 GPMC_D8 */
+ DM816X_IOPAD(0x0bc8, MUX_MODE0) /* PINCTRL234 GPMC_D9 */
+ DM816X_IOPAD(0x0bcc, MUX_MODE0) /* PINCTRL234 GPMC_D10 */
+ DM816X_IOPAD(0x0bd0, MUX_MODE0) /* PINCTRL234 GPMC_D11 */
+ DM816X_IOPAD(0x0bd4, MUX_MODE0) /* PINCTRL234 GPMC_D12 */
+ DM816X_IOPAD(0x0bd8, MUX_MODE0) /* PINCTRL234 GPMC_D13 */
+ DM816X_IOPAD(0x0bdc, MUX_MODE0) /* PINCTRL234 GPMC_D14 */
+ DM816X_IOPAD(0x0be0, MUX_MODE0) /* PINCTRL234 GPMC_D15 */
+ >;
+ };
};
&i2c1 {
@@ -90,6 +118,8 @@
&gpmc {
ranges = <0 0 0x04000000 0x01000000>; /* CS0: 16MB for NAND */
+ pinctrl-names = "default";
+ pinctrl-0 = <&nandflash_pins>;
nand@0,0 {
compatible = "ti,omap2-nand";
@@ -98,9 +128,11 @@
interrupt-parent = <&gpmc>;
interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
<1 IRQ_TYPE_NONE>; /* termcount */
+ rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
#address-cells = <1>;
#size-cells = <1>;
ti,nand-ecc-opt = "bch8";
+ ti,elm-id = <&elm>;
nand-bus-width = <16>;
gpmc,device-width = <2>;
gpmc,sync-clk-ps = <0>;
@@ -164,7 +196,7 @@
vmmc-supply = <&vmmcsd_fixed>;
bus-width = <4>;
cd-gpios = <&gpio2 7 GPIO_ACTIVE_LOW>;
- wp-gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>;
};
/* At least dm8168-evm rev c won't support multipoint, later may */
diff --git a/arch/arm/boot/dts/dm816x.dtsi b/arch/arm/boot/dts/dm816x.dtsi
index 59cbf958fcc3..566b2a8c8b96 100644
--- a/arch/arm/boot/dts/dm816x.dtsi
+++ b/arch/arm/boot/dts/dm816x.dtsi
@@ -145,7 +145,7 @@
};
elm: elm@48080000 {
- compatible = "ti,816-elm";
+ compatible = "ti,am3352-elm";
ti,hwmods = "elm";
reg = <0x48080000 0x2000>;
interrupts = <4>;
diff --git a/arch/arm/boot/dts/dra71-evm.dts b/arch/arm/boot/dts/dra71-evm.dts
index 4d57a55473af..a6298eb56978 100644
--- a/arch/arm/boot/dts/dra71-evm.dts
+++ b/arch/arm/boot/dts/dra71-evm.dts
@@ -190,7 +190,7 @@
ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
ti,tx-internal-delay = <DP83867_RGMIIDCTL_250_PS>;
ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>;
- ti,impedance-control = <0x1f>;
+ ti,min-output-impedance;
};
dp83867_1: ethernet-phy@3 {
@@ -198,7 +198,7 @@
ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
ti,tx-internal-delay = <DP83867_RGMIIDCTL_250_PS>;
ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>;
- ti,impedance-control = <0x1f>;
+ ti,min-output-impedance;
};
};
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 497a9470c888..5739389f5bb8 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -59,6 +59,9 @@
compatible = "samsung,exynos4210-audss-clock";
reg = <0x03810000 0x0C>;
#clock-cells = <1>;
+ clocks = <&clock CLK_FIN_PLL>, <&clock CLK_FOUT_EPLL>,
+ <&clock CLK_SCLK_AUDIO0>, <&clock CLK_SCLK_AUDIO0>;
+ clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in";
};
i2s0: i2s@03830000 {
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 2484f11761ea..858e1fed762a 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -1126,8 +1126,8 @@
};
};
- gpu: mali@ffa30000 {
- compatible = "rockchip,rk3288-mali", "arm,mali-t760", "arm,mali-midgard";
+ gpu: gpu@ffa30000 {
+ compatible = "rockchip,rk3288-mali", "arm,mali-t760";
reg = <0xffa30000 0x10000>;
interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 8923ba625b76..19a8f4fcfab5 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -44,7 +44,9 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/sun8i-a83t-ccu.h>
#include <dt-bindings/clock/sun8i-r-ccu.h>
+#include <dt-bindings/reset/sun8i-a83t-ccu.h>
/ {
interrupt-parent = <&gic>;
@@ -175,8 +177,8 @@
compatible = "allwinner,sun8i-a83t-dma";
reg = <0x01c02000 0x1000>;
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&ccu 21>;
- resets = <&ccu 7>;
+ clocks = <&ccu CLK_BUS_DMA>;
+ resets = <&ccu RST_BUS_DMA>;
#dma-cells = <1>;
};
@@ -195,7 +197,7 @@
<GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x01c20800 0x400>;
- clocks = <&ccu 45>, <&osc24M>, <&osc16Md512>;
+ clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc16Md512>;
clock-names = "apb", "hosc", "losc";
gpio-controller;
interrupt-controller;
@@ -247,8 +249,8 @@
"allwinner,sun8i-h3-spdif";
reg = <0x01c21000 0x400>;
interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&ccu 44>, <&ccu 76>;
- resets = <&ccu 32>;
+ clocks = <&ccu CLK_BUS_SPDIF>, <&ccu CLK_SPDIF>;
+ resets = <&ccu RST_BUS_SPDIF>;
clock-names = "apb", "spdif";
dmas = <&dma 2>;
dma-names = "tx";
@@ -263,8 +265,8 @@
interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
- clocks = <&ccu 53>;
- resets = <&ccu 40>;
+ clocks = <&ccu CLK_BUS_UART0>;
+ resets = <&ccu RST_BUS_UART0>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 6f2162608006..d38282b9e5d4 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -394,7 +394,7 @@
emac: ethernet@1c30000 {
compatible = "allwinner,sun8i-h3-emac";
syscon = <&syscon>;
- reg = <0x01c30000 0x104>;
+ reg = <0x01c30000 0x10000>;
interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";
resets = <&ccu RST_BUS_EMAC>;
diff --git a/arch/arm/boot/dts/tango4-vantage-1172.dts b/arch/arm/boot/dts/tango4-vantage-1172.dts
index 86d8df98802f..13bcc460bcb2 100644
--- a/arch/arm/boot/dts/tango4-vantage-1172.dts
+++ b/arch/arm/boot/dts/tango4-vantage-1172.dts
@@ -22,7 +22,7 @@
};
&eth0 {
- phy-connection-type = "rgmii";
+ phy-connection-type = "rgmii-id";
phy-handle = <&eth0_phy>;
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h
index 4e6e88a6b2f4..2244a94ed9c9 100644
--- a/arch/arm/include/asm/bug.h
+++ b/arch/arm/include/asm/bug.h
@@ -37,7 +37,7 @@ do { \
".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \
"2:\t.asciz " #__file "\n" \
".popsection\n" \
- ".pushsection __bug_table,\"a\"\n" \
+ ".pushsection __bug_table,\"aw\"\n" \
".align 2\n" \
"3:\t.word 1b, 2b\n" \
"\t.hword " #__line ", 0\n" \
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index d69bebf697e7..74504b154256 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -116,7 +116,7 @@ struct cpu_cache_fns {
void (*dma_unmap_area)(const void *, size_t, int);
void (*dma_flush_range)(const void *, const void *);
-};
+} __no_randomize_layout;
/*
* Select the calling method
diff --git a/arch/arm/include/asm/kexec.h b/arch/arm/include/asm/kexec.h
index 1869af6bac5c..25021b798a1e 100644
--- a/arch/arm/include/asm/kexec.h
+++ b/arch/arm/include/asm/kexec.h
@@ -19,6 +19,11 @@
#ifndef __ASSEMBLY__
+#define ARCH_HAS_KIMAGE_ARCH
+struct kimage_arch {
+ u32 kernel_r2;
+};
+
/**
* crash_setup_regs() - save registers for the panic kernel
* @newregs: registers are saved here
diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h
index 3f2eb76243e3..d5562f9ce600 100644
--- a/arch/arm/include/asm/tlb.h
+++ b/arch/arm/include/asm/tlb.h
@@ -148,7 +148,8 @@ static inline void tlb_flush_mmu(struct mmu_gather *tlb)
}
static inline void
-tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
+arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
+ unsigned long start, unsigned long end)
{
tlb->mm = mm;
tlb->fullmm = !(start | (end+1));
@@ -166,8 +167,14 @@ tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start
}
static inline void
-tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
+arch_tlb_finish_mmu(struct mmu_gather *tlb,
+ unsigned long start, unsigned long end, bool force)
{
+ if (force) {
+ tlb->range_start = start;
+ tlb->range_end = end;
+ }
+
tlb_flush_mmu(tlb);
/* keep the page table cache within bounds */
diff --git a/arch/arm/include/asm/ucontext.h b/arch/arm/include/asm/ucontext.h
index 14749aec94bf..921d8274855c 100644
--- a/arch/arm/include/asm/ucontext.h
+++ b/arch/arm/include/asm/ucontext.h
@@ -35,6 +35,12 @@ struct ucontext {
* bytes, to prevent unpredictable padding in the signal frame.
*/
+/*
+ * Dummy padding block: if this magic is encountered, the block should
+ * be skipped using the corresponding size field.
+ */
+#define DUMMY_MAGIC 0xb0d9ed01
+
#ifdef CONFIG_CRUNCH
#define CRUNCH_MAGIC 0x5065cf03
#define CRUNCH_STORAGE_SIZE (CRUNCH_SIZE + 8)
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 15495887ca14..fe1419eeb932 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -30,7 +30,6 @@ extern unsigned long kexec_boot_atags;
static atomic_t waiting_for_crash_ipi;
-static unsigned long dt_mem;
/*
* Provide a dummy crash_notes definition while crash dump arrives to arm.
* This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
@@ -42,6 +41,9 @@ int machine_kexec_prepare(struct kimage *image)
__be32 header;
int i, err;
+ image->arch.kernel_r2 = image->start - KEXEC_ARM_ZIMAGE_OFFSET
+ + KEXEC_ARM_ATAGS_OFFSET;
+
/*
* Validate that if the current HW supports SMP, then the SW supports
* and implements CPU hotplug for the current HW. If not, we won't be
@@ -66,8 +68,8 @@ int machine_kexec_prepare(struct kimage *image)
if (err)
return err;
- if (be32_to_cpu(header) == OF_DT_HEADER)
- dt_mem = current_segment->mem;
+ if (header == cpu_to_be32(OF_DT_HEADER))
+ image->arch.kernel_r2 = current_segment->mem;
}
return 0;
}
@@ -165,8 +167,7 @@ void machine_kexec(struct kimage *image)
kexec_start_address = image->start;
kexec_indirection_page = page_list;
kexec_mach_type = machine_arch_type;
- kexec_boot_atags = dt_mem ?: image->start - KEXEC_ARM_ZIMAGE_OFFSET
- + KEXEC_ARM_ATAGS_OFFSET;
+ kexec_boot_atags = image->arch.kernel_r2;
/* copy our kernel relocation code to the control code page */
reboot_entry = fncpy(reboot_code_buffer,
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 4e80bf7420d4..8e9a3e40d949 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -987,6 +987,9 @@ static void __init reserve_crashkernel(void)
if (crash_base <= 0) {
unsigned long long crash_max = idmap_to_phys((u32)~0);
+ unsigned long long lowmem_max = __pa(high_memory - 1) + 1;
+ if (crash_max > lowmem_max)
+ crash_max = lowmem_max;
crash_base = memblock_find_in_range(CRASH_ALIGN, crash_max,
crash_size, CRASH_ALIGN);
if (!crash_base) {
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 7b8f2141427b..5814298ef0b7 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -40,8 +40,10 @@ static int preserve_crunch_context(struct crunch_sigframe __user *frame)
return __copy_to_user(frame, kframe, sizeof(*frame));
}
-static int restore_crunch_context(struct crunch_sigframe __user *frame)
+static int restore_crunch_context(char __user **auxp)
{
+ struct crunch_sigframe __user *frame =
+ (struct crunch_sigframe __user *)*auxp;
char kbuf[sizeof(*frame) + 8];
struct crunch_sigframe *kframe;
@@ -52,6 +54,7 @@ static int restore_crunch_context(struct crunch_sigframe __user *frame)
if (kframe->magic != CRUNCH_MAGIC ||
kframe->size != CRUNCH_STORAGE_SIZE)
return -1;
+ *auxp += CRUNCH_STORAGE_SIZE;
crunch_task_restore(current_thread_info(), &kframe->storage);
return 0;
}
@@ -59,21 +62,39 @@ static int restore_crunch_context(struct crunch_sigframe __user *frame)
#ifdef CONFIG_IWMMXT
-static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame)
+static int preserve_iwmmxt_context(struct iwmmxt_sigframe __user *frame)
{
char kbuf[sizeof(*frame) + 8];
struct iwmmxt_sigframe *kframe;
+ int err = 0;
/* the iWMMXt context must be 64 bit aligned */
kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
- kframe->magic = IWMMXT_MAGIC;
- kframe->size = IWMMXT_STORAGE_SIZE;
- iwmmxt_task_copy(current_thread_info(), &kframe->storage);
- return __copy_to_user(frame, kframe, sizeof(*frame));
+
+ if (test_thread_flag(TIF_USING_IWMMXT)) {
+ kframe->magic = IWMMXT_MAGIC;
+ kframe->size = IWMMXT_STORAGE_SIZE;
+ iwmmxt_task_copy(current_thread_info(), &kframe->storage);
+
+ err = __copy_to_user(frame, kframe, sizeof(*frame));
+ } else {
+ /*
+ * For bug-compatibility with older kernels, some space
+ * has to be reserved for iWMMXt even if it's not used.
+ * Set the magic and size appropriately so that properly
+ * written userspace can skip it reliably:
+ */
+ __put_user_error(DUMMY_MAGIC, &frame->magic, err);
+ __put_user_error(IWMMXT_STORAGE_SIZE, &frame->size, err);
+ }
+
+ return err;
}
-static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
+static int restore_iwmmxt_context(char __user **auxp)
{
+ struct iwmmxt_sigframe __user *frame =
+ (struct iwmmxt_sigframe __user *)*auxp;
char kbuf[sizeof(*frame) + 8];
struct iwmmxt_sigframe *kframe;
@@ -81,10 +102,28 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
if (__copy_from_user(kframe, frame, sizeof(*frame)))
return -1;
- if (kframe->magic != IWMMXT_MAGIC ||
- kframe->size != IWMMXT_STORAGE_SIZE)
+
+ /*
+ * For non-iWMMXt threads: a single iwmmxt_sigframe-sized dummy
+ * block is discarded for compatibility with setup_sigframe() if
+ * present, but we don't mandate its presence. If some other
+ * magic is here, it's not for us:
+ */
+ if (!test_thread_flag(TIF_USING_IWMMXT) &&
+ kframe->magic != DUMMY_MAGIC)
+ return 0;
+
+ if (kframe->size != IWMMXT_STORAGE_SIZE)
return -1;
- iwmmxt_task_restore(current_thread_info(), &kframe->storage);
+
+ if (test_thread_flag(TIF_USING_IWMMXT)) {
+ if (kframe->magic != IWMMXT_MAGIC)
+ return -1;
+
+ iwmmxt_task_restore(current_thread_info(), &kframe->storage);
+ }
+
+ *auxp += IWMMXT_STORAGE_SIZE;
return 0;
}
@@ -107,8 +146,10 @@ static int preserve_vfp_context(struct vfp_sigframe __user *frame)
return vfp_preserve_user_clear_hwstate(&frame->ufp, &frame->ufp_exc);
}
-static int restore_vfp_context(struct vfp_sigframe __user *frame)
+static int restore_vfp_context(char __user **auxp)
{
+ struct vfp_sigframe __user *frame =
+ (struct vfp_sigframe __user *)*auxp;
unsigned long magic;
unsigned long size;
int err = 0;
@@ -121,6 +162,7 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame)
if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
return -EINVAL;
+ *auxp += size;
return vfp_restore_user_hwstate(&frame->ufp, &frame->ufp_exc);
}
@@ -141,7 +183,7 @@ struct rt_sigframe {
static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
{
- struct aux_sigframe __user *aux;
+ char __user *aux;
sigset_t set;
int err;
@@ -169,18 +211,18 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
err |= !valid_user_regs(regs);
- aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;
+ aux = (char __user *) sf->uc.uc_regspace;
#ifdef CONFIG_CRUNCH
if (err == 0)
- err |= restore_crunch_context(&aux->crunch);
+ err |= restore_crunch_context(&aux);
#endif
#ifdef CONFIG_IWMMXT
- if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))
- err |= restore_iwmmxt_context(&aux->iwmmxt);
+ if (err == 0)
+ err |= restore_iwmmxt_context(&aux);
#endif
#ifdef CONFIG_VFP
if (err == 0)
- err |= restore_vfp_context(&aux->vfp);
+ err |= restore_vfp_context(&aux);
#endif
return err;
@@ -286,7 +328,7 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
err |= preserve_crunch_context(&aux->crunch);
#endif
#ifdef CONFIG_IWMMXT
- if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))
+ if (err == 0)
err |= preserve_iwmmxt_context(&aux->iwmmxt);
#endif
#ifdef CONFIG_VFP
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index b5625d009288..e568c8c6f69c 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -1166,7 +1166,7 @@ static struct tvp514x_platform_data tvp5146_pdata = {
#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
-static const struct vpif_input da850_ch0_inputs[] = {
+static struct vpif_input da850_ch0_inputs[] = {
{
.input = {
.index = 0,
@@ -1181,7 +1181,7 @@ static const struct vpif_input da850_ch0_inputs[] = {
},
};
-static const struct vpif_input da850_ch1_inputs[] = {
+static struct vpif_input da850_ch1_inputs[] = {
{
.input = {
.index = 0,
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index f5dce9b4e617..f77a4f766050 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -218,6 +218,15 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
}
EXPORT_SYMBOL(clk_set_parent);
+struct clk *clk_get_parent(struct clk *clk)
+{
+ if (!clk)
+ return NULL;
+
+ return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
int clk_register(struct clk *clk)
{
if (clk == NULL || IS_ERR(clk))
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index 39ef3b613912..beec5f16443a 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -475,6 +475,26 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
}
EXPORT_SYMBOL(clk_set_rate);
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ WARN_ON(clk);
+ return 0;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ WARN_ON(clk);
+ return 0;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+ return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
diff --git a/arch/arm/mach-ixp4xx/include/mach/io.h b/arch/arm/mach-ixp4xx/include/mach/io.h
index 7a0c13bf4269..844e8ac593e2 100644
--- a/arch/arm/mach-ixp4xx/include/mach/io.h
+++ b/arch/arm/mach-ixp4xx/include/mach/io.h
@@ -95,8 +95,10 @@ static inline void __indirect_writeb(u8 value, volatile void __iomem *p)
}
static inline void __indirect_writesb(volatile void __iomem *bus_addr,
- const u8 *vaddr, int count)
+ const void *p, int count)
{
+ const u8 *vaddr = p;
+
while (count--)
writeb(*vaddr++, bus_addr);
}
@@ -118,8 +120,10 @@ static inline void __indirect_writew(u16 value, volatile void __iomem *p)
}
static inline void __indirect_writesw(volatile void __iomem *bus_addr,
- const u16 *vaddr, int count)
+ const void *p, int count)
{
+ const u16 *vaddr = p;
+
while (count--)
writew(*vaddr++, bus_addr);
}
@@ -137,8 +141,9 @@ static inline void __indirect_writel(u32 value, volatile void __iomem *p)
}
static inline void __indirect_writesl(volatile void __iomem *bus_addr,
- const u32 *vaddr, int count)
+ const void *p, int count)
{
+ const u32 *vaddr = p;
while (count--)
writel(*vaddr++, bus_addr);
}
@@ -160,8 +165,10 @@ static inline u8 __indirect_readb(const volatile void __iomem *p)
}
static inline void __indirect_readsb(const volatile void __iomem *bus_addr,
- u8 *vaddr, u32 count)
+ void *p, u32 count)
{
+ u8 *vaddr = p;
+
while (count--)
*vaddr++ = readb(bus_addr);
}
@@ -183,8 +190,10 @@ static inline u16 __indirect_readw(const volatile void __iomem *p)
}
static inline void __indirect_readsw(const volatile void __iomem *bus_addr,
- u16 *vaddr, u32 count)
+ void *p, u32 count)
{
+ u16 *vaddr = p;
+
while (count--)
*vaddr++ = readw(bus_addr);
}
@@ -204,8 +213,10 @@ static inline u32 __indirect_readl(const volatile void __iomem *p)
}
static inline void __indirect_readsl(const volatile void __iomem *bus_addr,
- u32 *vaddr, u32 count)
+ void *p, u32 count)
{
+ u32 *vaddr = p;
+
while (count--)
*vaddr++ = readl(bus_addr);
}
@@ -523,8 +534,15 @@ static inline void iowrite32_rep(void __iomem *addr, const void *vaddr,
#endif
}
-#define ioport_map(port, nr) ((void __iomem*)(port + PIO_OFFSET))
-#define ioport_unmap(addr)
+#define ioport_map(port, nr) ioport_map(port, nr)
+static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+ return ((void __iomem*)((port) + PIO_OFFSET));
+}
+#define ioport_unmap(addr) ioport_unmap(addr)
+static inline void ioport_unmap(void __iomem *addr)
+{
+}
#endif /* CONFIG_PCI */
#endif /* __ASM_ARM_ARCH_IO_H */
diff --git a/arch/arm/mach-mmp/devices.c b/arch/arm/mach-mmp/devices.c
index 3330ac7cfbef..671c7a09ab3d 100644
--- a/arch/arm/mach-mmp/devices.c
+++ b/arch/arm/mach-mmp/devices.c
@@ -238,7 +238,7 @@ void pxa_usb_phy_deinit(void __iomem *phy_reg)
#endif
#if IS_ENABLED(CONFIG_USB_SUPPORT)
-static u64 usb_dma_mask = ~(u32)0;
+static u64 __maybe_unused usb_dma_mask = ~(u32)0;
#if IS_ENABLED(CONFIG_USB_MV_UDC)
struct resource pxa168_u2o_resources[] = {
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
index e62273aacb43..4ffbbd217e82 100644
--- a/arch/arm/mach-mvebu/platsmp.c
+++ b/arch/arm/mach-mvebu/platsmp.c
@@ -211,7 +211,7 @@ static int mv98dx3236_resume_set_cpu_boot_addr(int hw_cpu, void *boot_addr)
return PTR_ERR(base);
writel(0, base + MV98DX3236_CPU_RESUME_CTRL_REG);
- writel(virt_to_phys(boot_addr), base + MV98DX3236_CPU_RESUME_ADDR_REG);
+ writel(__pa_symbol(boot_addr), base + MV98DX3236_CPU_RESUME_ADDR_REG);
iounmap(base);
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index 6613a6ff5dbc..6cbc69c92913 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -510,6 +510,7 @@ static void __init ams_delta_init(void)
static void modem_pm(struct uart_port *port, unsigned int state, unsigned old)
{
struct modem_private_data *priv = port->private_data;
+ int ret;
if (IS_ERR(priv->regulator))
return;
@@ -518,9 +519,16 @@ static void modem_pm(struct uart_port *port, unsigned int state, unsigned old)
return;
if (state == 0)
- regulator_enable(priv->regulator);
+ ret = regulator_enable(priv->regulator);
else if (old == 0)
- regulator_disable(priv->regulator);
+ ret = regulator_disable(priv->regulator);
+ else
+ ret = 0;
+
+ if (ret)
+ dev_warn(port->dev,
+ "ams_delta modem_pm: failed to %sable regulator: %d\n",
+ state ? "dis" : "en", ret);
}
static struct plat_serial8250_port ams_delta_modem_ports[] = {
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 4dfb99504810..95ac1929aede 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -441,13 +441,11 @@ static struct spi_board_info __initdata mistral_boardinfo[] = { {
.chip_select = 0,
} };
-#ifdef CONFIG_PM
static irqreturn_t
osk_mistral_wake_interrupt(int irq, void *ignored)
{
return IRQ_HANDLED;
}
-#endif
static void __init osk_mistral_init(void)
{
@@ -515,7 +513,6 @@ static void __init osk_mistral_init(void)
gpio_direction_input(OMAP_MPUIO(2));
irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
-#ifdef CONFIG_PM
/* share the IRQ in case someone wants to use the
* button for more than wakeup from system sleep.
*/
@@ -529,7 +526,6 @@ static void __init osk_mistral_init(void)
ret);
} else
enable_irq_wake(irq);
-#endif
} else
printk(KERN_ERR "OSK+Mistral: wakeup button is awol\n");
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 779fb1f680b3..b3b3b3a19183 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -8,7 +8,7 @@ ccflags-y := -I$(srctree)/$(src)/include \
# Common support
obj-y := id.o io.o control.o devices.o fb.o timer.o pm.o \
common.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \
- omap_device.o omap-headsmp.o sram.o drm.o
+ omap_device.o omap-headsmp.o sram.o
hwmod-common = omap_hwmod.o omap_hwmod_reset.o \
omap_hwmod_common_data.o
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index dc9e34e670a2..583fc39d84cd 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -28,11 +28,12 @@ static const struct of_device_id omap_dt_match_table[] __initconst = {
{ }
};
-static void __init omap_generic_init(void)
+static void __init __maybe_unused omap_generic_init(void)
{
pdata_quirks_init(omap_dt_match_table);
omapdss_init_of();
+ omap_soc_device_init();
}
#ifdef CONFIG_SOC_OMAP2420
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 8fa01c0ecdb2..b3f6eb5d04a2 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -66,6 +66,7 @@
*/
#define FRAMEDONE_IRQ_TIMEOUT 100
+#if defined(CONFIG_FB_OMAP2)
static struct platform_device omap_display_device = {
.name = "omapdss",
.id = -1,
@@ -163,6 +164,65 @@ static enum omapdss_version __init omap_display_get_version(void)
return OMAPDSS_VER_UNKNOWN;
}
+static int __init omapdss_init_fbdev(void)
+{
+ static struct omap_dss_board_info board_data = {
+ .dsi_enable_pads = omap_dsi_enable_pads,
+ .dsi_disable_pads = omap_dsi_disable_pads,
+ .set_min_bus_tput = omap_dss_set_min_bus_tput,
+ };
+ struct device_node *node;
+ int r;
+
+ board_data.version = omap_display_get_version();
+ if (board_data.version == OMAPDSS_VER_UNKNOWN) {
+ pr_err("DSS not supported on this SoC\n");
+ return -ENODEV;
+ }
+
+ omap_display_device.dev.platform_data = &board_data;
+
+ r = platform_device_register(&omap_display_device);
+ if (r < 0) {
+ pr_err("Unable to register omapdss device\n");
+ return r;
+ }
+
+ /* create vrfb device */
+ r = omap_init_vrfb();
+ if (r < 0) {
+ pr_err("Unable to register omapvrfb device\n");
+ return r;
+ }
+
+ /* create FB device */
+ r = omap_init_fb();
+ if (r < 0) {
+ pr_err("Unable to register omapfb device\n");
+ return r;
+ }
+
+ /* create V4L2 display device */
+ r = omap_init_vout();
+ if (r < 0) {
+ pr_err("Unable to register omap_vout device\n");
+ return r;
+ }
+
+ /* add DSI info for omap4 */
+ node = of_find_node_by_name(NULL, "omap4_padconf_global");
+ if (node)
+ omap4_dsi_mux_syscon = syscon_node_to_regmap(node);
+
+ return 0;
+}
+#else
+static inline int omapdss_init_fbdev(void)
+{
+ return 0;
+}
+#endif /* CONFIG_FB_OMAP2 */
+
static void dispc_disable_outputs(void)
{
u32 v, irq_mask = 0;
@@ -335,16 +395,9 @@ static struct device_node * __init omapdss_find_dss_of_node(void)
int __init omapdss_init_of(void)
{
int r;
- enum omapdss_version ver;
struct device_node *node;
struct platform_device *pdev;
- static struct omap_dss_board_info board_data = {
- .dsi_enable_pads = omap_dsi_enable_pads,
- .dsi_disable_pads = omap_dsi_disable_pads,
- .set_min_bus_tput = omap_dss_set_min_bus_tput,
- };
-
/* only create dss helper devices if dss is enabled in the .dts */
node = omapdss_find_dss_of_node();
@@ -354,13 +407,6 @@ int __init omapdss_init_of(void)
if (!of_device_is_available(node))
return 0;
- ver = omap_display_get_version();
-
- if (ver == OMAPDSS_VER_UNKNOWN) {
- pr_err("DSS not supported on this SoC\n");
- return -ENODEV;
- }
-
pdev = of_find_device_by_node(node);
if (!pdev) {
@@ -374,48 +420,5 @@ int __init omapdss_init_of(void)
return r;
}
- board_data.version = ver;
-
- omap_display_device.dev.platform_data = &board_data;
-
- r = platform_device_register(&omap_display_device);
- if (r < 0) {
- pr_err("Unable to register omapdss device\n");
- return r;
- }
-
- /* create DRM device */
- r = omap_init_drm();
- if (r < 0) {
- pr_err("Unable to register omapdrm device\n");
- return r;
- }
-
- /* create vrfb device */
- r = omap_init_vrfb();
- if (r < 0) {
- pr_err("Unable to register omapvrfb device\n");
- return r;
- }
-
- /* create FB device */
- r = omap_init_fb();
- if (r < 0) {
- pr_err("Unable to register omapfb device\n");
- return r;
- }
-
- /* create V4L2 display device */
- r = omap_init_vout();
- if (r < 0) {
- pr_err("Unable to register omap_vout device\n");
- return r;
- }
-
- /* add DSI info for omap4 */
- node = of_find_node_by_name(NULL, "omap4_padconf_global");
- if (node)
- omap4_dsi_mux_syscon = syscon_node_to_regmap(node);
-
- return 0;
+ return omapdss_init_fbdev();
}
diff --git a/arch/arm/mach-omap2/display.h b/arch/arm/mach-omap2/display.h
index 9a39646d4316..42ec2e99a2f4 100644
--- a/arch/arm/mach-omap2/display.h
+++ b/arch/arm/mach-omap2/display.h
@@ -26,7 +26,6 @@ struct omap_dss_dispc_dev_attr {
bool has_framedonetv_irq;
};
-int omap_init_drm(void);
int omap_init_vrfb(void);
int omap_init_fb(void);
int omap_init_vout(void);
diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c
deleted file mode 100644
index 44fef961bb70..000000000000
--- a/arch/arm/mach-omap2/drm.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * DRM/KMS device registration for TI OMAP platforms
- *
- * Copyright (C) 2012 Texas Instruments
- * Author: Rob Clark <rob.clark@linaro.org>
- *
- * 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.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_data/omap_drm.h>
-
-#include "soc.h"
-#include "display.h"
-
-#if IS_ENABLED(CONFIG_DRM_OMAP)
-
-static struct omap_drm_platform_data platform_data;
-
-static struct platform_device omap_drm_device = {
- .dev = {
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &platform_data,
- },
- .name = "omapdrm",
- .id = 0,
-};
-
-int __init omap_init_drm(void)
-{
- platform_data.omaprev = GET_OMAP_TYPE;
-
- return platform_device_register(&omap_drm_device);
-
-}
-#else
-int __init omap_init_drm(void) { return 0; }
-#endif
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index be517b048762..5b614388d72f 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -32,120 +32,6 @@ static u16 control_devconf1_offset;
#define HSMMC_NAME_LEN 9
-static void omap_hsmmc1_before_set_reg(struct device *dev,
- int power_on, int vdd)
-{
- u32 reg, prog_io;
- struct omap_hsmmc_platform_data *mmc = dev->platform_data;
-
- if (mmc->remux)
- mmc->remux(dev, power_on);
-
- /*
- * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
- * card with Vcc regulator (from twl4030 or whatever). OMAP has both
- * 1.8V and 3.0V modes, controlled by the PBIAS register.
- *
- * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which
- * is most naturally TWL VSIM; those pins also use PBIAS.
- *
- * FIXME handle VMMC1A as needed ...
- */
- if (power_on) {
- if (cpu_is_omap2430()) {
- reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1);
- if ((1 << vdd) >= MMC_VDD_30_31)
- reg |= OMAP243X_MMC1_ACTIVE_OVERWRITE;
- else
- reg &= ~OMAP243X_MMC1_ACTIVE_OVERWRITE;
- omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1);
- }
-
- if (mmc->internal_clock) {
- reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
- reg |= OMAP2_MMCSDIO1ADPCLKISEL;
- omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0);
- }
-
- reg = omap_ctrl_readl(control_pbias_offset);
- if (cpu_is_omap3630()) {
- /* Set MMC I/O to 52MHz */
- prog_io = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO1);
- prog_io |= OMAP3630_PRG_SDMMC1_SPEEDCTRL;
- omap_ctrl_writel(prog_io, OMAP343X_CONTROL_PROG_IO1);
- } else {
- reg |= OMAP2_PBIASSPEEDCTRL0;
- }
- reg &= ~OMAP2_PBIASLITEPWRDNZ0;
- omap_ctrl_writel(reg, control_pbias_offset);
- } else {
- reg = omap_ctrl_readl(control_pbias_offset);
- reg &= ~OMAP2_PBIASLITEPWRDNZ0;
- omap_ctrl_writel(reg, control_pbias_offset);
- }
-}
-
-static void omap_hsmmc1_after_set_reg(struct device *dev, int power_on, int vdd)
-{
- u32 reg;
-
- /* 100ms delay required for PBIAS configuration */
- msleep(100);
-
- if (power_on) {
- reg = omap_ctrl_readl(control_pbias_offset);
- reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0);
- if ((1 << vdd) <= MMC_VDD_165_195)
- reg &= ~OMAP2_PBIASLITEVMODE0;
- else
- reg |= OMAP2_PBIASLITEVMODE0;
- omap_ctrl_writel(reg, control_pbias_offset);
- } else {
- reg = omap_ctrl_readl(control_pbias_offset);
- reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 |
- OMAP2_PBIASLITEVMODE0);
- omap_ctrl_writel(reg, control_pbias_offset);
- }
-}
-
-static void hsmmc2_select_input_clk_src(struct omap_hsmmc_platform_data *mmc)
-{
- u32 reg;
-
- reg = omap_ctrl_readl(control_devconf1_offset);
- if (mmc->internal_clock)
- reg |= OMAP2_MMCSDIO2ADPCLKISEL;
- else
- reg &= ~OMAP2_MMCSDIO2ADPCLKISEL;
- omap_ctrl_writel(reg, control_devconf1_offset);
-}
-
-static void hsmmc2_before_set_reg(struct device *dev, int power_on, int vdd)
-{
- struct omap_hsmmc_platform_data *mmc = dev->platform_data;
-
- if (mmc->remux)
- mmc->remux(dev, power_on);
-
- if (power_on)
- hsmmc2_select_input_clk_src(mmc);
-}
-
-static int am35x_hsmmc2_set_power(struct device *dev, int power_on, int vdd)
-{
- struct omap_hsmmc_platform_data *mmc = dev->platform_data;
-
- if (power_on)
- hsmmc2_select_input_clk_src(mmc);
-
- return 0;
-}
-
-static int nop_mmc_set_power(struct device *dev, int power_on, int vdd)
-{
- return 0;
-}
-
static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
struct omap_hsmmc_platform_data *mmc)
{
@@ -157,101 +43,11 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
return -ENOMEM;
}
- if (c->name)
- strncpy(hc_name, c->name, HSMMC_NAME_LEN);
- else
- snprintf(hc_name, (HSMMC_NAME_LEN + 1), "mmc%islot%i",
- c->mmc, 1);
+ snprintf(hc_name, (HSMMC_NAME_LEN + 1), "mmc%islot%i", c->mmc, 1);
mmc->name = hc_name;
mmc->caps = c->caps;
- mmc->internal_clock = !c->ext_clock;
mmc->reg_offset = 0;
- if (c->cover_only) {
- /* detect if mobile phone cover removed */
- mmc->gpio_cd = -EINVAL;
- mmc->gpio_cod = c->gpio_cd;
- } else {
- /* card detect pin on the mmc socket itself */
- mmc->gpio_cd = c->gpio_cd;
- mmc->gpio_cod = -EINVAL;
- }
- mmc->gpio_wp = c->gpio_wp;
-
- mmc->remux = c->remux;
- mmc->init_card = c->init_card;
-
- if (c->nonremovable)
- mmc->nonremovable = 1;
-
- /*
- * NOTE: MMC slots should have a Vcc regulator set up.
- * This may be from a TWL4030-family chip, another
- * controllable regulator, or a fixed supply.
- *
- * temporary HACK: ocr_mask instead of fixed supply
- */
- if (soc_is_am35xx())
- mmc->ocr_mask = MMC_VDD_165_195 |
- MMC_VDD_26_27 |
- MMC_VDD_27_28 |
- MMC_VDD_29_30 |
- MMC_VDD_30_31 |
- MMC_VDD_31_32;
- else
- mmc->ocr_mask = c->ocr_mask;
-
- if (!soc_is_am35xx())
- mmc->features |= HSMMC_HAS_PBIAS;
-
- switch (c->mmc) {
- case 1:
- if (mmc->features & HSMMC_HAS_PBIAS) {
- /* on-chip level shifting via PBIAS0/PBIAS1 */
- mmc->before_set_reg =
- omap_hsmmc1_before_set_reg;
- mmc->after_set_reg =
- omap_hsmmc1_after_set_reg;
- }
-
- if (soc_is_am35xx())
- mmc->set_power = nop_mmc_set_power;
-
- /* OMAP3630 HSMMC1 supports only 4-bit */
- if (cpu_is_omap3630() &&
- (c->caps & MMC_CAP_8_BIT_DATA)) {
- c->caps &= ~MMC_CAP_8_BIT_DATA;
- c->caps |= MMC_CAP_4_BIT_DATA;
- mmc->caps = c->caps;
- }
- break;
- case 2:
- if (soc_is_am35xx())
- mmc->set_power = am35x_hsmmc2_set_power;
-
- if (c->ext_clock)
- c->transceiver = 1;
- if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) {
- c->caps &= ~MMC_CAP_8_BIT_DATA;
- c->caps |= MMC_CAP_4_BIT_DATA;
- }
- if (mmc->features & HSMMC_HAS_PBIAS) {
- /* off-chip level shifting, or none */
- mmc->before_set_reg = hsmmc2_before_set_reg;
- mmc->after_set_reg = NULL;
- }
- break;
- case 3:
- case 4:
- case 5:
- mmc->before_set_reg = NULL;
- mmc->after_set_reg = NULL;
- break;
- default:
- pr_err("MMC%d configuration not supported!\n", c->mmc);
- kfree(hc_name);
- return -ENODEV;
- }
return 0;
}
@@ -260,7 +56,6 @@ static int omap_hsmmc_done;
void omap_hsmmc_late_init(struct omap2_hsmmc_info *c)
{
struct platform_device *pdev;
- struct omap_hsmmc_platform_data *mmc_pdata;
int res;
if (omap_hsmmc_done != 1)
@@ -269,32 +64,12 @@ void omap_hsmmc_late_init(struct omap2_hsmmc_info *c)
omap_hsmmc_done++;
for (; c->mmc; c++) {
- if (!c->deferred)
- continue;
-
pdev = c->pdev;
if (!pdev)
continue;
-
- mmc_pdata = pdev->dev.platform_data;
- if (!mmc_pdata)
- continue;
-
- if (c->cover_only) {
- /* detect if mobile phone cover removed */
- mmc_pdata->gpio_cd = -EINVAL;
- mmc_pdata->gpio_cod = c->gpio_cd;
- } else {
- /* card detect pin on the mmc socket itself */
- mmc_pdata->gpio_cd = c->gpio_cd;
- mmc_pdata->gpio_cod = -EINVAL;
- }
- mmc_pdata->gpio_wp = c->gpio_wp;
-
res = omap_device_register(pdev);
if (res)
- pr_err("Could not late init MMC %s\n",
- c->name);
+ pr_err("Could not late init MMC\n");
}
}
@@ -336,13 +111,6 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,
if (oh->dev_attr != NULL) {
mmc_dev_attr = oh->dev_attr;
mmc_data->controller_flags = mmc_dev_attr->flags;
- /*
- * erratum 2.1.1.128 doesn't apply if board has
- * a transceiver is attached
- */
- if (hsmmcinfo->transceiver)
- mmc_data->controller_flags &=
- ~OMAP_HSMMC_BROKEN_MULTIBLOCK_READ;
}
pdev = platform_device_alloc(name, ctrl_nr - 1);
@@ -367,9 +135,6 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,
hsmmcinfo->pdev = pdev;
- if (hsmmcinfo->deferred)
- goto free_mmc;
-
res = omap_device_register(pdev);
if (res) {
pr_err("Could not register od for %s\n", name);
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index 69b619ddc765..af9af5094ec3 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -12,18 +12,9 @@ struct omap2_hsmmc_info {
u8 mmc; /* controller 1/2/3 */
u32 caps; /* 4/8 wires and any additional host
* capabilities OR'd (ref. linux/mmc/host.h) */
- bool transceiver; /* MMC-2 option */
- bool ext_clock; /* use external pin for input clock */
- bool cover_only; /* No card detect - just cover switch */
- bool nonremovable; /* Nonremovable e.g. eMMC */
- bool deferred; /* mmc needs a deferred probe */
int gpio_cd; /* or -EINVAL */
int gpio_wp; /* or -EINVAL */
- char *name; /* or NULL for default */
struct platform_device *pdev; /* mmc controller instance */
- int ocr_mask; /* temporary HACK */
- /* Remux (pad configuration) when powering on/off */
- void (*remux)(struct device *dev, int power_on);
/* init some special card */
void (*init_card)(struct mmc_card *card);
};
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 1d739d1a0a65..cb5d7314cf99 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -410,7 +410,7 @@ static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data)
return omap_hwmod_set_postsetup_state(oh, *(u8 *)data);
}
-static void __init omap_hwmod_init_postsetup(void)
+static void __init __maybe_unused omap_hwmod_init_postsetup(void)
{
u8 postsetup_state;
@@ -428,7 +428,6 @@ static void __init omap_hwmod_init_postsetup(void)
static void __init __maybe_unused omap_common_late_init(void)
{
omap2_common_pm_late_init();
- omap_soc_device_init();
}
#ifdef CONFIG_SOC_OMAP2420
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index d44e0e2f1106..841ba19d64a6 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -486,7 +486,6 @@ int __init omap3_pm_init(void)
ret = request_irq(omap_prcm_event_to_irq("io"),
_prcm_int_handle_io, IRQF_SHARED | IRQF_NO_SUSPEND, "pm_io",
omap3_pm_init);
- enable_irq(omap_prcm_event_to_irq("io"));
if (ret) {
pr_err("pm: Failed to request pm_io irq\n");
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c
index 382e236fbfd9..64f6451499a7 100644
--- a/arch/arm/mach-omap2/prm3xxx.c
+++ b/arch/arm/mach-omap2/prm3xxx.c
@@ -692,7 +692,6 @@ static int omap3xxx_prm_late_init(void)
{
struct device_node *np;
int irq_num;
- int ret;
if (!(prm_features & PRM_HAS_IO_WAKEUP))
return 0;
@@ -712,12 +711,8 @@ static int omap3xxx_prm_late_init(void)
}
omap3xxx_prm_enable_io_wakeup();
- ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
- if (!ret)
- irq_set_status_flags(omap_prcm_event_to_irq("io"),
- IRQ_NOAUTOEN);
- return ret;
+ return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
}
static void __exit omap3xxx_prm_exit(void)
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index 87e86a4a9ead..3ab5df1ce900 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -337,6 +337,27 @@ static void omap44xx_prm_reconfigure_io_chain(void)
}
/**
+ * omap44xx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
+ *
+ * Activates the I/O wakeup event latches and allows events logged by
+ * those latches to signal a wakeup event to the PRCM. For I/O wakeups
+ * to occur, WAKEUPENABLE bits must be set in the pad mux registers, and
+ * omap44xx_prm_reconfigure_io_chain() must be called. No return value.
+ */
+static void __init omap44xx_prm_enable_io_wakeup(void)
+{
+ s32 inst = omap4_prmst_get_prm_dev_inst();
+
+ if (inst == PRM_INSTANCE_UNKNOWN)
+ return;
+
+ omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK,
+ OMAP4430_GLOBAL_WUEN_MASK,
+ inst,
+ omap4_prcm_irq_setup.pm_ctrl);
+}
+
+/**
* omap44xx_prm_read_reset_sources - return the last SoC reset source
*
* Return a u32 representing the last reset sources of the SoC. The
@@ -668,6 +689,8 @@ struct pwrdm_ops omap4_pwrdm_operations = {
.pwrdm_has_voltdm = omap4_check_vcvp,
};
+static int omap44xx_prm_late_init(void);
+
/*
* XXX document
*/
@@ -675,6 +698,7 @@ static struct prm_ll_data omap44xx_prm_ll_data = {
.read_reset_sources = &omap44xx_prm_read_reset_sources,
.was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old,
.clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old,
+ .late_init = &omap44xx_prm_late_init,
.assert_hardreset = omap4_prminst_assert_hardreset,
.deassert_hardreset = omap4_prminst_deassert_hardreset,
.is_hardreset_asserted = omap4_prminst_is_hardreset_asserted,
@@ -711,6 +735,37 @@ int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
return prm_register(&omap44xx_prm_ll_data);
}
+static int omap44xx_prm_late_init(void)
+{
+ int irq_num;
+
+ if (!(prm_features & PRM_HAS_IO_WAKEUP))
+ return 0;
+
+ irq_num = of_irq_get(prm_init_data->np, 0);
+ /*
+ * Already have OMAP4 IRQ num. For all other platforms, we need
+ * IRQ numbers from DT
+ */
+ if (irq_num < 0 && !(prm_init_data->flags & PRM_IRQ_DEFAULT)) {
+ if (irq_num == -EPROBE_DEFER)
+ return irq_num;
+
+ /* Have nothing to do */
+ return 0;
+ }
+
+ /* Once OMAP4 DT is filled as well */
+ if (irq_num >= 0) {
+ omap4_prcm_irq_setup.irq = irq_num;
+ omap4_prcm_irq_setup.xlate_irq = NULL;
+ }
+
+ omap44xx_prm_enable_io_wakeup();
+
+ return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
+}
+
static void __exit omap44xx_prm_exit(void)
{
prm_unregister(&omap44xx_prm_ll_data);
diff --git a/arch/arm/mach-prima2/common.c b/arch/arm/mach-prima2/common.c
index 8cadb302a7d2..ffe05c27087e 100644
--- a/arch/arm/mach-prima2/common.c
+++ b/arch/arm/mach-prima2/common.c
@@ -15,7 +15,7 @@
#include <linux/of_platform.h>
#include "common.h"
-static void __init sirfsoc_init_late(void)
+static void __init __maybe_unused sirfsoc_init_late(void)
{
sirfsoc_pm_init();
}
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 76fbc115ec33..ce7d97babb0f 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -566,6 +566,7 @@ config MACH_ICONTROL
config ARCH_PXA_ESERIES
bool "PXA based Toshiba e-series PDAs"
select FB_W100
+ select FB
select PXA25x
config MACH_E330
diff --git a/arch/arm/mach-pxa/include/mach/mtd-xip.h b/arch/arm/mach-pxa/include/mach/mtd-xip.h
index 990d2bf2fb45..9bf4ea6a6f74 100644
--- a/arch/arm/mach-pxa/include/mach/mtd-xip.h
+++ b/arch/arm/mach-pxa/include/mach/mtd-xip.h
@@ -17,11 +17,15 @@
#include <mach/regs-ost.h>
-#define xip_irqpending() (ICIP & ICMR)
+/* restored July 2017, this did not build since 2011! */
+
+#define ICIP io_p2v(0x40d00000)
+#define ICMR io_p2v(0x40d00004)
+#define xip_irqpending() (readl(ICIP) & readl(ICMR))
/* we sample OSCR and convert desired delta to usec (1/4 ~= 1000000/3686400) */
-#define xip_currtime() (OSCR)
-#define xip_elapsed_since(x) (signed)((OSCR - (x)) / 4)
+#define xip_currtime() readl(OSCR)
+#define xip_elapsed_since(x) (signed)((readl(OSCR) - (x)) / 4)
/*
* xip_cpu_idle() is used when waiting for a delay equal or larger than
diff --git a/arch/arm/mach-rpc/include/mach/hardware.h b/arch/arm/mach-rpc/include/mach/hardware.h
index aa79fa47373a..622d4e5df029 100644
--- a/arch/arm/mach-rpc/include/mach/hardware.h
+++ b/arch/arm/mach-rpc/include/mach/hardware.h
@@ -25,8 +25,8 @@
* *_SIZE is the size of the region
* *_BASE is the virtual address
*/
-#define RAM_SIZE 0x10000000
-#define RAM_START 0x10000000
+#define RPC_RAM_SIZE 0x10000000
+#define RPC_RAM_START 0x10000000
#define EASI_SIZE 0x08000000 /* EASI I/O */
#define EASI_START 0x08000000
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index 0db46895c82a..7d52cd97d96e 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -35,6 +35,31 @@ struct clk clk_##_name = { \
static DEFINE_SPINLOCK(clocks_lock);
+/* Dummy clk routine to build generic kernel parts that may be using them */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ return clk_get_rate(clk);
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+ return NULL;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
static void clk_gpio27_enable(struct clk *clk)
{
/*
diff --git a/arch/arm/mach-sa1100/include/mach/mtd-xip.h b/arch/arm/mach-sa1100/include/mach/mtd-xip.h
index b3d684098fbf..cb76096a2e36 100644
--- a/arch/arm/mach-sa1100/include/mach/mtd-xip.h
+++ b/arch/arm/mach-sa1100/include/mach/mtd-xip.h
@@ -20,7 +20,7 @@
#define xip_irqpending() (ICIP & ICMR)
/* we sample OSCR and convert desired delta to usec (1/4 ~= 1000000/3686400) */
-#define xip_currtime() (OSCR)
-#define xip_elapsed_since(x) (signed)((OSCR - (x)) / 4)
+#define xip_currtime() readl_relaxed(OSCR)
+#define xip_elapsed_since(x) (signed)((readl_relaxed(OSCR) - (x)) / 4)
#endif /* __ARCH_SA1100_MTD_XIP_H__ */
diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
index 73e3adbc1330..44438f344dc8 100644
--- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
@@ -67,8 +67,12 @@ static int regulator_quirk_notify(struct notifier_block *nb,
{
struct device *dev = data;
struct i2c_client *client;
+ static bool done;
u32 mon;
+ if (done)
+ return 0;
+
mon = ioread32(irqc + IRQC_MONITOR);
dev_dbg(dev, "%s: %ld, IRQC_MONITOR = 0x%x\n", __func__, action, mon);
if (mon & REGULATOR_IRQ_MASK)
@@ -99,7 +103,7 @@ static int regulator_quirk_notify(struct notifier_block *nb,
remove:
dev_info(dev, "IRQ2 is not asserted, removing quirk\n");
- bus_unregister_notifier(&i2c_bus_type, nb);
+ done = true;
iounmap(irqc);
return 0;
}
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index 28083ef72819..71a34e8c345a 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -133,6 +133,7 @@ static irqreturn_t db8500_pmu_handler(int irq, void *dev, irq_handler_t handler)
static struct arm_pmu_platdata db8500_pmu_platdata = {
.handle_irq = db8500_pmu_handler,
+ .irq_flags = IRQF_NOBALANCING | IRQF_NO_THREAD,
};
static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
diff --git a/arch/arm/mach-w90x900/clock.c b/arch/arm/mach-w90x900/clock.c
index ac6fd1a2cb59..3f93fac98d97 100644
--- a/arch/arm/mach-w90x900/clock.c
+++ b/arch/arm/mach-w90x900/clock.c
@@ -93,3 +93,32 @@ void nuc900_subclk_enable(struct clk *clk, int enable)
__raw_writel(clken, W90X900_VA_CLKPWR + SUBCLK);
}
+
+/* dummy functions, should not be called */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ WARN_ON(clk);
+ return 0;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ WARN_ON(clk);
+ return 0;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ WARN_ON(clk);
+ return 0;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+ WARN_ON(clk);
+ return NULL;
+}
+EXPORT_SYMBOL(clk_get_parent);
diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
index 90ee354d803e..6db5fc26d154 100644
--- a/arch/arm/mm/dma-mapping-nommu.c
+++ b/arch/arm/mm/dma-mapping-nommu.c
@@ -40,9 +40,21 @@ static void *arm_nommu_dma_alloc(struct device *dev, size_t size,
{
const struct dma_map_ops *ops = &dma_noop_ops;
+ void *ret;
/*
- * We are here because:
+ * Try generic allocator first if we are advertised that
+ * consistency is not required.
+ */
+
+ if (attrs & DMA_ATTR_NON_CONSISTENT)
+ return ops->alloc(dev, size, dma_handle, gfp, attrs);
+
+ ret = dma_alloc_from_global_coherent(size, dma_handle);
+
+ /*
+ * dma_alloc_from_global_coherent() may fail because:
+ *
* - no consistent DMA region has been defined, so we can't
* continue.
* - there is no space left in consistent DMA region, so we
@@ -50,11 +62,8 @@ static void *arm_nommu_dma_alloc(struct device *dev, size_t size,
* advertised that consistency is not required.
*/
- if (attrs & DMA_ATTR_NON_CONSISTENT)
- return ops->alloc(dev, size, dma_handle, gfp, attrs);
-
- WARN_ON_ONCE(1);
- return NULL;
+ WARN_ON_ONCE(ret == NULL);
+ return ret;
}
static void arm_nommu_dma_free(struct device *dev, size_t size,
@@ -63,14 +72,31 @@ static void arm_nommu_dma_free(struct device *dev, size_t size,
{
const struct dma_map_ops *ops = &dma_noop_ops;
- if (attrs & DMA_ATTR_NON_CONSISTENT)
+ if (attrs & DMA_ATTR_NON_CONSISTENT) {
ops->free(dev, size, cpu_addr, dma_addr, attrs);
- else
- WARN_ON_ONCE(1);
+ } else {
+ int ret = dma_release_from_global_coherent(get_order(size),
+ cpu_addr);
+
+ WARN_ON_ONCE(ret == 0);
+ }
return;
}
+static int arm_nommu_dma_mmap(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size,
+ unsigned long attrs)
+{
+ int ret;
+
+ if (dma_mmap_from_global_coherent(vma, cpu_addr, size, &ret))
+ return ret;
+
+ return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
+}
+
+
static void __dma_page_cpu_to_dev(phys_addr_t paddr, size_t size,
enum dma_data_direction dir)
{
@@ -173,6 +199,7 @@ static void arm_nommu_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist
const struct dma_map_ops arm_nommu_dma_ops = {
.alloc = arm_nommu_dma_alloc,
.free = arm_nommu_dma_free,
+ .mmap = arm_nommu_dma_mmap,
.map_page = arm_nommu_dma_map_page,
.unmap_page = arm_nommu_dma_unmap_page,
.map_sg = arm_nommu_dma_map_sg,
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index e7380bafbfa6..fcf1473d6fed 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -851,7 +851,7 @@ static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
unsigned long pfn = dma_to_pfn(dev, dma_addr);
unsigned long off = vma->vm_pgoff;
- if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
+ if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
return ret;
if (off < nr_pages && nr_vma_pages <= (nr_pages - off)) {
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 9d00622ce845..bd0f33b77f57 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -452,7 +452,7 @@
emac: ethernet@1c30000 {
compatible = "allwinner,sun50i-a64-emac";
syscon = <&syscon>;
- reg = <0x01c30000 0x100>;
+ reg = <0x01c30000 0x10000>;
interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";
resets = <&ccu RST_BUS_EMAC>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index 35b8c88c3220..738ed689ff69 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -400,7 +400,7 @@
};
pwm_AO_ab: pwm@550 {
- compatible = "amlogic,meson-gx-pwm", "amlogic,meson-gxbb-pwm";
+ compatible = "amlogic,meson-gx-ao-pwm", "amlogic,meson-gxbb-ao-pwm";
reg = <0x0 0x00550 0x0 0x10>;
#pwm-cells = <3>;
status = "disabled";
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
index 72c5a9f64ca8..94567eb17875 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
@@ -109,8 +109,8 @@
status = "okay";
pinctrl-0 = <&pwm_ao_a_3_pins>, <&pwm_ao_b_pins>;
pinctrl-names = "default";
- clocks = <&clkc CLKID_FCLK_DIV4>;
- clock-names = "clkin0";
+ clocks = <&xtal> , <&xtal>;
+ clock-names = "clkin0", "clkin1" ;
};
&pwm_ef {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
index 890821d6e52b..266fbcf3e47f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
@@ -10,12 +10,20 @@
#include <dt-bindings/input/input.h>
-#include "meson-gxl-s905x-p212.dtsi"
+#include "meson-gxl-s905x.dtsi"
/ {
compatible = "libretech,cc", "amlogic,s905x", "amlogic,meson-gxl";
model = "Libre Technology CC";
+ aliases {
+ serial0 = &uart_AO;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
cvbs-connector {
compatible = "composite-video-connector";
@@ -26,6 +34,11 @@
};
};
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+ };
+
hdmi-connector {
compatible = "hdmi-connector";
type = "a";
@@ -53,6 +66,39 @@
linux,default-trigger = "heartbeat";
};
};
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x80000000>;
+ };
+
+ vcc_3v3: regulator-vcc_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc_card: regulator-vcc-card {
+ compatible = "regulator-gpio";
+
+ regulator-name = "VCC_CARD";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>;
+ gpios-states = <0>;
+
+ states = <3300000 0>,
+ <1800000 1>;
+ };
+
+ vddio_boot: regulator-vddio_boot {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDIO_BOOT";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
};
&cvbs_vdac_port {
@@ -61,6 +107,16 @@
};
};
+&ethmac {
+ status = "okay";
+};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_input_ao_pins>;
+ pinctrl-names = "default";
+};
+
&hdmi_tx {
status = "okay";
pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
@@ -73,20 +129,43 @@
};
};
-/*
- * The following devices exists but are exposed on the general
- * purpose GPIO header. End user may well decide to use those pins
- * for another purpose
- */
+/* SD card */
+&sd_emmc_b {
+ status = "okay";
+ pinctrl-0 = <&sdcard_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <100000000>;
+ disable-wp;
+
+ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
+ cd-inverted;
-&sd_emmc_a {
- status = "disabled";
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vcc_card>;
};
-&uart_A {
- status = "disabled";
+/* eMMC */
+&sd_emmc_c {
+ status = "okay";
+ pinctrl-0 = <&emmc_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ max-frequency = <50000000>;
+ non-removable;
+ disable-wp;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vddio_boot>;
};
-&wifi32k {
- status = "disabled";
+&uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_a_pins>;
+ pinctrl-names = "default";
};
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index dbcc3d4e2ed5..51763d674050 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -219,7 +219,7 @@
reg = <0x18800 0x100>, <0x18C00 0x20>;
gpiosb: gpio {
#gpio-cells = <2>;
- gpio-ranges = <&pinctrl_sb 0 0 29>;
+ gpio-ranges = <&pinctrl_sb 0 0 30>;
gpio-controller;
interrupts =
<GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
index 726528ce54e9..4c68605675a8 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
@@ -270,6 +270,7 @@
interrupt-names = "mem", "ring0", "ring1",
"ring2", "ring3", "eip";
clocks = <&cpm_clk 1 26>;
+ dma-coherent;
};
};
diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
index 95f8e5f607f6..923f354b02f0 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
@@ -64,7 +64,7 @@
compatible = "marvell,armada-8k-rtc";
reg = <0x284000 0x20>, <0x284080 0x24>;
reg-names = "rtc", "rtc-soc";
- interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <ICU_GRP_NSR 77 IRQ_TYPE_LEVEL_HIGH>;
};
cps_ethernet: ethernet@0 {
@@ -261,6 +261,7 @@
interrupt-names = "mem", "ring0", "ring1",
"ring2", "ring3", "eip";
clocks = <&cps_clk 1 26>;
+ dma-coherent;
/*
* The cryptographic engine found on the cp110
* master is enabled by default at the SoC
diff --git a/arch/arm64/boot/dts/renesas/salvator-common.dtsi b/arch/arm64/boot/dts/renesas/salvator-common.dtsi
index aef35e0b685a..a451996f590a 100644
--- a/arch/arm64/boot/dts/renesas/salvator-common.dtsi
+++ b/arch/arm64/boot/dts/renesas/salvator-common.dtsi
@@ -508,7 +508,7 @@
/* audio_clkout0/1/2/3 */
#clock-cells = <1>;
- clock-frequency = <11289600 12288000>;
+ clock-frequency = <12288000 11289600>;
status = "okay";
diff --git a/arch/arm64/boot/dts/renesas/ulcb.dtsi b/arch/arm64/boot/dts/renesas/ulcb.dtsi
index b5c6ee07d7f9..d1a3f3b7a0ab 100644
--- a/arch/arm64/boot/dts/renesas/ulcb.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb.dtsi
@@ -281,7 +281,7 @@
/* audio_clkout0/1/2/3 */
#clock-cells = <1>;
- clock-frequency = <11289600 12288000>;
+ clock-frequency = <12288000 11289600>;
status = "okay";
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 6c7d147eed54..b4ca115b3be1 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -476,6 +476,7 @@ CONFIG_QCOM_CLK_SMD_RPM=y
CONFIG_MSM_GCC_8916=y
CONFIG_MSM_GCC_8994=y
CONFIG_MSM_MMCC_8996=y
+CONFIG_HWSPINLOCK=y
CONFIG_HWSPINLOCK_QCOM=y
CONFIG_ARM_MHU=y
CONFIG_PLATFORM_MHU=y
diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h
index 99fa69c9c3cf..9ef0797380cb 100644
--- a/arch/arm64/include/asm/atomic_lse.h
+++ b/arch/arm64/include/asm/atomic_lse.h
@@ -435,7 +435,7 @@ static inline long atomic64_dec_if_positive(atomic64_t *v)
" sub x30, x30, %[ret]\n"
" cbnz x30, 1b\n"
"2:")
- : [ret] "+&r" (x0), [v] "+Q" (v->counter)
+ : [ret] "+r" (x0), [v] "+Q" (v->counter)
:
: __LL_SC_CLOBBERS, "cc", "memory");
diff --git a/arch/arm64/include/asm/bug.h b/arch/arm64/include/asm/bug.h
index 366448eb0fb7..a02a57186f56 100644
--- a/arch/arm64/include/asm/bug.h
+++ b/arch/arm64/include/asm/bug.h
@@ -36,7 +36,7 @@
#ifdef CONFIG_GENERIC_BUG
#define __BUG_ENTRY(flags) \
- ".pushsection __bug_table,\"a\"\n\t" \
+ ".pushsection __bug_table,\"aw\"\n\t" \
".align 2\n\t" \
"0: .long 1f - 0b\n\t" \
_BUGVERBOSE_LOCATION(__FILE__, __LINE__) \
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 32f82723338a..ef39dcb9ca6a 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -64,8 +64,10 @@
* TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area.
*/
#define VA_BITS (CONFIG_ARM64_VA_BITS)
-#define VA_START (UL(0xffffffffffffffff) << VA_BITS)
-#define PAGE_OFFSET (UL(0xffffffffffffffff) << (VA_BITS - 1))
+#define VA_START (UL(0xffffffffffffffff) - \
+ (UL(1) << VA_BITS) + 1)
+#define PAGE_OFFSET (UL(0xffffffffffffffff) - \
+ (UL(1) << (VA_BITS - 1)) + 1)
#define KIMAGE_VADDR (MODULES_END)
#define MODULES_END (MODULES_VADDR + MODULES_VSIZE)
#define MODULES_VADDR (VA_START + KASAN_SHADOW_SIZE)
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 16e44fa9b3b6..248339e4aaf5 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -492,7 +492,7 @@ asm(
* the "%x0" template means XZR.
*/
#define write_sysreg(v, r) do { \
- u64 __val = (u64)v; \
+ u64 __val = (u64)(v); \
asm volatile("msr " __stringify(r) ", %x0" \
: : "rZ" (__val)); \
} while (0)
@@ -508,7 +508,7 @@ asm(
})
#define write_sysreg_s(v, r) do { \
- u64 __val = (u64)v; \
+ u64 __val = (u64)(v); \
asm volatile("msr_s " __stringify(r) ", %x0" : : "rZ" (__val)); \
} while (0)
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index 8f0a1de11e4a..fab46a0ea223 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -69,7 +69,7 @@ static inline void set_fs(mm_segment_t fs)
*/
#define __range_ok(addr, size) \
({ \
- unsigned long __addr = (unsigned long __force)(addr); \
+ unsigned long __addr = (unsigned long)(addr); \
unsigned long flag, roksum; \
__chk_user_ptr(addr); \
asm("adds %1, %1, %3; ccmp %1, %4, #2, cc; cset %0, ls" \
diff --git a/arch/arm64/kernel/cpu_ops.c b/arch/arm64/kernel/cpu_ops.c
index e137ceaf5016..d16978213c5b 100644
--- a/arch/arm64/kernel/cpu_ops.c
+++ b/arch/arm64/kernel/cpu_ops.c
@@ -82,8 +82,8 @@ static const char *__init cpu_read_enable_method(int cpu)
* Don't warn spuriously.
*/
if (cpu != 0)
- pr_err("%s: missing enable-method property\n",
- dn->full_name);
+ pr_err("%pOF: missing enable-method property\n",
+ dn);
}
} else {
enable_method = acpi_get_enable_method(cpu);
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 321119881abf..dc66e6ec3a99 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -469,7 +469,7 @@ static u64 __init of_get_cpu_mpidr(struct device_node *dn)
*/
cell = of_get_property(dn, "reg", NULL);
if (!cell) {
- pr_err("%s: missing reg property\n", dn->full_name);
+ pr_err("%pOF: missing reg property\n", dn);
return INVALID_HWID;
}
@@ -478,7 +478,7 @@ static u64 __init of_get_cpu_mpidr(struct device_node *dn)
* Non affinity bits must be set to 0 in the DT
*/
if (hwid & ~MPIDR_HWID_BITMASK) {
- pr_err("%s: invalid reg property\n", dn->full_name);
+ pr_err("%pOF: invalid reg property\n", dn);
return INVALID_HWID;
}
return hwid;
@@ -627,8 +627,8 @@ static void __init of_parse_and_init_cpus(void)
goto next;
if (is_mpidr_duplicate(cpu_count, hwid)) {
- pr_err("%s: duplicate cpu reg properties in the DT\n",
- dn->full_name);
+ pr_err("%pOF: duplicate cpu reg properties in the DT\n",
+ dn);
goto next;
}
@@ -640,8 +640,8 @@ static void __init of_parse_and_init_cpus(void)
*/
if (hwid == cpu_logical_map(0)) {
if (bootcpu_valid) {
- pr_err("%s: duplicate boot cpu reg property in DT\n",
- dn->full_name);
+ pr_err("%pOF: duplicate boot cpu reg property in DT\n",
+ dn);
goto next;
}
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index 79244c75eaec..8d48b233e6ce 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -45,7 +45,7 @@ static int __init get_cpu_for_node(struct device_node *node)
}
}
- pr_crit("Unable to find CPU node for %s\n", cpu_node->full_name);
+ pr_crit("Unable to find CPU node for %pOF\n", cpu_node);
of_node_put(cpu_node);
return -1;
@@ -71,8 +71,8 @@ static int __init parse_core(struct device_node *core, int cluster_id,
cpu_topology[cpu].core_id = core_id;
cpu_topology[cpu].thread_id = i;
} else {
- pr_err("%s: Can't get CPU for thread\n",
- t->full_name);
+ pr_err("%pOF: Can't get CPU for thread\n",
+ t);
of_node_put(t);
return -EINVAL;
}
@@ -84,15 +84,15 @@ static int __init parse_core(struct device_node *core, int cluster_id,
cpu = get_cpu_for_node(core);
if (cpu >= 0) {
if (!leaf) {
- pr_err("%s: Core has both threads and CPU\n",
- core->full_name);
+ pr_err("%pOF: Core has both threads and CPU\n",
+ core);
return -EINVAL;
}
cpu_topology[cpu].cluster_id = cluster_id;
cpu_topology[cpu].core_id = core_id;
} else if (leaf) {
- pr_err("%s: Can't get CPU for leaf core\n", core->full_name);
+ pr_err("%pOF: Can't get CPU for leaf core\n", core);
return -EINVAL;
}
@@ -137,8 +137,8 @@ static int __init parse_cluster(struct device_node *cluster, int depth)
has_cores = true;
if (depth == 0) {
- pr_err("%s: cpu-map children should be clusters\n",
- c->full_name);
+ pr_err("%pOF: cpu-map children should be clusters\n",
+ c);
of_node_put(c);
return -EINVAL;
}
@@ -146,8 +146,8 @@ static int __init parse_cluster(struct device_node *cluster, int depth)
if (leaf) {
ret = parse_core(c, cluster_id, core_id++);
} else {
- pr_err("%s: Non-leaf cluster with core %s\n",
- cluster->full_name, name);
+ pr_err("%pOF: Non-leaf cluster with core %s\n",
+ cluster, name);
ret = -EINVAL;
}
@@ -159,7 +159,7 @@ static int __init parse_cluster(struct device_node *cluster, int depth)
} while (c);
if (leaf && !has_cores)
- pr_warn("%s: empty cluster\n", cluster->full_name);
+ pr_warn("%pOF: empty cluster\n", cluster);
if (leaf)
cluster_id++;
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index c7c7088097be..8a62648848e5 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -274,10 +274,12 @@ static DEFINE_RAW_SPINLOCK(die_lock);
void die(const char *str, struct pt_regs *regs, int err)
{
int ret;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&die_lock, flags);
oops_enter();
- raw_spin_lock_irq(&die_lock);
console_verbose();
bust_spinlocks(1);
ret = __die(str, err, regs);
@@ -287,13 +289,15 @@ void die(const char *str, struct pt_regs *regs, int err)
bust_spinlocks(0);
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
- raw_spin_unlock_irq(&die_lock);
oops_exit();
if (in_interrupt())
panic("Fatal exception in interrupt");
if (panic_on_oops)
panic("Fatal exception");
+
+ raw_spin_unlock_irqrestore(&die_lock, flags);
+
if (ret != NOTIFY_STOP)
do_exit(SIGSEGV);
}
@@ -519,7 +523,7 @@ static void cntfrq_read_handler(unsigned int esr, struct pt_regs *regs)
{
int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT;
- pt_regs_write_reg(regs, rt, read_sysreg(cntfrq_el0));
+ pt_regs_write_reg(regs, rt, arch_timer_get_rate());
regs->pc += 4;
}
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 77862881ae86..2e070d3baf9f 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -764,7 +764,7 @@ static bool access_pmovs(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
if (p->is_write) {
if (r->CRm & 0x2)
/* accessing PMOVSSET_EL0 */
- kvm_pmu_overflow_set(vcpu, p->regval & mask);
+ vcpu_sys_reg(vcpu, PMOVSSET_EL0) |= (p->regval & mask);
else
/* accessing PMOVSCLR_EL0 */
vcpu_sys_reg(vcpu, PMOVSSET_EL0) &= ~(p->regval & mask);
diff --git a/arch/arm64/lib/copy_page.S b/arch/arm64/lib/copy_page.S
index c3cd65e31814..076c43715e64 100644
--- a/arch/arm64/lib/copy_page.S
+++ b/arch/arm64/lib/copy_page.S
@@ -30,9 +30,10 @@
*/
ENTRY(copy_page)
alternative_if ARM64_HAS_NO_HW_PREFETCH
- # Prefetch two cache lines ahead.
- prfm pldl1strm, [x1, #128]
- prfm pldl1strm, [x1, #256]
+ // Prefetch three cache lines ahead.
+ prfm pldl1strm, [x1, #128]
+ prfm pldl1strm, [x1, #256]
+ prfm pldl1strm, [x1, #384]
alternative_else_nop_endif
ldp x2, x3, [x1]
@@ -50,7 +51,7 @@ alternative_else_nop_endif
subs x18, x18, #128
alternative_if ARM64_HAS_NO_HW_PREFETCH
- prfm pldl1strm, [x1, #384]
+ prfm pldl1strm, [x1, #384]
alternative_else_nop_endif
stnp x2, x3, [x0]
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index e90cd1db42a8..f27d4dd04384 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -329,7 +329,7 @@ static int __swiotlb_mmap(struct device *dev,
vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot,
is_device_dma_coherent(dev));
- if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
+ if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
return ret;
return __swiotlb_mmap_pfn(vma, pfn, size);
@@ -706,7 +706,7 @@ static int __iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot,
is_device_dma_coherent(dev));
- if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
+ if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
return ret;
if (attrs & DMA_ATTR_FORCE_CONTIGUOUS) {
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index c7861c9864e6..2509e4fe6992 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -163,26 +163,27 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
/* only preserve the access flags and write permission */
pte_val(entry) &= PTE_AF | PTE_WRITE | PTE_DIRTY;
- /*
- * PTE_RDONLY is cleared by default in the asm below, so set it in
- * back if necessary (read-only or clean PTE).
- */
+ /* set PTE_RDONLY if actual read-only or clean PTE */
if (!pte_write(entry) || !pte_sw_dirty(entry))
pte_val(entry) |= PTE_RDONLY;
/*
* Setting the flags must be done atomically to avoid racing with the
- * hardware update of the access/dirty state.
+ * hardware update of the access/dirty state. The PTE_RDONLY bit must
+ * be set to the most permissive (lowest value) of *ptep and entry
+ * (calculated as: a & b == ~(~a | ~b)).
*/
+ pte_val(entry) ^= PTE_RDONLY;
asm volatile("// ptep_set_access_flags\n"
" prfm pstl1strm, %2\n"
"1: ldxr %0, %2\n"
- " and %0, %0, %3 // clear PTE_RDONLY\n"
+ " eor %0, %0, %3 // negate PTE_RDONLY in *ptep\n"
" orr %0, %0, %4 // set flags\n"
+ " eor %0, %0, %3 // negate final PTE_RDONLY\n"
" stxr %w1, %0, %2\n"
" cbnz %w1, 1b\n"
: "=&r" (old_pteval), "=&r" (tmp), "+Q" (pte_val(*ptep))
- : "L" (~PTE_RDONLY), "r" (pte_val(entry)));
+ : "L" (PTE_RDONLY), "r" (pte_val(entry)));
flush_tlb_fix_spurious_fault(vma, address);
return 1;
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 23c2d89a362e..f1eb15e0e864 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -496,7 +496,7 @@ void mark_rodata_ro(void)
static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end,
pgprot_t prot, struct vm_struct *vma,
- int flags)
+ int flags, unsigned long vm_flags)
{
phys_addr_t pa_start = __pa_symbol(va_start);
unsigned long size = va_end - va_start;
@@ -507,10 +507,13 @@ static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end,
__create_pgd_mapping(pgd, pa_start, (unsigned long)va_start, size, prot,
early_pgtable_alloc, flags);
+ if (!(vm_flags & VM_NO_GUARD))
+ size += PAGE_SIZE;
+
vma->addr = va_start;
vma->phys_addr = pa_start;
vma->size = size;
- vma->flags = VM_MAP;
+ vma->flags = VM_MAP | vm_flags;
vma->caller = __builtin_return_address(0);
vm_area_add_early(vma);
@@ -541,14 +544,15 @@ static void __init map_kernel(pgd_t *pgd)
* Only rodata will be remapped with different permissions later on,
* all other segments are allowed to use contiguous mappings.
*/
- map_kernel_segment(pgd, _text, _etext, text_prot, &vmlinux_text, 0);
+ map_kernel_segment(pgd, _text, _etext, text_prot, &vmlinux_text, 0,
+ VM_NO_GUARD);
map_kernel_segment(pgd, __start_rodata, __inittext_begin, PAGE_KERNEL,
- &vmlinux_rodata, NO_CONT_MAPPINGS);
+ &vmlinux_rodata, NO_CONT_MAPPINGS, VM_NO_GUARD);
map_kernel_segment(pgd, __inittext_begin, __inittext_end, text_prot,
- &vmlinux_inittext, 0);
+ &vmlinux_inittext, 0, VM_NO_GUARD);
map_kernel_segment(pgd, __initdata_begin, __initdata_end, PAGE_KERNEL,
- &vmlinux_initdata, 0);
- map_kernel_segment(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data, 0);
+ &vmlinux_initdata, 0, VM_NO_GUARD);
+ map_kernel_segment(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data, 0, 0);
if (!pgd_val(*pgd_offset_raw(pgd, FIXADDR_START))) {
/*
diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
index b388a99fea7b..dad128ba98bf 100644
--- a/arch/arm64/mm/numa.c
+++ b/arch/arm64/mm/numa.c
@@ -208,8 +208,6 @@ int __init numa_add_memblk(int nid, u64 start, u64 end)
}
node_set(nid, numa_nodes_parsed);
- pr_info("Adding memblock [0x%llx - 0x%llx] on node %d\n",
- start, (end - 1), nid);
return ret;
}
@@ -223,10 +221,7 @@ static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn)
void *nd;
int tnid;
- if (start_pfn < end_pfn)
- pr_info("Initmem setup node %d [mem %#010Lx-%#010Lx]\n", nid,
- start_pfn << PAGE_SHIFT, (end_pfn << PAGE_SHIFT) - 1);
- else
+ if (start_pfn >= end_pfn)
pr_info("Initmem setup node %d [<memory-less node>]\n", nid);
nd_pa = memblock_alloc_try_nid(nd_size, SMP_CACHE_BYTES, nid);
diff --git a/arch/blackfin/include/asm/bug.h b/arch/blackfin/include/asm/bug.h
index 8d9b1eba89c4..76b2e82ee730 100644
--- a/arch/blackfin/include/asm/bug.h
+++ b/arch/blackfin/include/asm/bug.h
@@ -21,7 +21,7 @@
#define _BUG_OR_WARN(flags) \
asm volatile( \
"1: .hword %0\n" \
- " .section __bug_table,\"a\",@progbits\n" \
+ " .section __bug_table,\"aw\",@progbits\n" \
"2: .long 1b\n" \
" .long %1\n" \
" .short %2\n" \
@@ -38,7 +38,7 @@
#define _BUG_OR_WARN(flags) \
asm volatile( \
"1: .hword %0\n" \
- " .section __bug_table,\"a\",@progbits\n" \
+ " .section __bug_table,\"aw\",@progbits\n" \
"2: .long 1b\n" \
" .short %1\n" \
" .org 2b + %2\n" \
diff --git a/arch/blackfin/include/asm/flat.h b/arch/blackfin/include/asm/flat.h
index 296d7f56fbfd..f1d6ba7afbf2 100644
--- a/arch/blackfin/include/asm/flat.h
+++ b/arch/blackfin/include/asm/flat.h
@@ -44,8 +44,7 @@ flat_get_relocate_addr (unsigned long relval)
return relval & 0x03ffffff; /* Mask out top 6 bits */
}
-static inline int flat_set_persistent(unsigned long relval,
- unsigned long *persistent)
+static inline int flat_set_persistent(u32 relval, u32 *persistent)
{
int type = (relval >> 26) & 7;
if (type == 3) {
diff --git a/arch/blackfin/kernel/flat.c b/arch/blackfin/kernel/flat.c
index d29ab6a2e909..8ebc54daaa8e 100644
--- a/arch/blackfin/kernel/flat.c
+++ b/arch/blackfin/kernel/flat.c
@@ -32,7 +32,7 @@ unsigned long bfin_get_addr_from_rp(u32 *ptr,
break;
case FLAT_BFIN_RELOC_TYPE_32_BIT:
- pr_debug("*ptr = %lx", get_unaligned(ptr));
+ pr_debug("*ptr = %x", get_unaligned(ptr));
val = get_unaligned(ptr);
break;
@@ -77,7 +77,7 @@ void bfin_put_addr_at_rp(u32 *ptr, u32 addr, u32 relval)
case FLAT_BFIN_RELOC_TYPE_32_BIT:
put_unaligned(addr, ptr);
- pr_debug("new ptr =%lx", get_unaligned(ptr));
+ pr_debug("new ptr =%x", get_unaligned(ptr));
break;
}
}
diff --git a/arch/h8300/include/asm/flat.h b/arch/h8300/include/asm/flat.h
index 18d024251738..7e0bd6fa1532 100644
--- a/arch/h8300/include/asm/flat.h
+++ b/arch/h8300/include/asm/flat.h
@@ -24,7 +24,7 @@ static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
u32 *addr, u32 *persistent)
{
u32 val = get_unaligned((__force u32 *)rp);
- if (!(flags & FLAT_FLAG_GOTPIC)
+ if (!(flags & FLAT_FLAG_GOTPIC))
val &= 0x00ffffff;
*addr = val;
return 0;
diff --git a/arch/ia64/include/asm/tlb.h b/arch/ia64/include/asm/tlb.h
index fced197b9626..cbe5ac3699bf 100644
--- a/arch/ia64/include/asm/tlb.h
+++ b/arch/ia64/include/asm/tlb.h
@@ -168,7 +168,8 @@ static inline void __tlb_alloc_page(struct mmu_gather *tlb)
static inline void
-tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
+arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
+ unsigned long start, unsigned long end)
{
tlb->mm = mm;
tlb->max = ARRAY_SIZE(tlb->local);
@@ -185,8 +186,11 @@ tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start
* collected.
*/
static inline void
-tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
+arch_tlb_finish_mmu(struct mmu_gather *tlb,
+ unsigned long start, unsigned long end, bool force)
{
+ if (force)
+ tlb->need_flush = 1;
/*
* Note: tlb->nr may be 0 at this point, so we can't rely on tlb->start_addr and
* tlb->end_addr.
diff --git a/arch/m68k/include/asm/flat.h b/arch/m68k/include/asm/flat.h
index 48b62790fe70..b2a41f5b3890 100644
--- a/arch/m68k/include/asm/flat.h
+++ b/arch/m68k/include/asm/flat.h
@@ -30,8 +30,7 @@ static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
}
#define flat_get_relocate_addr(rel) (rel)
-static inline int flat_set_persistent(unsigned long relval,
- unsigned long *persistent)
+static inline int flat_set_persistent(u32 relval, u32 *persistent)
{
return 0;
}
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 8dd20358464f..48d91d5be4e9 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2260,7 +2260,7 @@ config CPU_R4K_CACHE_TLB
config MIPS_MT_SMP
bool "MIPS MT SMP support (1 TC on each available VPE)"
- depends on SYS_SUPPORTS_MULTITHREADING && !CPU_MIPSR6
+ depends on SYS_SUPPORTS_MULTITHREADING && !CPU_MIPSR6 && !CPU_MICROMIPS
select CPU_MIPSR2_IRQ_VI
select CPU_MIPSR2_IRQ_EI
select SYNC_R4K
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 04343625b929..bc2708c9ada4 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -243,8 +243,21 @@ include arch/mips/Kbuild.platforms
ifdef CONFIG_PHYSICAL_START
load-y = $(CONFIG_PHYSICAL_START)
endif
-entry-y = 0x$(shell $(NM) vmlinux 2>/dev/null \
+
+entry-noisa-y = 0x$(shell $(NM) vmlinux 2>/dev/null \
| grep "\bkernel_entry\b" | cut -f1 -d \ )
+ifdef CONFIG_CPU_MICROMIPS
+ #
+ # Set the ISA bit, since the kernel_entry symbol in the ELF will have it
+ # clear which would lead to images containing addresses which bootloaders may
+ # jump to as MIPS32 code.
+ #
+ entry-y = $(patsubst %0,%1,$(patsubst %2,%3,$(patsubst %4,%5, \
+ $(patsubst %6,%7,$(patsubst %8,%9,$(patsubst %a,%b, \
+ $(patsubst %c,%d,$(patsubst %e,%f,$(entry-noisa-y)))))))))
+else
+ entry-y = $(entry-noisa-y)
+endif
cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic
drivers-$(CONFIG_PCI) += arch/mips/pci/
diff --git a/arch/mips/boot/compressed/.gitignore b/arch/mips/boot/compressed/.gitignore
new file mode 100644
index 000000000000..ebae133f1d00
--- /dev/null
+++ b/arch/mips/boot/compressed/.gitignore
@@ -0,0 +1,2 @@
+ashldi3.c
+bswapsi.c
diff --git a/arch/mips/cavium-octeon/octeon-usb.c b/arch/mips/cavium-octeon/octeon-usb.c
index 542be1cd0f32..bfdfaf32d2c4 100644
--- a/arch/mips/cavium-octeon/octeon-usb.c
+++ b/arch/mips/cavium-octeon/octeon-usb.c
@@ -13,9 +13,9 @@
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/of_platform.h>
+#include <linux/io.h>
#include <asm/octeon/octeon.h>
-#include <asm/octeon/cvmx-gpio-defs.h>
/* USB Control Register */
union cvm_usbdrd_uctl_ctl {
diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S
index 1910223a9c02..cea2bb1621e6 100644
--- a/arch/mips/dec/int-handler.S
+++ b/arch/mips/dec/int-handler.S
@@ -147,23 +147,12 @@
* Find irq with highest priority
*/
# open coded PTR_LA t1, cpu_mask_nr_tbl
-#if (_MIPS_SZPTR == 32)
+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
# open coded la t1, cpu_mask_nr_tbl
lui t1, %hi(cpu_mask_nr_tbl)
addiu t1, %lo(cpu_mask_nr_tbl)
-
-#endif
-#if (_MIPS_SZPTR == 64)
- # open coded dla t1, cpu_mask_nr_tbl
- .set push
- .set noat
- lui t1, %highest(cpu_mask_nr_tbl)
- lui AT, %hi(cpu_mask_nr_tbl)
- daddiu t1, t1, %higher(cpu_mask_nr_tbl)
- daddiu AT, AT, %lo(cpu_mask_nr_tbl)
- dsll t1, 32
- daddu t1, t1, AT
- .set pop
+#else
+#error GCC `-msym32' option required for 64-bit DECstation builds
#endif
1: lw t2,(t1)
nop
@@ -214,23 +203,12 @@
* Find irq with highest priority
*/
# open coded PTR_LA t1,asic_mask_nr_tbl
-#if (_MIPS_SZPTR == 32)
+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
# open coded la t1, asic_mask_nr_tbl
lui t1, %hi(asic_mask_nr_tbl)
addiu t1, %lo(asic_mask_nr_tbl)
-
-#endif
-#if (_MIPS_SZPTR == 64)
- # open coded dla t1, asic_mask_nr_tbl
- .set push
- .set noat
- lui t1, %highest(asic_mask_nr_tbl)
- lui AT, %hi(asic_mask_nr_tbl)
- daddiu t1, t1, %higher(asic_mask_nr_tbl)
- daddiu AT, AT, %lo(asic_mask_nr_tbl)
- dsll t1, 32
- daddu t1, t1, AT
- .set pop
+#else
+#error GCC `-msym32' option required for 64-bit DECstation builds
#endif
2: lw t2,(t1)
nop
diff --git a/arch/mips/include/asm/cache.h b/arch/mips/include/asm/cache.h
index fc67947ed658..8b14c2706aa5 100644
--- a/arch/mips/include/asm/cache.h
+++ b/arch/mips/include/asm/cache.h
@@ -9,6 +9,8 @@
#ifndef _ASM_CACHE_H
#define _ASM_CACHE_H
+#include <kmalloc.h>
+
#define L1_CACHE_SHIFT CONFIG_MIPS_L1_CACHE_SHIFT
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index 8baa9033b181..721b698bfe3c 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -428,6 +428,9 @@
#ifndef cpu_scache_line_size
#define cpu_scache_line_size() cpu_data[0].scache.linesz
#endif
+#ifndef cpu_tcache_line_size
+#define cpu_tcache_line_size() cpu_data[0].tcache.linesz
+#endif
#ifndef cpu_hwrena_impl_bits
#define cpu_hwrena_impl_bits 0
diff --git a/arch/mips/include/asm/mach-ralink/ralink_regs.h b/arch/mips/include/asm/mach-ralink/ralink_regs.h
index 9df1a53bcb36..b4e7dfa214eb 100644
--- a/arch/mips/include/asm/mach-ralink/ralink_regs.h
+++ b/arch/mips/include/asm/mach-ralink/ralink_regs.h
@@ -13,6 +13,8 @@
#ifndef _RALINK_REGS_H_
#define _RALINK_REGS_H_
+#include <linux/io.h>
+
enum ralink_soc_type {
RALINK_UNKNOWN = 0,
RT2880_SOC,
diff --git a/arch/mips/include/asm/octeon/cvmx-l2c-defs.h b/arch/mips/include/asm/octeon/cvmx-l2c-defs.h
index d045973ddb33..3ea84acf1814 100644
--- a/arch/mips/include/asm/octeon/cvmx-l2c-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-l2c-defs.h
@@ -33,6 +33,10 @@
#define CVMX_L2C_DBG (CVMX_ADD_IO_SEG(0x0001180080000030ull))
#define CVMX_L2C_CFG (CVMX_ADD_IO_SEG(0x0001180080000000ull))
#define CVMX_L2C_CTL (CVMX_ADD_IO_SEG(0x0001180080800000ull))
+#define CVMX_L2C_ERR_TDTX(block_id) \
+ (CVMX_ADD_IO_SEG(0x0001180080A007E0ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_ERR_TTGX(block_id) \
+ (CVMX_ADD_IO_SEG(0x0001180080A007E8ull) + ((block_id) & 3) * 0x40000ull)
#define CVMX_L2C_LCKBASE (CVMX_ADD_IO_SEG(0x0001180080000058ull))
#define CVMX_L2C_LCKOFF (CVMX_ADD_IO_SEG(0x0001180080000060ull))
#define CVMX_L2C_PFCTL (CVMX_ADD_IO_SEG(0x0001180080000090ull))
@@ -66,9 +70,40 @@
((offset) & 1) * 8)
#define CVMX_L2C_WPAR_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080840000ull) + \
((offset) & 31) * 8)
-#define CVMX_L2D_FUS3 (CVMX_ADD_IO_SEG(0x00011800800007B8ull))
+union cvmx_l2c_err_tdtx {
+ uint64_t u64;
+ struct cvmx_l2c_err_tdtx_s {
+ __BITFIELD_FIELD(uint64_t dbe:1,
+ __BITFIELD_FIELD(uint64_t sbe:1,
+ __BITFIELD_FIELD(uint64_t vdbe:1,
+ __BITFIELD_FIELD(uint64_t vsbe:1,
+ __BITFIELD_FIELD(uint64_t syn:10,
+ __BITFIELD_FIELD(uint64_t reserved_22_49:28,
+ __BITFIELD_FIELD(uint64_t wayidx:18,
+ __BITFIELD_FIELD(uint64_t reserved_2_3:2,
+ __BITFIELD_FIELD(uint64_t type:2,
+ ;)))))))))
+ } s;
+};
+
+union cvmx_l2c_err_ttgx {
+ uint64_t u64;
+ struct cvmx_l2c_err_ttgx_s {
+ __BITFIELD_FIELD(uint64_t dbe:1,
+ __BITFIELD_FIELD(uint64_t sbe:1,
+ __BITFIELD_FIELD(uint64_t noway:1,
+ __BITFIELD_FIELD(uint64_t reserved_56_60:5,
+ __BITFIELD_FIELD(uint64_t syn:6,
+ __BITFIELD_FIELD(uint64_t reserved_22_49:28,
+ __BITFIELD_FIELD(uint64_t wayidx:15,
+ __BITFIELD_FIELD(uint64_t reserved_2_6:5,
+ __BITFIELD_FIELD(uint64_t type:2,
+ ;)))))))))
+ } s;
+};
+
union cvmx_l2c_cfg {
uint64_t u64;
struct cvmx_l2c_cfg_s {
diff --git a/arch/mips/include/asm/octeon/cvmx-l2d-defs.h b/arch/mips/include/asm/octeon/cvmx-l2d-defs.h
new file mode 100644
index 000000000000..a951ad5d65ad
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-l2d-defs.h
@@ -0,0 +1,60 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2017 Cavium, Inc.
+ *
+ * This file 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.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_L2D_DEFS_H__
+#define __CVMX_L2D_DEFS_H__
+
+#define CVMX_L2D_ERR (CVMX_ADD_IO_SEG(0x0001180080000010ull))
+#define CVMX_L2D_FUS3 (CVMX_ADD_IO_SEG(0x00011800800007B8ull))
+
+
+union cvmx_l2d_err {
+ uint64_t u64;
+ struct cvmx_l2d_err_s {
+ __BITFIELD_FIELD(uint64_t reserved_6_63:58,
+ __BITFIELD_FIELD(uint64_t bmhclsel:1,
+ __BITFIELD_FIELD(uint64_t ded_err:1,
+ __BITFIELD_FIELD(uint64_t sec_err:1,
+ __BITFIELD_FIELD(uint64_t ded_intena:1,
+ __BITFIELD_FIELD(uint64_t sec_intena:1,
+ __BITFIELD_FIELD(uint64_t ecc_ena:1,
+ ;)))))))
+ } s;
+};
+
+union cvmx_l2d_fus3 {
+ uint64_t u64;
+ struct cvmx_l2d_fus3_s {
+ __BITFIELD_FIELD(uint64_t reserved_40_63:24,
+ __BITFIELD_FIELD(uint64_t ema_ctl:3,
+ __BITFIELD_FIELD(uint64_t reserved_34_36:3,
+ __BITFIELD_FIELD(uint64_t q3fus:34,
+ ;))))
+ } s;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h
index 9742202f2a32..e638735cc3ac 100644
--- a/arch/mips/include/asm/octeon/cvmx.h
+++ b/arch/mips/include/asm/octeon/cvmx.h
@@ -62,6 +62,7 @@ enum cvmx_mips_space {
#include <asm/octeon/cvmx-iob-defs.h>
#include <asm/octeon/cvmx-ipd-defs.h>
#include <asm/octeon/cvmx-l2c-defs.h>
+#include <asm/octeon/cvmx-l2d-defs.h>
#include <asm/octeon/cvmx-l2t-defs.h>
#include <asm/octeon/cvmx-led-defs.h>
#include <asm/octeon/cvmx-mio-defs.h>
diff --git a/arch/mips/include/uapi/asm/ioctls.h b/arch/mips/include/uapi/asm/ioctls.h
index 68e19b689a00..1609cb0907ac 100644
--- a/arch/mips/include/uapi/asm/ioctls.h
+++ b/arch/mips/include/uapi/asm/ioctls.h
@@ -91,7 +91,7 @@
#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
-#define TIOCGPTPEER _IOR('T', 0x41, int) /* Safely open the slave */
+#define TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */
/* I hope the range from 0x5480 on is free ... */
#define TIOCSCTTY 0x5480 /* become controlling tty */
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 770d4d1516cb..6bace7695788 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -376,9 +376,6 @@ asmlinkage void start_secondary(void)
cpumask_set_cpu(cpu, &cpu_coherent_mask);
notify_cpu_starting(cpu);
- complete(&cpu_running);
- synchronise_count_slave(cpu);
-
set_cpu_online(cpu, true);
set_cpu_sibling_map(cpu);
@@ -386,6 +383,9 @@ asmlinkage void start_secondary(void)
calculate_cpu_foreign_map();
+ complete(&cpu_running);
+ synchronise_count_slave(cpu);
+
/*
* irq will be enabled in ->smp_finish(), enabling it too early
* is dangerous.
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index e08598c70b3e..8e78251eccc2 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -232,7 +232,7 @@ static int mips_dma_mmap(struct device *dev, struct vm_area_struct *vma,
else
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
+ if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
return ret;
if (off < count && user_count <= (count - off)) {
diff --git a/arch/mips/mm/uasm-mips.c b/arch/mips/mm/uasm-mips.c
index 3f74f6c1f065..9fea6c6bbf49 100644
--- a/arch/mips/mm/uasm-mips.c
+++ b/arch/mips/mm/uasm-mips.c
@@ -48,7 +48,7 @@
#include "uasm.c"
-static const struct insn const insn_table[insn_invalid] = {
+static const struct insn insn_table[insn_invalid] = {
[insn_addiu] = {M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM},
[insn_addu] = {M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD},
[insn_and] = {M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD},
diff --git a/arch/mips/net/ebpf_jit.c b/arch/mips/net/ebpf_jit.c
new file mode 100644
index 000000000000..3f87b96da5c4
--- /dev/null
+++ b/arch/mips/net/ebpf_jit.c
@@ -0,0 +1,1950 @@
+/*
+ * Just-In-Time compiler for eBPF filters on MIPS
+ *
+ * Copyright (c) 2017 Cavium, Inc.
+ *
+ * Based on code from:
+ *
+ * Copyright (c) 2014 Imagination Technologies Ltd.
+ * Author: Markos Chandras <markos.chandras@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/filter.h>
+#include <linux/bpf.h>
+#include <linux/slab.h>
+#include <asm/bitops.h>
+#include <asm/byteorder.h>
+#include <asm/cacheflush.h>
+#include <asm/cpu-features.h>
+#include <asm/uasm.h>
+
+/* Registers used by JIT */
+#define MIPS_R_ZERO 0
+#define MIPS_R_AT 1
+#define MIPS_R_V0 2 /* BPF_R0 */
+#define MIPS_R_V1 3
+#define MIPS_R_A0 4 /* BPF_R1 */
+#define MIPS_R_A1 5 /* BPF_R2 */
+#define MIPS_R_A2 6 /* BPF_R3 */
+#define MIPS_R_A3 7 /* BPF_R4 */
+#define MIPS_R_A4 8 /* BPF_R5 */
+#define MIPS_R_T4 12 /* BPF_AX */
+#define MIPS_R_T5 13
+#define MIPS_R_T6 14
+#define MIPS_R_T7 15
+#define MIPS_R_S0 16 /* BPF_R6 */
+#define MIPS_R_S1 17 /* BPF_R7 */
+#define MIPS_R_S2 18 /* BPF_R8 */
+#define MIPS_R_S3 19 /* BPF_R9 */
+#define MIPS_R_S4 20 /* BPF_TCC */
+#define MIPS_R_S5 21
+#define MIPS_R_S6 22
+#define MIPS_R_S7 23
+#define MIPS_R_T8 24
+#define MIPS_R_T9 25
+#define MIPS_R_SP 29
+#define MIPS_R_RA 31
+
+/* eBPF flags */
+#define EBPF_SAVE_S0 BIT(0)
+#define EBPF_SAVE_S1 BIT(1)
+#define EBPF_SAVE_S2 BIT(2)
+#define EBPF_SAVE_S3 BIT(3)
+#define EBPF_SAVE_S4 BIT(4)
+#define EBPF_SAVE_RA BIT(5)
+#define EBPF_SEEN_FP BIT(6)
+#define EBPF_SEEN_TC BIT(7)
+#define EBPF_TCC_IN_V1 BIT(8)
+
+/*
+ * For the mips64 ISA, we need to track the value range or type for
+ * each JIT register. The BPF machine requires zero extended 32-bit
+ * values, but the mips64 ISA requires sign extended 32-bit values.
+ * At each point in the BPF program we track the state of every
+ * register so that we can zero extend or sign extend as the BPF
+ * semantics require.
+ */
+enum reg_val_type {
+ /* uninitialized */
+ REG_UNKNOWN,
+ /* not known to be 32-bit compatible. */
+ REG_64BIT,
+ /* 32-bit compatible, no truncation needed for 64-bit ops. */
+ REG_64BIT_32BIT,
+ /* 32-bit compatible, need truncation for 64-bit ops. */
+ REG_32BIT,
+ /* 32-bit zero extended. */
+ REG_32BIT_ZERO_EX,
+ /* 32-bit no sign/zero extension needed. */
+ REG_32BIT_POS
+};
+
+/*
+ * high bit of offsets indicates if long branch conversion done at
+ * this insn.
+ */
+#define OFFSETS_B_CONV BIT(31)
+
+/**
+ * struct jit_ctx - JIT context
+ * @skf: The sk_filter
+ * @stack_size: eBPF stack size
+ * @tmp_offset: eBPF $sp offset to 8-byte temporary memory
+ * @idx: Instruction index
+ * @flags: JIT flags
+ * @offsets: Instruction offsets
+ * @target: Memory location for the compiled filter
+ * @reg_val_types Packed enum reg_val_type for each register.
+ */
+struct jit_ctx {
+ const struct bpf_prog *skf;
+ int stack_size;
+ int tmp_offset;
+ u32 idx;
+ u32 flags;
+ u32 *offsets;
+ u32 *target;
+ u64 *reg_val_types;
+ unsigned int long_b_conversion:1;
+ unsigned int gen_b_offsets:1;
+};
+
+static void set_reg_val_type(u64 *rvt, int reg, enum reg_val_type type)
+{
+ *rvt &= ~(7ull << (reg * 3));
+ *rvt |= ((u64)type << (reg * 3));
+}
+
+static enum reg_val_type get_reg_val_type(const struct jit_ctx *ctx,
+ int index, int reg)
+{
+ return (ctx->reg_val_types[index] >> (reg * 3)) & 7;
+}
+
+/* Simply emit the instruction if the JIT memory space has been allocated */
+#define emit_instr(ctx, func, ...) \
+do { \
+ if ((ctx)->target != NULL) { \
+ u32 *p = &(ctx)->target[ctx->idx]; \
+ uasm_i_##func(&p, ##__VA_ARGS__); \
+ } \
+ (ctx)->idx++; \
+} while (0)
+
+static unsigned int j_target(struct jit_ctx *ctx, int target_idx)
+{
+ unsigned long target_va, base_va;
+ unsigned int r;
+
+ if (!ctx->target)
+ return 0;
+
+ base_va = (unsigned long)ctx->target;
+ target_va = base_va + (ctx->offsets[target_idx] & ~OFFSETS_B_CONV);
+
+ if ((base_va & ~0x0ffffffful) != (target_va & ~0x0ffffffful))
+ return (unsigned int)-1;
+ r = target_va & 0x0ffffffful;
+ return r;
+}
+
+/* Compute the immediate value for PC-relative branches. */
+static u32 b_imm(unsigned int tgt, struct jit_ctx *ctx)
+{
+ if (!ctx->gen_b_offsets)
+ return 0;
+
+ /*
+ * We want a pc-relative branch. tgt is the instruction offset
+ * we want to jump to.
+
+ * Branch on MIPS:
+ * I: target_offset <- sign_extend(offset)
+ * I+1: PC += target_offset (delay slot)
+ *
+ * ctx->idx currently points to the branch instruction
+ * but the offset is added to the delay slot so we need
+ * to subtract 4.
+ */
+ return (ctx->offsets[tgt] & ~OFFSETS_B_CONV) -
+ (ctx->idx * 4) - 4;
+}
+
+int bpf_jit_enable __read_mostly;
+
+enum which_ebpf_reg {
+ src_reg,
+ src_reg_no_fp,
+ dst_reg,
+ dst_reg_fp_ok
+};
+
+/*
+ * For eBPF, the register mapping naturally falls out of the
+ * requirements of eBPF and the MIPS n64 ABI. We don't maintain a
+ * separate frame pointer, so BPF_REG_10 relative accesses are
+ * adjusted to be $sp relative.
+ */
+int ebpf_to_mips_reg(struct jit_ctx *ctx, const struct bpf_insn *insn,
+ enum which_ebpf_reg w)
+{
+ int ebpf_reg = (w == src_reg || w == src_reg_no_fp) ?
+ insn->src_reg : insn->dst_reg;
+
+ switch (ebpf_reg) {
+ case BPF_REG_0:
+ return MIPS_R_V0;
+ case BPF_REG_1:
+ return MIPS_R_A0;
+ case BPF_REG_2:
+ return MIPS_R_A1;
+ case BPF_REG_3:
+ return MIPS_R_A2;
+ case BPF_REG_4:
+ return MIPS_R_A3;
+ case BPF_REG_5:
+ return MIPS_R_A4;
+ case BPF_REG_6:
+ ctx->flags |= EBPF_SAVE_S0;
+ return MIPS_R_S0;
+ case BPF_REG_7:
+ ctx->flags |= EBPF_SAVE_S1;
+ return MIPS_R_S1;
+ case BPF_REG_8:
+ ctx->flags |= EBPF_SAVE_S2;
+ return MIPS_R_S2;
+ case BPF_REG_9:
+ ctx->flags |= EBPF_SAVE_S3;
+ return MIPS_R_S3;
+ case BPF_REG_10:
+ if (w == dst_reg || w == src_reg_no_fp)
+ goto bad_reg;
+ ctx->flags |= EBPF_SEEN_FP;
+ /*
+ * Needs special handling, return something that
+ * cannot be clobbered just in case.
+ */
+ return MIPS_R_ZERO;
+ case BPF_REG_AX:
+ return MIPS_R_T4;
+ default:
+bad_reg:
+ WARN(1, "Illegal bpf reg: %d\n", ebpf_reg);
+ return -EINVAL;
+ }
+}
+/*
+ * eBPF stack frame will be something like:
+ *
+ * Entry $sp ------> +--------------------------------+
+ * | $ra (optional) |
+ * +--------------------------------+
+ * | $s0 (optional) |
+ * +--------------------------------+
+ * | $s1 (optional) |
+ * +--------------------------------+
+ * | $s2 (optional) |
+ * +--------------------------------+
+ * | $s3 (optional) |
+ * +--------------------------------+
+ * | $s4 (optional) |
+ * +--------------------------------+
+ * | tmp-storage (if $ra saved) |
+ * $sp + tmp_offset --> +--------------------------------+ <--BPF_REG_10
+ * | BPF_REG_10 relative storage |
+ * | MAX_BPF_STACK (optional) |
+ * | . |
+ * | . |
+ * | . |
+ * $sp --------> +--------------------------------+
+ *
+ * If BPF_REG_10 is never referenced, then the MAX_BPF_STACK sized
+ * area is not allocated.
+ */
+static int gen_int_prologue(struct jit_ctx *ctx)
+{
+ int stack_adjust = 0;
+ int store_offset;
+ int locals_size;
+
+ if (ctx->flags & EBPF_SAVE_RA)
+ /*
+ * If RA we are doing a function call and may need
+ * extra 8-byte tmp area.
+ */
+ stack_adjust += 16;
+ if (ctx->flags & EBPF_SAVE_S0)
+ stack_adjust += 8;
+ if (ctx->flags & EBPF_SAVE_S1)
+ stack_adjust += 8;
+ if (ctx->flags & EBPF_SAVE_S2)
+ stack_adjust += 8;
+ if (ctx->flags & EBPF_SAVE_S3)
+ stack_adjust += 8;
+ if (ctx->flags & EBPF_SAVE_S4)
+ stack_adjust += 8;
+
+ BUILD_BUG_ON(MAX_BPF_STACK & 7);
+ locals_size = (ctx->flags & EBPF_SEEN_FP) ? MAX_BPF_STACK : 0;
+
+ stack_adjust += locals_size;
+ ctx->tmp_offset = locals_size;
+
+ ctx->stack_size = stack_adjust;
+
+ /*
+ * First instruction initializes the tail call count (TCC).
+ * On tail call we skip this instruction, and the TCC is
+ * passed in $v1 from the caller.
+ */
+ emit_instr(ctx, daddiu, MIPS_R_V1, MIPS_R_ZERO, MAX_TAIL_CALL_CNT);
+ if (stack_adjust)
+ emit_instr(ctx, daddiu, MIPS_R_SP, MIPS_R_SP, -stack_adjust);
+ else
+ return 0;
+
+ store_offset = stack_adjust - 8;
+
+ if (ctx->flags & EBPF_SAVE_RA) {
+ emit_instr(ctx, sd, MIPS_R_RA, store_offset, MIPS_R_SP);
+ store_offset -= 8;
+ }
+ if (ctx->flags & EBPF_SAVE_S0) {
+ emit_instr(ctx, sd, MIPS_R_S0, store_offset, MIPS_R_SP);
+ store_offset -= 8;
+ }
+ if (ctx->flags & EBPF_SAVE_S1) {
+ emit_instr(ctx, sd, MIPS_R_S1, store_offset, MIPS_R_SP);
+ store_offset -= 8;
+ }
+ if (ctx->flags & EBPF_SAVE_S2) {
+ emit_instr(ctx, sd, MIPS_R_S2, store_offset, MIPS_R_SP);
+ store_offset -= 8;
+ }
+ if (ctx->flags & EBPF_SAVE_S3) {
+ emit_instr(ctx, sd, MIPS_R_S3, store_offset, MIPS_R_SP);
+ store_offset -= 8;
+ }
+ if (ctx->flags & EBPF_SAVE_S4) {
+ emit_instr(ctx, sd, MIPS_R_S4, store_offset, MIPS_R_SP);
+ store_offset -= 8;
+ }
+
+ if ((ctx->flags & EBPF_SEEN_TC) && !(ctx->flags & EBPF_TCC_IN_V1))
+ emit_instr(ctx, daddu, MIPS_R_S4, MIPS_R_V1, MIPS_R_ZERO);
+
+ return 0;
+}
+
+static int build_int_epilogue(struct jit_ctx *ctx, int dest_reg)
+{
+ const struct bpf_prog *prog = ctx->skf;
+ int stack_adjust = ctx->stack_size;
+ int store_offset = stack_adjust - 8;
+ int r0 = MIPS_R_V0;
+
+ if (dest_reg == MIPS_R_RA &&
+ get_reg_val_type(ctx, prog->len, BPF_REG_0) == REG_32BIT_ZERO_EX)
+ /* Don't let zero extended value escape. */
+ emit_instr(ctx, sll, r0, r0, 0);
+
+ if (ctx->flags & EBPF_SAVE_RA) {
+ emit_instr(ctx, ld, MIPS_R_RA, store_offset, MIPS_R_SP);
+ store_offset -= 8;
+ }
+ if (ctx->flags & EBPF_SAVE_S0) {
+ emit_instr(ctx, ld, MIPS_R_S0, store_offset, MIPS_R_SP);
+ store_offset -= 8;
+ }
+ if (ctx->flags & EBPF_SAVE_S1) {
+ emit_instr(ctx, ld, MIPS_R_S1, store_offset, MIPS_R_SP);
+ store_offset -= 8;
+ }
+ if (ctx->flags & EBPF_SAVE_S2) {
+ emit_instr(ctx, ld, MIPS_R_S2, store_offset, MIPS_R_SP);
+ store_offset -= 8;
+ }
+ if (ctx->flags & EBPF_SAVE_S3) {
+ emit_instr(ctx, ld, MIPS_R_S3, store_offset, MIPS_R_SP);
+ store_offset -= 8;
+ }
+ if (ctx->flags & EBPF_SAVE_S4) {
+ emit_instr(ctx, ld, MIPS_R_S4, store_offset, MIPS_R_SP);
+ store_offset -= 8;
+ }
+ emit_instr(ctx, jr, dest_reg);
+
+ if (stack_adjust)
+ emit_instr(ctx, daddiu, MIPS_R_SP, MIPS_R_SP, stack_adjust);
+ else
+ emit_instr(ctx, nop);
+
+ return 0;
+}
+
+static void gen_imm_to_reg(const struct bpf_insn *insn, int reg,
+ struct jit_ctx *ctx)
+{
+ if (insn->imm >= S16_MIN && insn->imm <= S16_MAX) {
+ emit_instr(ctx, addiu, reg, MIPS_R_ZERO, insn->imm);
+ } else {
+ int lower = (s16)(insn->imm & 0xffff);
+ int upper = insn->imm - lower;
+
+ emit_instr(ctx, lui, reg, upper >> 16);
+ emit_instr(ctx, addiu, reg, reg, lower);
+ }
+
+}
+
+static int gen_imm_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
+ int idx)
+{
+ int upper_bound, lower_bound;
+ int dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
+
+ if (dst < 0)
+ return dst;
+
+ switch (BPF_OP(insn->code)) {
+ case BPF_MOV:
+ case BPF_ADD:
+ upper_bound = S16_MAX;
+ lower_bound = S16_MIN;
+ break;
+ case BPF_SUB:
+ upper_bound = -(int)S16_MIN;
+ lower_bound = -(int)S16_MAX;
+ break;
+ case BPF_AND:
+ case BPF_OR:
+ case BPF_XOR:
+ upper_bound = 0xffff;
+ lower_bound = 0;
+ break;
+ case BPF_RSH:
+ case BPF_LSH:
+ case BPF_ARSH:
+ /* Shift amounts are truncated, no need for bounds */
+ upper_bound = S32_MAX;
+ lower_bound = S32_MIN;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /*
+ * Immediate move clobbers the register, so no sign/zero
+ * extension needed.
+ */
+ if (BPF_CLASS(insn->code) == BPF_ALU64 &&
+ BPF_OP(insn->code) != BPF_MOV &&
+ get_reg_val_type(ctx, idx, insn->dst_reg) == REG_32BIT)
+ emit_instr(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32);
+ /* BPF_ALU | BPF_LSH doesn't need separate sign extension */
+ if (BPF_CLASS(insn->code) == BPF_ALU &&
+ BPF_OP(insn->code) != BPF_LSH &&
+ BPF_OP(insn->code) != BPF_MOV &&
+ get_reg_val_type(ctx, idx, insn->dst_reg) != REG_32BIT)
+ emit_instr(ctx, sll, dst, dst, 0);
+
+ if (insn->imm >= lower_bound && insn->imm <= upper_bound) {
+ /* single insn immediate case */
+ switch (BPF_OP(insn->code) | BPF_CLASS(insn->code)) {
+ case BPF_ALU64 | BPF_MOV:
+ emit_instr(ctx, daddiu, dst, MIPS_R_ZERO, insn->imm);
+ break;
+ case BPF_ALU64 | BPF_AND:
+ case BPF_ALU | BPF_AND:
+ emit_instr(ctx, andi, dst, dst, insn->imm);
+ break;
+ case BPF_ALU64 | BPF_OR:
+ case BPF_ALU | BPF_OR:
+ emit_instr(ctx, ori, dst, dst, insn->imm);
+ break;
+ case BPF_ALU64 | BPF_XOR:
+ case BPF_ALU | BPF_XOR:
+ emit_instr(ctx, xori, dst, dst, insn->imm);
+ break;
+ case BPF_ALU64 | BPF_ADD:
+ emit_instr(ctx, daddiu, dst, dst, insn->imm);
+ break;
+ case BPF_ALU64 | BPF_SUB:
+ emit_instr(ctx, daddiu, dst, dst, -insn->imm);
+ break;
+ case BPF_ALU64 | BPF_RSH:
+ emit_instr(ctx, dsrl_safe, dst, dst, insn->imm & 0x3f);
+ break;
+ case BPF_ALU | BPF_RSH:
+ emit_instr(ctx, srl, dst, dst, insn->imm & 0x1f);
+ break;
+ case BPF_ALU64 | BPF_LSH:
+ emit_instr(ctx, dsll_safe, dst, dst, insn->imm & 0x3f);
+ break;
+ case BPF_ALU | BPF_LSH:
+ emit_instr(ctx, sll, dst, dst, insn->imm & 0x1f);
+ break;
+ case BPF_ALU64 | BPF_ARSH:
+ emit_instr(ctx, dsra_safe, dst, dst, insn->imm & 0x3f);
+ break;
+ case BPF_ALU | BPF_ARSH:
+ emit_instr(ctx, sra, dst, dst, insn->imm & 0x1f);
+ break;
+ case BPF_ALU | BPF_MOV:
+ emit_instr(ctx, addiu, dst, MIPS_R_ZERO, insn->imm);
+ break;
+ case BPF_ALU | BPF_ADD:
+ emit_instr(ctx, addiu, dst, dst, insn->imm);
+ break;
+ case BPF_ALU | BPF_SUB:
+ emit_instr(ctx, addiu, dst, dst, -insn->imm);
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else {
+ /* multi insn immediate case */
+ if (BPF_OP(insn->code) == BPF_MOV) {
+ gen_imm_to_reg(insn, dst, ctx);
+ } else {
+ gen_imm_to_reg(insn, MIPS_R_AT, ctx);
+ switch (BPF_OP(insn->code) | BPF_CLASS(insn->code)) {
+ case BPF_ALU64 | BPF_AND:
+ case BPF_ALU | BPF_AND:
+ emit_instr(ctx, and, dst, dst, MIPS_R_AT);
+ break;
+ case BPF_ALU64 | BPF_OR:
+ case BPF_ALU | BPF_OR:
+ emit_instr(ctx, or, dst, dst, MIPS_R_AT);
+ break;
+ case BPF_ALU64 | BPF_XOR:
+ case BPF_ALU | BPF_XOR:
+ emit_instr(ctx, xor, dst, dst, MIPS_R_AT);
+ break;
+ case BPF_ALU64 | BPF_ADD:
+ emit_instr(ctx, daddu, dst, dst, MIPS_R_AT);
+ break;
+ case BPF_ALU64 | BPF_SUB:
+ emit_instr(ctx, dsubu, dst, dst, MIPS_R_AT);
+ break;
+ case BPF_ALU | BPF_ADD:
+ emit_instr(ctx, addu, dst, dst, MIPS_R_AT);
+ break;
+ case BPF_ALU | BPF_SUB:
+ emit_instr(ctx, subu, dst, dst, MIPS_R_AT);
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void * __must_check
+ool_skb_header_pointer(const struct sk_buff *skb, int offset,
+ int len, void *buffer)
+{
+ return skb_header_pointer(skb, offset, len, buffer);
+}
+
+static int size_to_len(const struct bpf_insn *insn)
+{
+ switch (BPF_SIZE(insn->code)) {
+ case BPF_B:
+ return 1;
+ case BPF_H:
+ return 2;
+ case BPF_W:
+ return 4;
+ case BPF_DW:
+ return 8;
+ }
+ return 0;
+}
+
+static void emit_const_to_reg(struct jit_ctx *ctx, int dst, u64 value)
+{
+ if (value >= 0xffffffffffff8000ull || value < 0x8000ull) {
+ emit_instr(ctx, daddiu, dst, MIPS_R_ZERO, (int)value);
+ } else if (value >= 0xffffffff80000000ull ||
+ (value < 0x80000000 && value > 0xffff)) {
+ emit_instr(ctx, lui, dst, (s32)(s16)(value >> 16));
+ emit_instr(ctx, ori, dst, dst, (unsigned int)(value & 0xffff));
+ } else {
+ int i;
+ bool seen_part = false;
+ int needed_shift = 0;
+
+ for (i = 0; i < 4; i++) {
+ u64 part = (value >> (16 * (3 - i))) & 0xffff;
+
+ if (seen_part && needed_shift > 0 && (part || i == 3)) {
+ emit_instr(ctx, dsll_safe, dst, dst, needed_shift);
+ needed_shift = 0;
+ }
+ if (part) {
+ if (i == 0 || (!seen_part && i < 3 && part < 0x8000)) {
+ emit_instr(ctx, lui, dst, (s32)(s16)part);
+ needed_shift = -16;
+ } else {
+ emit_instr(ctx, ori, dst,
+ seen_part ? dst : MIPS_R_ZERO,
+ (unsigned int)part);
+ }
+ seen_part = true;
+ }
+ if (seen_part)
+ needed_shift += 16;
+ }
+ }
+}
+
+static int emit_bpf_tail_call(struct jit_ctx *ctx, int this_idx)
+{
+ int off, b_off;
+
+ ctx->flags |= EBPF_SEEN_TC;
+ /*
+ * if (index >= array->map.max_entries)
+ * goto out;
+ */
+ off = offsetof(struct bpf_array, map.max_entries);
+ emit_instr(ctx, lwu, MIPS_R_T5, off, MIPS_R_A1);
+ emit_instr(ctx, sltu, MIPS_R_AT, MIPS_R_T5, MIPS_R_A2);
+ b_off = b_imm(this_idx + 1, ctx);
+ emit_instr(ctx, bne, MIPS_R_AT, MIPS_R_ZERO, b_off);
+ /*
+ * if (--TCC < 0)
+ * goto out;
+ */
+ /* Delay slot */
+ emit_instr(ctx, daddiu, MIPS_R_T5,
+ (ctx->flags & EBPF_TCC_IN_V1) ? MIPS_R_V1 : MIPS_R_S4, -1);
+ b_off = b_imm(this_idx + 1, ctx);
+ emit_instr(ctx, bltz, MIPS_R_T5, b_off);
+ /*
+ * prog = array->ptrs[index];
+ * if (prog == NULL)
+ * goto out;
+ */
+ /* Delay slot */
+ emit_instr(ctx, dsll, MIPS_R_T8, MIPS_R_A2, 3);
+ emit_instr(ctx, daddu, MIPS_R_T8, MIPS_R_T8, MIPS_R_A1);
+ off = offsetof(struct bpf_array, ptrs);
+ emit_instr(ctx, ld, MIPS_R_AT, off, MIPS_R_T8);
+ b_off = b_imm(this_idx + 1, ctx);
+ emit_instr(ctx, beq, MIPS_R_AT, MIPS_R_ZERO, b_off);
+ /* Delay slot */
+ emit_instr(ctx, nop);
+
+ /* goto *(prog->bpf_func + 4); */
+ off = offsetof(struct bpf_prog, bpf_func);
+ emit_instr(ctx, ld, MIPS_R_T9, off, MIPS_R_AT);
+ /* All systems are go... propagate TCC */
+ emit_instr(ctx, daddu, MIPS_R_V1, MIPS_R_T5, MIPS_R_ZERO);
+ /* Skip first instruction (TCC initialization) */
+ emit_instr(ctx, daddiu, MIPS_R_T9, MIPS_R_T9, 4);
+ return build_int_epilogue(ctx, MIPS_R_T9);
+}
+
+static bool use_bbit_insns(void)
+{
+ switch (current_cpu_type()) {
+ case CPU_CAVIUM_OCTEON:
+ case CPU_CAVIUM_OCTEON_PLUS:
+ case CPU_CAVIUM_OCTEON2:
+ case CPU_CAVIUM_OCTEON3:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool is_bad_offset(int b_off)
+{
+ return b_off > 0x1ffff || b_off < -0x20000;
+}
+
+/* Returns the number of insn slots consumed. */
+static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
+ int this_idx, int exit_idx)
+{
+ int src, dst, r, td, ts, mem_off, b_off;
+ bool need_swap, did_move, cmp_eq;
+ unsigned int target;
+ u64 t64;
+ s64 t64s;
+
+ switch (insn->code) {
+ case BPF_ALU64 | BPF_ADD | BPF_K: /* ALU64_IMM */
+ case BPF_ALU64 | BPF_SUB | BPF_K: /* ALU64_IMM */
+ case BPF_ALU64 | BPF_OR | BPF_K: /* ALU64_IMM */
+ case BPF_ALU64 | BPF_AND | BPF_K: /* ALU64_IMM */
+ case BPF_ALU64 | BPF_LSH | BPF_K: /* ALU64_IMM */
+ case BPF_ALU64 | BPF_RSH | BPF_K: /* ALU64_IMM */
+ case BPF_ALU64 | BPF_XOR | BPF_K: /* ALU64_IMM */
+ case BPF_ALU64 | BPF_ARSH | BPF_K: /* ALU64_IMM */
+ case BPF_ALU64 | BPF_MOV | BPF_K: /* ALU64_IMM */
+ case BPF_ALU | BPF_MOV | BPF_K: /* ALU32_IMM */
+ case BPF_ALU | BPF_ADD | BPF_K: /* ALU32_IMM */
+ case BPF_ALU | BPF_SUB | BPF_K: /* ALU32_IMM */
+ case BPF_ALU | BPF_OR | BPF_K: /* ALU64_IMM */
+ case BPF_ALU | BPF_AND | BPF_K: /* ALU64_IMM */
+ case BPF_ALU | BPF_LSH | BPF_K: /* ALU64_IMM */
+ case BPF_ALU | BPF_RSH | BPF_K: /* ALU64_IMM */
+ case BPF_ALU | BPF_XOR | BPF_K: /* ALU64_IMM */
+ case BPF_ALU | BPF_ARSH | BPF_K: /* ALU64_IMM */
+ r = gen_imm_insn(insn, ctx, this_idx);
+ if (r < 0)
+ return r;
+ break;
+ case BPF_ALU64 | BPF_MUL | BPF_K: /* ALU64_IMM */
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
+ if (dst < 0)
+ return dst;
+ if (get_reg_val_type(ctx, this_idx, insn->dst_reg) == REG_32BIT)
+ emit_instr(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32);
+ if (insn->imm == 1) /* Mult by 1 is a nop */
+ break;
+ gen_imm_to_reg(insn, MIPS_R_AT, ctx);
+ emit_instr(ctx, dmultu, MIPS_R_AT, dst);
+ emit_instr(ctx, mflo, dst);
+ break;
+ case BPF_ALU64 | BPF_NEG | BPF_K: /* ALU64_IMM */
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
+ if (dst < 0)
+ return dst;
+ if (get_reg_val_type(ctx, this_idx, insn->dst_reg) == REG_32BIT)
+ emit_instr(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32);
+ emit_instr(ctx, dsubu, dst, MIPS_R_ZERO, dst);
+ break;
+ case BPF_ALU | BPF_MUL | BPF_K: /* ALU_IMM */
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
+ if (dst < 0)
+ return dst;
+ td = get_reg_val_type(ctx, this_idx, insn->dst_reg);
+ if (td == REG_64BIT || td == REG_32BIT_ZERO_EX) {
+ /* sign extend */
+ emit_instr(ctx, sll, dst, dst, 0);
+ }
+ if (insn->imm == 1) /* Mult by 1 is a nop */
+ break;
+ gen_imm_to_reg(insn, MIPS_R_AT, ctx);
+ emit_instr(ctx, multu, dst, MIPS_R_AT);
+ emit_instr(ctx, mflo, dst);
+ break;
+ case BPF_ALU | BPF_NEG | BPF_K: /* ALU_IMM */
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
+ if (dst < 0)
+ return dst;
+ td = get_reg_val_type(ctx, this_idx, insn->dst_reg);
+ if (td == REG_64BIT || td == REG_32BIT_ZERO_EX) {
+ /* sign extend */
+ emit_instr(ctx, sll, dst, dst, 0);
+ }
+ emit_instr(ctx, subu, dst, MIPS_R_ZERO, dst);
+ break;
+ case BPF_ALU | BPF_DIV | BPF_K: /* ALU_IMM */
+ case BPF_ALU | BPF_MOD | BPF_K: /* ALU_IMM */
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
+ if (dst < 0)
+ return dst;
+ if (insn->imm == 0) { /* Div by zero */
+ b_off = b_imm(exit_idx, ctx);
+ if (is_bad_offset(b_off))
+ return -E2BIG;
+ emit_instr(ctx, beq, MIPS_R_ZERO, MIPS_R_ZERO, b_off);
+ emit_instr(ctx, addu, MIPS_R_V0, MIPS_R_ZERO, MIPS_R_ZERO);
+ }
+ td = get_reg_val_type(ctx, this_idx, insn->dst_reg);
+ if (td == REG_64BIT || td == REG_32BIT_ZERO_EX)
+ /* sign extend */
+ emit_instr(ctx, sll, dst, dst, 0);
+ if (insn->imm == 1) {
+ /* div by 1 is a nop, mod by 1 is zero */
+ if (BPF_OP(insn->code) == BPF_MOD)
+ emit_instr(ctx, addu, dst, MIPS_R_ZERO, MIPS_R_ZERO);
+ break;
+ }
+ gen_imm_to_reg(insn, MIPS_R_AT, ctx);
+ emit_instr(ctx, divu, dst, MIPS_R_AT);
+ if (BPF_OP(insn->code) == BPF_DIV)
+ emit_instr(ctx, mflo, dst);
+ else
+ emit_instr(ctx, mfhi, dst);
+ break;
+ case BPF_ALU64 | BPF_DIV | BPF_K: /* ALU_IMM */
+ case BPF_ALU64 | BPF_MOD | BPF_K: /* ALU_IMM */
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
+ if (dst < 0)
+ return dst;
+ if (insn->imm == 0) { /* Div by zero */
+ b_off = b_imm(exit_idx, ctx);
+ if (is_bad_offset(b_off))
+ return -E2BIG;
+ emit_instr(ctx, beq, MIPS_R_ZERO, MIPS_R_ZERO, b_off);
+ emit_instr(ctx, addu, MIPS_R_V0, MIPS_R_ZERO, MIPS_R_ZERO);
+ }
+ if (get_reg_val_type(ctx, this_idx, insn->dst_reg) == REG_32BIT)
+ emit_instr(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32);
+
+ if (insn->imm == 1) {
+ /* div by 1 is a nop, mod by 1 is zero */
+ if (BPF_OP(insn->code) == BPF_MOD)
+ emit_instr(ctx, addu, dst, MIPS_R_ZERO, MIPS_R_ZERO);
+ break;
+ }
+ gen_imm_to_reg(insn, MIPS_R_AT, ctx);
+ emit_instr(ctx, ddivu, dst, MIPS_R_AT);
+ if (BPF_OP(insn->code) == BPF_DIV)
+ emit_instr(ctx, mflo, dst);
+ else
+ emit_instr(ctx, mfhi, dst);
+ break;
+ case BPF_ALU64 | BPF_MOV | BPF_X: /* ALU64_REG */
+ case BPF_ALU64 | BPF_ADD | BPF_X: /* ALU64_REG */
+ case BPF_ALU64 | BPF_SUB | BPF_X: /* ALU64_REG */
+ case BPF_ALU64 | BPF_XOR | BPF_X: /* ALU64_REG */
+ case BPF_ALU64 | BPF_OR | BPF_X: /* ALU64_REG */
+ case BPF_ALU64 | BPF_AND | BPF_X: /* ALU64_REG */
+ case BPF_ALU64 | BPF_MUL | BPF_X: /* ALU64_REG */
+ case BPF_ALU64 | BPF_DIV | BPF_X: /* ALU64_REG */
+ case BPF_ALU64 | BPF_MOD | BPF_X: /* ALU64_REG */
+ case BPF_ALU64 | BPF_LSH | BPF_X: /* ALU64_REG */
+ case BPF_ALU64 | BPF_RSH | BPF_X: /* ALU64_REG */
+ case BPF_ALU64 | BPF_ARSH | BPF_X: /* ALU64_REG */
+ src = ebpf_to_mips_reg(ctx, insn, src_reg);
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
+ if (src < 0 || dst < 0)
+ return -EINVAL;
+ if (get_reg_val_type(ctx, this_idx, insn->dst_reg) == REG_32BIT)
+ emit_instr(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32);
+ did_move = false;
+ if (insn->src_reg == BPF_REG_10) {
+ if (BPF_OP(insn->code) == BPF_MOV) {
+ emit_instr(ctx, daddiu, dst, MIPS_R_SP, MAX_BPF_STACK);
+ did_move = true;
+ } else {
+ emit_instr(ctx, daddiu, MIPS_R_AT, MIPS_R_SP, MAX_BPF_STACK);
+ src = MIPS_R_AT;
+ }
+ } else if (get_reg_val_type(ctx, this_idx, insn->src_reg) == REG_32BIT) {
+ int tmp_reg = MIPS_R_AT;
+
+ if (BPF_OP(insn->code) == BPF_MOV) {
+ tmp_reg = dst;
+ did_move = true;
+ }
+ emit_instr(ctx, daddu, tmp_reg, src, MIPS_R_ZERO);
+ emit_instr(ctx, dinsu, tmp_reg, MIPS_R_ZERO, 32, 32);
+ src = MIPS_R_AT;
+ }
+ switch (BPF_OP(insn->code)) {
+ case BPF_MOV:
+ if (!did_move)
+ emit_instr(ctx, daddu, dst, src, MIPS_R_ZERO);
+ break;
+ case BPF_ADD:
+ emit_instr(ctx, daddu, dst, dst, src);
+ break;
+ case BPF_SUB:
+ emit_instr(ctx, dsubu, dst, dst, src);
+ break;
+ case BPF_XOR:
+ emit_instr(ctx, xor, dst, dst, src);
+ break;
+ case BPF_OR:
+ emit_instr(ctx, or, dst, dst, src);
+ break;
+ case BPF_AND:
+ emit_instr(ctx, and, dst, dst, src);
+ break;
+ case BPF_MUL:
+ emit_instr(ctx, dmultu, dst, src);
+ emit_instr(ctx, mflo, dst);
+ break;
+ case BPF_DIV:
+ case BPF_MOD:
+ b_off = b_imm(exit_idx, ctx);
+ if (is_bad_offset(b_off))
+ return -E2BIG;
+ emit_instr(ctx, beq, src, MIPS_R_ZERO, b_off);
+ emit_instr(ctx, movz, MIPS_R_V0, MIPS_R_ZERO, src);
+ emit_instr(ctx, ddivu, dst, src);
+ if (BPF_OP(insn->code) == BPF_DIV)
+ emit_instr(ctx, mflo, dst);
+ else
+ emit_instr(ctx, mfhi, dst);
+ break;
+ case BPF_LSH:
+ emit_instr(ctx, dsllv, dst, dst, src);
+ break;
+ case BPF_RSH:
+ emit_instr(ctx, dsrlv, dst, dst, src);
+ break;
+ case BPF_ARSH:
+ emit_instr(ctx, dsrav, dst, dst, src);
+ break;
+ default:
+ pr_err("ALU64_REG NOT HANDLED\n");
+ return -EINVAL;
+ }
+ break;
+ case BPF_ALU | BPF_MOV | BPF_X: /* ALU_REG */
+ case BPF_ALU | BPF_ADD | BPF_X: /* ALU_REG */
+ case BPF_ALU | BPF_SUB | BPF_X: /* ALU_REG */
+ case BPF_ALU | BPF_XOR | BPF_X: /* ALU_REG */
+ case BPF_ALU | BPF_OR | BPF_X: /* ALU_REG */
+ case BPF_ALU | BPF_AND | BPF_X: /* ALU_REG */
+ case BPF_ALU | BPF_MUL | BPF_X: /* ALU_REG */
+ case BPF_ALU | BPF_DIV | BPF_X: /* ALU_REG */
+ case BPF_ALU | BPF_MOD | BPF_X: /* ALU_REG */
+ case BPF_ALU | BPF_LSH | BPF_X: /* ALU_REG */
+ case BPF_ALU | BPF_RSH | BPF_X: /* ALU_REG */
+ src = ebpf_to_mips_reg(ctx, insn, src_reg_no_fp);
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
+ if (src < 0 || dst < 0)
+ return -EINVAL;
+ td = get_reg_val_type(ctx, this_idx, insn->dst_reg);
+ if (td == REG_64BIT || td == REG_32BIT_ZERO_EX) {
+ /* sign extend */
+ emit_instr(ctx, sll, dst, dst, 0);
+ }
+ did_move = false;
+ ts = get_reg_val_type(ctx, this_idx, insn->src_reg);
+ if (ts == REG_64BIT || ts == REG_32BIT_ZERO_EX) {
+ int tmp_reg = MIPS_R_AT;
+
+ if (BPF_OP(insn->code) == BPF_MOV) {
+ tmp_reg = dst;
+ did_move = true;
+ }
+ /* sign extend */
+ emit_instr(ctx, sll, tmp_reg, src, 0);
+ src = MIPS_R_AT;
+ }
+ switch (BPF_OP(insn->code)) {
+ case BPF_MOV:
+ if (!did_move)
+ emit_instr(ctx, addu, dst, src, MIPS_R_ZERO);
+ break;
+ case BPF_ADD:
+ emit_instr(ctx, addu, dst, dst, src);
+ break;
+ case BPF_SUB:
+ emit_instr(ctx, subu, dst, dst, src);
+ break;
+ case BPF_XOR:
+ emit_instr(ctx, xor, dst, dst, src);
+ break;
+ case BPF_OR:
+ emit_instr(ctx, or, dst, dst, src);
+ break;
+ case BPF_AND:
+ emit_instr(ctx, and, dst, dst, src);
+ break;
+ case BPF_MUL:
+ emit_instr(ctx, mul, dst, dst, src);
+ break;
+ case BPF_DIV:
+ case BPF_MOD:
+ b_off = b_imm(exit_idx, ctx);
+ if (is_bad_offset(b_off))
+ return -E2BIG;
+ emit_instr(ctx, beq, src, MIPS_R_ZERO, b_off);
+ emit_instr(ctx, movz, MIPS_R_V0, MIPS_R_ZERO, src);
+ emit_instr(ctx, divu, dst, src);
+ if (BPF_OP(insn->code) == BPF_DIV)
+ emit_instr(ctx, mflo, dst);
+ else
+ emit_instr(ctx, mfhi, dst);
+ break;
+ case BPF_LSH:
+ emit_instr(ctx, sllv, dst, dst, src);
+ break;
+ case BPF_RSH:
+ emit_instr(ctx, srlv, dst, dst, src);
+ break;
+ default:
+ pr_err("ALU_REG NOT HANDLED\n");
+ return -EINVAL;
+ }
+ break;
+ case BPF_JMP | BPF_EXIT:
+ if (this_idx + 1 < exit_idx) {
+ b_off = b_imm(exit_idx, ctx);
+ if (is_bad_offset(b_off))
+ return -E2BIG;
+ emit_instr(ctx, beq, MIPS_R_ZERO, MIPS_R_ZERO, b_off);
+ emit_instr(ctx, nop);
+ }
+ break;
+ case BPF_JMP | BPF_JEQ | BPF_K: /* JMP_IMM */
+ case BPF_JMP | BPF_JNE | BPF_K: /* JMP_IMM */
+ cmp_eq = (BPF_OP(insn->code) == BPF_JEQ);
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg_fp_ok);
+ if (dst < 0)
+ return dst;
+ if (insn->imm == 0) {
+ src = MIPS_R_ZERO;
+ } else {
+ gen_imm_to_reg(insn, MIPS_R_AT, ctx);
+ src = MIPS_R_AT;
+ }
+ goto jeq_common;
+ case BPF_JMP | BPF_JEQ | BPF_X: /* JMP_REG */
+ case BPF_JMP | BPF_JNE | BPF_X:
+ case BPF_JMP | BPF_JSGT | BPF_X:
+ case BPF_JMP | BPF_JSGE | BPF_X:
+ case BPF_JMP | BPF_JGT | BPF_X:
+ case BPF_JMP | BPF_JGE | BPF_X:
+ case BPF_JMP | BPF_JSET | BPF_X:
+ src = ebpf_to_mips_reg(ctx, insn, src_reg_no_fp);
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
+ if (src < 0 || dst < 0)
+ return -EINVAL;
+ td = get_reg_val_type(ctx, this_idx, insn->dst_reg);
+ ts = get_reg_val_type(ctx, this_idx, insn->src_reg);
+ if (td == REG_32BIT && ts != REG_32BIT) {
+ emit_instr(ctx, sll, MIPS_R_AT, src, 0);
+ src = MIPS_R_AT;
+ } else if (ts == REG_32BIT && td != REG_32BIT) {
+ emit_instr(ctx, sll, MIPS_R_AT, dst, 0);
+ dst = MIPS_R_AT;
+ }
+ if (BPF_OP(insn->code) == BPF_JSET) {
+ emit_instr(ctx, and, MIPS_R_AT, dst, src);
+ cmp_eq = false;
+ dst = MIPS_R_AT;
+ src = MIPS_R_ZERO;
+ } else if (BPF_OP(insn->code) == BPF_JSGT) {
+ emit_instr(ctx, dsubu, MIPS_R_AT, dst, src);
+ if ((insn + 1)->code == (BPF_JMP | BPF_EXIT) && insn->off == 1) {
+ b_off = b_imm(exit_idx, ctx);
+ if (is_bad_offset(b_off))
+ return -E2BIG;
+ emit_instr(ctx, blez, MIPS_R_AT, b_off);
+ emit_instr(ctx, nop);
+ return 2; /* We consumed the exit. */
+ }
+ b_off = b_imm(this_idx + insn->off + 1, ctx);
+ if (is_bad_offset(b_off))
+ return -E2BIG;
+ emit_instr(ctx, bgtz, MIPS_R_AT, b_off);
+ emit_instr(ctx, nop);
+ break;
+ } else if (BPF_OP(insn->code) == BPF_JSGE) {
+ emit_instr(ctx, slt, MIPS_R_AT, dst, src);
+ cmp_eq = true;
+ dst = MIPS_R_AT;
+ src = MIPS_R_ZERO;
+ } else if (BPF_OP(insn->code) == BPF_JGT) {
+ /* dst or src could be AT */
+ emit_instr(ctx, dsubu, MIPS_R_T8, dst, src);
+ emit_instr(ctx, sltu, MIPS_R_AT, dst, src);
+ /* SP known to be non-zero, movz becomes boolean not */
+ emit_instr(ctx, movz, MIPS_R_T9, MIPS_R_SP, MIPS_R_T8);
+ emit_instr(ctx, movn, MIPS_R_T9, MIPS_R_ZERO, MIPS_R_T8);
+ emit_instr(ctx, or, MIPS_R_AT, MIPS_R_T9, MIPS_R_AT);
+ cmp_eq = true;
+ dst = MIPS_R_AT;
+ src = MIPS_R_ZERO;
+ } else if (BPF_OP(insn->code) == BPF_JGE) {
+ emit_instr(ctx, sltu, MIPS_R_AT, dst, src);
+ cmp_eq = true;
+ dst = MIPS_R_AT;
+ src = MIPS_R_ZERO;
+ } else { /* JNE/JEQ case */
+ cmp_eq = (BPF_OP(insn->code) == BPF_JEQ);
+ }
+jeq_common:
+ /*
+ * If the next insn is EXIT and we are jumping arround
+ * only it, invert the sense of the compare and
+ * conditionally jump to the exit. Poor man's branch
+ * chaining.
+ */
+ if ((insn + 1)->code == (BPF_JMP | BPF_EXIT) && insn->off == 1) {
+ b_off = b_imm(exit_idx, ctx);
+ if (is_bad_offset(b_off)) {
+ target = j_target(ctx, exit_idx);
+ if (target == (unsigned int)-1)
+ return -E2BIG;
+ cmp_eq = !cmp_eq;
+ b_off = 4 * 3;
+ if (!(ctx->offsets[this_idx] & OFFSETS_B_CONV)) {
+ ctx->offsets[this_idx] |= OFFSETS_B_CONV;
+ ctx->long_b_conversion = 1;
+ }
+ }
+
+ if (cmp_eq)
+ emit_instr(ctx, bne, dst, src, b_off);
+ else
+ emit_instr(ctx, beq, dst, src, b_off);
+ emit_instr(ctx, nop);
+ if (ctx->offsets[this_idx] & OFFSETS_B_CONV) {
+ emit_instr(ctx, j, target);
+ emit_instr(ctx, nop);
+ }
+ return 2; /* We consumed the exit. */
+ }
+ b_off = b_imm(this_idx + insn->off + 1, ctx);
+ if (is_bad_offset(b_off)) {
+ target = j_target(ctx, this_idx + insn->off + 1);
+ if (target == (unsigned int)-1)
+ return -E2BIG;
+ cmp_eq = !cmp_eq;
+ b_off = 4 * 3;
+ if (!(ctx->offsets[this_idx] & OFFSETS_B_CONV)) {
+ ctx->offsets[this_idx] |= OFFSETS_B_CONV;
+ ctx->long_b_conversion = 1;
+ }
+ }
+
+ if (cmp_eq)
+ emit_instr(ctx, beq, dst, src, b_off);
+ else
+ emit_instr(ctx, bne, dst, src, b_off);
+ emit_instr(ctx, nop);
+ if (ctx->offsets[this_idx] & OFFSETS_B_CONV) {
+ emit_instr(ctx, j, target);
+ emit_instr(ctx, nop);
+ }
+ break;
+ case BPF_JMP | BPF_JSGT | BPF_K: /* JMP_IMM */
+ case BPF_JMP | BPF_JSGE | BPF_K: /* JMP_IMM */
+ cmp_eq = (BPF_OP(insn->code) == BPF_JSGE);
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg_fp_ok);
+ if (dst < 0)
+ return dst;
+
+ if (insn->imm == 0) {
+ if ((insn + 1)->code == (BPF_JMP | BPF_EXIT) && insn->off == 1) {
+ b_off = b_imm(exit_idx, ctx);
+ if (is_bad_offset(b_off))
+ return -E2BIG;
+ if (cmp_eq)
+ emit_instr(ctx, bltz, dst, b_off);
+ else
+ emit_instr(ctx, blez, dst, b_off);
+ emit_instr(ctx, nop);
+ return 2; /* We consumed the exit. */
+ }
+ b_off = b_imm(this_idx + insn->off + 1, ctx);
+ if (is_bad_offset(b_off))
+ return -E2BIG;
+ if (cmp_eq)
+ emit_instr(ctx, bgez, dst, b_off);
+ else
+ emit_instr(ctx, bgtz, dst, b_off);
+ emit_instr(ctx, nop);
+ break;
+ }
+ /*
+ * only "LT" compare available, so we must use imm + 1
+ * to generate "GT"
+ */
+ t64s = insn->imm + (cmp_eq ? 0 : 1);
+ if (t64s >= S16_MIN && t64s <= S16_MAX) {
+ emit_instr(ctx, slti, MIPS_R_AT, dst, (int)t64s);
+ src = MIPS_R_AT;
+ dst = MIPS_R_ZERO;
+ cmp_eq = true;
+ goto jeq_common;
+ }
+ emit_const_to_reg(ctx, MIPS_R_AT, (u64)t64s);
+ emit_instr(ctx, slt, MIPS_R_AT, dst, MIPS_R_AT);
+ src = MIPS_R_AT;
+ dst = MIPS_R_ZERO;
+ cmp_eq = true;
+ goto jeq_common;
+
+ case BPF_JMP | BPF_JGT | BPF_K:
+ case BPF_JMP | BPF_JGE | BPF_K:
+ cmp_eq = (BPF_OP(insn->code) == BPF_JGE);
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg_fp_ok);
+ if (dst < 0)
+ return dst;
+ /*
+ * only "LT" compare available, so we must use imm + 1
+ * to generate "GT"
+ */
+ t64s = (u64)(u32)(insn->imm) + (cmp_eq ? 0 : 1);
+ if (t64s >= 0 && t64s <= S16_MAX) {
+ emit_instr(ctx, sltiu, MIPS_R_AT, dst, (int)t64s);
+ src = MIPS_R_AT;
+ dst = MIPS_R_ZERO;
+ cmp_eq = true;
+ goto jeq_common;
+ }
+ emit_const_to_reg(ctx, MIPS_R_AT, (u64)t64s);
+ emit_instr(ctx, sltu, MIPS_R_AT, dst, MIPS_R_AT);
+ src = MIPS_R_AT;
+ dst = MIPS_R_ZERO;
+ cmp_eq = true;
+ goto jeq_common;
+
+ case BPF_JMP | BPF_JSET | BPF_K: /* JMP_IMM */
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg_fp_ok);
+ if (dst < 0)
+ return dst;
+
+ if (use_bbit_insns() && hweight32((u32)insn->imm) == 1) {
+ if ((insn + 1)->code == (BPF_JMP | BPF_EXIT) && insn->off == 1) {
+ b_off = b_imm(exit_idx, ctx);
+ if (is_bad_offset(b_off))
+ return -E2BIG;
+ emit_instr(ctx, bbit0, dst, ffs((u32)insn->imm) - 1, b_off);
+ emit_instr(ctx, nop);
+ return 2; /* We consumed the exit. */
+ }
+ b_off = b_imm(this_idx + insn->off + 1, ctx);
+ if (is_bad_offset(b_off))
+ return -E2BIG;
+ emit_instr(ctx, bbit1, dst, ffs((u32)insn->imm) - 1, b_off);
+ emit_instr(ctx, nop);
+ break;
+ }
+ t64 = (u32)insn->imm;
+ emit_const_to_reg(ctx, MIPS_R_AT, t64);
+ emit_instr(ctx, and, MIPS_R_AT, dst, MIPS_R_AT);
+ src = MIPS_R_AT;
+ dst = MIPS_R_ZERO;
+ cmp_eq = false;
+ goto jeq_common;
+
+ case BPF_JMP | BPF_JA:
+ /*
+ * Prefer relative branch for easier debugging, but
+ * fall back if needed.
+ */
+ b_off = b_imm(this_idx + insn->off + 1, ctx);
+ if (is_bad_offset(b_off)) {
+ target = j_target(ctx, this_idx + insn->off + 1);
+ if (target == (unsigned int)-1)
+ return -E2BIG;
+ emit_instr(ctx, j, target);
+ } else {
+ emit_instr(ctx, b, b_off);
+ }
+ emit_instr(ctx, nop);
+ break;
+ case BPF_LD | BPF_DW | BPF_IMM:
+ if (insn->src_reg != 0)
+ return -EINVAL;
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
+ if (dst < 0)
+ return dst;
+ t64 = ((u64)(u32)insn->imm) | ((u64)(insn + 1)->imm << 32);
+ emit_const_to_reg(ctx, dst, t64);
+ return 2; /* Double slot insn */
+
+ case BPF_JMP | BPF_CALL:
+ ctx->flags |= EBPF_SAVE_RA;
+ t64s = (s64)insn->imm + (s64)__bpf_call_base;
+ emit_const_to_reg(ctx, MIPS_R_T9, (u64)t64s);
+ emit_instr(ctx, jalr, MIPS_R_RA, MIPS_R_T9);
+ /* delay slot */
+ emit_instr(ctx, nop);
+ break;
+
+ case BPF_JMP | BPF_TAIL_CALL:
+ if (emit_bpf_tail_call(ctx, this_idx))
+ return -EINVAL;
+ break;
+
+ case BPF_LD | BPF_B | BPF_ABS:
+ case BPF_LD | BPF_H | BPF_ABS:
+ case BPF_LD | BPF_W | BPF_ABS:
+ case BPF_LD | BPF_DW | BPF_ABS:
+ ctx->flags |= EBPF_SAVE_RA;
+
+ gen_imm_to_reg(insn, MIPS_R_A1, ctx);
+ emit_instr(ctx, addiu, MIPS_R_A2, MIPS_R_ZERO, size_to_len(insn));
+
+ if (insn->imm < 0) {
+ emit_const_to_reg(ctx, MIPS_R_T9, (u64)bpf_internal_load_pointer_neg_helper);
+ } else {
+ emit_const_to_reg(ctx, MIPS_R_T9, (u64)ool_skb_header_pointer);
+ emit_instr(ctx, daddiu, MIPS_R_A3, MIPS_R_SP, ctx->tmp_offset);
+ }
+ goto ld_skb_common;
+
+ case BPF_LD | BPF_B | BPF_IND:
+ case BPF_LD | BPF_H | BPF_IND:
+ case BPF_LD | BPF_W | BPF_IND:
+ case BPF_LD | BPF_DW | BPF_IND:
+ ctx->flags |= EBPF_SAVE_RA;
+ src = ebpf_to_mips_reg(ctx, insn, src_reg_no_fp);
+ if (src < 0)
+ return src;
+ ts = get_reg_val_type(ctx, this_idx, insn->src_reg);
+ if (ts == REG_32BIT_ZERO_EX) {
+ /* sign extend */
+ emit_instr(ctx, sll, MIPS_R_A1, src, 0);
+ src = MIPS_R_A1;
+ }
+ if (insn->imm >= S16_MIN && insn->imm <= S16_MAX) {
+ emit_instr(ctx, daddiu, MIPS_R_A1, src, insn->imm);
+ } else {
+ gen_imm_to_reg(insn, MIPS_R_AT, ctx);
+ emit_instr(ctx, daddu, MIPS_R_A1, MIPS_R_AT, src);
+ }
+ /* truncate to 32-bit int */
+ emit_instr(ctx, sll, MIPS_R_A1, MIPS_R_A1, 0);
+ emit_instr(ctx, daddiu, MIPS_R_A3, MIPS_R_SP, ctx->tmp_offset);
+ emit_instr(ctx, slt, MIPS_R_AT, MIPS_R_A1, MIPS_R_ZERO);
+
+ emit_const_to_reg(ctx, MIPS_R_T8, (u64)bpf_internal_load_pointer_neg_helper);
+ emit_const_to_reg(ctx, MIPS_R_T9, (u64)ool_skb_header_pointer);
+ emit_instr(ctx, addiu, MIPS_R_A2, MIPS_R_ZERO, size_to_len(insn));
+ emit_instr(ctx, movn, MIPS_R_T9, MIPS_R_T8, MIPS_R_AT);
+
+ld_skb_common:
+ emit_instr(ctx, jalr, MIPS_R_RA, MIPS_R_T9);
+ /* delay slot move */
+ emit_instr(ctx, daddu, MIPS_R_A0, MIPS_R_S0, MIPS_R_ZERO);
+
+ /* Check the error value */
+ b_off = b_imm(exit_idx, ctx);
+ if (is_bad_offset(b_off)) {
+ target = j_target(ctx, exit_idx);
+ if (target == (unsigned int)-1)
+ return -E2BIG;
+
+ if (!(ctx->offsets[this_idx] & OFFSETS_B_CONV)) {
+ ctx->offsets[this_idx] |= OFFSETS_B_CONV;
+ ctx->long_b_conversion = 1;
+ }
+ emit_instr(ctx, bne, MIPS_R_V0, MIPS_R_ZERO, 4 * 3);
+ emit_instr(ctx, nop);
+ emit_instr(ctx, j, target);
+ emit_instr(ctx, nop);
+ } else {
+ emit_instr(ctx, beq, MIPS_R_V0, MIPS_R_ZERO, b_off);
+ emit_instr(ctx, nop);
+ }
+
+#ifdef __BIG_ENDIAN
+ need_swap = false;
+#else
+ need_swap = true;
+#endif
+ dst = MIPS_R_V0;
+ switch (BPF_SIZE(insn->code)) {
+ case BPF_B:
+ emit_instr(ctx, lbu, dst, 0, MIPS_R_V0);
+ break;
+ case BPF_H:
+ emit_instr(ctx, lhu, dst, 0, MIPS_R_V0);
+ if (need_swap)
+ emit_instr(ctx, wsbh, dst, dst);
+ break;
+ case BPF_W:
+ emit_instr(ctx, lw, dst, 0, MIPS_R_V0);
+ if (need_swap) {
+ emit_instr(ctx, wsbh, dst, dst);
+ emit_instr(ctx, rotr, dst, dst, 16);
+ }
+ break;
+ case BPF_DW:
+ emit_instr(ctx, ld, dst, 0, MIPS_R_V0);
+ if (need_swap) {
+ emit_instr(ctx, dsbh, dst, dst);
+ emit_instr(ctx, dshd, dst, dst);
+ }
+ break;
+ }
+
+ break;
+ case BPF_ALU | BPF_END | BPF_FROM_BE:
+ case BPF_ALU | BPF_END | BPF_FROM_LE:
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
+ if (dst < 0)
+ return dst;
+ td = get_reg_val_type(ctx, this_idx, insn->dst_reg);
+ if (insn->imm == 64 && td == REG_32BIT)
+ emit_instr(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32);
+
+ if (insn->imm != 64 &&
+ (td == REG_64BIT || td == REG_32BIT_ZERO_EX)) {
+ /* sign extend */
+ emit_instr(ctx, sll, dst, dst, 0);
+ }
+
+#ifdef __BIG_ENDIAN
+ need_swap = (BPF_SRC(insn->code) == BPF_FROM_LE);
+#else
+ need_swap = (BPF_SRC(insn->code) == BPF_FROM_BE);
+#endif
+ if (insn->imm == 16) {
+ if (need_swap)
+ emit_instr(ctx, wsbh, dst, dst);
+ emit_instr(ctx, andi, dst, dst, 0xffff);
+ } else if (insn->imm == 32) {
+ if (need_swap) {
+ emit_instr(ctx, wsbh, dst, dst);
+ emit_instr(ctx, rotr, dst, dst, 16);
+ }
+ } else { /* 64-bit*/
+ if (need_swap) {
+ emit_instr(ctx, dsbh, dst, dst);
+ emit_instr(ctx, dshd, dst, dst);
+ }
+ }
+ break;
+
+ case BPF_ST | BPF_B | BPF_MEM:
+ case BPF_ST | BPF_H | BPF_MEM:
+ case BPF_ST | BPF_W | BPF_MEM:
+ case BPF_ST | BPF_DW | BPF_MEM:
+ if (insn->dst_reg == BPF_REG_10) {
+ ctx->flags |= EBPF_SEEN_FP;
+ dst = MIPS_R_SP;
+ mem_off = insn->off + MAX_BPF_STACK;
+ } else {
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
+ if (dst < 0)
+ return dst;
+ mem_off = insn->off;
+ }
+ gen_imm_to_reg(insn, MIPS_R_AT, ctx);
+ switch (BPF_SIZE(insn->code)) {
+ case BPF_B:
+ emit_instr(ctx, sb, MIPS_R_AT, mem_off, dst);
+ break;
+ case BPF_H:
+ emit_instr(ctx, sh, MIPS_R_AT, mem_off, dst);
+ break;
+ case BPF_W:
+ emit_instr(ctx, sw, MIPS_R_AT, mem_off, dst);
+ break;
+ case BPF_DW:
+ emit_instr(ctx, sd, MIPS_R_AT, mem_off, dst);
+ break;
+ }
+ break;
+
+ case BPF_LDX | BPF_B | BPF_MEM:
+ case BPF_LDX | BPF_H | BPF_MEM:
+ case BPF_LDX | BPF_W | BPF_MEM:
+ case BPF_LDX | BPF_DW | BPF_MEM:
+ if (insn->src_reg == BPF_REG_10) {
+ ctx->flags |= EBPF_SEEN_FP;
+ src = MIPS_R_SP;
+ mem_off = insn->off + MAX_BPF_STACK;
+ } else {
+ src = ebpf_to_mips_reg(ctx, insn, src_reg_no_fp);
+ if (src < 0)
+ return src;
+ mem_off = insn->off;
+ }
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
+ if (dst < 0)
+ return dst;
+ switch (BPF_SIZE(insn->code)) {
+ case BPF_B:
+ emit_instr(ctx, lbu, dst, mem_off, src);
+ break;
+ case BPF_H:
+ emit_instr(ctx, lhu, dst, mem_off, src);
+ break;
+ case BPF_W:
+ emit_instr(ctx, lw, dst, mem_off, src);
+ break;
+ case BPF_DW:
+ emit_instr(ctx, ld, dst, mem_off, src);
+ break;
+ }
+ break;
+
+ case BPF_STX | BPF_B | BPF_MEM:
+ case BPF_STX | BPF_H | BPF_MEM:
+ case BPF_STX | BPF_W | BPF_MEM:
+ case BPF_STX | BPF_DW | BPF_MEM:
+ case BPF_STX | BPF_W | BPF_XADD:
+ case BPF_STX | BPF_DW | BPF_XADD:
+ if (insn->dst_reg == BPF_REG_10) {
+ ctx->flags |= EBPF_SEEN_FP;
+ dst = MIPS_R_SP;
+ mem_off = insn->off + MAX_BPF_STACK;
+ } else {
+ dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
+ if (dst < 0)
+ return dst;
+ mem_off = insn->off;
+ }
+ src = ebpf_to_mips_reg(ctx, insn, src_reg_no_fp);
+ if (src < 0)
+ return dst;
+ if (BPF_MODE(insn->code) == BPF_XADD) {
+ switch (BPF_SIZE(insn->code)) {
+ case BPF_W:
+ if (get_reg_val_type(ctx, this_idx, insn->src_reg) == REG_32BIT) {
+ emit_instr(ctx, sll, MIPS_R_AT, src, 0);
+ src = MIPS_R_AT;
+ }
+ emit_instr(ctx, ll, MIPS_R_T8, mem_off, dst);
+ emit_instr(ctx, addu, MIPS_R_T8, MIPS_R_T8, src);
+ emit_instr(ctx, sc, MIPS_R_T8, mem_off, dst);
+ /*
+ * On failure back up to LL (-4
+ * instructions of 4 bytes each
+ */
+ emit_instr(ctx, beq, MIPS_R_T8, MIPS_R_ZERO, -4 * 4);
+ emit_instr(ctx, nop);
+ break;
+ case BPF_DW:
+ if (get_reg_val_type(ctx, this_idx, insn->src_reg) == REG_32BIT) {
+ emit_instr(ctx, daddu, MIPS_R_AT, src, MIPS_R_ZERO);
+ emit_instr(ctx, dinsu, MIPS_R_AT, MIPS_R_ZERO, 32, 32);
+ src = MIPS_R_AT;
+ }
+ emit_instr(ctx, lld, MIPS_R_T8, mem_off, dst);
+ emit_instr(ctx, daddu, MIPS_R_T8, MIPS_R_T8, src);
+ emit_instr(ctx, scd, MIPS_R_T8, mem_off, dst);
+ emit_instr(ctx, beq, MIPS_R_T8, MIPS_R_ZERO, -4 * 4);
+ emit_instr(ctx, nop);
+ break;
+ }
+ } else { /* BPF_MEM */
+ switch (BPF_SIZE(insn->code)) {
+ case BPF_B:
+ emit_instr(ctx, sb, src, mem_off, dst);
+ break;
+ case BPF_H:
+ emit_instr(ctx, sh, src, mem_off, dst);
+ break;
+ case BPF_W:
+ emit_instr(ctx, sw, src, mem_off, dst);
+ break;
+ case BPF_DW:
+ if (get_reg_val_type(ctx, this_idx, insn->src_reg) == REG_32BIT) {
+ emit_instr(ctx, daddu, MIPS_R_AT, src, MIPS_R_ZERO);
+ emit_instr(ctx, dinsu, MIPS_R_AT, MIPS_R_ZERO, 32, 32);
+ src = MIPS_R_AT;
+ }
+ emit_instr(ctx, sd, src, mem_off, dst);
+ break;
+ }
+ }
+ break;
+
+ default:
+ pr_err("NOT HANDLED %d - (%02x)\n",
+ this_idx, (unsigned int)insn->code);
+ return -EINVAL;
+ }
+ return 1;
+}
+
+#define RVT_VISITED_MASK 0xc000000000000000ull
+#define RVT_FALL_THROUGH 0x4000000000000000ull
+#define RVT_BRANCH_TAKEN 0x8000000000000000ull
+#define RVT_DONE (RVT_FALL_THROUGH | RVT_BRANCH_TAKEN)
+
+static int build_int_body(struct jit_ctx *ctx)
+{
+ const struct bpf_prog *prog = ctx->skf;
+ const struct bpf_insn *insn;
+ int i, r;
+
+ for (i = 0; i < prog->len; ) {
+ insn = prog->insnsi + i;
+ if ((ctx->reg_val_types[i] & RVT_VISITED_MASK) == 0) {
+ /* dead instruction, don't emit it. */
+ i++;
+ continue;
+ }
+
+ if (ctx->target == NULL)
+ ctx->offsets[i] = (ctx->offsets[i] & OFFSETS_B_CONV) | (ctx->idx * 4);
+
+ r = build_one_insn(insn, ctx, i, prog->len);
+ if (r < 0)
+ return r;
+ i += r;
+ }
+ /* epilogue offset */
+ if (ctx->target == NULL)
+ ctx->offsets[i] = ctx->idx * 4;
+
+ /*
+ * All exits have an offset of the epilogue, some offsets may
+ * not have been set due to banch-around threading, so set
+ * them now.
+ */
+ if (ctx->target == NULL)
+ for (i = 0; i < prog->len; i++) {
+ insn = prog->insnsi + i;
+ if (insn->code == (BPF_JMP | BPF_EXIT))
+ ctx->offsets[i] = ctx->idx * 4;
+ }
+ return 0;
+}
+
+/* return the last idx processed, or negative for error */
+static int reg_val_propagate_range(struct jit_ctx *ctx, u64 initial_rvt,
+ int start_idx, bool follow_taken)
+{
+ const struct bpf_prog *prog = ctx->skf;
+ const struct bpf_insn *insn;
+ u64 exit_rvt = initial_rvt;
+ u64 *rvt = ctx->reg_val_types;
+ int idx;
+ int reg;
+
+ for (idx = start_idx; idx < prog->len; idx++) {
+ rvt[idx] = (rvt[idx] & RVT_VISITED_MASK) | exit_rvt;
+ insn = prog->insnsi + idx;
+ switch (BPF_CLASS(insn->code)) {
+ case BPF_ALU:
+ switch (BPF_OP(insn->code)) {
+ case BPF_ADD:
+ case BPF_SUB:
+ case BPF_MUL:
+ case BPF_DIV:
+ case BPF_OR:
+ case BPF_AND:
+ case BPF_LSH:
+ case BPF_RSH:
+ case BPF_NEG:
+ case BPF_MOD:
+ case BPF_XOR:
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT);
+ break;
+ case BPF_MOV:
+ if (BPF_SRC(insn->code)) {
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT);
+ } else {
+ /* IMM to REG move*/
+ if (insn->imm >= 0)
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT_POS);
+ else
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT);
+ }
+ break;
+ case BPF_END:
+ if (insn->imm == 64)
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_64BIT);
+ else if (insn->imm == 32)
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT);
+ else /* insn->imm == 16 */
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT_POS);
+ break;
+ }
+ rvt[idx] |= RVT_DONE;
+ break;
+ case BPF_ALU64:
+ switch (BPF_OP(insn->code)) {
+ case BPF_MOV:
+ if (BPF_SRC(insn->code)) {
+ /* REG to REG move*/
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_64BIT);
+ } else {
+ /* IMM to REG move*/
+ if (insn->imm >= 0)
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT_POS);
+ else
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_64BIT_32BIT);
+ }
+ break;
+ default:
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_64BIT);
+ }
+ rvt[idx] |= RVT_DONE;
+ break;
+ case BPF_LD:
+ switch (BPF_SIZE(insn->code)) {
+ case BPF_DW:
+ if (BPF_MODE(insn->code) == BPF_IMM) {
+ s64 val;
+
+ val = (s64)((u32)insn->imm | ((u64)(insn + 1)->imm << 32));
+ if (val > 0 && val <= S32_MAX)
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT_POS);
+ else if (val >= S32_MIN && val <= S32_MAX)
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_64BIT_32BIT);
+ else
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_64BIT);
+ rvt[idx] |= RVT_DONE;
+ idx++;
+ } else {
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_64BIT);
+ }
+ break;
+ case BPF_B:
+ case BPF_H:
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT_POS);
+ break;
+ case BPF_W:
+ if (BPF_MODE(insn->code) == BPF_IMM)
+ set_reg_val_type(&exit_rvt, insn->dst_reg,
+ insn->imm >= 0 ? REG_32BIT_POS : REG_32BIT);
+ else
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT);
+ break;
+ }
+ rvt[idx] |= RVT_DONE;
+ break;
+ case BPF_LDX:
+ switch (BPF_SIZE(insn->code)) {
+ case BPF_DW:
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_64BIT);
+ break;
+ case BPF_B:
+ case BPF_H:
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT_POS);
+ break;
+ case BPF_W:
+ set_reg_val_type(&exit_rvt, insn->dst_reg, REG_32BIT);
+ break;
+ }
+ rvt[idx] |= RVT_DONE;
+ break;
+ case BPF_JMP:
+ switch (BPF_OP(insn->code)) {
+ case BPF_EXIT:
+ rvt[idx] = RVT_DONE | exit_rvt;
+ rvt[prog->len] = exit_rvt;
+ return idx;
+ case BPF_JA:
+ rvt[idx] |= RVT_DONE;
+ idx += insn->off;
+ break;
+ case BPF_JEQ:
+ case BPF_JGT:
+ case BPF_JGE:
+ case BPF_JSET:
+ case BPF_JNE:
+ case BPF_JSGT:
+ case BPF_JSGE:
+ if (follow_taken) {
+ rvt[idx] |= RVT_BRANCH_TAKEN;
+ idx += insn->off;
+ follow_taken = false;
+ } else {
+ rvt[idx] |= RVT_FALL_THROUGH;
+ }
+ break;
+ case BPF_CALL:
+ set_reg_val_type(&exit_rvt, BPF_REG_0, REG_64BIT);
+ /* Upon call return, argument registers are clobbered. */
+ for (reg = BPF_REG_0; reg <= BPF_REG_5; reg++)
+ set_reg_val_type(&exit_rvt, reg, REG_64BIT);
+
+ rvt[idx] |= RVT_DONE;
+ break;
+ default:
+ WARN(1, "Unhandled BPF_JMP case.\n");
+ rvt[idx] |= RVT_DONE;
+ break;
+ }
+ break;
+ default:
+ rvt[idx] |= RVT_DONE;
+ break;
+ }
+ }
+ return idx;
+}
+
+/*
+ * Track the value range (i.e. 32-bit vs. 64-bit) of each register at
+ * each eBPF insn. This allows unneeded sign and zero extension
+ * operations to be omitted.
+ *
+ * Doesn't handle yet confluence of control paths with conflicting
+ * ranges, but it is good enough for most sane code.
+ */
+static int reg_val_propagate(struct jit_ctx *ctx)
+{
+ const struct bpf_prog *prog = ctx->skf;
+ u64 exit_rvt;
+ int reg;
+ int i;
+
+ /*
+ * 11 registers * 3 bits/reg leaves top bits free for other
+ * uses. Bit-62..63 used to see if we have visited an insn.
+ */
+ exit_rvt = 0;
+
+ /* Upon entry, argument registers are 64-bit. */
+ for (reg = BPF_REG_1; reg <= BPF_REG_5; reg++)
+ set_reg_val_type(&exit_rvt, reg, REG_64BIT);
+
+ /*
+ * First follow all conditional branches on the fall-through
+ * edge of control flow..
+ */
+ reg_val_propagate_range(ctx, exit_rvt, 0, false);
+restart_search:
+ /*
+ * Then repeatedly find the first conditional branch where
+ * both edges of control flow have not been taken, and follow
+ * the branch taken edge. We will end up restarting the
+ * search once per conditional branch insn.
+ */
+ for (i = 0; i < prog->len; i++) {
+ u64 rvt = ctx->reg_val_types[i];
+
+ if ((rvt & RVT_VISITED_MASK) == RVT_DONE ||
+ (rvt & RVT_VISITED_MASK) == 0)
+ continue;
+ if ((rvt & RVT_VISITED_MASK) == RVT_FALL_THROUGH) {
+ reg_val_propagate_range(ctx, rvt & ~RVT_VISITED_MASK, i, true);
+ } else { /* RVT_BRANCH_TAKEN */
+ WARN(1, "Unexpected RVT_BRANCH_TAKEN case.\n");
+ reg_val_propagate_range(ctx, rvt & ~RVT_VISITED_MASK, i, false);
+ }
+ goto restart_search;
+ }
+ /*
+ * Eventually all conditional branches have been followed on
+ * both branches and we are done. Any insn that has not been
+ * visited at this point is dead.
+ */
+
+ return 0;
+}
+
+static void jit_fill_hole(void *area, unsigned int size)
+{
+ u32 *p;
+
+ /* We are guaranteed to have aligned memory. */
+ for (p = area; size >= sizeof(u32); size -= sizeof(u32))
+ uasm_i_break(&p, BRK_BUG); /* Increments p */
+}
+
+struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
+{
+ struct bpf_prog *orig_prog = prog;
+ bool tmp_blinded = false;
+ struct bpf_prog *tmp;
+ struct bpf_binary_header *header = NULL;
+ struct jit_ctx ctx;
+ unsigned int image_size;
+ u8 *image_ptr;
+
+ if (!bpf_jit_enable || !cpu_has_mips64r2)
+ return prog;
+
+ tmp = bpf_jit_blind_constants(prog);
+ /* If blinding was requested and we failed during blinding,
+ * we must fall back to the interpreter.
+ */
+ if (IS_ERR(tmp))
+ return orig_prog;
+ if (tmp != prog) {
+ tmp_blinded = true;
+ prog = tmp;
+ }
+
+ memset(&ctx, 0, sizeof(ctx));
+
+ ctx.offsets = kcalloc(prog->len + 1, sizeof(*ctx.offsets), GFP_KERNEL);
+ if (ctx.offsets == NULL)
+ goto out_err;
+
+ ctx.reg_val_types = kcalloc(prog->len + 1, sizeof(*ctx.reg_val_types), GFP_KERNEL);
+ if (ctx.reg_val_types == NULL)
+ goto out_err;
+
+ ctx.skf = prog;
+
+ if (reg_val_propagate(&ctx))
+ goto out_err;
+
+ /*
+ * First pass discovers used resources and instruction offsets
+ * assuming short branches are used.
+ */
+ if (build_int_body(&ctx))
+ goto out_err;
+
+ /*
+ * If no calls are made (EBPF_SAVE_RA), then tail call count
+ * in $v1, else we must save in n$s4.
+ */
+ if (ctx.flags & EBPF_SEEN_TC) {
+ if (ctx.flags & EBPF_SAVE_RA)
+ ctx.flags |= EBPF_SAVE_S4;
+ else
+ ctx.flags |= EBPF_TCC_IN_V1;
+ }
+
+ /*
+ * Second pass generates offsets, if any branches are out of
+ * range a jump-around long sequence is generated, and we have
+ * to try again from the beginning to generate the new
+ * offsets. This is done until no additional conversions are
+ * necessary.
+ */
+ do {
+ ctx.idx = 0;
+ ctx.gen_b_offsets = 1;
+ ctx.long_b_conversion = 0;
+ if (gen_int_prologue(&ctx))
+ goto out_err;
+ if (build_int_body(&ctx))
+ goto out_err;
+ if (build_int_epilogue(&ctx, MIPS_R_RA))
+ goto out_err;
+ } while (ctx.long_b_conversion);
+
+ image_size = 4 * ctx.idx;
+
+ header = bpf_jit_binary_alloc(image_size, &image_ptr,
+ sizeof(u32), jit_fill_hole);
+ if (header == NULL)
+ goto out_err;
+
+ ctx.target = (u32 *)image_ptr;
+
+ /* Third pass generates the code */
+ ctx.idx = 0;
+ if (gen_int_prologue(&ctx))
+ goto out_err;
+ if (build_int_body(&ctx))
+ goto out_err;
+ if (build_int_epilogue(&ctx, MIPS_R_RA))
+ goto out_err;
+
+ /* Update the icache */
+ flush_icache_range((unsigned long)ctx.target,
+ (unsigned long)(ctx.target + ctx.idx * sizeof(u32)));
+
+ if (bpf_jit_enable > 1)
+ /* Dump JIT code */
+ bpf_jit_dump(prog->len, image_size, 2, ctx.target);
+
+ bpf_jit_binary_lock_ro(header);
+ prog->bpf_func = (void *)ctx.target;
+ prog->jited = 1;
+ prog->jited_len = image_size;
+out_normal:
+ if (tmp_blinded)
+ bpf_jit_prog_release_other(prog, prog == orig_prog ?
+ tmp : orig_prog);
+ kfree(ctx.offsets);
+ kfree(ctx.reg_val_types);
+
+ return prog;
+
+out_err:
+ prog = orig_prog;
+ if (header)
+ bpf_jit_binary_free(header);
+ goto out_normal;
+}
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index bd67ac74fe2d..9632436d74d7 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -28,16 +28,15 @@ EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
static int __init pcibios_set_cache_line_size(void)
{
- struct cpuinfo_mips *c = &current_cpu_data;
unsigned int lsize;
/*
* Set PCI cacheline size to that of the highest level in the
* cache hierarchy.
*/
- lsize = c->dcache.linesz;
- lsize = c->scache.linesz ? : lsize;
- lsize = c->tcache.linesz ? : lsize;
+ lsize = cpu_dcache_line_size();
+ lsize = cpu_scache_line_size() ? : lsize;
+ lsize = cpu_tcache_line_size() ? : lsize;
BUG_ON(!lsize);
diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c
index 094a0ee4af46..9be8b08ae46b 100644
--- a/arch/mips/ralink/mt7620.c
+++ b/arch/mips/ralink/mt7620.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/bug.h>
#include <asm/mipsregs.h>
#include <asm/mach-ralink/ralink_regs.h>
diff --git a/arch/mips/vdso/gettimeofday.c b/arch/mips/vdso/gettimeofday.c
index 974276e828b2..e2690d7ca4dd 100644
--- a/arch/mips/vdso/gettimeofday.c
+++ b/arch/mips/vdso/gettimeofday.c
@@ -35,7 +35,8 @@ static __always_inline long gettimeofday_fallback(struct timeval *_tv,
" syscall\n"
: "=r" (ret), "=r" (error)
: "r" (tv), "r" (tz), "r" (nr)
- : "memory");
+ : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
+ "$14", "$15", "$24", "$25", "hi", "lo", "memory");
return error ? -ret : ret;
}
@@ -55,7 +56,8 @@ static __always_inline long clock_gettime_fallback(clockid_t _clkid,
" syscall\n"
: "=r" (ret), "=r" (error)
: "r" (clkid), "r" (ts), "r" (nr)
- : "memory");
+ : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
+ "$14", "$15", "$24", "$25", "hi", "lo", "memory");
return error ? -ret : ret;
}
diff --git a/arch/mn10300/include/asm/bug.h b/arch/mn10300/include/asm/bug.h
index aa6a38886391..811414fb002d 100644
--- a/arch/mn10300/include/asm/bug.h
+++ b/arch/mn10300/include/asm/bug.h
@@ -21,7 +21,7 @@ do { \
asm volatile( \
" syscall 15 \n" \
"0: \n" \
- " .section __bug_table,\"a\" \n" \
+ " .section __bug_table,\"aw\" \n" \
" .long 0b,%0,%1 \n" \
" .previous \n" \
: \
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 531da9eb8f43..dda1f558ef35 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -47,6 +47,9 @@ config PARISC
and later HP3000 series). The PA-RISC Linux project home page is
at <http://www.parisc-linux.org/>.
+config CPU_BIG_ENDIAN
+ def_bool y
+
config MMU
def_bool y
diff --git a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig
index 143d02652792..ccc109761f44 100644
--- a/arch/parisc/configs/712_defconfig
+++ b/arch/parisc/configs/712_defconfig
@@ -1,11 +1,9 @@
-CONFIG_EXPERIMENTAL=y
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_KALLSYMS_ALL=y
CONFIG_SLAB=y
@@ -14,7 +12,6 @@ CONFIG_OPROFILE=m
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
CONFIG_PA7100LC=y
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_GSC_LASI=y
@@ -32,11 +29,9 @@ CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
-# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=m
# CONFIG_IPV6 is not set
CONFIG_NETFILTER=y
-CONFIG_IP_NF_QUEUE=m
CONFIG_LLC2=m
CONFIG_NET_PKTGEN=m
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
@@ -65,21 +60,20 @@ CONFIG_MD_LINEAR=m
CONFIG_MD_RAID0=m
CONFIG_MD_RAID1=m
CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
CONFIG_BONDING=m
+CONFIG_DUMMY=m
CONFIG_TUN=m
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=m
CONFIG_LASI_82596=y
CONFIG_PPP=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
CONFIG_PPP_MPPE=m
CONFIG_PPPOE=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
# CONFIG_KEYBOARD_HIL_OLD is not set
CONFIG_MOUSE_SERIAL=m
+CONFIG_LEGACY_PTY_COUNT=64
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=17
@@ -88,22 +82,17 @@ CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_MUX is not set
CONFIG_PDC_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=64
CONFIG_PRINTER=m
CONFIG_PPDEV=m
# CONFIG_HW_RANDOM is not set
CONFIG_RAW_DRIVER=y
# CONFIG_HWMON is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
CONFIG_FB=y
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y
CONFIG_DUMMY_CONSOLE_COLUMNS=128
CONFIG_DUMMY_CONSOLE_ROWS=48
CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
@@ -111,13 +100,9 @@ CONFIG_LOGO=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SEQUENCER=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-CONFIG_SND_SEQUENCER_OSS=y
CONFIG_SND_HARMONY=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
CONFIG_JFS_FS=m
CONFIG_XFS_FS=m
CONFIG_AUTOFS4_FS=y
@@ -130,14 +115,10 @@ CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_UFS_FS=m
CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=m
CONFIG_NFSD_V4=y
-CONFIG_RPCSEC_GSS_SPKM3=m
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
CONFIG_CIFS=m
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_737=m
@@ -177,21 +158,16 @@ CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
CONFIG_NLS_UTF8=m
-CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_MUTEXES=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST6=m
@@ -200,6 +176,7 @@ CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_DEFLATE=m
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
-CONFIG_LIBCRC32C=m
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig
index 1a4f776b49b8..5acb93dcaabf 100644
--- a/arch/parisc/configs/a500_defconfig
+++ b/arch/parisc/configs/a500_defconfig
@@ -1,13 +1,10 @@
-CONFIG_EXPERIMENTAL=y
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_EXPERT=y
CONFIG_KALLSYMS_ALL=y
CONFIG_SLAB=y
@@ -16,7 +13,6 @@ CONFIG_OPROFILE=m
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
CONFIG_PA8X00=y
CONFIG_64BIT=y
CONFIG_SMP=y
@@ -43,21 +39,17 @@ CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
-# CONFIG_INET_LRO is not set
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m
CONFIG_IPV6_TUNNEL=m
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
-CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_ECN=m
CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_RAW=m
@@ -70,7 +62,6 @@ CONFIG_IP6_NF_MATCH_OPTS=m
CONFIG_IP6_NF_MATCH_HL=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_TARGET_LOG=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
@@ -94,7 +85,6 @@ CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
CONFIG_BLK_DEV_SR=y
CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_ISCSI_ATTRS=m
CONFIG_SCSI_SYM53C8XX_2=y
CONFIG_SCSI_QLOGIC_1280=m
@@ -106,43 +96,38 @@ CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
CONFIG_FUSION=y
CONFIG_FUSION_SPI=m
-CONFIG_FUSION_FC=m
CONFIG_FUSION_CTL=m
CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
CONFIG_BONDING=m
+CONFIG_DUMMY=m
CONFIG_TUN=m
-CONFIG_NET_ETHERNET=y
-CONFIG_NET_VENDOR_3COM=y
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_3C589=m
CONFIG_VORTEX=m
CONFIG_TYPHOON=m
+CONFIG_ACENIC=m
+CONFIG_ACENIC_OMIT_TIGON_I=y
+CONFIG_PCNET32=m
+CONFIG_TIGON3=m
CONFIG_NET_TULIP=y
CONFIG_DE2104X=m
CONFIG_TULIP=y
CONFIG_TULIP_MMIO=y
CONFIG_PCMCIA_XIRCOM=m
CONFIG_HP100=m
-CONFIG_NET_PCI=y
-CONFIG_PCNET32=m
CONFIG_E100=m
-CONFIG_ACENIC=m
-CONFIG_ACENIC_OMIT_TIGON_I=y
CONFIG_E1000=m
-CONFIG_TIGON3=m
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
CONFIG_PCMCIA_SMC91C92=m
CONFIG_PCMCIA_XIRC2PS=m
CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_CS=m
@@ -151,7 +136,6 @@ CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_PDC_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set
CONFIG_RAW_DRIVER=y
# CONFIG_HWMON is not set
@@ -160,7 +144,6 @@ CONFIG_AGP_PARISC=y
# CONFIG_STI_CONSOLE is not set
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
CONFIG_JFS_FS=m
CONFIG_XFS_FS=m
CONFIG_AUTOFS4_FS=y
@@ -173,13 +156,9 @@ CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_UFS_FS=m
CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-CONFIG_NFS_V4=y
+CONFIG_NFS_V4=m
CONFIG_NFSD=m
CONFIG_NFSD_V4=y
-CONFIG_RPCSEC_GSS_SPKM3=m
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
CONFIG_CIFS=m
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_850=m
@@ -187,17 +166,12 @@ CONFIG_NLS_ASCII=m
CONFIG_NLS_ISO8859_1=m
CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_UTF8=m
-CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_FS=y
CONFIG_HEADERS_CHECK=y
-CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_BLOWFISH=m
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
-CONFIG_LIBCRC32C=m
diff --git a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig
index f1a0c25bef8d..83ffd161aec5 100644
--- a/arch/parisc/configs/b180_defconfig
+++ b/arch/parisc/configs/b180_defconfig
@@ -3,7 +3,6 @@ CONFIG_SYSVIPC=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_SLAB=y
CONFIG_MODULES=y
@@ -25,8 +24,6 @@ CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_LRO is not set
-CONFIG_IPV6=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
@@ -53,10 +50,9 @@ CONFIG_MD_LINEAR=y
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_LASI_82596=y
CONFIG_NET_TULIP=y
CONFIG_TULIP=y
+CONFIG_LASI_82596=y
CONFIG_PPP=y
CONFIG_INPUT_EVDEV=y
# CONFIG_KEYBOARD_HIL_OLD is not set
@@ -71,40 +67,31 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_PRINTER=y
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
CONFIG_FB=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SEQUENCER=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-CONFIG_SND_SEQUENCER_OSS=y
CONFIG_SND_HARMONY=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
CONFIG_AUTOFS4_FS=y
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
-CONFIG_SMB_FS=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_850=m
CONFIG_NLS_ASCII=m
CONFIG_NLS_ISO8859_1=m
CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_UTF8=m
-CONFIG_MAGIC_SYSRQ=y
CONFIG_HEADERS_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_SECURITY=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig
index 8e8f0e34f817..0764d3971cf6 100644
--- a/arch/parisc/configs/c3000_defconfig
+++ b/arch/parisc/configs/c3000_defconfig
@@ -1,12 +1,9 @@
-CONFIG_EXPERIMENTAL=y
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_EXPERT=y
CONFIG_KALLSYMS_ALL=y
CONFIG_SLAB=y
@@ -15,7 +12,6 @@ CONFIG_OPROFILE=m
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
CONFIG_PA8X00=y
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_GSC is not set
@@ -31,13 +27,11 @@ CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
CONFIG_INET6_IPCOMP=m
CONFIG_IPV6_TUNNEL=m
CONFIG_NETFILTER=y
CONFIG_NETFILTER_DEBUG=y
-CONFIG_IP_NF_QUEUE=m
CONFIG_NET_PKTGEN=m
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
@@ -50,13 +44,11 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
CONFIG_IDE=y
CONFIG_BLK_DEV_IDECD=y
CONFIG_BLK_DEV_NS87415=y
-CONFIG_PATA_SIL680=m
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
CONFIG_BLK_DEV_SR=y
CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_ISCSI_ATTRS=m
CONFIG_SCSI_SYM53C8XX_2=y
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
@@ -76,28 +68,23 @@ CONFIG_FUSION=y
CONFIG_FUSION_SPI=m
CONFIG_FUSION_CTL=m
CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
CONFIG_BONDING=m
+CONFIG_DUMMY=m
CONFIG_TUN=m
-CONFIG_NET_ETHERNET=y
+CONFIG_ACENIC=m
+CONFIG_TIGON3=m
CONFIG_NET_TULIP=y
CONFIG_DE2104X=m
CONFIG_TULIP=y
CONFIG_TULIP_MMIO=y
-CONFIG_NET_PCI=y
CONFIG_E100=m
-CONFIG_ACENIC=m
CONFIG_E1000=m
-CONFIG_TIGON3=m
CONFIG_PPP=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
CONFIG_PPPOE=m
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1600
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
# CONFIG_KEYBOARD_ATKBD is not set
# CONFIG_MOUSE_PS2 is not set
CONFIG_SERIO=m
@@ -111,7 +98,6 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_HW_RANDOM is not set
CONFIG_RAW_DRIVER=y
# CONFIG_HWMON is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
CONFIG_FB=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
@@ -121,9 +107,6 @@ CONFIG_LOGO=y
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SEQUENCER=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-CONFIG_SND_SEQUENCER_OSS=y
CONFIG_SND_AD1889=y
CONFIG_USB_HIDDEV=y
CONFIG_USB=y
@@ -139,7 +122,6 @@ CONFIG_USB_MICROTEK=m
CONFIG_USB_LEGOTOWER=m
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
CONFIG_XFS_FS=m
CONFIG_AUTOFS4_FS=y
CONFIG_ISO9660_FS=y
@@ -149,7 +131,6 @@ CONFIG_VFAT_FS=m
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
@@ -159,18 +140,13 @@ CONFIG_NLS_ASCII=m
CONFIG_NLS_ISO8859_1=m
CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_UTF8=m
-CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_FS=y
CONFIG_HEADERS_CHECK=y
-CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_MD5=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_DES=m
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
-CONFIG_LIBCRC32C=m
diff --git a/arch/parisc/configs/c8000_defconfig b/arch/parisc/configs/c8000_defconfig
index f6a4c016304b..088ab948a5ca 100644
--- a/arch/parisc/configs/c8000_defconfig
+++ b/arch/parisc/configs/c8000_defconfig
@@ -1,16 +1,13 @@
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
+# CONFIG_CROSS_MEMORY_ATTACH is not set
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
-CONFIG_RD_BZIP2=y
-CONFIG_RD_LZMA=y
-CONFIG_RD_LZO=y
CONFIG_EXPERT=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_SLAB=y
@@ -23,7 +20,6 @@ CONFIG_PA8X00=y
CONFIG_64BIT=y
CONFIG_SMP=y
CONFIG_PREEMPT=y
-# CONFIG_CROSS_MEMORY_ATTACH is not set
CONFIG_IOMMU_CCIO=y
CONFIG_PCI=y
CONFIG_PCI_LBA=y
@@ -146,7 +142,6 @@ CONFIG_FB_FOREIGN_ENDIAN=y
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y
# CONFIG_FB_STI is not set
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_LCD_CLASS_DEVICE is not set
# CONFIG_BACKLIGHT_GENERIC is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
@@ -157,12 +152,9 @@ CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_CLUT224 is not set
CONFIG_SOUND=m
CONFIG_SND=m
+CONFIG_SND_VERBOSE_PRINTK=y
CONFIG_SND_SEQUENCER=m
CONFIG_SND_SEQ_DUMMY=m
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-CONFIG_SND_SEQUENCER_OSS=y
-CONFIG_SND_VERBOSE_PRINTK=y
CONFIG_SND_AD1889=m
# CONFIG_SND_USB is not set
# CONFIG_SND_GSC is not set
@@ -174,8 +166,6 @@ CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT4_FS=m
CONFIG_REISERFS_FS=m
CONFIG_REISERFS_PROC_INFO=y
CONFIG_XFS_FS=m
@@ -238,11 +228,8 @@ CONFIG_DEBUG_SLAB=y
CONFIG_DEBUG_SLAB_LEAK=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DEBUG_STACKOVERFLOW=y
-CONFIG_LOCKUP_DETECTOR=y
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
CONFIG_PANIC_ON_OOPS=y
CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_PROVE_RCU_DELAY=y
CONFIG_DEBUG_BLOCK_EXT_DEVT=y
CONFIG_LATENCYTOP=y
CONFIG_KEYS=y
diff --git a/arch/parisc/configs/default_defconfig b/arch/parisc/configs/default_defconfig
index 310b6657e4ac..52c9050a7c5c 100644
--- a/arch/parisc/configs/default_defconfig
+++ b/arch/parisc/configs/default_defconfig
@@ -1,11 +1,9 @@
-CONFIG_EXPERIMENTAL=y
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_KALLSYMS_ALL=y
CONFIG_SLAB=y
@@ -41,9 +39,7 @@ CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
-# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=m
-CONFIG_IPV6=y
CONFIG_INET6_AH=y
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
@@ -82,26 +78,23 @@ CONFIG_MD_RAID1=y
CONFIG_MD_RAID10=y
CONFIG_BLK_DEV_DM=y
CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
CONFIG_BONDING=m
+CONFIG_DUMMY=m
CONFIG_TUN=m
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=m
-CONFIG_LASI_82596=y
-CONFIG_NET_TULIP=y
-CONFIG_TULIP=y
-CONFIG_NET_PCI=y
CONFIG_ACENIC=y
CONFIG_TIGON3=y
-CONFIG_NET_PCMCIA=y
+CONFIG_NET_TULIP=y
+CONFIG_TULIP=y
+CONFIG_LASI_82596=y
CONFIG_PPP=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
CONFIG_PPPOE=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
# CONFIG_KEYBOARD_HIL_OLD is not set
CONFIG_MOUSE_SERIAL=y
+CONFIG_LEGACY_PTY_COUNT=64
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_CS=y
@@ -109,31 +102,24 @@ CONFIG_SERIAL_8250_NR_UARTS=17
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_LEGACY_PTY_COUNT=64
CONFIG_PRINTER=m
CONFIG_PPDEV=m
# CONFIG_HW_RANDOM is not set
# CONFIG_HWMON is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
CONFIG_FB=y
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y
CONFIG_DUMMY_CONSOLE_COLUMNS=128
CONFIG_DUMMY_CONSOLE_ROWS=48
CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x16=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
# CONFIG_LOGO_LINUX_CLUT224 is not set
CONFIG_SOUND=y
CONFIG_SND=y
-CONFIG_SND_SEQUENCER=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-CONFIG_SND_SEQUENCER_OSS=y
CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_SEQUENCER=y
CONFIG_SND_AD1889=y
CONFIG_SND_HARMONY=y
CONFIG_HID_GYRATION=y
@@ -141,7 +127,6 @@ CONFIG_HID_NTRIG=y
CONFIG_HID_PANTHERLORD=y
CONFIG_HID_PETALYNX=y
CONFIG_HID_SAMSUNG=y
-CONFIG_HID_SONY=y
CONFIG_HID_SUNPLUS=y
CONFIG_HID_TOPSEED=y
CONFIG_USB=y
@@ -150,21 +135,15 @@ CONFIG_USB_OHCI_HCD=y
CONFIG_USB_UHCI_HCD=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_AUTOFS_FS=y
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
CONFIG_VFAT_FS=y
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
CONFIG_NFSD_V4=y
-CONFIG_RPCSEC_GSS_SPKM3=m
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
CONFIG_CIFS=m
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=m
@@ -204,30 +183,24 @@ CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
CONFIG_NLS_UTF8=y
-CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_FS=y
CONFIG_HEADERS_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_MUTEXES=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_KEYS=y
-CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
CONFIG_LIBCRC32C=m
+CONFIG_FONTS=y
diff --git a/arch/parisc/configs/generic-32bit_defconfig b/arch/parisc/configs/generic-32bit_defconfig
index 8688ba7f5966..37ae4b57c001 100644
--- a/arch/parisc/configs/generic-32bit_defconfig
+++ b/arch/parisc/configs/generic-32bit_defconfig
@@ -2,15 +2,11 @@ CONFIG_LOCALVERSION="-32bit"
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
-CONFIG_FHANDLE=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
CONFIG_BLK_DEV_INITRD=y
-CONFIG_RD_BZIP2=y
-CONFIG_RD_LZMA=y
-CONFIG_RD_LZO=y
CONFIG_EXPERT=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_PERF_EVENTS=y
@@ -49,7 +45,6 @@ CONFIG_INET_ESP=m
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=m
CONFIG_LLC2=m
# CONFIG_WIRELESS is not set
@@ -149,10 +144,8 @@ CONFIG_PRINTER=m
CONFIG_PPDEV=m
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
-CONFIG_POWER_SUPPLY=y
# CONFIG_HWMON is not set
CONFIG_AGP=y
-CONFIG_VIDEO_OUTPUT_CONTROL=y
CONFIG_FB=y
CONFIG_FB_FOREIGN_ENDIAN=y
CONFIG_FB_MODE_HELPERS=y
@@ -169,11 +162,8 @@ CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_CLUT224 is not set
CONFIG_SOUND=m
CONFIG_SND=m
-CONFIG_SND_SEQUENCER=m
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-CONFIG_SND_SEQUENCER_OSS=y
CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_SEQUENCER=m
CONFIG_SND_AD1889=m
CONFIG_SND_HARMONY=m
CONFIG_HIDRAW=y
@@ -223,12 +213,7 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_SECURITY=y
CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_SECURITY=y
-CONFIG_EXT4_FS=y
-CONFIG_XFS_FS=m
-CONFIG_XFS_QUOTA=y
-CONFIG_XFS_RT=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QFMT_V2=y
@@ -293,15 +278,12 @@ CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_DEBUG_SHIRQ=y
CONFIG_DETECT_HUNG_TASK=y
-CONFIG_TIMER_STATS=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
-CONFIG_RCU_CPU_STALL_INFO=y
CONFIG_LATENCYTOP=y
CONFIG_LKDTM=m
CONFIG_KEYS=y
-CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_MD5=y
@@ -320,7 +302,6 @@ CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_DEFLATE=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRC_CCITT=m
CONFIG_CRC_T10DIF=y
CONFIG_FONTS=y
diff --git a/arch/parisc/configs/generic-64bit_defconfig b/arch/parisc/configs/generic-64bit_defconfig
index c564e6e1fa23..d39e7f821aba 100644
--- a/arch/parisc/configs/generic-64bit_defconfig
+++ b/arch/parisc/configs/generic-64bit_defconfig
@@ -8,10 +8,11 @@ CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
-# CONFIG_UTS_NS is not set
-# CONFIG_IPC_NS is not set
-# CONFIG_PID_NS is not set
-# CONFIG_NET_NS is not set
+CONFIG_CGROUPS=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_SWAP=y
+CONFIG_CGROUP_PIDS=y
+CONFIG_CPUSETS=y
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -52,7 +53,6 @@ CONFIG_INET_ESP=m
CONFIG_INET_XFRM_MODE_TRANSPORT=m
CONFIG_INET_XFRM_MODE_TUNNEL=m
CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_LRO=m
CONFIG_INET_DIAG=m
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_ADVANCED is not set
@@ -84,7 +84,6 @@ CONFIG_PATA_SIL680=y
CONFIG_ATA_GENERIC=y
CONFIG_MD=y
CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
CONFIG_BLK_DEV_DM=m
CONFIG_DM_RAID=m
CONFIG_DM_UEVENT=y
@@ -138,21 +137,21 @@ CONFIG_QLGE=m
# CONFIG_NET_VENDOR_TI is not set
# CONFIG_NET_VENDOR_VIA is not set
# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_MDIO_BITBANG=m
CONFIG_PHYLIB=y
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
CONFIG_BROADCOM_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_DAVICOM_PHY=m
CONFIG_ICPLUS_PHY=m
-CONFIG_REALTEK_PHY=m
+CONFIG_LSI_ET1011C_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_MARVELL_PHY=m
CONFIG_NATIONAL_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_REALTEK_PHY=m
+CONFIG_SMSC_PHY=m
CONFIG_STE10XP=m
-CONFIG_LSI_ET1011C_PHY=m
-CONFIG_MDIO_BITBANG=m
+CONFIG_VITESSE_PHY=m
CONFIG_SLIP=m
CONFIG_SLIP_COMPRESSED=y
CONFIG_SLIP_SMART=y
@@ -166,10 +165,8 @@ CONFIG_INPUT_MISC=y
CONFIG_SERIO_SERPORT=m
# CONFIG_HP_SDC is not set
CONFIG_SERIO_RAW=m
-CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_NOZOMI=m
-# CONFIG_DEVKMEM is not set
CONFIG_SERIAL_8250=y
# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
CONFIG_SERIAL_8250_CONSOLE=y
@@ -207,10 +204,8 @@ CONFIG_AGP=y
CONFIG_AGP_PARISC=y
CONFIG_DRM=y
CONFIG_DRM_RADEON=y
-CONFIG_DRM_RADEON_UMS=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_MODE_HELPERS=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_BACKLIGHT_GENERIC is not set
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
CONFIG_LOGO=y
@@ -246,8 +241,6 @@ CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_SECURITY=y
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_SECURITY=y
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_XFS_FS=m
CONFIG_BTRFS_FS=m
CONFIG_QUOTA=y
@@ -286,27 +279,16 @@ CONFIG_DEBUG_FS=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_STACKOVERFLOW=y
-CONFIG_LOCKUP_DETECTOR=y
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
-CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
# CONFIG_SCHED_DEBUG is not set
-CONFIG_TIMER_STATS=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_FCRYPT=m
CONFIG_CRYPTO_DEFLATE=m
# CONFIG_CRYPTO_HW is not set
CONFIG_CRC_CCITT=m
CONFIG_LIBCRC32C=y
-CONFIG_XZ_DEC_X86=y
-CONFIG_XZ_DEC_POWERPC=y
-CONFIG_XZ_DEC_IA64=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_ARMTHUMB=y
-CONFIG_XZ_DEC_SPARC=y
diff --git a/arch/parisc/include/asm/bug.h b/arch/parisc/include/asm/bug.h
index d2742273a685..07ea467f22fc 100644
--- a/arch/parisc/include/asm/bug.h
+++ b/arch/parisc/include/asm/bug.h
@@ -27,7 +27,7 @@
do { \
asm volatile("\n" \
"1:\t" PARISC_BUG_BREAK_ASM "\n" \
- "\t.pushsection __bug_table,\"a\"\n" \
+ "\t.pushsection __bug_table,\"aw\"\n" \
"2:\t" ASM_WORD_INSN "1b, %c0\n" \
"\t.short %c1, %c2\n" \
"\t.org 2b+%c3\n" \
@@ -50,7 +50,7 @@
do { \
asm volatile("\n" \
"1:\t" PARISC_BUG_BREAK_ASM "\n" \
- "\t.pushsection __bug_table,\"a\"\n" \
+ "\t.pushsection __bug_table,\"aw\"\n" \
"2:\t" ASM_WORD_INSN "1b, %c0\n" \
"\t.short %c1, %c2\n" \
"\t.org 2b+%c3\n" \
@@ -64,7 +64,7 @@
do { \
asm volatile("\n" \
"1:\t" PARISC_BUG_BREAK_ASM "\n" \
- "\t.pushsection __bug_table,\"a\"\n" \
+ "\t.pushsection __bug_table,\"aw\"\n" \
"2:\t" ASM_WORD_INSN "1b\n" \
"\t.short %c0\n" \
"\t.org 2b+%c1\n" \
diff --git a/arch/parisc/include/asm/pdcpat.h b/arch/parisc/include/asm/pdcpat.h
index 32e105fb8adb..e3c0586260d8 100644
--- a/arch/parisc/include/asm/pdcpat.h
+++ b/arch/parisc/include/asm/pdcpat.h
@@ -150,7 +150,7 @@
#define PDC_PAT_MEM_SETGM 9L /* Set Good Memory value */
#define PDC_PAT_MEM_ADD_PAGE 10L /* ADDs a page to the cell */
#define PDC_PAT_MEM_ADDRESS 11L /* Get Physical Location From */
- /* Memory Address */
+ /* Memory Address */
#define PDC_PAT_MEM_GET_TXT_SIZE 12L /* Get Formatted Text Size */
#define PDC_PAT_MEM_GET_PD_TXT 13L /* Get PD Formatted Text */
#define PDC_PAT_MEM_GET_CELL_TXT 14L /* Get Cell Formatted Text */
@@ -228,6 +228,17 @@ struct pdc_pat_mem_read_pd_retinfo { /* PDC_PAT_MEM/PDC_PAT_MEM_PD_READ */
unsigned long pdt_entries;
};
+struct pdc_pat_mem_phys_mem_location { /* PDC_PAT_MEM/PDC_PAT_MEM_ADDRESS */
+ u64 cabinet:8;
+ u64 ign1:8;
+ u64 ign2:8;
+ u64 cell_slot:8;
+ u64 ign3:8;
+ u64 dimm_slot:8; /* DIMM slot, e.g. 0x1A, 0x2B, show user hex value! */
+ u64 ign4:8;
+ u64 source:4; /* for mem: always 0x07 */
+ u64 source_detail:4; /* for mem: always 0x04 (SIMM or DIMM) */
+};
struct pdc_pat_pd_addr_map_entry {
unsigned char entry_type; /* 1 = Memory Descriptor Entry Type */
@@ -319,6 +330,9 @@ extern int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret,
extern int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret,
unsigned long *pdt_entries_ptr, unsigned long count,
unsigned long offset);
+extern int pdc_pat_mem_get_dimm_phys_location(
+ struct pdc_pat_mem_phys_mem_location *pret,
+ unsigned long phys_addr);
#endif /* __ASSEMBLY__ */
diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h
index 88fe0aad4390..bc208136bbb2 100644
--- a/arch/parisc/include/asm/thread_info.h
+++ b/arch/parisc/include/asm/thread_info.h
@@ -34,7 +34,7 @@ struct thread_info {
/* thread information allocation */
-#define THREAD_SIZE_ORDER 2 /* PA-RISC requires at least 16k stack */
+#define THREAD_SIZE_ORDER 3 /* PA-RISC requires at least 32k stack */
/* Be sure to hunt all references to this down when you change the size of
* the kernel stack */
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
diff --git a/arch/parisc/include/uapi/asm/ioctls.h b/arch/parisc/include/uapi/asm/ioctls.h
index 674c68a5bbd0..d0e3321403be 100644
--- a/arch/parisc/include/uapi/asm/ioctls.h
+++ b/arch/parisc/include/uapi/asm/ioctls.h
@@ -60,7 +60,7 @@
#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
-#define TIOCGPTPEER _IOR('T', 0x41, int) /* Safely open the slave */
+#define TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */
#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
#define FIOCLEX 0x5451
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index c32a09095216..19c0c141bc3f 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -453,8 +453,8 @@ void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
before it can be accessed through the kernel mapping. */
preempt_disable();
flush_dcache_page_asm(__pa(vfrom), vaddr);
- preempt_enable();
copy_page_asm(vto, vfrom);
+ preempt_enable();
}
EXPORT_SYMBOL(copy_user_page);
@@ -539,6 +539,10 @@ void flush_cache_mm(struct mm_struct *mm)
struct vm_area_struct *vma;
pgd_t *pgd;
+ /* Flush the TLB to avoid speculation if coherency is required. */
+ if (parisc_requires_coherency())
+ flush_tlb_all();
+
/* Flushing the whole cache on each cpu takes forever on
rp3440, etc. So, avoid it if the mm isn't too big. */
if (mm_total_size(mm) >= parisc_cache_flush_threshold) {
@@ -577,33 +581,21 @@ void flush_cache_mm(struct mm_struct *mm)
void flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{
- unsigned long addr;
- pgd_t *pgd;
-
BUG_ON(!vma->vm_mm->context);
- if ((end - start) >= parisc_cache_flush_threshold) {
- flush_cache_all();
- return;
- }
+ /* Flush the TLB to avoid speculation if coherency is required. */
+ if (parisc_requires_coherency())
+ flush_tlb_range(vma, start, end);
- if (vma->vm_mm->context == mfsp(3)) {
- flush_user_dcache_range_asm(start, end);
- if (vma->vm_flags & VM_EXEC)
- flush_user_icache_range_asm(start, end);
+ if ((end - start) >= parisc_cache_flush_threshold
+ || vma->vm_mm->context != mfsp(3)) {
+ flush_cache_all();
return;
}
- pgd = vma->vm_mm->pgd;
- for (addr = start & PAGE_MASK; addr < end; addr += PAGE_SIZE) {
- unsigned long pfn;
- pte_t *ptep = get_ptep(pgd, addr);
- if (!ptep)
- continue;
- pfn = pte_pfn(*ptep);
- if (pfn_valid(pfn))
- __flush_cache_page(vma, addr, PFN_PHYS(pfn));
- }
+ flush_user_dcache_range_asm(start, end);
+ if (vma->vm_flags & VM_EXEC)
+ flush_user_icache_range_asm(start, end);
}
void
@@ -612,7 +604,8 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
BUG_ON(!vma->vm_mm->context);
if (pfn_valid(pfn)) {
- flush_tlb_page(vma, vmaddr);
+ if (parisc_requires_coherency())
+ flush_tlb_page(vma, vmaddr);
__flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
}
}
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index 98190252c12f..f622a311d04a 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -1481,12 +1481,44 @@ int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret,
unsigned long offset)
{
int retval;
- unsigned long flags;
+ unsigned long flags, entries;
spin_lock_irqsave(&pdc_lock, flags);
retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_PD_READ,
- __pa(&pret), __pa(pdt_entries_ptr),
+ __pa(&pdc_result), __pa(pdt_entries_ptr),
count, offset);
+
+ if (retval == PDC_OK) {
+ entries = min(pdc_result[0], count);
+ pret->actual_count_bytes = entries;
+ pret->pdt_entries = entries / sizeof(unsigned long);
+ }
+
+ spin_unlock_irqrestore(&pdc_lock, flags);
+
+ return retval;
+}
+
+/**
+ * pdc_pat_mem_get_dimm_phys_location - Get physical DIMM slot via PAT firmware
+ * @pret: ptr to hold returned information
+ * @phys_addr: physical address to examine
+ *
+ */
+int pdc_pat_mem_get_dimm_phys_location(
+ struct pdc_pat_mem_phys_mem_location *pret,
+ unsigned long phys_addr)
+{
+ int retval;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pdc_lock, flags);
+ retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_ADDRESS,
+ __pa(&pdc_result), phys_addr);
+
+ if (retval == PDC_OK)
+ memcpy(pret, &pdc_result, sizeof(*pret));
+
spin_unlock_irqrestore(&pdc_lock, flags);
return retval;
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index ba5e1c7b1f17..0ca254085a66 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -380,7 +380,7 @@ static inline int eirr_to_irq(unsigned long eirr)
/*
* IRQ STACK - used for irq handler
*/
-#define IRQ_STACK_SIZE (4096 << 2) /* 16k irq stack size */
+#define IRQ_STACK_SIZE (4096 << 3) /* 32k irq stack size */
union irq_stack_union {
unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)];
@@ -413,6 +413,10 @@ static inline void stack_overflow_check(struct pt_regs *regs)
if (regs->sr[7])
return;
+ /* exit if already in panic */
+ if (sysctl_panic_on_stackoverflow < 0)
+ return;
+
/* calculate kernel stack usage */
stack_usage = sp - stack_start;
#ifdef CONFIG_IRQSTACKS
@@ -454,8 +458,10 @@ check_kernel_stack:
#ifdef CONFIG_IRQSTACKS
panic_check:
#endif
- if (sysctl_panic_on_stackoverflow)
+ if (sysctl_panic_on_stackoverflow) {
+ sysctl_panic_on_stackoverflow = -1; /* disable further checks */
panic("low stack detected by irq handler - check messages\n");
+ }
#endif
}
diff --git a/arch/parisc/kernel/pdt.c b/arch/parisc/kernel/pdt.c
index f3a797e670b0..d02874ecb94d 100644
--- a/arch/parisc/kernel/pdt.c
+++ b/arch/parisc/kernel/pdt.c
@@ -112,10 +112,12 @@ void __init pdc_pdt_init(void)
#ifdef CONFIG_64BIT
struct pdc_pat_mem_read_pd_retinfo pat_pret;
+ /* try old obsolete PAT firmware function first */
+ pdt_type = PDT_PAT_OLD;
ret = pdc_pat_mem_read_cell_pdt(&pat_pret, pdt_entry,
MAX_PDT_ENTRIES);
if (ret != PDC_OK) {
- pdt_type = PDT_PAT_OLD;
+ pdt_type = PDT_PAT_NEW;
ret = pdc_pat_mem_read_pd_pdt(&pat_pret, pdt_entry,
MAX_PDT_TABLE_SIZE, 0);
}
@@ -131,11 +133,20 @@ void __init pdc_pdt_init(void)
}
for (i = 0; i < pdt_status.pdt_entries; i++) {
- if (i < 20)
- pr_warn("PDT: BAD PAGE #%d at 0x%08lx (error_type = %lu)\n",
- i,
- pdt_entry[i] & PAGE_MASK,
- pdt_entry[i] & 1);
+ struct pdc_pat_mem_phys_mem_location loc;
+
+ /* get DIMM slot number */
+ loc.dimm_slot = 0xff;
+#ifdef CONFIG_64BIT
+ pdc_pat_mem_get_dimm_phys_location(&loc, pdt_entry[i]);
+#endif
+
+ pr_warn("PDT: BAD PAGE #%d at 0x%08lx, "
+ "DIMM slot %02x (error_type = %lu)\n",
+ i,
+ pdt_entry[i] & PAGE_MASK,
+ loc.dimm_slot,
+ pdt_entry[i] & 1);
/* mark memory page bad */
memblock_reserve(pdt_entry[i] & PAGE_MASK, PAGE_SIZE);
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index b64d7d21646e..a45a67d526f8 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -53,6 +53,7 @@
#include <linux/uaccess.h>
#include <linux/rcupdate.h>
#include <linux/random.h>
+#include <linux/nmi.h>
#include <asm/io.h>
#include <asm/asm-offsets.h>
@@ -145,6 +146,7 @@ void machine_power_off(void)
/* prevent soft lockup/stalled CPU messages for endless loop. */
rcu_sysrq_start();
+ lockup_detector_suspend();
for (;;);
}
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 3d6ef1b29c6a..ffe2cbf52d1a 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -78,6 +78,8 @@ SECTIONS
*(.text.sys_exit)
*(.text.do_sigaltstack)
*(.text.do_fork)
+ *(.text.div)
+ *($$*) /* millicode routines */
*(.text.*)
*(.fixup)
*(.lock.text) /* out-of-line lock text */
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 8d4ed73d5490..e2b3e7a00c9e 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -59,6 +59,19 @@ machine-$(CONFIG_PPC64) += 64
machine-$(CONFIG_CPU_LITTLE_ENDIAN) += le
UTS_MACHINE := $(subst $(space),,$(machine-y))
+# XXX This needs to be before we override LD below
+ifdef CONFIG_PPC32
+KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
+else
+ifeq ($(call ld-ifversion, -ge, 225000000, y),y)
+# Have the linker provide sfpr if possible.
+# There is a corresponding test in arch/powerpc/lib/Makefile
+KBUILD_LDFLAGS_MODULE += --save-restore-funcs
+else
+KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
+endif
+endif
+
ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y)
override LD += -EL
LDEMULATION := lppc
@@ -190,18 +203,6 @@ else
CHECKFLAGS += -D__LITTLE_ENDIAN__
endif
-ifdef CONFIG_PPC32
-KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
-else
-ifeq ($(call ld-ifversion, -ge, 225000000, y),y)
-# Have the linker provide sfpr if possible.
-# There is a corresponding test in arch/powerpc/lib/Makefile
-KBUILD_LDFLAGS_MODULE += --save-restore-funcs
-else
-KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
-endif
-endif
-
ifeq ($(CONFIG_476FPE_ERR46),y)
KBUILD_LDFLAGS_MODULE += --ppc476-workaround \
-T $(srctree)/arch/powerpc/platforms/44x/ppc476_modules.lds
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index a7814a7b1523..6f952fe1f084 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -25,12 +25,20 @@ compress-$(CONFIG_KERNEL_XZ) := CONFIG_KERNEL_XZ
BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -Os -msoft-float -pipe \
-fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
- -isystem $(shell $(CROSS32CC) -print-file-name=include) \
-D$(compress-y)
+BOOTCC := $(CC)
ifdef CONFIG_PPC64_BOOT_WRAPPER
BOOTCFLAGS += -m64
+else
+BOOTCFLAGS += -m32
+ifdef CROSS32_COMPILE
+ BOOTCC := $(CROSS32_COMPILE)gcc
+endif
endif
+
+BOOTCFLAGS += -isystem $(shell $(BOOTCC) -print-file-name=include)
+
ifdef CONFIG_CPU_BIG_ENDIAN
BOOTCFLAGS += -mbig-endian
else
@@ -183,10 +191,10 @@ clean-files := $(zlib-) $(zlibheader-) $(zliblinuxheader-) \
empty.c zImage.coff.lds zImage.ps3.lds zImage.lds
quiet_cmd_bootcc = BOOTCC $@
- cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
+ cmd_bootcc = $(BOOTCC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
quiet_cmd_bootas = BOOTAS $@
- cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $<
+ cmd_bootas = $(BOOTCC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $<
quiet_cmd_bootar = BOOTAR $@
cmd_bootar = $(CROSS32AR) -cr$(KBUILD_ARFLAGS) $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@
diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig
index 0695ce047d56..34fc9bbfca9e 100644
--- a/arch/powerpc/configs/powernv_defconfig
+++ b/arch/powerpc/configs/powernv_defconfig
@@ -293,7 +293,8 @@ CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_STACKOVERFLOW=y
-CONFIG_LOCKUP_DETECTOR=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_HARDLOCKUP_DETECTOR=y
CONFIG_LATENCYTOP=y
CONFIG_SCHED_TRACER=y
CONFIG_BLK_DEV_IO_TRACE=y
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 5175028c56ce..c5246d29f385 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -324,7 +324,8 @@ CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_STACKOVERFLOW=y
-CONFIG_LOCKUP_DETECTOR=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_HARDLOCKUP_DETECTOR=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_LATENCYTOP=y
CONFIG_SCHED_TRACER=y
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index 1a61aa20dfba..fd5d98a0b95c 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -291,7 +291,8 @@ CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_STACKOVERFLOW=y
-CONFIG_LOCKUP_DETECTOR=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_HARDLOCKUP_DETECTOR=y
CONFIG_LATENCYTOP=y
CONFIG_SCHED_TRACER=y
CONFIG_BLK_DEV_IO_TRACE=y
diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h
index 0ce513f2926f..36fc7bfe9e11 100644
--- a/arch/powerpc/include/asm/book3s/64/hash.h
+++ b/arch/powerpc/include/asm/book3s/64/hash.h
@@ -91,6 +91,7 @@ static inline int hash__pgd_bad(pgd_t pgd)
}
#ifdef CONFIG_STRICT_KERNEL_RWX
extern void hash__mark_rodata_ro(void);
+extern void hash__mark_initmem_nx(void);
#endif
extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h
index 77529a3e3811..5b4023c616f7 100644
--- a/arch/powerpc/include/asm/book3s/64/mmu.h
+++ b/arch/powerpc/include/asm/book3s/64/mmu.h
@@ -59,13 +59,14 @@ extern struct patb_entry *partition_tb;
#define PRTS_MASK 0x1f /* process table size field */
#define PRTB_MASK 0x0ffffffffffff000UL
-/*
- * Limit process table to PAGE_SIZE table. This
- * also limit the max pid we can support.
- * MAX_USER_CONTEXT * 16 bytes of space.
- */
-#define PRTB_SIZE_SHIFT (CONTEXT_BITS + 4)
-#define PRTB_ENTRIES (1ul << CONTEXT_BITS)
+/* Number of supported PID bits */
+extern unsigned int mmu_pid_bits;
+
+/* Base PID to allocate from */
+extern unsigned int mmu_base_pid;
+
+#define PRTB_SIZE_SHIFT (mmu_pid_bits + 4)
+#define PRTB_ENTRIES (1ul << mmu_pid_bits)
/*
* Power9 currently only support 64K partition table size.
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index c0737c86a362..818a58fc3f4f 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -608,9 +608,17 @@ static inline pte_t pte_mkdevmap(pte_t pte)
return __pte(pte_val(pte) | _PAGE_SPECIAL|_PAGE_DEVMAP);
}
+/*
+ * This is potentially called with a pmd as the argument, in which case it's not
+ * safe to check _PAGE_DEVMAP unless we also confirm that _PAGE_PTE is set.
+ * That's because the bit we use for _PAGE_DEVMAP is not reserved for software
+ * use in page directory entries (ie. non-ptes).
+ */
static inline int pte_devmap(pte_t pte)
{
- return !!(pte_raw(pte) & cpu_to_be64(_PAGE_DEVMAP));
+ u64 mask = cpu_to_be64(_PAGE_DEVMAP | _PAGE_PTE);
+
+ return (pte_raw(pte) & mask) == mask;
}
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
@@ -1192,5 +1200,6 @@ static inline const int pud_pfn(pud_t pud)
BUILD_BUG();
return 0;
}
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_POWERPC_BOOK3S_64_PGTABLE_H_ */
diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h
index 487709ff6875..544440b5aff3 100644
--- a/arch/powerpc/include/asm/book3s/64/radix.h
+++ b/arch/powerpc/include/asm/book3s/64/radix.h
@@ -118,6 +118,7 @@
#ifdef CONFIG_STRICT_KERNEL_RWX
extern void radix__mark_rodata_ro(void);
+extern void radix__mark_initmem_nx(void);
#endif
static inline unsigned long __radix_pte_update(pte_t *ptep, unsigned long clr,
diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
index 0151af6c2a50..87fcc1948817 100644
--- a/arch/powerpc/include/asm/bug.h
+++ b/arch/powerpc/include/asm/bug.h
@@ -18,7 +18,7 @@
#include <asm/asm-offsets.h>
#ifdef CONFIG_DEBUG_BUGVERBOSE
.macro EMIT_BUG_ENTRY addr,file,line,flags
- .section __bug_table,"a"
+ .section __bug_table,"aw"
5001: PPC_LONG \addr, 5002f
.short \line, \flags
.org 5001b+BUG_ENTRY_SIZE
@@ -29,7 +29,7 @@
.endm
#else
.macro EMIT_BUG_ENTRY addr,file,line,flags
- .section __bug_table,"a"
+ .section __bug_table,"aw"
5001: PPC_LONG \addr
.short \flags
.org 5001b+BUG_ENTRY_SIZE
@@ -42,14 +42,14 @@
sizeof(struct bug_entry), respectively */
#ifdef CONFIG_DEBUG_BUGVERBOSE
#define _EMIT_BUG_ENTRY \
- ".section __bug_table,\"a\"\n" \
+ ".section __bug_table,\"aw\"\n" \
"2:\t" PPC_LONG "1b, %0\n" \
"\t.short %1, %2\n" \
".org 2b+%3\n" \
".previous\n"
#else
#define _EMIT_BUG_ENTRY \
- ".section __bug_table,\"a\"\n" \
+ ".section __bug_table,\"aw\"\n" \
"2:\t" PPC_LONG "1b\n" \
"\t.short %2\n" \
".org 2b+%3\n" \
diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h
index da7e9432fa8f..0c76675394c5 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -45,7 +45,7 @@ extern void set_context(unsigned long id, pgd_t *pgd);
#ifdef CONFIG_PPC_BOOK3S_64
extern void radix__switch_mmu_context(struct mm_struct *prev,
- struct mm_struct *next);
+ struct mm_struct *next);
static inline void switch_mmu_context(struct mm_struct *prev,
struct mm_struct *next,
struct task_struct *tsk)
@@ -67,6 +67,12 @@ extern void __destroy_context(unsigned long context_id);
extern void mmu_context_init(void);
#endif
+#if defined(CONFIG_KVM_BOOK3S_HV_POSSIBLE) && defined(CONFIG_PPC_RADIX_MMU)
+extern void radix_kvm_prefetch_workaround(struct mm_struct *mm);
+#else
+static inline void radix_kvm_prefetch_workaround(struct mm_struct *mm) { }
+#endif
+
extern void switch_cop(struct mm_struct *next);
extern int use_cop(unsigned long acop, struct mm_struct *mm);
extern void drop_cop(unsigned long acop, struct mm_struct *mm);
@@ -79,9 +85,13 @@ static inline void switch_mm_irqs_off(struct mm_struct *prev,
struct mm_struct *next,
struct task_struct *tsk)
{
+ bool new_on_cpu = false;
+
/* Mark this context has been used on the new CPU */
- if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(next)))
+ if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(next))) {
cpumask_set_cpu(smp_processor_id(), mm_cpumask(next));
+ new_on_cpu = true;
+ }
/* 32-bit keeps track of the current PGDIR in the thread struct */
#ifdef CONFIG_PPC32
@@ -109,6 +119,10 @@ static inline void switch_mm_irqs_off(struct mm_struct *prev,
if (cpu_has_feature(CPU_FTR_ALTIVEC))
asm volatile ("dssall");
#endif /* CONFIG_ALTIVEC */
+
+ if (new_on_cpu)
+ radix_kvm_prefetch_workaround(next);
+
/*
* The actual HW switching method differs between the various
* sub architectures. Out of line for now
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index dd01212935ac..afae9a336136 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -80,6 +80,13 @@ unsigned long vmalloc_to_phys(void *vmalloc_addr);
void pgtable_cache_add(unsigned shift, void (*ctor)(void *));
void pgtable_cache_init(void);
+
+#ifdef CONFIG_STRICT_KERNEL_RWX
+void mark_initmem_nx(void);
+#else
+static inline void mark_initmem_nx(void) { }
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_POWERPC_PGTABLE_H */
diff --git a/arch/powerpc/include/uapi/asm/ioctls.h b/arch/powerpc/include/uapi/asm/ioctls.h
index bfd609a3e928..e3b10469f787 100644
--- a/arch/powerpc/include/uapi/asm/ioctls.h
+++ b/arch/powerpc/include/uapi/asm/ioctls.h
@@ -100,7 +100,7 @@
#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
-#define TIOCGPTPEER _IOR('T', 0x41, int) /* Safely open the slave */
+#define TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */
#define TIOCSERCONFIG 0x5453
#define TIOCSERGWILD 0x5454
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 49d8422767b4..e925c1c99c71 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -223,17 +223,27 @@ system_call_exit:
andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
bne- .Lsyscall_exit_work
- /* If MSR_FP and MSR_VEC are set in user msr, then no need to restore */
- li r7,MSR_FP
+ andi. r0,r8,MSR_FP
+ beq 2f
#ifdef CONFIG_ALTIVEC
- oris r7,r7,MSR_VEC@h
+ andis. r0,r8,MSR_VEC@h
+ bne 3f
#endif
- and r0,r8,r7
- cmpd r0,r7
- bne .Lsyscall_restore_math
-.Lsyscall_restore_math_cont:
+2: addi r3,r1,STACK_FRAME_OVERHEAD
+#ifdef CONFIG_PPC_BOOK3S
+ li r10,MSR_RI
+ mtmsrd r10,1 /* Restore RI */
+#endif
+ bl restore_math
+#ifdef CONFIG_PPC_BOOK3S
+ li r11,0
+ mtmsrd r11,1
+#endif
+ ld r8,_MSR(r1)
+ ld r3,RESULT(r1)
+ li r11,-MAX_ERRNO
- cmpld r3,r11
+3: cmpld r3,r11
ld r5,_CCR(r1)
bge- .Lsyscall_error
.Lsyscall_error_cont:
@@ -267,40 +277,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
std r5,_CCR(r1)
b .Lsyscall_error_cont
-.Lsyscall_restore_math:
- /*
- * Some initial tests from restore_math to avoid the heavyweight
- * C code entry and MSR manipulations.
- */
- LOAD_REG_IMMEDIATE(r0, MSR_TS_MASK)
- and. r0,r0,r8
- bne 1f
-
- ld r7,PACACURRENT(r13)
- lbz r0,THREAD+THREAD_LOAD_FP(r7)
-#ifdef CONFIG_ALTIVEC
- lbz r6,THREAD+THREAD_LOAD_VEC(r7)
- add r0,r0,r6
-#endif
- cmpdi r0,0
- beq .Lsyscall_restore_math_cont
-
-1: addi r3,r1,STACK_FRAME_OVERHEAD
-#ifdef CONFIG_PPC_BOOK3S
- li r10,MSR_RI
- mtmsrd r10,1 /* Restore RI */
-#endif
- bl restore_math
-#ifdef CONFIG_PPC_BOOK3S
- li r11,0
- mtmsrd r11,1
-#endif
- /* Restore volatiles, reload MSR from updated one */
- ld r8,_MSR(r1)
- ld r3,RESULT(r1)
- li r11,-MAX_ERRNO
- b .Lsyscall_restore_math_cont
-
/* Traced system call support */
.Lsyscall_dotrace:
bl save_nvgprs
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index e6d8354d79ef..f14f3c04ec7e 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -824,7 +824,7 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception)
* r3 volatile parameter and return value for status
* r4-r10 volatile input and output value
* r11 volatile hypercall number and output value
- * r12 volatile
+ * r12 volatile input and output value
* r13-r31 nonvolatile
* LR nonvolatile
* CTR volatile
@@ -834,25 +834,26 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception)
* Other registers nonvolatile
*
* The intersection of volatile registers that don't contain possible
- * inputs is: r12, cr0, xer, ctr. We may use these as scratch regs
- * upon entry without saving.
+ * inputs is: cr0, xer, ctr. We may use these as scratch regs upon entry
+ * without saving, though xer is not a good idea to use, as hardware may
+ * interpret some bits so it may be costly to change them.
*/
#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
/*
* There is a little bit of juggling to get syscall and hcall
- * working well. Save r10 in ctr to be restored in case it is a
- * hcall.
+ * working well. Save r13 in ctr to avoid using SPRG scratch
+ * register.
*
* Userspace syscalls have already saved the PPR, hcalls must save
* it before setting HMT_MEDIUM.
*/
#define SYSCALL_KVMTEST \
- mr r12,r13; \
+ mtctr r13; \
GET_PACA(r13); \
- mtctr r10; \
+ std r10,PACA_EXGEN+EX_R10(r13); \
KVMTEST_PR(0xc00); /* uses r10, branch to do_kvm_0xc00_system_call */ \
HMT_MEDIUM; \
- mr r9,r12; \
+ mfctr r9;
#else
#define SYSCALL_KVMTEST \
@@ -935,8 +936,8 @@ EXC_VIRT_END(system_call, 0x4c00, 0x100)
* This is a hcall, so register convention is as above, with these
* differences:
* r13 = PACA
- * r12 = orig r13
- * ctr = orig r10
+ * ctr = orig r13
+ * orig r10 saved in PACA
*/
TRAMP_KVM_BEGIN(do_kvm_0xc00)
/*
@@ -944,14 +945,13 @@ TRAMP_KVM_BEGIN(do_kvm_0xc00)
* HMT_MEDIUM. That allows the KVM code to save that value into the
* guest state (it is the guest's PPR value).
*/
- OPT_GET_SPR(r0, SPRN_PPR, CPU_FTR_HAS_PPR)
+ OPT_GET_SPR(r10, SPRN_PPR, CPU_FTR_HAS_PPR)
HMT_MEDIUM
- OPT_SAVE_REG_TO_PACA(PACA_EXGEN+EX_PPR, r0, CPU_FTR_HAS_PPR)
+ OPT_SAVE_REG_TO_PACA(PACA_EXGEN+EX_PPR, r10, CPU_FTR_HAS_PPR)
mfctr r10
- SET_SCRATCH0(r12)
+ SET_SCRATCH0(r10)
std r9,PACA_EXGEN+EX_R9(r13)
mfcr r9
- std r10,PACA_EXGEN+EX_R10(r13)
KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xc00)
#endif
@@ -1325,10 +1325,18 @@ EXC_VIRT_NONE(0x5800, 0x100)
std r10,PACA_EXGEN+EX_R13(r13); \
EXCEPTION_PROLOG_PSERIES_1(soft_nmi_common, _H)
+/*
+ * Branch to soft_nmi_interrupt using the emergency stack. The emergency
+ * stack is one that is usable by maskable interrupts so long as MSR_EE
+ * remains off. It is used for recovery when something has corrupted the
+ * normal kernel stack, for example. The "soft NMI" must not use the process
+ * stack because we want irq disabled sections to avoid touching the stack
+ * at all (other than PMU interrupts), so use the emergency stack for this,
+ * and run it entirely with interrupts hard disabled.
+ */
EXC_COMMON_BEGIN(soft_nmi_common)
mr r10,r1
ld r1,PACAEMERGSP(r13)
- ld r1,PACA_NMI_EMERG_SP(r13)
subi r1,r1,INT_FRAME_SIZE
EXCEPTION_COMMON_NORET_STACK(PACA_EXGEN, 0x900,
system_reset, soft_nmi_interrupt,
diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S
index 5adb390e773b..e6252c5a57a4 100644
--- a/arch/powerpc/kernel/idle_book3s.S
+++ b/arch/powerpc/kernel/idle_book3s.S
@@ -30,6 +30,7 @@
* Use unused space in the interrupt stack to save and restore
* registers for winkle support.
*/
+#define _MMCR0 GPR0
#define _SDR1 GPR3
#define _PTCR GPR3
#define _RPR GPR4
@@ -272,6 +273,14 @@ power_enter_stop:
b pnv_wakeup_noloss
.Lhandle_esl_ec_set:
+ /*
+ * POWER9 DD2 can incorrectly set PMAO when waking up after a
+ * state-loss idle. Saving and restoring MMCR0 over idle is a
+ * workaround.
+ */
+ mfspr r4,SPRN_MMCR0
+ std r4,_MMCR0(r1)
+
/*
* Check if the requested state is a deep idle state.
*/
@@ -450,10 +459,20 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_300)
pnv_restore_hyp_resource_arch300:
/*
* Workaround for POWER9, if we lost resources, the ERAT
- * might have been mixed up and needs flushing.
+ * might have been mixed up and needs flushing. We also need
+ * to reload MMCR0 (see comment above). We also need to set
+ * then clear bit 60 in MMCRA to ensure the PMU starts running.
*/
blt cr3,1f
PPC_INVALIDATE_ERAT
+ ld r1,PACAR1(r13)
+ mfspr r4,SPRN_MMCRA
+ ori r4,r4,(1 << (63-60))
+ mtspr SPRN_MMCRA,r4
+ xori r4,r4,(1 << (63-60))
+ mtspr SPRN_MMCRA,r4
+ ld r4,_MMCR0(r1)
+ mtspr SPRN_MMCR0,r4
1:
/*
* POWER ISA 3. Use PSSCR to determine if we
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 0bcec745a672..f291f7826abc 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -145,6 +145,19 @@ notrace unsigned int __check_irq_replay(void)
/* Clear bit 0 which we wouldn't clear otherwise */
local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS;
+ if (happened & PACA_IRQ_HARD_DIS) {
+ /*
+ * We may have missed a decrementer interrupt if hard disabled.
+ * Check the decrementer register in case we had a rollover
+ * while hard disabled.
+ */
+ if (!(happened & PACA_IRQ_DEC)) {
+ if (decrementer_check_overflow()) {
+ local_paca->irq_happened |= PACA_IRQ_DEC;
+ happened |= PACA_IRQ_DEC;
+ }
+ }
+ }
/*
* Force the delivery of pending soft-disabled interrupts on PS3.
@@ -170,7 +183,7 @@ notrace unsigned int __check_irq_replay(void)
* in case we also had a rollover while hard disabled
*/
local_paca->irq_happened &= ~PACA_IRQ_DEC;
- if ((happened & PACA_IRQ_DEC) || decrementer_check_overflow())
+ if (happened & PACA_IRQ_DEC)
return 0x900;
/* Finally check if an external interrupt happened */
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 9f3e2c932dcc..ec480966f9bf 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -511,10 +511,6 @@ void restore_math(struct pt_regs *regs)
{
unsigned long msr;
- /*
- * Syscall exit makes a similar initial check before branching
- * to restore_math. Keep them in synch.
- */
if (!msr_tm_active(regs->msr) &&
!current->thread.load_fp && !loadvec(current->thread))
return;
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 925a4ef90559..660ed39e9c9a 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -127,12 +127,19 @@ static void flush_tmregs_to_thread(struct task_struct *tsk)
* If task is not current, it will have been flushed already to
* it's thread_struct during __switch_to().
*
- * A reclaim flushes ALL the state.
+ * A reclaim flushes ALL the state or if not in TM save TM SPRs
+ * in the appropriate thread structures from live.
*/
- if (tsk == current && MSR_TM_SUSPENDED(mfmsr()))
- tm_reclaim_current(TM_CAUSE_SIGNAL);
+ if (tsk != current)
+ return;
+ if (MSR_TM_SUSPENDED(mfmsr())) {
+ tm_reclaim_current(TM_CAUSE_SIGNAL);
+ } else {
+ tm_enable();
+ tm_save_sprs(&(tsk->thread));
+ }
}
#else
static inline void flush_tmregs_to_thread(struct task_struct *tsk) { }
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 997c88d54acf..8d3320562c70 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -351,7 +351,7 @@ static void nmi_ipi_lock_start(unsigned long *flags)
hard_irq_disable();
while (atomic_cmpxchg(&__nmi_ipi_lock, 0, 1) == 1) {
raw_local_irq_restore(*flags);
- cpu_relax();
+ spin_until_cond(atomic_read(&__nmi_ipi_lock) == 0);
raw_local_irq_save(*flags);
hard_irq_disable();
}
@@ -360,7 +360,7 @@ static void nmi_ipi_lock_start(unsigned long *flags)
static void nmi_ipi_lock(void)
{
while (atomic_cmpxchg(&__nmi_ipi_lock, 0, 1) == 1)
- cpu_relax();
+ spin_until_cond(atomic_read(&__nmi_ipi_lock) == 0);
}
static void nmi_ipi_unlock(void)
@@ -475,7 +475,7 @@ int smp_send_nmi_ipi(int cpu, void (*fn)(struct pt_regs *), u64 delay_us)
nmi_ipi_lock_start(&flags);
while (nmi_ipi_busy_count) {
nmi_ipi_unlock_end(&flags);
- cpu_relax();
+ spin_until_cond(nmi_ipi_busy_count == 0);
nmi_ipi_lock_start(&flags);
}
@@ -1003,21 +1003,13 @@ static struct sched_domain_topology_level powerpc_topology[] = {
{ NULL, },
};
-static __init long smp_setup_cpu_workfn(void *data __always_unused)
-{
- smp_ops->setup_cpu(boot_cpuid);
- return 0;
-}
-
void __init smp_cpus_done(unsigned int max_cpus)
{
/*
- * We want the setup_cpu() here to be called on the boot CPU, but
- * init might run on any CPU, so make sure it's invoked on the boot
- * CPU.
+ * We are running pinned to the boot CPU, see rest_init().
*/
if (smp_ops && smp_ops->setup_cpu)
- work_on_cpu_safe(boot_cpuid, smp_setup_cpu_workfn, NULL);
+ smp_ops->setup_cpu(boot_cpuid);
if (smp_ops && smp_ops->bringup_done)
smp_ops->bringup_done();
diff --git a/arch/powerpc/kernel/watchdog.c b/arch/powerpc/kernel/watchdog.c
index b67f8b03a32d..34721a257a77 100644
--- a/arch/powerpc/kernel/watchdog.c
+++ b/arch/powerpc/kernel/watchdog.c
@@ -71,15 +71,20 @@ static inline void wd_smp_lock(unsigned long *flags)
* This may be called from low level interrupt handlers at some
* point in future.
*/
- local_irq_save(*flags);
- while (unlikely(test_and_set_bit_lock(0, &__wd_smp_lock)))
- cpu_relax();
+ raw_local_irq_save(*flags);
+ hard_irq_disable(); /* Make it soft-NMI safe */
+ while (unlikely(test_and_set_bit_lock(0, &__wd_smp_lock))) {
+ raw_local_irq_restore(*flags);
+ spin_until_cond(!test_bit(0, &__wd_smp_lock));
+ raw_local_irq_save(*flags);
+ hard_irq_disable();
+ }
}
static inline void wd_smp_unlock(unsigned long *flags)
{
clear_bit_unlock(0, &__wd_smp_lock);
- local_irq_restore(*flags);
+ raw_local_irq_restore(*flags);
}
static void wd_lockup_ipi(struct pt_regs *regs)
@@ -96,10 +101,10 @@ static void wd_lockup_ipi(struct pt_regs *regs)
nmi_panic(regs, "Hard LOCKUP");
}
-static void set_cpu_stuck(int cpu, u64 tb)
+static void set_cpumask_stuck(const struct cpumask *cpumask, u64 tb)
{
- cpumask_set_cpu(cpu, &wd_smp_cpus_stuck);
- cpumask_clear_cpu(cpu, &wd_smp_cpus_pending);
+ cpumask_or(&wd_smp_cpus_stuck, &wd_smp_cpus_stuck, cpumask);
+ cpumask_andnot(&wd_smp_cpus_pending, &wd_smp_cpus_pending, cpumask);
if (cpumask_empty(&wd_smp_cpus_pending)) {
wd_smp_last_reset_tb = tb;
cpumask_andnot(&wd_smp_cpus_pending,
@@ -107,6 +112,10 @@ static void set_cpu_stuck(int cpu, u64 tb)
&wd_smp_cpus_stuck);
}
}
+static void set_cpu_stuck(int cpu, u64 tb)
+{
+ set_cpumask_stuck(cpumask_of(cpu), tb);
+}
static void watchdog_smp_panic(int cpu, u64 tb)
{
@@ -135,11 +144,9 @@ static void watchdog_smp_panic(int cpu, u64 tb)
}
smp_flush_nmi_ipi(1000000);
- /* Take the stuck CPU out of the watch group */
- for_each_cpu(c, &wd_smp_cpus_pending)
- set_cpu_stuck(c, tb);
+ /* Take the stuck CPUs out of the watch group */
+ set_cpumask_stuck(&wd_smp_cpus_pending, tb);
-out:
wd_smp_unlock(&flags);
printk_safe_flush();
@@ -152,6 +159,11 @@ out:
if (hardlockup_panic)
nmi_panic(NULL, "Hard LOCKUP");
+
+ return;
+
+out:
+ wd_smp_unlock(&flags);
}
static void wd_smp_clear_cpu_pending(int cpu, u64 tb)
@@ -258,9 +270,11 @@ static void wd_timer_fn(unsigned long data)
void arch_touch_nmi_watchdog(void)
{
+ unsigned long ticks = tb_ticks_per_usec * wd_timer_period_ms * 1000;
int cpu = smp_processor_id();
- watchdog_timer_interrupt(cpu);
+ if (get_tb() - per_cpu(wd_timer_tb, cpu) >= ticks)
+ watchdog_timer_interrupt(cpu);
}
EXPORT_SYMBOL(arch_touch_nmi_watchdog);
@@ -283,6 +297,8 @@ static void stop_watchdog_timer_on(unsigned int cpu)
static int start_wd_on_cpu(unsigned int cpu)
{
+ unsigned long flags;
+
if (cpumask_test_cpu(cpu, &wd_cpus_enabled)) {
WARN_ON(1);
return 0;
@@ -297,12 +313,14 @@ static int start_wd_on_cpu(unsigned int cpu)
if (!cpumask_test_cpu(cpu, &watchdog_cpumask))
return 0;
+ wd_smp_lock(&flags);
cpumask_set_cpu(cpu, &wd_cpus_enabled);
if (cpumask_weight(&wd_cpus_enabled) == 1) {
cpumask_set_cpu(cpu, &wd_smp_cpus_pending);
wd_smp_last_reset_tb = get_tb();
}
- smp_wmb();
+ wd_smp_unlock(&flags);
+
start_watchdog_timer_on(cpu);
return 0;
@@ -310,12 +328,17 @@ static int start_wd_on_cpu(unsigned int cpu)
static int stop_wd_on_cpu(unsigned int cpu)
{
+ unsigned long flags;
+
if (!cpumask_test_cpu(cpu, &wd_cpus_enabled))
return 0; /* Can happen in CPU unplug case */
stop_watchdog_timer_on(cpu);
+ wd_smp_lock(&flags);
cpumask_clear_cpu(cpu, &wd_cpus_enabled);
+ wd_smp_unlock(&flags);
+
wd_smp_clear_cpu_pending(cpu, get_tb());
return 0;
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index 8cb0190e2a73..b42812e014c0 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -164,8 +164,10 @@ long kvmppc_alloc_reset_hpt(struct kvm *kvm, int order)
goto out;
}
- if (kvm->arch.hpt.virt)
+ if (kvm->arch.hpt.virt) {
kvmppc_free_hpt(&kvm->arch.hpt);
+ kvmppc_rmap_reset(kvm);
+ }
err = kvmppc_allocate_hpt(&info, order);
if (err < 0)
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 0b436df746fc..359c79cdf0cc 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -3211,6 +3211,8 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
run->fail_entry.hardware_entry_failure_reason = 0;
return -EINVAL;
}
+ /* Enable TM so we can read the TM SPRs */
+ mtmsr(mfmsr() | MSR_TM);
current->thread.tm_tfhar = mfspr(SPRN_TFHAR);
current->thread.tm_tfiar = mfspr(SPRN_TFIAR);
current->thread.tm_texasr = mfspr(SPRN_TEXASR);
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index cb44065e2946..c52184a8efdf 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1443,12 +1443,14 @@ mc_cont:
ori r6,r6,1
mtspr SPRN_CTRLT,r6
4:
- /* Read the guest SLB and save it away */
+ /* Check if we are running hash or radix and store it in cr2 */
ld r5, VCPU_KVM(r9)
lbz r0, KVM_RADIX(r5)
- cmpwi r0, 0
+ cmpwi cr2,r0,0
+
+ /* Read the guest SLB and save it away */
li r5, 0
- bne 3f /* for radix, save 0 entries */
+ bne cr2, 3f /* for radix, save 0 entries */
lwz r0,VCPU_SLB_NR(r9) /* number of entries in SLB */
mtctr r0
li r6,0
@@ -1712,11 +1714,6 @@ BEGIN_FTR_SECTION_NESTED(96)
END_FTR_SECTION_NESTED(CPU_FTR_ARCH_300, 0, 96)
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
22:
- /* Clear out SLB */
- li r5,0
- slbmte r5,r5
- slbia
- ptesync
/* Restore host values of some registers */
BEGIN_FTR_SECTION
@@ -1737,10 +1734,56 @@ BEGIN_FTR_SECTION
mtspr SPRN_PID, r7
mtspr SPRN_IAMR, r8
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
+
+#ifdef CONFIG_PPC_RADIX_MMU
+ /*
+ * Are we running hash or radix ?
+ */
+ beq cr2,3f
+
+ /* Radix: Handle the case where the guest used an illegal PID */
+ LOAD_REG_ADDR(r4, mmu_base_pid)
+ lwz r3, VCPU_GUEST_PID(r9)
+ lwz r5, 0(r4)
+ cmpw cr0,r3,r5
+ blt 2f
+
+ /*
+ * Illegal PID, the HW might have prefetched and cached in the TLB
+ * some translations for the LPID 0 / guest PID combination which
+ * Linux doesn't know about, so we need to flush that PID out of
+ * the TLB. First we need to set LPIDR to 0 so tlbiel applies to
+ * the right context.
+ */
+ li r0,0
+ mtspr SPRN_LPID,r0
+ isync
+
+ /* Then do a congruence class local flush */
+ ld r6,VCPU_KVM(r9)
+ lwz r0,KVM_TLB_SETS(r6)
+ mtctr r0
+ li r7,0x400 /* IS field = 0b01 */
+ ptesync
+ sldi r0,r3,32 /* RS has PID */
+1: PPC_TLBIEL(7,0,2,1,1) /* RIC=2, PRS=1, R=1 */
+ addi r7,r7,0x1000
+ bdnz 1b
+ ptesync
+
+2: /* Flush the ERAT on radix P9 DD1 guest exit */
BEGIN_FTR_SECTION
PPC_INVALIDATE_ERAT
END_FTR_SECTION_IFSET(CPU_FTR_POWER9_DD1)
+ b 4f
+#endif /* CONFIG_PPC_RADIX_MMU */
+ /* Hash: clear out SLB */
+3: li r5,0
+ slbmte r5,r5
+ slbia
+ ptesync
+4:
/*
* POWER7/POWER8 guest -> host partition switch code.
* We don't have to lock against tlbies but we do
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 8541f18694a4..46b4e67d2372 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -402,6 +402,7 @@ void __init mem_init(void)
void free_initmem(void)
{
ppc_md.progress = ppc_printk_progress;
+ mark_initmem_nx();
free_initmem_default(POISON_FREE_INITMEM);
}
diff --git a/arch/powerpc/mm/mmu_context_book3s64.c b/arch/powerpc/mm/mmu_context_book3s64.c
index abed1fe6992f..a75f63833284 100644
--- a/arch/powerpc/mm/mmu_context_book3s64.c
+++ b/arch/powerpc/mm/mmu_context_book3s64.c
@@ -126,9 +126,10 @@ static int hash__init_new_context(struct mm_struct *mm)
static int radix__init_new_context(struct mm_struct *mm)
{
unsigned long rts_field;
- int index;
+ int index, max_id;
- index = alloc_context_id(1, PRTB_ENTRIES - 1);
+ max_id = (1 << mmu_pid_bits) - 1;
+ index = alloc_context_id(mmu_base_pid, max_id);
if (index < 0)
return index;
diff --git a/arch/powerpc/mm/pgtable-hash64.c b/arch/powerpc/mm/pgtable-hash64.c
index 188b4107584d..443a2c66a304 100644
--- a/arch/powerpc/mm/pgtable-hash64.c
+++ b/arch/powerpc/mm/pgtable-hash64.c
@@ -425,33 +425,51 @@ int hash__has_transparent_hugepage(void)
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
#ifdef CONFIG_STRICT_KERNEL_RWX
-void hash__mark_rodata_ro(void)
+static bool hash__change_memory_range(unsigned long start, unsigned long end,
+ unsigned long newpp)
{
- unsigned long start = (unsigned long)_stext;
- unsigned long end = (unsigned long)__init_begin;
unsigned long idx;
unsigned int step, shift;
- unsigned long newpp = PP_RXXX;
shift = mmu_psize_defs[mmu_linear_psize].shift;
step = 1 << shift;
- start = ((start + step - 1) >> shift) << shift;
- end = (end >> shift) << shift;
+ start = ALIGN_DOWN(start, step);
+ end = ALIGN(end, step); // aligns up
- pr_devel("marking ro start %lx, end %lx, step %x\n",
- start, end, step);
+ if (start >= end)
+ return false;
- if (start == end) {
- pr_warn("could not set rodata ro, relocate the start"
- " of the kernel to a 0x%x boundary\n", step);
- return;
- }
+ pr_debug("Changing page protection on range 0x%lx-0x%lx, to 0x%lx, step 0x%x\n",
+ start, end, newpp, step);
for (idx = start; idx < end; idx += step)
/* Not sure if we can do much with the return value */
mmu_hash_ops.hpte_updateboltedpp(newpp, idx, mmu_linear_psize,
mmu_kernel_ssize);
+ return true;
+}
+
+void hash__mark_rodata_ro(void)
+{
+ unsigned long start, end;
+
+ start = (unsigned long)_stext;
+ end = (unsigned long)__init_begin;
+
+ WARN_ON(!hash__change_memory_range(start, end, PP_RXXX));
+}
+
+void hash__mark_initmem_nx(void)
+{
+ unsigned long start, end, pp;
+
+ start = (unsigned long)__init_begin;
+ end = (unsigned long)__init_end;
+
+ pp = htab_convert_pte_flags(pgprot_val(PAGE_KERNEL));
+
+ WARN_ON(!hash__change_memory_range(start, end, pp));
}
#endif
diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c
index 8c13e4282308..671a45d86c18 100644
--- a/arch/powerpc/mm/pgtable-radix.c
+++ b/arch/powerpc/mm/pgtable-radix.c
@@ -25,6 +25,9 @@
#include <trace/events/thp.h>
+unsigned int mmu_pid_bits;
+unsigned int mmu_base_pid;
+
static int native_register_process_table(unsigned long base, unsigned long pg_sz,
unsigned long table_size)
{
@@ -112,10 +115,9 @@ set_the_pte:
}
#ifdef CONFIG_STRICT_KERNEL_RWX
-void radix__mark_rodata_ro(void)
+void radix__change_memory_range(unsigned long start, unsigned long end,
+ unsigned long clear)
{
- unsigned long start = (unsigned long)_stext;
- unsigned long end = (unsigned long)__init_begin;
unsigned long idx;
pgd_t *pgdp;
pud_t *pudp;
@@ -125,7 +127,8 @@ void radix__mark_rodata_ro(void)
start = ALIGN_DOWN(start, PAGE_SIZE);
end = PAGE_ALIGN(end); // aligns up
- pr_devel("marking ro start %lx, end %lx\n", start, end);
+ pr_debug("Changing flags on range %lx-%lx removing 0x%lx\n",
+ start, end, clear);
for (idx = start; idx < end; idx += PAGE_SIZE) {
pgdp = pgd_offset_k(idx);
@@ -147,11 +150,29 @@ void radix__mark_rodata_ro(void)
if (!ptep)
continue;
update_the_pte:
- radix__pte_update(&init_mm, idx, ptep, _PAGE_WRITE, 0, 0);
+ radix__pte_update(&init_mm, idx, ptep, clear, 0, 0);
}
radix__flush_tlb_kernel_range(start, end);
}
+
+void radix__mark_rodata_ro(void)
+{
+ unsigned long start, end;
+
+ start = (unsigned long)_stext;
+ end = (unsigned long)__init_begin;
+
+ radix__change_memory_range(start, end, _PAGE_WRITE);
+}
+
+void radix__mark_initmem_nx(void)
+{
+ unsigned long start = (unsigned long)__init_begin;
+ unsigned long end = (unsigned long)__init_end;
+
+ radix__change_memory_range(start, end, _PAGE_EXEC);
+}
#endif /* CONFIG_STRICT_KERNEL_RWX */
static inline void __meminit print_mapping(unsigned long start,
@@ -243,11 +264,34 @@ static void __init radix_init_pgtable(void)
for_each_memblock(memory, reg)
WARN_ON(create_physical_mapping(reg->base,
reg->base + reg->size));
+
+ /* Find out how many PID bits are supported */
+ if (cpu_has_feature(CPU_FTR_HVMODE)) {
+ if (!mmu_pid_bits)
+ mmu_pid_bits = 20;
+#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+ /*
+ * When KVM is possible, we only use the top half of the
+ * PID space to avoid collisions between host and guest PIDs
+ * which can cause problems due to prefetch when exiting the
+ * guest with AIL=3
+ */
+ mmu_base_pid = 1 << (mmu_pid_bits - 1);
+#else
+ mmu_base_pid = 1;
+#endif
+ } else {
+ /* The guest uses the bottom half of the PID space */
+ if (!mmu_pid_bits)
+ mmu_pid_bits = 19;
+ mmu_base_pid = 1;
+ }
+
/*
* Allocate Partition table and process table for the
* host.
*/
- BUILD_BUG_ON_MSG((PRTB_SIZE_SHIFT > 36), "Process table size too large.");
+ BUG_ON(PRTB_SIZE_SHIFT > 36);
process_tb = early_alloc_pgtable(1UL << PRTB_SIZE_SHIFT);
/*
* Fill in the process table.
@@ -321,6 +365,12 @@ static int __init radix_dt_scan_page_sizes(unsigned long node,
if (type == NULL || strcmp(type, "cpu") != 0)
return 0;
+ /* Find MMU PID size */
+ prop = of_get_flat_dt_prop(node, "ibm,mmu-pid-bits", &size);
+ if (prop && size == 4)
+ mmu_pid_bits = be32_to_cpup(prop);
+
+ /* Grab page size encodings */
prop = of_get_flat_dt_prop(node, "ibm,processor-radix-AP-encodings", &size);
if (!prop)
return 0;
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 5c0b795d656c..0736e94c7615 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -505,4 +505,12 @@ void mark_rodata_ro(void)
else
hash__mark_rodata_ro();
}
+
+void mark_initmem_nx(void)
+{
+ if (radix_enabled())
+ radix__mark_initmem_nx();
+ else
+ hash__mark_initmem_nx();
+}
#endif
diff --git a/arch/powerpc/mm/subpage-prot.c b/arch/powerpc/mm/subpage-prot.c
index e94fbd4c8845..781532d7bc4d 100644
--- a/arch/powerpc/mm/subpage-prot.c
+++ b/arch/powerpc/mm/subpage-prot.c
@@ -36,7 +36,7 @@ void subpage_prot_free(struct mm_struct *mm)
}
}
addr = 0;
- for (i = 0; i < 2; ++i) {
+ for (i = 0; i < (TASK_SIZE_USER64 >> 43); ++i) {
p = spt->protptrs[i];
if (!p)
continue;
diff --git a/arch/powerpc/mm/tlb-radix.c b/arch/powerpc/mm/tlb-radix.c
index 744e0164ecf5..16ae1bbe13f0 100644
--- a/arch/powerpc/mm/tlb-radix.c
+++ b/arch/powerpc/mm/tlb-radix.c
@@ -12,12 +12,12 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/memblock.h>
-#include <asm/ppc-opcode.h>
+#include <asm/ppc-opcode.h>
#include <asm/tlb.h>
#include <asm/tlbflush.h>
#include <asm/trace.h>
-
+#include <asm/cputhreads.h>
#define RIC_FLUSH_TLB 0
#define RIC_FLUSH_PWC 1
@@ -454,3 +454,44 @@ void radix__flush_tlb_pte_p9_dd1(unsigned long old_pte, struct mm_struct *mm,
else
radix__flush_tlb_page_psize(mm, address, mmu_virtual_psize);
}
+
+#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+extern void radix_kvm_prefetch_workaround(struct mm_struct *mm)
+{
+ unsigned int pid = mm->context.id;
+
+ if (unlikely(pid == MMU_NO_CONTEXT))
+ return;
+
+ /*
+ * If this context hasn't run on that CPU before and KVM is
+ * around, there's a slim chance that the guest on another
+ * CPU just brought in obsolete translation into the TLB of
+ * this CPU due to a bad prefetch using the guest PID on
+ * the way into the hypervisor.
+ *
+ * We work around this here. If KVM is possible, we check if
+ * any sibling thread is in KVM. If it is, the window may exist
+ * and thus we flush that PID from the core.
+ *
+ * A potential future improvement would be to mark which PIDs
+ * have never been used on the system and avoid it if the PID
+ * is new and the process has no other cpumask bit set.
+ */
+ if (cpu_has_feature(CPU_FTR_HVMODE) && radix_enabled()) {
+ int cpu = smp_processor_id();
+ int sib = cpu_first_thread_sibling(cpu);
+ bool flush = false;
+
+ for (; sib <= cpu_last_thread_sibling(cpu) && !flush; sib++) {
+ if (sib == cpu)
+ continue;
+ if (paca[sib].kvm_hstate.kvm_vcpu)
+ flush = true;
+ }
+ if (flush)
+ _tlbiel_pid(pid, RIC_FLUSH_ALL);
+ }
+}
+EXPORT_SYMBOL_GPL(radix_kvm_prefetch_workaround);
+#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index d7c9b186954d..763ffca9628d 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -89,7 +89,7 @@ static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
goto err;
ret = of_irq_to_resource(np, 0, &res[1]);
- if (!ret)
+ if (ret <= 0)
goto err;
pdev = platform_device_alloc("mpc83xx_spi", i);
diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c
index 2abee070373f..a553aeea7af6 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -56,6 +56,7 @@ u64 pnv_first_deep_stop_state = MAX_STOP_STATE;
*/
static u64 pnv_deepest_stop_psscr_val;
static u64 pnv_deepest_stop_psscr_mask;
+static u64 pnv_deepest_stop_flag;
static bool deepest_stop_found;
static int pnv_save_sprs_for_deep_states(void)
@@ -185,8 +186,40 @@ static void pnv_alloc_idle_core_states(void)
update_subcore_sibling_mask();
- if (supported_cpuidle_states & OPAL_PM_LOSE_FULL_CONTEXT)
- pnv_save_sprs_for_deep_states();
+ if (supported_cpuidle_states & OPAL_PM_LOSE_FULL_CONTEXT) {
+ int rc = pnv_save_sprs_for_deep_states();
+
+ if (likely(!rc))
+ return;
+
+ /*
+ * The stop-api is unable to restore hypervisor
+ * resources on wakeup from platform idle states which
+ * lose full context. So disable such states.
+ */
+ supported_cpuidle_states &= ~OPAL_PM_LOSE_FULL_CONTEXT;
+ pr_warn("cpuidle-powernv: Disabling idle states that lose full context\n");
+ pr_warn("cpuidle-powernv: Idle power-savings, CPU-Hotplug affected\n");
+
+ if (cpu_has_feature(CPU_FTR_ARCH_300) &&
+ (pnv_deepest_stop_flag & OPAL_PM_LOSE_FULL_CONTEXT)) {
+ /*
+ * Use the default stop state for CPU-Hotplug
+ * if available.
+ */
+ if (default_stop_found) {
+ pnv_deepest_stop_psscr_val =
+ pnv_default_stop_val;
+ pnv_deepest_stop_psscr_mask =
+ pnv_default_stop_mask;
+ pr_warn("cpuidle-powernv: Offlined CPUs will stop with psscr = 0x%016llx\n",
+ pnv_deepest_stop_psscr_val);
+ } else { /* Fallback to snooze loop for CPU-Hotplug */
+ deepest_stop_found = false;
+ pr_warn("cpuidle-powernv: Offlined CPUs will busy wait\n");
+ }
+ }
+ }
}
u32 pnv_get_supported_cpuidle_states(void)
@@ -375,7 +408,8 @@ unsigned long pnv_cpu_offline(unsigned int cpu)
pnv_deepest_stop_psscr_val;
srr1 = power9_idle_stop(psscr);
- } else if (idle_states & OPAL_PM_WINKLE_ENABLED) {
+ } else if ((idle_states & OPAL_PM_WINKLE_ENABLED) &&
+ (idle_states & OPAL_PM_LOSE_FULL_CONTEXT)) {
srr1 = power7_idle_insn(PNV_THREAD_WINKLE);
} else if ((idle_states & OPAL_PM_SLEEP_ENABLED) ||
(idle_states & OPAL_PM_SLEEP_ENABLED_ER1)) {
@@ -553,6 +587,7 @@ static int __init pnv_power9_idle_init(struct device_node *np, u32 *flags,
max_residency_ns = residency_ns[i];
pnv_deepest_stop_psscr_val = psscr_val[i];
pnv_deepest_stop_psscr_mask = psscr_mask[i];
+ pnv_deepest_stop_flag = flags[i];
deepest_stop_found = true;
}
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 9b87abb178f0..cad6b57ce494 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -78,7 +78,7 @@ void opal_configure_cores(void)
* ie. Host hash supports hash guests
* Host radix supports hash/radix guests
*/
- if (cpu_has_feature(CPU_FTR_ARCH_300)) {
+ if (early_cpu_has_feature(CPU_FTR_ARCH_300)) {
reinit_flags |= OPAL_REINIT_CPUS_MMU_HASH;
if (early_radix_enabled())
reinit_flags |= OPAL_REINIT_CPUS_MMU_RADIX;
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 437613588df1..b900eb1d5e17 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1852,6 +1852,14 @@ static int pnv_pci_ioda_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
/* 4GB offset bypasses 32-bit space */
set_dma_offset(&pdev->dev, (1ULL << 32));
set_dma_ops(&pdev->dev, &dma_direct_ops);
+ } else if (dma_mask >> 32 && dma_mask != DMA_BIT_MASK(64)) {
+ /*
+ * Fail the request if a DMA mask between 32 and 64 bits
+ * was requested but couldn't be fulfilled. Ideally we
+ * would do this for 64-bits but historically we have
+ * always fallen back to 32-bits.
+ */
+ return -ENOMEM;
} else {
dev_info(&pdev->dev, "Using 32-bit DMA via iommu\n");
set_dma_ops(&pdev->dev, &dma_iommu_ops);
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index e5bf1e84047f..011ef2180fe6 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -82,7 +82,6 @@ static int pSeries_reconfig_remove_node(struct device_node *np)
of_detach_node(np);
of_node_put(parent);
- of_node_put(np); /* Must decrement the refcount */
return 0;
}
diff --git a/arch/s390/include/asm/bug.h b/arch/s390/include/asm/bug.h
index 1bbd9dbfe4e0..ce9cc123988b 100644
--- a/arch/s390/include/asm/bug.h
+++ b/arch/s390/include/asm/bug.h
@@ -14,7 +14,7 @@
".section .rodata.str,\"aMS\",@progbits,1\n" \
"2: .asciz \""__FILE__"\"\n" \
".previous\n" \
- ".section __bug_table,\"a\"\n" \
+ ".section __bug_table,\"aw\"\n" \
"3: .long 1b-3b,2b-3b\n" \
" .short %0,%1\n" \
" .org 3b+%2\n" \
@@ -30,7 +30,7 @@
asm volatile( \
"0: j 0b+2\n" \
"1:\n" \
- ".section __bug_table,\"a\"\n" \
+ ".section __bug_table,\"aw\"\n" \
"2: .long 1b-2b\n" \
" .short %0\n" \
" .org 2b+%1\n" \
diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h
index 7317b3108a88..2eb8ff0d6fca 100644
--- a/arch/s390/include/asm/tlb.h
+++ b/arch/s390/include/asm/tlb.h
@@ -47,10 +47,9 @@ struct mmu_table_batch {
extern void tlb_table_flush(struct mmu_gather *tlb);
extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
-static inline void tlb_gather_mmu(struct mmu_gather *tlb,
- struct mm_struct *mm,
- unsigned long start,
- unsigned long end)
+static inline void
+arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
+ unsigned long start, unsigned long end)
{
tlb->mm = mm;
tlb->start = start;
@@ -76,9 +75,15 @@ static inline void tlb_flush_mmu(struct mmu_gather *tlb)
tlb_flush_mmu_free(tlb);
}
-static inline void tlb_finish_mmu(struct mmu_gather *tlb,
- unsigned long start, unsigned long end)
+static inline void
+arch_tlb_finish_mmu(struct mmu_gather *tlb,
+ unsigned long start, unsigned long end, bool force)
{
+ if (force) {
+ tlb->start = start;
+ tlb->end = end;
+ }
+
tlb_flush_mmu(tlb);
}
diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c
index 0c82f7903fc7..c1bf75ffb875 100644
--- a/arch/s390/kernel/perf_cpum_sf.c
+++ b/arch/s390/kernel/perf_cpum_sf.c
@@ -998,7 +998,7 @@ static int perf_push_sample(struct perf_event *event, struct sf_raw_sample *sfr)
psw_bits(regs.psw).ia = sfr->basic.ia;
psw_bits(regs.psw).dat = sfr->basic.T;
psw_bits(regs.psw).wait = sfr->basic.W;
- psw_bits(regs.psw).per = sfr->basic.P;
+ psw_bits(regs.psw).pstate = sfr->basic.P;
psw_bits(regs.psw).as = sfr->basic.AS;
/*
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 3f2884e99ed4..af09d3437631 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -1324,7 +1324,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
{
uint8_t *keys;
uint64_t hva;
- int i, r = 0;
+ int srcu_idx, i, r = 0;
if (args->flags != 0)
return -EINVAL;
@@ -1342,6 +1342,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
return -ENOMEM;
down_read(&current->mm->mmap_sem);
+ srcu_idx = srcu_read_lock(&kvm->srcu);
for (i = 0; i < args->count; i++) {
hva = gfn_to_hva(kvm, args->start_gfn + i);
if (kvm_is_error_hva(hva)) {
@@ -1353,6 +1354,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
if (r)
break;
}
+ srcu_read_unlock(&kvm->srcu, srcu_idx);
up_read(&current->mm->mmap_sem);
if (!r) {
@@ -1370,7 +1372,7 @@ static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
{
uint8_t *keys;
uint64_t hva;
- int i, r = 0;
+ int srcu_idx, i, r = 0;
if (args->flags != 0)
return -EINVAL;
@@ -1396,6 +1398,7 @@ static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
goto out;
down_read(&current->mm->mmap_sem);
+ srcu_idx = srcu_read_lock(&kvm->srcu);
for (i = 0; i < args->count; i++) {
hva = gfn_to_hva(kvm, args->start_gfn + i);
if (kvm_is_error_hva(hva)) {
@@ -1413,6 +1416,7 @@ static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
if (r)
break;
}
+ srcu_read_unlock(&kvm->srcu, srcu_idx);
up_read(&current->mm->mmap_sem);
out:
kvfree(keys);
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index d4d409ba206b..4a1f7366b17a 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -591,11 +591,11 @@ void ptep_zap_key(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
unsigned long ptev;
pgste_t pgste;
- /* Clear storage key */
+ /* Clear storage key ACC and F, but set R/C */
preempt_disable();
pgste = pgste_get_lock(ptep);
- pgste_val(pgste) &= ~(PGSTE_ACC_BITS | PGSTE_FP_BIT |
- PGSTE_GR_BIT | PGSTE_GC_BIT);
+ pgste_val(pgste) &= ~(PGSTE_ACC_BITS | PGSTE_FP_BIT);
+ pgste_val(pgste) |= PGSTE_GR_BIT | PGSTE_GC_BIT;
ptev = pte_val(*ptep);
if (!(ptev & _PAGE_INVALID) && (ptev & _PAGE_WRITE))
page_set_storage_key(ptev & PAGE_MASK, PAGE_DEFAULT_KEY, 1);
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
index 01c6fbc3e85b..1803797fc885 100644
--- a/arch/s390/net/bpf_jit_comp.c
+++ b/arch/s390/net/bpf_jit_comp.c
@@ -1253,7 +1253,8 @@ static int bpf_jit_prog(struct bpf_jit *jit, struct bpf_prog *fp)
insn_count = bpf_jit_insn(jit, fp, i);
if (insn_count < 0)
return -1;
- jit->addrs[i + 1] = jit->prg; /* Next instruction address */
+ /* Next instruction address */
+ jit->addrs[i + insn_count] = jit->prg;
}
bpf_jit_epilogue(jit);
diff --git a/arch/sh/include/asm/bug.h b/arch/sh/include/asm/bug.h
index c9828f785ca0..5b5086367639 100644
--- a/arch/sh/include/asm/bug.h
+++ b/arch/sh/include/asm/bug.h
@@ -24,14 +24,14 @@
*/
#ifdef CONFIG_DEBUG_BUGVERBOSE
#define _EMIT_BUG_ENTRY \
- "\t.pushsection __bug_table,\"a\"\n" \
+ "\t.pushsection __bug_table,\"aw\"\n" \
"2:\t.long 1b, %O1\n" \
"\t.short %O2, %O3\n" \
"\t.org 2b+%O4\n" \
"\t.popsection\n"
#else
#define _EMIT_BUG_ENTRY \
- "\t.pushsection __bug_table,\"a\"\n" \
+ "\t.pushsection __bug_table,\"aw\"\n" \
"2:\t.long 1b\n" \
"\t.short %O3\n" \
"\t.org 2b+%O4\n" \
diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h
index 46e0d635e36f..51a8bc967e75 100644
--- a/arch/sh/include/asm/tlb.h
+++ b/arch/sh/include/asm/tlb.h
@@ -36,7 +36,8 @@ static inline void init_tlb_gather(struct mmu_gather *tlb)
}
static inline void
-tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
+arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
+ unsigned long start, unsigned long end)
{
tlb->mm = mm;
tlb->start = start;
@@ -47,9 +48,10 @@ tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start
}
static inline void
-tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
+arch_tlb_finish_mmu(struct mmu_gather *tlb,
+ unsigned long start, unsigned long end, bool force)
{
- if (tlb->fullmm)
+ if (tlb->fullmm || force)
flush_tlb_mm(tlb->mm);
/* keep the page table cache within bounds */
diff --git a/arch/sh/include/uapi/asm/ioctls.h b/arch/sh/include/uapi/asm/ioctls.h
index eec7901e9e65..787bac9f67da 100644
--- a/arch/sh/include/uapi/asm/ioctls.h
+++ b/arch/sh/include/uapi/asm/ioctls.h
@@ -93,7 +93,7 @@
#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
-#define TIOCGPTPEER _IOR('T', 0x41, int) /* Safely open the slave */
+#define TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */
#define TIOCSERCONFIG _IO('T', 83) /* 0x5453 */
#define TIOCSERGWILD _IOR('T', 84, int) /* 0x5454 */
diff --git a/arch/sparc/configs/sparc32_defconfig b/arch/sparc/configs/sparc32_defconfig
index c74d3701ad68..207a43a2d8b3 100644
--- a/arch/sparc/configs/sparc32_defconfig
+++ b/arch/sparc/configs/sparc32_defconfig
@@ -1,4 +1,3 @@
-CONFIG_EXPERIMENTAL=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_LOG_BUF_SHIFT=14
@@ -23,7 +22,6 @@ CONFIG_IP_PNP_DHCP=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_IPCOMP=y
-# CONFIG_INET_LRO is not set
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m
@@ -69,7 +67,6 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
-CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
CONFIG_ISO9660_FS=m
CONFIG_PROC_KCORE=y
@@ -82,7 +79,6 @@ CONFIG_NLS=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_HUNG_TASK=y
# CONFIG_SCHED_DEBUG is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_KGDB=y
CONFIG_KGDB_TESTS=y
CONFIG_CRYPTO_NULL=m
diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig
index b2e650d1764f..ca8609d7292f 100644
--- a/arch/sparc/configs/sparc64_defconfig
+++ b/arch/sparc/configs/sparc64_defconfig
@@ -1,5 +1,4 @@
CONFIG_64BIT=y
-CONFIG_EXPERIMENTAL=y
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -184,7 +183,6 @@ CONFIG_HID_TOPSEED=y
CONFIG_HID_THRUSTMASTER=y
CONFIG_HID_ZEROPLUS=y
CONFIG_USB=y
-# CONFIG_USB_DEVICE_CLASS is not set
CONFIG_USB_EHCI_HCD=m
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
CONFIG_USB_OHCI_HCD=y
@@ -210,8 +208,6 @@ CONFIG_LOCKUP_DETECTOR=y
CONFIG_DETECT_HUNG_TASK=y
# CONFIG_SCHED_DEBUG is not set
CONFIG_SCHEDSTATS=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_UPROBE_EVENTS=y
CONFIG_KEYS=y
diff --git a/arch/sparc/include/asm/mmu_context_64.h b/arch/sparc/include/asm/mmu_context_64.h
index 2cddcda4f85f..87841d687f8d 100644
--- a/arch/sparc/include/asm/mmu_context_64.h
+++ b/arch/sparc/include/asm/mmu_context_64.h
@@ -27,9 +27,11 @@ void destroy_context(struct mm_struct *mm);
void __tsb_context_switch(unsigned long pgd_pa,
struct tsb_config *tsb_base,
struct tsb_config *tsb_huge,
- unsigned long tsb_descr_pa);
+ unsigned long tsb_descr_pa,
+ unsigned long secondary_ctx);
-static inline void tsb_context_switch(struct mm_struct *mm)
+static inline void tsb_context_switch_ctx(struct mm_struct *mm,
+ unsigned long ctx)
{
__tsb_context_switch(__pa(mm->pgd),
&mm->context.tsb_block[MM_TSB_BASE],
@@ -40,9 +42,12 @@ static inline void tsb_context_switch(struct mm_struct *mm)
#else
NULL
#endif
- , __pa(&mm->context.tsb_descr[MM_TSB_BASE]));
+ , __pa(&mm->context.tsb_descr[MM_TSB_BASE]),
+ ctx);
}
+#define tsb_context_switch(X) tsb_context_switch_ctx(X, 0)
+
void tsb_grow(struct mm_struct *mm,
unsigned long tsb_index,
unsigned long mm_rss);
@@ -112,8 +117,7 @@ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, str
* cpu0 to update it's TSB because at that point the cpu_vm_mask
* only had cpu1 set in it.
*/
- load_secondary_context(mm);
- tsb_context_switch(mm);
+ tsb_context_switch_ctx(mm, CTX_HWBITS(mm->context));
/* Any time a processor runs a context on an address space
* for the first time, we must flush that context out of the
diff --git a/arch/sparc/include/asm/spitfire.h b/arch/sparc/include/asm/spitfire.h
index 1d8321c827a8..1b1286d05069 100644
--- a/arch/sparc/include/asm/spitfire.h
+++ b/arch/sparc/include/asm/spitfire.h
@@ -47,10 +47,26 @@
#define SUN4V_CHIP_NIAGARA5 0x05
#define SUN4V_CHIP_SPARC_M6 0x06
#define SUN4V_CHIP_SPARC_M7 0x07
+#define SUN4V_CHIP_SPARC_M8 0x08
#define SUN4V_CHIP_SPARC64X 0x8a
#define SUN4V_CHIP_SPARC_SN 0x8b
#define SUN4V_CHIP_UNKNOWN 0xff
+/*
+ * The following CPU_ID_xxx constants are used
+ * to identify the CPU type in the setup phase
+ * (see head_64.S)
+ */
+#define CPU_ID_NIAGARA1 ('1')
+#define CPU_ID_NIAGARA2 ('2')
+#define CPU_ID_NIAGARA3 ('3')
+#define CPU_ID_NIAGARA4 ('4')
+#define CPU_ID_NIAGARA5 ('5')
+#define CPU_ID_M6 ('6')
+#define CPU_ID_M7 ('7')
+#define CPU_ID_M8 ('8')
+#define CPU_ID_SONOMA1 ('N')
+
#ifndef __ASSEMBLY__
enum ultra_tlb_layout {
diff --git a/arch/sparc/include/asm/trap_block.h b/arch/sparc/include/asm/trap_block.h
index ec9c04de3664..ff05992dae7a 100644
--- a/arch/sparc/include/asm/trap_block.h
+++ b/arch/sparc/include/asm/trap_block.h
@@ -54,6 +54,7 @@ extern struct trap_per_cpu trap_block[NR_CPUS];
void init_cur_cpu_trap(struct thread_info *);
void setup_tba(void);
extern int ncpus_probed;
+extern u64 cpu_mondo_counter[NR_CPUS];
unsigned long real_hard_smp_processor_id(void);
diff --git a/arch/sparc/include/uapi/asm/ioctls.h b/arch/sparc/include/uapi/asm/ioctls.h
index 6d27398632ea..f5df72b93bb2 100644
--- a/arch/sparc/include/uapi/asm/ioctls.h
+++ b/arch/sparc/include/uapi/asm/ioctls.h
@@ -88,7 +88,7 @@
#define TIOCGPTN _IOR('t', 134, unsigned int) /* Get Pty Number */
#define TIOCSPTLCK _IOW('t', 135, int) /* Lock/unlock PTY */
#define TIOCSIG _IOW('t', 136, int) /* Generate signal on Pty slave */
-#define TIOCGPTPEER _IOR('t', 137, int) /* Safely open the slave */
+#define TIOCGPTPEER _IO('t', 137) /* Safely open the slave */
/* Little f */
#define FIOCLEX _IO('f', 1)
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 493e023a468a..ef4f18f7a674 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -506,6 +506,12 @@ static void __init sun4v_cpu_probe(void)
sparc_pmu_type = "sparc-m7";
break;
+ case SUN4V_CHIP_SPARC_M8:
+ sparc_cpu_type = "SPARC-M8";
+ sparc_fpu_type = "SPARC-M8 integrated FPU";
+ sparc_pmu_type = "sparc-m8";
+ break;
+
case SUN4V_CHIP_SPARC_SN:
sparc_cpu_type = "SPARC-SN";
sparc_fpu_type = "SPARC-SN integrated FPU";
diff --git a/arch/sparc/kernel/cpumap.c b/arch/sparc/kernel/cpumap.c
index 45c820e1cba5..90d550bbfeef 100644
--- a/arch/sparc/kernel/cpumap.c
+++ b/arch/sparc/kernel/cpumap.c
@@ -328,6 +328,7 @@ static int iterate_cpu(struct cpuinfo_tree *t, unsigned int root_index)
case SUN4V_CHIP_NIAGARA5:
case SUN4V_CHIP_SPARC_M6:
case SUN4V_CHIP_SPARC_M7:
+ case SUN4V_CHIP_SPARC_M8:
case SUN4V_CHIP_SPARC_SN:
case SUN4V_CHIP_SPARC64X:
rover_inc_table = niagara_iterate_method;
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S
index 41a407328667..78e0211753d2 100644
--- a/arch/sparc/kernel/head_64.S
+++ b/arch/sparc/kernel/head_64.S
@@ -424,22 +424,25 @@ EXPORT_SYMBOL(sun4v_chip_type)
nop
70: ldub [%g1 + 7], %g2
- cmp %g2, '3'
+ cmp %g2, CPU_ID_NIAGARA3
be,pt %xcc, 5f
mov SUN4V_CHIP_NIAGARA3, %g4
- cmp %g2, '4'
+ cmp %g2, CPU_ID_NIAGARA4
be,pt %xcc, 5f
mov SUN4V_CHIP_NIAGARA4, %g4
- cmp %g2, '5'
+ cmp %g2, CPU_ID_NIAGARA5
be,pt %xcc, 5f
mov SUN4V_CHIP_NIAGARA5, %g4
- cmp %g2, '6'
+ cmp %g2, CPU_ID_M6
be,pt %xcc, 5f
mov SUN4V_CHIP_SPARC_M6, %g4
- cmp %g2, '7'
+ cmp %g2, CPU_ID_M7
be,pt %xcc, 5f
mov SUN4V_CHIP_SPARC_M7, %g4
- cmp %g2, 'N'
+ cmp %g2, CPU_ID_M8
+ be,pt %xcc, 5f
+ mov SUN4V_CHIP_SPARC_M8, %g4
+ cmp %g2, CPU_ID_SONOMA1
be,pt %xcc, 5f
mov SUN4V_CHIP_SPARC_SN, %g4
ba,pt %xcc, 49f
@@ -448,10 +451,10 @@ EXPORT_SYMBOL(sun4v_chip_type)
91: sethi %hi(prom_cpu_compatible), %g1
or %g1, %lo(prom_cpu_compatible), %g1
ldub [%g1 + 17], %g2
- cmp %g2, '1'
+ cmp %g2, CPU_ID_NIAGARA1
be,pt %xcc, 5f
mov SUN4V_CHIP_NIAGARA1, %g4
- cmp %g2, '2'
+ cmp %g2, CPU_ID_NIAGARA2
be,pt %xcc, 5f
mov SUN4V_CHIP_NIAGARA2, %g4
@@ -602,6 +605,9 @@ niagara_tlb_fixup:
cmp %g1, SUN4V_CHIP_SPARC_M7
be,pt %xcc, niagara4_patch
nop
+ cmp %g1, SUN4V_CHIP_SPARC_M8
+ be,pt %xcc, niagara4_patch
+ nop
cmp %g1, SUN4V_CHIP_SPARC_SN
be,pt %xcc, niagara4_patch
nop
diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c
index 24f21c726dfa..f10e2f712394 100644
--- a/arch/sparc/kernel/pci_sun4v.c
+++ b/arch/sparc/kernel/pci_sun4v.c
@@ -673,12 +673,14 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,
static int dma_4v_supported(struct device *dev, u64 device_mask)
{
struct iommu *iommu = dev->archdata.iommu;
- u64 dma_addr_mask;
+ u64 dma_addr_mask = iommu->dma_addr_mask;
- if (device_mask > DMA_BIT_MASK(32) && iommu->atu)
- dma_addr_mask = iommu->atu->dma_addr_mask;
- else
- dma_addr_mask = iommu->dma_addr_mask;
+ if (device_mask > DMA_BIT_MASK(32)) {
+ if (iommu->atu)
+ dma_addr_mask = iommu->atu->dma_addr_mask;
+ else
+ return 0;
+ }
if ((device_mask & dma_addr_mask) == dma_addr_mask)
return 1;
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index 4d9c3e13c150..150ee7d4b059 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -288,10 +288,17 @@ static void __init sun4v_patch(void)
sun4v_patch_2insn_range(&__sun4v_2insn_patch,
&__sun4v_2insn_patch_end);
- if (sun4v_chip_type == SUN4V_CHIP_SPARC_M7 ||
- sun4v_chip_type == SUN4V_CHIP_SPARC_SN)
+
+ switch (sun4v_chip_type) {
+ case SUN4V_CHIP_SPARC_M7:
+ case SUN4V_CHIP_SPARC_M8:
+ case SUN4V_CHIP_SPARC_SN:
sun_m7_patch_2insn_range(&__sun_m7_2insn_patch,
&__sun_m7_2insn_patch_end);
+ break;
+ default:
+ break;
+ }
sun4v_hvapi_init();
}
@@ -529,6 +536,7 @@ static void __init init_sparc64_elf_hwcap(void)
sun4v_chip_type == SUN4V_CHIP_NIAGARA5 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M6 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M7 ||
+ sun4v_chip_type == SUN4V_CHIP_SPARC_M8 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_SN ||
sun4v_chip_type == SUN4V_CHIP_SPARC64X)
cap |= HWCAP_SPARC_BLKINIT;
@@ -538,6 +546,7 @@ static void __init init_sparc64_elf_hwcap(void)
sun4v_chip_type == SUN4V_CHIP_NIAGARA5 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M6 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M7 ||
+ sun4v_chip_type == SUN4V_CHIP_SPARC_M8 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_SN ||
sun4v_chip_type == SUN4V_CHIP_SPARC64X)
cap |= HWCAP_SPARC_N2;
@@ -568,6 +577,7 @@ static void __init init_sparc64_elf_hwcap(void)
sun4v_chip_type == SUN4V_CHIP_NIAGARA5 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M6 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M7 ||
+ sun4v_chip_type == SUN4V_CHIP_SPARC_M8 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_SN ||
sun4v_chip_type == SUN4V_CHIP_SPARC64X)
cap |= (AV_SPARC_VIS | AV_SPARC_VIS2 |
@@ -578,6 +588,7 @@ static void __init init_sparc64_elf_hwcap(void)
sun4v_chip_type == SUN4V_CHIP_NIAGARA5 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M6 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_M7 ||
+ sun4v_chip_type == SUN4V_CHIP_SPARC_M8 ||
sun4v_chip_type == SUN4V_CHIP_SPARC_SN ||
sun4v_chip_type == SUN4V_CHIP_SPARC64X)
cap |= (AV_SPARC_VIS3 | AV_SPARC_HPC |
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index fdf31040a7dc..3218bc43302e 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -622,22 +622,48 @@ retry:
}
}
-/* Multi-cpu list version. */
+#define CPU_MONDO_COUNTER(cpuid) (cpu_mondo_counter[cpuid])
+#define MONDO_USEC_WAIT_MIN 2
+#define MONDO_USEC_WAIT_MAX 100
+#define MONDO_RETRY_LIMIT 500000
+
+/* Multi-cpu list version.
+ *
+ * Deliver xcalls to 'cnt' number of cpus in 'cpu_list'.
+ * Sometimes not all cpus receive the mondo, requiring us to re-send
+ * the mondo until all cpus have received, or cpus are truly stuck
+ * unable to receive mondo, and we timeout.
+ * Occasionally a target cpu strand is borrowed briefly by hypervisor to
+ * perform guest service, such as PCIe error handling. Consider the
+ * service time, 1 second overall wait is reasonable for 1 cpu.
+ * Here two in-between mondo check wait time are defined: 2 usec for
+ * single cpu quick turn around and up to 100usec for large cpu count.
+ * Deliver mondo to large number of cpus could take longer, we adjusts
+ * the retry count as long as target cpus are making forward progress.
+ */
static void hypervisor_xcall_deliver(struct trap_per_cpu *tb, int cnt)
{
- int retries, this_cpu, prev_sent, i, saw_cpu_error;
+ int this_cpu, tot_cpus, prev_sent, i, rem;
+ int usec_wait, retries, tot_retries;
+ u16 first_cpu = 0xffff;
+ unsigned long xc_rcvd = 0;
unsigned long status;
+ int ecpuerror_id = 0;
+ int enocpu_id = 0;
u16 *cpu_list;
+ u16 cpu;
this_cpu = smp_processor_id();
-
cpu_list = __va(tb->cpu_list_pa);
-
- saw_cpu_error = 0;
- retries = 0;
+ usec_wait = cnt * MONDO_USEC_WAIT_MIN;
+ if (usec_wait > MONDO_USEC_WAIT_MAX)
+ usec_wait = MONDO_USEC_WAIT_MAX;
+ retries = tot_retries = 0;
+ tot_cpus = cnt;
prev_sent = 0;
+
do {
- int forward_progress, n_sent;
+ int n_sent, mondo_delivered, target_cpu_busy;
status = sun4v_cpu_mondo_send(cnt,
tb->cpu_list_pa,
@@ -645,94 +671,113 @@ static void hypervisor_xcall_deliver(struct trap_per_cpu *tb, int cnt)
/* HV_EOK means all cpus received the xcall, we're done. */
if (likely(status == HV_EOK))
- break;
+ goto xcall_done;
+
+ /* If not these non-fatal errors, panic */
+ if (unlikely((status != HV_EWOULDBLOCK) &&
+ (status != HV_ECPUERROR) &&
+ (status != HV_ENOCPU)))
+ goto fatal_errors;
/* First, see if we made any forward progress.
*
+ * Go through the cpu_list, count the target cpus that have
+ * received our mondo (n_sent), and those that did not (rem).
+ * Re-pack cpu_list with the cpus remain to be retried in the
+ * front - this simplifies tracking the truly stalled cpus.
+ *
* The hypervisor indicates successful sends by setting
* cpu list entries to the value 0xffff.
+ *
+ * EWOULDBLOCK means some target cpus did not receive the
+ * mondo and retry usually helps.
+ *
+ * ECPUERROR means at least one target cpu is in error state,
+ * it's usually safe to skip the faulty cpu and retry.
+ *
+ * ENOCPU means one of the target cpu doesn't belong to the
+ * domain, perhaps offlined which is unexpected, but not
+ * fatal and it's okay to skip the offlined cpu.
*/
+ rem = 0;
n_sent = 0;
for (i = 0; i < cnt; i++) {
- if (likely(cpu_list[i] == 0xffff))
+ cpu = cpu_list[i];
+ if (likely(cpu == 0xffff)) {
n_sent++;
+ } else if ((status == HV_ECPUERROR) &&
+ (sun4v_cpu_state(cpu) == HV_CPU_STATE_ERROR)) {
+ ecpuerror_id = cpu + 1;
+ } else if (status == HV_ENOCPU && !cpu_online(cpu)) {
+ enocpu_id = cpu + 1;
+ } else {
+ cpu_list[rem++] = cpu;
+ }
}
- forward_progress = 0;
- if (n_sent > prev_sent)
- forward_progress = 1;
+ /* No cpu remained, we're done. */
+ if (rem == 0)
+ break;
- prev_sent = n_sent;
+ /* Otherwise, update the cpu count for retry. */
+ cnt = rem;
- /* If we get a HV_ECPUERROR, then one or more of the cpus
- * in the list are in error state. Use the cpu_state()
- * hypervisor call to find out which cpus are in error state.
+ /* Record the overall number of mondos received by the
+ * first of the remaining cpus.
*/
- if (unlikely(status == HV_ECPUERROR)) {
- for (i = 0; i < cnt; i++) {
- long err;
- u16 cpu;
+ if (first_cpu != cpu_list[0]) {
+ first_cpu = cpu_list[0];
+ xc_rcvd = CPU_MONDO_COUNTER(first_cpu);
+ }
- cpu = cpu_list[i];
- if (cpu == 0xffff)
- continue;
+ /* Was any mondo delivered successfully? */
+ mondo_delivered = (n_sent > prev_sent);
+ prev_sent = n_sent;
- err = sun4v_cpu_state(cpu);
- if (err == HV_CPU_STATE_ERROR) {
- saw_cpu_error = (cpu + 1);
- cpu_list[i] = 0xffff;
- }
- }
- } else if (unlikely(status != HV_EWOULDBLOCK))
- goto fatal_mondo_error;
+ /* or, was any target cpu busy processing other mondos? */
+ target_cpu_busy = (xc_rcvd < CPU_MONDO_COUNTER(first_cpu));
+ xc_rcvd = CPU_MONDO_COUNTER(first_cpu);
- /* Don't bother rewriting the CPU list, just leave the
- * 0xffff and non-0xffff entries in there and the
- * hypervisor will do the right thing.
- *
- * Only advance timeout state if we didn't make any
- * forward progress.
+ /* Retry count is for no progress. If we're making progress,
+ * reset the retry count.
*/
- if (unlikely(!forward_progress)) {
- if (unlikely(++retries > 10000))
- goto fatal_mondo_timeout;
-
- /* Delay a little bit to let other cpus catch up
- * on their cpu mondo queue work.
- */
- udelay(2 * cnt);
+ if (likely(mondo_delivered || target_cpu_busy)) {
+ tot_retries += retries;
+ retries = 0;
+ } else if (unlikely(retries > MONDO_RETRY_LIMIT)) {
+ goto fatal_mondo_timeout;
}
- } while (1);
- if (unlikely(saw_cpu_error))
- goto fatal_mondo_cpu_error;
+ /* Delay a little bit to let other cpus catch up on
+ * their cpu mondo queue work.
+ */
+ if (!mondo_delivered)
+ udelay(usec_wait);
- return;
+ retries++;
+ } while (1);
-fatal_mondo_cpu_error:
- printk(KERN_CRIT "CPU[%d]: SUN4V mondo cpu error, some target cpus "
- "(including %d) were in error state\n",
- this_cpu, saw_cpu_error - 1);
+xcall_done:
+ if (unlikely(ecpuerror_id > 0)) {
+ pr_crit("CPU[%d]: SUN4V mondo cpu error, target cpu(%d) was in error state\n",
+ this_cpu, ecpuerror_id - 1);
+ } else if (unlikely(enocpu_id > 0)) {
+ pr_crit("CPU[%d]: SUN4V mondo cpu error, target cpu(%d) does not belong to the domain\n",
+ this_cpu, enocpu_id - 1);
+ }
return;
+fatal_errors:
+ /* fatal errors include bad alignment, etc */
+ pr_crit("CPU[%d]: Args were cnt(%d) cpulist_pa(%lx) mondo_block_pa(%lx)\n",
+ this_cpu, tot_cpus, tb->cpu_list_pa, tb->cpu_mondo_block_pa);
+ panic("Unexpected SUN4V mondo error %lu\n", status);
+
fatal_mondo_timeout:
- printk(KERN_CRIT "CPU[%d]: SUN4V mondo timeout, no forward "
- " progress after %d retries.\n",
- this_cpu, retries);
- goto dump_cpu_list_and_out;
-
-fatal_mondo_error:
- printk(KERN_CRIT "CPU[%d]: Unexpected SUN4V mondo error %lu\n",
- this_cpu, status);
- printk(KERN_CRIT "CPU[%d]: Args were cnt(%d) cpulist_pa(%lx) "
- "mondo_block_pa(%lx)\n",
- this_cpu, cnt, tb->cpu_list_pa, tb->cpu_mondo_block_pa);
-
-dump_cpu_list_and_out:
- printk(KERN_CRIT "CPU[%d]: CPU list [ ", this_cpu);
- for (i = 0; i < cnt; i++)
- printk("%u ", cpu_list[i]);
- printk("]\n");
+ /* some cpus being non-responsive to the cpu mondo */
+ pr_crit("CPU[%d]: SUN4V mondo timeout, cpu(%d) made no forward progress after %d retries. Total target cpus(%d).\n",
+ this_cpu, first_cpu, (tot_retries + retries), tot_cpus);
+ panic("SUN4V mondo timeout panic\n");
}
static void (*xcall_deliver_impl)(struct trap_per_cpu *, int);
diff --git a/arch/sparc/kernel/sun4v_ivec.S b/arch/sparc/kernel/sun4v_ivec.S
index 559bc5e9c199..34631995859a 100644
--- a/arch/sparc/kernel/sun4v_ivec.S
+++ b/arch/sparc/kernel/sun4v_ivec.S
@@ -26,6 +26,21 @@ sun4v_cpu_mondo:
ldxa [%g0] ASI_SCRATCHPAD, %g4
sub %g4, TRAP_PER_CPU_FAULT_INFO, %g4
+ /* Get smp_processor_id() into %g3 */
+ sethi %hi(trap_block), %g5
+ or %g5, %lo(trap_block), %g5
+ sub %g4, %g5, %g3
+ srlx %g3, TRAP_BLOCK_SZ_SHIFT, %g3
+
+ /* Increment cpu_mondo_counter[smp_processor_id()] */
+ sethi %hi(cpu_mondo_counter), %g5
+ or %g5, %lo(cpu_mondo_counter), %g5
+ sllx %g3, 3, %g3
+ add %g5, %g3, %g5
+ ldx [%g5], %g3
+ add %g3, 1, %g3
+ stx %g3, [%g5]
+
/* Get CPU mondo queue base phys address into %g7. */
ldx [%g4 + TRAP_PER_CPU_CPU_MONDO_PA], %g7
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index 196ee5eb4d48..ad31af1dd726 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -2733,6 +2733,7 @@ void do_getpsr(struct pt_regs *regs)
}
}
+u64 cpu_mondo_counter[NR_CPUS] = {0};
struct trap_per_cpu trap_block[NR_CPUS];
EXPORT_SYMBOL(trap_block);
diff --git a/arch/sparc/kernel/tsb.S b/arch/sparc/kernel/tsb.S
index 07c0df924960..db872dbfafe9 100644
--- a/arch/sparc/kernel/tsb.S
+++ b/arch/sparc/kernel/tsb.S
@@ -360,6 +360,7 @@ tsb_flush:
* %o1: TSB base config pointer
* %o2: TSB huge config pointer, or NULL if none
* %o3: Hypervisor TSB descriptor physical address
+ * %o4: Secondary context to load, if non-zero
*
* We have to run this whole thing with interrupts
* disabled so that the current cpu doesn't change
@@ -372,6 +373,17 @@ __tsb_context_switch:
rdpr %pstate, %g1
wrpr %g1, PSTATE_IE, %pstate
+ brz,pn %o4, 1f
+ mov SECONDARY_CONTEXT, %o5
+
+661: stxa %o4, [%o5] ASI_DMMU
+ .section .sun4v_1insn_patch, "ax"
+ .word 661b
+ stxa %o4, [%o5] ASI_MMU
+ .previous
+ flush %g6
+
+1:
TRAP_LOAD_TRAP_BLOCK(%g2, %g3)
stx %o0, [%g2 + TRAP_PER_CPU_PGD_PADDR]
diff --git a/arch/sparc/lib/U3memcpy.S b/arch/sparc/lib/U3memcpy.S
index 54f98706b03b..5a8cb37f0a3b 100644
--- a/arch/sparc/lib/U3memcpy.S
+++ b/arch/sparc/lib/U3memcpy.S
@@ -145,13 +145,13 @@ ENDPROC(U3_retl_o2_plus_GS_plus_0x08)
ENTRY(U3_retl_o2_and_7_plus_GS)
and %o2, 7, %o2
retl
- add %o2, GLOBAL_SPARE, %o2
+ add %o2, GLOBAL_SPARE, %o0
ENDPROC(U3_retl_o2_and_7_plus_GS)
ENTRY(U3_retl_o2_and_7_plus_GS_plus_8)
add GLOBAL_SPARE, 8, GLOBAL_SPARE
and %o2, 7, %o2
retl
- add %o2, GLOBAL_SPARE, %o2
+ add %o2, GLOBAL_SPARE, %o0
ENDPROC(U3_retl_o2_and_7_plus_GS_plus_8)
#endif
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 3c40ebd50f92..afa0099f3748 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -325,6 +325,29 @@ static void __update_mmu_tsb_insert(struct mm_struct *mm, unsigned long tsb_inde
}
#ifdef CONFIG_HUGETLB_PAGE
+static void __init add_huge_page_size(unsigned long size)
+{
+ unsigned int order;
+
+ if (size_to_hstate(size))
+ return;
+
+ order = ilog2(size) - PAGE_SHIFT;
+ hugetlb_add_hstate(order);
+}
+
+static int __init hugetlbpage_init(void)
+{
+ add_huge_page_size(1UL << HPAGE_64K_SHIFT);
+ add_huge_page_size(1UL << HPAGE_SHIFT);
+ add_huge_page_size(1UL << HPAGE_256MB_SHIFT);
+ add_huge_page_size(1UL << HPAGE_2GB_SHIFT);
+
+ return 0;
+}
+
+arch_initcall(hugetlbpage_init);
+
static int __init setup_hugepagesz(char *string)
{
unsigned long long hugepage_size;
@@ -364,7 +387,7 @@ static int __init setup_hugepagesz(char *string)
goto out;
}
- hugetlb_add_hstate(hugepage_shift - PAGE_SHIFT);
+ add_huge_page_size(hugepage_size);
rc = 1;
out:
@@ -1921,12 +1944,22 @@ static void __init setup_page_offset(void)
break;
case SUN4V_CHIP_SPARC_M7:
case SUN4V_CHIP_SPARC_SN:
- default:
/* M7 and later support 52-bit virtual addresses. */
sparc64_va_hole_top = 0xfff8000000000000UL;
sparc64_va_hole_bottom = 0x0008000000000000UL;
max_phys_bits = 49;
break;
+ case SUN4V_CHIP_SPARC_M8:
+ default:
+ /* M8 and later support 54-bit virtual addresses.
+ * However, restricting M8 and above VA bits to 53
+ * as 4-level page table cannot support more than
+ * 53 VA bits.
+ */
+ sparc64_va_hole_top = 0xfff0000000000000UL;
+ sparc64_va_hole_bottom = 0x0010000000000000UL;
+ max_phys_bits = 51;
+ break;
}
}
@@ -2138,6 +2171,7 @@ static void __init sun4v_linear_pte_xor_finalize(void)
*/
switch (sun4v_chip_type) {
case SUN4V_CHIP_SPARC_M7:
+ case SUN4V_CHIP_SPARC_M8:
case SUN4V_CHIP_SPARC_SN:
pagecv_flag = 0x00;
break;
@@ -2290,6 +2324,7 @@ void __init paging_init(void)
*/
switch (sun4v_chip_type) {
case SUN4V_CHIP_SPARC_M7:
+ case SUN4V_CHIP_SPARC_M8:
case SUN4V_CHIP_SPARC_SN:
page_cache4v_flag = _PAGE_CP_4V;
break;
diff --git a/arch/sparc/power/hibernate.c b/arch/sparc/power/hibernate.c
index 17bd2e167e07..df707a8ad311 100644
--- a/arch/sparc/power/hibernate.c
+++ b/arch/sparc/power/hibernate.c
@@ -35,6 +35,5 @@ void restore_processor_state(void)
{
struct mm_struct *mm = current->active_mm;
- load_secondary_context(mm);
- tsb_context_switch(mm);
+ tsb_context_switch_ctx(mm, CTX_HWBITS(mm->context));
}
diff --git a/arch/um/include/asm/tlb.h b/arch/um/include/asm/tlb.h
index 600a2e9bfee2..344d95619d03 100644
--- a/arch/um/include/asm/tlb.h
+++ b/arch/um/include/asm/tlb.h
@@ -45,7 +45,8 @@ static inline void init_tlb_gather(struct mmu_gather *tlb)
}
static inline void
-tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
+arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
+ unsigned long start, unsigned long end)
{
tlb->mm = mm;
tlb->start = start;
@@ -80,13 +81,19 @@ tlb_flush_mmu(struct mmu_gather *tlb)
tlb_flush_mmu_free(tlb);
}
-/* tlb_finish_mmu
+/* arch_tlb_finish_mmu
* Called at the end of the shootdown operation to free up any resources
* that were required.
*/
static inline void
-tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
+arch_tlb_finish_mmu(struct mmu_gather *tlb,
+ unsigned long start, unsigned long end, bool force)
{
+ if (force) {
+ tlb->start = start;
+ tlb->end = end;
+ tlb->need_flush = 1;
+ }
tlb_flush_mmu(tlb);
/* keep the page table cache within bounds */
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index fcb7604172ce..cd20ca0b4043 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -348,6 +348,7 @@ config X86_DEBUG_FPU
config PUNIT_ATOM_DEBUG
tristate "ATOM Punit debug driver"
+ depends on PCI
select DEBUG_FS
select IOSF_MBI
---help---
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index 0d810fb15eac..d88a2fddba8c 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -73,12 +73,13 @@ UBSAN_SANITIZE := n
$(obj)/bzImage: asflags-y := $(SVGA_MODE)
quiet_cmd_image = BUILD $@
+silent_redirect_image = >/dev/null
cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin \
- $(obj)/zoffset.h $@
+ $(obj)/zoffset.h $@ $($(quiet)redirect_image)
$(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE
$(call if_changed,image)
- @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
+ @$(kecho) 'Kernel: $@ is ready' ' (#'`cat .version`')'
OBJCOPYFLAGS_vmlinux.bin := -O binary -R .note -R .comment -S
$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 2c860ad4fe06..8a958274b54c 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -34,6 +34,7 @@ KBUILD_CFLAGS += $(cflags-y)
KBUILD_CFLAGS += -mno-mmx -mno-sse
KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector)
+KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member)
KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
GCOV_PROFILE := n
diff --git a/arch/x86/boot/string.c b/arch/x86/boot/string.c
index 630e3664906b..16f49123d747 100644
--- a/arch/x86/boot/string.c
+++ b/arch/x86/boot/string.c
@@ -16,6 +16,15 @@
#include "ctype.h"
#include "string.h"
+/*
+ * Undef these macros so that the functions that we provide
+ * here will have the correct names regardless of how string.h
+ * may have chosen to #define them.
+ */
+#undef memcpy
+#undef memset
+#undef memcmp
+
int memcmp(const void *s1, const void *s2, size_t len)
{
bool diff;
diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig
index 6cf79e1a6830..0eb9f92f3717 100644
--- a/arch/x86/configs/i386_defconfig
+++ b/arch/x86/configs/i386_defconfig
@@ -1,5 +1,4 @@
# CONFIG_64BIT is not set
-CONFIG_EXPERIMENTAL=y
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -125,7 +124,6 @@ CONFIG_NF_CONNTRACK_IPV4=y
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
-CONFIG_IP_NF_TARGET_ULOG=y
CONFIG_NF_NAT=y
CONFIG_IP_NF_TARGET_MASQUERADE=y
CONFIG_IP_NF_MANGLE=y
@@ -255,7 +253,6 @@ CONFIG_USB_OHCI_HCD=y
CONFIG_USB_UHCI_HCD=y
CONFIG_USB_PRINTER=y
CONFIG_USB_STORAGE=y
-CONFIG_USB_LIBUSUAL=y
CONFIG_EDAC=y
CONFIG_RTC_CLASS=y
# CONFIG_RTC_HCTOSYS is not set
diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig
index de45f57b410d..4a4b16e56d35 100644
--- a/arch/x86/configs/x86_64_defconfig
+++ b/arch/x86/configs/x86_64_defconfig
@@ -1,4 +1,3 @@
-CONFIG_EXPERIMENTAL=y
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -124,7 +123,6 @@ CONFIG_NF_CONNTRACK_IPV4=y
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
-CONFIG_IP_NF_TARGET_ULOG=y
CONFIG_NF_NAT=y
CONFIG_IP_NF_TARGET_MASQUERADE=y
CONFIG_IP_NF_MANGLE=y
@@ -251,7 +249,6 @@ CONFIG_USB_OHCI_HCD=y
CONFIG_USB_UHCI_HCD=y
CONFIG_USB_PRINTER=y
CONFIG_USB_STORAGE=y
-CONFIG_USB_LIBUSUAL=y
CONFIG_EDAC=y
CONFIG_RTC_CLASS=y
# CONFIG_RTC_HCTOSYS is not set
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index a9a8027a6c0e..d271fb79248f 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -705,6 +705,7 @@ apicinterrupt X86_PLATFORM_IPI_VECTOR x86_platform_ipi smp_x86_platform_ipi
#ifdef CONFIG_HAVE_KVM
apicinterrupt3 POSTED_INTR_VECTOR kvm_posted_intr_ipi smp_kvm_posted_intr_ipi
apicinterrupt3 POSTED_INTR_WAKEUP_VECTOR kvm_posted_intr_wakeup_ipi smp_kvm_posted_intr_wakeup_ipi
+apicinterrupt3 POSTED_INTR_NESTED_VECTOR kvm_posted_intr_nested_ipi smp_kvm_posted_intr_nested_ipi
#endif
#ifdef CONFIG_X86_MCE_THRESHOLD
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index ff1ea2fb9705..8e3db8f642a7 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -191,8 +191,8 @@ static void release_pmc_hardware(void) {}
static bool check_hw_exists(void)
{
- u64 val, val_fail, val_new= ~0;
- int i, reg, reg_fail, ret = 0;
+ u64 val, val_fail = -1, val_new= ~0;
+ int i, reg, reg_fail = -1, ret = 0;
int bios_fail = 0;
int reg_safe = -1;
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index aa62437d1aa1..98b0f0729527 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -1708,6 +1708,120 @@ static __initconst const u64 glm_hw_cache_extra_regs
},
};
+static __initconst const u64 glp_hw_cache_event_ids
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ [C(L1D)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = 0x81d0, /* MEM_UOPS_RETIRED.ALL_LOADS */
+ [C(RESULT_MISS)] = 0x0,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = 0x82d0, /* MEM_UOPS_RETIRED.ALL_STORES */
+ [C(RESULT_MISS)] = 0x0,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = 0x0,
+ [C(RESULT_MISS)] = 0x0,
+ },
+ },
+ [C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = 0x0380, /* ICACHE.ACCESSES */
+ [C(RESULT_MISS)] = 0x0280, /* ICACHE.MISSES */
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = -1,
+ [C(RESULT_MISS)] = -1,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = 0x0,
+ [C(RESULT_MISS)] = 0x0,
+ },
+ },
+ [C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = 0x1b7, /* OFFCORE_RESPONSE */
+ [C(RESULT_MISS)] = 0x1b7, /* OFFCORE_RESPONSE */
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = 0x1b7, /* OFFCORE_RESPONSE */
+ [C(RESULT_MISS)] = 0x1b7, /* OFFCORE_RESPONSE */
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = 0x0,
+ [C(RESULT_MISS)] = 0x0,
+ },
+ },
+ [C(DTLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = 0x81d0, /* MEM_UOPS_RETIRED.ALL_LOADS */
+ [C(RESULT_MISS)] = 0xe08, /* DTLB_LOAD_MISSES.WALK_COMPLETED */
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = 0x82d0, /* MEM_UOPS_RETIRED.ALL_STORES */
+ [C(RESULT_MISS)] = 0xe49, /* DTLB_STORE_MISSES.WALK_COMPLETED */
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = 0x0,
+ [C(RESULT_MISS)] = 0x0,
+ },
+ },
+ [C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = 0x00c0, /* INST_RETIRED.ANY_P */
+ [C(RESULT_MISS)] = 0x0481, /* ITLB.MISS */
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = -1,
+ [C(RESULT_MISS)] = -1,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = -1,
+ [C(RESULT_MISS)] = -1,
+ },
+ },
+ [C(BPU)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
+ [C(RESULT_MISS)] = 0x00c5, /* BR_MISP_RETIRED.ALL_BRANCHES */
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = -1,
+ [C(RESULT_MISS)] = -1,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = -1,
+ [C(RESULT_MISS)] = -1,
+ },
+ },
+};
+
+static __initconst const u64 glp_hw_cache_extra_regs
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ [C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = GLM_DEMAND_READ|
+ GLM_LLC_ACCESS,
+ [C(RESULT_MISS)] = GLM_DEMAND_READ|
+ GLM_LLC_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = GLM_DEMAND_WRITE|
+ GLM_LLC_ACCESS,
+ [C(RESULT_MISS)] = GLM_DEMAND_WRITE|
+ GLM_LLC_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = 0x0,
+ [C(RESULT_MISS)] = 0x0,
+ },
+ },
+};
+
#define KNL_OT_L2_HITE BIT_ULL(19) /* Other Tile L2 Hit */
#define KNL_OT_L2_HITF BIT_ULL(20) /* Other Tile L2 Hit */
#define KNL_MCDRAM_LOCAL BIT_ULL(21)
@@ -3016,6 +3130,9 @@ static int hsw_hw_config(struct perf_event *event)
return 0;
}
+static struct event_constraint counter0_constraint =
+ INTEL_ALL_EVENT_CONSTRAINT(0, 0x1);
+
static struct event_constraint counter2_constraint =
EVENT_CONSTRAINT(0, 0x4, 0);
@@ -3037,6 +3154,21 @@ hsw_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
return c;
}
+static struct event_constraint *
+glp_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+ struct perf_event *event)
+{
+ struct event_constraint *c;
+
+ /* :ppp means to do reduced skid PEBS which is PMC0 only. */
+ if (event->attr.precise_ip == 3)
+ return &counter0_constraint;
+
+ c = intel_get_event_constraints(cpuc, idx, event);
+
+ return c;
+}
+
/*
* Broadwell:
*
@@ -3265,10 +3397,8 @@ static void intel_pmu_cpu_dying(int cpu)
static void intel_pmu_sched_task(struct perf_event_context *ctx,
bool sched_in)
{
- if (x86_pmu.pebs_active)
- intel_pmu_pebs_sched_task(ctx, sched_in);
- if (x86_pmu.lbr_nr)
- intel_pmu_lbr_sched_task(ctx, sched_in);
+ intel_pmu_pebs_sched_task(ctx, sched_in);
+ intel_pmu_lbr_sched_task(ctx, sched_in);
}
PMU_FORMAT_ATTR(offcore_rsp, "config1:0-63");
@@ -3838,6 +3968,32 @@ __init int intel_pmu_init(void)
pr_cont("Goldmont events, ");
break;
+ case INTEL_FAM6_ATOM_GEMINI_LAKE:
+ memcpy(hw_cache_event_ids, glp_hw_cache_event_ids,
+ sizeof(hw_cache_event_ids));
+ memcpy(hw_cache_extra_regs, glp_hw_cache_extra_regs,
+ sizeof(hw_cache_extra_regs));
+
+ intel_pmu_lbr_init_skl();
+
+ x86_pmu.event_constraints = intel_slm_event_constraints;
+ x86_pmu.pebs_constraints = intel_glp_pebs_event_constraints;
+ x86_pmu.extra_regs = intel_glm_extra_regs;
+ /*
+ * It's recommended to use CPU_CLK_UNHALTED.CORE_P + NPEBS
+ * for precise cycles.
+ */
+ x86_pmu.pebs_aliases = NULL;
+ x86_pmu.pebs_prec_dist = true;
+ x86_pmu.lbr_pt_coexist = true;
+ x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+ x86_pmu.get_event_constraints = glp_get_event_constraints;
+ x86_pmu.cpu_events = glm_events_attrs;
+ /* Goldmont Plus has 4-wide pipeline */
+ event_attr_td_total_slots_scale_glm.event_str = "4";
+ pr_cont("Goldmont plus events, ");
+ break;
+
case INTEL_FAM6_WESTMERE:
case INTEL_FAM6_WESTMERE_EP:
case INTEL_FAM6_WESTMERE_EX:
diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c
index 238ae3248ba5..4cf100ff2a37 100644
--- a/arch/x86/events/intel/cstate.c
+++ b/arch/x86/events/intel/cstate.c
@@ -40,16 +40,16 @@
* Model specific counters:
* MSR_CORE_C1_RES: CORE C1 Residency Counter
* perf code: 0x00
- * Available model: SLM,AMT
+ * Available model: SLM,AMT,GLM
* Scope: Core (each processor core has a MSR)
* MSR_CORE_C3_RESIDENCY: CORE C3 Residency Counter
* perf code: 0x01
- * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL
+ * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,GLM
* Scope: Core
* MSR_CORE_C6_RESIDENCY: CORE C6 Residency Counter
* perf code: 0x02
* Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW
- * SKL,KNL
+ * SKL,KNL,GLM
* Scope: Core
* MSR_CORE_C7_RESIDENCY: CORE C7 Residency Counter
* perf code: 0x03
@@ -57,16 +57,17 @@
* Scope: Core
* MSR_PKG_C2_RESIDENCY: Package C2 Residency Counter.
* perf code: 0x00
- * Available model: SNB,IVB,HSW,BDW,SKL,KNL
+ * Available model: SNB,IVB,HSW,BDW,SKL,KNL,GLM
* Scope: Package (physical package)
* MSR_PKG_C3_RESIDENCY: Package C3 Residency Counter.
* perf code: 0x01
* Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,KNL
+ * GLM
* Scope: Package (physical package)
* MSR_PKG_C6_RESIDENCY: Package C6 Residency Counter.
* perf code: 0x02
* Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW
- * SKL,KNL
+ * SKL,KNL,GLM
* Scope: Package (physical package)
* MSR_PKG_C7_RESIDENCY: Package C7 Residency Counter.
* perf code: 0x03
@@ -82,7 +83,7 @@
* Scope: Package (physical package)
* MSR_PKG_C10_RESIDENCY: Package C10 Residency Counter.
* perf code: 0x06
- * Available model: HSW ULT only
+ * Available model: HSW ULT, GLM
* Scope: Package (physical package)
*
*/
@@ -504,6 +505,17 @@ static const struct cstate_model knl_cstates __initconst = {
};
+static const struct cstate_model glm_cstates __initconst = {
+ .core_events = BIT(PERF_CSTATE_CORE_C1_RES) |
+ BIT(PERF_CSTATE_CORE_C3_RES) |
+ BIT(PERF_CSTATE_CORE_C6_RES),
+
+ .pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
+ BIT(PERF_CSTATE_PKG_C3_RES) |
+ BIT(PERF_CSTATE_PKG_C6_RES) |
+ BIT(PERF_CSTATE_PKG_C10_RES),
+};
+
#define X86_CSTATES_MODEL(model, states) \
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long) &(states) }
@@ -546,6 +558,8 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = {
X86_CSTATES_MODEL(INTEL_FAM6_XEON_PHI_KNL, knl_cstates),
X86_CSTATES_MODEL(INTEL_FAM6_XEON_PHI_KNM, knl_cstates),
+
+ X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT, glm_cstates),
{ },
};
MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match);
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index c6d23ffe422d..a322fed5f8ed 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -606,12 +606,6 @@ static inline void intel_pmu_drain_pebs_buffer(void)
x86_pmu.drain_pebs(&regs);
}
-void intel_pmu_pebs_sched_task(struct perf_event_context *ctx, bool sched_in)
-{
- if (!sched_in)
- intel_pmu_drain_pebs_buffer();
-}
-
/*
* PEBS
*/
@@ -651,6 +645,12 @@ struct event_constraint intel_glm_pebs_event_constraints[] = {
EVENT_CONSTRAINT_END
};
+struct event_constraint intel_glp_pebs_event_constraints[] = {
+ /* Allow all events as PEBS with no flags */
+ INTEL_ALL_EVENT_CONSTRAINT(0, 0xf),
+ EVENT_CONSTRAINT_END
+};
+
struct event_constraint intel_nehalem_pebs_event_constraints[] = {
INTEL_PLD_CONSTRAINT(0x100b, 0xf), /* MEM_INST_RETIRED.* */
INTEL_FLAGS_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */
@@ -816,6 +816,14 @@ static inline bool pebs_needs_sched_cb(struct cpu_hw_events *cpuc)
return cpuc->n_pebs && (cpuc->n_pebs == cpuc->n_large_pebs);
}
+void intel_pmu_pebs_sched_task(struct perf_event_context *ctx, bool sched_in)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ if (!sched_in && pebs_needs_sched_cb(cpuc))
+ intel_pmu_drain_pebs_buffer();
+}
+
static inline void pebs_update_threshold(struct cpu_hw_events *cpuc)
{
struct debug_store *ds = cpuc->ds;
@@ -889,6 +897,8 @@ void intel_pmu_pebs_enable(struct perf_event *event)
if (hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) {
ds->pebs_event_reset[hwc->idx] =
(u64)(-hwc->sample_period) & x86_pmu.cntval_mask;
+ } else {
+ ds->pebs_event_reset[hwc->idx] = 0;
}
}
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index eb261656a320..955457a30197 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -380,8 +380,12 @@ static void __intel_pmu_lbr_save(struct x86_perf_task_context *task_ctx)
void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in)
{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
struct x86_perf_task_context *task_ctx;
+ if (!cpuc->lbr_users)
+ return;
+
/*
* If LBR callstack feature is enabled and the stack was saved when
* the task was scheduled out, restore the stack. Otherwise flush
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index dae2fedc1601..4f9127644b80 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -316,7 +316,7 @@
#define SKX_UPI_PCI_PMON_CTL0 0x350
#define SKX_UPI_PCI_PMON_CTR0 0x318
#define SKX_UPI_PCI_PMON_BOX_CTL 0x378
-#define SKX_PMON_CTL_UMASK_EXT 0xff
+#define SKX_UPI_CTL_UMASK_EXT 0xffefff
/* SKX M2M */
#define SKX_M2M_PCI_PMON_CTL0 0x228
@@ -328,7 +328,7 @@ DEFINE_UNCORE_FORMAT_ATTR(event2, event, "config:0-6");
DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21");
DEFINE_UNCORE_FORMAT_ATTR(use_occ_ctr, use_occ_ctr, "config:7");
DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
-DEFINE_UNCORE_FORMAT_ATTR(umask_ext, umask, "config:8-15,32-39");
+DEFINE_UNCORE_FORMAT_ATTR(umask_ext, umask, "config:8-15,32-43,45-55");
DEFINE_UNCORE_FORMAT_ATTR(qor, qor, "config:16");
DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19");
@@ -351,7 +351,6 @@ DEFINE_UNCORE_FORMAT_ATTR(filter_cid, filter_cid, "config1:5");
DEFINE_UNCORE_FORMAT_ATTR(filter_link, filter_link, "config1:5-8");
DEFINE_UNCORE_FORMAT_ATTR(filter_link2, filter_link, "config1:6-8");
DEFINE_UNCORE_FORMAT_ATTR(filter_link3, filter_link, "config1:12");
-DEFINE_UNCORE_FORMAT_ATTR(filter_link4, filter_link, "config1:9-12");
DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17");
DEFINE_UNCORE_FORMAT_ATTR(filter_nid2, filter_nid, "config1:32-47");
DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22");
@@ -3302,7 +3301,6 @@ static struct attribute *skx_uncore_cha_formats_attr[] = {
&format_attr_inv.attr,
&format_attr_thresh8.attr,
&format_attr_filter_tid4.attr,
- &format_attr_filter_link4.attr,
&format_attr_filter_state5.attr,
&format_attr_filter_rem.attr,
&format_attr_filter_loc.attr,
@@ -3312,7 +3310,6 @@ static struct attribute *skx_uncore_cha_formats_attr[] = {
&format_attr_filter_opc_0.attr,
&format_attr_filter_opc_1.attr,
&format_attr_filter_nc.attr,
- &format_attr_filter_c6.attr,
&format_attr_filter_isoc.attr,
NULL,
};
@@ -3333,8 +3330,11 @@ static struct extra_reg skx_uncore_cha_extra_regs[] = {
SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4),
SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4),
SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4),
- SNBEP_CBO_EVENT_EXTRA_REG(0x2134, 0xffff, 0x4),
- SNBEP_CBO_EVENT_EXTRA_REG(0x8134, 0xffff, 0x4),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x3134, 0xffff, 0x4),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x9134, 0xffff, 0x4),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x35, 0xff, 0x8),
+ SNBEP_CBO_EVENT_EXTRA_REG(0x36, 0xff, 0x8),
+ EVENT_EXTRA_END
};
static u64 skx_cha_filter_mask(int fields)
@@ -3347,6 +3347,17 @@ static u64 skx_cha_filter_mask(int fields)
mask |= SKX_CHA_MSR_PMON_BOX_FILTER_LINK;
if (fields & 0x4)
mask |= SKX_CHA_MSR_PMON_BOX_FILTER_STATE;
+ if (fields & 0x8) {
+ mask |= SKX_CHA_MSR_PMON_BOX_FILTER_REM;
+ mask |= SKX_CHA_MSR_PMON_BOX_FILTER_LOC;
+ mask |= SKX_CHA_MSR_PMON_BOX_FILTER_ALL_OPC;
+ mask |= SKX_CHA_MSR_PMON_BOX_FILTER_NM;
+ mask |= SKX_CHA_MSR_PMON_BOX_FILTER_NOT_NM;
+ mask |= SKX_CHA_MSR_PMON_BOX_FILTER_OPC0;
+ mask |= SKX_CHA_MSR_PMON_BOX_FILTER_OPC1;
+ mask |= SKX_CHA_MSR_PMON_BOX_FILTER_NC;
+ mask |= SKX_CHA_MSR_PMON_BOX_FILTER_ISOC;
+ }
return mask;
}
@@ -3492,6 +3503,26 @@ static struct intel_uncore_type skx_uncore_irp = {
.format_group = &skx_uncore_format_group,
};
+static struct attribute *skx_uncore_pcu_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh8.attr,
+ &format_attr_occ_invert.attr,
+ &format_attr_occ_edge_det.attr,
+ &format_attr_filter_band0.attr,
+ &format_attr_filter_band1.attr,
+ &format_attr_filter_band2.attr,
+ &format_attr_filter_band3.attr,
+ NULL,
+};
+
+static struct attribute_group skx_uncore_pcu_format_group = {
+ .name = "format",
+ .attrs = skx_uncore_pcu_formats_attr,
+};
+
static struct intel_uncore_ops skx_uncore_pcu_ops = {
IVBEP_UNCORE_MSR_OPS_COMMON_INIT(),
.hw_config = hswep_pcu_hw_config,
@@ -3510,7 +3541,7 @@ static struct intel_uncore_type skx_uncore_pcu = {
.box_ctl = HSWEP_PCU_MSR_PMON_BOX_CTL,
.num_shared_regs = 1,
.ops = &skx_uncore_pcu_ops,
- .format_group = &snbep_uncore_pcu_format_group,
+ .format_group = &skx_uncore_pcu_format_group,
};
static struct intel_uncore_type *skx_msr_uncores[] = {
@@ -3603,8 +3634,8 @@ static struct intel_uncore_type skx_uncore_upi = {
.perf_ctr_bits = 48,
.perf_ctr = SKX_UPI_PCI_PMON_CTR0,
.event_ctl = SKX_UPI_PCI_PMON_CTL0,
- .event_mask = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
- .event_mask_ext = SKX_PMON_CTL_UMASK_EXT,
+ .event_mask = SNBEP_PMON_RAW_EVENT_MASK,
+ .event_mask_ext = SKX_UPI_CTL_UMASK_EXT,
.box_ctl = SKX_UPI_PCI_PMON_BOX_CTL,
.ops = &skx_upi_uncore_pci_ops,
.format_group = &skx_upi_uncore_format_group,
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index 53728eea1bed..476aec3a4cab 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -879,6 +879,8 @@ extern struct event_constraint intel_slm_pebs_event_constraints[];
extern struct event_constraint intel_glm_pebs_event_constraints[];
+extern struct event_constraint intel_glp_pebs_event_constraints[];
+
extern struct event_constraint intel_nehalem_pebs_event_constraints[];
extern struct event_constraint intel_westmere_pebs_event_constraints[];
diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h
index 39e702d90cdb..aa6b2023d8f8 100644
--- a/arch/x86/include/asm/bug.h
+++ b/arch/x86/include/asm/bug.h
@@ -35,7 +35,7 @@
#define _BUG_FLAGS(ins, flags) \
do { \
asm volatile("1:\t" ins "\n" \
- ".pushsection __bug_table,\"a\"\n" \
+ ".pushsection __bug_table,\"aw\"\n" \
"2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \
"\t" __BUG_REL(%c0) "\t# bug_entry::file\n" \
"\t.word %c1" "\t# bug_entry::line\n" \
@@ -52,7 +52,7 @@ do { \
#define _BUG_FLAGS(ins, flags) \
do { \
asm volatile("1:\t" ins "\n" \
- ".pushsection __bug_table,\"a\"\n" \
+ ".pushsection __bug_table,\"aw\"\n" \
"2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \
"\t.word %c0" "\t# bug_entry::flags\n" \
"\t.org 2b+%c1\n" \
diff --git a/arch/x86/include/asm/entry_arch.h b/arch/x86/include/asm/entry_arch.h
index df002992d8fd..07b06955a05d 100644
--- a/arch/x86/include/asm/entry_arch.h
+++ b/arch/x86/include/asm/entry_arch.h
@@ -25,6 +25,8 @@ BUILD_INTERRUPT3(kvm_posted_intr_ipi, POSTED_INTR_VECTOR,
smp_kvm_posted_intr_ipi)
BUILD_INTERRUPT3(kvm_posted_intr_wakeup_ipi, POSTED_INTR_WAKEUP_VECTOR,
smp_kvm_posted_intr_wakeup_ipi)
+BUILD_INTERRUPT3(kvm_posted_intr_nested_ipi, POSTED_INTR_NESTED_VECTOR,
+ smp_kvm_posted_intr_nested_ipi)
#endif
/*
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index 9b76cd331990..ad1ed531febc 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -15,6 +15,7 @@ typedef struct {
#ifdef CONFIG_HAVE_KVM
unsigned int kvm_posted_intr_ipis;
unsigned int kvm_posted_intr_wakeup_ipis;
+ unsigned int kvm_posted_intr_nested_ipis;
#endif
unsigned int x86_platform_ipis; /* arch dependent */
unsigned int apic_perf_irqs;
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index b90e1053049b..d6dbafbd4207 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -30,6 +30,7 @@ extern asmlinkage void apic_timer_interrupt(void);
extern asmlinkage void x86_platform_ipi(void);
extern asmlinkage void kvm_posted_intr_ipi(void);
extern asmlinkage void kvm_posted_intr_wakeup_ipi(void);
+extern asmlinkage void kvm_posted_intr_nested_ipi(void);
extern asmlinkage void error_interrupt(void);
extern asmlinkage void irq_work_interrupt(void);
@@ -62,6 +63,7 @@ extern void trace_call_function_single_interrupt(void);
#define trace_reboot_interrupt reboot_interrupt
#define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi
#define trace_kvm_posted_intr_wakeup_ipi kvm_posted_intr_wakeup_ipi
+#define trace_kvm_posted_intr_nested_ipi kvm_posted_intr_nested_ipi
#endif /* CONFIG_TRACING */
#ifdef CONFIG_X86_LOCAL_APIC
diff --git a/arch/x86/include/asm/hypervisor.h b/arch/x86/include/asm/hypervisor.h
index 21126155a739..0ead9dbb9130 100644
--- a/arch/x86/include/asm/hypervisor.h
+++ b/arch/x86/include/asm/hypervisor.h
@@ -43,6 +43,9 @@ struct hypervisor_x86 {
/* pin current vcpu to specified physical cpu (run rarely) */
void (*pin_vcpu)(int);
+
+ /* called during init_mem_mapping() to setup early mappings. */
+ void (*init_mem_mapping)(void);
};
extern const struct hypervisor_x86 *x86_hyper;
@@ -57,8 +60,15 @@ extern const struct hypervisor_x86 x86_hyper_kvm;
extern void init_hypervisor_platform(void);
extern bool hypervisor_x2apic_available(void);
extern void hypervisor_pin_vcpu(int cpu);
+
+static inline void hypervisor_init_mem_mapping(void)
+{
+ if (x86_hyper && x86_hyper->init_mem_mapping)
+ x86_hyper->init_mem_mapping();
+}
#else
static inline void init_hypervisor_platform(void) { }
static inline bool hypervisor_x2apic_available(void) { return false; }
+static inline void hypervisor_init_mem_mapping(void) { }
#endif /* CONFIG_HYPERVISOR_GUEST */
#endif /* _ASM_X86_HYPERVISOR_H */
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 7afb0e2f07f4..48febf07e828 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -328,13 +328,13 @@ static inline unsigned type in##bwl##_p(int port) \
static inline void outs##bwl(int port, const void *addr, unsigned long count) \
{ \
asm volatile("rep; outs" #bwl \
- : "+S"(addr), "+c"(count) : "d"(port)); \
+ : "+S"(addr), "+c"(count) : "d"(port) : "memory"); \
} \
\
static inline void ins##bwl(int port, void *addr, unsigned long count) \
{ \
asm volatile("rep; ins" #bwl \
- : "+D"(addr), "+c"(count) : "d"(port)); \
+ : "+D"(addr), "+c"(count) : "d"(port) : "memory"); \
}
BUILDIO(b, b, char)
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index 6ca9fd6234e1..aaf8d28b5d00 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -83,7 +83,6 @@
*/
#define X86_PLATFORM_IPI_VECTOR 0xf7
-#define POSTED_INTR_WAKEUP_VECTOR 0xf1
/*
* IRQ work vector:
*/
@@ -98,6 +97,8 @@
/* Vector for KVM to deliver posted interrupt IPI */
#ifdef CONFIG_HAVE_KVM
#define POSTED_INTR_VECTOR 0xf2
+#define POSTED_INTR_WAKEUP_VECTOR 0xf1
+#define POSTED_INTR_NESTED_VECTOR 0xf0
#endif
/*
diff --git a/arch/x86/include/asm/kprobes.h b/arch/x86/include/asm/kprobes.h
index 34b984c60790..6cf65437b5e5 100644
--- a/arch/x86/include/asm/kprobes.h
+++ b/arch/x86/include/asm/kprobes.h
@@ -52,10 +52,10 @@ typedef u8 kprobe_opcode_t;
#define flush_insn_slot(p) do { } while (0)
/* optinsn template addresses */
-extern __visible kprobe_opcode_t optprobe_template_entry;
-extern __visible kprobe_opcode_t optprobe_template_val;
-extern __visible kprobe_opcode_t optprobe_template_call;
-extern __visible kprobe_opcode_t optprobe_template_end;
+extern __visible kprobe_opcode_t optprobe_template_entry[];
+extern __visible kprobe_opcode_t optprobe_template_val[];
+extern __visible kprobe_opcode_t optprobe_template_call[];
+extern __visible kprobe_opcode_t optprobe_template_end[];
#define MAX_OPTIMIZED_LENGTH (MAX_INSN_SIZE + RELATIVE_ADDR_SIZE)
#define MAX_OPTINSN_SIZE \
(((unsigned long)&optprobe_template_end - \
diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
index ecfcb6643c9b..265c907d7d4c 100644
--- a/arch/x86/include/asm/mmu_context.h
+++ b/arch/x86/include/asm/mmu_context.h
@@ -293,7 +293,7 @@ static inline unsigned long __get_current_cr3_fast(void)
unsigned long cr3 = __pa(this_cpu_read(cpu_tlbstate.loaded_mm)->pgd);
/* For now, be very restrictive about when this can be called. */
- VM_WARN_ON(in_nmi() || !in_atomic());
+ VM_WARN_ON(in_nmi() || preemptible());
VM_BUG_ON(cr3 != __read_cr3());
return cr3;
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
index cb976bab6299..9ffc36bfe4cd 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -84,7 +84,7 @@ struct pv_init_ops {
*/
unsigned (*patch)(u8 type, u16 clobber, void *insnbuf,
unsigned long addr, unsigned len);
-};
+} __no_randomize_layout;
struct pv_lazy_ops {
@@ -92,12 +92,12 @@ struct pv_lazy_ops {
void (*enter)(void);
void (*leave)(void);
void (*flush)(void);
-};
+} __no_randomize_layout;
struct pv_time_ops {
unsigned long long (*sched_clock)(void);
unsigned long long (*steal_clock)(int cpu);
-};
+} __no_randomize_layout;
struct pv_cpu_ops {
/* hooks for various privileged instructions */
@@ -176,7 +176,7 @@ struct pv_cpu_ops {
void (*start_context_switch)(struct task_struct *prev);
void (*end_context_switch)(struct task_struct *next);
-};
+} __no_randomize_layout;
struct pv_irq_ops {
/*
@@ -199,7 +199,7 @@ struct pv_irq_ops {
#ifdef CONFIG_X86_64
void (*adjust_exception_frame)(void);
#endif
-};
+} __no_randomize_layout;
struct pv_mmu_ops {
unsigned long (*read_cr2)(void);
@@ -305,7 +305,7 @@ struct pv_mmu_ops {
an mfn. We can tell which is which from the index. */
void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx,
phys_addr_t phys, pgprot_t flags);
-};
+} __no_randomize_layout;
struct arch_spinlock;
#ifdef CONFIG_SMP
@@ -322,7 +322,7 @@ struct pv_lock_ops {
void (*kick)(int cpu);
struct paravirt_callee_save vcpu_is_preempted;
-};
+} __no_randomize_layout;
/* This contains all the paravirt structures: we get a convenient
* number for each function using the offset which we use to indicate
@@ -334,7 +334,7 @@ struct paravirt_patch_template {
struct pv_irq_ops pv_irq_ops;
struct pv_mmu_ops pv_mmu_ops;
struct pv_lock_ops pv_lock_ops;
-};
+} __no_randomize_layout;
extern struct pv_info pv_info;
extern struct pv_init_ops pv_init_ops;
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 6a79547e8ee0..028245e1c42b 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -129,7 +129,7 @@ struct cpuinfo_x86 {
/* Index into per_cpu list: */
u16 cpu_index;
u32 microcode;
-};
+} __randomize_layout;
struct cpuid_regs {
u32 eax, ebx, ecx, edx;
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 6bb680671088..7491e73d9253 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -347,6 +347,14 @@ static void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
struct mpc_intsrc mp_irq;
/*
+ * Check bus_irq boundary.
+ */
+ if (bus_irq >= NR_IRQS_LEGACY) {
+ pr_warn("Invalid bus_irq %u for legacy override\n", bus_irq);
+ return;
+ }
+
+ /*
* Convert 'gsi' to 'ioapic.pin'.
*/
ioapic = mp_find_ioapic(gsi);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index b4f5f73febdb..237e9c2341c7 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2093,7 +2093,7 @@ static inline void __init check_timer(void)
int idx;
idx = find_irq_entry(apic1, pin1, mp_INT);
if (idx != -1 && irq_trigger(idx))
- unmask_ioapic_irq(irq_get_chip_data(0));
+ unmask_ioapic_irq(irq_get_irq_data(0));
}
irq_domain_deactivate_irq(irq_data);
irq_domain_activate_irq(irq_data);
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index bb5abe8f5fd4..3b9e220621f8 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -134,6 +134,7 @@ static void init_amd_k6(struct cpuinfo_x86 *c)
n = K6_BUG_LOOP;
f_vide = vide;
+ OPTIMIZER_HIDE_VAR(f_vide);
d = rdtsc();
while (n--)
f_vide();
diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c
index d869c8671e36..7cf7c70b6ef2 100644
--- a/arch/x86/kernel/cpu/aperfmperf.c
+++ b/arch/x86/kernel/cpu/aperfmperf.c
@@ -8,20 +8,25 @@
* This file is licensed under GPLv2.
*/
-#include <linux/jiffies.h>
+#include <linux/delay.h>
+#include <linux/ktime.h>
#include <linux/math64.h>
#include <linux/percpu.h>
#include <linux/smp.h>
struct aperfmperf_sample {
unsigned int khz;
- unsigned long jiffies;
+ ktime_t time;
u64 aperf;
u64 mperf;
};
static DEFINE_PER_CPU(struct aperfmperf_sample, samples);
+#define APERFMPERF_CACHE_THRESHOLD_MS 10
+#define APERFMPERF_REFRESH_DELAY_MS 20
+#define APERFMPERF_STALE_THRESHOLD_MS 1000
+
/*
* aperfmperf_snapshot_khz()
* On the current CPU, snapshot APERF, MPERF, and jiffies
@@ -33,9 +38,11 @@ static void aperfmperf_snapshot_khz(void *dummy)
u64 aperf, aperf_delta;
u64 mperf, mperf_delta;
struct aperfmperf_sample *s = this_cpu_ptr(&samples);
+ ktime_t now = ktime_get();
+ s64 time_delta = ktime_ms_delta(now, s->time);
- /* Don't bother re-computing within 10 ms */
- if (time_before(jiffies, s->jiffies + HZ/100))
+ /* Don't bother re-computing within the cache threshold time. */
+ if (time_delta < APERFMPERF_CACHE_THRESHOLD_MS)
return;
rdmsrl(MSR_IA32_APERF, aperf);
@@ -51,22 +58,21 @@ static void aperfmperf_snapshot_khz(void *dummy)
if (mperf_delta == 0)
return;
- /*
- * if (cpu_khz * aperf_delta) fits into ULLONG_MAX, then
- * khz = (cpu_khz * aperf_delta) / mperf_delta
- */
- if (div64_u64(ULLONG_MAX, cpu_khz) > aperf_delta)
- s->khz = div64_u64((cpu_khz * aperf_delta), mperf_delta);
- else /* khz = aperf_delta / (mperf_delta / cpu_khz) */
- s->khz = div64_u64(aperf_delta,
- div64_u64(mperf_delta, cpu_khz));
- s->jiffies = jiffies;
+ s->time = now;
s->aperf = aperf;
s->mperf = mperf;
+
+ /* If the previous iteration was too long ago, discard it. */
+ if (time_delta > APERFMPERF_STALE_THRESHOLD_MS)
+ s->khz = 0;
+ else
+ s->khz = div64_u64((cpu_khz * aperf_delta), mperf_delta);
}
unsigned int arch_freq_get_on_cpu(int cpu)
{
+ unsigned int khz;
+
if (!cpu_khz)
return 0;
@@ -74,6 +80,12 @@ unsigned int arch_freq_get_on_cpu(int cpu)
return 0;
smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1);
+ khz = per_cpu(samples.khz, cpu);
+ if (khz)
+ return khz;
+
+ msleep(APERFMPERF_REFRESH_DELAY_MS);
+ smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1);
return per_cpu(samples.khz, cpu);
}
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 3fe45f84ced4..cbf1f6ba39a8 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -235,8 +235,7 @@ static void __init dtb_add_ioapic(struct device_node *dn)
ret = of_address_to_resource(dn, 0, &r);
if (ret) {
- printk(KERN_ERR "Can't obtain address from node %s.\n",
- dn->full_name);
+ printk(KERN_ERR "Can't obtain address from device node %pOF.\n", dn);
return;
}
mp_register_ioapic(++ioapic_id, r.start, gsi_top, &cfg);
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index d907c3d8633f..a4516ca4c4f3 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -527,6 +527,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = {
INTEL_BXT_IDS(&gen9_early_ops),
INTEL_KBL_IDS(&gen9_early_ops),
INTEL_GLK_IDS(&gen9_early_ops),
+ INTEL_CNL_IDS(&gen9_early_ops),
};
static void __init
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 16f82a3aaec7..8ce4212e2b8d 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -345,21 +345,10 @@ static int hpet_shutdown(struct clock_event_device *evt, int timer)
return 0;
}
-static int hpet_resume(struct clock_event_device *evt, int timer)
-{
- if (!timer) {
- hpet_enable_legacy_int();
- } else {
- struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
-
- irq_domain_deactivate_irq(irq_get_irq_data(hdev->irq));
- irq_domain_activate_irq(irq_get_irq_data(hdev->irq));
- disable_hardirq(hdev->irq);
- irq_set_affinity(hdev->irq, cpumask_of(hdev->cpu));
- enable_irq(hdev->irq);
- }
+static int hpet_resume(struct clock_event_device *evt)
+{
+ hpet_enable_legacy_int();
hpet_print_config();
-
return 0;
}
@@ -417,7 +406,7 @@ static int hpet_legacy_set_periodic(struct clock_event_device *evt)
static int hpet_legacy_resume(struct clock_event_device *evt)
{
- return hpet_resume(evt, 0);
+ return hpet_resume(evt);
}
static int hpet_legacy_next_event(unsigned long delta,
@@ -510,8 +499,14 @@ static int hpet_msi_set_periodic(struct clock_event_device *evt)
static int hpet_msi_resume(struct clock_event_device *evt)
{
struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
+ struct irq_data *data = irq_get_irq_data(hdev->irq);
+ struct msi_msg msg;
- return hpet_resume(evt, hdev->num);
+ /* Restore the MSI msg and unmask the interrupt */
+ irq_chip_compose_msi_msg(data, &msg);
+ hpet_msi_write(hdev, &msg);
+ hpet_msi_unmask(data);
+ return 0;
}
static int hpet_msi_next_event(unsigned long delta,
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 4aa03c5a14c9..4ed0aba8dbc8 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -155,6 +155,12 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_printf(p, "%10u ", irq_stats(j)->kvm_posted_intr_ipis);
seq_puts(p, " Posted-interrupt notification event\n");
+ seq_printf(p, "%*s: ", prec, "NPI");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ",
+ irq_stats(j)->kvm_posted_intr_nested_ipis);
+ seq_puts(p, " Nested posted-interrupt event\n");
+
seq_printf(p, "%*s: ", prec, "PIW");
for_each_online_cpu(j)
seq_printf(p, "%10u ",
@@ -313,6 +319,19 @@ __visible void smp_kvm_posted_intr_wakeup_ipi(struct pt_regs *regs)
exiting_irq();
set_irq_regs(old_regs);
}
+
+/*
+ * Handler for POSTED_INTERRUPT_NESTED_VECTOR.
+ */
+__visible void smp_kvm_posted_intr_nested_ipi(struct pt_regs *regs)
+{
+ struct pt_regs *old_regs = set_irq_regs(regs);
+
+ entering_ack_irq();
+ inc_irq_stat(kvm_posted_intr_nested_ipis);
+ exiting_irq();
+ set_irq_regs(old_regs);
+}
#endif
__visible void __irq_entry smp_trace_x86_platform_ipi(struct pt_regs *regs)
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index 7468c6987547..c7fd18526c3e 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -150,6 +150,8 @@ static void __init apic_intr_init(void)
alloc_intr_gate(POSTED_INTR_VECTOR, kvm_posted_intr_ipi);
/* IPI for KVM to deliver interrupt to wake up tasks */
alloc_intr_gate(POSTED_INTR_WAKEUP_VECTOR, kvm_posted_intr_wakeup_ipi);
+ /* IPI for KVM to deliver nested posted interrupt */
+ alloc_intr_gate(POSTED_INTR_NESTED_VECTOR, kvm_posted_intr_nested_ipi);
#endif
/* IPI vectors for APIC spurious and error interrupts */
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index 6b877807598b..f0153714ddac 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -457,6 +457,8 @@ static int arch_copy_kprobe(struct kprobe *p)
int arch_prepare_kprobe(struct kprobe *p)
{
+ int ret;
+
if (alternatives_text_reserved(p->addr, p->addr))
return -EINVAL;
@@ -467,7 +469,13 @@ int arch_prepare_kprobe(struct kprobe *p)
if (!p->ainsn.insn)
return -ENOMEM;
- return arch_copy_kprobe(p);
+ ret = arch_copy_kprobe(p);
+ if (ret) {
+ free_insn_slot(p->ainsn.insn, 0);
+ p->ainsn.insn = NULL;
+ }
+
+ return ret;
}
void arch_arm_kprobe(struct kprobe *p)
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 71c17a5be983..d04e30e3c0ff 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -151,6 +151,8 @@ void kvm_async_pf_task_wait(u32 token)
if (hlist_unhashed(&n.link))
break;
+ rcu_irq_exit();
+
if (!n.halted) {
local_irq_enable();
schedule();
@@ -159,11 +161,11 @@ void kvm_async_pf_task_wait(u32 token)
/*
* We cannot reschedule. So halt.
*/
- rcu_irq_exit();
native_safe_halt();
local_irq_disable();
- rcu_irq_enter();
}
+
+ rcu_irq_enter();
}
if (!n.halted)
finish_swait(&n.wq, &wait);
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 67393fc88353..a56bf6051f4e 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -471,12 +471,12 @@ static int __init reboot_init(void)
/*
* The DMI quirks table takes precedence. If no quirks entry
- * matches and the ACPI Hardware Reduced bit is set, force EFI
- * reboot.
+ * matches and the ACPI Hardware Reduced bit is set and EFI
+ * runtime services are enabled, force EFI reboot.
*/
rv = dmi_check_system(reboot_dmi_table);
- if (!rv && efi_reboot_required())
+ if (!rv && efi_reboot_required() && !efi_runtime_disabled())
reboot_type = BOOT_EFI;
return 0;
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index 760433b2574a..2688c7dc5323 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -22,7 +22,7 @@ config KVM
depends on HAVE_KVM
depends on HIGH_RES_TIMERS
# for TASKSTATS/TASK_DELAY_ACCT:
- depends on NET
+ depends on NET && MULTIUSER
select PREEMPT_NOTIFIERS
select MMU_NOTIFIER
select ANON_INODES
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 2695a34fa1c5..337b6d2730fa 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -649,9 +649,10 @@ void kvm_hv_process_stimers(struct kvm_vcpu *vcpu)
}
if ((stimer->config & HV_STIMER_ENABLE) &&
- stimer->count)
- stimer_start(stimer);
- else
+ stimer->count) {
+ if (!stimer->msg_pending)
+ stimer_start(stimer);
+ } else
stimer_cleanup(stimer);
}
}
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 2819d4c123eb..589dcc117086 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -1495,11 +1495,10 @@ EXPORT_SYMBOL_GPL(kvm_lapic_hv_timer_in_use);
static void cancel_hv_timer(struct kvm_lapic *apic)
{
+ WARN_ON(preemptible());
WARN_ON(!apic->lapic_timer.hv_timer_in_use);
- preempt_disable();
kvm_x86_ops->cancel_hv_timer(apic->vcpu);
apic->lapic_timer.hv_timer_in_use = false;
- preempt_enable();
}
static bool start_hv_timer(struct kvm_lapic *apic)
@@ -1507,6 +1506,7 @@ static bool start_hv_timer(struct kvm_lapic *apic)
struct kvm_timer *ktimer = &apic->lapic_timer;
int r;
+ WARN_ON(preemptible());
if (!kvm_x86_ops->set_hv_timer)
return false;
@@ -1538,6 +1538,8 @@ static bool start_hv_timer(struct kvm_lapic *apic)
static void start_sw_timer(struct kvm_lapic *apic)
{
struct kvm_timer *ktimer = &apic->lapic_timer;
+
+ WARN_ON(preemptible());
if (apic->lapic_timer.hv_timer_in_use)
cancel_hv_timer(apic);
if (!apic_lvtt_period(apic) && atomic_read(&ktimer->pending))
@@ -1552,15 +1554,20 @@ static void start_sw_timer(struct kvm_lapic *apic)
static void restart_apic_timer(struct kvm_lapic *apic)
{
+ preempt_disable();
if (!start_hv_timer(apic))
start_sw_timer(apic);
+ preempt_enable();
}
void kvm_lapic_expired_hv_timer(struct kvm_vcpu *vcpu)
{
struct kvm_lapic *apic = vcpu->arch.apic;
- WARN_ON(!apic->lapic_timer.hv_timer_in_use);
+ preempt_disable();
+ /* If the preempt notifier has already run, it also called apic_timer_expired */
+ if (!apic->lapic_timer.hv_timer_in_use)
+ goto out;
WARN_ON(swait_active(&vcpu->wq));
cancel_hv_timer(apic);
apic_timer_expired(apic);
@@ -1569,6 +1576,8 @@ void kvm_lapic_expired_hv_timer(struct kvm_vcpu *vcpu)
advance_periodic_target_expiration(apic);
restart_apic_timer(apic);
}
+out:
+ preempt_enable();
}
EXPORT_SYMBOL_GPL(kvm_lapic_expired_hv_timer);
@@ -1582,9 +1591,11 @@ void kvm_lapic_switch_to_sw_timer(struct kvm_vcpu *vcpu)
{
struct kvm_lapic *apic = vcpu->arch.apic;
+ preempt_disable();
/* Possibly the TSC deadline timer is not enabled yet */
if (apic->lapic_timer.hv_timer_in_use)
start_sw_timer(apic);
+ preempt_enable();
}
EXPORT_SYMBOL_GPL(kvm_lapic_switch_to_sw_timer);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 4d8141e533c3..1107626938cc 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -2430,6 +2430,16 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
svm->vmcb->control.exit_code = SVM_EXIT_EXCP_BASE + nr;
svm->vmcb->control.exit_code_hi = 0;
svm->vmcb->control.exit_info_1 = error_code;
+
+ /*
+ * FIXME: we should not write CR2 when L1 intercepts an L2 #PF exception.
+ * The fix is to add the ancillary datum (CR2 or DR6) to structs
+ * kvm_queued_exception and kvm_vcpu_events, so that CR2 and DR6 can be
+ * written only when inject_pending_event runs (DR6 would written here
+ * too). This should be conditional on a new capability---if the
+ * capability is disabled, kvm_multiple_exception would write the
+ * ancillary information to CR2 or DR6, for backwards ABI-compatibility.
+ */
if (svm->vcpu.arch.exception.nested_apf)
svm->vmcb->control.exit_info_2 = svm->vcpu.arch.apf.nested_apf_token;
else
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 84e62acf2dd8..9b21b1223035 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -198,7 +198,8 @@ struct loaded_vmcs {
struct vmcs *vmcs;
struct vmcs *shadow_vmcs;
int cpu;
- int launched;
+ bool launched;
+ bool nmi_known_unmasked;
struct list_head loaded_vmcss_on_cpu_link;
};
@@ -415,13 +416,10 @@ struct nested_vmx {
/* The guest-physical address of the current VMCS L1 keeps for L2 */
gpa_t current_vmptr;
- /* The host-usable pointer to the above */
- struct page *current_vmcs12_page;
- struct vmcs12 *current_vmcs12;
/*
* Cache of the guest's VMCS, existing outside of guest memory.
* Loaded from guest memory during VMPTRLD. Flushed to guest
- * memory during VMXOFF, VMCLEAR, VMPTRLD.
+ * memory during VMCLEAR and VMPTRLD.
*/
struct vmcs12 *cached_vmcs12;
/*
@@ -562,7 +560,6 @@ struct vcpu_vmx {
struct kvm_vcpu vcpu;
unsigned long host_rsp;
u8 fail;
- bool nmi_known_unmasked;
u32 exit_intr_info;
u32 idt_vectoring_info;
ulong rflags;
@@ -927,6 +924,10 @@ static u32 vmx_segment_access_rights(struct kvm_segment *var);
static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx);
static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx);
static int alloc_identity_pagetable(struct kvm *kvm);
+static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu);
+static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked);
+static bool nested_vmx_is_page_fault_vmexit(struct vmcs12 *vmcs12,
+ u16 error_code);
static DEFINE_PER_CPU(struct vmcs *, vmxarea);
static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
@@ -2326,6 +2327,11 @@ static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
__vmx_load_host_state(to_vmx(vcpu));
}
+static bool emulation_required(struct kvm_vcpu *vcpu)
+{
+ return emulate_invalid_guest_state && !guest_state_valid(vcpu);
+}
+
static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu);
/*
@@ -2363,6 +2369,8 @@ static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
{
+ unsigned long old_rflags = vmx_get_rflags(vcpu);
+
__set_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail);
to_vmx(vcpu)->rflags = rflags;
if (to_vmx(vcpu)->rmode.vm86_active) {
@@ -2370,6 +2378,9 @@ static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
}
vmcs_writel(GUEST_RFLAGS, rflags);
+
+ if ((old_rflags ^ to_vmx(vcpu)->rflags) & X86_EFLAGS_VM)
+ to_vmx(vcpu)->emulation_required = emulation_required(vcpu);
}
static u32 vmx_get_pkru(struct kvm_vcpu *vcpu)
@@ -2418,6 +2429,30 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
vmx_set_interrupt_shadow(vcpu, 0);
}
+static void nested_vmx_inject_exception_vmexit(struct kvm_vcpu *vcpu,
+ unsigned long exit_qual)
+{
+ struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
+ unsigned int nr = vcpu->arch.exception.nr;
+ u32 intr_info = nr | INTR_INFO_VALID_MASK;
+
+ if (vcpu->arch.exception.has_error_code) {
+ vmcs12->vm_exit_intr_error_code = vcpu->arch.exception.error_code;
+ intr_info |= INTR_INFO_DELIVER_CODE_MASK;
+ }
+
+ if (kvm_exception_is_soft(nr))
+ intr_info |= INTR_TYPE_SOFT_EXCEPTION;
+ else
+ intr_info |= INTR_TYPE_HARD_EXCEPTION;
+
+ if (!(vmcs12->idt_vectoring_info_field & VECTORING_INFO_VALID_MASK) &&
+ vmx_get_nmi_mask(vcpu))
+ intr_info |= INTR_INFO_UNBLOCK_NMI;
+
+ nested_vmx_vmexit(vcpu, EXIT_REASON_EXCEPTION_NMI, intr_info, exit_qual);
+}
+
/*
* KVM wants to inject page-faults which it got to the guest. This function
* checks whether in a nested guest, we need to inject them to L1 or L2.
@@ -2427,23 +2462,38 @@ static int nested_vmx_check_exception(struct kvm_vcpu *vcpu)
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
unsigned int nr = vcpu->arch.exception.nr;
- if (!((vmcs12->exception_bitmap & (1u << nr)) ||
- (nr == PF_VECTOR && vcpu->arch.exception.nested_apf)))
- return 0;
+ if (nr == PF_VECTOR) {
+ if (vcpu->arch.exception.nested_apf) {
+ nested_vmx_inject_exception_vmexit(vcpu,
+ vcpu->arch.apf.nested_apf_token);
+ return 1;
+ }
+ /*
+ * FIXME: we must not write CR2 when L1 intercepts an L2 #PF exception.
+ * The fix is to add the ancillary datum (CR2 or DR6) to structs
+ * kvm_queued_exception and kvm_vcpu_events, so that CR2 and DR6
+ * can be written only when inject_pending_event runs. This should be
+ * conditional on a new capability---if the capability is disabled,
+ * kvm_multiple_exception would write the ancillary information to
+ * CR2 or DR6, for backwards ABI-compatibility.
+ */
+ if (nested_vmx_is_page_fault_vmexit(vmcs12,
+ vcpu->arch.exception.error_code)) {
+ nested_vmx_inject_exception_vmexit(vcpu, vcpu->arch.cr2);
+ return 1;
+ }
+ } else {
+ unsigned long exit_qual = 0;
+ if (nr == DB_VECTOR)
+ exit_qual = vcpu->arch.dr6;
- if (vcpu->arch.exception.nested_apf) {
- vmcs_write32(VM_EXIT_INTR_ERROR_CODE, vcpu->arch.exception.error_code);
- nested_vmx_vmexit(vcpu, EXIT_REASON_EXCEPTION_NMI,
- PF_VECTOR | INTR_TYPE_HARD_EXCEPTION |
- INTR_INFO_DELIVER_CODE_MASK | INTR_INFO_VALID_MASK,
- vcpu->arch.apf.nested_apf_token);
- return 1;
+ if (vmcs12->exception_bitmap & (1u << nr)) {
+ nested_vmx_inject_exception_vmexit(vcpu, exit_qual);
+ return 1;
+ }
}
- nested_vmx_vmexit(vcpu, EXIT_REASON_EXCEPTION_NMI,
- vmcs_read32(VM_EXIT_INTR_INFO),
- vmcs_readl(EXIT_QUALIFICATION));
- return 1;
+ return 0;
}
static void vmx_queue_exception(struct kvm_vcpu *vcpu)
@@ -2657,7 +2707,7 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx)
* reason is that if one of these bits is necessary, it will appear
* in vmcs01 and prepare_vmcs02, when it bitwise-or's the control
* fields of vmcs01 and vmcs02, will turn these bits off - and
- * nested_vmx_exit_handled() will not pass related exits to L1.
+ * nested_vmx_exit_reflected() will not pass related exits to L1.
* These rules have exceptions below.
*/
@@ -3857,11 +3907,6 @@ static __init int alloc_kvm_area(void)
return 0;
}
-static bool emulation_required(struct kvm_vcpu *vcpu)
-{
- return emulate_invalid_guest_state && !guest_state_valid(vcpu);
-}
-
static void fix_pmode_seg(struct kvm_vcpu *vcpu, int seg,
struct kvm_segment *save)
{
@@ -4950,6 +4995,28 @@ static bool vmx_get_enable_apicv(void)
return enable_apicv;
}
+static void nested_mark_vmcs12_pages_dirty(struct kvm_vcpu *vcpu)
+{
+ struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
+ gfn_t gfn;
+
+ /*
+ * Don't need to mark the APIC access page dirty; it is never
+ * written to by the CPU during APIC virtualization.
+ */
+
+ if (nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW)) {
+ gfn = vmcs12->virtual_apic_page_addr >> PAGE_SHIFT;
+ kvm_vcpu_mark_page_dirty(vcpu, gfn);
+ }
+
+ if (nested_cpu_has_posted_intr(vmcs12)) {
+ gfn = vmcs12->posted_intr_desc_addr >> PAGE_SHIFT;
+ kvm_vcpu_mark_page_dirty(vcpu, gfn);
+ }
+}
+
+
static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -4957,18 +5024,15 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
void *vapic_page;
u16 status;
- if (vmx->nested.pi_desc &&
- vmx->nested.pi_pending) {
- vmx->nested.pi_pending = false;
- if (!pi_test_and_clear_on(vmx->nested.pi_desc))
- return;
-
- max_irr = find_last_bit(
- (unsigned long *)vmx->nested.pi_desc->pir, 256);
+ if (!vmx->nested.pi_desc || !vmx->nested.pi_pending)
+ return;
- if (max_irr == 256)
- return;
+ vmx->nested.pi_pending = false;
+ if (!pi_test_and_clear_on(vmx->nested.pi_desc))
+ return;
+ max_irr = find_last_bit((unsigned long *)vmx->nested.pi_desc->pir, 256);
+ if (max_irr != 256) {
vapic_page = kmap(vmx->nested.virtual_apic_page);
__kvm_apic_update_irr(vmx->nested.pi_desc->pir, vapic_page);
kunmap(vmx->nested.virtual_apic_page);
@@ -4980,11 +5044,16 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
vmcs_write16(GUEST_INTR_STATUS, status);
}
}
+
+ nested_mark_vmcs12_pages_dirty(vcpu);
}
-static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu)
+static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu,
+ bool nested)
{
#ifdef CONFIG_SMP
+ int pi_vec = nested ? POSTED_INTR_NESTED_VECTOR : POSTED_INTR_VECTOR;
+
if (vcpu->mode == IN_GUEST_MODE) {
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -5002,8 +5071,7 @@ static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu)
*/
WARN_ON_ONCE(pi_test_sn(&vmx->pi_desc));
- apic->send_IPI_mask(get_cpu_mask(vcpu->cpu),
- POSTED_INTR_VECTOR);
+ apic->send_IPI_mask(get_cpu_mask(vcpu->cpu), pi_vec);
return true;
}
#endif
@@ -5018,7 +5086,7 @@ static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu,
if (is_guest_mode(vcpu) &&
vector == vmx->nested.posted_intr_nv) {
/* the PIR and ON have been set by L1. */
- kvm_vcpu_trigger_posted_interrupt(vcpu);
+ kvm_vcpu_trigger_posted_interrupt(vcpu, true);
/*
* If a posted intr is not recognized by hardware,
* we will accomplish it in the next vmentry.
@@ -5052,7 +5120,7 @@ static void vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector)
if (pi_test_and_set_on(&vmx->pi_desc))
return;
- if (!kvm_vcpu_trigger_posted_interrupt(vcpu))
+ if (!kvm_vcpu_trigger_posted_interrupt(vcpu, false))
kvm_vcpu_kick(vcpu);
}
@@ -5510,10 +5578,8 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
- if (!is_guest_mode(vcpu)) {
- ++vcpu->stat.nmi_injections;
- vmx->nmi_known_unmasked = false;
- }
+ ++vcpu->stat.nmi_injections;
+ vmx->loaded_vmcs->nmi_known_unmasked = false;
if (vmx->rmode.vm86_active) {
if (kvm_inject_realmode_interrupt(vcpu, NMI_VECTOR, 0) != EMULATE_DONE)
@@ -5527,16 +5593,21 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu)
{
- if (to_vmx(vcpu)->nmi_known_unmasked)
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+ bool masked;
+
+ if (vmx->loaded_vmcs->nmi_known_unmasked)
return false;
- return vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & GUEST_INTR_STATE_NMI;
+ masked = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & GUEST_INTR_STATE_NMI;
+ vmx->loaded_vmcs->nmi_known_unmasked = !masked;
+ return masked;
}
static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
- vmx->nmi_known_unmasked = !masked;
+ vmx->loaded_vmcs->nmi_known_unmasked = !masked;
if (masked)
vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
GUEST_INTR_STATE_NMI);
@@ -7124,34 +7195,32 @@ static int nested_vmx_check_permission(struct kvm_vcpu *vcpu)
return 1;
}
+static void vmx_disable_shadow_vmcs(struct vcpu_vmx *vmx)
+{
+ vmcs_clear_bits(SECONDARY_VM_EXEC_CONTROL, SECONDARY_EXEC_SHADOW_VMCS);
+ vmcs_write64(VMCS_LINK_POINTER, -1ull);
+}
+
static inline void nested_release_vmcs12(struct vcpu_vmx *vmx)
{
if (vmx->nested.current_vmptr == -1ull)
return;
- /* current_vmptr and current_vmcs12 are always set/reset together */
- if (WARN_ON(vmx->nested.current_vmcs12 == NULL))
- return;
-
if (enable_shadow_vmcs) {
/* copy to memory all shadowed fields in case
they were modified */
copy_shadow_to_vmcs12(vmx);
vmx->nested.sync_shadow_vmcs = false;
- vmcs_clear_bits(SECONDARY_VM_EXEC_CONTROL,
- SECONDARY_EXEC_SHADOW_VMCS);
- vmcs_write64(VMCS_LINK_POINTER, -1ull);
+ vmx_disable_shadow_vmcs(vmx);
}
vmx->nested.posted_intr_nv = -1;
/* Flush VMCS12 to guest memory */
- memcpy(vmx->nested.current_vmcs12, vmx->nested.cached_vmcs12,
- VMCS12_SIZE);
+ kvm_vcpu_write_guest_page(&vmx->vcpu,
+ vmx->nested.current_vmptr >> PAGE_SHIFT,
+ vmx->nested.cached_vmcs12, 0, VMCS12_SIZE);
- kunmap(vmx->nested.current_vmcs12_page);
- nested_release_page(vmx->nested.current_vmcs12_page);
vmx->nested.current_vmptr = -1ull;
- vmx->nested.current_vmcs12 = NULL;
}
/*
@@ -7165,12 +7234,14 @@ static void free_nested(struct vcpu_vmx *vmx)
vmx->nested.vmxon = false;
free_vpid(vmx->nested.vpid02);
- nested_release_vmcs12(vmx);
+ vmx->nested.posted_intr_nv = -1;
+ vmx->nested.current_vmptr = -1ull;
if (vmx->nested.msr_bitmap) {
free_page((unsigned long)vmx->nested.msr_bitmap);
vmx->nested.msr_bitmap = NULL;
}
if (enable_shadow_vmcs) {
+ vmx_disable_shadow_vmcs(vmx);
vmcs_clear(vmx->vmcs01.shadow_vmcs);
free_vmcs(vmx->vmcs01.shadow_vmcs);
vmx->vmcs01.shadow_vmcs = NULL;
@@ -7569,14 +7640,14 @@ static int handle_vmptrld(struct kvm_vcpu *vcpu)
}
nested_release_vmcs12(vmx);
- vmx->nested.current_vmcs12 = new_vmcs12;
- vmx->nested.current_vmcs12_page = page;
/*
* Load VMCS12 from guest memory since it is not already
* cached.
*/
- memcpy(vmx->nested.cached_vmcs12,
- vmx->nested.current_vmcs12, VMCS12_SIZE);
+ memcpy(vmx->nested.cached_vmcs12, new_vmcs12, VMCS12_SIZE);
+ kunmap(page);
+ nested_release_page_clean(page);
+
set_current_vmptr(vmx, vmptr);
}
@@ -8009,12 +8080,11 @@ static bool nested_vmx_exit_handled_cr(struct kvm_vcpu *vcpu,
* should handle it ourselves in L0 (and then continue L2). Only call this
* when in is_guest_mode (L2).
*/
-static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
+static bool nested_vmx_exit_reflected(struct kvm_vcpu *vcpu, u32 exit_reason)
{
u32 intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
struct vcpu_vmx *vmx = to_vmx(vcpu);
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
- u32 exit_reason = vmx->exit_reason;
trace_kvm_nested_vmexit(kvm_rip_read(vcpu), exit_reason,
vmcs_readl(EXIT_QUALIFICATION),
@@ -8023,6 +8093,18 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
vmcs_read32(VM_EXIT_INTR_ERROR_CODE),
KVM_ISA_VMX);
+ /*
+ * The host physical addresses of some pages of guest memory
+ * are loaded into VMCS02 (e.g. L1's Virtual APIC Page). The CPU
+ * may write to these pages via their host physical address while
+ * L2 is running, bypassing any address-translation-based dirty
+ * tracking (e.g. EPT write protection).
+ *
+ * Mark them dirty on every exit from L2 to prevent them from
+ * getting out of sync with dirty tracking.
+ */
+ nested_mark_vmcs12_pages_dirty(vcpu);
+
if (vmx->nested.nested_run_pending)
return false;
@@ -8159,6 +8241,29 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
}
}
+static int nested_vmx_reflect_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason)
+{
+ u32 exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
+
+ /*
+ * At this point, the exit interruption info in exit_intr_info
+ * is only valid for EXCEPTION_NMI exits. For EXTERNAL_INTERRUPT
+ * we need to query the in-kernel LAPIC.
+ */
+ WARN_ON(exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT);
+ if ((exit_intr_info &
+ (INTR_INFO_VALID_MASK | INTR_INFO_DELIVER_CODE_MASK)) ==
+ (INTR_INFO_VALID_MASK | INTR_INFO_DELIVER_CODE_MASK)) {
+ struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
+ vmcs12->vm_exit_intr_error_code =
+ vmcs_read32(VM_EXIT_INTR_ERROR_CODE);
+ }
+
+ nested_vmx_vmexit(vcpu, exit_reason, exit_intr_info,
+ vmcs_readl(EXIT_QUALIFICATION));
+ return 1;
+}
+
static void vmx_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2)
{
*info1 = vmcs_readl(EXIT_QUALIFICATION);
@@ -8405,12 +8510,8 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
if (vmx->emulation_required)
return handle_invalid_guest_state(vcpu);
- if (is_guest_mode(vcpu) && nested_vmx_exit_handled(vcpu)) {
- nested_vmx_vmexit(vcpu, exit_reason,
- vmcs_read32(VM_EXIT_INTR_INFO),
- vmcs_readl(EXIT_QUALIFICATION));
- return 1;
- }
+ if (is_guest_mode(vcpu) && nested_vmx_exit_reflected(vcpu, exit_reason))
+ return nested_vmx_reflect_vmexit(vcpu, exit_reason);
if (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) {
dump_vmcs();
@@ -8736,7 +8837,7 @@ static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx)
idtv_info_valid = vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK;
- if (vmx->nmi_known_unmasked)
+ if (vmx->loaded_vmcs->nmi_known_unmasked)
return;
/*
* Can't use vmx->exit_intr_info since we're not sure what
@@ -8760,7 +8861,7 @@ static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx)
vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
GUEST_INTR_STATE_NMI);
else
- vmx->nmi_known_unmasked =
+ vmx->loaded_vmcs->nmi_known_unmasked =
!(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO)
& GUEST_INTR_STATE_NMI);
}
@@ -9213,7 +9314,6 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
vmx->nested.posted_intr_nv = -1;
vmx->nested.current_vmptr = -1ull;
- vmx->nested.current_vmcs12 = NULL;
vmx->msr_ia32_feature_control_valid_bits = FEATURE_CONTROL_LOCKED;
@@ -9499,12 +9599,15 @@ static void vmx_inject_page_fault_nested(struct kvm_vcpu *vcpu,
WARN_ON(!is_guest_mode(vcpu));
- if (nested_vmx_is_page_fault_vmexit(vmcs12, fault->error_code))
- nested_vmx_vmexit(vcpu, to_vmx(vcpu)->exit_reason,
- vmcs_read32(VM_EXIT_INTR_INFO),
- vmcs_readl(EXIT_QUALIFICATION));
- else
+ if (nested_vmx_is_page_fault_vmexit(vmcs12, fault->error_code)) {
+ vmcs12->vm_exit_intr_error_code = fault->error_code;
+ nested_vmx_vmexit(vcpu, EXIT_REASON_EXCEPTION_NMI,
+ PF_VECTOR | INTR_TYPE_HARD_EXCEPTION |
+ INTR_INFO_DELIVER_CODE_MASK | INTR_INFO_VALID_MASK,
+ fault->address);
+ } else {
kvm_inject_page_fault(vcpu, fault);
+ }
}
static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu,
@@ -10032,6 +10135,8 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
vmcs12->vm_entry_instruction_len);
vmcs_write32(GUEST_INTERRUPTIBILITY_INFO,
vmcs12->guest_interruptibility_info);
+ vmx->loaded_vmcs->nmi_known_unmasked =
+ !(vmcs12->guest_interruptibility_info & GUEST_INTR_STATE_NMI);
} else {
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0);
}
@@ -10056,13 +10161,9 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
/* Posted interrupts setting is only taken from vmcs12. */
if (nested_cpu_has_posted_intr(vmcs12)) {
- /*
- * Note that we use L0's vector here and in
- * vmx_deliver_nested_posted_interrupt.
- */
vmx->nested.posted_intr_nv = vmcs12->posted_intr_nv;
vmx->nested.pi_pending = false;
- vmcs_write16(POSTED_INTR_NV, POSTED_INTR_VECTOR);
+ vmcs_write16(POSTED_INTR_NV, POSTED_INTR_NESTED_VECTOR);
} else {
exec_control &= ~PIN_BASED_POSTED_INTR;
}
@@ -10086,12 +10187,6 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
* "or"ing of the EB of vmcs01 and vmcs12, because when enable_ept,
* vmcs01's EB.PF is 0 so the "or" will take vmcs12's value, and when
* !enable_ept, EB.PF is 1, so the "or" will always be 1.
- *
- * A problem with this approach (when !enable_ept) is that L1 may be
- * injected with more page faults than it asked for. This could have
- * caused problems, but in practice existing hypervisors don't care.
- * To fix this, we will need to emulate the PFEC checking (on the L1
- * page tables), using walk_addr(), when injecting PFs to L1.
*/
vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK,
enable_ept ? vmcs12->page_fault_error_code_mask : 0);
@@ -10488,6 +10583,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
{
struct vmcs12 *vmcs12;
struct vcpu_vmx *vmx = to_vmx(vcpu);
+ u32 interrupt_shadow = vmx_get_interrupt_shadow(vcpu);
u32 exit_qual;
int ret;
@@ -10512,6 +10608,12 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
* for misconfigurations which will anyway be caught by the processor
* when using the merged vmcs02.
*/
+ if (interrupt_shadow & KVM_X86_SHADOW_INT_MOV_SS) {
+ nested_vmx_failValid(vcpu,
+ VMXERR_ENTRY_EVENTS_BLOCKED_BY_MOV_SS);
+ goto out;
+ }
+
if (vmcs12->launch_state == launch) {
nested_vmx_failValid(vcpu,
launch ? VMXERR_VMLAUNCH_NONCLEAR_VMCS
@@ -10832,13 +10934,8 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
vmcs12->vm_exit_reason = exit_reason;
vmcs12->exit_qualification = exit_qualification;
-
vmcs12->vm_exit_intr_info = exit_intr_info;
- if ((vmcs12->vm_exit_intr_info &
- (INTR_INFO_VALID_MASK | INTR_INFO_DELIVER_CODE_MASK)) ==
- (INTR_INFO_VALID_MASK | INTR_INFO_DELIVER_CODE_MASK))
- vmcs12->vm_exit_intr_error_code =
- vmcs_read32(VM_EXIT_INTR_ERROR_CODE);
+
vmcs12->idt_vectoring_info_field = 0;
vmcs12->vm_exit_instruction_len = vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
vmcs12->vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
@@ -10926,7 +11023,9 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
*/
vmx_flush_tlb(vcpu);
}
-
+ /* Restore posted intr vector. */
+ if (nested_cpu_has_posted_intr(vmcs12))
+ vmcs_write16(POSTED_INTR_NV, POSTED_INTR_VECTOR);
vmcs_write32(GUEST_SYSENTER_CS, vmcs12->host_ia32_sysenter_cs);
vmcs_writel(GUEST_SYSENTER_ESP, vmcs12->host_ia32_sysenter_esp);
@@ -11032,8 +11131,15 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
vmx_switch_vmcs(vcpu, &vmx->vmcs01);
- if ((exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT)
- && nested_exit_intr_ack_set(vcpu)) {
+ /*
+ * TODO: SDM says that with acknowledge interrupt on exit, bit 31 of
+ * the VM-exit interrupt information (valid interrupt) is always set to
+ * 1 on EXIT_REASON_EXTERNAL_INTERRUPT, so we shouldn't need
+ * kvm_cpu_has_interrupt(). See the commit message for details.
+ */
+ if (nested_exit_intr_ack_set(vcpu) &&
+ exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT &&
+ kvm_cpu_has_interrupt(vcpu)) {
int irq = kvm_cpu_get_interrupt(vcpu);
WARN_ON(irq < 0);
vmcs12->vm_exit_intr_info = irq |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 5b8f07889f6a..d734aa8c5b4f 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -597,8 +597,8 @@ bool pdptrs_changed(struct kvm_vcpu *vcpu)
(unsigned long *)&vcpu->arch.regs_avail))
return true;
- gfn = (kvm_read_cr3(vcpu) & ~31u) >> PAGE_SHIFT;
- offset = (kvm_read_cr3(vcpu) & ~31u) & (PAGE_SIZE - 1);
+ gfn = (kvm_read_cr3(vcpu) & 0xffffffe0ul) >> PAGE_SHIFT;
+ offset = (kvm_read_cr3(vcpu) & 0xffffffe0ul) & (PAGE_SIZE - 1);
r = kvm_read_nested_guest_page(vcpu, gfn, pdpte, offset, sizeof(pdpte),
PFERR_USER_MASK | PFERR_WRITE_MASK);
if (r < 0)
@@ -3159,15 +3159,18 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
kvm_set_hflags(vcpu, hflags);
vcpu->arch.smi_pending = events->smi.pending;
- if (events->smi.smm_inside_nmi)
- vcpu->arch.hflags |= HF_SMM_INSIDE_NMI_MASK;
- else
- vcpu->arch.hflags &= ~HF_SMM_INSIDE_NMI_MASK;
- if (lapic_in_kernel(vcpu)) {
- if (events->smi.latched_init)
- set_bit(KVM_APIC_INIT, &vcpu->arch.apic->pending_events);
+
+ if (events->smi.smm) {
+ if (events->smi.smm_inside_nmi)
+ vcpu->arch.hflags |= HF_SMM_INSIDE_NMI_MASK;
else
- clear_bit(KVM_APIC_INIT, &vcpu->arch.apic->pending_events);
+ vcpu->arch.hflags &= ~HF_SMM_INSIDE_NMI_MASK;
+ if (lapic_in_kernel(vcpu)) {
+ if (events->smi.latched_init)
+ set_bit(KVM_APIC_INIT, &vcpu->arch.apic->pending_events);
+ else
+ clear_bit(KVM_APIC_INIT, &vcpu->arch.apic->pending_events);
+ }
}
}
@@ -6215,6 +6218,7 @@ static void kvm_pv_kick_cpu_op(struct kvm *kvm, unsigned long flags, int apicid)
lapic_irq.shorthand = 0;
lapic_irq.dest_mode = 0;
+ lapic_irq.level = 0;
lapic_irq.dest_id = apicid;
lapic_irq.msi_redir_hint = false;
diff --git a/arch/x86/math-emu/Makefile b/arch/x86/math-emu/Makefile
index 9b0c63b60302..1b2dac174321 100644
--- a/arch/x86/math-emu/Makefile
+++ b/arch/x86/math-emu/Makefile
@@ -5,8 +5,8 @@
#DEBUG = -DDEBUGGING
DEBUG =
PARANOID = -DPARANOID
-EXTRA_CFLAGS := $(PARANOID) $(DEBUG) -fno-builtin $(MATH_EMULATION)
-EXTRA_AFLAGS := $(PARANOID)
+ccflags-y += $(PARANOID) $(DEBUG) -fno-builtin $(MATH_EMULATION)
+asflags-y += $(PARANOID)
# From 'C' language sources:
C_OBJS =fpu_entry.o errors.o \
diff --git a/arch/x86/math-emu/fpu_emu.h b/arch/x86/math-emu/fpu_emu.h
index afbc4d805d66..c9c320dccca1 100644
--- a/arch/x86/math-emu/fpu_emu.h
+++ b/arch/x86/math-emu/fpu_emu.h
@@ -157,7 +157,7 @@ extern u_char const data_sizes_16[32];
#define signbyte(a) (((u_char *)(a))[9])
#define getsign(a) (signbyte(a) & 0x80)
-#define setsign(a,b) { if (b) signbyte(a) |= 0x80; else signbyte(a) &= 0x7f; }
+#define setsign(a,b) { if ((b) != 0) signbyte(a) |= 0x80; else signbyte(a) &= 0x7f; }
#define copysign(a,b) { if (getsign(a)) signbyte(b) |= 0x80; \
else signbyte(b) &= 0x7f; }
#define changesign(a) { signbyte(a) ^= 0x80; }
diff --git a/arch/x86/math-emu/reg_compare.c b/arch/x86/math-emu/reg_compare.c
index b77360fdbf4a..19b33b50adfa 100644
--- a/arch/x86/math-emu/reg_compare.c
+++ b/arch/x86/math-emu/reg_compare.c
@@ -168,7 +168,7 @@ static int compare(FPU_REG const *b, int tagb)
/* This function requires that st(0) is not empty */
int FPU_compare_st_data(FPU_REG const *loaded_data, u_char loaded_tag)
{
- int f = 0, c;
+ int f, c;
c = compare(loaded_data, loaded_tag);
@@ -189,12 +189,12 @@ int FPU_compare_st_data(FPU_REG const *loaded_data, u_char loaded_tag)
case COMP_No_Comp:
f = SW_C3 | SW_C2 | SW_C0;
break;
-#ifdef PARANOID
default:
+#ifdef PARANOID
EXCEPTION(EX_INTERNAL | 0x121);
+#endif /* PARANOID */
f = SW_C3 | SW_C2 | SW_C0;
break;
-#endif /* PARANOID */
}
setcc(f);
if (c & COMP_Denormal) {
@@ -205,7 +205,7 @@ int FPU_compare_st_data(FPU_REG const *loaded_data, u_char loaded_tag)
static int compare_st_st(int nr)
{
- int f = 0, c;
+ int f, c;
FPU_REG *st_ptr;
if (!NOT_EMPTY(0) || !NOT_EMPTY(nr)) {
@@ -235,12 +235,12 @@ static int compare_st_st(int nr)
case COMP_No_Comp:
f = SW_C3 | SW_C2 | SW_C0;
break;
-#ifdef PARANOID
default:
+#ifdef PARANOID
EXCEPTION(EX_INTERNAL | 0x122);
+#endif /* PARANOID */
f = SW_C3 | SW_C2 | SW_C0;
break;
-#endif /* PARANOID */
}
setcc(f);
if (c & COMP_Denormal) {
@@ -283,12 +283,12 @@ static int compare_i_st_st(int nr)
case COMP_No_Comp:
f = X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF;
break;
-#ifdef PARANOID
default:
+#ifdef PARANOID
EXCEPTION(EX_INTERNAL | 0x122);
+#endif /* PARANOID */
f = 0;
break;
-#endif /* PARANOID */
}
FPU_EFLAGS = (FPU_EFLAGS & ~(X86_EFLAGS_ZF | X86_EFLAGS_PF | X86_EFLAGS_CF)) | f;
if (c & COMP_Denormal) {
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 673541eb3b3f..bf3f1065d6ad 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -18,6 +18,7 @@
#include <asm/dma.h> /* for MAX_DMA_PFN */
#include <asm/microcode.h>
#include <asm/kaslr.h>
+#include <asm/hypervisor.h>
/*
* We need to define the tracepoints somewhere, and tlb.c
@@ -636,6 +637,8 @@ void __init init_mem_mapping(void)
load_cr3(swapper_pg_dir);
__flush_tlb_all();
+ hypervisor_init_mem_mapping();
+
early_memtest(0, max_pfn_mapped << PAGE_SHIFT);
}
diff --git a/arch/x86/platform/intel-mid/device_libs/platform_max7315.c b/arch/x86/platform/intel-mid/device_libs/platform_max7315.c
index 6e075afa7877..58337b2bc682 100644
--- a/arch/x86/platform/intel-mid/device_libs/platform_max7315.c
+++ b/arch/x86/platform/intel-mid/device_libs/platform_max7315.c
@@ -38,8 +38,10 @@ static void __init *max7315_platform_data(void *info)
*/
strcpy(i2c_info->type, "max7315");
if (nr++) {
- sprintf(base_pin_name, "max7315_%d_base", nr);
- sprintf(intr_pin_name, "max7315_%d_int", nr);
+ snprintf(base_pin_name, sizeof(base_pin_name),
+ "max7315_%d_base", nr);
+ snprintf(intr_pin_name, sizeof(intr_pin_name),
+ "max7315_%d_int", nr);
} else {
strcpy(base_pin_name, "max7315_base");
strcpy(intr_pin_name, "max7315_int");
diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c
index d4a61ddf9e62..3e4bdb442fbc 100644
--- a/arch/x86/platform/uv/tlb_uv.c
+++ b/arch/x86/platform/uv/tlb_uv.c
@@ -40,7 +40,6 @@ static int timeout_base_ns[] = {
static int timeout_us;
static bool nobau = true;
static int nobau_perm;
-static cycles_t congested_cycles;
/* tunables: */
static int max_concurr = MAX_BAU_CONCURRENT;
@@ -829,10 +828,10 @@ static void record_send_stats(cycles_t time1, cycles_t time2,
if ((completion_status == FLUSH_COMPLETE) && (try == 1)) {
bcp->period_requests++;
bcp->period_time += elapsed;
- if ((elapsed > congested_cycles) &&
+ if ((elapsed > usec_2_cycles(bcp->cong_response_us)) &&
(bcp->period_requests > bcp->cong_reps) &&
((bcp->period_time / bcp->period_requests) >
- congested_cycles)) {
+ usec_2_cycles(bcp->cong_response_us))) {
stat->s_congested++;
disable_for_period(bcp, stat);
}
@@ -2222,14 +2221,17 @@ static int __init uv_bau_init(void)
else if (is_uv1_hub())
ops = uv1_bau_ops;
+ nuvhubs = uv_num_possible_blades();
+ if (nuvhubs < 2) {
+ pr_crit("UV: BAU disabled - insufficient hub count\n");
+ goto err_bau_disable;
+ }
+
for_each_possible_cpu(cur_cpu) {
mask = &per_cpu(uv_flush_tlb_mask, cur_cpu);
zalloc_cpumask_var_node(mask, GFP_KERNEL, cpu_to_node(cur_cpu));
}
- nuvhubs = uv_num_possible_blades();
- congested_cycles = usec_2_cycles(congested_respns_us);
-
uv_base_pnode = 0x7fffffff;
for (uvhub = 0; uvhub < nuvhubs; uvhub++) {
cpus = uv_blade_nr_possible_cpus(uvhub);
@@ -2242,9 +2244,8 @@ static int __init uv_bau_init(void)
enable_timeouts();
if (init_per_cpu(nuvhubs, uv_base_pnode)) {
- set_bau_off();
- nobau_perm = 1;
- return 0;
+ pr_crit("UV: BAU disabled - per CPU init failed\n");
+ goto err_bau_disable;
}
vector = UV_BAU_MESSAGE;
@@ -2270,6 +2271,16 @@ static int __init uv_bau_init(void)
}
return 0;
+
+err_bau_disable:
+
+ for_each_possible_cpu(cur_cpu)
+ free_cpumask_var(per_cpu(uv_flush_tlb_mask, cur_cpu));
+
+ set_bau_off();
+ nobau_perm = 1;
+
+ return -EINVAL;
}
core_initcall(uv_bau_init);
fs_initcall(uv_ptc_init);
diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c
index 87d791356ea9..de503c225ae1 100644
--- a/arch/x86/xen/enlighten_hvm.c
+++ b/arch/x86/xen/enlighten_hvm.c
@@ -12,6 +12,7 @@
#include <asm/setup.h>
#include <asm/hypervisor.h>
#include <asm/e820/api.h>
+#include <asm/early_ioremap.h>
#include <asm/xen/cpuid.h>
#include <asm/xen/hypervisor.h>
@@ -21,38 +22,50 @@
#include "mmu.h"
#include "smp.h"
-void __ref xen_hvm_init_shared_info(void)
+static unsigned long shared_info_pfn;
+
+void xen_hvm_init_shared_info(void)
{
struct xen_add_to_physmap xatp;
- u64 pa;
-
- if (HYPERVISOR_shared_info == &xen_dummy_shared_info) {
- /*
- * Search for a free page starting at 4kB physical address.
- * Low memory is preferred to avoid an EPT large page split up
- * by the mapping.
- * Starting below X86_RESERVE_LOW (usually 64kB) is fine as
- * the BIOS used for HVM guests is well behaved and won't
- * clobber memory other than the first 4kB.
- */
- for (pa = PAGE_SIZE;
- !e820__mapped_all(pa, pa + PAGE_SIZE, E820_TYPE_RAM) ||
- memblock_is_reserved(pa);
- pa += PAGE_SIZE)
- ;
-
- memblock_reserve(pa, PAGE_SIZE);
- HYPERVISOR_shared_info = __va(pa);
- }
xatp.domid = DOMID_SELF;
xatp.idx = 0;
xatp.space = XENMAPSPACE_shared_info;
- xatp.gpfn = virt_to_pfn(HYPERVISOR_shared_info);
+ xatp.gpfn = shared_info_pfn;
if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
BUG();
}
+static void __init reserve_shared_info(void)
+{
+ u64 pa;
+
+ /*
+ * Search for a free page starting at 4kB physical address.
+ * Low memory is preferred to avoid an EPT large page split up
+ * by the mapping.
+ * Starting below X86_RESERVE_LOW (usually 64kB) is fine as
+ * the BIOS used for HVM guests is well behaved and won't
+ * clobber memory other than the first 4kB.
+ */
+ for (pa = PAGE_SIZE;
+ !e820__mapped_all(pa, pa + PAGE_SIZE, E820_TYPE_RAM) ||
+ memblock_is_reserved(pa);
+ pa += PAGE_SIZE)
+ ;
+
+ shared_info_pfn = PHYS_PFN(pa);
+
+ memblock_reserve(pa, PAGE_SIZE);
+ HYPERVISOR_shared_info = early_memremap(pa, PAGE_SIZE);
+}
+
+static void __init xen_hvm_init_mem_mapping(void)
+{
+ early_memunmap(HYPERVISOR_shared_info, PAGE_SIZE);
+ HYPERVISOR_shared_info = __va(PFN_PHYS(shared_info_pfn));
+}
+
static void __init init_hvm_pv_info(void)
{
int major, minor;
@@ -153,6 +166,7 @@ static void __init xen_hvm_guest_init(void)
init_hvm_pv_info();
+ reserve_shared_info();
xen_hvm_init_shared_info();
/*
@@ -218,5 +232,6 @@ const struct hypervisor_x86 x86_hyper_xen_hvm = {
.init_platform = xen_hvm_guest_init,
.pin_vcpu = xen_pin_vcpu,
.x2apic_available = xen_x2apic_para_available,
+ .init_mem_mapping = xen_hvm_init_mem_mapping,
};
EXPORT_SYMBOL(x86_hyper_xen_hvm);
diff --git a/arch/x86/xen/smp_pv.c b/arch/x86/xen/smp_pv.c
index 1ea598e5f030..51471408fdd1 100644
--- a/arch/x86/xen/smp_pv.c
+++ b/arch/x86/xen/smp_pv.c
@@ -19,6 +19,7 @@
#include <linux/irq_work.h>
#include <linux/tick.h>
#include <linux/nmi.h>
+#include <linux/cpuhotplug.h>
#include <asm/paravirt.h>
#include <asm/desc.h>
@@ -413,7 +414,7 @@ static void xen_pv_play_dead(void) /* used only with HOTPLUG_CPU */
*/
tick_nohz_idle_enter();
- cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
+ cpuhp_online_idle(CPUHP_AP_ONLINE_IDLE);
}
#else /* !CONFIG_HOTPLUG_CPU */
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index a1895a8e85c1..1ecb05db3632 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -309,7 +309,6 @@ static irqreturn_t xen_timer_interrupt(int irq, void *dev_id)
void xen_teardown_timer(int cpu)
{
struct clock_event_device *evt;
- BUG_ON(cpu == 0);
evt = &per_cpu(xen_clock_events, cpu).evt;
if (evt->irq >= 0) {
diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild
index 2d716ebc5a5e..dff7cc39437c 100644
--- a/arch/xtensa/include/asm/Kbuild
+++ b/arch/xtensa/include/asm/Kbuild
@@ -1,5 +1,6 @@
generic-y += bug.h
generic-y += clkdev.h
+generic-y += device.h
generic-y += div64.h
generic-y += dma-contiguous.h
generic-y += emergency-restart.h
@@ -17,6 +18,7 @@ generic-y += local.h
generic-y += local64.h
generic-y += mcs_spinlock.h
generic-y += mm-arch-hooks.h
+generic-y += param.h
generic-y += percpu.h
generic-y += preempt.h
generic-y += rwsem.h
diff --git a/arch/xtensa/include/asm/device.h b/arch/xtensa/include/asm/device.h
deleted file mode 100644
index 1deeb8ebbb1b..000000000000
--- a/arch/xtensa/include/asm/device.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Arch specific extensions to struct device
- *
- * This file is released under the GPLv2
- */
-#ifndef _ASM_XTENSA_DEVICE_H
-#define _ASM_XTENSA_DEVICE_H
-
-struct dev_archdata {
-};
-
-struct pdev_archdata {
-};
-
-#endif /* _ASM_XTENSA_DEVICE_H */
diff --git a/arch/xtensa/include/asm/param.h b/arch/xtensa/include/asm/param.h
deleted file mode 100644
index 0a70e780ef2a..000000000000
--- a/arch/xtensa/include/asm/param.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * include/asm-xtensa/param.h
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001 - 2005 Tensilica Inc.
- */
-#ifndef _XTENSA_PARAM_H
-#define _XTENSA_PARAM_H
-
-#include <uapi/asm/param.h>
-
-# define HZ CONFIG_HZ /* internal timer frequency */
-# define USER_HZ 100 /* for user interfaces in "ticks" */
-# define CLOCKS_PER_SEC (USER_HZ) /* frequnzy at which times() counts */
-#endif /* _XTENSA_PARAM_H */
diff --git a/arch/xtensa/include/uapi/asm/ioctls.h b/arch/xtensa/include/uapi/asm/ioctls.h
index 98b004e24e85..47d82c09be7b 100644
--- a/arch/xtensa/include/uapi/asm/ioctls.h
+++ b/arch/xtensa/include/uapi/asm/ioctls.h
@@ -105,7 +105,7 @@
#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
-#define TIOCGPTPEER _IOR('T', 0x41, int) /* Safely open the slave */
+#define TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */
#define TIOCSERCONFIG _IO('T', 83)
#define TIOCSERGWILD _IOR('T', 84, int)
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
index d159e9b9c018..672391003e40 100644
--- a/arch/xtensa/kernel/xtensa_ksyms.c
+++ b/arch/xtensa/kernel/xtensa_ksyms.c
@@ -94,13 +94,11 @@ unsigned long __sync_fetch_and_or_4(unsigned long *p, unsigned long v)
}
EXPORT_SYMBOL(__sync_fetch_and_or_4);
-#ifdef CONFIG_NET
/*
* Networking support
*/
EXPORT_SYMBOL(csum_partial);
EXPORT_SYMBOL(csum_partial_copy_generic);
-#endif /* CONFIG_NET */
/*
* Architecture-specific symbols
diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c
index 1a804a2f9a5b..3c75c4e597da 100644
--- a/arch/xtensa/mm/cache.c
+++ b/arch/xtensa/mm/cache.c
@@ -103,6 +103,7 @@ void clear_user_highpage(struct page *page, unsigned long vaddr)
clear_page_alias(kvaddr, paddr);
preempt_enable();
}
+EXPORT_SYMBOL(clear_user_highpage);
void copy_user_highpage(struct page *dst, struct page *src,
unsigned long vaddr, struct vm_area_struct *vma)
@@ -119,10 +120,7 @@ void copy_user_highpage(struct page *dst, struct page *src,
copy_page_alias(dst_vaddr, src_vaddr, dst_paddr, src_paddr);
preempt_enable();
}
-
-#endif /* DCACHE_WAY_SIZE > PAGE_SIZE */
-
-#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+EXPORT_SYMBOL(copy_user_highpage);
/*
* Any time the kernel writes to a user page cache page, or it is about to
@@ -176,7 +174,7 @@ void flush_dcache_page(struct page *page)
/* There shouldn't be an entry in the cache for this page anymore. */
}
-
+EXPORT_SYMBOL(flush_dcache_page);
/*
* For now, flush the whole cache. FIXME??
@@ -188,6 +186,7 @@ void local_flush_cache_range(struct vm_area_struct *vma,
__flush_invalidate_dcache_all();
__invalidate_icache_all();
}
+EXPORT_SYMBOL(local_flush_cache_range);
/*
* Remove any entry in the cache for this page.
@@ -207,8 +206,9 @@ void local_flush_cache_page(struct vm_area_struct *vma, unsigned long address,
__flush_invalidate_dcache_page_alias(virt, phys);
__invalidate_icache_page_alias(virt, phys);
}
+EXPORT_SYMBOL(local_flush_cache_page);
-#endif
+#endif /* DCACHE_WAY_SIZE > PAGE_SIZE */
void
update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep)
@@ -225,7 +225,7 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep)
flush_tlb_page(vma, addr);
-#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+#if (DCACHE_WAY_SIZE > PAGE_SIZE)
if (!PageReserved(page) && test_bit(PG_arch_1, &page->flags)) {
unsigned long phys = page_to_phys(page);
@@ -256,7 +256,7 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep)
* flush_dcache_page() on the page.
*/
-#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+#if (DCACHE_WAY_SIZE > PAGE_SIZE)
void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
unsigned long vaddr, void *dst, const void *src,
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index 60a6835265fc..436b6ca6b175 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -4299,6 +4299,9 @@ static void bfq_completed_request(struct bfq_queue *bfqq, struct bfq_data *bfqd)
bfq_bfqq_expire(bfqd, bfqq, false,
BFQQE_NO_MORE_REQUESTS);
}
+
+ if (!bfqd->rq_in_driver)
+ bfq_schedule_dispatch(bfqd);
}
static void bfq_put_rq_priv_body(struct bfq_queue *bfqq)
diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h
index 8fd83b885774..859f0a8c97c8 100644
--- a/block/bfq-iosched.h
+++ b/block/bfq-iosched.h
@@ -52,7 +52,7 @@ struct bfq_entity;
struct bfq_service_tree {
/* tree for active entities (i.e., those backlogged) */
struct rb_root active;
- /* tree for idle entities (i.e., not backlogged, with V <= F_i)*/
+ /* tree for idle entities (i.e., not backlogged, with V < F_i)*/
struct rb_root idle;
/* idle entity with minimum F_i */
@@ -71,17 +71,29 @@ struct bfq_service_tree {
*
* bfq_sched_data is the basic scheduler queue. It supports three
* ioprio_classes, and can be used either as a toplevel queue or as an
- * intermediate queue on a hierarchical setup. @next_in_service
- * points to the active entity of the sched_data service trees that
- * will be scheduled next. It is used to reduce the number of steps
- * needed for each hierarchical-schedule update.
+ * intermediate queue in a hierarchical setup.
*
* The supported ioprio_classes are the same as in CFQ, in descending
* priority order, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE.
* Requests from higher priority queues are served before all the
* requests from lower priority queues; among requests of the same
* queue requests are served according to B-WF2Q+.
- * All the fields are protected by the queue lock of the containing bfqd.
+ *
+ * The schedule is implemented by the service trees, plus the field
+ * @next_in_service, which points to the entity on the active trees
+ * that will be served next, if 1) no changes in the schedule occurs
+ * before the current in-service entity is expired, 2) the in-service
+ * queue becomes idle when it expires, and 3) if the entity pointed by
+ * in_service_entity is not a queue, then the in-service child entity
+ * of the entity pointed by in_service_entity becomes idle on
+ * expiration. This peculiar definition allows for the following
+ * optimization, not yet exploited: while a given entity is still in
+ * service, we already know which is the best candidate for next
+ * service among the other active entitities in the same parent
+ * entity. We can then quickly compare the timestamps of the
+ * in-service entity with those of such best candidate.
+ *
+ * All fields are protected by the lock of the containing bfqd.
*/
struct bfq_sched_data {
/* entity in service */
diff --git a/block/bfq-wf2q.c b/block/bfq-wf2q.c
index 5ec05cd42b80..911aa7431dbe 100644
--- a/block/bfq-wf2q.c
+++ b/block/bfq-wf2q.c
@@ -188,21 +188,23 @@ static bool bfq_update_parent_budget(struct bfq_entity *next_in_service)
/*
* This function tells whether entity stops being a candidate for next
- * service, according to the following logic.
+ * service, according to the restrictive definition of the field
+ * next_in_service. In particular, this function is invoked for an
+ * entity that is about to be set in service.
*
- * This function is invoked for an entity that is about to be set in
- * service. If such an entity is a queue, then the entity is no longer
- * a candidate for next service (i.e, a candidate entity to serve
- * after the in-service entity is expired). The function then returns
- * true.
+ * If entity is a queue, then the entity is no longer a candidate for
+ * next service according to the that definition, because entity is
+ * about to become the in-service queue. This function then returns
+ * true if entity is a queue.
*
- * In contrast, the entity could stil be a candidate for next service
- * if it is not a queue, and has more than one child. In fact, even if
- * one of its children is about to be set in service, other children
- * may still be the next to serve. As a consequence, a non-queue
- * entity is not a candidate for next-service only if it has only one
- * child. And only if this condition holds, then the function returns
- * true for a non-queue entity.
+ * In contrast, entity could still be a candidate for next service if
+ * it is not a queue, and has more than one active child. In fact,
+ * even if one of its children is about to be set in service, other
+ * active children may still be the next to serve, for the parent
+ * entity, even according to the above definition. As a consequence, a
+ * non-queue entity is not a candidate for next-service only if it has
+ * only one active child. And only if this condition holds, then this
+ * function returns true for a non-queue entity.
*/
static bool bfq_no_longer_next_in_service(struct bfq_entity *entity)
{
@@ -213,6 +215,18 @@ static bool bfq_no_longer_next_in_service(struct bfq_entity *entity)
bfqg = container_of(entity, struct bfq_group, entity);
+ /*
+ * The field active_entities does not always contain the
+ * actual number of active children entities: it happens to
+ * not account for the in-service entity in case the latter is
+ * removed from its active tree (which may get done after
+ * invoking the function bfq_no_longer_next_in_service in
+ * bfq_get_next_queue). Fortunately, here, i.e., while
+ * bfq_no_longer_next_in_service is not yet completed in
+ * bfq_get_next_queue, bfq_active_extract has not yet been
+ * invoked, and thus active_entities still coincides with the
+ * actual number of active entities.
+ */
if (bfqg->active_entities == 1)
return true;
@@ -954,7 +968,7 @@ static void bfq_update_fin_time_enqueue(struct bfq_entity *entity,
* one of its children receives a new request.
*
* Basically, this function updates the timestamps of entity and
- * inserts entity into its active tree, ater possible extracting it
+ * inserts entity into its active tree, ater possibly extracting it
* from its idle tree.
*/
static void __bfq_activate_entity(struct bfq_entity *entity,
@@ -1048,7 +1062,7 @@ static void __bfq_requeue_entity(struct bfq_entity *entity)
entity->start = entity->finish;
/*
* In addition, if the entity had more than one child
- * when set in service, then was not extracted from
+ * when set in service, then it was not extracted from
* the active tree. This implies that the position of
* the entity in the active tree may need to be
* changed now, because we have just updated the start
@@ -1056,9 +1070,8 @@ static void __bfq_requeue_entity(struct bfq_entity *entity)
* time in a moment (the requeueing is then, more
* precisely, a repositioning in this case). To
* implement this repositioning, we: 1) dequeue the
- * entity here, 2) update the finish time and
- * requeue the entity according to the new
- * timestamps below.
+ * entity here, 2) update the finish time and requeue
+ * the entity according to the new timestamps below.
*/
if (entity->tree)
bfq_active_extract(st, entity);
@@ -1105,9 +1118,10 @@ static void __bfq_activate_requeue_entity(struct bfq_entity *entity,
/**
- * bfq_activate_entity - activate or requeue an entity representing a bfq_queue,
- * and activate, requeue or reposition all ancestors
- * for which such an update becomes necessary.
+ * bfq_activate_requeue_entity - activate or requeue an entity representing a
+ * bfq_queue, and activate, requeue or reposition
+ * all ancestors for which such an update becomes
+ * necessary.
* @entity: the entity to activate.
* @non_blocking_wait_rq: true if this entity was waiting for a request
* @requeue: true if this is a requeue, which implies that bfqq is
@@ -1135,9 +1149,9 @@ static void bfq_activate_requeue_entity(struct bfq_entity *entity,
* @ins_into_idle_tree: if false, the entity will not be put into the
* idle tree.
*
- * Deactivates an entity, independently from its previous state. Must
+ * Deactivates an entity, independently of its previous state. Must
* be invoked only if entity is on a service tree. Extracts the entity
- * from that tree, and if necessary and allowed, puts it on the idle
+ * from that tree, and if necessary and allowed, puts it into the idle
* tree.
*/
bool __bfq_deactivate_entity(struct bfq_entity *entity, bool ins_into_idle_tree)
@@ -1158,8 +1172,10 @@ bool __bfq_deactivate_entity(struct bfq_entity *entity, bool ins_into_idle_tree)
st = bfq_entity_service_tree(entity);
is_in_service = entity == sd->in_service_entity;
- if (is_in_service)
+ if (is_in_service) {
bfq_calc_finish(entity, entity->service);
+ sd->in_service_entity = NULL;
+ }
if (entity->tree == &st->active)
bfq_active_extract(st, entity);
@@ -1177,7 +1193,7 @@ bool __bfq_deactivate_entity(struct bfq_entity *entity, bool ins_into_idle_tree)
/**
* bfq_deactivate_entity - deactivate an entity representing a bfq_queue.
* @entity: the entity to deactivate.
- * @ins_into_idle_tree: true if the entity can be put on the idle tree
+ * @ins_into_idle_tree: true if the entity can be put into the idle tree
*/
static void bfq_deactivate_entity(struct bfq_entity *entity,
bool ins_into_idle_tree,
@@ -1208,16 +1224,29 @@ static void bfq_deactivate_entity(struct bfq_entity *entity,
*/
bfq_update_next_in_service(sd, NULL);
- if (sd->next_in_service)
+ if (sd->next_in_service || sd->in_service_entity) {
/*
- * The parent entity is still backlogged,
- * because next_in_service is not NULL. So, no
- * further upwards deactivation must be
- * performed. Yet, next_in_service has
- * changed. Then the schedule does need to be
- * updated upwards.
+ * The parent entity is still active, because
+ * either next_in_service or in_service_entity
+ * is not NULL. So, no further upwards
+ * deactivation must be performed. Yet,
+ * next_in_service has changed. Then the
+ * schedule does need to be updated upwards.
+ *
+ * NOTE If in_service_entity is not NULL, then
+ * next_in_service may happen to be NULL,
+ * although the parent entity is evidently
+ * active. This happens if 1) the entity
+ * pointed by in_service_entity is the only
+ * active entity in the parent entity, and 2)
+ * according to the definition of
+ * next_in_service, the in_service_entity
+ * cannot be considered as
+ * next_in_service. See the comments on the
+ * definition of next_in_service for details.
*/
break;
+ }
/*
* If we get here, then the parent is no more
@@ -1297,7 +1326,7 @@ static void bfq_update_vtime(struct bfq_service_tree *st, u64 new_value)
*
* This function searches the first schedulable entity, starting from the
* root of the tree and going on the left every time on this side there is
- * a subtree with at least one eligible (start >= vtime) entity. The path on
+ * a subtree with at least one eligible (start <= vtime) entity. The path on
* the right is followed only if a) the left subtree contains no eligible
* entities and b) no eligible entity has been found yet.
*/
@@ -1494,47 +1523,34 @@ struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
/*
* If entity is no longer a candidate for next
- * service, then we extract it from its active tree,
- * for the following reason. To further boost the
- * throughput in some special case, BFQ needs to know
- * which is the next candidate entity to serve, while
- * there is already an entity in service. In this
- * respect, to make it easy to compute/update the next
- * candidate entity to serve after the current
- * candidate has been set in service, there is a case
- * where it is necessary to extract the current
- * candidate from its service tree. Such a case is
- * when the entity just set in service cannot be also
- * a candidate for next service. Details about when
- * this conditions holds are reported in the comments
- * on the function bfq_no_longer_next_in_service()
- * invoked below.
+ * service, then it must be extracted from its active
+ * tree, so as to make sure that it won't be
+ * considered when computing next_in_service. See the
+ * comments on the function
+ * bfq_no_longer_next_in_service() for details.
*/
if (bfq_no_longer_next_in_service(entity))
bfq_active_extract(bfq_entity_service_tree(entity),
entity);
/*
- * For the same reason why we may have just extracted
- * entity from its active tree, we may need to update
- * next_in_service for the sched_data of entity too,
- * regardless of whether entity has been extracted.
- * In fact, even if entity has not been extracted, a
- * descendant entity may get extracted. Such an event
- * would cause a change in next_in_service for the
- * level of the descendant entity, and thus possibly
- * back to upper levels.
+ * Even if entity is not to be extracted according to
+ * the above check, a descendant entity may get
+ * extracted in one of the next iterations of this
+ * loop. Such an event could cause a change in
+ * next_in_service for the level of the descendant
+ * entity, and thus possibly back to this level.
*
- * We cannot perform the resulting needed update
- * before the end of this loop, because, to know which
- * is the correct next-to-serve candidate entity for
- * each level, we need first to find the leaf entity
- * to set in service. In fact, only after we know
- * which is the next-to-serve leaf entity, we can
- * discover whether the parent entity of the leaf
- * entity becomes the next-to-serve, and so on.
+ * However, we cannot perform the resulting needed
+ * update of next_in_service for this level before the
+ * end of the whole loop, because, to know which is
+ * the correct next-to-serve candidate entity for each
+ * level, we need first to find the leaf entity to set
+ * in service. In fact, only after we know which is
+ * the next-to-serve leaf entity, we can discover
+ * whether the parent entity of the leaf entity
+ * becomes the next-to-serve, and so on.
*/
-
}
bfqq = bfq_entity_to_bfqq(entity);
diff --git a/block/bio-integrity.c b/block/bio-integrity.c
index 83e92beb3c9f..9b1ea478577b 100644
--- a/block/bio-integrity.c
+++ b/block/bio-integrity.c
@@ -387,9 +387,11 @@ static void bio_integrity_verify_fn(struct work_struct *work)
*/
bool __bio_integrity_endio(struct bio *bio)
{
- if (bio_op(bio) == REQ_OP_READ && !bio->bi_status) {
- struct bio_integrity_payload *bip = bio_integrity(bio);
+ struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
+ struct bio_integrity_payload *bip = bio_integrity(bio);
+ if (bio_op(bio) == REQ_OP_READ && !bio->bi_status &&
+ (bip->bip_flags & BIP_BLOCK_INTEGRITY) && bi->profile->verify_fn) {
INIT_WORK(&bip->bip_work, bio_integrity_verify_fn);
queue_work(kintegrityd_wq, &bip->bip_work);
return false;
diff --git a/block/blk-core.c b/block/blk-core.c
index 970b9c9638c5..dbecbf4a64e0 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -3421,6 +3421,10 @@ EXPORT_SYMBOL(blk_finish_plug);
*/
void blk_pm_runtime_init(struct request_queue *q, struct device *dev)
{
+ /* not support for RQF_PM and ->rpm_status in blk-mq yet */
+ if (q->mq_ops)
+ return;
+
q->dev = dev;
q->rpm_status = RPM_ACTIVE;
pm_runtime_set_autosuspend_delay(q->dev, -1);
diff --git a/block/blk-mq-cpumap.c b/block/blk-mq-cpumap.c
index 4891f042a22f..9f8cffc8a701 100644
--- a/block/blk-mq-cpumap.c
+++ b/block/blk-mq-cpumap.c
@@ -17,9 +17,9 @@
static int cpu_to_queue_index(unsigned int nr_queues, const int cpu)
{
/*
- * Non online CPU will be mapped to queue index 0.
+ * Non present CPU will be mapped to queue index 0.
*/
- if (!cpu_online(cpu))
+ if (!cpu_present(cpu))
return 0;
return cpu % nr_queues;
}
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 041f7b7fa0d6..535cbdf32aab 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -301,11 +301,12 @@ static struct request *blk_mq_get_request(struct request_queue *q,
struct elevator_queue *e = q->elevator;
struct request *rq;
unsigned int tag;
+ struct blk_mq_ctx *local_ctx = NULL;
blk_queue_enter_live(q);
data->q = q;
if (likely(!data->ctx))
- data->ctx = blk_mq_get_ctx(q);
+ data->ctx = local_ctx = blk_mq_get_ctx(q);
if (likely(!data->hctx))
data->hctx = blk_mq_map_queue(q, data->ctx->cpu);
if (op & REQ_NOWAIT)
@@ -324,6 +325,10 @@ static struct request *blk_mq_get_request(struct request_queue *q,
tag = blk_mq_get_tag(data);
if (tag == BLK_MQ_TAG_FAIL) {
+ if (local_ctx) {
+ blk_mq_put_ctx(local_ctx);
+ data->ctx = NULL;
+ }
blk_queue_exit(q);
return NULL;
}
@@ -356,12 +361,12 @@ struct request *blk_mq_alloc_request(struct request_queue *q, unsigned int op,
rq = blk_mq_get_request(q, NULL, op, &alloc_data);
- blk_mq_put_ctx(alloc_data.ctx);
- blk_queue_exit(q);
-
if (!rq)
return ERR_PTR(-EWOULDBLOCK);
+ blk_mq_put_ctx(alloc_data.ctx);
+ blk_queue_exit(q);
+
rq->__data_len = 0;
rq->__sector = (sector_t) -1;
rq->bio = rq->biotail = NULL;
@@ -407,11 +412,11 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q,
rq = blk_mq_get_request(q, NULL, op, &alloc_data);
- blk_queue_exit(q);
-
if (!rq)
return ERR_PTR(-EWOULDBLOCK);
+ blk_queue_exit(q);
+
return rq;
}
EXPORT_SYMBOL_GPL(blk_mq_alloc_request_hctx);
@@ -679,8 +684,8 @@ EXPORT_SYMBOL(blk_mq_kick_requeue_list);
void blk_mq_delay_kick_requeue_list(struct request_queue *q,
unsigned long msecs)
{
- kblockd_schedule_delayed_work(&q->requeue_work,
- msecs_to_jiffies(msecs));
+ kblockd_mod_delayed_work_on(WORK_CPU_UNBOUND, &q->requeue_work,
+ msecs_to_jiffies(msecs));
}
EXPORT_SYMBOL(blk_mq_delay_kick_requeue_list);
diff --git a/crypto/authencesn.c b/crypto/authencesn.c
index 6f8f6b86bfe2..0cf5fefdb859 100644
--- a/crypto/authencesn.c
+++ b/crypto/authencesn.c
@@ -248,6 +248,9 @@ static int crypto_authenc_esn_decrypt_tail(struct aead_request *req,
u8 *ihash = ohash + crypto_ahash_digestsize(auth);
u32 tmp[2];
+ if (!authsize)
+ goto decrypt;
+
/* Move high-order bits of sequence number back. */
scatterwalk_map_and_copy(tmp, dst, 4, 4, 0);
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0);
@@ -256,6 +259,8 @@ static int crypto_authenc_esn_decrypt_tail(struct aead_request *req,
if (crypto_memneq(ihash, ohash, authsize))
return -EBADMSG;
+decrypt:
+
sg_init_table(areq_ctx->dst, 2);
dst = scatterwalk_ffwd(areq_ctx->dst, dst, assoclen);
diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
index fc6c416f8724..d5999eb41c00 100644
--- a/drivers/acpi/acpi_apd.c
+++ b/drivers/acpi/acpi_apd.c
@@ -180,8 +180,8 @@ static const struct acpi_device_id acpi_apd_device_ids[] = {
{ "APMC0D0F", APD_ADDR(xgene_i2c_desc) },
{ "BRCM900D", APD_ADDR(vulcan_spi_desc) },
{ "CAV900D", APD_ADDR(vulcan_spi_desc) },
- { "HISI0A21", APD_ADDR(hip07_i2c_desc) },
- { "HISI0A22", APD_ADDR(hip08_i2c_desc) },
+ { "HISI02A1", APD_ADDR(hip07_i2c_desc) },
+ { "HISI02A2", APD_ADDR(hip08_i2c_desc) },
#endif
{ }
};
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index e51a1e98e62f..f88caf5aab76 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -85,6 +85,7 @@ static const struct lpss_device_desc lpss_dma_desc = {
};
struct lpss_private_data {
+ struct acpi_device *adev;
void __iomem *mmio_base;
resource_size_t mmio_size;
unsigned int fixed_clk_rate;
@@ -155,6 +156,12 @@ static struct pwm_lookup byt_pwm_lookup[] = {
static void byt_pwm_setup(struct lpss_private_data *pdata)
{
+ struct acpi_device *adev = pdata->adev;
+
+ /* Only call pwm_add_table for the first PWM controller */
+ if (!adev->pnp.unique_id || strcmp(adev->pnp.unique_id, "1"))
+ return;
+
if (!acpi_dev_present("INT33FD", NULL, -1))
pwm_add_table(byt_pwm_lookup, ARRAY_SIZE(byt_pwm_lookup));
}
@@ -180,6 +187,12 @@ static struct pwm_lookup bsw_pwm_lookup[] = {
static void bsw_pwm_setup(struct lpss_private_data *pdata)
{
+ struct acpi_device *adev = pdata->adev;
+
+ /* Only call pwm_add_table for the first PWM controller */
+ if (!adev->pnp.unique_id || strcmp(adev->pnp.unique_id, "1"))
+ return;
+
pwm_add_table(bsw_pwm_lookup, ARRAY_SIZE(bsw_pwm_lookup));
}
@@ -456,6 +469,7 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
goto err_out;
}
+ pdata->adev = adev;
pdata->dev_desc = dev_desc;
if (dev_desc->setup)
diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c
index 8c4e0a18460a..bf22c29d2517 100644
--- a/drivers/acpi/acpi_watchdog.c
+++ b/drivers/acpi/acpi_watchdog.c
@@ -86,7 +86,12 @@ void __init acpi_watchdog_init(void)
found = false;
resource_list_for_each_entry(rentry, &resource_list) {
- if (resource_contains(rentry->res, &res)) {
+ if (rentry->res->flags == res.flags &&
+ resource_overlaps(rentry->res, &res)) {
+ if (res.start < rentry->res->start)
+ rentry->res->start = res.start;
+ if (res.end > rentry->res->end)
+ rentry->res->end = res.end;
found = true;
break;
}
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index ddb01e9fa5b2..62068a5e814f 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -151,6 +151,10 @@ static bool ec_freeze_events __read_mostly = false;
module_param(ec_freeze_events, bool, 0644);
MODULE_PARM_DESC(ec_freeze_events, "Disabling event handling during suspend/resume");
+static bool ec_no_wakeup __read_mostly;
+module_param(ec_no_wakeup, bool, 0644);
+MODULE_PARM_DESC(ec_no_wakeup, "Do not wake up from suspend-to-idle");
+
struct acpi_ec_query_handler {
struct list_head node;
acpi_ec_query_func func;
@@ -535,6 +539,14 @@ static void acpi_ec_disable_event(struct acpi_ec *ec)
spin_unlock_irqrestore(&ec->lock, flags);
__acpi_ec_flush_event(ec);
}
+
+void acpi_ec_flush_work(void)
+{
+ if (first_ec)
+ __acpi_ec_flush_event(first_ec);
+
+ flush_scheduled_work();
+}
#endif /* CONFIG_PM_SLEEP */
static bool acpi_ec_guard_event(struct acpi_ec *ec)
@@ -1880,6 +1892,32 @@ static int acpi_ec_suspend(struct device *dev)
return 0;
}
+static int acpi_ec_suspend_noirq(struct device *dev)
+{
+ struct acpi_ec *ec = acpi_driver_data(to_acpi_device(dev));
+
+ /*
+ * The SCI handler doesn't run at this point, so the GPE can be
+ * masked at the low level without side effects.
+ */
+ if (ec_no_wakeup && test_bit(EC_FLAGS_STARTED, &ec->flags) &&
+ ec->reference_count >= 1)
+ acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE);
+
+ return 0;
+}
+
+static int acpi_ec_resume_noirq(struct device *dev)
+{
+ struct acpi_ec *ec = acpi_driver_data(to_acpi_device(dev));
+
+ if (ec_no_wakeup && test_bit(EC_FLAGS_STARTED, &ec->flags) &&
+ ec->reference_count >= 1)
+ acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE);
+
+ return 0;
+}
+
static int acpi_ec_resume(struct device *dev)
{
struct acpi_ec *ec =
@@ -1891,6 +1929,7 @@ static int acpi_ec_resume(struct device *dev)
#endif
static const struct dev_pm_ops acpi_ec_pm = {
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(acpi_ec_suspend_noirq, acpi_ec_resume_noirq)
SET_SYSTEM_SLEEP_PM_OPS(acpi_ec_suspend, acpi_ec_resume)
};
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 9531d3276f65..58dd7ab3c653 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -193,6 +193,10 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
void *data);
void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);
+#ifdef CONFIG_PM_SLEEP
+void acpi_ec_flush_work(void);
+#endif
+
/*--------------------------------------------------------------------------
Suspend/Resume
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index b75b734ee73a..19182d091587 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -3160,6 +3160,8 @@ static struct acpi_driver acpi_nfit_driver = {
static __init int nfit_init(void)
{
+ int ret;
+
BUILD_BUG_ON(sizeof(struct acpi_table_nfit) != 40);
BUILD_BUG_ON(sizeof(struct acpi_nfit_system_address) != 56);
BUILD_BUG_ON(sizeof(struct acpi_nfit_memory_map) != 48);
@@ -3187,8 +3189,14 @@ static __init int nfit_init(void)
return -ENOMEM;
nfit_mce_register();
+ ret = acpi_bus_register_driver(&acpi_nfit_driver);
+ if (ret) {
+ nfit_mce_unregister();
+ destroy_workqueue(nfit_wq);
+ }
+
+ return ret;
- return acpi_bus_register_driver(&acpi_nfit_driver);
}
static __exit void nfit_exit(void)
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index edb0c79f7c64..917f1cc0fda4 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -443,7 +443,7 @@ int __init acpi_numa_init(void)
* So go over all cpu entries in SRAT to get apicid to node mapping.
*/
- /* SRAT: Static Resource Affinity Table */
+ /* SRAT: System Resource Affinity Table */
if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
struct acpi_subtable_proc srat_proc[3];
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index be17664736b2..fa8243c5c062 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -777,11 +777,11 @@ static void acpi_freeze_sync(void)
/*
* Process all pending events in case there are any wakeup ones.
*
- * The EC driver uses the system workqueue, so that one needs to be
- * flushed too.
+ * The EC driver uses the system workqueue and an additional special
+ * one, so those need to be flushed too.
*/
+ acpi_ec_flush_work();
acpi_os_wait_events_complete();
- flush_scheduled_work();
s2idle_wakeup = false;
}
diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
index 4ac3e06b41d8..98aa8c808a33 100644
--- a/drivers/acpi/spcr.c
+++ b/drivers/acpi/spcr.c
@@ -17,6 +17,16 @@
#include <linux/serial_core.h>
/*
+ * Erratum 44 for QDF2432v1 and QDF2400v1 SoCs describes the BUSY bit as
+ * occasionally getting stuck as 1. To avoid the potential for a hang, check
+ * TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART
+ * implementations, so only do so if an affected platform is detected in
+ * parse_spcr().
+ */
+bool qdf2400_e44_present;
+EXPORT_SYMBOL(qdf2400_e44_present);
+
+/*
* Some Qualcomm Datacenter Technologies SoCs have a defective UART BUSY bit.
* Detect them by examining the OEM fields in the SPCR header, similiar to PCI
* quirk detection in pci_mcfg.c.
@@ -147,8 +157,30 @@ int __init parse_spcr(bool earlycon)
goto done;
}
- if (qdf2400_erratum_44_present(&table->header))
- uart = "qdf2400_e44";
+ /*
+ * If the E44 erratum is required, then we need to tell the pl011
+ * driver to implement the work-around.
+ *
+ * The global variable is used by the probe function when it
+ * creates the UARTs, whether or not they're used as a console.
+ *
+ * If the user specifies "traditional" earlycon, the qdf2400_e44
+ * console name matches the EARLYCON_DECLARE() statement, and
+ * SPCR is not used. Parameter "earlycon" is false.
+ *
+ * If the user specifies "SPCR" earlycon, then we need to update
+ * the console name so that it also says "qdf2400_e44". Parameter
+ * "earlycon" is true.
+ *
+ * For consistency, if we change the console name, then we do it
+ * for everyone, not just earlycon.
+ */
+ if (qdf2400_erratum_44_present(&table->header)) {
+ qdf2400_e44_present = true;
+ if (earlycon)
+ uart = "qdf2400_e44";
+ }
+
if (xgene_8250_erratum_present(table))
iotype = "mmio32";
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index aae4d8d4be36..f7665c31feca 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2200,8 +2200,12 @@ static void binder_transaction(struct binder_proc *proc,
list_add_tail(&t->work.entry, target_list);
tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
list_add_tail(&tcomplete->entry, &thread->todo);
- if (target_wait)
- wake_up_interruptible(target_wait);
+ if (target_wait) {
+ if (reply || !(t->flags & TF_ONE_WAY))
+ wake_up_interruptible_sync(target_wait);
+ else
+ wake_up_interruptible(target_wait);
+ }
return;
err_translate_failed:
@@ -3247,10 +3251,6 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
/*pr_info("binder_ioctl: %d:%d %x %lx\n",
proc->pid, current->pid, cmd, arg);*/
- if (unlikely(current->mm != proc->vma_vm_mm)) {
- pr_err("current mm mismatch proc mm\n");
- return -EINVAL;
- }
trace_binder_ioctl(cmd, arg);
ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
@@ -3464,9 +3464,8 @@ static int binder_open(struct inode *nodp, struct file *filp)
proc = kzalloc(sizeof(*proc), GFP_KERNEL);
if (proc == NULL)
return -ENOMEM;
- get_task_struct(current);
- proc->tsk = current;
- proc->vma_vm_mm = current->mm;
+ get_task_struct(current->group_leader);
+ proc->tsk = current->group_leader;
INIT_LIST_HEAD(&proc->todo);
init_waitqueue_head(&proc->wait);
proc->default_priority = task_nice(current);
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 948fc86980a1..363fc5330c21 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -215,7 +215,7 @@ config SATA_FSL
config SATA_GEMINI
tristate "Gemini SATA bridge support"
- depends on PATA_FTIDE010
+ depends on ARCH_GEMINI || COMPILE_TEST
default ARCH_GEMINI
help
This enabled support for the FTIDE010 to SATA bridge
@@ -613,7 +613,7 @@ config PATA_FTIDE010
tristate "Faraday Technology FTIDE010 PATA support"
depends on OF
depends on ARM
- default ARCH_GEMINI
+ depends on SATA_GEMINI
help
This option enables support for the Faraday FTIDE010
PATA controller found in the Cortina Gemini SoCs.
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 8453f9a4682f..fa7dd4394c02 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2083,7 +2083,7 @@ unsigned int ata_read_log_page(struct ata_device *dev, u8 log,
retry:
ata_tf_init(dev, &tf);
if (dev->dma_mode && ata_id_has_read_log_dma_ext(dev->id) &&
- !(dev->horkage & ATA_HORKAGE_NO_NCQ_LOG)) {
+ !(dev->horkage & ATA_HORKAGE_NO_DMA_LOG)) {
tf.command = ATA_CMD_READ_LOG_DMA_EXT;
tf.protocol = ATA_PROT_DMA;
dma = true;
@@ -2102,8 +2102,8 @@ retry:
buf, sectors * ATA_SECT_SIZE, 0);
if (err_mask && dma) {
- dev->horkage |= ATA_HORKAGE_NO_NCQ_LOG;
- ata_dev_warn(dev, "READ LOG DMA EXT failed, trying unqueued\n");
+ dev->horkage |= ATA_HORKAGE_NO_DMA_LOG;
+ ata_dev_warn(dev, "READ LOG DMA EXT failed, trying PIO\n");
goto retry;
}
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index b70bcf6d2914..3dbd05532c09 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1434,7 +1434,7 @@ void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev,
/**
* ata_eh_done - EH action complete
-* @ap: target ATA port
+ * @link: ATA link for which EH actions are complete
* @dev: target ATA dev for per-dev action (can be NULL)
* @action: action just completed
*
@@ -1576,7 +1576,7 @@ unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key)
/**
* ata_eh_request_sense - perform REQUEST_SENSE_DATA_EXT
- * @dev: device to perform REQUEST_SENSE_SENSE_DATA_EXT to
+ * @qc: qc to perform REQUEST_SENSE_SENSE_DATA_EXT to
* @cmd: scsi command for which the sense code should be set
*
* Perform REQUEST_SENSE_DATA_EXT after the device reported CHECK
@@ -4175,7 +4175,6 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)
struct ata_link *link;
struct ata_device *dev;
unsigned long flags;
- int rc = 0;
/* are we resuming? */
spin_lock_irqsave(ap->lock, flags);
@@ -4202,7 +4201,7 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)
ata_acpi_set_state(ap, ap->pm_mesg);
if (ap->ops->port_resume)
- rc = ap->ops->port_resume(ap);
+ ap->ops->port_resume(ap);
/* tell ACPI that we're resuming */
ata_acpi_on_resume(ap);
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index d462c5a3a7ef..44ba292f2cd7 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3030,10 +3030,12 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
static struct ata_device *ata_find_dev(struct ata_port *ap, int devno)
{
if (!sata_pmp_attached(ap)) {
- if (likely(devno < ata_link_max_devices(&ap->link)))
+ if (likely(devno >= 0 &&
+ devno < ata_link_max_devices(&ap->link)))
return &ap->link.device[devno];
} else {
- if (likely(devno < ap->nr_pmp_links))
+ if (likely(devno >= 0 &&
+ devno < ap->nr_pmp_links))
return &ap->pmp_link[devno].device[0];
}
diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c
index ee9844758736..537d11869069 100644
--- a/drivers/ata/sata_rcar.c
+++ b/drivers/ata/sata_rcar.c
@@ -858,6 +858,14 @@ static const struct of_device_id sata_rcar_match[] = {
.compatible = "renesas,sata-r8a7795",
.data = (void *)RCAR_GEN2_SATA
},
+ {
+ .compatible = "renesas,rcar-gen2-sata",
+ .data = (void *)RCAR_GEN2_SATA
+ },
+ {
+ .compatible = "renesas,rcar-gen3-sata",
+ .data = (void *)RCAR_GEN2_SATA
+ },
{ },
};
MODULE_DEVICE_TABLE(of, sata_rcar_match);
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index 292dec18ffb8..07bdd51b3b9a 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -1613,7 +1613,7 @@ static int zatm_init_one(struct pci_dev *pci_dev,
ret = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32));
if (ret < 0)
- goto out_disable;
+ goto out_release;
zatm_dev->pci_dev = pci_dev;
dev->dev_data = zatm_dev;
diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c
index 2ae24c28e70c..1c152aed6b82 100644
--- a/drivers/base/dma-coherent.c
+++ b/drivers/base/dma-coherent.c
@@ -25,7 +25,7 @@ static inline struct dma_coherent_mem *dev_get_coherent_memory(struct device *de
{
if (dev && dev->dma_mem)
return dev->dma_mem;
- return dma_coherent_default_memory;
+ return NULL;
}
static inline dma_addr_t dma_get_device_base(struct device *dev,
@@ -165,34 +165,15 @@ void *dma_mark_declared_memory_occupied(struct device *dev,
}
EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
-/**
- * dma_alloc_from_coherent() - try to allocate memory from the per-device coherent area
- *
- * @dev: device from which we allocate memory
- * @size: size of requested memory area
- * @dma_handle: This will be filled with the correct dma handle
- * @ret: This pointer will be filled with the virtual address
- * to allocated area.
- *
- * This function should be only called from per-arch dma_alloc_coherent()
- * to support allocation from per-device coherent memory pools.
- *
- * Returns 0 if dma_alloc_coherent should continue with allocating from
- * generic memory areas, or !0 if dma_alloc_coherent should return @ret.
- */
-int dma_alloc_from_coherent(struct device *dev, ssize_t size,
- dma_addr_t *dma_handle, void **ret)
+static void *__dma_alloc_from_coherent(struct dma_coherent_mem *mem,
+ ssize_t size, dma_addr_t *dma_handle)
{
- struct dma_coherent_mem *mem = dev_get_coherent_memory(dev);
int order = get_order(size);
unsigned long flags;
int pageno;
int dma_memory_map;
+ void *ret;
- if (!mem)
- return 0;
-
- *ret = NULL;
spin_lock_irqsave(&mem->spinlock, flags);
if (unlikely(size > (mem->size << PAGE_SHIFT)))
@@ -203,21 +184,50 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size,
goto err;
/*
- * Memory was found in the per-device area.
+ * Memory was found in the coherent area.
*/
- *dma_handle = dma_get_device_base(dev, mem) + (pageno << PAGE_SHIFT);
- *ret = mem->virt_base + (pageno << PAGE_SHIFT);
+ *dma_handle = mem->device_base + (pageno << PAGE_SHIFT);
+ ret = mem->virt_base + (pageno << PAGE_SHIFT);
dma_memory_map = (mem->flags & DMA_MEMORY_MAP);
spin_unlock_irqrestore(&mem->spinlock, flags);
if (dma_memory_map)
- memset(*ret, 0, size);
+ memset(ret, 0, size);
else
- memset_io(*ret, 0, size);
+ memset_io(ret, 0, size);
- return 1;
+ return ret;
err:
spin_unlock_irqrestore(&mem->spinlock, flags);
+ return NULL;
+}
+
+/**
+ * dma_alloc_from_dev_coherent() - allocate memory from device coherent pool
+ * @dev: device from which we allocate memory
+ * @size: size of requested memory area
+ * @dma_handle: This will be filled with the correct dma handle
+ * @ret: This pointer will be filled with the virtual address
+ * to allocated area.
+ *
+ * This function should be only called from per-arch dma_alloc_coherent()
+ * to support allocation from per-device coherent memory pools.
+ *
+ * Returns 0 if dma_alloc_coherent should continue with allocating from
+ * generic memory areas, or !0 if dma_alloc_coherent should return @ret.
+ */
+int dma_alloc_from_dev_coherent(struct device *dev, ssize_t size,
+ dma_addr_t *dma_handle, void **ret)
+{
+ struct dma_coherent_mem *mem = dev_get_coherent_memory(dev);
+
+ if (!mem)
+ return 0;
+
+ *ret = __dma_alloc_from_coherent(mem, size, dma_handle);
+ if (*ret)
+ return 1;
+
/*
* In the case where the allocation can not be satisfied from the
* per-device area, try to fall back to generic memory if the
@@ -225,25 +235,20 @@ err:
*/
return mem->flags & DMA_MEMORY_EXCLUSIVE;
}
-EXPORT_SYMBOL(dma_alloc_from_coherent);
+EXPORT_SYMBOL(dma_alloc_from_dev_coherent);
-/**
- * dma_release_from_coherent() - try to free the memory allocated from per-device coherent memory pool
- * @dev: device from which the memory was allocated
- * @order: the order of pages allocated
- * @vaddr: virtual address of allocated pages
- *
- * This checks whether the memory was allocated from the per-device
- * coherent memory pool and if so, releases that memory.
- *
- * Returns 1 if we correctly released the memory, or 0 if
- * dma_release_coherent() should proceed with releasing memory from
- * generic pools.
- */
-int dma_release_from_coherent(struct device *dev, int order, void *vaddr)
+void *dma_alloc_from_global_coherent(ssize_t size, dma_addr_t *dma_handle)
{
- struct dma_coherent_mem *mem = dev_get_coherent_memory(dev);
+ if (!dma_coherent_default_memory)
+ return NULL;
+
+ return __dma_alloc_from_coherent(dma_coherent_default_memory, size,
+ dma_handle);
+}
+static int __dma_release_from_coherent(struct dma_coherent_mem *mem,
+ int order, void *vaddr)
+{
if (mem && vaddr >= mem->virt_base && vaddr <
(mem->virt_base + (mem->size << PAGE_SHIFT))) {
int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
@@ -256,28 +261,39 @@ int dma_release_from_coherent(struct device *dev, int order, void *vaddr)
}
return 0;
}
-EXPORT_SYMBOL(dma_release_from_coherent);
/**
- * dma_mmap_from_coherent() - try to mmap the memory allocated from
- * per-device coherent memory pool to userspace
+ * dma_release_from_dev_coherent() - free memory to device coherent memory pool
* @dev: device from which the memory was allocated
- * @vma: vm_area for the userspace memory
- * @vaddr: cpu address returned by dma_alloc_from_coherent
- * @size: size of the memory buffer allocated by dma_alloc_from_coherent
- * @ret: result from remap_pfn_range()
+ * @order: the order of pages allocated
+ * @vaddr: virtual address of allocated pages
*
* This checks whether the memory was allocated from the per-device
- * coherent memory pool and if so, maps that memory to the provided vma.
+ * coherent memory pool and if so, releases that memory.
*
- * Returns 1 if we correctly mapped the memory, or 0 if the caller should
- * proceed with mapping memory from generic pools.
+ * Returns 1 if we correctly released the memory, or 0 if the caller should
+ * proceed with releasing memory from generic pools.
*/
-int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma,
- void *vaddr, size_t size, int *ret)
+int dma_release_from_dev_coherent(struct device *dev, int order, void *vaddr)
{
struct dma_coherent_mem *mem = dev_get_coherent_memory(dev);
+ return __dma_release_from_coherent(mem, order, vaddr);
+}
+EXPORT_SYMBOL(dma_release_from_dev_coherent);
+
+int dma_release_from_global_coherent(int order, void *vaddr)
+{
+ if (!dma_coherent_default_memory)
+ return 0;
+
+ return __dma_release_from_coherent(dma_coherent_default_memory, order,
+ vaddr);
+}
+
+static int __dma_mmap_from_coherent(struct dma_coherent_mem *mem,
+ struct vm_area_struct *vma, void *vaddr, size_t size, int *ret)
+{
if (mem && vaddr >= mem->virt_base && vaddr + size <=
(mem->virt_base + (mem->size << PAGE_SHIFT))) {
unsigned long off = vma->vm_pgoff;
@@ -296,7 +312,39 @@ int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma,
}
return 0;
}
-EXPORT_SYMBOL(dma_mmap_from_coherent);
+
+/**
+ * dma_mmap_from_dev_coherent() - mmap memory from the device coherent pool
+ * @dev: device from which the memory was allocated
+ * @vma: vm_area for the userspace memory
+ * @vaddr: cpu address returned by dma_alloc_from_dev_coherent
+ * @size: size of the memory buffer allocated
+ * @ret: result from remap_pfn_range()
+ *
+ * This checks whether the memory was allocated from the per-device
+ * coherent memory pool and if so, maps that memory to the provided vma.
+ *
+ * Returns 1 if we correctly mapped the memory, or 0 if the caller should
+ * proceed with mapping memory from generic pools.
+ */
+int dma_mmap_from_dev_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *vaddr, size_t size, int *ret)
+{
+ struct dma_coherent_mem *mem = dev_get_coherent_memory(dev);
+
+ return __dma_mmap_from_coherent(mem, vma, vaddr, size, ret);
+}
+EXPORT_SYMBOL(dma_mmap_from_dev_coherent);
+
+int dma_mmap_from_global_coherent(struct vm_area_struct *vma, void *vaddr,
+ size_t size, int *ret)
+{
+ if (!dma_coherent_default_memory)
+ return 0;
+
+ return __dma_mmap_from_coherent(dma_coherent_default_memory, vma,
+ vaddr, size, ret);
+}
/*
* Support for reserved memory regions defined in device tree
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index 5096755d185e..b555ff9dd8fc 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -235,7 +235,7 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
+ if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
return ret;
if (off < count && user_count <= (count - off)) {
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index b9f907eedbf7..bfbe1e154128 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -30,7 +30,6 @@
#include <linux/syscore_ops.h>
#include <linux/reboot.h>
#include <linux/security.h>
-#include <linux/swait.h>
#include <generated/utsrelease.h>
@@ -112,13 +111,13 @@ static inline long firmware_loading_timeout(void)
* state of the firmware loading.
*/
struct fw_state {
- struct swait_queue_head wq;
+ struct completion completion;
enum fw_status status;
};
static void fw_state_init(struct fw_state *fw_st)
{
- init_swait_queue_head(&fw_st->wq);
+ init_completion(&fw_st->completion);
fw_st->status = FW_STATUS_UNKNOWN;
}
@@ -131,9 +130,7 @@ static int __fw_state_wait_common(struct fw_state *fw_st, long timeout)
{
long ret;
- ret = swait_event_interruptible_timeout(fw_st->wq,
- __fw_state_is_done(READ_ONCE(fw_st->status)),
- timeout);
+ ret = wait_for_completion_killable_timeout(&fw_st->completion, timeout);
if (ret != 0 && fw_st->status == FW_STATUS_ABORTED)
return -ENOENT;
if (!ret)
@@ -148,35 +145,34 @@ static void __fw_state_set(struct fw_state *fw_st,
WRITE_ONCE(fw_st->status, status);
if (status == FW_STATUS_DONE || status == FW_STATUS_ABORTED)
- swake_up(&fw_st->wq);
+ complete_all(&fw_st->completion);
}
#define fw_state_start(fw_st) \
__fw_state_set(fw_st, FW_STATUS_LOADING)
#define fw_state_done(fw_st) \
__fw_state_set(fw_st, FW_STATUS_DONE)
+#define fw_state_aborted(fw_st) \
+ __fw_state_set(fw_st, FW_STATUS_ABORTED)
#define fw_state_wait(fw_st) \
__fw_state_wait_common(fw_st, MAX_SCHEDULE_TIMEOUT)
-#ifndef CONFIG_FW_LOADER_USER_HELPER
-
-#define fw_state_is_aborted(fw_st) false
-
-#else /* CONFIG_FW_LOADER_USER_HELPER */
-
static int __fw_state_check(struct fw_state *fw_st, enum fw_status status)
{
return fw_st->status == status;
}
+#define fw_state_is_aborted(fw_st) \
+ __fw_state_check(fw_st, FW_STATUS_ABORTED)
+
+#ifdef CONFIG_FW_LOADER_USER_HELPER
+
#define fw_state_aborted(fw_st) \
__fw_state_set(fw_st, FW_STATUS_ABORTED)
#define fw_state_is_done(fw_st) \
__fw_state_check(fw_st, FW_STATUS_DONE)
#define fw_state_is_loading(fw_st) \
__fw_state_check(fw_st, FW_STATUS_LOADING)
-#define fw_state_is_aborted(fw_st) \
- __fw_state_check(fw_st, FW_STATUS_ABORTED)
#define fw_state_wait_timeout(fw_st, timeout) \
__fw_state_wait_common(fw_st, timeout)
@@ -1200,6 +1196,28 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name,
return 1; /* need to load */
}
+/*
+ * Batched requests need only one wake, we need to do this step last due to the
+ * fallback mechanism. The buf is protected with kref_get(), and it won't be
+ * released until the last user calls release_firmware().
+ *
+ * Failed batched requests are possible as well, in such cases we just share
+ * the struct firmware_buf and won't release it until all requests are woken
+ * and have gone through this same path.
+ */
+static void fw_abort_batch_reqs(struct firmware *fw)
+{
+ struct firmware_buf *buf;
+
+ /* Loaded directly? */
+ if (!fw || !fw->priv)
+ return;
+
+ buf = fw->priv;
+ if (!fw_state_is_aborted(&buf->fw_st))
+ fw_state_aborted(&buf->fw_st);
+}
+
/* called from request_firmware() and request_firmware_work_func() */
static int
_request_firmware(const struct firmware **firmware_p, const char *name,
@@ -1243,6 +1261,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
out:
if (ret < 0) {
+ fw_abort_batch_reqs(fw);
release_firmware(fw);
fw = NULL;
}
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 3b8210ebb50e..60303aa28587 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1222,8 +1222,6 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev,
spin_unlock_irq(&dev->power.lock);
- dev_pm_domain_set(dev, &genpd->domain);
-
return gpd_data;
err_free:
@@ -1237,8 +1235,6 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev,
static void genpd_free_dev_data(struct device *dev,
struct generic_pm_domain_data *gpd_data)
{
- dev_pm_domain_set(dev, NULL);
-
spin_lock_irq(&dev->power.lock);
dev->power.subsys_data->domain_data = NULL;
@@ -1275,6 +1271,8 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
if (ret)
goto out;
+ dev_pm_domain_set(dev, &genpd->domain);
+
genpd->device_count++;
genpd->max_off_time_changed = true;
@@ -1336,6 +1334,8 @@ static int genpd_remove_device(struct generic_pm_domain *genpd,
if (genpd->detach_dev)
genpd->detach_dev(genpd, dev);
+ dev_pm_domain_set(dev, NULL);
+
list_del_init(&pdd->list_node);
genpd_unlock(genpd);
diff --git a/drivers/base/regmap/regmap-w1.c b/drivers/base/regmap/regmap-w1.c
index 5f04e7bf063e..e6c64b0be5b2 100644
--- a/drivers/base/regmap/regmap-w1.c
+++ b/drivers/base/regmap/regmap-w1.c
@@ -1,7 +1,7 @@
/*
* Register map access API - W1 (1-Wire) support
*
- * Copyright (C) 2017 OAO Radioavionica
+ * Copyright (c) 2017 Radioavionica Corporation
* Author: Alex A. Mihaylov <minimumlaw@rambler.ru>
*
* This program is free software; you can redistribute it and/or modify
@@ -11,7 +11,7 @@
#include <linux/regmap.h>
#include <linux/module.h>
-#include "../../w1/w1.h"
+#include <linux/w1.h>
#include "internal.h"
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index dea7d85134ee..5bdf923294a5 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -626,7 +626,6 @@ static void recv_work(struct work_struct *work)
struct nbd_device *nbd = args->nbd;
struct nbd_config *config = nbd->config;
struct nbd_cmd *cmd;
- int ret = 0;
while (1) {
cmd = nbd_read_stat(nbd, args->index);
@@ -636,7 +635,6 @@ static void recv_work(struct work_struct *work)
mutex_lock(&nsock->tx_lock);
nbd_mark_nsock_dead(nbd, nsock, 1);
mutex_unlock(&nsock->tx_lock);
- ret = PTR_ERR(cmd);
break;
}
@@ -910,7 +908,8 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg)
continue;
}
sk_set_memalloc(sock->sk);
- sock->sk->sk_sndtimeo = nbd->tag_set.timeout;
+ if (nbd->tag_set.timeout)
+ sock->sk->sk_sndtimeo = nbd->tag_set.timeout;
atomic_inc(&config->recv_threads);
refcount_inc(&nbd->config_refs);
old = nsock->sock;
@@ -924,6 +923,8 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg)
mutex_unlock(&nsock->tx_lock);
sockfd_put(old);
+ clear_bit(NBD_DISCONNECTED, &config->runtime_flags);
+
/* We take the tx_mutex in an error path in the recv_work, so we
* need to queue_work outside of the tx_mutex.
*/
@@ -980,11 +981,15 @@ static void send_disconnects(struct nbd_device *nbd)
int i, ret;
for (i = 0; i < config->num_connections; i++) {
+ struct nbd_sock *nsock = config->socks[i];
+
iov_iter_kvec(&from, WRITE | ITER_KVEC, &iov, 1, sizeof(request));
+ mutex_lock(&nsock->tx_lock);
ret = sock_xmit(nbd, i, 1, &from, 0, NULL);
if (ret <= 0)
dev_err(disk_to_dev(nbd->disk),
"Send disconnect failed %d\n", ret);
+ mutex_unlock(&nsock->tx_lock);
}
}
@@ -993,9 +998,8 @@ static int nbd_disconnect(struct nbd_device *nbd)
struct nbd_config *config = nbd->config;
dev_info(disk_to_dev(nbd->disk), "NBD_DISCONNECT\n");
- if (!test_and_set_bit(NBD_DISCONNECT_REQUESTED,
- &config->runtime_flags))
- send_disconnects(nbd);
+ set_bit(NBD_DISCONNECT_REQUESTED, &config->runtime_flags);
+ send_disconnects(nbd);
return 0;
}
@@ -1076,7 +1080,9 @@ static int nbd_start_device(struct nbd_device *nbd)
return -ENOMEM;
}
sk_set_memalloc(config->socks[i]->sock->sk);
- config->socks[i]->sock->sk->sk_sndtimeo = nbd->tag_set.timeout;
+ if (nbd->tag_set.timeout)
+ config->socks[i]->sock->sk->sk_sndtimeo =
+ nbd->tag_set.timeout;
atomic_inc(&config->recv_threads);
refcount_inc(&nbd->config_refs);
INIT_WORK(&args->work, recv_work);
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index 6b16ead1da58..ad9749463d4f 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -875,6 +875,56 @@ static void print_version(void)
printk(KERN_INFO "%s", version);
}
+struct vdc_check_port_data {
+ int dev_no;
+ char *type;
+};
+
+static int vdc_device_probed(struct device *dev, void *arg)
+{
+ struct vio_dev *vdev = to_vio_dev(dev);
+ struct vdc_check_port_data *port_data;
+
+ port_data = (struct vdc_check_port_data *)arg;
+
+ if ((vdev->dev_no == port_data->dev_no) &&
+ (!(strcmp((char *)&vdev->type, port_data->type))) &&
+ dev_get_drvdata(dev)) {
+ /* This device has already been configured
+ * by vdc_port_probe()
+ */
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/* Determine whether the VIO device is part of an mpgroup
+ * by locating all the virtual-device-port nodes associated
+ * with the parent virtual-device node for the VIO device
+ * and checking whether any of these nodes are vdc-ports
+ * which have already been configured.
+ *
+ * Returns true if this device is part of an mpgroup and has
+ * already been probed.
+ */
+static bool vdc_port_mpgroup_check(struct vio_dev *vdev)
+{
+ struct vdc_check_port_data port_data;
+ struct device *dev;
+
+ port_data.dev_no = vdev->dev_no;
+ port_data.type = (char *)&vdev->type;
+
+ dev = device_find_child(vdev->dev.parent, &port_data,
+ vdc_device_probed);
+
+ if (dev)
+ return true;
+
+ return false;
+}
+
static int vdc_port_probe(struct vio_dev *vdev, const struct vio_device_id *id)
{
struct mdesc_handle *hp;
@@ -893,6 +943,14 @@ static int vdc_port_probe(struct vio_dev *vdev, const struct vio_device_id *id)
goto err_out_release_mdesc;
}
+ /* Check if this device is part of an mpgroup */
+ if (vdc_port_mpgroup_check(vdev)) {
+ printk(KERN_WARNING
+ "VIO: Ignoring extra vdisk port %s",
+ dev_name(&vdev->dev));
+ goto err_out_release_mdesc;
+ }
+
port = kzalloc(sizeof(*port), GFP_KERNEL);
err = -ENOMEM;
if (!port) {
@@ -943,6 +1001,9 @@ static int vdc_port_probe(struct vio_dev *vdev, const struct vio_device_id *id)
if (err)
goto err_out_free_tx_ring;
+ /* Note that the device driver_data is used to determine
+ * whether the port has been probed.
+ */
dev_set_drvdata(&vdev->dev, port);
mdesc_release(hp);
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 4e02aa5fdac0..1498b899a593 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -541,12 +541,9 @@ virtblk_cache_type_store(struct device *dev, struct device_attribute *attr,
int i;
BUG_ON(!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_CONFIG_WCE));
- for (i = ARRAY_SIZE(virtblk_cache_types); --i >= 0; )
- if (sysfs_streq(buf, virtblk_cache_types[i]))
- break;
-
+ i = sysfs_match_string(virtblk_cache_types, buf);
if (i < 0)
- return -EINVAL;
+ return i;
virtio_cwrite8(vdev, offsetof(struct virtio_blk_config, wce), i);
virtblk_update_cache_mode(vdev);
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index c852ed3c01d5..98e34e4c62b8 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -111,7 +111,7 @@ struct blk_shadow {
};
struct blkif_req {
- int error;
+ blk_status_t error;
};
static inline struct blkif_req *blkif_req(struct request *rq)
@@ -708,6 +708,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
* existing persistent grants, or if we have to get new grants,
* as there are not sufficiently many free.
*/
+ bool new_persistent_gnts = false;
struct scatterlist *sg;
int num_sg, max_grefs, num_grant;
@@ -719,19 +720,21 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
*/
max_grefs += INDIRECT_GREFS(max_grefs);
- /*
- * We have to reserve 'max_grefs' grants because persistent
- * grants are shared by all rings.
- */
- if (max_grefs > 0)
- if (gnttab_alloc_grant_references(max_grefs, &setup.gref_head) < 0) {
+ /* Check if we have enough persistent grants to allocate a requests */
+ if (rinfo->persistent_gnts_c < max_grefs) {
+ new_persistent_gnts = true;
+
+ if (gnttab_alloc_grant_references(
+ max_grefs - rinfo->persistent_gnts_c,
+ &setup.gref_head) < 0) {
gnttab_request_free_callback(
&rinfo->callback,
blkif_restart_queue_callback,
rinfo,
- max_grefs);
+ max_grefs - rinfo->persistent_gnts_c);
return 1;
}
+ }
/* Fill out a communications ring structure. */
id = blkif_ring_get_request(rinfo, req, &ring_req);
@@ -832,7 +835,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
if (unlikely(require_extra_req))
rinfo->shadow[extra_id].req = *extra_ring_req;
- if (max_grefs > 0)
+ if (new_persistent_gnts)
gnttab_free_grant_references(setup.gref_head);
return 0;
@@ -906,8 +909,8 @@ out_err:
return BLK_STS_IOERR;
out_busy:
- spin_unlock_irqrestore(&rinfo->ring_lock, flags);
blk_mq_stop_hw_queue(hctx);
+ spin_unlock_irqrestore(&rinfo->ring_lock, flags);
return BLK_STS_RESOURCE;
}
@@ -1616,7 +1619,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
printk(KERN_WARNING "blkfront: %s: %s op failed\n",
info->gd->disk_name, op_name(bret->operation));
- blkif_req(req)->error = -EOPNOTSUPP;
+ blkif_req(req)->error = BLK_STS_NOTSUPP;
}
if (unlikely(bret->status == BLKIF_RSP_ERROR &&
rinfo->shadow[id].req.u.rw.nr_segments == 0)) {
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 856d5dc02451..3b1b6340ba13 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -308,7 +308,7 @@ static ssize_t comp_algorithm_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t len)
{
struct zram *zram = dev_to_zram(dev);
- char compressor[CRYPTO_MAX_ALG_NAME];
+ char compressor[ARRAY_SIZE(zram->compressor)];
size_t sz;
strlcpy(compressor, buf, sizeof(compressor));
@@ -327,7 +327,7 @@ static ssize_t comp_algorithm_store(struct device *dev,
return -EBUSY;
}
- strlcpy(zram->compressor, compressor, sizeof(compressor));
+ strcpy(zram->compressor, compressor);
up_write(&zram->init_lock);
return len;
}
diff --git a/drivers/bus/uniphier-system-bus.c b/drivers/bus/uniphier-system-bus.c
index 1e6e0269edcc..f76be6bd6eb3 100644
--- a/drivers/bus/uniphier-system-bus.c
+++ b/drivers/bus/uniphier-system-bus.c
@@ -256,10 +256,23 @@ static int uniphier_system_bus_probe(struct platform_device *pdev)
uniphier_system_bus_set_reg(priv);
+ platform_set_drvdata(pdev, priv);
+
/* Now, the bus is configured. Populate platform_devices below it */
return of_platform_default_populate(dev->of_node, NULL, dev);
}
+static int __maybe_unused uniphier_system_bus_resume(struct device *dev)
+{
+ uniphier_system_bus_set_reg(dev_get_drvdata(dev));
+
+ return 0;
+}
+
+static const struct dev_pm_ops uniphier_system_bus_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(NULL, uniphier_system_bus_resume)
+};
+
static const struct of_device_id uniphier_system_bus_match[] = {
{ .compatible = "socionext,uniphier-system-bus" },
{ /* sentinel */ }
@@ -271,6 +284,7 @@ static struct platform_driver uniphier_system_bus_driver = {
.driver = {
.name = "uniphier-system-bus",
.of_match_table = uniphier_system_bus_match,
+ .pm = &uniphier_system_bus_pm_ops,
},
};
module_platform_driver(uniphier_system_bus_driver);
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index dcbbb4ea3cc1..89527bae4602 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -381,7 +381,7 @@ static void agp_ali_remove(struct pci_dev *pdev)
agp_put_bridge(bridge);
}
-static struct pci_device_id agp_ali_pci_table[] = {
+static const struct pci_device_id agp_ali_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 5fbd333e4c6d..b450544dcaf0 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -21,7 +21,7 @@
#define AMD_TLBFLUSH 0x0c /* In mmio region (32-bit register) */
#define AMD_CACHEENTRY 0x10 /* In mmio region (32-bit register) */
-static struct pci_device_id agp_amdk7_pci_table[];
+static const struct pci_device_id agp_amdk7_pci_table[];
struct amd_page_map {
unsigned long *real;
@@ -508,7 +508,7 @@ static int agp_amdk7_resume(struct pci_dev *pdev)
#endif /* CONFIG_PM */
/* must be the same order as name table above */
-static struct pci_device_id agp_amdk7_pci_table[] = {
+static const struct pci_device_id agp_amdk7_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index c99cd19d9147..e50c29c97ca7 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -610,7 +610,7 @@ static int agp_amd64_resume(struct pci_dev *pdev)
#endif /* CONFIG_PM */
-static struct pci_device_id agp_amd64_pci_table[] = {
+static const struct pci_device_id agp_amd64_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index 0b5ec7af2414..88b4cbee4dac 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -540,7 +540,7 @@ static void agp_ati_remove(struct pci_dev *pdev)
agp_put_bridge(bridge);
}
-static struct pci_device_id agp_ati_pci_table[] = {
+static const struct pci_device_id agp_ati_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index 533cb6d229b8..7f88490b5479 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -427,7 +427,7 @@ static int agp_efficeon_resume(struct pci_dev *pdev)
}
#endif
-static struct pci_device_id agp_efficeon_pci_table[] = {
+static const struct pci_device_id agp_efficeon_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 0a21daed5b62..9e4f27a6cb5a 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -828,7 +828,7 @@ static int agp_intel_resume(struct pci_dev *pdev)
}
#endif
-static struct pci_device_id agp_intel_pci_table[] = {
+static const struct pci_device_id agp_intel_pci_table[] = {
#define ID(x) \
{ \
.class = (PCI_CLASS_BRIDGE_HOST << 8), \
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index 6c8d39cb566e..828b34445203 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -420,7 +420,7 @@ static int agp_nvidia_resume(struct pci_dev *pdev)
#endif
-static struct pci_device_id agp_nvidia_pci_table[] = {
+static const struct pci_device_id agp_nvidia_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
index 2c74038da459..14909fc5d767 100644
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -237,7 +237,7 @@ static int agp_sis_resume(struct pci_dev *pdev)
#endif /* CONFIG_PM */
-static struct pci_device_id agp_sis_pci_table[] = {
+static const struct pci_device_id agp_sis_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index fdced547ad59..c381c8e396fc 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -679,7 +679,7 @@ static void agp_uninorth_remove(struct pci_dev *pdev)
agp_put_bridge(bridge);
}
-static struct pci_device_id agp_uninorth_pci_table[] = {
+static const struct pci_device_id agp_uninorth_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
diff --git a/drivers/char/random.c b/drivers/char/random.c
index afa3ce7d3e72..8ad92707e45f 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1492,7 +1492,7 @@ static void _warn_unseeded_randomness(const char *func_name, void *caller,
#ifndef CONFIG_WARN_ALL_UNSEEDED_RANDOM
print_once = true;
#endif
- pr_notice("random: %s called from %pF with crng_init=%d\n",
+ pr_notice("random: %s called from %pS with crng_init=%d\n",
func_name, caller, crng_init);
}
diff --git a/drivers/clk/clk-gemini.c b/drivers/clk/clk-gemini.c
index c391a49aaaff..b4cf2f699a21 100644
--- a/drivers/clk/clk-gemini.c
+++ b/drivers/clk/clk-gemini.c
@@ -237,6 +237,18 @@ static int gemini_reset(struct reset_controller_dev *rcdev,
BIT(GEMINI_RESET_CPU1) | BIT(id));
}
+static int gemini_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ return 0;
+}
+
+static int gemini_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ return 0;
+}
+
static int gemini_reset_status(struct reset_controller_dev *rcdev,
unsigned long id)
{
@@ -253,6 +265,8 @@ static int gemini_reset_status(struct reset_controller_dev *rcdev,
static const struct reset_control_ops gemini_reset_ops = {
.reset = gemini_reset,
+ .assert = gemini_reset_assert,
+ .deassert = gemini_reset_deassert,
.status = gemini_reset_status,
};
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
index 43b0f2f08df2..9cdf9d5050ac 100644
--- a/drivers/clk/keystone/sci-clk.c
+++ b/drivers/clk/keystone/sci-clk.c
@@ -22,6 +22,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/soc/ti/ti_sci_protocol.h>
+#include <linux/bsearch.h>
#define SCI_CLK_SSC_ENABLE BIT(0)
#define SCI_CLK_ALLOW_FREQ_CHANGE BIT(1)
@@ -44,6 +45,7 @@ struct sci_clk_data {
* @dev: Device pointer for the clock provider
* @clk_data: Clock data
* @clocks: Clocks array for this device
+ * @num_clocks: Total number of clocks for this provider
*/
struct sci_clk_provider {
const struct ti_sci_handle *sci;
@@ -51,6 +53,7 @@ struct sci_clk_provider {
struct device *dev;
const struct sci_clk_data *clk_data;
struct clk_hw **clocks;
+ int num_clocks;
};
/**
@@ -58,7 +61,6 @@ struct sci_clk_provider {
* @hw: Hardware clock cookie for common clock framework
* @dev_id: Device index
* @clk_id: Clock index
- * @node: Clocks list link
* @provider: Master clock provider
* @flags: Flags for the clock
*/
@@ -66,7 +68,6 @@ struct sci_clk {
struct clk_hw hw;
u16 dev_id;
u8 clk_id;
- struct list_head node;
struct sci_clk_provider *provider;
u8 flags;
};
@@ -367,6 +368,19 @@ err:
return &sci_clk->hw;
}
+static int _cmp_sci_clk(const void *a, const void *b)
+{
+ const struct sci_clk *ca = a;
+ const struct sci_clk *cb = *(struct sci_clk **)b;
+
+ if (ca->dev_id == cb->dev_id && ca->clk_id == cb->clk_id)
+ return 0;
+ if (ca->dev_id > cb->dev_id ||
+ (ca->dev_id == cb->dev_id && ca->clk_id > cb->clk_id))
+ return 1;
+ return -1;
+}
+
/**
* sci_clk_get - Xlate function for getting clock handles
* @clkspec: device tree clock specifier
@@ -380,29 +394,22 @@ err:
static struct clk_hw *sci_clk_get(struct of_phandle_args *clkspec, void *data)
{
struct sci_clk_provider *provider = data;
- u16 dev_id;
- u8 clk_id;
- const struct sci_clk_data *clks = provider->clk_data;
- struct clk_hw **clocks = provider->clocks;
+ struct sci_clk **clk;
+ struct sci_clk key;
if (clkspec->args_count != 2)
return ERR_PTR(-EINVAL);
- dev_id = clkspec->args[0];
- clk_id = clkspec->args[1];
+ key.dev_id = clkspec->args[0];
+ key.clk_id = clkspec->args[1];
- while (clks->num_clks) {
- if (clks->dev == dev_id) {
- if (clk_id >= clks->num_clks)
- return ERR_PTR(-EINVAL);
-
- return clocks[clk_id];
- }
+ clk = bsearch(&key, provider->clocks, provider->num_clocks,
+ sizeof(clk), _cmp_sci_clk);
- clks++;
- }
+ if (!clk)
+ return ERR_PTR(-ENODEV);
- return ERR_PTR(-ENODEV);
+ return &(*clk)->hw;
}
static int ti_sci_init_clocks(struct sci_clk_provider *p)
@@ -410,18 +417,29 @@ static int ti_sci_init_clocks(struct sci_clk_provider *p)
const struct sci_clk_data *data = p->clk_data;
struct clk_hw *hw;
int i;
+ int num_clks = 0;
while (data->num_clks) {
- p->clocks = devm_kcalloc(p->dev, data->num_clks,
- sizeof(struct sci_clk),
- GFP_KERNEL);
- if (!p->clocks)
- return -ENOMEM;
+ num_clks += data->num_clks;
+ data++;
+ }
+ p->num_clocks = num_clks;
+
+ p->clocks = devm_kcalloc(p->dev, num_clks, sizeof(struct sci_clk),
+ GFP_KERNEL);
+ if (!p->clocks)
+ return -ENOMEM;
+
+ num_clks = 0;
+
+ data = p->clk_data;
+
+ while (data->num_clks) {
for (i = 0; i < data->num_clks; i++) {
hw = _sci_clk_build(p, data->dev, i);
if (!IS_ERR(hw)) {
- p->clocks[i] = hw;
+ p->clocks[num_clks++] = hw;
continue;
}
diff --git a/drivers/clk/meson/clk-mpll.c b/drivers/clk/meson/clk-mpll.c
index 39eab69fe51a..44a5a535ca63 100644
--- a/drivers/clk/meson/clk-mpll.c
+++ b/drivers/clk/meson/clk-mpll.c
@@ -161,6 +161,13 @@ static int mpll_set_rate(struct clk_hw *hw,
reg = PARM_SET(p->width, p->shift, reg, 1);
writel(reg, mpll->base + p->reg_off);
+ p = &mpll->ssen;
+ if (p->width != 0) {
+ reg = readl(mpll->base + p->reg_off);
+ reg = PARM_SET(p->width, p->shift, reg, 1);
+ writel(reg, mpll->base + p->reg_off);
+ }
+
p = &mpll->n2;
reg = readl(mpll->base + p->reg_off);
reg = PARM_SET(p->width, p->shift, reg, n2);
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
index d6feafe8bd6c..1629da9b4141 100644
--- a/drivers/clk/meson/clkc.h
+++ b/drivers/clk/meson/clkc.h
@@ -118,6 +118,7 @@ struct meson_clk_mpll {
struct parm sdm_en;
struct parm n2;
struct parm en;
+ struct parm ssen;
spinlock_t *lock;
};
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index a897ea45327c..a7ea5f3da89d 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -528,6 +528,11 @@ static struct meson_clk_mpll gxbb_mpll0 = {
.shift = 14,
.width = 1,
},
+ .ssen = {
+ .reg_off = HHI_MPLL_CNTL,
+ .shift = 25,
+ .width = 1,
+ },
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll0",
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
index bb3f1de876b1..6ec512ad2598 100644
--- a/drivers/clk/meson/meson8b.c
+++ b/drivers/clk/meson/meson8b.c
@@ -267,6 +267,11 @@ static struct meson_clk_mpll meson8b_mpll0 = {
.shift = 14,
.width = 1,
},
+ .ssen = {
+ .reg_off = HHI_MPLL_CNTL,
+ .shift = 25,
+ .width = 1,
+ },
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpll0",
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 0748a0b333c5..9a6476aa7d81 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -1283,16 +1283,16 @@ static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] __ini
static const struct samsung_pll_rate_table exynos5420_epll_24mhz_tbl[] = {
PLL_36XX_RATE(600000000U, 100, 2, 1, 0),
PLL_36XX_RATE(400000000U, 200, 3, 2, 0),
- PLL_36XX_RATE(393216000U, 197, 3, 2, 25690),
- PLL_36XX_RATE(361267200U, 301, 5, 2, 3671),
+ PLL_36XX_RATE(393216003U, 197, 3, 2, -25690),
+ PLL_36XX_RATE(361267218U, 301, 5, 2, 3671),
PLL_36XX_RATE(200000000U, 200, 3, 3, 0),
- PLL_36XX_RATE(196608000U, 197, 3, 3, -25690),
- PLL_36XX_RATE(180633600U, 301, 5, 3, 3671),
- PLL_36XX_RATE(131072000U, 131, 3, 3, 4719),
+ PLL_36XX_RATE(196608001U, 197, 3, 3, -25690),
+ PLL_36XX_RATE(180633609U, 301, 5, 3, 3671),
+ PLL_36XX_RATE(131072006U, 131, 3, 3, 4719),
PLL_36XX_RATE(100000000U, 200, 3, 4, 0),
- PLL_36XX_RATE(65536000U, 131, 3, 4, 4719),
- PLL_36XX_RATE(49152000U, 197, 3, 5, 25690),
- PLL_36XX_RATE(32768000U, 131, 3, 5, 4719),
+ PLL_36XX_RATE( 65536003U, 131, 3, 4, 4719),
+ PLL_36XX_RATE( 49152000U, 197, 3, 5, -25690),
+ PLL_36XX_RATE( 32768001U, 131, 3, 5, 4719),
};
static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = {
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.c b/drivers/clk/sunxi-ng/ccu-sun5i.c
index 5372bf8be5e6..31d7ffda9aab 100644
--- a/drivers/clk/sunxi-ng/ccu-sun5i.c
+++ b/drivers/clk/sunxi-ng/ccu-sun5i.c
@@ -184,7 +184,7 @@ static struct ccu_mux cpu_clk = {
.hw.init = CLK_HW_INIT_PARENTS("cpu",
cpu_parents,
&ccu_mux_ops,
- CLK_IS_CRITICAL),
+ CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
}
};
diff --git a/drivers/clk/x86/clk-pmc-atom.c b/drivers/clk/x86/clk-pmc-atom.c
index f99abc1106f0..08ef69945ffb 100644
--- a/drivers/clk/x86/clk-pmc-atom.c
+++ b/drivers/clk/x86/clk-pmc-atom.c
@@ -186,6 +186,13 @@ static struct clk_plt *plt_clk_register(struct platform_device *pdev, int id,
pclk->reg = base + PMC_CLK_CTL_OFFSET + id * PMC_CLK_CTL_SIZE;
spin_lock_init(&pclk->lock);
+ /*
+ * If the clock was already enabled by the firmware mark it as critical
+ * to avoid it being gated by the clock framework if no driver owns it.
+ */
+ if (plt_clk_is_enabled(&pclk->hw))
+ init.flags |= CLK_IS_CRITICAL;
+
ret = devm_clk_hw_register(&pdev->dev, &pclk->hw);
if (ret) {
pclk = ERR_PTR(ret);
diff --git a/drivers/clocksource/timer-of.c b/drivers/clocksource/timer-of.c
index f6e7491c873c..d509b500a7b5 100644
--- a/drivers/clocksource/timer-of.c
+++ b/drivers/clocksource/timer-of.c
@@ -41,8 +41,16 @@ static __init int timer_irq_init(struct device_node *np,
struct timer_of *to = container_of(of_irq, struct timer_of, of_irq);
struct clock_event_device *clkevt = &to->clkevt;
- of_irq->irq = of_irq->name ? of_irq_get_byname(np, of_irq->name):
- irq_of_parse_and_map(np, of_irq->index);
+ if (of_irq->name) {
+ of_irq->irq = ret = of_irq_get_byname(np, of_irq->name);
+ if (ret < 0) {
+ pr_err("Failed to get interrupt %s for %s\n",
+ of_irq->name, np->full_name);
+ return ret;
+ }
+ } else {
+ of_irq->irq = irq_of_parse_and_map(np, of_irq->index);
+ }
if (!of_irq->irq) {
pr_err("Failed to map interrupt for %s\n", np->full_name);
return -EINVAL;
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index b7fb8b7c980d..0566455f233e 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -225,6 +225,9 @@ struct global_params {
* @vid: Stores VID limits for this CPU
* @pid: Stores PID parameters for this CPU
* @last_sample_time: Last Sample time
+ * @aperf_mperf_shift: Number of clock cycles after aperf, merf is incremented
+ * This shift is a multiplier to mperf delta to
+ * calculate CPU busy.
* @prev_aperf: Last APERF value read from APERF MSR
* @prev_mperf: Last MPERF value read from MPERF MSR
* @prev_tsc: Last timestamp counter (TSC) value
@@ -259,6 +262,7 @@ struct cpudata {
u64 last_update;
u64 last_sample_time;
+ u64 aperf_mperf_shift;
u64 prev_aperf;
u64 prev_mperf;
u64 prev_tsc;
@@ -321,6 +325,7 @@ struct pstate_funcs {
int (*get_min)(void);
int (*get_turbo)(void);
int (*get_scaling)(void);
+ int (*get_aperf_mperf_shift)(void);
u64 (*get_val)(struct cpudata*, int pstate);
void (*get_vid)(struct cpudata *);
void (*update_util)(struct update_util_data *data, u64 time,
@@ -1486,6 +1491,11 @@ static u64 core_get_val(struct cpudata *cpudata, int pstate)
return val;
}
+static int knl_get_aperf_mperf_shift(void)
+{
+ return 10;
+}
+
static int knl_get_turbo_pstate(void)
{
u64 value;
@@ -1543,6 +1553,9 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
cpu->pstate.max_freq = cpu->pstate.max_pstate * cpu->pstate.scaling;
cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * cpu->pstate.scaling;
+ if (pstate_funcs.get_aperf_mperf_shift)
+ cpu->aperf_mperf_shift = pstate_funcs.get_aperf_mperf_shift();
+
if (pstate_funcs.get_vid)
pstate_funcs.get_vid(cpu);
@@ -1616,7 +1629,8 @@ static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu)
int32_t busy_frac, boost;
int target, avg_pstate;
- busy_frac = div_fp(sample->mperf, sample->tsc);
+ busy_frac = div_fp(sample->mperf << cpu->aperf_mperf_shift,
+ sample->tsc);
boost = cpu->iowait_boost;
cpu->iowait_boost >>= 1;
@@ -1675,7 +1689,8 @@ static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)
sample_ratio = div_fp(pid_params.sample_rate_ns, duration_ns);
perf_scaled = mul_fp(perf_scaled, sample_ratio);
} else {
- sample_ratio = div_fp(100 * cpu->sample.mperf, cpu->sample.tsc);
+ sample_ratio = div_fp(100 * (cpu->sample.mperf << cpu->aperf_mperf_shift),
+ cpu->sample.tsc);
if (sample_ratio < int_tofp(1))
perf_scaled = 0;
}
@@ -1807,6 +1822,7 @@ static const struct pstate_funcs knl_funcs = {
.get_max_physical = core_get_max_pstate_physical,
.get_min = core_get_min_pstate,
.get_turbo = knl_get_turbo_pstate,
+ .get_aperf_mperf_shift = knl_get_aperf_mperf_shift,
.get_scaling = core_get_scaling,
.get_val = core_get_val,
.update_util = intel_pstate_update_util_pid,
@@ -1906,13 +1922,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
return 0;
}
-static unsigned int intel_pstate_get(unsigned int cpu_num)
-{
- struct cpudata *cpu = all_cpu_data[cpu_num];
-
- return cpu ? get_avg_frequency(cpu) : 0;
-}
-
static void intel_pstate_set_update_util_hook(unsigned int cpu_num)
{
struct cpudata *cpu = all_cpu_data[cpu_num];
@@ -2153,7 +2162,6 @@ static struct cpufreq_driver intel_pstate = {
.setpolicy = intel_pstate_set_policy,
.suspend = intel_pstate_hwp_save_state,
.resume = intel_pstate_resume,
- .get = intel_pstate_get,
.init = intel_pstate_cpu_init,
.exit = intel_pstate_cpu_exit,
.stop_cpu = intel_pstate_stop_cpu,
@@ -2403,6 +2411,7 @@ static void __init copy_cpu_funcs(struct pstate_funcs *funcs)
pstate_funcs.get_val = funcs->get_val;
pstate_funcs.get_vid = funcs->get_vid;
pstate_funcs.update_util = funcs->update_util;
+ pstate_funcs.get_aperf_mperf_shift = funcs->get_aperf_mperf_shift;
intel_pstate_use_acpi_profile();
}
diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c
index 37b0698b7193..42896a67aeae 100644
--- a/drivers/cpuidle/cpuidle-powernv.c
+++ b/drivers/cpuidle/cpuidle-powernv.c
@@ -235,6 +235,7 @@ static inline int validate_dt_prop_sizes(const char *prop1, int prop1_len,
return -1;
}
+extern u32 pnv_get_supported_cpuidle_states(void);
static int powernv_add_idle_states(void)
{
struct device_node *power_mgt;
@@ -248,6 +249,8 @@ static int powernv_add_idle_states(void)
const char *names[CPUIDLE_STATE_MAX];
u32 has_stop_states = 0;
int i, rc;
+ u32 supported_flags = pnv_get_supported_cpuidle_states();
+
/* Currently we have snooze statically defined */
@@ -362,6 +365,13 @@ static int powernv_add_idle_states(void)
for (i = 0; i < dt_idle_states; i++) {
unsigned int exit_latency, target_residency;
bool stops_timebase = false;
+
+ /*
+ * Skip the platform idle state whose flag isn't in
+ * the supported_cpuidle_states flag mask.
+ */
+ if ((flags[i] & supported_flags) != flags[i])
+ continue;
/*
* If an idle state has exit latency beyond
* POWERNV_THRESHOLD_LATENCY_NS then don't use it
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 193204dfbf3a..4b75084fabad 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -655,7 +655,7 @@ source "drivers/crypto/virtio/Kconfig"
config CRYPTO_DEV_BCM_SPU
tristate "Broadcom symmetric crypto/hash acceleration support"
depends on ARCH_BCM_IPROC
- depends on BCM_PDC_MBOX
+ depends on MAILBOX
default m
select CRYPTO_DES
select CRYPTO_MD5
diff --git a/drivers/crypto/bcm/spu2.c b/drivers/crypto/bcm/spu2.c
index ef04c9748317..bf7ac621c591 100644
--- a/drivers/crypto/bcm/spu2.c
+++ b/drivers/crypto/bcm/spu2.c
@@ -302,6 +302,7 @@ spu2_hash_xlate(enum hash_alg hash_alg, enum hash_mode hash_mode,
break;
case HASH_ALG_SHA3_512:
*spu2_type = SPU2_HASH_TYPE_SHA3_512;
+ break;
case HASH_ALG_LAST:
default:
err = -EINVAL;
diff --git a/drivers/crypto/cavium/nitrox/nitrox_main.c b/drivers/crypto/cavium/nitrox/nitrox_main.c
index ae44a464cd2d..9ccefb9b7232 100644
--- a/drivers/crypto/cavium/nitrox/nitrox_main.c
+++ b/drivers/crypto/cavium/nitrox/nitrox_main.c
@@ -18,8 +18,9 @@
#define SE_GROUP 0
#define DRIVER_VERSION "1.0"
+#define FW_DIR "cavium/"
/* SE microcode */
-#define SE_FW "cnn55xx_se.fw"
+#define SE_FW FW_DIR "cnn55xx_se.fw"
static const char nitrox_driver_name[] = "CNN55XX";
diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
index e7f87ac12685..1fabd4aee81b 100644
--- a/drivers/crypto/inside-secure/safexcel.c
+++ b/drivers/crypto/inside-secure/safexcel.c
@@ -773,7 +773,6 @@ static int safexcel_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct resource *res;
struct safexcel_crypto_priv *priv;
- u64 dma_mask;
int i, ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -802,9 +801,7 @@ static int safexcel_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
}
- if (of_property_read_u64(dev->of_node, "dma-mask", &dma_mask))
- dma_mask = DMA_BIT_MASK(64);
- ret = dma_set_mask_and_coherent(dev, dma_mask);
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
if (ret)
goto err_clk;
diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
index 8527a5899a2f..3f819399cd95 100644
--- a/drivers/crypto/inside-secure/safexcel_hash.c
+++ b/drivers/crypto/inside-secure/safexcel_hash.c
@@ -883,10 +883,7 @@ static int safexcel_hmac_sha1_setkey(struct crypto_ahash *tfm, const u8 *key,
if (ret)
return ret;
- memcpy(ctx->ipad, &istate.state, SHA1_DIGEST_SIZE);
- memcpy(ctx->opad, &ostate.state, SHA1_DIGEST_SIZE);
-
- for (i = 0; i < ARRAY_SIZE(istate.state); i++) {
+ for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++) {
if (ctx->ipad[i] != le32_to_cpu(istate.state[i]) ||
ctx->opad[i] != le32_to_cpu(ostate.state[i])) {
ctx->base.needs_inv = true;
@@ -894,6 +891,9 @@ static int safexcel_hmac_sha1_setkey(struct crypto_ahash *tfm, const u8 *key,
}
}
+ memcpy(ctx->ipad, &istate.state, SHA1_DIGEST_SIZE);
+ memcpy(ctx->opad, &ostate.state, SHA1_DIGEST_SIZE);
+
return 0;
}
diff --git a/drivers/dax/device-dax.h b/drivers/dax/device-dax.h
index fdcd9769ffde..688b051750bd 100644
--- a/drivers/dax/device-dax.h
+++ b/drivers/dax/device-dax.h
@@ -21,5 +21,5 @@ struct dax_region *alloc_dax_region(struct device *parent,
int region_id, struct resource *res, unsigned int align,
void *addr, unsigned long flags);
struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
- struct resource *res, int count);
+ int id, struct resource *res, int count);
#endif /* __DEVICE_DAX_H__ */
diff --git a/drivers/dax/device.c b/drivers/dax/device.c
index 12943d19bfc4..e9f3b3e4bbf4 100644
--- a/drivers/dax/device.c
+++ b/drivers/dax/device.c
@@ -529,7 +529,8 @@ static void dev_dax_release(struct device *dev)
struct dax_region *dax_region = dev_dax->region;
struct dax_device *dax_dev = dev_dax->dax_dev;
- ida_simple_remove(&dax_region->ida, dev_dax->id);
+ if (dev_dax->id >= 0)
+ ida_simple_remove(&dax_region->ida, dev_dax->id);
dax_region_put(dax_region);
put_dax(dax_dev);
kfree(dev_dax);
@@ -559,7 +560,7 @@ static void unregister_dev_dax(void *dev)
}
struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
- struct resource *res, int count)
+ int id, struct resource *res, int count)
{
struct device *parent = dax_region->dev;
struct dax_device *dax_dev;
@@ -567,7 +568,10 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
struct inode *inode;
struct device *dev;
struct cdev *cdev;
- int rc = 0, i;
+ int rc, i;
+
+ if (!count)
+ return ERR_PTR(-EINVAL);
dev_dax = kzalloc(sizeof(*dev_dax) + sizeof(*res) * count, GFP_KERNEL);
if (!dev_dax)
@@ -587,10 +591,16 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
if (i < count)
goto err_id;
- dev_dax->id = ida_simple_get(&dax_region->ida, 0, 0, GFP_KERNEL);
- if (dev_dax->id < 0) {
- rc = dev_dax->id;
- goto err_id;
+ if (id < 0) {
+ id = ida_simple_get(&dax_region->ida, 0, 0, GFP_KERNEL);
+ dev_dax->id = id;
+ if (id < 0) {
+ rc = id;
+ goto err_id;
+ }
+ } else {
+ /* region provider owns @id lifetime */
+ dev_dax->id = -1;
}
/*
@@ -598,8 +608,10 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
* device outside of mmap of the resulting character device.
*/
dax_dev = alloc_dax(dev_dax, NULL, NULL);
- if (!dax_dev)
+ if (!dax_dev) {
+ rc = -ENOMEM;
goto err_dax;
+ }
/* from here on we're committed to teardown via dax_dev_release() */
dev = &dev_dax->dev;
@@ -620,7 +632,7 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
dev->parent = parent;
dev->groups = dax_attribute_groups;
dev->release = dev_dax_release;
- dev_set_name(dev, "dax%d.%d", dax_region->id, dev_dax->id);
+ dev_set_name(dev, "dax%d.%d", dax_region->id, id);
rc = cdev_device_add(cdev, dev);
if (rc) {
@@ -636,7 +648,8 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,
return dev_dax;
err_dax:
- ida_simple_remove(&dax_region->ida, dev_dax->id);
+ if (dev_dax->id >= 0)
+ ida_simple_remove(&dax_region->ida, dev_dax->id);
err_id:
kfree(dev_dax);
diff --git a/drivers/dax/pmem.c b/drivers/dax/pmem.c
index 9f2a0b4fd801..8d8c852ba8f2 100644
--- a/drivers/dax/pmem.c
+++ b/drivers/dax/pmem.c
@@ -58,13 +58,12 @@ static void dax_pmem_percpu_kill(void *data)
static int dax_pmem_probe(struct device *dev)
{
- int rc;
void *addr;
struct resource res;
+ int rc, id, region_id;
struct nd_pfn_sb *pfn_sb;
struct dev_dax *dev_dax;
struct dax_pmem *dax_pmem;
- struct nd_region *nd_region;
struct nd_namespace_io *nsio;
struct dax_region *dax_region;
struct nd_namespace_common *ndns;
@@ -123,14 +122,17 @@ static int dax_pmem_probe(struct device *dev)
/* adjust the dax_region resource to the start of data */
res.start += le64_to_cpu(pfn_sb->dataoff);
- nd_region = to_nd_region(dev->parent);
- dax_region = alloc_dax_region(dev, nd_region->id, &res,
+ rc = sscanf(dev_name(&ndns->dev), "namespace%d.%d", &region_id, &id);
+ if (rc != 2)
+ return -EINVAL;
+
+ dax_region = alloc_dax_region(dev, region_id, &res,
le32_to_cpu(pfn_sb->align), addr, PFN_DEV|PFN_MAP);
if (!dax_region)
return -ENOMEM;
/* TODO: support for subdividing a dax region... */
- dev_dax = devm_create_dev_dax(dax_region, &res, 1);
+ dev_dax = devm_create_dev_dax(dax_region, id, &res, 1);
/* child dev_dax instances now own the lifetime of the dax_region */
dax_region_put(dax_region);
diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index ce9e563e6e1d..938eb4868f7f 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -278,6 +278,12 @@ void dax_write_cache(struct dax_device *dax_dev, bool wc)
}
EXPORT_SYMBOL_GPL(dax_write_cache);
+bool dax_write_cache_enabled(struct dax_device *dax_dev)
+{
+ return test_bit(DAXDEV_WRITE_CACHE, &dax_dev->flags);
+}
+EXPORT_SYMBOL_GPL(dax_write_cache_enabled);
+
bool dax_alive(struct dax_device *dax_dev)
{
lockdep_assert_held(&dax_srcu);
diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index 57da14c15987..9a302799040e 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -48,7 +48,7 @@ static atomic64_t dma_fence_context_counter = ATOMIC64_INIT(0);
*/
u64 dma_fence_context_alloc(unsigned num)
{
- BUG_ON(!num);
+ WARN_ON(!num);
return atomic64_add_return(num, &dma_fence_context_counter) - num;
}
EXPORT_SYMBOL(dma_fence_context_alloc);
@@ -75,11 +75,6 @@ int dma_fence_signal_locked(struct dma_fence *fence)
if (WARN_ON(!fence))
return -EINVAL;
- if (!ktime_to_ns(fence->timestamp)) {
- fence->timestamp = ktime_get();
- smp_mb__before_atomic();
- }
-
if (test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
ret = -EINVAL;
@@ -87,8 +82,11 @@ int dma_fence_signal_locked(struct dma_fence *fence)
* we might have raced with the unlocked dma_fence_signal,
* still run through all callbacks
*/
- } else
+ } else {
+ fence->timestamp = ktime_get();
+ set_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags);
trace_dma_fence_signaled(fence);
+ }
list_for_each_entry_safe(cur, tmp, &fence->cb_list, node) {
list_del_init(&cur->node);
@@ -115,14 +113,11 @@ int dma_fence_signal(struct dma_fence *fence)
if (!fence)
return -EINVAL;
- if (!ktime_to_ns(fence->timestamp)) {
- fence->timestamp = ktime_get();
- smp_mb__before_atomic();
- }
-
if (test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
return -EINVAL;
+ fence->timestamp = ktime_get();
+ set_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags);
trace_dma_fence_signaled(fence);
if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &fence->flags)) {
@@ -177,7 +172,7 @@ void dma_fence_release(struct kref *kref)
trace_dma_fence_destroy(fence);
- BUG_ON(!list_empty(&fence->cb_list));
+ WARN_ON(!list_empty(&fence->cb_list));
if (fence->ops->release)
fence->ops->release(fence);
diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index 393817e849ed..dec3a815455d 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -195,8 +195,7 @@ done:
if (old)
kfree_rcu(old, rcu);
- if (old_fence)
- dma_fence_put(old_fence);
+ dma_fence_put(old_fence);
}
/**
@@ -258,12 +257,71 @@ void reservation_object_add_excl_fence(struct reservation_object *obj,
dma_fence_put(rcu_dereference_protected(old->shared[i],
reservation_object_held(obj)));
- if (old_fence)
- dma_fence_put(old_fence);
+ dma_fence_put(old_fence);
}
EXPORT_SYMBOL(reservation_object_add_excl_fence);
/**
+* reservation_object_copy_fences - Copy all fences from src to dst.
+* @dst: the destination reservation object
+* @src: the source reservation object
+*
+* Copy all fences from src to dst. Both src->lock as well as dst-lock must be
+* held.
+*/
+int reservation_object_copy_fences(struct reservation_object *dst,
+ struct reservation_object *src)
+{
+ struct reservation_object_list *src_list, *dst_list;
+ struct dma_fence *old, *new;
+ size_t size;
+ unsigned i;
+
+ src_list = reservation_object_get_list(src);
+
+ if (src_list) {
+ size = offsetof(typeof(*src_list),
+ shared[src_list->shared_count]);
+ dst_list = kmalloc(size, GFP_KERNEL);
+ if (!dst_list)
+ return -ENOMEM;
+
+ dst_list->shared_count = src_list->shared_count;
+ dst_list->shared_max = src_list->shared_count;
+ for (i = 0; i < src_list->shared_count; ++i)
+ dst_list->shared[i] =
+ dma_fence_get(src_list->shared[i]);
+ } else {
+ dst_list = NULL;
+ }
+
+ kfree(dst->staged);
+ dst->staged = NULL;
+
+ src_list = reservation_object_get_list(dst);
+
+ old = reservation_object_get_excl(dst);
+ new = reservation_object_get_excl(src);
+
+ dma_fence_get(new);
+
+ preempt_disable();
+ write_seqcount_begin(&dst->seq);
+ /* write_seqcount_begin provides the necessary memory barrier */
+ RCU_INIT_POINTER(dst->fence_excl, new);
+ RCU_INIT_POINTER(dst->fence, dst_list);
+ write_seqcount_end(&dst->seq);
+ preempt_enable();
+
+ if (src_list)
+ kfree_rcu(src_list, rcu);
+ dma_fence_put(old);
+
+ return 0;
+}
+EXPORT_SYMBOL(reservation_object_copy_fences);
+
+/**
* reservation_object_get_fences_rcu - Get an object's shared and exclusive
* fences without update side lock held
* @obj: the reservation object
@@ -373,12 +431,25 @@ long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
long ret = timeout ? timeout : 1;
retry:
- fence = NULL;
shared_count = 0;
seq = read_seqcount_begin(&obj->seq);
rcu_read_lock();
- if (wait_all) {
+ fence = rcu_dereference(obj->fence_excl);
+ if (fence && !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
+ if (!dma_fence_get_rcu(fence))
+ goto unlock_retry;
+
+ if (dma_fence_is_signaled(fence)) {
+ dma_fence_put(fence);
+ fence = NULL;
+ }
+
+ } else {
+ fence = NULL;
+ }
+
+ if (!fence && wait_all) {
struct reservation_object_list *fobj =
rcu_dereference(obj->fence);
@@ -405,22 +476,6 @@ retry:
}
}
- if (!shared_count) {
- struct dma_fence *fence_excl = rcu_dereference(obj->fence_excl);
-
- if (fence_excl &&
- !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
- &fence_excl->flags)) {
- if (!dma_fence_get_rcu(fence_excl))
- goto unlock_retry;
-
- if (dma_fence_is_signaled(fence_excl))
- dma_fence_put(fence_excl);
- else
- fence = fence_excl;
- }
- }
-
rcu_read_unlock();
if (fence) {
if (read_seqcount_retry(&obj->seq, seq)) {
diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index 69c5ff36e2f9..38cc7389a6c1 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -96,9 +96,9 @@ static struct sync_timeline *sync_timeline_create(const char *name)
obj->context = dma_fence_context_alloc(1);
strlcpy(obj->name, name, sizeof(obj->name));
- INIT_LIST_HEAD(&obj->child_list_head);
- INIT_LIST_HEAD(&obj->active_list_head);
- spin_lock_init(&obj->child_list_lock);
+ obj->pt_tree = RB_ROOT;
+ INIT_LIST_HEAD(&obj->pt_list);
+ spin_lock_init(&obj->lock);
sync_timeline_debug_add(obj);
@@ -125,68 +125,6 @@ static void sync_timeline_put(struct sync_timeline *obj)
kref_put(&obj->kref, sync_timeline_free);
}
-/**
- * sync_timeline_signal() - signal a status change on a sync_timeline
- * @obj: sync_timeline to signal
- * @inc: num to increment on timeline->value
- *
- * A sync implementation should call this any time one of it's fences
- * has signaled or has an error condition.
- */
-static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
-{
- unsigned long flags;
- struct sync_pt *pt, *next;
-
- trace_sync_timeline(obj);
-
- spin_lock_irqsave(&obj->child_list_lock, flags);
-
- obj->value += inc;
-
- list_for_each_entry_safe(pt, next, &obj->active_list_head,
- active_list) {
- if (dma_fence_is_signaled_locked(&pt->base))
- list_del_init(&pt->active_list);
- }
-
- spin_unlock_irqrestore(&obj->child_list_lock, flags);
-}
-
-/**
- * sync_pt_create() - creates a sync pt
- * @parent: fence's parent sync_timeline
- * @size: size to allocate for this pt
- * @inc: value of the fence
- *
- * Creates a new sync_pt as a child of @parent. @size bytes will be
- * allocated allowing for implementation specific data to be kept after
- * the generic sync_timeline struct. Returns the sync_pt object or
- * NULL in case of error.
- */
-static struct sync_pt *sync_pt_create(struct sync_timeline *obj, int size,
- unsigned int value)
-{
- unsigned long flags;
- struct sync_pt *pt;
-
- if (size < sizeof(*pt))
- return NULL;
-
- pt = kzalloc(size, GFP_KERNEL);
- if (!pt)
- return NULL;
-
- spin_lock_irqsave(&obj->child_list_lock, flags);
- sync_timeline_get(obj);
- dma_fence_init(&pt->base, &timeline_fence_ops, &obj->child_list_lock,
- obj->context, value);
- list_add_tail(&pt->child_list, &obj->child_list_head);
- INIT_LIST_HEAD(&pt->active_list);
- spin_unlock_irqrestore(&obj->child_list_lock, flags);
- return pt;
-}
-
static const char *timeline_fence_get_driver_name(struct dma_fence *fence)
{
return "sw_sync";
@@ -203,13 +141,17 @@ static void timeline_fence_release(struct dma_fence *fence)
{
struct sync_pt *pt = dma_fence_to_sync_pt(fence);
struct sync_timeline *parent = dma_fence_parent(fence);
- unsigned long flags;
- spin_lock_irqsave(fence->lock, flags);
- list_del(&pt->child_list);
- if (!list_empty(&pt->active_list))
- list_del(&pt->active_list);
- spin_unlock_irqrestore(fence->lock, flags);
+ if (!list_empty(&pt->link)) {
+ unsigned long flags;
+
+ spin_lock_irqsave(fence->lock, flags);
+ if (!list_empty(&pt->link)) {
+ list_del(&pt->link);
+ rb_erase(&pt->node, &parent->pt_tree);
+ }
+ spin_unlock_irqrestore(fence->lock, flags);
+ }
sync_timeline_put(parent);
dma_fence_free(fence);
@@ -219,18 +161,11 @@ static bool timeline_fence_signaled(struct dma_fence *fence)
{
struct sync_timeline *parent = dma_fence_parent(fence);
- return (fence->seqno > parent->value) ? false : true;
+ return !__dma_fence_is_later(fence->seqno, parent->value);
}
static bool timeline_fence_enable_signaling(struct dma_fence *fence)
{
- struct sync_pt *pt = dma_fence_to_sync_pt(fence);
- struct sync_timeline *parent = dma_fence_parent(fence);
-
- if (timeline_fence_signaled(fence))
- return false;
-
- list_add_tail(&pt->active_list, &parent->active_list_head);
return true;
}
@@ -259,6 +194,107 @@ static const struct dma_fence_ops timeline_fence_ops = {
.timeline_value_str = timeline_fence_timeline_value_str,
};
+/**
+ * sync_timeline_signal() - signal a status change on a sync_timeline
+ * @obj: sync_timeline to signal
+ * @inc: num to increment on timeline->value
+ *
+ * A sync implementation should call this any time one of it's fences
+ * has signaled or has an error condition.
+ */
+static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
+{
+ struct sync_pt *pt, *next;
+
+ trace_sync_timeline(obj);
+
+ spin_lock_irq(&obj->lock);
+
+ obj->value += inc;
+
+ list_for_each_entry_safe(pt, next, &obj->pt_list, link) {
+ if (!timeline_fence_signaled(&pt->base))
+ break;
+
+ list_del_init(&pt->link);
+ rb_erase(&pt->node, &obj->pt_tree);
+
+ /*
+ * A signal callback may release the last reference to this
+ * fence, causing it to be freed. That operation has to be
+ * last to avoid a use after free inside this loop, and must
+ * be after we remove the fence from the timeline in order to
+ * prevent deadlocking on timeline->lock inside
+ * timeline_fence_release().
+ */
+ dma_fence_signal_locked(&pt->base);
+ }
+
+ spin_unlock_irq(&obj->lock);
+}
+
+/**
+ * sync_pt_create() - creates a sync pt
+ * @parent: fence's parent sync_timeline
+ * @inc: value of the fence
+ *
+ * Creates a new sync_pt as a child of @parent. @size bytes will be
+ * allocated allowing for implementation specific data to be kept after
+ * the generic sync_timeline struct. Returns the sync_pt object or
+ * NULL in case of error.
+ */
+static struct sync_pt *sync_pt_create(struct sync_timeline *obj,
+ unsigned int value)
+{
+ struct sync_pt *pt;
+
+ pt = kzalloc(sizeof(*pt), GFP_KERNEL);
+ if (!pt)
+ return NULL;
+
+ sync_timeline_get(obj);
+ dma_fence_init(&pt->base, &timeline_fence_ops, &obj->lock,
+ obj->context, value);
+ INIT_LIST_HEAD(&pt->link);
+
+ spin_lock_irq(&obj->lock);
+ if (!dma_fence_is_signaled_locked(&pt->base)) {
+ struct rb_node **p = &obj->pt_tree.rb_node;
+ struct rb_node *parent = NULL;
+
+ while (*p) {
+ struct sync_pt *other;
+ int cmp;
+
+ parent = *p;
+ other = rb_entry(parent, typeof(*pt), node);
+ cmp = value - other->base.seqno;
+ if (cmp > 0) {
+ p = &parent->rb_right;
+ } else if (cmp < 0) {
+ p = &parent->rb_left;
+ } else {
+ if (dma_fence_get_rcu(&other->base)) {
+ dma_fence_put(&pt->base);
+ pt = other;
+ goto unlock;
+ }
+ p = &parent->rb_left;
+ }
+ }
+ rb_link_node(&pt->node, parent, p);
+ rb_insert_color(&pt->node, &obj->pt_tree);
+
+ parent = rb_next(&pt->node);
+ list_add_tail(&pt->link,
+ parent ? &rb_entry(parent, typeof(*pt), node)->link : &obj->pt_list);
+ }
+unlock:
+ spin_unlock_irq(&obj->lock);
+
+ return pt;
+}
+
/*
* *WARNING*
*
@@ -309,7 +345,7 @@ static long sw_sync_ioctl_create_fence(struct sync_timeline *obj,
goto err;
}
- pt = sync_pt_create(obj, sizeof(*pt), data.value);
+ pt = sync_pt_create(obj, data.value);
if (!pt) {
err = -ENOMEM;
goto err;
@@ -345,6 +381,11 @@ static long sw_sync_ioctl_inc(struct sync_timeline *obj, unsigned long arg)
if (copy_from_user(&value, (void __user *)arg, sizeof(value)))
return -EFAULT;
+ while (value > INT_MAX) {
+ sync_timeline_signal(obj, INT_MAX);
+ value -= INT_MAX;
+ }
+
sync_timeline_signal(obj, value);
return 0;
diff --git a/drivers/dma-buf/sync_debug.c b/drivers/dma-buf/sync_debug.c
index 82a6e7f6d37f..c4c8ecb24aa9 100644
--- a/drivers/dma-buf/sync_debug.c
+++ b/drivers/dma-buf/sync_debug.c
@@ -84,7 +84,7 @@ static void sync_print_fence(struct seq_file *s,
show ? "_" : "",
sync_status_str(status));
- if (status) {
+ if (test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags)) {
struct timespec64 ts64 =
ktime_to_timespec64(fence->timestamp);
@@ -116,17 +116,15 @@ static void sync_print_fence(struct seq_file *s,
static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj)
{
struct list_head *pos;
- unsigned long flags;
seq_printf(s, "%s: %d\n", obj->name, obj->value);
- spin_lock_irqsave(&obj->child_list_lock, flags);
- list_for_each(pos, &obj->child_list_head) {
- struct sync_pt *pt =
- container_of(pos, struct sync_pt, child_list);
+ spin_lock_irq(&obj->lock);
+ list_for_each(pos, &obj->pt_list) {
+ struct sync_pt *pt = container_of(pos, struct sync_pt, link);
sync_print_fence(s, &pt->base, false);
}
- spin_unlock_irqrestore(&obj->child_list_lock, flags);
+ spin_unlock_irq(&obj->lock);
}
static void sync_print_sync_file(struct seq_file *s,
@@ -151,12 +149,11 @@ static void sync_print_sync_file(struct seq_file *s,
static int sync_debugfs_show(struct seq_file *s, void *unused)
{
- unsigned long flags;
struct list_head *pos;
seq_puts(s, "objs:\n--------------\n");
- spin_lock_irqsave(&sync_timeline_list_lock, flags);
+ spin_lock_irq(&sync_timeline_list_lock);
list_for_each(pos, &sync_timeline_list_head) {
struct sync_timeline *obj =
container_of(pos, struct sync_timeline,
@@ -165,11 +162,11 @@ static int sync_debugfs_show(struct seq_file *s, void *unused)
sync_print_obj(s, obj);
seq_putc(s, '\n');
}
- spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
+ spin_unlock_irq(&sync_timeline_list_lock);
seq_puts(s, "fences:\n--------------\n");
- spin_lock_irqsave(&sync_file_list_lock, flags);
+ spin_lock_irq(&sync_file_list_lock);
list_for_each(pos, &sync_file_list_head) {
struct sync_file *sync_file =
container_of(pos, struct sync_file, sync_file_list);
@@ -177,7 +174,7 @@ static int sync_debugfs_show(struct seq_file *s, void *unused)
sync_print_sync_file(s, sync_file);
seq_putc(s, '\n');
}
- spin_unlock_irqrestore(&sync_file_list_lock, flags);
+ spin_unlock_irq(&sync_file_list_lock);
return 0;
}
diff --git a/drivers/dma-buf/sync_debug.h b/drivers/dma-buf/sync_debug.h
index 26fe8b9907b3..d615a89f774c 100644
--- a/drivers/dma-buf/sync_debug.h
+++ b/drivers/dma-buf/sync_debug.h
@@ -14,6 +14,7 @@
#define _LINUX_SYNC_H
#include <linux/list.h>
+#include <linux/rbtree.h>
#include <linux/spinlock.h>
#include <linux/dma-fence.h>
@@ -24,42 +25,41 @@
* struct sync_timeline - sync object
* @kref: reference count on fence.
* @name: name of the sync_timeline. Useful for debugging
- * @child_list_head: list of children sync_pts for this sync_timeline
- * @child_list_lock: lock protecting @child_list_head and fence.status
- * @active_list_head: list of active (unsignaled/errored) sync_pts
+ * @lock: lock protecting @pt_list and @value
+ * @pt_tree: rbtree of active (unsignaled/errored) sync_pts
+ * @pt_list: list of active (unsignaled/errored) sync_pts
* @sync_timeline_list: membership in global sync_timeline_list
*/
struct sync_timeline {
struct kref kref;
char name[32];
- /* protected by child_list_lock */
+ /* protected by lock */
u64 context;
int value;
- struct list_head child_list_head;
- spinlock_t child_list_lock;
-
- struct list_head active_list_head;
+ struct rb_root pt_tree;
+ struct list_head pt_list;
+ spinlock_t lock;
struct list_head sync_timeline_list;
};
static inline struct sync_timeline *dma_fence_parent(struct dma_fence *fence)
{
- return container_of(fence->lock, struct sync_timeline, child_list_lock);
+ return container_of(fence->lock, struct sync_timeline, lock);
}
/**
* struct sync_pt - sync_pt object
* @base: base fence object
- * @child_list: sync timeline child's list
- * @active_list: sync timeline active child's list
+ * @link: link on the sync timeline's list
+ * @node: node in the sync timeline's tree
*/
struct sync_pt {
struct dma_fence base;
- struct list_head child_list;
- struct list_head active_list;
+ struct list_head link;
+ struct rb_node node;
};
#ifdef CONFIG_SW_SYNC
diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c
index 545e2c5c4815..66fb40d0ebdb 100644
--- a/drivers/dma-buf/sync_file.c
+++ b/drivers/dma-buf/sync_file.c
@@ -304,7 +304,7 @@ static int sync_file_release(struct inode *inode, struct file *file)
{
struct sync_file *sync_file = file->private_data;
- if (test_bit(POLL_ENABLED, &sync_file->fence->flags))
+ if (test_bit(POLL_ENABLED, &sync_file->flags))
dma_fence_remove_callback(sync_file->fence, &sync_file->cb);
dma_fence_put(sync_file->fence);
kfree(sync_file);
@@ -318,7 +318,8 @@ static unsigned int sync_file_poll(struct file *file, poll_table *wait)
poll_wait(file, &sync_file->wq, wait);
- if (!test_and_set_bit(POLL_ENABLED, &sync_file->fence->flags)) {
+ if (list_empty(&sync_file->cb.node) &&
+ !test_and_set_bit(POLL_ENABLED, &sync_file->flags)) {
if (dma_fence_add_callback(sync_file->fence, &sync_file->cb,
fence_check_cb_func) < 0)
wake_up_all(&sync_file->wq);
@@ -391,7 +392,13 @@ static void sync_fill_fence_info(struct dma_fence *fence,
sizeof(info->driver_name));
info->status = dma_fence_get_status(fence);
- info->timestamp_ns = ktime_to_ns(fence->timestamp);
+ while (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags) &&
+ !test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags))
+ cpu_relax();
+ info->timestamp_ns =
+ test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags) ?
+ ktime_to_ns(fence->timestamp) :
+ ktime_set(0, 0);
}
static long sync_file_ioctl_fence_info(struct sync_file *sync_file,
diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
index a485864cb512..06432d84cbf8 100644
--- a/drivers/fsi/fsi-core.c
+++ b/drivers/fsi/fsi-core.c
@@ -532,7 +532,7 @@ static inline uint32_t fsi_smode_sid(int x)
return (x & FSI_SMODE_SID_MASK) << FSI_SMODE_SID_SHIFT;
}
-static const uint32_t fsi_slave_smode(int id)
+static uint32_t fsi_slave_smode(int id)
{
return FSI_SMODE_WSC | FSI_SMODE_ECRC
| fsi_smode_sid(id)
@@ -883,17 +883,16 @@ struct bus_type fsi_bus_type = {
};
EXPORT_SYMBOL_GPL(fsi_bus_type);
-static int fsi_init(void)
+static int __init fsi_init(void)
{
return bus_register(&fsi_bus_type);
}
+postcore_initcall(fsi_init);
static void fsi_exit(void)
{
bus_unregister(&fsi_bus_type);
}
-
-module_init(fsi_init);
module_exit(fsi_exit);
module_param(discard_errors, int, 0664);
MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index f235eae04c16..461d6fc3688b 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -504,6 +504,7 @@ config GPIO_XGENE_SB
depends on ARCH_XGENE && OF_GPIO
select GPIO_GENERIC
select GPIOLIB_IRQCHIP
+ select IRQ_DOMAIN_HIERARCHY
help
This driver supports the GPIO block within the APM X-Gene
Standby Domain. Say yes here to enable the GPIO functionality.
diff --git a/drivers/gpio/gpio-exar.c b/drivers/gpio/gpio-exar.c
index fb8d304cfa17..0ecd2369c2ca 100644
--- a/drivers/gpio/gpio-exar.c
+++ b/drivers/gpio/gpio-exar.c
@@ -132,7 +132,7 @@ static int gpio_exar_probe(struct platform_device *pdev)
if (!p)
return -ENOMEM;
- ret = device_property_read_u32(&pdev->dev, "linux,first-pin",
+ ret = device_property_read_u32(&pdev->dev, "exar,first-pin",
&first_pin);
if (ret)
return ret;
diff --git a/drivers/gpio/gpio-lp87565.c b/drivers/gpio/gpio-lp87565.c
index 6313c50bb91b..a121c8f10610 100644
--- a/drivers/gpio/gpio-lp87565.c
+++ b/drivers/gpio/gpio-lp87565.c
@@ -26,6 +26,27 @@ struct lp87565_gpio {
struct regmap *map;
};
+static int lp87565_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+ struct lp87565_gpio *gpio = gpiochip_get_data(chip);
+ int ret, val;
+
+ ret = regmap_read(gpio->map, LP87565_REG_GPIO_IN, &val);
+ if (ret < 0)
+ return ret;
+
+ return !!(val & BIT(offset));
+}
+
+static void lp87565_gpio_set(struct gpio_chip *chip, unsigned int offset,
+ int value)
+{
+ struct lp87565_gpio *gpio = gpiochip_get_data(chip);
+
+ regmap_update_bits(gpio->map, LP87565_REG_GPIO_OUT,
+ BIT(offset), value ? BIT(offset) : 0);
+}
+
static int lp87565_gpio_get_direction(struct gpio_chip *chip,
unsigned int offset)
{
@@ -54,30 +75,11 @@ static int lp87565_gpio_direction_output(struct gpio_chip *chip,
{
struct lp87565_gpio *gpio = gpiochip_get_data(chip);
+ lp87565_gpio_set(chip, offset, value);
+
return regmap_update_bits(gpio->map,
LP87565_REG_GPIO_CONFIG,
- BIT(offset), !value ? BIT(offset) : 0);
-}
-
-static int lp87565_gpio_get(struct gpio_chip *chip, unsigned int offset)
-{
- struct lp87565_gpio *gpio = gpiochip_get_data(chip);
- int ret, val;
-
- ret = regmap_read(gpio->map, LP87565_REG_GPIO_IN, &val);
- if (ret < 0)
- return ret;
-
- return !!(val & BIT(offset));
-}
-
-static void lp87565_gpio_set(struct gpio_chip *chip, unsigned int offset,
- int value)
-{
- struct lp87565_gpio *gpio = gpiochip_get_data(chip);
-
- regmap_update_bits(gpio->map, LP87565_REG_GPIO_OUT,
- BIT(offset), value ? BIT(offset) : 0);
+ BIT(offset), BIT(offset));
}
static int lp87565_gpio_request(struct gpio_chip *gc, unsigned int offset)
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index 3abea3f0b307..92692251ade1 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -424,6 +424,9 @@ static int mxc_gpio_probe(struct platform_device *pdev)
return PTR_ERR(port->base);
port->irq_high = platform_get_irq(pdev, 1);
+ if (port->irq_high < 0)
+ port->irq_high = 0;
+
port->irq = platform_get_irq(pdev, 0);
if (port->irq < 0)
return port->irq;
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index 88529d3c06c9..506c6a67c5fc 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -360,7 +360,7 @@ static void tegra_gpio_irq_handler(struct irq_desc *desc)
{
int port;
int pin;
- int unmasked = 0;
+ bool unmasked = false;
int gpio;
u32 lvl;
unsigned long sta;
@@ -384,8 +384,8 @@ static void tegra_gpio_irq_handler(struct irq_desc *desc)
* before executing the handler so that we don't
* miss edges
*/
- if (lvl & (0x100 << pin)) {
- unmasked = 1;
+ if (!unmasked && lvl & (0x100 << pin)) {
+ unmasked = true;
chained_irq_exit(chip, desc);
}
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 9568708a550b..cd003b74512f 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -704,24 +704,23 @@ static irqreturn_t lineevent_irq_thread(int irq, void *p)
{
struct lineevent_state *le = p;
struct gpioevent_data ge;
- int ret;
+ int ret, level;
ge.timestamp = ktime_get_real_ns();
+ level = gpiod_get_value_cansleep(le->desc);
if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE
&& le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) {
- int level = gpiod_get_value_cansleep(le->desc);
-
if (level)
/* Emit low-to-high event */
ge.id = GPIOEVENT_EVENT_RISING_EDGE;
else
/* Emit high-to-low event */
ge.id = GPIOEVENT_EVENT_FALLING_EDGE;
- } else if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE) {
+ } else if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE && level) {
/* Emit low-to-high event */
ge.id = GPIOEVENT_EVENT_RISING_EDGE;
- } else if (le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) {
+ } else if (le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE && !level) {
/* Emit high-to-low event */
ge.id = GPIOEVENT_EVENT_FALLING_EDGE;
} else {
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 24a066e1841c..a8acc197dec3 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -33,7 +33,7 @@ drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
drm_simple_kms_helper.o drm_modeset_helper.o \
- drm_scdc_helper.o
+ drm_scdc_helper.o drm_gem_framebuffer_helper.o
drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile
index faea6349228f..658bac0cdc5e 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -25,7 +25,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \
amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \
amdgpu_gtt_mgr.o amdgpu_vram_mgr.o amdgpu_virt.o amdgpu_atomfirmware.o \
- amdgpu_queue_mgr.o
+ amdgpu_queue_mgr.o amdgpu_vf_error.o
# add asic specific block
amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index ff7bf1a9f967..12e71bbfd222 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -68,13 +68,16 @@
#include "gpu_scheduler.h"
#include "amdgpu_virt.h"
+#include "amdgpu_gart.h"
/*
* Modules parameters.
*/
extern int amdgpu_modeset;
extern int amdgpu_vram_limit;
-extern int amdgpu_gart_size;
+extern int amdgpu_vis_vram_limit;
+extern unsigned amdgpu_gart_size;
+extern int amdgpu_gtt_size;
extern int amdgpu_moverate;
extern int amdgpu_benchmarking;
extern int amdgpu_testing;
@@ -93,6 +96,7 @@ extern int amdgpu_bapm;
extern int amdgpu_deep_color;
extern int amdgpu_vm_size;
extern int amdgpu_vm_block_size;
+extern int amdgpu_vm_fragment_size;
extern int amdgpu_vm_fault_stop;
extern int amdgpu_vm_debug;
extern int amdgpu_vm_update_mode;
@@ -104,6 +108,7 @@ extern unsigned amdgpu_pcie_gen_cap;
extern unsigned amdgpu_pcie_lane_cap;
extern unsigned amdgpu_cg_mask;
extern unsigned amdgpu_pg_mask;
+extern unsigned amdgpu_sdma_phase_quantum;
extern char *amdgpu_disable_cu;
extern char *amdgpu_virtual_display;
extern unsigned amdgpu_pp_feature_mask;
@@ -369,78 +374,10 @@ struct amdgpu_clock {
};
/*
- * BO.
+ * GEM.
*/
-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_va_mapping {
- struct list_head list;
- struct rb_node rb;
- uint64_t start;
- uint64_t last;
- uint64_t __subtree_last;
- uint64_t offset;
- uint64_t flags;
-};
-
-/* bo virtual addresses in a specific vm */
-struct amdgpu_bo_va {
- /* protected by bo being reserved */
- struct list_head bo_list;
- struct dma_fence *last_pt_update;
- unsigned ref_count;
-
- /* protected by vm mutex and spinlock */
- struct list_head vm_status;
-
- /* mappings for this bo_va */
- struct list_head invalids;
- struct list_head valids;
-
- /* constant after initialization */
- struct amdgpu_vm *vm;
- struct amdgpu_bo *bo;
-};
#define AMDGPU_GEM_DOMAIN_MAX 0x3
-
-struct amdgpu_bo {
- /* Protected by tbo.reserved */
- u32 prefered_domains;
- u32 allowed_domains;
- struct ttm_place placements[AMDGPU_GEM_DOMAIN_MAX + 1];
- struct ttm_placement placement;
- struct ttm_buffer_object tbo;
- struct ttm_bo_kmap_obj kmap;
- u64 flags;
- unsigned pin_count;
- void *kptr;
- u64 tiling_flags;
- u64 metadata_flags;
- void *metadata;
- u32 metadata_size;
- unsigned prime_shared_count;
- /* list of all virtual address to which this bo
- * is associated to
- */
- struct list_head va;
- /* Constant after initialization */
- struct drm_gem_object gem_base;
- struct amdgpu_bo *parent;
- struct amdgpu_bo *shadow;
-
- struct ttm_bo_kmap_obj dma_buf_vmap;
- struct amdgpu_mn *mn;
- struct list_head mn_list;
- struct list_head shadow_list;
-};
#define gem_to_amdgpu_bo(gobj) container_of((gobj), struct amdgpu_bo, gem_base)
void amdgpu_gem_object_free(struct drm_gem_object *obj);
@@ -532,49 +469,6 @@ int amdgpu_fence_slab_init(void);
void amdgpu_fence_slab_fini(void);
/*
- * GART structures, functions & helpers
- */
-struct amdgpu_mc;
-
-#define AMDGPU_GPU_PAGE_SIZE 4096
-#define AMDGPU_GPU_PAGE_MASK (AMDGPU_GPU_PAGE_SIZE - 1)
-#define AMDGPU_GPU_PAGE_SHIFT 12
-#define AMDGPU_GPU_PAGE_ALIGN(a) (((a) + AMDGPU_GPU_PAGE_MASK) & ~AMDGPU_GPU_PAGE_MASK)
-
-struct amdgpu_gart {
- dma_addr_t table_addr;
- struct amdgpu_bo *robj;
- void *ptr;
- unsigned num_gpu_pages;
- unsigned num_cpu_pages;
- unsigned table_size;
-#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
- struct page **pages;
-#endif
- bool ready;
-
- /* Asic default pte flags */
- uint64_t gart_pte_flags;
-
- const struct amdgpu_gart_funcs *gart_funcs;
-};
-
-int amdgpu_gart_table_ram_alloc(struct amdgpu_device *adev);
-void amdgpu_gart_table_ram_free(struct amdgpu_device *adev);
-int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev);
-void amdgpu_gart_table_vram_free(struct amdgpu_device *adev);
-int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev);
-void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev);
-int amdgpu_gart_init(struct amdgpu_device *adev);
-void amdgpu_gart_fini(struct amdgpu_device *adev);
-int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
- int pages);
-int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
- int pages, struct page **pagelist,
- dma_addr_t *dma_addr, uint64_t flags);
-int amdgpu_ttm_recover_gart(struct amdgpu_device *adev);
-
-/*
* VMHUB structures, functions & helpers
*/
struct amdgpu_vmhub {
@@ -598,22 +492,20 @@ struct amdgpu_mc {
* about vram size near mc fb location */
u64 mc_vram_size;
u64 visible_vram_size;
- u64 gtt_size;
- u64 gtt_start;
- u64 gtt_end;
+ u64 gart_size;
+ u64 gart_start;
+ u64 gart_end;
u64 vram_start;
u64 vram_end;
unsigned vram_width;
u64 real_vram_size;
int vram_mtrr;
- u64 gtt_base_align;
u64 mc_mask;
const struct firmware *fw; /* MC firmware */
uint32_t fw_version;
struct amdgpu_irq_src vm_fault;
uint32_t vram_type;
uint32_t srbm_soft_reset;
- struct amdgpu_mode_mc_save save;
bool prt_warning;
uint64_t stolen_size;
/* apertures */
@@ -719,15 +611,15 @@ typedef enum _AMDGPU_DOORBELL64_ASSIGNMENT
/* overlap the doorbell assignment with VCN as they are mutually exclusive
* VCE engine's doorbell is 32 bit and two VCE ring share one QWORD
*/
- AMDGPU_DOORBELL64_RING0_1 = 0xF8,
- AMDGPU_DOORBELL64_RING2_3 = 0xF9,
- AMDGPU_DOORBELL64_RING4_5 = 0xFA,
- AMDGPU_DOORBELL64_RING6_7 = 0xFB,
+ AMDGPU_DOORBELL64_UVD_RING0_1 = 0xF8,
+ AMDGPU_DOORBELL64_UVD_RING2_3 = 0xF9,
+ AMDGPU_DOORBELL64_UVD_RING4_5 = 0xFA,
+ AMDGPU_DOORBELL64_UVD_RING6_7 = 0xFB,
- AMDGPU_DOORBELL64_UVD_RING0_1 = 0xFC,
- AMDGPU_DOORBELL64_UVD_RING2_3 = 0xFD,
- AMDGPU_DOORBELL64_UVD_RING4_5 = 0xFE,
- AMDGPU_DOORBELL64_UVD_RING6_7 = 0xFF,
+ AMDGPU_DOORBELL64_VCE_RING0_1 = 0xFC,
+ AMDGPU_DOORBELL64_VCE_RING2_3 = 0xFD,
+ AMDGPU_DOORBELL64_VCE_RING4_5 = 0xFE,
+ AMDGPU_DOORBELL64_VCE_RING6_7 = 0xFF,
AMDGPU_DOORBELL64_MAX_ASSIGNMENT = 0xFF,
AMDGPU_DOORBELL64_INVALID = 0xFFFF
@@ -857,6 +749,7 @@ void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr);
struct amdgpu_fpriv {
struct amdgpu_vm vm;
struct amdgpu_bo_va *prt_va;
+ struct amdgpu_bo_va *csa_va;
struct mutex bo_list_lock;
struct idr bo_list_handles;
struct amdgpu_ctx_mgr ctx_mgr;
@@ -866,6 +759,14 @@ 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;
@@ -1159,7 +1060,9 @@ struct amdgpu_cs_parser {
struct list_head validated;
struct dma_fence *fence;
uint64_t bytes_moved_threshold;
+ uint64_t bytes_moved_vis_threshold;
uint64_t bytes_moved;
+ uint64_t bytes_moved_vis;
struct amdgpu_bo_list_entry *evictable;
/* user fence */
@@ -1230,8 +1133,6 @@ struct amdgpu_wb {
int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb);
void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb);
-int amdgpu_wb_get_64bit(struct amdgpu_device *adev, u32 *wb);
-void amdgpu_wb_free_64bit(struct amdgpu_device *adev, u32 wb);
void amdgpu_get_pcie_info(struct amdgpu_device *adev);
@@ -1525,7 +1426,7 @@ struct amdgpu_device {
bool is_atom_fw;
uint8_t *bios;
uint32_t bios_size;
- struct amdgpu_bo *stollen_vga_memory;
+ struct amdgpu_bo *stolen_vga_memory;
uint32_t bios_scratch_reg_offset;
uint32_t bios_scratch[AMDGPU_BIOS_NUM_SCRATCH];
@@ -1557,6 +1458,10 @@ struct amdgpu_device {
spinlock_t gc_cac_idx_lock;
amdgpu_rreg_t gc_cac_rreg;
amdgpu_wreg_t gc_cac_wreg;
+ /* protects concurrent se_cac register access */
+ spinlock_t se_cac_idx_lock;
+ amdgpu_rreg_t se_cac_rreg;
+ amdgpu_wreg_t se_cac_wreg;
/* protects concurrent ENDPOINT (audio) register access */
spinlock_t audio_endpt_idx_lock;
amdgpu_block_rreg_t audio_endpt_rreg;
@@ -1579,9 +1484,6 @@ struct amdgpu_device {
struct amdgpu_mman mman;
struct amdgpu_vram_scratch vram_scratch;
struct amdgpu_wb wb;
- atomic64_t vram_usage;
- atomic64_t vram_vis_usage;
- atomic64_t gtt_usage;
atomic64_t num_bytes_moved;
atomic64_t num_evictions;
atomic64_t num_vram_cpu_page_faults;
@@ -1593,6 +1495,7 @@ struct amdgpu_device {
spinlock_t lock;
s64 last_update_us;
s64 accum_us; /* accumulated microseconds */
+ s64 accum_us_vis; /* for visible VRAM */
u32 log2_max_MBps;
} mm_stats;
@@ -1687,6 +1590,8 @@ struct amdgpu_device {
bool has_hw_reset;
u8 reset_magic[AMDGPU_RESET_MAGIC_NUM];
+ /* record last mm index being written through WREG32*/
+ unsigned long last_mm_index;
};
static inline struct amdgpu_device *amdgpu_ttm_adev(struct ttm_bo_device *bdev)
@@ -1742,6 +1647,8 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);
#define WREG32_DIDT(reg, v) adev->didt_wreg(adev, (reg), (v))
#define RREG32_GC_CAC(reg) adev->gc_cac_rreg(adev, (reg))
#define WREG32_GC_CAC(reg, v) adev->gc_cac_wreg(adev, (reg), (v))
+#define RREG32_SE_CAC(reg) adev->se_cac_rreg(adev, (reg))
+#define WREG32_SE_CAC(reg, v) adev->se_cac_wreg(adev, (reg), (v))
#define RREG32_AUDIO_ENDPT(block, reg) adev->audio_endpt_rreg(adev, (block), (reg))
#define WREG32_AUDIO_ENDPT(block, reg, v) adev->audio_endpt_wreg(adev, (block), (reg), (v))
#define WREG32_P(reg, val, mask) \
@@ -1792,50 +1699,6 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);
#define RBIOS16(i) (RBIOS8(i) | (RBIOS8((i)+1) << 8))
#define RBIOS32(i) ((RBIOS16(i)) | (RBIOS16((i)+2) << 16))
-/*
- * RING helpers.
- */
-static inline void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v)
-{
- if (ring->count_dw <= 0)
- DRM_ERROR("amdgpu: writing more dwords to the ring than expected!\n");
- ring->ring[ring->wptr++ & ring->buf_mask] = v;
- ring->wptr &= ring->ptr_mask;
- ring->count_dw--;
-}
-
-static inline void amdgpu_ring_write_multiple(struct amdgpu_ring *ring, void *src, int count_dw)
-{
- unsigned occupied, chunk1, chunk2;
- void *dst;
-
- if (unlikely(ring->count_dw < count_dw)) {
- DRM_ERROR("amdgpu: writing more dwords to the ring than expected!\n");
- return;
- }
-
- occupied = ring->wptr & ring->buf_mask;
- dst = (void *)&ring->ring[occupied];
- chunk1 = ring->buf_mask + 1 - occupied;
- chunk1 = (chunk1 >= count_dw) ? count_dw: chunk1;
- chunk2 = count_dw - chunk1;
- chunk1 <<= 2;
- chunk2 <<= 2;
-
- if (chunk1)
- memcpy(dst, src, chunk1);
-
- if (chunk2) {
- src += chunk1;
- dst = (void *)ring->ring;
- memcpy(dst, src, chunk2);
- }
-
- ring->wptr += count_dw;
- ring->wptr &= ring->ptr_mask;
- ring->count_dw -= count_dw;
-}
-
static inline struct amdgpu_sdma_instance *
amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
{
@@ -1898,7 +1761,6 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev))
#define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv))
#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev))
-#define amdgpu_display_set_vga_render_state(adev, r) (adev)->mode_info.funcs->set_vga_render_state((adev), (r))
#define amdgpu_display_vblank_get_counter(adev, crtc) (adev)->mode_info.funcs->vblank_get_counter((adev), (crtc))
#define amdgpu_display_vblank_wait(adev, crtc) (adev)->mode_info.funcs->vblank_wait((adev), (crtc))
#define amdgpu_display_backlight_set_level(adev, e, l) (adev)->mode_info.funcs->backlight_set_level((e), (l))
@@ -1911,8 +1773,6 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
#define amdgpu_display_page_flip_get_scanoutpos(adev, crtc, vbl, pos) (adev)->mode_info.funcs->page_flip_get_scanoutpos((adev), (crtc), (vbl), (pos))
#define amdgpu_display_add_encoder(adev, e, s, c) (adev)->mode_info.funcs->add_encoder((adev), (e), (s), (c))
#define amdgpu_display_add_connector(adev, ci, sd, ct, ib, coi, h, r) (adev)->mode_info.funcs->add_connector((adev), (ci), (sd), (ct), (ib), (coi), (h), (r))
-#define amdgpu_display_stop_mc_access(adev, s) (adev)->mode_info.funcs->stop_mc_access((adev), (s))
-#define amdgpu_display_resume_mc_access(adev, s) (adev)->mode_info.funcs->resume_mc_access((adev), (s))
#define amdgpu_emit_copy_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_copy_buffer((ib), (s), (d), (b))
#define amdgpu_emit_fill_buffer(adev, ib, s, d, b) (adev)->mman.buffer_funcs->emit_fill_buffer((ib), (s), (d), (b))
#define amdgpu_gfx_get_gpu_clock_counter(adev) (adev)->gfx.funcs->get_gpu_clock_counter((adev))
@@ -1927,7 +1787,8 @@ void amdgpu_pci_config_reset(struct amdgpu_device *adev);
bool amdgpu_need_post(struct amdgpu_device *adev);
void amdgpu_update_display_priority(struct amdgpu_device *adev);
-void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes);
+void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes,
+ u64 num_vis_bytes);
void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *abo, u32 domain);
bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo);
int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages);
@@ -1943,7 +1804,7 @@ bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm);
uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
struct ttm_mem_reg *mem);
void amdgpu_vram_location(struct amdgpu_device *adev, struct amdgpu_mc *mc, u64 base);
-void amdgpu_gtt_location(struct amdgpu_device *adev, struct amdgpu_mc *mc);
+void amdgpu_gart_location(struct amdgpu_device *adev, struct amdgpu_mc *mc);
void amdgpu_ttm_set_active_vram_size(struct amdgpu_device *adev, u64 size);
int amdgpu_ttm_init(struct amdgpu_device *adev);
void amdgpu_ttm_fini(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
index 06879d1dcabd..a52795d9b458 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
@@ -285,19 +285,20 @@ static int acp_hw_init(void *handle)
return 0;
else if (r)
return r;
+ if (adev->asic_type != CHIP_STONEY) {
+ adev->acp.acp_genpd = kzalloc(sizeof(struct acp_pm_domain), GFP_KERNEL);
+ if (adev->acp.acp_genpd == NULL)
+ return -ENOMEM;
- adev->acp.acp_genpd = kzalloc(sizeof(struct acp_pm_domain), GFP_KERNEL);
- if (adev->acp.acp_genpd == NULL)
- return -ENOMEM;
-
- adev->acp.acp_genpd->gpd.name = "ACP_AUDIO";
- adev->acp.acp_genpd->gpd.power_off = acp_poweroff;
- adev->acp.acp_genpd->gpd.power_on = acp_poweron;
+ adev->acp.acp_genpd->gpd.name = "ACP_AUDIO";
+ adev->acp.acp_genpd->gpd.power_off = acp_poweroff;
+ adev->acp.acp_genpd->gpd.power_on = acp_poweron;
- adev->acp.acp_genpd->cgs_dev = adev->acp.cgs_device;
+ adev->acp.acp_genpd->cgs_dev = adev->acp.cgs_device;
- pm_genpd_init(&adev->acp.acp_genpd->gpd, NULL, false);
+ pm_genpd_init(&adev->acp.acp_genpd->gpd, NULL, false);
+ }
adev->acp.acp_cell = kzalloc(sizeof(struct mfd_cell) * ACP_DEVS,
GFP_KERNEL);
@@ -319,14 +320,29 @@ static int acp_hw_init(void *handle)
return -ENOMEM;
}
- i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
+ switch (adev->asic_type) {
+ case CHIP_STONEY:
+ i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
+ DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
+ break;
+ default:
+ i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
+ }
i2s_pdata[0].cap = DWC_I2S_PLAY;
i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000;
i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_PLAY_REG_OFFSET;
i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_PLAY_REG_OFFSET;
+ switch (adev->asic_type) {
+ case CHIP_STONEY:
+ i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
+ DW_I2S_QUIRK_COMP_PARAM1 |
+ DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
+ break;
+ default:
+ i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
+ DW_I2S_QUIRK_COMP_PARAM1;
+ }
- i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
- DW_I2S_QUIRK_COMP_PARAM1;
i2s_pdata[1].cap = DWC_I2S_RECORD;
i2s_pdata[1].snd_rates = SNDRV_PCM_RATE_8000_96000;
i2s_pdata[1].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET;
@@ -373,12 +389,14 @@ static int acp_hw_init(void *handle)
if (r)
return r;
- for (i = 0; i < ACP_DEVS ; i++) {
- dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
- r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev);
- if (r) {
- dev_err(dev, "Failed to add dev to genpd\n");
- return r;
+ if (adev->asic_type != CHIP_STONEY) {
+ for (i = 0; i < ACP_DEVS ; i++) {
+ dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
+ r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev);
+ if (r) {
+ dev_err(dev, "Failed to add dev to genpd\n");
+ return r;
+ }
}
}
@@ -398,20 +416,22 @@ static int acp_hw_fini(void *handle)
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
/* return early if no ACP */
- if (!adev->acp.acp_genpd)
+ if (!adev->acp.acp_cell)
return 0;
- for (i = 0; i < ACP_DEVS ; i++) {
- dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
- ret = pm_genpd_remove_device(&adev->acp.acp_genpd->gpd, dev);
- /* If removal fails, dont giveup and try rest */
- if (ret)
- dev_err(dev, "remove dev from genpd failed\n");
+ if (adev->acp.acp_genpd) {
+ for (i = 0; i < ACP_DEVS ; i++) {
+ dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
+ ret = pm_genpd_remove_device(&adev->acp.acp_genpd->gpd, dev);
+ /* If removal fails, dont giveup and try rest */
+ if (ret)
+ dev_err(dev, "remove dev from genpd failed\n");
+ }
+ kfree(adev->acp.acp_genpd);
}
mfd_remove_devices(adev->acp.parent);
kfree(adev->acp.acp_res);
- kfree(adev->acp.acp_genpd);
kfree(adev->acp.acp_cell);
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
index ef79551b4cb7..57afad79f55d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
@@ -30,10 +30,10 @@
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include "amdgpu.h"
+#include "amdgpu_pm.h"
#include "amd_acpi.h"
#include "atom.h"
-extern void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev);
/* Call the ATIF method
*/
/**
@@ -289,7 +289,7 @@ out:
* handles it.
* Returns NOTIFY code
*/
-int amdgpu_atif_handler(struct amdgpu_device *adev,
+static int amdgpu_atif_handler(struct amdgpu_device *adev,
struct acpi_bus_event *event)
{
struct amdgpu_atif *atif = &adev->atif;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
index 5f8ada1d872b..5432af39a674 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
@@ -27,16 +27,15 @@
#include "amdgpu_gfx.h"
#include <linux/module.h>
-const struct kfd2kgd_calls *kfd2kgd;
const struct kgd2kfd_calls *kgd2kfd;
-bool (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**);
+bool (*kgd2kfd_init_p)(unsigned int, const struct kgd2kfd_calls**);
int amdgpu_amdkfd_init(void)
{
int ret;
#if defined(CONFIG_HSA_AMD_MODULE)
- int (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**);
+ int (*kgd2kfd_init_p)(unsigned int, const struct kgd2kfd_calls**);
kgd2kfd_init_p = symbol_request(kgd2kfd_init);
@@ -61,8 +60,21 @@ int amdgpu_amdkfd_init(void)
return ret;
}
-bool amdgpu_amdkfd_load_interface(struct amdgpu_device *adev)
+void amdgpu_amdkfd_fini(void)
+{
+ if (kgd2kfd) {
+ kgd2kfd->exit();
+ symbol_put(kgd2kfd_init);
+ }
+}
+
+void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev)
{
+ const struct kfd2kgd_calls *kfd2kgd;
+
+ if (!kgd2kfd)
+ return;
+
switch (adev->asic_type) {
#ifdef CONFIG_DRM_AMDGPU_CIK
case CHIP_KAVERI:
@@ -73,25 +85,12 @@ bool amdgpu_amdkfd_load_interface(struct amdgpu_device *adev)
kfd2kgd = amdgpu_amdkfd_gfx_8_0_get_functions();
break;
default:
- return false;
+ dev_info(adev->dev, "kfd not supported on this ASIC\n");
+ return;
}
- return true;
-}
-
-void amdgpu_amdkfd_fini(void)
-{
- if (kgd2kfd) {
- kgd2kfd->exit();
- symbol_put(kgd2kfd_init);
- }
-}
-
-void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev)
-{
- if (kgd2kfd)
- adev->kfd = kgd2kfd->probe((struct kgd_dev *)adev,
- adev->pdev, kfd2kgd);
+ adev->kfd = kgd2kfd->probe((struct kgd_dev *)adev,
+ adev->pdev, kfd2kgd);
}
void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
@@ -101,7 +100,6 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
if (adev->kfd) {
struct kgd2kfd_shared_resources gpu_resources = {
.compute_vmid_bitmap = 0xFF00,
- .num_mec = adev->gfx.mec.num_mec,
.num_pipe_per_mec = adev->gfx.mec.num_pipe_per_mec,
.num_queue_per_pipe = adev->gfx.mec.num_queue_per_pipe
};
@@ -122,7 +120,7 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
/* According to linux/bitmap.h we shouldn't use bitmap_clear if
* nbits is not compile time constant */
- last_valid_bit = adev->gfx.mec.num_mec
+ last_valid_bit = 1 /* only first MEC can have compute queues */
* adev->gfx.mec.num_pipe_per_mec
* adev->gfx.mec.num_queue_per_pipe;
for (i = last_valid_bit; i < KGD_MAX_QUEUES; ++i)
@@ -185,7 +183,8 @@ int alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
return -ENOMEM;
r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_GTT,
- AMDGPU_GEM_CREATE_CPU_GTT_USWC, NULL, NULL, &(*mem)->bo);
+ AMDGPU_GEM_CREATE_CPU_GTT_USWC, NULL, NULL, 0,
+ &(*mem)->bo);
if (r) {
dev_err(adev->dev,
"failed to allocate BO for amdkfd (%d)\n", r);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
index 73f83a10ae14..8d689ab7e429 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -26,6 +26,7 @@
#define AMDGPU_AMDKFD_H_INCLUDED
#include <linux/types.h>
+#include <linux/mmu_context.h>
#include <kgd_kfd_interface.h>
struct amdgpu_device;
@@ -39,8 +40,6 @@ struct kgd_mem {
int amdgpu_amdkfd_init(void);
void amdgpu_amdkfd_fini(void);
-bool amdgpu_amdkfd_load_interface(struct amdgpu_device *adev);
-
void amdgpu_amdkfd_suspend(struct amdgpu_device *adev);
int amdgpu_amdkfd_resume(struct amdgpu_device *adev);
void amdgpu_amdkfd_interrupt(struct amdgpu_device *adev,
@@ -62,4 +61,19 @@ uint64_t get_gpu_clock_counter(struct kgd_dev *kgd);
uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd);
+#define read_user_wptr(mmptr, wptr, dst) \
+ ({ \
+ bool valid = false; \
+ if ((mmptr) && (wptr)) { \
+ if ((mmptr) == current->mm) { \
+ valid = !get_user((dst), (wptr)); \
+ } else if (current->mm == NULL) { \
+ use_mm(mmptr); \
+ valid = !get_user((dst), (wptr)); \
+ unuse_mm(mmptr); \
+ } \
+ } \
+ valid; \
+ })
+
#endif /* AMDGPU_AMDKFD_H_INCLUDED */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
index 5254562fd0f9..b9dbbf9cb8b0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
@@ -39,6 +39,12 @@
#include "gmc/gmc_7_1_sh_mask.h"
#include "cik_structs.h"
+enum hqd_dequeue_request_type {
+ NO_ACTION = 0,
+ DRAIN_PIPE,
+ RESET_WAVES
+};
+
enum {
MAX_TRAPID = 8, /* 3 bits in the bitfield. */
MAX_WATCH_ADDRESSES = 4
@@ -96,12 +102,15 @@ static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
uint32_t hpd_size, uint64_t hpd_gpu_addr);
static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id);
static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
- uint32_t queue_id, uint32_t __user *wptr);
+ uint32_t queue_id, uint32_t __user *wptr,
+ uint32_t wptr_shift, uint32_t wptr_mask,
+ struct mm_struct *mm);
static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd);
static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
uint32_t pipe_id, uint32_t queue_id);
-static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
+static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
+ enum kfd_preempt_type reset_type,
unsigned int utimeout, uint32_t pipe_id,
uint32_t queue_id);
static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd);
@@ -126,6 +135,33 @@ static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd,
static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid);
static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type);
+static void set_scratch_backing_va(struct kgd_dev *kgd,
+ uint64_t va, uint32_t vmid);
+
+/* Because of REG_GET_FIELD() being used, we put this function in the
+ * asic specific file.
+ */
+static int get_tile_config(struct kgd_dev *kgd,
+ struct tile_config *config)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
+
+ config->gb_addr_config = adev->gfx.config.gb_addr_config;
+ config->num_banks = REG_GET_FIELD(adev->gfx.config.mc_arb_ramcfg,
+ MC_ARB_RAMCFG, NOOFBANK);
+ config->num_ranks = REG_GET_FIELD(adev->gfx.config.mc_arb_ramcfg,
+ MC_ARB_RAMCFG, NOOFRANKS);
+
+ config->tile_config_ptr = adev->gfx.config.tile_mode_array;
+ config->num_tile_configs =
+ ARRAY_SIZE(adev->gfx.config.tile_mode_array);
+ config->macro_tile_config_ptr =
+ adev->gfx.config.macrotile_mode_array;
+ config->num_macro_tile_configs =
+ ARRAY_SIZE(adev->gfx.config.macrotile_mode_array);
+
+ return 0;
+}
static const struct kfd2kgd_calls kfd2kgd = {
.init_gtt_mem_allocation = alloc_gtt_mem,
@@ -150,7 +186,9 @@ static const struct kfd2kgd_calls kfd2kgd = {
.get_atc_vmid_pasid_mapping_pasid = get_atc_vmid_pasid_mapping_pasid,
.get_atc_vmid_pasid_mapping_valid = get_atc_vmid_pasid_mapping_valid,
.write_vmid_invalidate_request = write_vmid_invalidate_request,
- .get_fw_version = get_fw_version
+ .get_fw_version = get_fw_version,
+ .set_scratch_backing_va = set_scratch_backing_va,
+ .get_tile_config = get_tile_config,
};
struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void)
@@ -186,7 +224,7 @@ static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id,
{
struct amdgpu_device *adev = get_amdgpu_device(kgd);
- uint32_t mec = (++pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
+ uint32_t mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
uint32_t pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
lock_srbm(kgd, mec, pipe, queue_id, 0);
@@ -290,20 +328,38 @@ static inline struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd)
}
static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
- uint32_t queue_id, uint32_t __user *wptr)
+ uint32_t queue_id, uint32_t __user *wptr,
+ uint32_t wptr_shift, uint32_t wptr_mask,
+ struct mm_struct *mm)
{
struct amdgpu_device *adev = get_amdgpu_device(kgd);
- uint32_t wptr_shadow, is_wptr_shadow_valid;
struct cik_mqd *m;
+ uint32_t *mqd_hqd;
+ uint32_t reg, wptr_val, data;
m = get_mqd(mqd);
- is_wptr_shadow_valid = !get_user(wptr_shadow, wptr);
- if (is_wptr_shadow_valid)
- m->cp_hqd_pq_wptr = wptr_shadow;
-
acquire_queue(kgd, pipe_id, queue_id);
- gfx_v7_0_mqd_commit(adev, m);
+
+ /* HQD registers extend from CP_MQD_BASE_ADDR to CP_MQD_CONTROL. */
+ mqd_hqd = &m->cp_mqd_base_addr_lo;
+
+ for (reg = mmCP_MQD_BASE_ADDR; reg <= mmCP_MQD_CONTROL; reg++)
+ WREG32(reg, mqd_hqd[reg - mmCP_MQD_BASE_ADDR]);
+
+ /* Copy userspace write pointer value to register.
+ * Activate doorbell logic to monitor subsequent changes.
+ */
+ data = REG_SET_FIELD(m->cp_hqd_pq_doorbell_control,
+ CP_HQD_PQ_DOORBELL_CONTROL, DOORBELL_EN, 1);
+ WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, data);
+
+ if (read_user_wptr(mm, wptr, wptr_val))
+ WREG32(mmCP_HQD_PQ_WPTR, (wptr_val << wptr_shift) & wptr_mask);
+
+ data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1);
+ WREG32(mmCP_HQD_ACTIVE, data);
+
release_queue(kgd);
return 0;
@@ -382,30 +438,99 @@ static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
return false;
}
-static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
+static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
+ enum kfd_preempt_type reset_type,
unsigned int utimeout, uint32_t pipe_id,
uint32_t queue_id)
{
struct amdgpu_device *adev = get_amdgpu_device(kgd);
uint32_t temp;
- int timeout = utimeout;
+ enum hqd_dequeue_request_type type;
+ unsigned long flags, end_jiffies;
+ int retry;
acquire_queue(kgd, pipe_id, queue_id);
WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, 0);
- WREG32(mmCP_HQD_DEQUEUE_REQUEST, reset_type);
+ switch (reset_type) {
+ case KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN:
+ type = DRAIN_PIPE;
+ break;
+ case KFD_PREEMPT_TYPE_WAVEFRONT_RESET:
+ type = RESET_WAVES;
+ break;
+ default:
+ type = DRAIN_PIPE;
+ break;
+ }
+
+ /* Workaround: If IQ timer is active and the wait time is close to or
+ * equal to 0, dequeueing is not safe. Wait until either the wait time
+ * is larger or timer is cleared. Also, ensure that IQ_REQ_PEND is
+ * cleared before continuing. Also, ensure wait times are set to at
+ * least 0x3.
+ */
+ local_irq_save(flags);
+ preempt_disable();
+ retry = 5000; /* wait for 500 usecs at maximum */
+ while (true) {
+ temp = RREG32(mmCP_HQD_IQ_TIMER);
+ if (REG_GET_FIELD(temp, CP_HQD_IQ_TIMER, PROCESSING_IQ)) {
+ pr_debug("HW is processing IQ\n");
+ goto loop;
+ }
+ if (REG_GET_FIELD(temp, CP_HQD_IQ_TIMER, ACTIVE)) {
+ if (REG_GET_FIELD(temp, CP_HQD_IQ_TIMER, RETRY_TYPE)
+ == 3) /* SEM-rearm is safe */
+ break;
+ /* Wait time 3 is safe for CP, but our MMIO read/write
+ * time is close to 1 microsecond, so check for 10 to
+ * leave more buffer room
+ */
+ if (REG_GET_FIELD(temp, CP_HQD_IQ_TIMER, WAIT_TIME)
+ >= 10)
+ break;
+ pr_debug("IQ timer is active\n");
+ } else
+ break;
+loop:
+ if (!retry) {
+ pr_err("CP HQD IQ timer status time out\n");
+ break;
+ }
+ ndelay(100);
+ --retry;
+ }
+ retry = 1000;
+ while (true) {
+ temp = RREG32(mmCP_HQD_DEQUEUE_REQUEST);
+ if (!(temp & CP_HQD_DEQUEUE_REQUEST__IQ_REQ_PEND_MASK))
+ break;
+ pr_debug("Dequeue request is pending\n");
+ if (!retry) {
+ pr_err("CP HQD dequeue request time out\n");
+ break;
+ }
+ ndelay(100);
+ --retry;
+ }
+ local_irq_restore(flags);
+ preempt_enable();
+
+ WREG32(mmCP_HQD_DEQUEUE_REQUEST, type);
+
+ end_jiffies = (utimeout * HZ / 1000) + jiffies;
while (true) {
temp = RREG32(mmCP_HQD_ACTIVE);
- if (temp & CP_HQD_ACTIVE__ACTIVE_MASK)
+ if (!(temp & CP_HQD_ACTIVE__ACTIVE_MASK))
break;
- if (timeout <= 0) {
- pr_err("kfd: cp queue preemption time out.\n");
+ if (time_after(jiffies, end_jiffies)) {
+ pr_err("cp queue preemption time out\n");
release_queue(kgd);
return -ETIME;
}
- msleep(20);
- timeout -= 20;
+ usleep_range(500, 1000);
}
release_queue(kgd);
@@ -556,6 +681,16 @@ static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid)
WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
}
+static void set_scratch_backing_va(struct kgd_dev *kgd,
+ uint64_t va, uint32_t vmid)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
+
+ lock_srbm(kgd, 0, 0, 0, vmid);
+ WREG32(mmSH_HIDDEN_PRIVATE_BASE_VMID, va);
+ unlock_srbm(kgd);
+}
+
static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
{
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
@@ -566,42 +701,42 @@ static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
switch (type) {
case KGD_ENGINE_PFP:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.pfp_fw->data;
+ adev->gfx.pfp_fw->data;
break;
case KGD_ENGINE_ME:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.me_fw->data;
+ adev->gfx.me_fw->data;
break;
case KGD_ENGINE_CE:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.ce_fw->data;
+ adev->gfx.ce_fw->data;
break;
case KGD_ENGINE_MEC1:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.mec_fw->data;
+ adev->gfx.mec_fw->data;
break;
case KGD_ENGINE_MEC2:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.mec2_fw->data;
+ adev->gfx.mec2_fw->data;
break;
case KGD_ENGINE_RLC:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.rlc_fw->data;
+ adev->gfx.rlc_fw->data;
break;
case KGD_ENGINE_SDMA1:
hdr = (const union amdgpu_firmware_header *)
- adev->sdma.instance[0].fw->data;
+ adev->sdma.instance[0].fw->data;
break;
case KGD_ENGINE_SDMA2:
hdr = (const union amdgpu_firmware_header *)
- adev->sdma.instance[1].fw->data;
+ adev->sdma.instance[1].fw->data;
break;
default:
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
index 133d06671e46..fb6e5dbd5a03 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
@@ -39,6 +39,12 @@
#include "vi_structs.h"
#include "vid.h"
+enum hqd_dequeue_request_type {
+ NO_ACTION = 0,
+ DRAIN_PIPE,
+ RESET_WAVES
+};
+
struct cik_sdma_rlc_registers;
/*
@@ -55,12 +61,15 @@ static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
uint32_t hpd_size, uint64_t hpd_gpu_addr);
static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id);
static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
- uint32_t queue_id, uint32_t __user *wptr);
+ uint32_t queue_id, uint32_t __user *wptr,
+ uint32_t wptr_shift, uint32_t wptr_mask,
+ struct mm_struct *mm);
static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd);
static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
uint32_t pipe_id, uint32_t queue_id);
static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd);
-static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
+static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
+ enum kfd_preempt_type reset_type,
unsigned int utimeout, uint32_t pipe_id,
uint32_t queue_id);
static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
@@ -85,6 +94,33 @@ static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd,
uint8_t vmid);
static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid);
static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type);
+static void set_scratch_backing_va(struct kgd_dev *kgd,
+ uint64_t va, uint32_t vmid);
+
+/* Because of REG_GET_FIELD() being used, we put this function in the
+ * asic specific file.
+ */
+static int get_tile_config(struct kgd_dev *kgd,
+ struct tile_config *config)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
+
+ config->gb_addr_config = adev->gfx.config.gb_addr_config;
+ config->num_banks = REG_GET_FIELD(adev->gfx.config.mc_arb_ramcfg,
+ MC_ARB_RAMCFG, NOOFBANK);
+ config->num_ranks = REG_GET_FIELD(adev->gfx.config.mc_arb_ramcfg,
+ MC_ARB_RAMCFG, NOOFRANKS);
+
+ config->tile_config_ptr = adev->gfx.config.tile_mode_array;
+ config->num_tile_configs =
+ ARRAY_SIZE(adev->gfx.config.tile_mode_array);
+ config->macro_tile_config_ptr =
+ adev->gfx.config.macrotile_mode_array;
+ config->num_macro_tile_configs =
+ ARRAY_SIZE(adev->gfx.config.macrotile_mode_array);
+
+ return 0;
+}
static const struct kfd2kgd_calls kfd2kgd = {
.init_gtt_mem_allocation = alloc_gtt_mem,
@@ -111,12 +147,15 @@ static const struct kfd2kgd_calls kfd2kgd = {
.get_atc_vmid_pasid_mapping_valid =
get_atc_vmid_pasid_mapping_valid,
.write_vmid_invalidate_request = write_vmid_invalidate_request,
- .get_fw_version = get_fw_version
+ .get_fw_version = get_fw_version,
+ .set_scratch_backing_va = set_scratch_backing_va,
+ .get_tile_config = get_tile_config,
};
struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void)
{
return (struct kfd2kgd_calls *)&kfd2kgd;
+ return (struct kfd2kgd_calls *)&kfd2kgd;
}
static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd)
@@ -147,7 +186,7 @@ static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id,
{
struct amdgpu_device *adev = get_amdgpu_device(kgd);
- uint32_t mec = (++pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
+ uint32_t mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
uint32_t pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
lock_srbm(kgd, mec, pipe, queue_id, 0);
@@ -216,7 +255,7 @@ static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id)
uint32_t mec;
uint32_t pipe;
- mec = (++pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
+ mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
lock_srbm(kgd, mec, pipe, 0, 0);
@@ -244,20 +283,67 @@ static inline struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd)
}
static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
- uint32_t queue_id, uint32_t __user *wptr)
+ uint32_t queue_id, uint32_t __user *wptr,
+ uint32_t wptr_shift, uint32_t wptr_mask,
+ struct mm_struct *mm)
{
- struct vi_mqd *m;
- uint32_t shadow_wptr, valid_wptr;
struct amdgpu_device *adev = get_amdgpu_device(kgd);
+ struct vi_mqd *m;
+ uint32_t *mqd_hqd;
+ uint32_t reg, wptr_val, data;
m = get_mqd(mqd);
- valid_wptr = copy_from_user(&shadow_wptr, wptr, sizeof(shadow_wptr));
- if (valid_wptr == 0)
- m->cp_hqd_pq_wptr = shadow_wptr;
-
acquire_queue(kgd, pipe_id, queue_id);
- gfx_v8_0_mqd_commit(adev, mqd);
+
+ /* HIQ is set during driver init period with vmid set to 0*/
+ if (m->cp_hqd_vmid == 0) {
+ uint32_t value, mec, pipe;
+
+ mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1;
+ pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec);
+
+ pr_debug("kfd: set HIQ, mec:%d, pipe:%d, queue:%d.\n",
+ mec, pipe, queue_id);
+ value = RREG32(mmRLC_CP_SCHEDULERS);
+ value = REG_SET_FIELD(value, RLC_CP_SCHEDULERS, scheduler1,
+ ((mec << 5) | (pipe << 3) | queue_id | 0x80));
+ WREG32(mmRLC_CP_SCHEDULERS, value);
+ }
+
+ /* HQD registers extend from CP_MQD_BASE_ADDR to CP_HQD_EOP_WPTR_MEM. */
+ mqd_hqd = &m->cp_mqd_base_addr_lo;
+
+ for (reg = mmCP_MQD_BASE_ADDR; reg <= mmCP_HQD_EOP_CONTROL; reg++)
+ WREG32(reg, mqd_hqd[reg - mmCP_MQD_BASE_ADDR]);
+
+ /* Tonga errata: EOP RPTR/WPTR should be left unmodified.
+ * This is safe since EOP RPTR==WPTR for any inactive HQD
+ * on ASICs that do not support context-save.
+ * EOP writes/reads can start anywhere in the ring.
+ */
+ if (get_amdgpu_device(kgd)->asic_type != CHIP_TONGA) {
+ WREG32(mmCP_HQD_EOP_RPTR, m->cp_hqd_eop_rptr);
+ WREG32(mmCP_HQD_EOP_WPTR, m->cp_hqd_eop_wptr);
+ WREG32(mmCP_HQD_EOP_WPTR_MEM, m->cp_hqd_eop_wptr_mem);
+ }
+
+ for (reg = mmCP_HQD_EOP_EVENTS; reg <= mmCP_HQD_ERROR; reg++)
+ WREG32(reg, mqd_hqd[reg - mmCP_MQD_BASE_ADDR]);
+
+ /* Copy userspace write pointer value to register.
+ * Activate doorbell logic to monitor subsequent changes.
+ */
+ data = REG_SET_FIELD(m->cp_hqd_pq_doorbell_control,
+ CP_HQD_PQ_DOORBELL_CONTROL, DOORBELL_EN, 1);
+ WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, data);
+
+ if (read_user_wptr(mm, wptr, wptr_val))
+ WREG32(mmCP_HQD_PQ_WPTR, (wptr_val << wptr_shift) & wptr_mask);
+
+ data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1);
+ WREG32(mmCP_HQD_ACTIVE, data);
+
release_queue(kgd);
return 0;
@@ -308,29 +394,102 @@ static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
return false;
}
-static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
+static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
+ enum kfd_preempt_type reset_type,
unsigned int utimeout, uint32_t pipe_id,
uint32_t queue_id)
{
struct amdgpu_device *adev = get_amdgpu_device(kgd);
uint32_t temp;
- int timeout = utimeout;
+ enum hqd_dequeue_request_type type;
+ unsigned long flags, end_jiffies;
+ int retry;
+ struct vi_mqd *m = get_mqd(mqd);
acquire_queue(kgd, pipe_id, queue_id);
- WREG32(mmCP_HQD_DEQUEUE_REQUEST, reset_type);
+ if (m->cp_hqd_vmid == 0)
+ WREG32_FIELD(RLC_CP_SCHEDULERS, scheduler1, 0);
+
+ switch (reset_type) {
+ case KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN:
+ type = DRAIN_PIPE;
+ break;
+ case KFD_PREEMPT_TYPE_WAVEFRONT_RESET:
+ type = RESET_WAVES;
+ break;
+ default:
+ type = DRAIN_PIPE;
+ break;
+ }
+ /* Workaround: If IQ timer is active and the wait time is close to or
+ * equal to 0, dequeueing is not safe. Wait until either the wait time
+ * is larger or timer is cleared. Also, ensure that IQ_REQ_PEND is
+ * cleared before continuing. Also, ensure wait times are set to at
+ * least 0x3.
+ */
+ local_irq_save(flags);
+ preempt_disable();
+ retry = 5000; /* wait for 500 usecs at maximum */
+ while (true) {
+ temp = RREG32(mmCP_HQD_IQ_TIMER);
+ if (REG_GET_FIELD(temp, CP_HQD_IQ_TIMER, PROCESSING_IQ)) {
+ pr_debug("HW is processing IQ\n");
+ goto loop;
+ }
+ if (REG_GET_FIELD(temp, CP_HQD_IQ_TIMER, ACTIVE)) {
+ if (REG_GET_FIELD(temp, CP_HQD_IQ_TIMER, RETRY_TYPE)
+ == 3) /* SEM-rearm is safe */
+ break;
+ /* Wait time 3 is safe for CP, but our MMIO read/write
+ * time is close to 1 microsecond, so check for 10 to
+ * leave more buffer room
+ */
+ if (REG_GET_FIELD(temp, CP_HQD_IQ_TIMER, WAIT_TIME)
+ >= 10)
+ break;
+ pr_debug("IQ timer is active\n");
+ } else
+ break;
+loop:
+ if (!retry) {
+ pr_err("CP HQD IQ timer status time out\n");
+ break;
+ }
+ ndelay(100);
+ --retry;
+ }
+ retry = 1000;
+ while (true) {
+ temp = RREG32(mmCP_HQD_DEQUEUE_REQUEST);
+ if (!(temp & CP_HQD_DEQUEUE_REQUEST__IQ_REQ_PEND_MASK))
+ break;
+ pr_debug("Dequeue request is pending\n");
+
+ if (!retry) {
+ pr_err("CP HQD dequeue request time out\n");
+ break;
+ }
+ ndelay(100);
+ --retry;
+ }
+ local_irq_restore(flags);
+ preempt_enable();
+
+ WREG32(mmCP_HQD_DEQUEUE_REQUEST, type);
+
+ end_jiffies = (utimeout * HZ / 1000) + jiffies;
while (true) {
temp = RREG32(mmCP_HQD_ACTIVE);
- if (temp & CP_HQD_ACTIVE__ACTIVE_MASK)
+ if (!(temp & CP_HQD_ACTIVE__ACTIVE_MASK))
break;
- if (timeout <= 0) {
- pr_err("kfd: cp queue preemption time out.\n");
+ if (time_after(jiffies, end_jiffies)) {
+ pr_err("cp queue preemption time out.\n");
release_queue(kgd);
return -ETIME;
}
- msleep(20);
- timeout -= 20;
+ usleep_range(500, 1000);
}
release_queue(kgd);
@@ -444,6 +603,16 @@ static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd,
return 0;
}
+static void set_scratch_backing_va(struct kgd_dev *kgd,
+ uint64_t va, uint32_t vmid)
+{
+ struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
+
+ lock_srbm(kgd, 0, 0, 0, vmid);
+ WREG32(mmSH_HIDDEN_PRIVATE_BASE_VMID, va);
+ unlock_srbm(kgd);
+}
+
static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
{
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
@@ -454,42 +623,42 @@ static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
switch (type) {
case KGD_ENGINE_PFP:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.pfp_fw->data;
+ adev->gfx.pfp_fw->data;
break;
case KGD_ENGINE_ME:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.me_fw->data;
+ adev->gfx.me_fw->data;
break;
case KGD_ENGINE_CE:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.ce_fw->data;
+ adev->gfx.ce_fw->data;
break;
case KGD_ENGINE_MEC1:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.mec_fw->data;
+ adev->gfx.mec_fw->data;
break;
case KGD_ENGINE_MEC2:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.mec2_fw->data;
+ adev->gfx.mec2_fw->data;
break;
case KGD_ENGINE_RLC:
hdr = (const union amdgpu_firmware_header *)
- adev->gfx.rlc_fw->data;
+ adev->gfx.rlc_fw->data;
break;
case KGD_ENGINE_SDMA1:
hdr = (const union amdgpu_firmware_header *)
- adev->sdma.instance[0].fw->data;
+ adev->sdma.instance[0].fw->data;
break;
case KGD_ENGINE_SDMA2:
hdr = (const union amdgpu_firmware_header *)
- adev->sdma.instance[1].fw->data;
+ adev->sdma.instance[1].fw->data;
break;
default:
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
index 1e8e1123ddf4..ce443586a0c7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
@@ -1686,7 +1686,7 @@ void amdgpu_atombios_scratch_regs_lock(struct amdgpu_device *adev, bool lock)
{
uint32_t bios_6_scratch;
- bios_6_scratch = RREG32(mmBIOS_SCRATCH_6);
+ bios_6_scratch = RREG32(adev->bios_scratch_reg_offset + 6);
if (lock) {
bios_6_scratch |= ATOM_S6_CRITICAL_STATE;
@@ -1696,15 +1696,17 @@ void amdgpu_atombios_scratch_regs_lock(struct amdgpu_device *adev, bool lock)
bios_6_scratch |= ATOM_S6_ACC_MODE;
}
- WREG32(mmBIOS_SCRATCH_6, bios_6_scratch);
+ WREG32(adev->bios_scratch_reg_offset + 6, bios_6_scratch);
}
void amdgpu_atombios_scratch_regs_init(struct amdgpu_device *adev)
{
uint32_t bios_2_scratch, bios_6_scratch;
- bios_2_scratch = RREG32(mmBIOS_SCRATCH_2);
- bios_6_scratch = RREG32(mmBIOS_SCRATCH_6);
+ adev->bios_scratch_reg_offset = mmBIOS_SCRATCH_0;
+
+ bios_2_scratch = RREG32(adev->bios_scratch_reg_offset + 2);
+ bios_6_scratch = RREG32(adev->bios_scratch_reg_offset + 6);
/* let the bios control the backlight */
bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE;
@@ -1715,8 +1717,8 @@ void amdgpu_atombios_scratch_regs_init(struct amdgpu_device *adev)
/* clear the vbios dpms state */
bios_2_scratch &= ~ATOM_S2_DEVICE_DPMS_STATE;
- WREG32(mmBIOS_SCRATCH_2, bios_2_scratch);
- WREG32(mmBIOS_SCRATCH_6, bios_6_scratch);
+ WREG32(adev->bios_scratch_reg_offset + 2, bios_2_scratch);
+ WREG32(adev->bios_scratch_reg_offset + 6, bios_6_scratch);
}
void amdgpu_atombios_scratch_regs_save(struct amdgpu_device *adev)
@@ -1724,7 +1726,7 @@ void amdgpu_atombios_scratch_regs_save(struct amdgpu_device *adev)
int i;
for (i = 0; i < AMDGPU_BIOS_NUM_SCRATCH; i++)
- adev->bios_scratch[i] = RREG32(mmBIOS_SCRATCH_0 + i);
+ adev->bios_scratch[i] = RREG32(adev->bios_scratch_reg_offset + i);
}
void amdgpu_atombios_scratch_regs_restore(struct amdgpu_device *adev)
@@ -1738,20 +1740,30 @@ void amdgpu_atombios_scratch_regs_restore(struct amdgpu_device *adev)
adev->bios_scratch[7] &= ~ATOM_S7_ASIC_INIT_COMPLETE_MASK;
for (i = 0; i < AMDGPU_BIOS_NUM_SCRATCH; i++)
- WREG32(mmBIOS_SCRATCH_0 + i, adev->bios_scratch[i]);
+ WREG32(adev->bios_scratch_reg_offset + i, adev->bios_scratch[i]);
}
void amdgpu_atombios_scratch_regs_engine_hung(struct amdgpu_device *adev,
bool hung)
{
- u32 tmp = RREG32(mmBIOS_SCRATCH_3);
+ u32 tmp = RREG32(adev->bios_scratch_reg_offset + 3);
if (hung)
tmp |= ATOM_S3_ASIC_GUI_ENGINE_HUNG;
else
tmp &= ~ATOM_S3_ASIC_GUI_ENGINE_HUNG;
- WREG32(mmBIOS_SCRATCH_3, tmp);
+ WREG32(adev->bios_scratch_reg_offset + 3, tmp);
+}
+
+bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev)
+{
+ u32 tmp = RREG32(adev->bios_scratch_reg_offset + 7);
+
+ if (tmp & ATOM_S7_ASIC_INIT_COMPLETE_MASK)
+ return false;
+ else
+ return true;
}
/* Atom needs data in little endian format
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
index 38d0fe32e5cd..b0d5d1d7fdba 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h
@@ -200,6 +200,7 @@ void amdgpu_atombios_scratch_regs_save(struct amdgpu_device *adev);
void amdgpu_atombios_scratch_regs_restore(struct amdgpu_device *adev);
void amdgpu_atombios_scratch_regs_engine_hung(struct amdgpu_device *adev,
bool hung);
+bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev);
void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le);
int amdgpu_atombios_get_max_vddc(struct amdgpu_device *adev, u8 voltage_type,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
index 4bdda56fccee..f9ffe8ef0cd6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
@@ -66,41 +66,6 @@ void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev)
}
}
-void amdgpu_atomfirmware_scratch_regs_save(struct amdgpu_device *adev)
-{
- int i;
-
- for (i = 0; i < AMDGPU_BIOS_NUM_SCRATCH; i++)
- adev->bios_scratch[i] = RREG32(adev->bios_scratch_reg_offset + i);
-}
-
-void amdgpu_atomfirmware_scratch_regs_restore(struct amdgpu_device *adev)
-{
- int i;
-
- /*
- * VBIOS will check ASIC_INIT_COMPLETE bit to decide if
- * execute ASIC_Init posting via driver
- */
- adev->bios_scratch[7] &= ~ATOM_S7_ASIC_INIT_COMPLETE_MASK;
-
- for (i = 0; i < AMDGPU_BIOS_NUM_SCRATCH; i++)
- WREG32(adev->bios_scratch_reg_offset + i, adev->bios_scratch[i]);
-}
-
-void amdgpu_atomfirmware_scratch_regs_engine_hung(struct amdgpu_device *adev,
- bool hung)
-{
- u32 tmp = RREG32(adev->bios_scratch_reg_offset + 3);
-
- if (hung)
- tmp |= ATOM_S3_ASIC_GUI_ENGINE_HUNG;
- else
- tmp &= ~ATOM_S3_ASIC_GUI_ENGINE_HUNG;
-
- WREG32(adev->bios_scratch_reg_offset + 3, tmp);
-}
-
int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)
{
struct atom_context *ctx = adev->mode_info.atom_context;
@@ -130,3 +95,129 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)
ctx->scratch_size_bytes = usage_bytes;
return 0;
}
+
+union igp_info {
+ struct atom_integrated_system_info_v1_11 v11;
+};
+
+/*
+ * Return vram width from integrated system info table, if available,
+ * or 0 if not.
+ */
+int amdgpu_atomfirmware_get_vram_width(struct amdgpu_device *adev)
+{
+ struct amdgpu_mode_info *mode_info = &adev->mode_info;
+ int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
+ integratedsysteminfo);
+ u16 data_offset, size;
+ union igp_info *igp_info;
+ u8 frev, crev;
+
+ /* get any igp specific overrides */
+ if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, &size,
+ &frev, &crev, &data_offset)) {
+ igp_info = (union igp_info *)
+ (mode_info->atom_context->bios + data_offset);
+ switch (crev) {
+ case 11:
+ return igp_info->v11.umachannelnumber * 64;
+ default:
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+union firmware_info {
+ struct atom_firmware_info_v3_1 v31;
+};
+
+union smu_info {
+ struct atom_smu_info_v3_1 v31;
+};
+
+union umc_info {
+ struct atom_umc_info_v3_1 v31;
+};
+
+int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev)
+{
+ struct amdgpu_mode_info *mode_info = &adev->mode_info;
+ struct amdgpu_pll *spll = &adev->clock.spll;
+ struct amdgpu_pll *mpll = &adev->clock.mpll;
+ uint8_t frev, crev;
+ uint16_t data_offset;
+ int ret = -EINVAL, index;
+
+ index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
+ firmwareinfo);
+ if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
+ &frev, &crev, &data_offset)) {
+ union firmware_info *firmware_info =
+ (union firmware_info *)(mode_info->atom_context->bios +
+ data_offset);
+
+ adev->clock.default_sclk =
+ le32_to_cpu(firmware_info->v31.bootup_sclk_in10khz);
+ adev->clock.default_mclk =
+ le32_to_cpu(firmware_info->v31.bootup_mclk_in10khz);
+
+ adev->pm.current_sclk = adev->clock.default_sclk;
+ adev->pm.current_mclk = adev->clock.default_mclk;
+
+ /* not technically a clock, but... */
+ adev->mode_info.firmware_flags =
+ le32_to_cpu(firmware_info->v31.firmware_capability);
+
+ ret = 0;
+ }
+
+ index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
+ smu_info);
+ if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
+ &frev, &crev, &data_offset)) {
+ union smu_info *smu_info =
+ (union smu_info *)(mode_info->atom_context->bios +
+ data_offset);
+
+ /* system clock */
+ spll->reference_freq = le32_to_cpu(smu_info->v31.core_refclk_10khz);
+
+ spll->reference_div = 0;
+ spll->min_post_div = 1;
+ spll->max_post_div = 1;
+ spll->min_ref_div = 2;
+ spll->max_ref_div = 0xff;
+ spll->min_feedback_div = 4;
+ spll->max_feedback_div = 0xff;
+ spll->best_vco = 0;
+
+ ret = 0;
+ }
+
+ index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
+ umc_info);
+ if (amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
+ &frev, &crev, &data_offset)) {
+ union umc_info *umc_info =
+ (union umc_info *)(mode_info->atom_context->bios +
+ data_offset);
+
+ /* memory clock */
+ mpll->reference_freq = le32_to_cpu(umc_info->v31.mem_refclk_10khz);
+
+ mpll->reference_div = 0;
+ mpll->min_post_div = 1;
+ mpll->max_post_div = 1;
+ mpll->min_ref_div = 2;
+ mpll->max_ref_div = 0xff;
+ mpll->min_feedback_div = 4;
+ mpll->max_feedback_div = 0xff;
+ mpll->best_vco = 0;
+
+ ret = 0;
+ }
+
+ return ret;
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
index a2c3ebe22c71..288b97e54347 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.h
@@ -26,10 +26,8 @@
bool amdgpu_atomfirmware_gpu_supports_virtualization(struct amdgpu_device *adev);
void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev);
-void amdgpu_atomfirmware_scratch_regs_save(struct amdgpu_device *adev);
-void amdgpu_atomfirmware_scratch_regs_restore(struct amdgpu_device *adev);
-void amdgpu_atomfirmware_scratch_regs_engine_hung(struct amdgpu_device *adev,
- bool hung);
int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev);
+int amdgpu_atomfirmware_get_vram_width(struct amdgpu_device *adev);
+int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
index 1beae5b930d0..63ec1e1bb6aa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_benchmark.c
@@ -40,7 +40,7 @@ static int amdgpu_benchmark_do_move(struct amdgpu_device *adev, unsigned size,
for (i = 0; i < n; i++) {
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
r = amdgpu_copy_buffer(ring, saddr, daddr, size, NULL, &fence,
- false);
+ false, false);
if (r)
goto exit_do_move;
r = dma_fence_wait(fence, false);
@@ -81,7 +81,7 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size,
n = AMDGPU_BENCHMARK_ITERATIONS;
r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, sdomain, 0, NULL,
- NULL, &sobj);
+ NULL, 0, &sobj);
if (r) {
goto out_cleanup;
}
@@ -94,7 +94,7 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size,
goto out_cleanup;
}
r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, ddomain, 0, NULL,
- NULL, &dobj);
+ NULL, 0, &dobj);
if (r) {
goto out_cleanup;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
index 365e735f6647..c21adf60a7f2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
@@ -86,19 +86,6 @@ static bool check_atom_bios(uint8_t *bios, size_t size)
return false;
}
-static bool is_atom_fw(uint8_t *bios)
-{
- uint16_t bios_header_start = bios[0x48] | (bios[0x49] << 8);
- uint8_t frev = bios[bios_header_start + 2];
- uint8_t crev = bios[bios_header_start + 3];
-
- if ((frev < 3) ||
- ((frev == 3) && (crev < 3)))
- return false;
-
- return true;
-}
-
/* If you boot an IGP board with a discrete card as the primary,
* the IGP rom is not accessible via the rom bar as the IGP rom is
* part of the system bios. On boot, the system bios puts a
@@ -117,7 +104,7 @@ static bool igp_read_bios_from_vram(struct amdgpu_device *adev)
adev->bios = NULL;
vram_base = pci_resource_start(adev->pdev, 0);
- bios = ioremap(vram_base, size);
+ bios = ioremap_wc(vram_base, size);
if (!bios) {
return false;
}
@@ -455,6 +442,6 @@ bool amdgpu_get_bios(struct amdgpu_device *adev)
return false;
success:
- adev->is_atom_fw = is_atom_fw(adev->bios);
+ adev->is_atom_fw = (adev->asic_type >= CHIP_VEGA10) ? true : false;
return true;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
index f621ee115c98..59089e027f4d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
@@ -83,7 +83,7 @@ static int amdgpu_bo_list_create(struct amdgpu_device *adev,
r = idr_alloc(&fpriv->bo_list_handles, list, 1, 0, GFP_KERNEL);
mutex_unlock(&fpriv->bo_list_lock);
if (r < 0) {
- kfree(list);
+ amdgpu_bo_list_free(list);
return r;
}
*id = r;
@@ -136,7 +136,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
}
bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj));
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm);
if (usermm) {
@@ -156,11 +156,11 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
entry->tv.bo = &entry->robj->tbo;
entry->tv.shared = !entry->robj->prime_shared_count;
- if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_GDS)
+ if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GDS)
gds_obj = entry->robj;
- if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_GWS)
+ if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GWS)
gws_obj = entry->robj;
- if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_OA)
+ if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_OA)
oa_obj = entry->robj;
total_size += amdgpu_bo_size(entry->robj);
@@ -198,12 +198,16 @@ amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id)
result = idr_find(&fpriv->bo_list_handles, id);
if (result) {
- if (kref_get_unless_zero(&result->refcount))
+ if (kref_get_unless_zero(&result->refcount)) {
+ rcu_read_unlock();
mutex_lock(&result->lock);
- else
+ } else {
+ rcu_read_unlock();
result = NULL;
+ }
+ } else {
+ rcu_read_unlock();
}
- rcu_read_unlock();
return result;
}
@@ -266,7 +270,7 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data,
struct amdgpu_fpriv *fpriv = filp->driver_priv;
union drm_amdgpu_bo_list *args = data;
uint32_t handle = args->in.list_handle;
- const void __user *uptr = (const void*)(uintptr_t)args->in.bo_info_ptr;
+ const void __user *uptr = u64_to_user_ptr(args->in.bo_info_ptr);
struct drm_amdgpu_bo_list_entry *info;
struct amdgpu_bo_list *list;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
index c0a806280257..fd435a96481c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
@@ -124,7 +124,7 @@ static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device,
ret = amdgpu_bo_create_restricted(adev, size, PAGE_SIZE,
true, domain, flags,
NULL, &placement, NULL,
- &obj);
+ 0, &obj);
if (ret) {
DRM_ERROR("(%d) bo create failed\n", ret);
return ret;
@@ -166,7 +166,7 @@ static int amdgpu_cgs_gmap_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t h
r = amdgpu_bo_reserve(obj, true);
if (unlikely(r != 0))
return r;
- r = amdgpu_bo_pin_restricted(obj, obj->prefered_domains,
+ r = amdgpu_bo_pin_restricted(obj, obj->preferred_domains,
min_offset, max_offset, mcaddr);
amdgpu_bo_unreserve(obj);
return r;
@@ -240,6 +240,8 @@ static uint32_t amdgpu_cgs_read_ind_register(struct cgs_device *cgs_device,
return RREG32_DIDT(index);
case CGS_IND_REG_GC_CAC:
return RREG32_GC_CAC(index);
+ case CGS_IND_REG_SE_CAC:
+ return RREG32_SE_CAC(index);
case CGS_IND_REG__AUDIO_ENDPT:
DRM_ERROR("audio endpt register access not implemented.\n");
return 0;
@@ -266,6 +268,8 @@ static void amdgpu_cgs_write_ind_register(struct cgs_device *cgs_device,
return WREG32_DIDT(index, value);
case CGS_IND_REG_GC_CAC:
return WREG32_GC_CAC(index, value);
+ case CGS_IND_REG_SE_CAC:
+ return WREG32_SE_CAC(index, value);
case CGS_IND_REG__AUDIO_ENDPT:
DRM_ERROR("audio endpt register access not implemented.\n");
return;
@@ -610,6 +614,17 @@ static int amdgpu_cgs_enter_safe_mode(struct cgs_device *cgs_device,
return 0;
}
+static void amdgpu_cgs_lock_grbm_idx(struct cgs_device *cgs_device,
+ bool lock)
+{
+ CGS_FUNC_ADEV;
+
+ if (lock)
+ mutex_lock(&adev->grbm_idx_mutex);
+ else
+ mutex_unlock(&adev->grbm_idx_mutex);
+}
+
static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
enum cgs_ucode_id type,
struct cgs_firmware_info *info)
@@ -644,7 +659,7 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
info->version = (uint16_t)le32_to_cpu(header->header.ucode_version);
if (CGS_UCODE_ID_CP_MEC == type)
- info->image_size = (header->jt_offset) << 2;
+ info->image_size = le32_to_cpu(header->jt_offset) << 2;
info->fw_version = amdgpu_get_firmware_version(cgs_device, type);
info->feature_version = (uint16_t)le32_to_cpu(header->ucode_feature_version);
@@ -719,7 +734,13 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
strcpy(fw_name, "amdgpu/polaris12_smc.bin");
break;
case CHIP_VEGA10:
- strcpy(fw_name, "amdgpu/vega10_smc.bin");
+ if ((adev->pdev->device == 0x687f) &&
+ ((adev->pdev->revision == 0xc0) ||
+ (adev->pdev->revision == 0xc1) ||
+ (adev->pdev->revision == 0xc3)))
+ strcpy(fw_name, "amdgpu/vega10_acg_smc.bin");
+ else
+ strcpy(fw_name, "amdgpu/vega10_smc.bin");
break;
default:
DRM_ERROR("SMC firmware not supported\n");
@@ -1117,6 +1138,7 @@ static const struct cgs_ops amdgpu_cgs_ops = {
.query_system_info = amdgpu_cgs_query_system_info,
.is_virtualization_enabled = amdgpu_cgs_is_virtualization_enabled,
.enter_safe_mode = amdgpu_cgs_enter_safe_mode,
+ .lock_grbm_idx = amdgpu_cgs_lock_grbm_idx,
};
static const struct cgs_os_ops amdgpu_cgs_os_ops = {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 5599c01b265d..15d4a28d73bb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -54,7 +54,7 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p,
*offset = data->offset;
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (amdgpu_ttm_tt_get_usermm(p->uf_entry.robj->tbo.ttm)) {
amdgpu_bo_unref(&p->uf_entry.robj);
@@ -90,7 +90,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
}
/* get chunks */
- chunk_array_user = (uint64_t __user *)(uintptr_t)(cs->in.chunks);
+ chunk_array_user = u64_to_user_ptr(cs->in.chunks);
if (copy_from_user(chunk_array, chunk_array_user,
sizeof(uint64_t)*cs->in.num_chunks)) {
ret = -EFAULT;
@@ -110,7 +110,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
struct drm_amdgpu_cs_chunk user_chunk;
uint32_t __user *cdata;
- chunk_ptr = (void __user *)(uintptr_t)chunk_array[i];
+ chunk_ptr = u64_to_user_ptr(chunk_array[i]);
if (copy_from_user(&user_chunk, chunk_ptr,
sizeof(struct drm_amdgpu_cs_chunk))) {
ret = -EFAULT;
@@ -121,7 +121,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
p->chunks[i].length_dw = user_chunk.length_dw;
size = p->chunks[i].length_dw;
- cdata = (void __user *)(uintptr_t)user_chunk.chunk_data;
+ cdata = u64_to_user_ptr(user_chunk.chunk_data);
p->chunks[i].kdata = kvmalloc_array(size, sizeof(uint32_t), GFP_KERNEL);
if (p->chunks[i].kdata == NULL) {
@@ -223,10 +223,11 @@ static s64 bytes_to_us(struct amdgpu_device *adev, u64 bytes)
* ticks. The accumulated microseconds (us) are converted to bytes and
* returned.
*/
-static u64 amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev)
+static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev,
+ u64 *max_bytes,
+ u64 *max_vis_bytes)
{
s64 time_us, increment_us;
- u64 max_bytes;
u64 free_vram, total_vram, used_vram;
/* Allow a maximum of 200 accumulated ms. This is basically per-IB
@@ -238,11 +239,14 @@ static u64 amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev)
*/
const s64 us_upper_bound = 200000;
- if (!adev->mm_stats.log2_max_MBps)
- return 0;
+ if (!adev->mm_stats.log2_max_MBps) {
+ *max_bytes = 0;
+ *max_vis_bytes = 0;
+ return;
+ }
total_vram = adev->mc.real_vram_size - adev->vram_pin_size;
- used_vram = atomic64_read(&adev->vram_usage);
+ used_vram = amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
free_vram = used_vram >= total_vram ? 0 : total_vram - used_vram;
spin_lock(&adev->mm_stats.lock);
@@ -280,23 +284,46 @@ static u64 amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev)
adev->mm_stats.accum_us = max(min_us, adev->mm_stats.accum_us);
}
- /* This returns 0 if the driver is in debt to disallow (optional)
+ /* This is set to 0 if the driver is in debt to disallow (optional)
* buffer moves.
*/
- max_bytes = us_to_bytes(adev, adev->mm_stats.accum_us);
+ *max_bytes = us_to_bytes(adev, adev->mm_stats.accum_us);
+
+ /* Do the same for visible VRAM if half of it is free */
+ if (adev->mc.visible_vram_size < adev->mc.real_vram_size) {
+ u64 total_vis_vram = adev->mc.visible_vram_size;
+ u64 used_vis_vram =
+ amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
+
+ if (used_vis_vram < total_vis_vram) {
+ u64 free_vis_vram = total_vis_vram - used_vis_vram;
+ adev->mm_stats.accum_us_vis = min(adev->mm_stats.accum_us_vis +
+ increment_us, us_upper_bound);
+
+ if (free_vis_vram >= total_vis_vram / 2)
+ adev->mm_stats.accum_us_vis =
+ max(bytes_to_us(adev, free_vis_vram / 2),
+ adev->mm_stats.accum_us_vis);
+ }
+
+ *max_vis_bytes = us_to_bytes(adev, adev->mm_stats.accum_us_vis);
+ } else {
+ *max_vis_bytes = 0;
+ }
spin_unlock(&adev->mm_stats.lock);
- return max_bytes;
}
/* Report how many bytes have really been moved for the last command
* submission. This can result in a debt that can stop buffer migrations
* temporarily.
*/
-void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes)
+void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes,
+ u64 num_vis_bytes)
{
spin_lock(&adev->mm_stats.lock);
adev->mm_stats.accum_us -= bytes_to_us(adev, num_bytes);
+ adev->mm_stats.accum_us_vis -= bytes_to_us(adev, num_vis_bytes);
spin_unlock(&adev->mm_stats.lock);
}
@@ -304,7 +331,7 @@ static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p,
struct amdgpu_bo *bo)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
- u64 initial_bytes_moved;
+ u64 initial_bytes_moved, bytes_moved;
uint32_t domain;
int r;
@@ -314,17 +341,35 @@ static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p,
/* Don't move this buffer if we have depleted our allowance
* to move it. Don't move anything if the threshold is zero.
*/
- if (p->bytes_moved < p->bytes_moved_threshold)
- domain = bo->prefered_domains;
- else
+ if (p->bytes_moved < p->bytes_moved_threshold) {
+ if (adev->mc.visible_vram_size < adev->mc.real_vram_size &&
+ (bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)) {
+ /* And don't move a CPU_ACCESS_REQUIRED BO to limited
+ * visible VRAM if we've depleted our allowance to do
+ * that.
+ */
+ if (p->bytes_moved_vis < p->bytes_moved_vis_threshold)
+ domain = bo->preferred_domains;
+ else
+ domain = bo->allowed_domains;
+ } else {
+ domain = bo->preferred_domains;
+ }
+ } else {
domain = bo->allowed_domains;
+ }
retry:
amdgpu_ttm_placement_from_domain(bo, domain);
initial_bytes_moved = atomic64_read(&adev->num_bytes_moved);
r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
- p->bytes_moved += atomic64_read(&adev->num_bytes_moved) -
- initial_bytes_moved;
+ bytes_moved = atomic64_read(&adev->num_bytes_moved) -
+ initial_bytes_moved;
+ p->bytes_moved += bytes_moved;
+ if (adev->mc.visible_vram_size < adev->mc.real_vram_size &&
+ bo->tbo.mem.mem_type == TTM_PL_VRAM &&
+ bo->tbo.mem.start < adev->mc.visible_vram_size >> PAGE_SHIFT)
+ p->bytes_moved_vis += bytes_moved;
if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) {
domain = bo->allowed_domains;
@@ -350,7 +395,8 @@ static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
struct amdgpu_bo_list_entry *candidate = p->evictable;
struct amdgpu_bo *bo = candidate->robj;
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
- u64 initial_bytes_moved;
+ u64 initial_bytes_moved, bytes_moved;
+ bool update_bytes_moved_vis;
uint32_t other;
/* If we reached our current BO we can forget it */
@@ -370,10 +416,17 @@ static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
/* Good we can try to move this BO somewhere else */
amdgpu_ttm_placement_from_domain(bo, other);
+ update_bytes_moved_vis =
+ adev->mc.visible_vram_size < adev->mc.real_vram_size &&
+ bo->tbo.mem.mem_type == TTM_PL_VRAM &&
+ bo->tbo.mem.start < adev->mc.visible_vram_size >> PAGE_SHIFT;
initial_bytes_moved = atomic64_read(&adev->num_bytes_moved);
r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
- p->bytes_moved += atomic64_read(&adev->num_bytes_moved) -
+ bytes_moved = atomic64_read(&adev->num_bytes_moved) -
initial_bytes_moved;
+ p->bytes_moved += bytes_moved;
+ if (update_bytes_moved_vis)
+ p->bytes_moved_vis += bytes_moved;
if (unlikely(r))
break;
@@ -554,8 +607,10 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
list_splice(&need_pages, &p->validated);
}
- p->bytes_moved_threshold = amdgpu_cs_get_threshold_for_moves(p->adev);
+ amdgpu_cs_get_threshold_for_moves(p->adev, &p->bytes_moved_threshold,
+ &p->bytes_moved_vis_threshold);
p->bytes_moved = 0;
+ p->bytes_moved_vis = 0;
p->evictable = list_last_entry(&p->validated,
struct amdgpu_bo_list_entry,
tv.head);
@@ -579,8 +634,8 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
goto error_validate;
}
- amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved);
-
+ amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved,
+ p->bytes_moved_vis);
fpriv->vm.last_eviction_counter =
atomic64_read(&p->adev->num_evictions);
@@ -619,10 +674,8 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
}
error_validate:
- if (r) {
- amdgpu_vm_move_pt_bos_in_lru(p->adev, &fpriv->vm);
+ if (r)
ttm_eu_backoff_reservation(&p->ticket, &p->validated);
- }
error_free_pages:
@@ -670,21 +723,18 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p)
* If error is set than unvalidate buffer, otherwise just free memory
* used by parsing context.
**/
-static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bool backoff)
+static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error,
+ bool backoff)
{
- struct amdgpu_fpriv *fpriv = parser->filp->driver_priv;
unsigned i;
- if (!error) {
- amdgpu_vm_move_pt_bos_in_lru(parser->adev, &fpriv->vm);
-
+ if (!error)
ttm_eu_fence_buffer_objects(&parser->ticket,
&parser->validated,
parser->fence);
- } else if (backoff) {
+ else if (backoff)
ttm_eu_backoff_reservation(&parser->ticket,
&parser->validated);
- }
for (i = 0; i < parser->num_post_dep_syncobjs; i++)
drm_syncobj_put(parser->post_dep_syncobjs[i]);
@@ -737,7 +787,8 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
if (amdgpu_sriov_vf(adev)) {
struct dma_fence *f;
- bo_va = vm->csa_bo_va;
+
+ bo_va = fpriv->csa_va;
BUG_ON(!bo_va);
r = amdgpu_vm_bo_update(adev, bo_va, false);
if (r)
@@ -774,7 +825,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
}
- r = amdgpu_vm_clear_invalids(adev, vm, &p->job->sync);
+ r = amdgpu_vm_clear_moved(adev, vm, &p->job->sync);
if (amdgpu_vm_debug && p->bo_list) {
/* Invalidate all BOs to test for userspace bugs */
@@ -1383,7 +1434,7 @@ int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data,
if (fences == NULL)
return -ENOMEM;
- fences_user = (void __user *)(uintptr_t)(wait->in.fences);
+ fences_user = u64_to_user_ptr(wait->in.fences);
if (copy_from_user(fences, fences_user,
sizeof(struct drm_amdgpu_fence) * fence_count)) {
r = -EFAULT;
@@ -1436,7 +1487,7 @@ amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
addr > mapping->last)
continue;
- *bo = lobj->bo_va->bo;
+ *bo = lobj->bo_va->base.bo;
return mapping;
}
@@ -1445,7 +1496,7 @@ amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
addr > mapping->last)
continue;
- *bo = lobj->bo_va->bo;
+ *bo = lobj->bo_va->base.bo;
return mapping;
}
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 4a8fc15467cf..1a459ac63df4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -53,6 +53,9 @@
#include "bif/bif_4_1_d.h"
#include <linux/pci.h>
#include <linux/firmware.h>
+#include "amdgpu_vf_error.h"
+
+#include "amdgpu_amdkfd.h"
MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin");
@@ -128,6 +131,10 @@ void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
{
trace_amdgpu_mm_wreg(adev->pdev->device, reg, v);
+ if (adev->asic_type >= CHIP_VEGA10 && reg == 0) {
+ adev->last_mm_index = v;
+ }
+
if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)) {
BUG_ON(in_interrupt());
return amdgpu_virt_kiq_wreg(adev, reg, v);
@@ -143,6 +150,10 @@ void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
writel(v, ((void __iomem *)adev->rmmio) + (mmMM_DATA * 4));
spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
}
+
+ if (adev->asic_type >= CHIP_VEGA10 && reg == 1 && adev->last_mm_index == 0x5702C) {
+ udelay(500);
+ }
}
u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg)
@@ -157,6 +168,9 @@ u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg)
void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
{
+ if (adev->asic_type >= CHIP_VEGA10 && reg == 0) {
+ adev->last_mm_index = v;
+ }
if ((reg * 4) < adev->rio_mem_size)
iowrite32(v, adev->rio_mem + (reg * 4));
@@ -164,6 +178,10 @@ void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
iowrite32((reg * 4), adev->rio_mem + (mmMM_INDEX * 4));
iowrite32(v, adev->rio_mem + (mmMM_DATA * 4));
}
+
+ if (adev->asic_type >= CHIP_VEGA10 && reg == 1 && adev->last_mm_index == 0x5702C) {
+ udelay(500);
+ }
}
/**
@@ -318,51 +336,16 @@ static void amdgpu_block_invalid_wreg(struct amdgpu_device *adev,
static int amdgpu_vram_scratch_init(struct amdgpu_device *adev)
{
- int r;
-
- if (adev->vram_scratch.robj == NULL) {
- r = amdgpu_bo_create(adev, AMDGPU_GPU_PAGE_SIZE,
- PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, &adev->vram_scratch.robj);
- if (r) {
- return r;
- }
- }
-
- r = amdgpu_bo_reserve(adev->vram_scratch.robj, false);
- if (unlikely(r != 0))
- return r;
- r = amdgpu_bo_pin(adev->vram_scratch.robj,
- AMDGPU_GEM_DOMAIN_VRAM, &adev->vram_scratch.gpu_addr);
- if (r) {
- amdgpu_bo_unreserve(adev->vram_scratch.robj);
- return r;
- }
- r = amdgpu_bo_kmap(adev->vram_scratch.robj,
- (void **)&adev->vram_scratch.ptr);
- if (r)
- amdgpu_bo_unpin(adev->vram_scratch.robj);
- amdgpu_bo_unreserve(adev->vram_scratch.robj);
-
- return r;
+ return amdgpu_bo_create_kernel(adev, AMDGPU_GPU_PAGE_SIZE,
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->vram_scratch.robj,
+ &adev->vram_scratch.gpu_addr,
+ (void **)&adev->vram_scratch.ptr);
}
static void amdgpu_vram_scratch_fini(struct amdgpu_device *adev)
{
- int r;
-
- if (adev->vram_scratch.robj == NULL) {
- return;
- }
- r = amdgpu_bo_reserve(adev->vram_scratch.robj, true);
- if (likely(r == 0)) {
- amdgpu_bo_kunmap(adev->vram_scratch.robj);
- amdgpu_bo_unpin(adev->vram_scratch.robj);
- amdgpu_bo_unreserve(adev->vram_scratch.robj);
- }
- amdgpu_bo_unref(&adev->vram_scratch.robj);
+ amdgpu_bo_free_kernel(&adev->vram_scratch.robj, NULL, NULL);
}
/**
@@ -521,7 +504,8 @@ static int amdgpu_wb_init(struct amdgpu_device *adev)
int r;
if (adev->wb.wb_obj == NULL) {
- r = amdgpu_bo_create_kernel(adev, AMDGPU_MAX_WB * sizeof(uint32_t),
+ /* AMDGPU_MAX_WB * sizeof(uint32_t) * 8 = AMDGPU_MAX_WB 256bit slots */
+ r = amdgpu_bo_create_kernel(adev, AMDGPU_MAX_WB * sizeof(uint32_t) * 8,
PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
&adev->wb.wb_obj, &adev->wb.gpu_addr,
(void **)&adev->wb.wb);
@@ -552,32 +536,10 @@ static int amdgpu_wb_init(struct amdgpu_device *adev)
int amdgpu_wb_get(struct amdgpu_device *adev, u32 *wb)
{
unsigned long offset = find_first_zero_bit(adev->wb.used, adev->wb.num_wb);
- if (offset < adev->wb.num_wb) {
- __set_bit(offset, adev->wb.used);
- *wb = offset;
- return 0;
- } else {
- return -EINVAL;
- }
-}
-/**
- * amdgpu_wb_get_64bit - Allocate a wb entry
- *
- * @adev: amdgpu_device pointer
- * @wb: wb index
- *
- * Allocate a wb slot for use by the driver (all asics).
- * Returns 0 on success or -EINVAL on failure.
- */
-int amdgpu_wb_get_64bit(struct amdgpu_device *adev, u32 *wb)
-{
- unsigned long offset = bitmap_find_next_zero_area_off(adev->wb.used,
- adev->wb.num_wb, 0, 2, 7, 0);
- if ((offset + 1) < adev->wb.num_wb) {
+ if (offset < adev->wb.num_wb) {
__set_bit(offset, adev->wb.used);
- __set_bit(offset + 1, adev->wb.used);
- *wb = offset;
+ *wb = offset * 8; /* convert to dw offset */
return 0;
} else {
return -EINVAL;
@@ -599,22 +561,6 @@ void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb)
}
/**
- * amdgpu_wb_free_64bit - Free a wb entry
- *
- * @adev: amdgpu_device pointer
- * @wb: wb index
- *
- * Free a wb slot allocated for use by the driver (all asics)
- */
-void amdgpu_wb_free_64bit(struct amdgpu_device *adev, u32 wb)
-{
- if ((wb + 1) < adev->wb.num_wb) {
- __clear_bit(wb, adev->wb.used);
- __clear_bit(wb + 1, adev->wb.used);
- }
-}
-
-/**
* amdgpu_vram_location - try to find VRAM location
* @adev: amdgpu device structure holding all necessary informations
* @mc: memory controller structure holding memory informations
@@ -665,7 +611,7 @@ void amdgpu_vram_location(struct amdgpu_device *adev, struct amdgpu_mc *mc, u64
}
/**
- * amdgpu_gtt_location - try to find GTT location
+ * amdgpu_gart_location - try to find GTT location
* @adev: amdgpu device structure holding all necessary informations
* @mc: memory controller structure holding memory informations
*
@@ -676,28 +622,28 @@ void amdgpu_vram_location(struct amdgpu_device *adev, struct amdgpu_mc *mc, u64
*
* FIXME: when reducing GTT size align new size on power of 2.
*/
-void amdgpu_gtt_location(struct amdgpu_device *adev, struct amdgpu_mc *mc)
+void amdgpu_gart_location(struct amdgpu_device *adev, struct amdgpu_mc *mc)
{
u64 size_af, size_bf;
- size_af = ((adev->mc.mc_mask - mc->vram_end) + mc->gtt_base_align) & ~mc->gtt_base_align;
- size_bf = mc->vram_start & ~mc->gtt_base_align;
+ size_af = adev->mc.mc_mask - mc->vram_end;
+ size_bf = mc->vram_start;
if (size_bf > size_af) {
- if (mc->gtt_size > size_bf) {
+ if (mc->gart_size > size_bf) {
dev_warn(adev->dev, "limiting GTT\n");
- mc->gtt_size = size_bf;
+ mc->gart_size = size_bf;
}
- mc->gtt_start = 0;
+ mc->gart_start = 0;
} else {
- if (mc->gtt_size > size_af) {
+ if (mc->gart_size > size_af) {
dev_warn(adev->dev, "limiting GTT\n");
- mc->gtt_size = size_af;
+ mc->gart_size = size_af;
}
- mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align;
+ mc->gart_start = mc->vram_end + 1;
}
- mc->gtt_end = mc->gtt_start + mc->gtt_size - 1;
+ mc->gart_end = mc->gart_start + mc->gart_size - 1;
dev_info(adev->dev, "GTT: %lluM 0x%016llX - 0x%016llX\n",
- mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end);
+ mc->gart_size >> 20, mc->gart_start, mc->gart_end);
}
/*
@@ -720,7 +666,12 @@ bool amdgpu_need_post(struct amdgpu_device *adev)
adev->has_hw_reset = false;
return true;
}
- /* then check MEM_SIZE, in case the crtcs are off */
+
+ /* bios scratch used on CIK+ */
+ if (adev->asic_type >= CHIP_BONAIRE)
+ return amdgpu_atombios_scratch_need_asic_init(adev);
+
+ /* check MEM_SIZE for older asics */
reg = amdgpu_asic_get_config_memsize(adev);
if ((reg != 0) && (reg != 0xffffffff))
@@ -1031,19 +982,6 @@ static unsigned int amdgpu_vga_set_decode(void *cookie, bool state)
return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
}
-/**
- * amdgpu_check_pot_argument - check that argument is a power of two
- *
- * @arg: value to check
- *
- * Validates that a certain argument is a power of two (all asics).
- * Returns true if argument is valid.
- */
-static bool amdgpu_check_pot_argument(int arg)
-{
- return (arg & (arg - 1)) == 0;
-}
-
static void amdgpu_check_block_size(struct amdgpu_device *adev)
{
/* defines number of bits in page table versus page directory,
@@ -1077,7 +1015,7 @@ static void amdgpu_check_vm_size(struct amdgpu_device *adev)
if (amdgpu_vm_size == -1)
return;
- if (!amdgpu_check_pot_argument(amdgpu_vm_size)) {
+ if (!is_power_of_2(amdgpu_vm_size)) {
dev_warn(adev->dev, "VM size (%d) must be a power of 2\n",
amdgpu_vm_size);
goto def_value;
@@ -1118,19 +1056,31 @@ static void amdgpu_check_arguments(struct amdgpu_device *adev)
dev_warn(adev->dev, "sched jobs (%d) must be at least 4\n",
amdgpu_sched_jobs);
amdgpu_sched_jobs = 4;
- } else if (!amdgpu_check_pot_argument(amdgpu_sched_jobs)){
+ } else if (!is_power_of_2(amdgpu_sched_jobs)){
dev_warn(adev->dev, "sched jobs (%d) must be a power of 2\n",
amdgpu_sched_jobs);
amdgpu_sched_jobs = roundup_pow_of_two(amdgpu_sched_jobs);
}
- if (amdgpu_gart_size != -1) {
+ if (amdgpu_gart_size < 32) {
+ /* gart size must be greater or equal to 32M */
+ dev_warn(adev->dev, "gart size (%d) too small\n",
+ amdgpu_gart_size);
+ amdgpu_gart_size = 32;
+ }
+
+ if (amdgpu_gtt_size != -1 && amdgpu_gtt_size < 32) {
/* gtt size must be greater or equal to 32M */
- if (amdgpu_gart_size < 32) {
- dev_warn(adev->dev, "gart size (%d) too small\n",
- amdgpu_gart_size);
- amdgpu_gart_size = -1;
- }
+ dev_warn(adev->dev, "gtt size (%d) too small\n",
+ amdgpu_gtt_size);
+ amdgpu_gtt_size = -1;
+ }
+
+ /* valid range is between 4 and 9 inclusive */
+ if (amdgpu_vm_fragment_size != -1 &&
+ (amdgpu_vm_fragment_size > 9 || amdgpu_vm_fragment_size < 4)) {
+ dev_warn(adev->dev, "valid range is between 4 and 9\n");
+ amdgpu_vm_fragment_size = -1;
}
amdgpu_check_vm_size(adev);
@@ -1138,7 +1088,7 @@ static void amdgpu_check_arguments(struct amdgpu_device *adev)
amdgpu_check_block_size(adev);
if (amdgpu_vram_page_split != -1 && (amdgpu_vram_page_split < 16 ||
- !amdgpu_check_pot_argument(amdgpu_vram_page_split))) {
+ !is_power_of_2(amdgpu_vram_page_split))) {
dev_warn(adev->dev, "invalid VRAM page split (%d)\n",
amdgpu_vram_page_split);
amdgpu_vram_page_split = 1024;
@@ -1901,7 +1851,8 @@ static int amdgpu_sriov_reinit_late(struct amdgpu_device *adev)
AMD_IP_BLOCK_TYPE_DCE,
AMD_IP_BLOCK_TYPE_GFX,
AMD_IP_BLOCK_TYPE_SDMA,
- AMD_IP_BLOCK_TYPE_VCE,
+ AMD_IP_BLOCK_TYPE_UVD,
+ AMD_IP_BLOCK_TYPE_VCE
};
for (i = 0; i < ARRAY_SIZE(ip_order); i++) {
@@ -2019,7 +1970,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
adev->flags = flags;
adev->asic_type = flags & AMD_ASIC_MASK;
adev->usec_timeout = AMDGPU_MAX_USEC_TIMEOUT;
- adev->mc.gtt_size = 512 * 1024 * 1024;
+ adev->mc.gart_size = 512 * 1024 * 1024;
adev->accel_working = false;
adev->num_rings = 0;
adev->mman.buffer_funcs = NULL;
@@ -2068,6 +2019,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
spin_lock_init(&adev->uvd_ctx_idx_lock);
spin_lock_init(&adev->didt_idx_lock);
spin_lock_init(&adev->gc_cac_idx_lock);
+ spin_lock_init(&adev->se_cac_idx_lock);
spin_lock_init(&adev->audio_endpt_idx_lock);
spin_lock_init(&adev->mm_stats.lock);
@@ -2143,6 +2095,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
r = amdgpu_atombios_init(adev);
if (r) {
dev_err(adev->dev, "amdgpu_atombios_init failed\n");
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_ATOMBIOS_INIT_FAIL, 0, 0);
goto failed;
}
@@ -2153,6 +2106,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
if (amdgpu_vpost_needed(adev)) {
if (!adev->bios) {
dev_err(adev->dev, "no vBIOS found\n");
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_NO_VBIOS, 0, 0);
r = -EINVAL;
goto failed;
}
@@ -2160,18 +2114,28 @@ int amdgpu_device_init(struct amdgpu_device *adev,
r = amdgpu_atom_asic_init(adev->mode_info.atom_context);
if (r) {
dev_err(adev->dev, "gpu post error!\n");
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_GPU_POST_ERROR, 0, 0);
goto failed;
}
} else {
DRM_INFO("GPU post is not needed\n");
}
- if (!adev->is_atom_fw) {
+ if (adev->is_atom_fw) {
+ /* Initialize clocks */
+ r = amdgpu_atomfirmware_get_clock_info(adev);
+ if (r) {
+ dev_err(adev->dev, "amdgpu_atomfirmware_get_clock_info failed\n");
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL, 0, 0);
+ goto failed;
+ }
+ } else {
/* Initialize clocks */
r = amdgpu_atombios_get_clock_info(adev);
if (r) {
dev_err(adev->dev, "amdgpu_atombios_get_clock_info failed\n");
- return r;
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL, 0, 0);
+ goto failed;
}
/* init i2c buses */
amdgpu_atombios_i2c_init(adev);
@@ -2181,6 +2145,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
r = amdgpu_fence_driver_init(adev);
if (r) {
dev_err(adev->dev, "amdgpu_fence_driver_init failed\n");
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_FENCE_INIT_FAIL, 0, 0);
goto failed;
}
@@ -2190,6 +2155,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
r = amdgpu_init(adev);
if (r) {
dev_err(adev->dev, "amdgpu_init failed\n");
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_AMDGPU_INIT_FAIL, 0, 0);
amdgpu_fini(adev);
goto failed;
}
@@ -2209,6 +2175,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
r = amdgpu_ib_pool_init(adev);
if (r) {
dev_err(adev->dev, "IB initialization failed (%d).\n", r);
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_IB_INIT_FAIL, 0, r);
goto failed;
}
@@ -2253,12 +2220,14 @@ int amdgpu_device_init(struct amdgpu_device *adev,
r = amdgpu_late_init(adev);
if (r) {
dev_err(adev->dev, "amdgpu_late_init failed\n");
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_AMDGPU_LATE_INIT_FAIL, 0, r);
goto failed;
}
return 0;
failed:
+ amdgpu_vf_error_trans_all(adev);
if (runtime)
vga_switcheroo_fini_domain_pm_ops(adev->dev);
return r;
@@ -2351,6 +2320,8 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon)
}
drm_modeset_unlock_all(dev);
+ amdgpu_amdkfd_suspend(adev);
+
/* unpin the front buffers and cursors */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
@@ -2392,10 +2363,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon)
*/
amdgpu_bo_evict_vram(adev);
- if (adev->is_atom_fw)
- amdgpu_atomfirmware_scratch_regs_save(adev);
- else
- amdgpu_atombios_scratch_regs_save(adev);
+ amdgpu_atombios_scratch_regs_save(adev);
pci_save_state(dev->pdev);
if (suspend) {
/* Shut down the device */
@@ -2444,10 +2412,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)
if (r)
goto unlock;
}
- if (adev->is_atom_fw)
- amdgpu_atomfirmware_scratch_regs_restore(adev);
- else
- amdgpu_atombios_scratch_regs_restore(adev);
+ amdgpu_atombios_scratch_regs_restore(adev);
/* post card */
if (amdgpu_need_post(adev)) {
@@ -2490,6 +2455,9 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)
}
}
}
+ r = amdgpu_amdkfd_resume(adev);
+ if (r)
+ return r;
/* blat the mode back in */
if (fbcon) {
@@ -2860,21 +2828,9 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
r = amdgpu_suspend(adev);
retry:
- /* Disable fb access */
- if (adev->mode_info.num_crtc) {
- struct amdgpu_mode_mc_save save;
- amdgpu_display_stop_mc_access(adev, &save);
- amdgpu_wait_for_idle(adev, AMD_IP_BLOCK_TYPE_GMC);
- }
- if (adev->is_atom_fw)
- amdgpu_atomfirmware_scratch_regs_save(adev);
- else
- amdgpu_atombios_scratch_regs_save(adev);
+ amdgpu_atombios_scratch_regs_save(adev);
r = amdgpu_asic_reset(adev);
- if (adev->is_atom_fw)
- amdgpu_atomfirmware_scratch_regs_restore(adev);
- else
- amdgpu_atombios_scratch_regs_restore(adev);
+ amdgpu_atombios_scratch_regs_restore(adev);
/* post card */
amdgpu_atom_asic_init(adev->mode_info.atom_context);
@@ -2952,6 +2908,7 @@ out:
}
} else {
dev_err(adev->dev, "asic resume failed (%d).\n", r);
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_ASIC_RESUME_FAIL, 0, r);
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
if (adev->rings[i] && adev->rings[i]->sched.thread) {
kthread_unpark(adev->rings[i]->sched.thread);
@@ -2962,12 +2919,16 @@ out:
drm_helper_resume_force_mode(adev->ddev);
ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched);
- if (r)
+ if (r) {
/* bad news, how to tell it to userspace ? */
dev_info(adev->dev, "GPU reset failed\n");
- else
+ amdgpu_vf_error_put(AMDGIM_ERROR_VF_GPU_RESET_FAIL, 0, r);
+ }
+ else {
dev_info(adev->dev, "GPU reset successed!\n");
+ }
+ amdgpu_vf_error_trans_all(adev);
return r;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index cdf2ab20166a..6ad243293a78 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -482,7 +482,7 @@ static void amdgpu_user_framebuffer_destroy(struct drm_framebuffer *fb)
{
struct amdgpu_framebuffer *amdgpu_fb = to_amdgpu_framebuffer(fb);
- drm_gem_object_unreference_unlocked(amdgpu_fb->obj);
+ drm_gem_object_put_unlocked(amdgpu_fb->obj);
drm_framebuffer_cleanup(fb);
kfree(amdgpu_fb);
}
@@ -542,14 +542,14 @@ amdgpu_user_framebuffer_create(struct drm_device *dev,
amdgpu_fb = kzalloc(sizeof(*amdgpu_fb), GFP_KERNEL);
if (amdgpu_fb == NULL) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(-ENOMEM);
}
ret = amdgpu_framebuffer_init(dev, amdgpu_fb, mode_cmd, obj);
if (ret) {
kfree(amdgpu_fb);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(ret);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index b59f37c83fa6..e39ec981b11c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -68,13 +68,16 @@
* - 3.16.0 - Add reserved vmid support
* - 3.17.0 - Add AMDGPU_NUM_VRAM_CPU_PAGE_FAULTS.
* - 3.18.0 - Export gpu always on cu bitmap
+ * - 3.19.0 - Add support for UVD MJPEG decode
*/
#define KMS_DRIVER_MAJOR 3
-#define KMS_DRIVER_MINOR 18
+#define KMS_DRIVER_MINOR 19
#define KMS_DRIVER_PATCHLEVEL 0
int amdgpu_vram_limit = 0;
-int amdgpu_gart_size = -1; /* auto */
+int amdgpu_vis_vram_limit = 0;
+unsigned amdgpu_gart_size = 256;
+int amdgpu_gtt_size = -1; /* auto */
int amdgpu_moverate = -1; /* auto */
int amdgpu_benchmarking = 0;
int amdgpu_testing = 0;
@@ -92,6 +95,7 @@ unsigned amdgpu_ip_block_mask = 0xffffffff;
int amdgpu_bapm = -1;
int amdgpu_deep_color = 0;
int amdgpu_vm_size = -1;
+int amdgpu_vm_fragment_size = -1;
int amdgpu_vm_block_size = -1;
int amdgpu_vm_fault_stop = 0;
int amdgpu_vm_debug = 0;
@@ -106,6 +110,7 @@ unsigned amdgpu_pcie_gen_cap = 0;
unsigned amdgpu_pcie_lane_cap = 0;
unsigned amdgpu_cg_mask = 0xffffffff;
unsigned amdgpu_pg_mask = 0xffffffff;
+unsigned amdgpu_sdma_phase_quantum = 32;
char *amdgpu_disable_cu = NULL;
char *amdgpu_virtual_display = NULL;
unsigned amdgpu_pp_feature_mask = 0xffffffff;
@@ -120,8 +125,14 @@ int amdgpu_lbpw = -1;
MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes");
module_param_named(vramlimit, amdgpu_vram_limit, int, 0600);
-MODULE_PARM_DESC(gartsize, "Size of PCIE/IGP gart to setup in megabytes (32, 64, etc., -1 = auto)");
-module_param_named(gartsize, amdgpu_gart_size, int, 0600);
+MODULE_PARM_DESC(vis_vramlimit, "Restrict visible VRAM for testing, in megabytes");
+module_param_named(vis_vramlimit, amdgpu_vis_vram_limit, int, 0444);
+
+MODULE_PARM_DESC(gartsize, "Size of PCIE/IGP gart to setup in megabytes (32, 64, etc.)");
+module_param_named(gartsize, amdgpu_gart_size, uint, 0600);
+
+MODULE_PARM_DESC(gttsize, "Size of the GTT domain in megabytes (-1 = auto)");
+module_param_named(gttsize, amdgpu_gtt_size, int, 0600);
MODULE_PARM_DESC(moverate, "Maximum buffer migration rate in MB/s. (32, 64, etc., -1=auto, 0=1=disabled)");
module_param_named(moverate, amdgpu_moverate, int, 0600);
@@ -174,6 +185,9 @@ module_param_named(deep_color, amdgpu_deep_color, int, 0444);
MODULE_PARM_DESC(vm_size, "VM address space size in gigabytes (default 64GB)");
module_param_named(vm_size, amdgpu_vm_size, int, 0444);
+MODULE_PARM_DESC(vm_fragment_size, "VM fragment size in bits (4, 5, etc. 4 = 64K (default), Max 9 = 2M)");
+module_param_named(vm_fragment_size, amdgpu_vm_fragment_size, int, 0444);
+
MODULE_PARM_DESC(vm_block_size, "VM page table size in bits (default depending on vm_size)");
module_param_named(vm_block_size, amdgpu_vm_block_size, int, 0444);
@@ -186,7 +200,7 @@ module_param_named(vm_debug, amdgpu_vm_debug, int, 0644);
MODULE_PARM_DESC(vm_update_mode, "VM update using CPU (0 = never (default except for large BAR(LB)), 1 = Graphics only, 2 = Compute only (default for LB), 3 = Both");
module_param_named(vm_update_mode, amdgpu_vm_update_mode, int, 0444);
-MODULE_PARM_DESC(vram_page_split, "Number of pages after we split VRAM allocations (default 1024, -1 = disable)");
+MODULE_PARM_DESC(vram_page_split, "Number of pages after we split VRAM allocations (default 512, -1 = disable)");
module_param_named(vram_page_split, amdgpu_vram_page_split, int, 0444);
MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))");
@@ -199,7 +213,7 @@ MODULE_PARM_DESC(sched_hw_submission, "the max number of HW submissions (default
module_param_named(sched_hw_submission, amdgpu_sched_hw_submission, int, 0444);
MODULE_PARM_DESC(ppfeaturemask, "all power features enabled (default))");
-module_param_named(ppfeaturemask, amdgpu_pp_feature_mask, int, 0444);
+module_param_named(ppfeaturemask, amdgpu_pp_feature_mask, uint, 0444);
MODULE_PARM_DESC(no_evict, "Support pinning request from user space (1 = enable, 0 = disable (default))");
module_param_named(no_evict, amdgpu_no_evict, int, 0444);
@@ -219,6 +233,9 @@ module_param_named(cg_mask, amdgpu_cg_mask, uint, 0444);
MODULE_PARM_DESC(pg_mask, "Powergating flags mask (0 = disable power gating)");
module_param_named(pg_mask, amdgpu_pg_mask, uint, 0444);
+MODULE_PARM_DESC(sdma_phase_quantum, "SDMA context switch phase quantum (x 1K GPU clock cycles, 0 = no change (default 32))");
+module_param_named(sdma_phase_quantum, amdgpu_sdma_phase_quantum, uint, 0444);
+
MODULE_PARM_DESC(disable_cu, "Disable CUs (se.sh.cu,...)");
module_param_named(disable_cu, amdgpu_disable_cu, charp, 0444);
@@ -803,7 +820,6 @@ static struct drm_driver kms_driver = {
.open = amdgpu_driver_open_kms,
.postclose = amdgpu_driver_postclose_kms,
.lastclose = amdgpu_driver_lastclose_kms,
- .set_busid = drm_pci_set_busid,
.unload = amdgpu_driver_unload_kms,
.get_vblank_counter = amdgpu_get_vblank_counter_kms,
.enable_vblank = amdgpu_enable_vblank_kms,
@@ -823,7 +839,6 @@ static struct drm_driver kms_driver = {
.gem_close_object = amdgpu_gem_object_close,
.dumb_create = amdgpu_mode_dumb_create,
.dumb_map_offset = amdgpu_mode_dumb_mmap,
- .dumb_destroy = drm_gem_dumb_destroy,
.fops = &amdgpu_driver_kms_fops,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
index c0d8c6ff6380..9afa9c097e1f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
@@ -118,7 +118,7 @@ static void amdgpufb_destroy_pinned_object(struct drm_gem_object *gobj)
amdgpu_bo_unpin(abo);
amdgpu_bo_unreserve(abo);
}
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
}
static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
@@ -245,13 +245,12 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
- info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &amdgpufb_ops;
tmp = amdgpu_bo_gpu_offset(abo) - adev->mc.vram_start;
info->fix.smem_start = adev->mc.aper_base + tmp;
info->fix.smem_len = amdgpu_bo_size(abo);
- info->screen_base = abo->kptr;
+ info->screen_base = amdgpu_bo_kptr(abo);
info->screen_size = amdgpu_bo_size(abo);
drm_fb_helper_fill_var(info, &rfbdev->helper, sizes->fb_width, sizes->fb_height);
@@ -281,7 +280,7 @@ out:
}
if (fb && ret) {
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
drm_framebuffer_unregister_private(fb);
drm_framebuffer_cleanup(fb);
kfree(fb);
@@ -312,31 +311,7 @@ static int amdgpu_fbdev_destroy(struct drm_device *dev, struct amdgpu_fbdev *rfb
return 0;
}
-/** Sets the color ramps on behalf of fbcon */
-static void amdgpu_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
-
- amdgpu_crtc->lut_r[regno] = red >> 6;
- amdgpu_crtc->lut_g[regno] = green >> 6;
- amdgpu_crtc->lut_b[regno] = blue >> 6;
-}
-
-/** Gets the color ramps on behalf of fbcon */
-static void amdgpu_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno)
-{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
-
- *red = amdgpu_crtc->lut_r[regno] << 6;
- *green = amdgpu_crtc->lut_g[regno] << 6;
- *blue = amdgpu_crtc->lut_b[regno] << 6;
-}
-
static const struct drm_fb_helper_funcs amdgpu_fb_helper_funcs = {
- .gamma_set = amdgpu_crtc_fb_gamma_set,
- .gamma_get = amdgpu_crtc_fb_gamma_get,
.fb_probe = amdgpufb_create,
};
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
index a57abc1a25fb..94c1e2e8e34c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
@@ -55,6 +55,19 @@
/*
* Common GART table functions.
*/
+
+/**
+ * amdgpu_gart_set_defaults - set the default gart_size
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * Set the default gart_size based on parameters and available VRAM.
+ */
+void amdgpu_gart_set_defaults(struct amdgpu_device *adev)
+{
+ adev->mc.gart_size = (uint64_t)amdgpu_gart_size << 20;
+}
+
/**
* amdgpu_gart_table_ram_alloc - allocate system ram for gart page table
*
@@ -131,7 +144,7 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev)
PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,
AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, &adev->gart.robj);
+ NULL, NULL, 0, &adev->gart.robj);
if (r) {
return r;
}
@@ -263,6 +276,41 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
}
/**
+ * amdgpu_gart_map - map dma_addresses into GART entries
+ *
+ * @adev: amdgpu_device pointer
+ * @offset: offset into the GPU's gart aperture
+ * @pages: number of pages to bind
+ * @dma_addr: DMA addresses of pages
+ *
+ * Map the dma_addresses into GART entries (all asics).
+ * Returns 0 for success, -EINVAL for failure.
+ */
+int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
+ int pages, dma_addr_t *dma_addr, uint64_t flags,
+ void *dst)
+{
+ uint64_t page_base;
+ unsigned i, j, t;
+
+ if (!adev->gart.ready) {
+ WARN(1, "trying to bind memory to uninitialized GART !\n");
+ return -EINVAL;
+ }
+
+ t = offset / AMDGPU_GPU_PAGE_SIZE;
+
+ for (i = 0; i < pages; i++) {
+ page_base = dma_addr[i];
+ for (j = 0; j < (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); j++, t++) {
+ amdgpu_gart_set_pte_pde(adev, dst, t, page_base, flags);
+ page_base += AMDGPU_GPU_PAGE_SIZE;
+ }
+ }
+ return 0;
+}
+
+/**
* amdgpu_gart_bind - bind pages into the gart page table
*
* @adev: amdgpu_device pointer
@@ -279,31 +327,30 @@ int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
int pages, struct page **pagelist, dma_addr_t *dma_addr,
uint64_t flags)
{
- unsigned t;
- unsigned p;
- uint64_t page_base;
- int i, j;
+#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
+ unsigned i,t,p;
+#endif
+ int r;
if (!adev->gart.ready) {
WARN(1, "trying to bind memory to uninitialized GART !\n");
return -EINVAL;
}
+#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
t = offset / AMDGPU_GPU_PAGE_SIZE;
p = t / (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE);
-
- for (i = 0; i < pages; i++, p++) {
-#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
+ for (i = 0; i < pages; i++, p++)
adev->gart.pages[p] = pagelist[i];
#endif
- if (adev->gart.ptr) {
- page_base = dma_addr[i];
- for (j = 0; j < (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); j++, t++) {
- amdgpu_gart_set_pte_pde(adev, adev->gart.ptr, t, page_base, flags);
- page_base += AMDGPU_GPU_PAGE_SIZE;
- }
- }
+
+ if (adev->gart.ptr) {
+ r = amdgpu_gart_map(adev, offset, pages, dma_addr, flags,
+ adev->gart.ptr);
+ if (r)
+ return r;
}
+
mb();
amdgpu_gart_flush_gpu_tlb(adev, 0);
return 0;
@@ -333,8 +380,8 @@ int amdgpu_gart_init(struct amdgpu_device *adev)
if (r)
return r;
/* Compute table size */
- adev->gart.num_cpu_pages = adev->mc.gtt_size / PAGE_SIZE;
- adev->gart.num_gpu_pages = adev->mc.gtt_size / AMDGPU_GPU_PAGE_SIZE;
+ adev->gart.num_cpu_pages = adev->mc.gart_size / PAGE_SIZE;
+ adev->gart.num_gpu_pages = adev->mc.gart_size / AMDGPU_GPU_PAGE_SIZE;
DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n",
adev->gart.num_cpu_pages, adev->gart.num_gpu_pages);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h
new file mode 100644
index 000000000000..d4cce6936200
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2017 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_GART_H__
+#define __AMDGPU_GART_H__
+
+#include <linux/types.h>
+
+/*
+ * GART structures, functions & helpers
+ */
+struct amdgpu_device;
+struct amdgpu_bo;
+struct amdgpu_gart_funcs;
+
+#define AMDGPU_GPU_PAGE_SIZE 4096
+#define AMDGPU_GPU_PAGE_MASK (AMDGPU_GPU_PAGE_SIZE - 1)
+#define AMDGPU_GPU_PAGE_SHIFT 12
+#define AMDGPU_GPU_PAGE_ALIGN(a) (((a) + AMDGPU_GPU_PAGE_MASK) & ~AMDGPU_GPU_PAGE_MASK)
+
+struct amdgpu_gart {
+ dma_addr_t table_addr;
+ struct amdgpu_bo *robj;
+ void *ptr;
+ unsigned num_gpu_pages;
+ unsigned num_cpu_pages;
+ unsigned table_size;
+#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
+ struct page **pages;
+#endif
+ bool ready;
+
+ /* Asic default pte flags */
+ uint64_t gart_pte_flags;
+
+ const struct amdgpu_gart_funcs *gart_funcs;
+};
+
+void amdgpu_gart_set_defaults(struct amdgpu_device *adev);
+int amdgpu_gart_table_ram_alloc(struct amdgpu_device *adev);
+void amdgpu_gart_table_ram_free(struct amdgpu_device *adev);
+int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev);
+void amdgpu_gart_table_vram_free(struct amdgpu_device *adev);
+int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev);
+void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev);
+int amdgpu_gart_init(struct amdgpu_device *adev);
+void amdgpu_gart_fini(struct amdgpu_device *adev);
+int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
+ int pages);
+int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
+ int pages, dma_addr_t *dma_addr, uint64_t flags,
+ void *dst);
+int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
+ int pages, struct page **pagelist,
+ dma_addr_t *dma_addr, uint64_t flags);
+
+#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index 621f739103a6..7171968f261e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -49,7 +49,6 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
struct drm_gem_object **obj)
{
struct amdgpu_bo *robj;
- unsigned long max_size;
int r;
*obj = NULL;
@@ -58,20 +57,9 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
alignment = PAGE_SIZE;
}
- if (!(initial_domain & (AMDGPU_GEM_DOMAIN_GDS | AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA))) {
- /* Maximum bo size is the unpinned gtt size since we use the gtt to
- * handle vram to system pool migrations.
- */
- max_size = adev->mc.gtt_size - adev->gart_pin_size;
- if (size > max_size) {
- DRM_DEBUG("Allocation size %ldMb bigger than %ldMb limit\n",
- size >> 20, max_size >> 20);
- return -ENOMEM;
- }
- }
retry:
r = amdgpu_bo_create(adev, size, alignment, kernel, initial_domain,
- flags, NULL, NULL, &robj);
+ flags, NULL, NULL, 0, &robj);
if (r) {
if (r != -ERESTARTSYS) {
if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) {
@@ -103,7 +91,7 @@ void amdgpu_gem_force_release(struct amdgpu_device *adev)
spin_lock(&file->table_lock);
idr_for_each_entry(&file->object_idr, gobj, handle) {
WARN_ONCE(1, "And also active allocations!\n");
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
}
idr_destroy(&file->object_idr);
spin_unlock(&file->table_lock);
@@ -237,9 +225,7 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
if (args->in.domain_flags & ~(AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
AMDGPU_GEM_CREATE_CPU_GTT_USWC |
- AMDGPU_GEM_CREATE_VRAM_CLEARED|
- AMDGPU_GEM_CREATE_SHADOW |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS))
+ AMDGPU_GEM_CREATE_VRAM_CLEARED))
return -EINVAL;
/* reject invalid gem domains */
@@ -275,7 +261,7 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
r = drm_gem_handle_create(filp, gobj, &handle);
/* drop reference from allocate - handle holds it now */
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (r)
return r;
@@ -318,7 +304,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
return r;
bo = gem_to_amdgpu_bo(gobj);
- bo->prefered_domains = AMDGPU_GEM_DOMAIN_GTT;
+ bo->preferred_domains = AMDGPU_GEM_DOMAIN_GTT;
bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT;
r = amdgpu_ttm_tt_set_userptr(bo->tbo.ttm, args->addr, args->flags);
if (r)
@@ -353,7 +339,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
r = drm_gem_handle_create(filp, gobj, &handle);
/* drop reference from allocate - handle holds it now */
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (r)
return r;
@@ -367,7 +353,7 @@ unlock_mmap_sem:
up_read(&current->mm->mmap_sem);
release_object:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -386,11 +372,11 @@ int amdgpu_mode_dumb_mmap(struct drm_file *filp,
robj = gem_to_amdgpu_bo(gobj);
if (amdgpu_ttm_tt_get_usermm(robj->tbo.ttm) ||
(robj->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)) {
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return -EPERM;
}
*offset_p = amdgpu_bo_mmap_offset(robj);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return 0;
}
@@ -460,7 +446,7 @@ int amdgpu_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
} else
r = ret;
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -503,7 +489,7 @@ int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,
unreserve:
amdgpu_bo_unreserve(robj);
out:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -635,7 +621,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
switch (args->operation) {
case AMDGPU_VA_OP_MAP:
- r = amdgpu_vm_alloc_pts(adev, bo_va->vm, args->va_address,
+ r = amdgpu_vm_alloc_pts(adev, bo_va->base.vm, args->va_address,
args->map_size);
if (r)
goto error_backoff;
@@ -655,7 +641,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
args->map_size);
break;
case AMDGPU_VA_OP_REPLACE:
- r = amdgpu_vm_alloc_pts(adev, bo_va->vm, args->va_address,
+ r = amdgpu_vm_alloc_pts(adev, bo_va->base.vm, args->va_address,
args->map_size);
if (r)
goto error_backoff;
@@ -676,7 +662,7 @@ error_backoff:
ttm_eu_backoff_reservation(&ticket, &list);
error_unref:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -701,11 +687,11 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
switch (args->op) {
case AMDGPU_GEM_OP_GET_GEM_CREATE_INFO: {
struct drm_amdgpu_gem_create_in info;
- void __user *out = (void __user *)(uintptr_t)args->value;
+ void __user *out = u64_to_user_ptr(args->value);
info.bo_size = robj->gem_base.size;
info.alignment = robj->tbo.mem.page_alignment << PAGE_SHIFT;
- info.domains = robj->prefered_domains;
+ info.domains = robj->preferred_domains;
info.domain_flags = robj->flags;
amdgpu_bo_unreserve(robj);
if (copy_to_user(out, &info, sizeof(info)))
@@ -723,10 +709,10 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
amdgpu_bo_unreserve(robj);
break;
}
- robj->prefered_domains = args->value & (AMDGPU_GEM_DOMAIN_VRAM |
+ robj->preferred_domains = args->value & (AMDGPU_GEM_DOMAIN_VRAM |
AMDGPU_GEM_DOMAIN_GTT |
AMDGPU_GEM_DOMAIN_CPU);
- robj->allowed_domains = robj->prefered_domains;
+ robj->allowed_domains = robj->preferred_domains;
if (robj->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM)
robj->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT;
@@ -738,7 +724,7 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
}
out:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -766,7 +752,7 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,
r = drm_gem_handle_create(file_priv, gobj, &handle);
/* drop reference from allocate - handle holds it now */
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (r) {
return r;
}
@@ -784,6 +770,7 @@ static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data)
unsigned domain;
const char *placement;
unsigned pin_count;
+ uint64_t offset;
domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
switch (domain) {
@@ -798,9 +785,12 @@ static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data)
placement = " CPU";
break;
}
- seq_printf(m, "\t0x%08x: %12ld byte %s @ 0x%010Lx",
- id, amdgpu_bo_size(bo), placement,
- amdgpu_bo_gpu_offset(bo));
+ seq_printf(m, "\t0x%08x: %12ld byte %s",
+ id, amdgpu_bo_size(bo), placement);
+
+ offset = ACCESS_ONCE(bo->tbo.mem.start);
+ if (offset != AMDGPU_BO_INVALID_OFFSET)
+ seq_printf(m, " @ 0x%010Lx", offset);
pin_count = ACCESS_ONCE(bo->pin_count);
if (pin_count)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
index e26108aad3fe..4f6c68fc1dd9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
@@ -125,7 +125,8 @@ void amdgpu_gfx_compute_queue_acquire(struct amdgpu_device *adev)
if (mec >= adev->gfx.mec.num_mec)
break;
- if (adev->gfx.mec.num_mec > 1) {
+ /* FIXME: spreading the queues across pipes causes perf regressions */
+ if (0) {
/* policy: amdgpu owns the first two queues of the first MEC */
if (mec == 0 && queue < 2)
set_bit(i, adev->gfx.mec.queue_bitmap);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
index f7d22c44034d..9e05e257729f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
@@ -28,7 +28,7 @@
struct amdgpu_gtt_mgr {
struct drm_mm mm;
spinlock_t lock;
- uint64_t available;
+ atomic64_t available;
};
/**
@@ -42,15 +42,19 @@ struct amdgpu_gtt_mgr {
static int amdgpu_gtt_mgr_init(struct ttm_mem_type_manager *man,
unsigned long p_size)
{
+ struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);
struct amdgpu_gtt_mgr *mgr;
+ uint64_t start, size;
mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
if (!mgr)
return -ENOMEM;
- drm_mm_init(&mgr->mm, 0, p_size);
+ start = AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS;
+ size = (adev->mc.gart_size >> PAGE_SHIFT) - start;
+ drm_mm_init(&mgr->mm, start, size);
spin_lock_init(&mgr->lock);
- mgr->available = p_size;
+ atomic64_set(&mgr->available, p_size);
man->priv = mgr;
return 0;
}
@@ -81,6 +85,20 @@ static int amdgpu_gtt_mgr_fini(struct ttm_mem_type_manager *man)
}
/**
+ * amdgpu_gtt_mgr_is_allocated - Check if mem has address space
+ *
+ * @mem: the mem object to check
+ *
+ * Check if a mem object has already address space allocated.
+ */
+bool amdgpu_gtt_mgr_is_allocated(struct ttm_mem_reg *mem)
+{
+ struct drm_mm_node *node = mem->mm_node;
+
+ return (node->start != AMDGPU_BO_INVALID_OFFSET);
+}
+
+/**
* amdgpu_gtt_mgr_alloc - allocate new ranges
*
* @man: TTM memory type manager
@@ -95,13 +113,14 @@ int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
const struct ttm_place *place,
struct ttm_mem_reg *mem)
{
+ struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);
struct amdgpu_gtt_mgr *mgr = man->priv;
struct drm_mm_node *node = mem->mm_node;
enum drm_mm_insert_mode mode;
unsigned long fpfn, lpfn;
int r;
- if (node->start != AMDGPU_BO_INVALID_OFFSET)
+ if (amdgpu_gtt_mgr_is_allocated(mem))
return 0;
if (place)
@@ -112,7 +131,7 @@ int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
if (place && place->lpfn)
lpfn = place->lpfn;
else
- lpfn = man->size;
+ lpfn = adev->gart.num_cpu_pages;
mode = DRM_MM_INSERT_BEST;
if (place && place->flags & TTM_PL_FLAG_TOPDOWN)
@@ -134,15 +153,6 @@ int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
return r;
}
-void amdgpu_gtt_mgr_print(struct seq_file *m, struct ttm_mem_type_manager *man)
-{
- struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);
- struct amdgpu_gtt_mgr *mgr = man->priv;
-
- seq_printf(m, "man size:%llu pages, gtt available:%llu pages, usage:%lluMB\n",
- man->size, mgr->available, (u64)atomic64_read(&adev->gtt_usage) >> 20);
-
-}
/**
* amdgpu_gtt_mgr_new - allocate a new node
*
@@ -163,11 +173,11 @@ static int amdgpu_gtt_mgr_new(struct ttm_mem_type_manager *man,
int r;
spin_lock(&mgr->lock);
- if (mgr->available < mem->num_pages) {
+ if (atomic64_read(&mgr->available) < mem->num_pages) {
spin_unlock(&mgr->lock);
return 0;
}
- mgr->available -= mem->num_pages;
+ atomic64_sub(mem->num_pages, &mgr->available);
spin_unlock(&mgr->lock);
node = kzalloc(sizeof(*node), GFP_KERNEL);
@@ -194,9 +204,7 @@ static int amdgpu_gtt_mgr_new(struct ttm_mem_type_manager *man,
return 0;
err_out:
- spin_lock(&mgr->lock);
- mgr->available += mem->num_pages;
- spin_unlock(&mgr->lock);
+ atomic64_add(mem->num_pages, &mgr->available);
return r;
}
@@ -223,30 +231,47 @@ static void amdgpu_gtt_mgr_del(struct ttm_mem_type_manager *man,
spin_lock(&mgr->lock);
if (node->start != AMDGPU_BO_INVALID_OFFSET)
drm_mm_remove_node(node);
- mgr->available += mem->num_pages;
spin_unlock(&mgr->lock);
+ atomic64_add(mem->num_pages, &mgr->available);
kfree(node);
mem->mm_node = NULL;
}
/**
+ * amdgpu_gtt_mgr_usage - return usage of GTT domain
+ *
+ * @man: TTM memory type manager
+ *
+ * Return how many bytes are used in the GTT domain
+ */
+uint64_t amdgpu_gtt_mgr_usage(struct ttm_mem_type_manager *man)
+{
+ struct amdgpu_gtt_mgr *mgr = man->priv;
+
+ return (u64)(man->size - atomic64_read(&mgr->available)) * PAGE_SIZE;
+}
+
+/**
* amdgpu_gtt_mgr_debug - dump VRAM table
*
* @man: TTM memory type manager
- * @prefix: text prefix
+ * @printer: DRM printer to use
*
* Dump the table content using printk.
*/
static void amdgpu_gtt_mgr_debug(struct ttm_mem_type_manager *man,
- const char *prefix)
+ struct drm_printer *printer)
{
struct amdgpu_gtt_mgr *mgr = man->priv;
- struct drm_printer p = drm_debug_printer(prefix);
spin_lock(&mgr->lock);
- drm_mm_print(&mgr->mm, &p);
+ drm_mm_print(&mgr->mm, printer);
spin_unlock(&mgr->lock);
+
+ drm_printf(printer, "man size:%llu pages, gtt available:%llu pages, usage:%lluMB\n",
+ man->size, (u64)atomic64_read(&mgr->available),
+ amdgpu_gtt_mgr_usage(man) >> 20);
}
const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func = {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
index f774b3f497d2..659997bfff30 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
@@ -130,6 +130,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
unsigned i;
int r = 0;
+ bool need_pipe_sync = false;
if (num_ibs == 0)
return -EINVAL;
@@ -165,15 +166,15 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
if (ring->funcs->emit_pipeline_sync && job &&
((tmp = amdgpu_sync_get_fence(&job->sched_sync)) ||
amdgpu_vm_need_pipeline_sync(ring, job))) {
- amdgpu_ring_emit_pipeline_sync(ring);
+ need_pipe_sync = true;
dma_fence_put(tmp);
}
if (ring->funcs->insert_start)
ring->funcs->insert_start(ring);
- if (vm) {
- r = amdgpu_vm_flush(ring, job);
+ if (job) {
+ r = amdgpu_vm_flush(ring, job, need_pipe_sync);
if (r) {
amdgpu_ring_undo(ring);
return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
index 62da6c5c6095..4bdd851f56d0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -220,6 +220,10 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
int r = 0;
spin_lock_init(&adev->irq.lock);
+
+ /* Disable vblank irqs aggressively for power-saving */
+ adev->ddev->vblank_disable_immediate = true;
+
r = drm_vblank_init(adev->ddev, adev->mode_info.num_crtc);
if (r) {
return r;
@@ -263,7 +267,6 @@ void amdgpu_irq_fini(struct amdgpu_device *adev)
{
unsigned i, j;
- drm_vblank_cleanup(adev->ddev);
if (adev->irq.installed) {
drm_irq_uninstall(adev->ddev);
adev->irq.installed = false;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index 3d641e10e6b6..4510627ae83e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -81,6 +81,8 @@ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,
r = amdgpu_ib_get(adev, NULL, size, &(*job)->ibs[0]);
if (r)
kfree(*job);
+ else
+ (*job)->vm_pd_addr = adev->gart.table_addr;
return r;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index b0b23101d1c8..e16229000a98 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -158,7 +158,6 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)
"Error during ACPI methods call\n");
}
- amdgpu_amdkfd_load_interface(adev);
amdgpu_amdkfd_device_probe(adev);
amdgpu_amdkfd_device_init(adev);
@@ -456,13 +455,13 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
ui64 = atomic64_read(&adev->num_vram_cpu_page_faults);
return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
case AMDGPU_INFO_VRAM_USAGE:
- ui64 = atomic64_read(&adev->vram_usage);
+ ui64 = amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
case AMDGPU_INFO_VIS_VRAM_USAGE:
- ui64 = atomic64_read(&adev->vram_vis_usage);
+ ui64 = amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
case AMDGPU_INFO_GTT_USAGE:
- ui64 = atomic64_read(&adev->gtt_usage);
+ ui64 = amdgpu_gtt_mgr_usage(&adev->mman.bdev.man[TTM_PL_TT]);
return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
case AMDGPU_INFO_GDS_CONFIG: {
struct drm_amdgpu_info_gds gds_info;
@@ -485,7 +484,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
vram_gtt.vram_size -= adev->vram_pin_size;
vram_gtt.vram_cpu_accessible_size = adev->mc.visible_vram_size;
vram_gtt.vram_cpu_accessible_size -= (adev->vram_pin_size - adev->invisible_pin_size);
- vram_gtt.gtt_size = adev->mc.gtt_size;
+ vram_gtt.gtt_size = adev->mman.bdev.man[TTM_PL_TT].size;
+ vram_gtt.gtt_size *= PAGE_SIZE;
vram_gtt.gtt_size -= adev->gart_pin_size;
return copy_to_user(out, &vram_gtt,
min((size_t)size, sizeof(vram_gtt))) ? -EFAULT : 0;
@@ -497,7 +497,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
mem.vram.total_heap_size = adev->mc.real_vram_size;
mem.vram.usable_heap_size =
adev->mc.real_vram_size - adev->vram_pin_size;
- mem.vram.heap_usage = atomic64_read(&adev->vram_usage);
+ mem.vram.heap_usage =
+ amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
mem.vram.max_allocation = mem.vram.usable_heap_size * 3 / 4;
mem.cpu_accessible_vram.total_heap_size =
@@ -506,14 +507,16 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
adev->mc.visible_vram_size -
(adev->vram_pin_size - adev->invisible_pin_size);
mem.cpu_accessible_vram.heap_usage =
- atomic64_read(&adev->vram_vis_usage);
+ amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
mem.cpu_accessible_vram.max_allocation =
mem.cpu_accessible_vram.usable_heap_size * 3 / 4;
- mem.gtt.total_heap_size = adev->mc.gtt_size;
- mem.gtt.usable_heap_size =
- adev->mc.gtt_size - adev->gart_pin_size;
- mem.gtt.heap_usage = atomic64_read(&adev->gtt_usage);
+ mem.gtt.total_heap_size = adev->mman.bdev.man[TTM_PL_TT].size;
+ mem.gtt.total_heap_size *= PAGE_SIZE;
+ mem.gtt.usable_heap_size = mem.gtt.total_heap_size
+ - adev->gart_pin_size;
+ mem.gtt.heap_usage =
+ amdgpu_gtt_mgr_usage(&adev->mman.bdev.man[TTM_PL_TT]);
mem.gtt.max_allocation = mem.gtt.usable_heap_size * 3 / 4;
return copy_to_user(out, &mem,
@@ -571,8 +574,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
dev_info.max_engine_clock = amdgpu_dpm_get_sclk(adev, false) * 10;
dev_info.max_memory_clock = amdgpu_dpm_get_mclk(adev, false) * 10;
} else {
- dev_info.max_engine_clock = adev->pm.default_sclk * 10;
- dev_info.max_memory_clock = adev->pm.default_mclk * 10;
+ dev_info.max_engine_clock = adev->clock.default_sclk * 10;
+ dev_info.max_memory_clock = adev->clock.default_mclk * 10;
}
dev_info.enabled_rb_pipes_mask = adev->gfx.config.backend_enable_mask;
dev_info.num_rb_pipes = adev->gfx.config.max_backends_per_se *
@@ -587,10 +590,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
dev_info.virtual_address_offset = AMDGPU_VA_RESERVED_SIZE;
dev_info.virtual_address_max = (uint64_t)adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE;
dev_info.virtual_address_alignment = max((int)PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE);
- dev_info.pte_fragment_size = (1 << AMDGPU_LOG2_PAGES_PER_FRAG) *
- AMDGPU_GPU_PAGE_SIZE;
+ dev_info.pte_fragment_size = (1 << adev->vm_manager.fragment_size) * AMDGPU_GPU_PAGE_SIZE;
dev_info.gart_page_size = AMDGPU_GPU_PAGE_SIZE;
-
dev_info.cu_active_number = adev->gfx.cu_info.number;
dev_info.cu_ao_mask = adev->gfx.cu_info.ao_cu_mask;
dev_info.ce_ram_size = adev->gfx.ce_ram_size;
@@ -839,7 +840,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
}
if (amdgpu_sriov_vf(adev)) {
- r = amdgpu_map_static_csa(adev, &fpriv->vm);
+ r = amdgpu_map_static_csa(adev, &fpriv->vm, &fpriv->csa_va);
if (r)
goto out_suspend;
}
@@ -892,8 +893,8 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
if (amdgpu_sriov_vf(adev)) {
/* TODO: how to handle reserve failure */
BUG_ON(amdgpu_bo_reserve(adev->virt.csa_obj, true));
- amdgpu_vm_bo_rmv(adev, fpriv->vm.csa_bo_va);
- fpriv->vm.csa_bo_va = NULL;
+ amdgpu_vm_bo_rmv(adev, fpriv->csa_va);
+ fpriv->csa_va = NULL;
amdgpu_bo_unreserve(adev->virt.csa_obj);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
index 38f739fb727b..6558a3ed57a7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
@@ -359,7 +359,7 @@ void amdgpu_mn_unregister(struct amdgpu_bo *bo)
head = bo->mn_list.next;
bo->mn = NULL;
- list_del(&bo->mn_list);
+ list_del_init(&bo->mn_list);
if (list_empty(head)) {
struct amdgpu_mn_node *node;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 43a9d3aec6c4..2af2678ddaf6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -257,15 +257,7 @@ struct amdgpu_audio {
int num_pins;
};
-struct amdgpu_mode_mc_save {
- u32 vga_render_control;
- u32 vga_hdp_control;
- bool crtc_enabled[AMDGPU_MAX_CRTCS];
-};
-
struct amdgpu_display_funcs {
- /* vga render */
- void (*set_vga_render_state)(struct amdgpu_device *adev, bool render);
/* display watermarks */
void (*bandwidth_update)(struct amdgpu_device *adev);
/* get frame count */
@@ -300,10 +292,6 @@ struct amdgpu_display_funcs {
uint16_t connector_object_id,
struct amdgpu_hpd *hpd,
struct amdgpu_router *router);
- void (*stop_mc_access)(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save);
- void (*resume_mc_access)(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save);
};
struct amdgpu_mode_info {
@@ -369,7 +357,6 @@ struct amdgpu_atom_ss {
struct amdgpu_crtc {
struct drm_crtc base;
int crtc_id;
- u16 lut_r[256], lut_g[256], lut_b[256];
bool enabled;
bool can_tile;
uint32_t crtc_offset;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 8ee69652be8c..e7e899190bef 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -37,55 +37,6 @@
#include "amdgpu.h"
#include "amdgpu_trace.h"
-
-
-static u64 amdgpu_get_vis_part_size(struct amdgpu_device *adev,
- struct ttm_mem_reg *mem)
-{
- if (mem->start << PAGE_SHIFT >= adev->mc.visible_vram_size)
- return 0;
-
- return ((mem->start << PAGE_SHIFT) + mem->size) >
- adev->mc.visible_vram_size ?
- adev->mc.visible_vram_size - (mem->start << PAGE_SHIFT) :
- mem->size;
-}
-
-static void amdgpu_update_memory_usage(struct amdgpu_device *adev,
- struct ttm_mem_reg *old_mem,
- struct ttm_mem_reg *new_mem)
-{
- u64 vis_size;
- if (!adev)
- return;
-
- if (new_mem) {
- switch (new_mem->mem_type) {
- case TTM_PL_TT:
- atomic64_add(new_mem->size, &adev->gtt_usage);
- break;
- case TTM_PL_VRAM:
- atomic64_add(new_mem->size, &adev->vram_usage);
- vis_size = amdgpu_get_vis_part_size(adev, new_mem);
- atomic64_add(vis_size, &adev->vram_vis_usage);
- break;
- }
- }
-
- if (old_mem) {
- switch (old_mem->mem_type) {
- case TTM_PL_TT:
- atomic64_sub(old_mem->size, &adev->gtt_usage);
- break;
- case TTM_PL_VRAM:
- atomic64_sub(old_mem->size, &adev->vram_usage);
- vis_size = amdgpu_get_vis_part_size(adev, old_mem);
- atomic64_sub(vis_size, &adev->vram_vis_usage);
- break;
- }
- }
-}
-
static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev);
@@ -93,7 +44,7 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo)
bo = container_of(tbo, struct amdgpu_bo, tbo);
- amdgpu_update_memory_usage(adev, &bo->tbo.mem, NULL);
+ amdgpu_bo_kunmap(bo);
drm_gem_object_release(&bo->gem_base);
amdgpu_bo_unref(&bo->parent);
@@ -219,7 +170,7 @@ static void amdgpu_fill_placement_to_bo(struct amdgpu_bo *bo,
}
/**
- * amdgpu_bo_create_kernel - create BO for kernel use
+ * amdgpu_bo_create_reserved - create reserved BO for kernel use
*
* @adev: amdgpu device object
* @size: size for the new BO
@@ -229,24 +180,30 @@ static void amdgpu_fill_placement_to_bo(struct amdgpu_bo *bo,
* @gpu_addr: GPU addr of the pinned BO
* @cpu_addr: optional CPU address mapping
*
- * Allocates and pins a BO for kernel internal use.
+ * Allocates and pins a BO for kernel internal use, and returns it still
+ * reserved.
*
* Returns 0 on success, negative error code otherwise.
*/
-int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
- unsigned long size, int align,
- u32 domain, struct amdgpu_bo **bo_ptr,
- u64 *gpu_addr, void **cpu_addr)
+int amdgpu_bo_create_reserved(struct amdgpu_device *adev,
+ unsigned long size, int align,
+ u32 domain, struct amdgpu_bo **bo_ptr,
+ u64 *gpu_addr, void **cpu_addr)
{
+ bool free = false;
int r;
- r = amdgpu_bo_create(adev, size, align, true, domain,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, bo_ptr);
- if (r) {
- dev_err(adev->dev, "(%d) failed to allocate kernel bo\n", r);
- return r;
+ if (!*bo_ptr) {
+ r = amdgpu_bo_create(adev, size, align, true, domain,
+ AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
+ AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
+ NULL, NULL, 0, bo_ptr);
+ if (r) {
+ dev_err(adev->dev, "(%d) failed to allocate kernel bo\n",
+ r);
+ return r;
+ }
+ free = true;
}
r = amdgpu_bo_reserve(*bo_ptr, false);
@@ -269,20 +226,52 @@ int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
}
}
- amdgpu_bo_unreserve(*bo_ptr);
-
return 0;
error_unreserve:
amdgpu_bo_unreserve(*bo_ptr);
error_free:
- amdgpu_bo_unref(bo_ptr);
+ if (free)
+ amdgpu_bo_unref(bo_ptr);
return r;
}
/**
+ * amdgpu_bo_create_kernel - create BO for kernel use
+ *
+ * @adev: amdgpu device object
+ * @size: size for the new BO
+ * @align: alignment for the new BO
+ * @domain: where to place it
+ * @bo_ptr: resulting BO
+ * @gpu_addr: GPU addr of the pinned BO
+ * @cpu_addr: optional CPU address mapping
+ *
+ * Allocates and pins a BO for kernel internal use.
+ *
+ * Returns 0 on success, negative error code otherwise.
+ */
+int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
+ unsigned long size, int align,
+ u32 domain, struct amdgpu_bo **bo_ptr,
+ u64 *gpu_addr, void **cpu_addr)
+{
+ int r;
+
+ r = amdgpu_bo_create_reserved(adev, size, align, domain, bo_ptr,
+ gpu_addr, cpu_addr);
+
+ if (r)
+ return r;
+
+ amdgpu_bo_unreserve(*bo_ptr);
+
+ return 0;
+}
+
+/**
* amdgpu_bo_free_kernel - free BO for kernel use
*
* @bo: amdgpu BO to free
@@ -317,12 +306,13 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
struct sg_table *sg,
struct ttm_placement *placement,
struct reservation_object *resv,
+ uint64_t init_value,
struct amdgpu_bo **bo_ptr)
{
struct amdgpu_bo *bo;
enum ttm_bo_type type;
unsigned long page_align;
- u64 initial_bytes_moved;
+ u64 initial_bytes_moved, bytes_moved;
size_t acc_size;
int r;
@@ -351,13 +341,13 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
}
INIT_LIST_HEAD(&bo->shadow_list);
INIT_LIST_HEAD(&bo->va);
- bo->prefered_domains = domain & (AMDGPU_GEM_DOMAIN_VRAM |
+ bo->preferred_domains = domain & (AMDGPU_GEM_DOMAIN_VRAM |
AMDGPU_GEM_DOMAIN_GTT |
AMDGPU_GEM_DOMAIN_CPU |
AMDGPU_GEM_DOMAIN_GDS |
AMDGPU_GEM_DOMAIN_GWS |
AMDGPU_GEM_DOMAIN_OA);
- bo->allowed_domains = bo->prefered_domains;
+ bo->allowed_domains = bo->preferred_domains;
if (!kernel && bo->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM)
bo->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT;
@@ -398,8 +388,14 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, type,
&bo->placement, page_align, !kernel, NULL,
acc_size, sg, resv, &amdgpu_ttm_bo_destroy);
- amdgpu_cs_report_moved_bytes(adev,
- atomic64_read(&adev->num_bytes_moved) - initial_bytes_moved);
+ bytes_moved = atomic64_read(&adev->num_bytes_moved) -
+ initial_bytes_moved;
+ if (adev->mc.visible_vram_size < adev->mc.real_vram_size &&
+ bo->tbo.mem.mem_type == TTM_PL_VRAM &&
+ bo->tbo.mem.start < adev->mc.visible_vram_size >> PAGE_SHIFT)
+ amdgpu_cs_report_moved_bytes(adev, bytes_moved, bytes_moved);
+ else
+ amdgpu_cs_report_moved_bytes(adev, bytes_moved, 0);
if (unlikely(r != 0))
return r;
@@ -411,7 +407,7 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
bo->tbo.mem.placement & TTM_PL_FLAG_VRAM) {
struct dma_fence *fence;
- r = amdgpu_fill_buffer(bo, 0, bo->tbo.resv, &fence);
+ r = amdgpu_fill_buffer(bo, init_value, bo->tbo.resv, &fence);
if (unlikely(r))
goto fail_unreserve;
@@ -426,6 +422,10 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
trace_amdgpu_bo_create(bo);
+ /* Treat CPU_ACCESS_REQUIRED only as a hint if given by UMD */
+ if (type == ttm_bo_type_device)
+ bo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
+
return 0;
fail_unreserve:
@@ -459,6 +459,7 @@ static int amdgpu_bo_create_shadow(struct amdgpu_device *adev,
AMDGPU_GEM_CREATE_CPU_GTT_USWC,
NULL, &placement,
bo->tbo.resv,
+ 0,
&bo->shadow);
if (!r) {
bo->shadow->parent = amdgpu_bo_ref(bo);
@@ -470,11 +471,15 @@ static int amdgpu_bo_create_shadow(struct amdgpu_device *adev,
return r;
}
+/* init_value will only take effect when flags contains
+ * AMDGPU_GEM_CREATE_VRAM_CLEARED.
+ */
int amdgpu_bo_create(struct amdgpu_device *adev,
unsigned long size, int byte_align,
bool kernel, u32 domain, u64 flags,
struct sg_table *sg,
struct reservation_object *resv,
+ uint64_t init_value,
struct amdgpu_bo **bo_ptr)
{
struct ttm_placement placement = {0};
@@ -489,7 +494,7 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
r = amdgpu_bo_create_restricted(adev, size, byte_align, kernel,
domain, flags, sg, &placement,
- resv, bo_ptr);
+ resv, init_value, bo_ptr);
if (r)
return r;
@@ -535,7 +540,7 @@ int amdgpu_bo_backup_to_shadow(struct amdgpu_device *adev,
r = amdgpu_copy_buffer(ring, bo_addr, shadow_addr,
amdgpu_bo_size(bo), resv, fence,
- direct);
+ direct, false);
if (!r)
amdgpu_bo_fence(bo, *fence, true);
@@ -551,7 +556,7 @@ int amdgpu_bo_validate(struct amdgpu_bo *bo)
if (bo->pin_count)
return 0;
- domain = bo->prefered_domains;
+ domain = bo->preferred_domains;
retry:
amdgpu_ttm_placement_from_domain(bo, domain);
@@ -588,7 +593,7 @@ int amdgpu_bo_restore_from_shadow(struct amdgpu_device *adev,
r = amdgpu_copy_buffer(ring, shadow_addr, bo_addr,
amdgpu_bo_size(bo), resv, fence,
- direct);
+ direct, false);
if (!r)
amdgpu_bo_fence(bo, *fence, true);
@@ -598,16 +603,16 @@ err:
int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr)
{
- bool is_iomem;
+ void *kptr;
long r;
if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)
return -EPERM;
- if (bo->kptr) {
- if (ptr) {
- *ptr = bo->kptr;
- }
+ kptr = amdgpu_bo_kptr(bo);
+ if (kptr) {
+ if (ptr)
+ *ptr = kptr;
return 0;
}
@@ -620,19 +625,23 @@ int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr)
if (r)
return r;
- bo->kptr = ttm_kmap_obj_virtual(&bo->kmap, &is_iomem);
if (ptr)
- *ptr = bo->kptr;
+ *ptr = amdgpu_bo_kptr(bo);
return 0;
}
+void *amdgpu_bo_kptr(struct amdgpu_bo *bo)
+{
+ bool is_iomem;
+
+ return ttm_kmap_obj_virtual(&bo->kmap, &is_iomem);
+}
+
void amdgpu_bo_kunmap(struct amdgpu_bo *bo)
{
- if (bo->kptr == NULL)
- return;
- bo->kptr = NULL;
- ttm_bo_kunmap(&bo->kmap);
+ if (bo->kmap.bo)
+ ttm_bo_kunmap(&bo->kmap);
}
struct amdgpu_bo *amdgpu_bo_ref(struct amdgpu_bo *bo)
@@ -724,15 +733,16 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
dev_err(adev->dev, "%p pin failed\n", bo);
goto error;
}
- r = amdgpu_ttm_bind(&bo->tbo, &bo->tbo.mem);
- if (unlikely(r)) {
- dev_err(adev->dev, "%p bind failed\n", bo);
- goto error;
- }
bo->pin_count = 1;
- if (gpu_addr != NULL)
+ if (gpu_addr != NULL) {
+ r = amdgpu_ttm_bind(&bo->tbo, &bo->tbo.mem);
+ if (unlikely(r)) {
+ dev_err(adev->dev, "%p bind failed\n", bo);
+ goto error;
+ }
*gpu_addr = amdgpu_bo_gpu_offset(bo);
+ }
if (domain == AMDGPU_GEM_DOMAIN_VRAM) {
adev->vram_pin_size += amdgpu_bo_size(bo);
if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)
@@ -921,6 +931,8 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
abo = container_of(bo, struct amdgpu_bo, tbo);
amdgpu_vm_bo_invalidate(adev, abo);
+ amdgpu_bo_kunmap(abo);
+
/* remember the eviction */
if (evict)
atomic64_inc(&adev->num_evictions);
@@ -930,8 +942,6 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
return;
/* move_notify is called before move happens */
- amdgpu_update_memory_usage(adev, &bo->mem, new_mem);
-
trace_amdgpu_ttm_bo_move(abo, new_mem->mem_type, old_mem->mem_type);
}
@@ -939,19 +949,22 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
struct amdgpu_bo *abo;
- unsigned long offset, size, lpfn;
- int i, r;
+ unsigned long offset, size;
+ int r;
if (!amdgpu_ttm_bo_is_amdgpu_bo(bo))
return 0;
abo = container_of(bo, struct amdgpu_bo, tbo);
+
+ /* Remember that this BO was accessed by the CPU */
+ abo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
+
if (bo->mem.mem_type != TTM_PL_VRAM)
return 0;
size = bo->mem.num_pages << PAGE_SHIFT;
offset = bo->mem.start << PAGE_SHIFT;
- /* TODO: figure out how to map scattered VRAM to the CPU */
if ((offset + size) <= adev->mc.visible_vram_size)
return 0;
@@ -961,26 +974,21 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
/* hurrah the memory is not visible ! */
atomic64_inc(&adev->num_vram_cpu_page_faults);
- amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM);
- lpfn = adev->mc.visible_vram_size >> PAGE_SHIFT;
- for (i = 0; i < abo->placement.num_placement; i++) {
- /* Force into visible VRAM */
- if ((abo->placements[i].flags & TTM_PL_FLAG_VRAM) &&
- (!abo->placements[i].lpfn ||
- abo->placements[i].lpfn > lpfn))
- abo->placements[i].lpfn = lpfn;
- }
+ amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM |
+ AMDGPU_GEM_DOMAIN_GTT);
+
+ /* Avoid costly evictions; only set GTT as a busy placement */
+ abo->placement.num_busy_placement = 1;
+ abo->placement.busy_placement = &abo->placements[1];
+
r = ttm_bo_validate(bo, &abo->placement, false, false);
- if (unlikely(r == -ENOMEM)) {
- amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_GTT);
- return ttm_bo_validate(bo, &abo->placement, false, false);
- } else if (unlikely(r != 0)) {
+ if (unlikely(r != 0))
return r;
- }
offset = bo->mem.start << PAGE_SHIFT;
/* this should never happen */
- if ((offset + size) > adev->mc.visible_vram_size)
+ if (bo->mem.mem_type == TTM_PL_VRAM &&
+ (offset + size) > adev->mc.visible_vram_size)
return -EINVAL;
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
index 382485115b06..a288fa6d72c8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -33,6 +33,61 @@
#define AMDGPU_BO_INVALID_OFFSET LONG_MAX
+/* bo virtual addresses in a vm */
+struct amdgpu_bo_va_mapping {
+ struct list_head list;
+ struct rb_node rb;
+ uint64_t start;
+ uint64_t last;
+ uint64_t __subtree_last;
+ uint64_t offset;
+ uint64_t flags;
+};
+
+/* User space allocated BO in a VM */
+struct amdgpu_bo_va {
+ struct amdgpu_vm_bo_base base;
+
+ /* protected by bo being reserved */
+ struct dma_fence *last_pt_update;
+ unsigned ref_count;
+
+ /* mappings for this bo_va */
+ struct list_head invalids;
+ struct list_head valids;
+};
+
+struct amdgpu_bo {
+ /* Protected by tbo.reserved */
+ u32 preferred_domains;
+ u32 allowed_domains;
+ struct ttm_place placements[AMDGPU_GEM_DOMAIN_MAX + 1];
+ struct ttm_placement placement;
+ struct ttm_buffer_object tbo;
+ struct ttm_bo_kmap_obj kmap;
+ u64 flags;
+ unsigned pin_count;
+ u64 tiling_flags;
+ u64 metadata_flags;
+ void *metadata;
+ u32 metadata_size;
+ unsigned prime_shared_count;
+ /* list of all virtual address to which this bo is associated to */
+ struct list_head va;
+ /* Constant after initialization */
+ struct drm_gem_object gem_base;
+ struct amdgpu_bo *parent;
+ struct amdgpu_bo *shadow;
+
+ struct ttm_bo_kmap_obj dma_buf_vmap;
+ struct amdgpu_mn *mn;
+
+ union {
+ struct list_head mn_list;
+ struct list_head shadow_list;
+ };
+};
+
/**
* amdgpu_mem_type_to_domain - return domain corresponding to mem_type
* @mem_type: ttm memory type
@@ -120,7 +175,11 @@ static inline u64 amdgpu_bo_mmap_offset(struct amdgpu_bo *bo)
*/
static inline bool amdgpu_bo_gpu_accessible(struct amdgpu_bo *bo)
{
- return bo->tbo.mem.mem_type != TTM_PL_SYSTEM;
+ switch (bo->tbo.mem.mem_type) {
+ case TTM_PL_TT: return amdgpu_ttm_is_bound(bo->tbo.ttm);
+ case TTM_PL_VRAM: return true;
+ default: return false;
+ }
}
int amdgpu_bo_create(struct amdgpu_device *adev,
@@ -128,6 +187,7 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
bool kernel, u32 domain, u64 flags,
struct sg_table *sg,
struct reservation_object *resv,
+ uint64_t init_value,
struct amdgpu_bo **bo_ptr);
int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
unsigned long size, int byte_align,
@@ -135,7 +195,12 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
struct sg_table *sg,
struct ttm_placement *placement,
struct reservation_object *resv,
+ uint64_t init_value,
struct amdgpu_bo **bo_ptr);
+int amdgpu_bo_create_reserved(struct amdgpu_device *adev,
+ unsigned long size, int align,
+ u32 domain, struct amdgpu_bo **bo_ptr,
+ u64 *gpu_addr, void **cpu_addr);
int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
unsigned long size, int align,
u32 domain, struct amdgpu_bo **bo_ptr,
@@ -143,6 +208,7 @@ int amdgpu_bo_create_kernel(struct amdgpu_device *adev,
void amdgpu_bo_free_kernel(struct amdgpu_bo **bo, u64 *gpu_addr,
void **cpu_addr);
int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr);
+void *amdgpu_bo_kptr(struct amdgpu_bo *bo);
void amdgpu_bo_kunmap(struct amdgpu_bo *bo);
struct amdgpu_bo *amdgpu_bo_ref(struct amdgpu_bo *bo);
void amdgpu_bo_unref(struct amdgpu_bo **bo);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h
index c19c4d138751..f21a7716b90e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h
@@ -30,6 +30,7 @@ struct cg_flag_name
const char *name;
};
+void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev);
int amdgpu_pm_sysfs_init(struct amdgpu_device *adev);
void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev);
void amdgpu_pm_print_power_states(struct amdgpu_device *adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
index 6bdc866570ab..5b3f92891f89 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
@@ -69,7 +69,7 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
ww_mutex_lock(&resv->lock, NULL);
ret = amdgpu_bo_create(adev, attach->dmabuf->size, PAGE_SIZE, false,
- AMDGPU_GEM_DOMAIN_GTT, 0, sg, resv, &bo);
+ AMDGPU_GEM_DOMAIN_GTT, 0, sg, resv, 0, &bo);
ww_mutex_unlock(&resv->lock);
if (ret)
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index 4083be61b328..8c2204c7b384 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -63,8 +63,13 @@ static int psp_sw_init(void *handle)
psp->smu_reload_quirk = psp_v3_1_smu_reload_quirk;
break;
case CHIP_RAVEN:
+#if 0
+ psp->init_microcode = psp_v10_0_init_microcode;
+#endif
psp->prep_cmd_buf = psp_v10_0_prep_cmd_buf;
psp->ring_init = psp_v10_0_ring_init;
+ psp->ring_create = psp_v10_0_ring_create;
+ psp->ring_destroy = psp_v10_0_ring_destroy;
psp->cmd_submit = psp_v10_0_cmd_submit;
psp->compare_sram_data = psp_v10_0_compare_sram_data;
break;
@@ -95,9 +100,8 @@ int psp_wait_for(struct psp_context *psp, uint32_t reg_index,
int i;
struct amdgpu_device *adev = psp->adev;
- val = RREG32(reg_index);
-
for (i = 0; i < adev->usec_timeout; i++) {
+ val = RREG32(reg_index);
if (check_changed) {
if (val != reg_val)
return 0;
@@ -118,33 +122,18 @@ psp_cmd_submit_buf(struct psp_context *psp,
int index)
{
int ret;
- struct amdgpu_bo *cmd_buf_bo;
- uint64_t cmd_buf_mc_addr;
- struct psp_gfx_cmd_resp *cmd_buf_mem;
- struct amdgpu_device *adev = psp->adev;
-
- ret = amdgpu_bo_create_kernel(adev, PSP_CMD_BUFFER_SIZE, PAGE_SIZE,
- AMDGPU_GEM_DOMAIN_VRAM,
- &cmd_buf_bo, &cmd_buf_mc_addr,
- (void **)&cmd_buf_mem);
- if (ret)
- return ret;
- memset(cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE);
+ memset(psp->cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE);
- memcpy(cmd_buf_mem, cmd, sizeof(struct psp_gfx_cmd_resp));
+ memcpy(psp->cmd_buf_mem, cmd, sizeof(struct psp_gfx_cmd_resp));
- ret = psp_cmd_submit(psp, ucode, cmd_buf_mc_addr,
+ ret = psp_cmd_submit(psp, ucode, psp->cmd_buf_mc_addr,
fence_mc_addr, index);
while (*((unsigned int *)psp->fence_buf) != index) {
msleep(1);
}
- amdgpu_bo_free_kernel(&cmd_buf_bo,
- &cmd_buf_mc_addr,
- (void **)&cmd_buf_mem);
-
return ret;
}
@@ -352,13 +341,20 @@ static int psp_load_fw(struct amdgpu_device *adev)
&psp->fence_buf_mc_addr,
&psp->fence_buf);
if (ret)
+ goto failed_mem2;
+
+ ret = amdgpu_bo_create_kernel(adev, PSP_CMD_BUFFER_SIZE, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &psp->cmd_buf_bo, &psp->cmd_buf_mc_addr,
+ (void **)&psp->cmd_buf_mem);
+ if (ret)
goto failed_mem1;
memset(psp->fence_buf, 0, PSP_FENCE_BUFFER_SIZE);
ret = psp_ring_init(psp, PSP_RING_TYPE__KM);
if (ret)
- goto failed_mem1;
+ goto failed_mem;
ret = psp_tmr_init(psp);
if (ret)
@@ -379,9 +375,13 @@ static int psp_load_fw(struct amdgpu_device *adev)
return 0;
failed_mem:
+ amdgpu_bo_free_kernel(&psp->cmd_buf_bo,
+ &psp->cmd_buf_mc_addr,
+ (void **)&psp->cmd_buf_mem);
+failed_mem1:
amdgpu_bo_free_kernel(&psp->fence_buf_bo,
&psp->fence_buf_mc_addr, &psp->fence_buf);
-failed_mem1:
+failed_mem2:
amdgpu_bo_free_kernel(&psp->fw_pri_bo,
&psp->fw_pri_mc_addr, &psp->fw_pri_buf);
failed:
@@ -435,16 +435,15 @@ static int psp_hw_fini(void *handle)
psp_ring_destroy(psp, PSP_RING_TYPE__KM);
- if (psp->tmr_buf)
- amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf);
-
- if (psp->fw_pri_buf)
- amdgpu_bo_free_kernel(&psp->fw_pri_bo,
- &psp->fw_pri_mc_addr, &psp->fw_pri_buf);
-
- if (psp->fence_buf_bo)
- amdgpu_bo_free_kernel(&psp->fence_buf_bo,
- &psp->fence_buf_mc_addr, &psp->fence_buf);
+ amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf);
+ amdgpu_bo_free_kernel(&psp->fw_pri_bo,
+ &psp->fw_pri_mc_addr, &psp->fw_pri_buf);
+ amdgpu_bo_free_kernel(&psp->fence_buf_bo,
+ &psp->fence_buf_mc_addr, &psp->fence_buf);
+ amdgpu_bo_free_kernel(&psp->asd_shared_bo, &psp->asd_shared_mc_addr,
+ &psp->asd_shared_buf);
+ amdgpu_bo_free_kernel(&psp->cmd_buf_bo, &psp->cmd_buf_mc_addr,
+ (void **)&psp->cmd_buf_mem);
kfree(psp->cmd);
psp->cmd = NULL;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
index 1a1c8b469f93..538fa9dbfb21 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
@@ -108,6 +108,11 @@ struct psp_context
struct amdgpu_bo *fence_buf_bo;
uint64_t fence_buf_mc_addr;
void *fence_buf;
+
+ /* cmd buffer */
+ struct amdgpu_bo *cmd_buf_bo;
+ uint64_t cmd_buf_mc_addr;
+ struct psp_gfx_cmd_resp *cmd_buf_mem;
};
struct amdgpu_psp_funcs {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
index 75165e07b1cd..6c5646b48d1a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -184,32 +184,16 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
return r;
}
- if (ring->funcs->support_64bit_ptrs) {
- r = amdgpu_wb_get_64bit(adev, &ring->rptr_offs);
- if (r) {
- dev_err(adev->dev, "(%d) ring rptr_offs wb alloc failed\n", r);
- return r;
- }
-
- r = amdgpu_wb_get_64bit(adev, &ring->wptr_offs);
- if (r) {
- dev_err(adev->dev, "(%d) ring wptr_offs wb alloc failed\n", r);
- return r;
- }
-
- } else {
- r = amdgpu_wb_get(adev, &ring->rptr_offs);
- if (r) {
- dev_err(adev->dev, "(%d) ring rptr_offs wb alloc failed\n", r);
- return r;
- }
-
- r = amdgpu_wb_get(adev, &ring->wptr_offs);
- if (r) {
- dev_err(adev->dev, "(%d) ring wptr_offs wb alloc failed\n", r);
- return r;
- }
+ r = amdgpu_wb_get(adev, &ring->rptr_offs);
+ if (r) {
+ dev_err(adev->dev, "(%d) ring rptr_offs wb alloc failed\n", r);
+ return r;
+ }
+ r = amdgpu_wb_get(adev, &ring->wptr_offs);
+ if (r) {
+ dev_err(adev->dev, "(%d) ring wptr_offs wb alloc failed\n", r);
+ return r;
}
r = amdgpu_wb_get(adev, &ring->fence_offs);
@@ -277,18 +261,15 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring)
{
ring->ready = false;
- if (ring->funcs->support_64bit_ptrs) {
- amdgpu_wb_free_64bit(ring->adev, ring->cond_exe_offs);
- amdgpu_wb_free_64bit(ring->adev, ring->fence_offs);
- amdgpu_wb_free_64bit(ring->adev, ring->rptr_offs);
- amdgpu_wb_free_64bit(ring->adev, ring->wptr_offs);
- } else {
- amdgpu_wb_free(ring->adev, ring->cond_exe_offs);
- amdgpu_wb_free(ring->adev, ring->fence_offs);
- amdgpu_wb_free(ring->adev, ring->rptr_offs);
- amdgpu_wb_free(ring->adev, ring->wptr_offs);
- }
+ /* Not to finish a ring which is not initialized */
+ if (!(ring->adev) || !(ring->adev->rings[ring->idx]))
+ return;
+
+ amdgpu_wb_free(ring->adev, ring->rptr_offs);
+ amdgpu_wb_free(ring->adev, ring->wptr_offs);
+ amdgpu_wb_free(ring->adev, ring->cond_exe_offs);
+ amdgpu_wb_free(ring->adev, ring->fence_offs);
amdgpu_bo_free_kernel(&ring->ring_obj,
&ring->gpu_addr,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
index bc8dec992f73..322d25299a00 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -212,4 +212,44 @@ static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring)
}
+static inline void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v)
+{
+ if (ring->count_dw <= 0)
+ DRM_ERROR("amdgpu: writing more dwords to the ring than expected!\n");
+ ring->ring[ring->wptr++ & ring->buf_mask] = v;
+ ring->wptr &= ring->ptr_mask;
+ ring->count_dw--;
+}
+
+static inline void amdgpu_ring_write_multiple(struct amdgpu_ring *ring,
+ void *src, int count_dw)
+{
+ unsigned occupied, chunk1, chunk2;
+ void *dst;
+
+ if (unlikely(ring->count_dw < count_dw))
+ DRM_ERROR("amdgpu: writing more dwords to the ring than expected!\n");
+
+ occupied = ring->wptr & ring->buf_mask;
+ dst = (void *)&ring->ring[occupied];
+ chunk1 = ring->buf_mask + 1 - occupied;
+ chunk1 = (chunk1 >= count_dw) ? count_dw: chunk1;
+ chunk2 = count_dw - chunk1;
+ chunk1 <<= 2;
+ chunk2 <<= 2;
+
+ if (chunk1)
+ memcpy(dst, src, chunk1);
+
+ if (chunk2) {
+ src += chunk1;
+ dst = (void *)ring->ring;
+ memcpy(dst, src, chunk2);
+ }
+
+ ring->wptr += count_dw;
+ ring->wptr &= ring->ptr_mask;
+ ring->count_dw -= count_dw;
+}
+
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
index 5ca75a456ad2..3144400435b7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
@@ -64,7 +64,7 @@ int amdgpu_sa_bo_manager_init(struct amdgpu_device *adev,
INIT_LIST_HEAD(&sa_manager->flist[i]);
r = amdgpu_bo_create(adev, size, align, true, domain,
- 0, NULL, NULL, &sa_manager->bo);
+ 0, NULL, NULL, 0, &sa_manager->bo);
if (r) {
dev_err(adev->dev, "(%d) failed to allocate bo for manager\n", r);
return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
index a6899180b265..c586f44312f9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
@@ -244,6 +244,12 @@ struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync,
struct dma_fence *f = e->fence;
struct amd_sched_fence *s_fence = to_amd_sched_fence(f);
+ if (dma_fence_is_signaled(f)) {
+ hash_del(&e->node);
+ dma_fence_put(f);
+ kmem_cache_free(amdgpu_sync_slab, e);
+ continue;
+ }
if (ring && s_fence) {
/* For fences from the same ring it is sufficient
* when they are scheduled.
@@ -256,13 +262,6 @@ struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync,
}
}
- if (dma_fence_is_signaled(f)) {
- hash_del(&e->node);
- dma_fence_put(f);
- kmem_cache_free(amdgpu_sync_slab, e);
- continue;
- }
-
return f;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
index 15510dadde01..ed8c3739015b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c
@@ -33,7 +33,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
struct amdgpu_bo *vram_obj = NULL;
struct amdgpu_bo **gtt_obj = NULL;
- uint64_t gtt_addr, vram_addr;
+ uint64_t gart_addr, vram_addr;
unsigned n, size;
int i, r;
@@ -42,7 +42,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
/* Number of tests =
* (Total GTT - IB pool - writeback page - ring buffers) / test size
*/
- n = adev->mc.gtt_size - AMDGPU_IB_POOL_SIZE*64*1024;
+ n = adev->mc.gart_size - AMDGPU_IB_POOL_SIZE*64*1024;
for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
if (adev->rings[i])
n -= adev->rings[i]->ring_size;
@@ -61,7 +61,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
r = amdgpu_bo_create(adev, size, PAGE_SIZE, true,
AMDGPU_GEM_DOMAIN_VRAM, 0,
- NULL, NULL, &vram_obj);
+ NULL, NULL, 0, &vram_obj);
if (r) {
DRM_ERROR("Failed to create VRAM object\n");
goto out_cleanup;
@@ -76,13 +76,13 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
}
for (i = 0; i < n; i++) {
void *gtt_map, *vram_map;
- void **gtt_start, **gtt_end;
+ void **gart_start, **gart_end;
void **vram_start, **vram_end;
struct dma_fence *fence = NULL;
r = amdgpu_bo_create(adev, size, PAGE_SIZE, true,
AMDGPU_GEM_DOMAIN_GTT, 0, NULL,
- NULL, gtt_obj + i);
+ NULL, 0, gtt_obj + i);
if (r) {
DRM_ERROR("Failed to create GTT object %d\n", i);
goto out_lclean;
@@ -91,7 +91,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
r = amdgpu_bo_reserve(gtt_obj[i], false);
if (unlikely(r != 0))
goto out_lclean_unref;
- r = amdgpu_bo_pin(gtt_obj[i], AMDGPU_GEM_DOMAIN_GTT, &gtt_addr);
+ r = amdgpu_bo_pin(gtt_obj[i], AMDGPU_GEM_DOMAIN_GTT, &gart_addr);
if (r) {
DRM_ERROR("Failed to pin GTT object %d\n", i);
goto out_lclean_unres;
@@ -103,15 +103,15 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
goto out_lclean_unpin;
}
- for (gtt_start = gtt_map, gtt_end = gtt_map + size;
- gtt_start < gtt_end;
- gtt_start++)
- *gtt_start = gtt_start;
+ for (gart_start = gtt_map, gart_end = gtt_map + size;
+ gart_start < gart_end;
+ gart_start++)
+ *gart_start = gart_start;
amdgpu_bo_kunmap(gtt_obj[i]);
- r = amdgpu_copy_buffer(ring, gtt_addr, vram_addr,
- size, NULL, &fence, false);
+ r = amdgpu_copy_buffer(ring, gart_addr, vram_addr,
+ size, NULL, &fence, false, false);
if (r) {
DRM_ERROR("Failed GTT->VRAM copy %d\n", i);
@@ -132,21 +132,21 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
goto out_lclean_unpin;
}
- for (gtt_start = gtt_map, gtt_end = gtt_map + size,
+ for (gart_start = gtt_map, gart_end = gtt_map + size,
vram_start = vram_map, vram_end = vram_map + size;
vram_start < vram_end;
- gtt_start++, vram_start++) {
- if (*vram_start != gtt_start) {
+ gart_start++, vram_start++) {
+ if (*vram_start != gart_start) {
DRM_ERROR("Incorrect GTT->VRAM copy %d: Got 0x%p, "
"expected 0x%p (GTT/VRAM offset "
"0x%16llx/0x%16llx)\n",
- i, *vram_start, gtt_start,
+ i, *vram_start, gart_start,
(unsigned long long)
- (gtt_addr - adev->mc.gtt_start +
- (void*)gtt_start - gtt_map),
+ (gart_addr - adev->mc.gart_start +
+ (void*)gart_start - gtt_map),
(unsigned long long)
(vram_addr - adev->mc.vram_start +
- (void*)gtt_start - gtt_map));
+ (void*)gart_start - gtt_map));
amdgpu_bo_kunmap(vram_obj);
goto out_lclean_unpin;
}
@@ -155,8 +155,8 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
amdgpu_bo_kunmap(vram_obj);
- r = amdgpu_copy_buffer(ring, vram_addr, gtt_addr,
- size, NULL, &fence, false);
+ r = amdgpu_copy_buffer(ring, vram_addr, gart_addr,
+ size, NULL, &fence, false, false);
if (r) {
DRM_ERROR("Failed VRAM->GTT copy %d\n", i);
@@ -177,20 +177,20 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
goto out_lclean_unpin;
}
- for (gtt_start = gtt_map, gtt_end = gtt_map + size,
+ for (gart_start = gtt_map, gart_end = gtt_map + size,
vram_start = vram_map, vram_end = vram_map + size;
- gtt_start < gtt_end;
- gtt_start++, vram_start++) {
- if (*gtt_start != vram_start) {
+ gart_start < gart_end;
+ gart_start++, vram_start++) {
+ if (*gart_start != vram_start) {
DRM_ERROR("Incorrect VRAM->GTT copy %d: Got 0x%p, "
"expected 0x%p (VRAM/GTT offset "
"0x%16llx/0x%16llx)\n",
- i, *gtt_start, vram_start,
+ i, *gart_start, vram_start,
(unsigned long long)
(vram_addr - adev->mc.vram_start +
(void*)vram_start - vram_map),
(unsigned long long)
- (gtt_addr - adev->mc.gtt_start +
+ (gart_addr - adev->mc.gart_start +
(void*)vram_start - vram_map));
amdgpu_bo_kunmap(gtt_obj[i]);
goto out_lclean_unpin;
@@ -200,7 +200,7 @@ static void amdgpu_do_test_moves(struct amdgpu_device *adev)
amdgpu_bo_kunmap(gtt_obj[i]);
DRM_INFO("Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x%llx\n",
- gtt_addr - adev->mc.gtt_start);
+ gart_addr - adev->mc.gart_start);
continue;
out_lclean_unpin:
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
index 8601904e670a..1c88bd5e29ad 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h
@@ -14,6 +14,62 @@
#define AMDGPU_JOB_GET_TIMELINE_NAME(job) \
job->base.s_fence->finished.ops->get_timeline_name(&job->base.s_fence->finished)
+TRACE_EVENT(amdgpu_ttm_tt_populate,
+ TP_PROTO(struct amdgpu_device *adev, uint64_t dma_address, uint64_t phys_address),
+ TP_ARGS(adev, dma_address, phys_address),
+ TP_STRUCT__entry(
+ __field(uint16_t, domain)
+ __field(uint8_t, bus)
+ __field(uint8_t, slot)
+ __field(uint8_t, func)
+ __field(uint64_t, dma)
+ __field(uint64_t, phys)
+ ),
+ TP_fast_assign(
+ __entry->domain = pci_domain_nr(adev->pdev->bus);
+ __entry->bus = adev->pdev->bus->number;
+ __entry->slot = PCI_SLOT(adev->pdev->devfn);
+ __entry->func = PCI_FUNC(adev->pdev->devfn);
+ __entry->dma = dma_address;
+ __entry->phys = phys_address;
+ ),
+ TP_printk("%04x:%02x:%02x.%x: 0x%llx => 0x%llx",
+ (unsigned)__entry->domain,
+ (unsigned)__entry->bus,
+ (unsigned)__entry->slot,
+ (unsigned)__entry->func,
+ (unsigned long long)__entry->dma,
+ (unsigned long long)__entry->phys)
+);
+
+TRACE_EVENT(amdgpu_ttm_tt_unpopulate,
+ TP_PROTO(struct amdgpu_device *adev, uint64_t dma_address, uint64_t phys_address),
+ TP_ARGS(adev, dma_address, phys_address),
+ TP_STRUCT__entry(
+ __field(uint16_t, domain)
+ __field(uint8_t, bus)
+ __field(uint8_t, slot)
+ __field(uint8_t, func)
+ __field(uint64_t, dma)
+ __field(uint64_t, phys)
+ ),
+ TP_fast_assign(
+ __entry->domain = pci_domain_nr(adev->pdev->bus);
+ __entry->bus = adev->pdev->bus->number;
+ __entry->slot = PCI_SLOT(adev->pdev->devfn);
+ __entry->func = PCI_FUNC(adev->pdev->devfn);
+ __entry->dma = dma_address;
+ __entry->phys = phys_address;
+ ),
+ TP_printk("%04x:%02x:%02x.%x: 0x%llx => 0x%llx",
+ (unsigned)__entry->domain,
+ (unsigned)__entry->bus,
+ (unsigned)__entry->slot,
+ (unsigned)__entry->func,
+ (unsigned long long)__entry->dma,
+ (unsigned long long)__entry->phys)
+);
+
TRACE_EVENT(amdgpu_mm_rreg,
TP_PROTO(unsigned did, uint32_t reg, uint32_t value),
TP_ARGS(did, reg, value),
@@ -105,12 +161,12 @@ TRACE_EVENT(amdgpu_bo_create,
__entry->bo = bo;
__entry->pages = bo->tbo.num_pages;
__entry->type = bo->tbo.mem.mem_type;
- __entry->prefer = bo->prefered_domains;
+ __entry->prefer = bo->preferred_domains;
__entry->allow = bo->allowed_domains;
__entry->visible = bo->flags;
),
- TP_printk("bo=%p, pages=%u, type=%d, prefered=%d, allowed=%d, visible=%d",
+ TP_printk("bo=%p, pages=%u, type=%d, preferred=%d, allowed=%d, visible=%d",
__entry->bo, __entry->pages, __entry->type,
__entry->prefer, __entry->allow, __entry->visible)
);
@@ -224,17 +280,17 @@ TRACE_EVENT(amdgpu_vm_bo_map,
__field(long, start)
__field(long, last)
__field(u64, offset)
- __field(u32, flags)
+ __field(u64, flags)
),
TP_fast_assign(
- __entry->bo = bo_va ? bo_va->bo : NULL;
+ __entry->bo = bo_va ? bo_va->base.bo : NULL;
__entry->start = mapping->start;
__entry->last = mapping->last;
__entry->offset = mapping->offset;
__entry->flags = mapping->flags;
),
- TP_printk("bo=%p, start=%lx, last=%lx, offset=%010llx, flags=%08x",
+ TP_printk("bo=%p, start=%lx, last=%lx, offset=%010llx, flags=%llx",
__entry->bo, __entry->start, __entry->last,
__entry->offset, __entry->flags)
);
@@ -248,17 +304,17 @@ TRACE_EVENT(amdgpu_vm_bo_unmap,
__field(long, start)
__field(long, last)
__field(u64, offset)
- __field(u32, flags)
+ __field(u64, flags)
),
TP_fast_assign(
- __entry->bo = bo_va->bo;
+ __entry->bo = bo_va->base.bo;
__entry->start = mapping->start;
__entry->last = mapping->last;
__entry->offset = mapping->offset;
__entry->flags = mapping->flags;
),
- TP_printk("bo=%p, start=%lx, last=%lx, offset=%010llx, flags=%08x",
+ TP_printk("bo=%p, start=%lx, last=%lx, offset=%010llx, flags=%llx",
__entry->bo, __entry->start, __entry->last,
__entry->offset, __entry->flags)
);
@@ -269,7 +325,7 @@ DECLARE_EVENT_CLASS(amdgpu_vm_mapping,
TP_STRUCT__entry(
__field(u64, soffset)
__field(u64, eoffset)
- __field(u32, flags)
+ __field(u64, flags)
),
TP_fast_assign(
@@ -277,7 +333,7 @@ DECLARE_EVENT_CLASS(amdgpu_vm_mapping,
__entry->eoffset = mapping->last + 1;
__entry->flags = mapping->flags;
),
- TP_printk("soffs=%010llx, eoffs=%010llx, flags=%08x",
+ TP_printk("soffs=%010llx, eoffs=%010llx, flags=%llx",
__entry->soffset, __entry->eoffset, __entry->flags)
);
@@ -293,14 +349,14 @@ DEFINE_EVENT(amdgpu_vm_mapping, amdgpu_vm_bo_mapping,
TRACE_EVENT(amdgpu_vm_set_ptes,
TP_PROTO(uint64_t pe, uint64_t addr, unsigned count,
- uint32_t incr, uint32_t flags),
+ uint32_t incr, uint64_t flags),
TP_ARGS(pe, addr, count, incr, flags),
TP_STRUCT__entry(
__field(u64, pe)
__field(u64, addr)
__field(u32, count)
__field(u32, incr)
- __field(u32, flags)
+ __field(u64, flags)
),
TP_fast_assign(
@@ -310,7 +366,7 @@ TRACE_EVENT(amdgpu_vm_set_ptes,
__entry->incr = incr;
__entry->flags = flags;
),
- TP_printk("pe=%010Lx, addr=%010Lx, incr=%u, flags=%08x, count=%u",
+ TP_printk("pe=%010Lx, addr=%010Lx, incr=%u, flags=%llx, count=%u",
__entry->pe, __entry->addr, __entry->incr,
__entry->flags, __entry->count)
);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index c9b131b13ef7..8b2c294f6f79 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -43,14 +43,20 @@
#include <linux/pagemap.h>
#include <linux/debugfs.h>
#include "amdgpu.h"
+#include "amdgpu_trace.h"
#include "bif/bif_4_1_d.h"
#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
+static int amdgpu_map_buffer(struct ttm_buffer_object *bo,
+ struct ttm_mem_reg *mem, unsigned num_pages,
+ uint64_t offset, unsigned window,
+ struct amdgpu_ring *ring,
+ uint64_t *addr);
+
static int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev);
static void amdgpu_ttm_debugfs_fini(struct amdgpu_device *adev);
-
/*
* Global memory.
*/
@@ -97,6 +103,8 @@ static int amdgpu_ttm_global_init(struct amdgpu_device *adev)
goto error_bo;
}
+ mutex_init(&adev->mman.gtt_window_lock);
+
ring = adev->mman.buffer_funcs_ring;
rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_KERNEL];
r = amd_sched_entity_init(&ring->sched, &adev->mman.entity,
@@ -123,6 +131,7 @@ static void amdgpu_ttm_global_fini(struct amdgpu_device *adev)
if (adev->mman.mem_global_referenced) {
amd_sched_entity_fini(adev->mman.entity.sched,
&adev->mman.entity);
+ mutex_destroy(&adev->mman.gtt_window_lock);
drm_global_item_unref(&adev->mman.bo_global_ref.ref);
drm_global_item_unref(&adev->mman.mem_global_ref);
adev->mman.mem_global_referenced = false;
@@ -150,7 +159,7 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
break;
case TTM_PL_TT:
man->func = &amdgpu_gtt_mgr_func;
- man->gpu_offset = adev->mc.gtt_start;
+ man->gpu_offset = adev->mc.gart_start;
man->available_caching = TTM_PL_MASK_CACHING;
man->default_caching = TTM_PL_FLAG_CACHED;
man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | TTM_MEMTYPE_FLAG_CMA;
@@ -186,12 +195,11 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
{
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
struct amdgpu_bo *abo;
- static struct ttm_place placements = {
+ static const struct ttm_place placements = {
.fpfn = 0,
.lpfn = 0,
.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM
};
- unsigned i;
if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) {
placement->placement = &placements;
@@ -207,22 +215,36 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
adev->mman.buffer_funcs_ring &&
adev->mman.buffer_funcs_ring->ready == false) {
amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_CPU);
+ } else if (adev->mc.visible_vram_size < adev->mc.real_vram_size &&
+ !(abo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)) {
+ unsigned fpfn = adev->mc.visible_vram_size >> PAGE_SHIFT;
+ struct drm_mm_node *node = bo->mem.mm_node;
+ unsigned long pages_left;
+
+ for (pages_left = bo->mem.num_pages;
+ pages_left;
+ pages_left -= node->size, node++) {
+ if (node->start < fpfn)
+ break;
+ }
+
+ if (!pages_left)
+ goto gtt;
+
+ /* Try evicting to the CPU inaccessible part of VRAM
+ * first, but only set GTT as busy placement, so this
+ * BO will be evicted to GTT rather than causing other
+ * BOs to be evicted from VRAM
+ */
+ amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM |
+ AMDGPU_GEM_DOMAIN_GTT);
+ abo->placements[0].fpfn = fpfn;
+ abo->placements[0].lpfn = 0;
+ abo->placement.busy_placement = &abo->placements[1];
+ abo->placement.num_busy_placement = 1;
} else {
+gtt:
amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_GTT);
- for (i = 0; i < abo->placement.num_placement; ++i) {
- if (!(abo->placements[i].flags &
- TTM_PL_FLAG_TT))
- continue;
-
- if (abo->placements[i].lpfn)
- continue;
-
- /* set an upper limit to force directly
- * allocating address space for the BO.
- */
- abo->placements[i].lpfn =
- adev->mc.gtt_size >> PAGE_SHIFT;
- }
}
break;
case TTM_PL_TT:
@@ -252,29 +274,18 @@ static void amdgpu_move_null(struct ttm_buffer_object *bo,
new_mem->mm_node = NULL;
}
-static int amdgpu_mm_node_addr(struct ttm_buffer_object *bo,
- struct drm_mm_node *mm_node,
- struct ttm_mem_reg *mem,
- uint64_t *addr)
+static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo,
+ struct drm_mm_node *mm_node,
+ struct ttm_mem_reg *mem)
{
- int r;
+ uint64_t addr = 0;
- switch (mem->mem_type) {
- case TTM_PL_TT:
- r = amdgpu_ttm_bind(bo, mem);
- if (r)
- return r;
-
- case TTM_PL_VRAM:
- *addr = mm_node->start << PAGE_SHIFT;
- *addr += bo->bdev->man[mem->mem_type].gpu_offset;
- break;
- default:
- DRM_ERROR("Unknown placement %d\n", mem->mem_type);
- return -EINVAL;
+ if (mem->mem_type != TTM_PL_TT ||
+ amdgpu_gtt_mgr_is_allocated(mem)) {
+ addr = mm_node->start << PAGE_SHIFT;
+ addr += bo->bdev->man[mem->mem_type].gpu_offset;
}
-
- return 0;
+ return addr;
}
static int amdgpu_move_blit(struct ttm_buffer_object *bo,
@@ -299,26 +310,40 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
}
old_mm = old_mem->mm_node;
- r = amdgpu_mm_node_addr(bo, old_mm, old_mem, &old_start);
- if (r)
- return r;
old_size = old_mm->size;
-
+ old_start = amdgpu_mm_node_addr(bo, old_mm, old_mem);
new_mm = new_mem->mm_node;
- r = amdgpu_mm_node_addr(bo, new_mm, new_mem, &new_start);
- if (r)
- return r;
new_size = new_mm->size;
+ new_start = amdgpu_mm_node_addr(bo, new_mm, new_mem);
num_pages = new_mem->num_pages;
+ mutex_lock(&adev->mman.gtt_window_lock);
while (num_pages) {
- unsigned long cur_pages = min(old_size, new_size);
+ unsigned long cur_pages = min(min(old_size, new_size),
+ (u64)AMDGPU_GTT_MAX_TRANSFER_SIZE);
+ uint64_t from = old_start, to = new_start;
struct dma_fence *next;
- r = amdgpu_copy_buffer(ring, old_start, new_start,
+ if (old_mem->mem_type == TTM_PL_TT &&
+ !amdgpu_gtt_mgr_is_allocated(old_mem)) {
+ r = amdgpu_map_buffer(bo, old_mem, cur_pages,
+ old_start, 0, ring, &from);
+ if (r)
+ goto error;
+ }
+
+ if (new_mem->mem_type == TTM_PL_TT &&
+ !amdgpu_gtt_mgr_is_allocated(new_mem)) {
+ r = amdgpu_map_buffer(bo, new_mem, cur_pages,
+ new_start, 1, ring, &to);
+ if (r)
+ goto error;
+ }
+
+ r = amdgpu_copy_buffer(ring, from, to,
cur_pages * PAGE_SIZE,
- bo->resv, &next, false);
+ bo->resv, &next, false, true);
if (r)
goto error;
@@ -331,10 +356,7 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
old_size -= cur_pages;
if (!old_size) {
- r = amdgpu_mm_node_addr(bo, ++old_mm, old_mem,
- &old_start);
- if (r)
- goto error;
+ old_start = amdgpu_mm_node_addr(bo, ++old_mm, old_mem);
old_size = old_mm->size;
} else {
old_start += cur_pages * PAGE_SIZE;
@@ -342,22 +364,21 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
new_size -= cur_pages;
if (!new_size) {
- r = amdgpu_mm_node_addr(bo, ++new_mm, new_mem,
- &new_start);
- if (r)
- goto error;
-
+ new_start = amdgpu_mm_node_addr(bo, ++new_mm, new_mem);
new_size = new_mm->size;
} else {
new_start += cur_pages * PAGE_SIZE;
}
}
+ mutex_unlock(&adev->mman.gtt_window_lock);
r = ttm_bo_pipeline_move(bo, fence, evict, new_mem);
dma_fence_put(fence);
return r;
error:
+ mutex_unlock(&adev->mman.gtt_window_lock);
+
if (fence)
dma_fence_wait(fence, false);
dma_fence_put(fence);
@@ -384,7 +405,7 @@ static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo,
placement.num_busy_placement = 1;
placement.busy_placement = &placements;
placements.fpfn = 0;
- placements.lpfn = adev->mc.gtt_size >> PAGE_SHIFT;
+ placements.lpfn = 0;
placements.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
r = ttm_bo_mem_space(bo, &placement, &tmp_mem,
interruptible, no_wait_gpu);
@@ -431,7 +452,7 @@ static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo,
placement.num_busy_placement = 1;
placement.busy_placement = &placements;
placements.fpfn = 0;
- placements.lpfn = adev->mc.gtt_size >> PAGE_SHIFT;
+ placements.lpfn = 0;
placements.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
r = ttm_bo_mem_space(bo, &placement, &tmp_mem,
interruptible, no_wait_gpu);
@@ -507,6 +528,15 @@ memcpy:
}
}
+ if (bo->type == ttm_bo_type_device &&
+ new_mem->mem_type == TTM_PL_VRAM &&
+ old_mem->mem_type != TTM_PL_VRAM) {
+ /* amdgpu_bo_fault_reserve_notify will re-set this if the CPU
+ * accesses the BO after it's moved.
+ */
+ abo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
+ }
+
/* update statistics */
atomic64_add((u64)bo->num_pages << PAGE_SHIFT, &adev->num_bytes_moved);
return 0;
@@ -633,6 +663,38 @@ release_pages:
return r;
}
+static void amdgpu_trace_dma_map(struct ttm_tt *ttm)
+{
+ struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
+ struct amdgpu_ttm_tt *gtt = (void *)ttm;
+ unsigned i;
+
+ if (unlikely(trace_amdgpu_ttm_tt_populate_enabled())) {
+ for (i = 0; i < ttm->num_pages; i++) {
+ trace_amdgpu_ttm_tt_populate(
+ adev,
+ gtt->ttm.dma_address[i],
+ page_to_phys(ttm->pages[i]));
+ }
+ }
+}
+
+static void amdgpu_trace_dma_unmap(struct ttm_tt *ttm)
+{
+ struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
+ struct amdgpu_ttm_tt *gtt = (void *)ttm;
+ unsigned i;
+
+ if (unlikely(trace_amdgpu_ttm_tt_unpopulate_enabled())) {
+ for (i = 0; i < ttm->num_pages; i++) {
+ trace_amdgpu_ttm_tt_unpopulate(
+ adev,
+ gtt->ttm.dma_address[i],
+ page_to_phys(ttm->pages[i]));
+ }
+ }
+}
+
/* prepare the sg table with the user pages */
static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
{
@@ -659,6 +721,8 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
gtt->ttm.dma_address, ttm->num_pages);
+ amdgpu_trace_dma_map(ttm);
+
return 0;
release_sg:
@@ -692,14 +756,41 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
put_page(page);
}
+ amdgpu_trace_dma_unmap(ttm);
+
sg_free_table(ttm->sg);
}
+static int amdgpu_ttm_do_bind(struct ttm_tt *ttm, struct ttm_mem_reg *mem)
+{
+ struct amdgpu_ttm_tt *gtt = (void *)ttm;
+ uint64_t flags;
+ int r;
+
+ spin_lock(&gtt->adev->gtt_list_lock);
+ flags = amdgpu_ttm_tt_pte_flags(gtt->adev, ttm, mem);
+ gtt->offset = (u64)mem->start << PAGE_SHIFT;
+ r = amdgpu_gart_bind(gtt->adev, gtt->offset, ttm->num_pages,
+ ttm->pages, gtt->ttm.dma_address, flags);
+
+ if (r) {
+ DRM_ERROR("failed to bind %lu pages at 0x%08llX\n",
+ ttm->num_pages, gtt->offset);
+ goto error_gart_bind;
+ }
+
+ list_add_tail(&gtt->list, &gtt->adev->gtt_list);
+error_gart_bind:
+ spin_unlock(&gtt->adev->gtt_list_lock);
+ return r;
+
+}
+
static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm,
struct ttm_mem_reg *bo_mem)
{
struct amdgpu_ttm_tt *gtt = (void*)ttm;
- int r;
+ int r = 0;
if (gtt->userptr) {
r = amdgpu_ttm_tt_pin_userptr(ttm);
@@ -718,7 +809,10 @@ static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm,
bo_mem->mem_type == AMDGPU_PL_OA)
return -EINVAL;
- return 0;
+ if (amdgpu_gtt_mgr_is_allocated(bo_mem))
+ r = amdgpu_ttm_do_bind(ttm, bo_mem);
+
+ return r;
}
bool amdgpu_ttm_is_bound(struct ttm_tt *ttm)
@@ -731,8 +825,6 @@ bool amdgpu_ttm_is_bound(struct ttm_tt *ttm)
int amdgpu_ttm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *bo_mem)
{
struct ttm_tt *ttm = bo->ttm;
- struct amdgpu_ttm_tt *gtt = (void *)bo->ttm;
- uint64_t flags;
int r;
if (!ttm || amdgpu_ttm_is_bound(ttm))
@@ -745,22 +837,7 @@ int amdgpu_ttm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *bo_mem)
return r;
}
- spin_lock(&gtt->adev->gtt_list_lock);
- flags = amdgpu_ttm_tt_pte_flags(gtt->adev, ttm, bo_mem);
- gtt->offset = (u64)bo_mem->start << PAGE_SHIFT;
- r = amdgpu_gart_bind(gtt->adev, gtt->offset, ttm->num_pages,
- ttm->pages, gtt->ttm.dma_address, flags);
-
- if (r) {
- DRM_ERROR("failed to bind %lu pages at 0x%08llX\n",
- ttm->num_pages, gtt->offset);
- goto error_gart_bind;
- }
-
- list_add_tail(&gtt->list, &gtt->adev->gtt_list);
-error_gart_bind:
- spin_unlock(&gtt->adev->gtt_list_lock);
- return r;
+ return amdgpu_ttm_do_bind(ttm, bo_mem);
}
int amdgpu_ttm_recover_gart(struct amdgpu_device *adev)
@@ -852,7 +929,7 @@ static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_bo_device *bdev,
static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm)
{
- struct amdgpu_device *adev;
+ struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
struct amdgpu_ttm_tt *gtt = (void *)ttm;
unsigned i;
int r;
@@ -875,14 +952,14 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm)
drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
gtt->ttm.dma_address, ttm->num_pages);
ttm->state = tt_unbound;
- return 0;
+ r = 0;
+ goto trace_mappings;
}
- adev = amdgpu_ttm_adev(ttm->bdev);
-
#ifdef CONFIG_SWIOTLB
if (swiotlb_nr_tbl()) {
- return ttm_dma_populate(&gtt->ttm, adev->dev);
+ r = ttm_dma_populate(&gtt->ttm, adev->dev);
+ goto trace_mappings;
}
#endif
@@ -905,7 +982,12 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm)
return -EFAULT;
}
}
- return 0;
+
+ r = 0;
+trace_mappings:
+ if (likely(!r))
+ amdgpu_trace_dma_map(ttm);
+ return r;
}
static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm)
@@ -926,6 +1008,8 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm)
adev = amdgpu_ttm_adev(ttm->bdev);
+ amdgpu_trace_dma_unmap(ttm);
+
#ifdef CONFIG_SWIOTLB
if (swiotlb_nr_tbl()) {
ttm_dma_unpopulate(&gtt->ttm, adev->dev);
@@ -1075,6 +1159,67 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
return ttm_bo_eviction_valuable(bo, place);
}
+static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo,
+ unsigned long offset,
+ void *buf, int len, int write)
+{
+ struct amdgpu_bo *abo = container_of(bo, struct amdgpu_bo, tbo);
+ struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev);
+ struct drm_mm_node *nodes = abo->tbo.mem.mm_node;
+ uint32_t value = 0;
+ int ret = 0;
+ uint64_t pos;
+ unsigned long flags;
+
+ if (bo->mem.mem_type != TTM_PL_VRAM)
+ return -EIO;
+
+ while (offset >= (nodes->size << PAGE_SHIFT)) {
+ offset -= nodes->size << PAGE_SHIFT;
+ ++nodes;
+ }
+ pos = (nodes->start << PAGE_SHIFT) + offset;
+
+ while (len && pos < adev->mc.mc_vram_size) {
+ uint64_t aligned_pos = pos & ~(uint64_t)3;
+ uint32_t bytes = 4 - (pos & 3);
+ uint32_t shift = (pos & 3) * 8;
+ uint32_t mask = 0xffffffff << shift;
+
+ if (len < bytes) {
+ mask &= 0xffffffff >> (bytes - len) * 8;
+ bytes = len;
+ }
+
+ spin_lock_irqsave(&adev->mmio_idx_lock, flags);
+ WREG32(mmMM_INDEX, ((uint32_t)aligned_pos) | 0x80000000);
+ WREG32(mmMM_INDEX_HI, aligned_pos >> 31);
+ if (!write || mask != 0xffffffff)
+ value = RREG32(mmMM_DATA);
+ if (write) {
+ value &= ~mask;
+ value |= (*(uint32_t *)buf << shift) & mask;
+ WREG32(mmMM_DATA, value);
+ }
+ spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
+ if (!write) {
+ value = (value & mask) >> shift;
+ memcpy(buf, &value, bytes);
+ }
+
+ ret += bytes;
+ buf = (uint8_t *)buf + bytes;
+ pos += bytes;
+ len -= bytes;
+ if (pos >= (nodes->start + nodes->size) << PAGE_SHIFT) {
+ ++nodes;
+ pos = (nodes->start << PAGE_SHIFT);
+ }
+ }
+
+ return ret;
+}
+
static struct ttm_bo_driver amdgpu_bo_driver = {
.ttm_tt_create = &amdgpu_ttm_tt_create,
.ttm_tt_populate = &amdgpu_ttm_tt_populate,
@@ -1090,11 +1235,14 @@ static struct ttm_bo_driver amdgpu_bo_driver = {
.io_mem_reserve = &amdgpu_ttm_io_mem_reserve,
.io_mem_free = &amdgpu_ttm_io_mem_free,
.io_mem_pfn = amdgpu_ttm_io_mem_pfn,
+ .access_memory = &amdgpu_ttm_access_memory
};
int amdgpu_ttm_init(struct amdgpu_device *adev)
{
+ uint64_t gtt_size;
int r;
+ u64 vis_vram_limit;
r = amdgpu_ttm_global_init(adev);
if (r) {
@@ -1118,36 +1266,37 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
DRM_ERROR("Failed initializing VRAM heap.\n");
return r;
}
+
+ /* Reduce size of CPU-visible VRAM if requested */
+ vis_vram_limit = (u64)amdgpu_vis_vram_limit * 1024 * 1024;
+ if (amdgpu_vis_vram_limit > 0 &&
+ vis_vram_limit <= adev->mc.visible_vram_size)
+ adev->mc.visible_vram_size = vis_vram_limit;
+
/* Change the size here instead of the init above so only lpfn is affected */
amdgpu_ttm_set_active_vram_size(adev, adev->mc.visible_vram_size);
- r = amdgpu_bo_create(adev, adev->mc.stolen_size, PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, &adev->stollen_vga_memory);
- if (r) {
- return r;
- }
- r = amdgpu_bo_reserve(adev->stollen_vga_memory, false);
+ r = amdgpu_bo_create_kernel(adev, adev->mc.stolen_size, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->stolen_vga_memory,
+ NULL, NULL);
if (r)
return r;
- r = amdgpu_bo_pin(adev->stollen_vga_memory, AMDGPU_GEM_DOMAIN_VRAM, NULL);
- amdgpu_bo_unreserve(adev->stollen_vga_memory);
- if (r) {
- amdgpu_bo_unref(&adev->stollen_vga_memory);
- return r;
- }
DRM_INFO("amdgpu: %uM of VRAM memory ready\n",
(unsigned) (adev->mc.real_vram_size / (1024 * 1024)));
- r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_TT,
- adev->mc.gtt_size >> PAGE_SHIFT);
+
+ if (amdgpu_gtt_size == -1)
+ gtt_size = max((AMDGPU_DEFAULT_GTT_SIZE_MB << 20),
+ adev->mc.mc_vram_size);
+ else
+ gtt_size = (uint64_t)amdgpu_gtt_size << 20;
+ r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_TT, gtt_size >> PAGE_SHIFT);
if (r) {
DRM_ERROR("Failed initializing GTT heap.\n");
return r;
}
DRM_INFO("amdgpu: %uM of GTT memory ready.\n",
- (unsigned)(adev->mc.gtt_size / (1024 * 1024)));
+ (unsigned)(gtt_size / (1024 * 1024)));
adev->gds.mem.total_size = adev->gds.mem.total_size << AMDGPU_GDS_SHIFT;
adev->gds.mem.gfx_partition_size = adev->gds.mem.gfx_partition_size << AMDGPU_GDS_SHIFT;
@@ -1203,13 +1352,13 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
if (!adev->mman.initialized)
return;
amdgpu_ttm_debugfs_fini(adev);
- if (adev->stollen_vga_memory) {
- r = amdgpu_bo_reserve(adev->stollen_vga_memory, true);
+ if (adev->stolen_vga_memory) {
+ r = amdgpu_bo_reserve(adev->stolen_vga_memory, true);
if (r == 0) {
- amdgpu_bo_unpin(adev->stollen_vga_memory);
- amdgpu_bo_unreserve(adev->stollen_vga_memory);
+ amdgpu_bo_unpin(adev->stolen_vga_memory);
+ amdgpu_bo_unreserve(adev->stolen_vga_memory);
}
- amdgpu_bo_unref(&adev->stollen_vga_memory);
+ amdgpu_bo_unref(&adev->stolen_vga_memory);
}
ttm_bo_clean_mm(&adev->mman.bdev, TTM_PL_VRAM);
ttm_bo_clean_mm(&adev->mman.bdev, TTM_PL_TT);
@@ -1256,12 +1405,77 @@ int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma)
return ttm_bo_mmap(filp, vma, &adev->mman.bdev);
}
-int amdgpu_copy_buffer(struct amdgpu_ring *ring,
- uint64_t src_offset,
- uint64_t dst_offset,
- uint32_t byte_count,
+static int amdgpu_map_buffer(struct ttm_buffer_object *bo,
+ struct ttm_mem_reg *mem, unsigned num_pages,
+ uint64_t offset, unsigned window,
+ struct amdgpu_ring *ring,
+ uint64_t *addr)
+{
+ struct amdgpu_ttm_tt *gtt = (void *)bo->ttm;
+ struct amdgpu_device *adev = ring->adev;
+ struct ttm_tt *ttm = bo->ttm;
+ struct amdgpu_job *job;
+ unsigned num_dw, num_bytes;
+ dma_addr_t *dma_address;
+ struct dma_fence *fence;
+ uint64_t src_addr, dst_addr;
+ uint64_t flags;
+ int r;
+
+ BUG_ON(adev->mman.buffer_funcs->copy_max_bytes <
+ AMDGPU_GTT_MAX_TRANSFER_SIZE * 8);
+
+ *addr = adev->mc.gart_start;
+ *addr += (u64)window * AMDGPU_GTT_MAX_TRANSFER_SIZE *
+ AMDGPU_GPU_PAGE_SIZE;
+
+ num_dw = adev->mman.buffer_funcs->copy_num_dw;
+ while (num_dw & 0x7)
+ num_dw++;
+
+ num_bytes = num_pages * 8;
+
+ r = amdgpu_job_alloc_with_ib(adev, num_dw * 4 + num_bytes, &job);
+ if (r)
+ return r;
+
+ src_addr = num_dw * 4;
+ src_addr += job->ibs[0].gpu_addr;
+
+ dst_addr = adev->gart.table_addr;
+ dst_addr += window * AMDGPU_GTT_MAX_TRANSFER_SIZE * 8;
+ amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr,
+ dst_addr, num_bytes);
+
+ amdgpu_ring_pad_ib(ring, &job->ibs[0]);
+ WARN_ON(job->ibs[0].length_dw > num_dw);
+
+ dma_address = &gtt->ttm.dma_address[offset >> PAGE_SHIFT];
+ flags = amdgpu_ttm_tt_pte_flags(adev, ttm, mem);
+ r = amdgpu_gart_map(adev, 0, num_pages, dma_address, flags,
+ &job->ibs[0].ptr[num_dw]);
+ if (r)
+ goto error_free;
+
+ r = amdgpu_job_submit(job, ring, &adev->mman.entity,
+ AMDGPU_FENCE_OWNER_UNDEFINED, &fence);
+ if (r)
+ goto error_free;
+
+ dma_fence_put(fence);
+
+ return r;
+
+error_free:
+ amdgpu_job_free(job);
+ return r;
+}
+
+int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
+ uint64_t dst_offset, uint32_t byte_count,
struct reservation_object *resv,
- struct dma_fence **fence, bool direct_submit)
+ struct dma_fence **fence, bool direct_submit,
+ bool vm_needs_flush)
{
struct amdgpu_device *adev = ring->adev;
struct amdgpu_job *job;
@@ -1283,6 +1497,7 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring,
if (r)
return r;
+ job->vm_needs_flush = vm_needs_flush;
if (resv) {
r = amdgpu_sync_resv(adev, &job->sync, resv,
AMDGPU_FENCE_OWNER_UNDEFINED);
@@ -1327,11 +1542,12 @@ error_free:
}
int amdgpu_fill_buffer(struct amdgpu_bo *bo,
- uint32_t src_data,
+ uint64_t src_data,
struct reservation_object *resv,
struct dma_fence **fence)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
+ /* max_bytes applies to SDMA_OP_PTEPDE as well as SDMA_OP_CONST_FILL*/
uint32_t max_bytes = adev->mman.buffer_funcs->fill_max_bytes;
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
@@ -1347,6 +1563,12 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
return -EINVAL;
}
+ if (bo->tbo.mem.mem_type == TTM_PL_TT) {
+ r = amdgpu_ttm_bind(&bo->tbo, &bo->tbo.mem);
+ if (r)
+ return r;
+ }
+
num_pages = bo->tbo.num_pages;
mm_node = bo->tbo.mem.mm_node;
num_loops = 0;
@@ -1357,7 +1579,9 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
num_pages -= mm_node->size;
++mm_node;
}
- num_dw = num_loops * adev->mman.buffer_funcs->fill_num_dw;
+
+ /* 10 double words for each SDMA_OP_PTEPDE cmd */
+ num_dw = num_loops * 10;
/* for IB padding */
num_dw += 64;
@@ -1382,16 +1606,16 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
uint32_t byte_count = mm_node->size << PAGE_SHIFT;
uint64_t dst_addr;
- r = amdgpu_mm_node_addr(&bo->tbo, mm_node,
- &bo->tbo.mem, &dst_addr);
- if (r)
- return r;
+ WARN_ONCE(byte_count & 0x7, "size should be a multiple of 8");
+ dst_addr = amdgpu_mm_node_addr(&bo->tbo, mm_node, &bo->tbo.mem);
while (byte_count) {
uint32_t cur_size_in_bytes = min(byte_count, max_bytes);
- amdgpu_emit_fill_buffer(adev, &job->ibs[0], src_data,
- dst_addr, cur_size_in_bytes);
+ amdgpu_vm_set_pte_pde(adev, &job->ibs[0],
+ dst_addr, 0,
+ cur_size_in_bytes >> 3, 0,
+ src_data);
dst_addr += cur_size_in_bytes;
byte_count -= cur_size_in_bytes;
@@ -1417,32 +1641,16 @@ error_free:
#if defined(CONFIG_DEBUG_FS)
-extern void amdgpu_gtt_mgr_print(struct seq_file *m, struct ttm_mem_type_manager
- *man);
static int amdgpu_mm_dump_table(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *)m->private;
unsigned ttm_pl = *(int *)node->info_ent->data;
struct drm_device *dev = node->minor->dev;
struct amdgpu_device *adev = dev->dev_private;
- struct drm_mm *mm = (struct drm_mm *)adev->mman.bdev.man[ttm_pl].priv;
- struct ttm_bo_global *glob = adev->mman.bdev.glob;
+ struct ttm_mem_type_manager *man = &adev->mman.bdev.man[ttm_pl];
struct drm_printer p = drm_seq_file_printer(m);
- spin_lock(&glob->lru_lock);
- drm_mm_print(mm, &p);
- spin_unlock(&glob->lru_lock);
- switch (ttm_pl) {
- case TTM_PL_VRAM:
- seq_printf(m, "man size:%llu pages, ram usage:%lluMB, vis usage:%lluMB\n",
- adev->mman.bdev.man[ttm_pl].size,
- (u64)atomic64_read(&adev->vram_usage) >> 20,
- (u64)atomic64_read(&adev->vram_vis_usage) >> 20);
- break;
- case TTM_PL_TT:
- amdgpu_gtt_mgr_print(m, &adev->mman.bdev.man[TTM_PL_TT]);
- break;
- }
+ man->func->debug(man, &p);
return 0;
}
@@ -1574,7 +1782,7 @@ static int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev)
adev, &amdgpu_ttm_gtt_fops);
if (IS_ERR(ent))
return PTR_ERR(ent);
- i_size_write(ent->d_inode, adev->mc.gtt_size);
+ i_size_write(ent->d_inode, adev->mc.gart_size);
adev->mman.gtt = ent;
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
index 6bdede8ff12b..f22a4758719d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -34,6 +34,9 @@
#define AMDGPU_PL_FLAG_GWS (TTM_PL_FLAG_PRIV << 1)
#define AMDGPU_PL_FLAG_OA (TTM_PL_FLAG_PRIV << 2)
+#define AMDGPU_GTT_MAX_TRANSFER_SIZE 512
+#define AMDGPU_GTT_NUM_TRANSFER_WINDOWS 2
+
struct amdgpu_mman {
struct ttm_bo_global_ref bo_global_ref;
struct drm_global_reference mem_global_ref;
@@ -49,6 +52,8 @@ struct amdgpu_mman {
/* buffer handling */
const struct amdgpu_buffer_funcs *buffer_funcs;
struct amdgpu_ring *buffer_funcs_ring;
+
+ struct mutex gtt_window_lock;
/* Scheduler entity for buffer moves */
struct amd_sched_entity entity;
};
@@ -56,24 +61,29 @@ struct amdgpu_mman {
extern const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func;
extern const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func;
+bool amdgpu_gtt_mgr_is_allocated(struct ttm_mem_reg *mem);
int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
struct ttm_buffer_object *tbo,
const struct ttm_place *place,
struct ttm_mem_reg *mem);
+uint64_t amdgpu_gtt_mgr_usage(struct ttm_mem_type_manager *man);
+
+uint64_t amdgpu_vram_mgr_usage(struct ttm_mem_type_manager *man);
+uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_mem_type_manager *man);
-int amdgpu_copy_buffer(struct amdgpu_ring *ring,
- uint64_t src_offset,
- uint64_t dst_offset,
- uint32_t byte_count,
+int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
+ uint64_t dst_offset, uint32_t byte_count,
struct reservation_object *resv,
- struct dma_fence **fence, bool direct_submit);
+ struct dma_fence **fence, bool direct_submit,
+ bool vm_needs_flush);
int amdgpu_fill_buffer(struct amdgpu_bo *bo,
- uint32_t src_data,
+ uint64_t src_data,
struct reservation_object *resv,
struct dma_fence **fence);
int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma);
bool amdgpu_ttm_is_bound(struct ttm_tt *ttm);
int amdgpu_ttm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *bo_mem);
+int amdgpu_ttm_recover_gart(struct amdgpu_device *adev);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
index 4f50eeb65855..36c763310df5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
@@ -275,14 +275,10 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type)
else
return AMDGPU_FW_LOAD_PSP;
case CHIP_RAVEN:
-#if 0
- if (!load_type)
+ if (load_type != 2)
return AMDGPU_FW_LOAD_DIRECT;
else
return AMDGPU_FW_LOAD_PSP;
-#else
- return AMDGPU_FW_LOAD_DIRECT;
-#endif
default:
DRM_ERROR("Unknow firmware load type\n");
}
@@ -362,8 +358,6 @@ static int amdgpu_ucode_patch_jt(struct amdgpu_firmware_info *ucode,
(le32_to_cpu(header->jt_offset) * 4);
memcpy(dst_addr, src_addr, le32_to_cpu(header->jt_size) * 4);
- ucode->ucode_size += le32_to_cpu(header->jt_size) * 4;
-
return 0;
}
@@ -377,10 +371,15 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev)
struct amdgpu_firmware_info *ucode = NULL;
const struct common_firmware_header *header = NULL;
+ if (!adev->firmware.fw_size) {
+ dev_warn(adev->dev, "No ip firmware need to load\n");
+ return 0;
+ }
+
err = amdgpu_bo_create(adev, adev->firmware.fw_size, PAGE_SIZE, true,
amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT,
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, bo);
+ NULL, NULL, 0, bo);
if (err) {
dev_err(adev->dev, "(%d) Firmware buffer allocate failed\n", err);
goto failed;
@@ -459,6 +458,9 @@ int amdgpu_ucode_fini_bo(struct amdgpu_device *adev)
int i;
struct amdgpu_firmware_info *ucode = NULL;
+ if (!adev->firmware.fw_size)
+ return 0;
+
for (i = 0; i < adev->firmware.max_ucodes; i++) {
ucode = &adev->firmware.ucode[i];
if (ucode->fw) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
index 2ca09f111f08..e19928dae8e3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -588,6 +588,10 @@ static int amdgpu_uvd_cs_msg_decode(struct amdgpu_device *adev, uint32_t *msg,
}
break;
+ case 8: /* MJPEG */
+ min_dpb_size = 0;
+ break;
+
case 16: /* H265 */
image_size = (ALIGN(width, 16) * ALIGN(height, 16) * 3) / 2;
image_size = ALIGN(image_size, 256);
@@ -1051,7 +1055,7 @@ int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
AMDGPU_GEM_DOMAIN_VRAM,
AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, &bo);
+ NULL, NULL, 0, &bo);
if (r)
return r;
@@ -1101,7 +1105,7 @@ int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
AMDGPU_GEM_DOMAIN_VRAM,
AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, &bo);
+ NULL, NULL, 0, &bo);
if (r)
return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
index b692ad402252..c855366521ab 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
@@ -937,9 +937,9 @@ int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring)
unsigned i;
int r, timeout = adev->usec_timeout;
- /* workaround VCE ring test slow issue for sriov*/
+ /* skip ring test for sriov*/
if (amdgpu_sriov_vf(adev))
- timeout *= 10;
+ return 0;
r = amdgpu_ring_alloc(ring, 16);
if (r) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
index 09190fadd228..041e0121590c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -209,9 +209,9 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
if (fences == 0) {
if (adev->pm.dpm_enabled) {
+ /* might be used when with pg/cg
amdgpu_dpm_enable_uvd(adev, false);
- } else {
- amdgpu_asic_set_uvd_clocks(adev, 0, 0);
+ */
}
} else {
schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
@@ -223,12 +223,10 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
struct amdgpu_device *adev = ring->adev;
bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
- if (set_clocks) {
- if (adev->pm.dpm_enabled) {
- amdgpu_dpm_enable_uvd(adev, true);
- } else {
- amdgpu_asic_set_uvd_clocks(adev, 53300, 40000);
- }
+ if (set_clocks && adev->pm.dpm_enabled) {
+ /* might be used when with pg/cg
+ amdgpu_dpm_enable_uvd(adev, true);
+ */
}
}
@@ -361,7 +359,7 @@ static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t hand
AMDGPU_GEM_DOMAIN_VRAM,
AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, &bo);
+ NULL, NULL, 0, &bo);
if (r)
return r;
@@ -413,7 +411,7 @@ static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han
AMDGPU_GEM_DOMAIN_VRAM,
AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL, &bo);
+ NULL, NULL, 0, &bo);
if (r)
return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c
new file mode 100644
index 000000000000..45ac91861965
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2017 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.
+ *
+ */
+
+#include "amdgpu.h"
+#include "amdgpu_vf_error.h"
+#include "mxgpu_ai.h"
+
+#define AMDGPU_VF_ERROR_ENTRY_SIZE 16
+
+/* struct error_entry - amdgpu VF error information. */
+struct amdgpu_vf_error_buffer {
+ int read_count;
+ int write_count;
+ uint16_t code[AMDGPU_VF_ERROR_ENTRY_SIZE];
+ uint16_t flags[AMDGPU_VF_ERROR_ENTRY_SIZE];
+ uint64_t data[AMDGPU_VF_ERROR_ENTRY_SIZE];
+};
+
+struct amdgpu_vf_error_buffer admgpu_vf_errors;
+
+
+void amdgpu_vf_error_put(uint16_t sub_error_code, uint16_t error_flags, uint64_t error_data)
+{
+ int index;
+ uint16_t error_code = AMDGIM_ERROR_CODE(AMDGIM_ERROR_CATEGORY_VF, sub_error_code);
+
+ index = admgpu_vf_errors.write_count % AMDGPU_VF_ERROR_ENTRY_SIZE;
+ admgpu_vf_errors.code [index] = error_code;
+ admgpu_vf_errors.flags [index] = error_flags;
+ admgpu_vf_errors.data [index] = error_data;
+ admgpu_vf_errors.write_count ++;
+}
+
+
+void amdgpu_vf_error_trans_all(struct amdgpu_device *adev)
+{
+ /* u32 pf2vf_flags = 0; */
+ u32 data1, data2, data3;
+ int index;
+
+ if ((NULL == adev) || (!amdgpu_sriov_vf(adev)) || (!adev->virt.ops) || (!adev->virt.ops->trans_msg)) {
+ return;
+ }
+/*
+ TODO: Enable these code when pv2vf_info is merged
+ AMDGPU_FW_VRAM_PF2VF_READ (adev, feature_flags, &pf2vf_flags);
+ if (!(pf2vf_flags & AMDGIM_FEATURE_ERROR_LOG_COLLECT)) {
+ return;
+ }
+*/
+ /* The errors are overlay of array, correct read_count as full. */
+ if (admgpu_vf_errors.write_count - admgpu_vf_errors.read_count > AMDGPU_VF_ERROR_ENTRY_SIZE) {
+ admgpu_vf_errors.read_count = admgpu_vf_errors.write_count - AMDGPU_VF_ERROR_ENTRY_SIZE;
+ }
+
+ while (admgpu_vf_errors.read_count < admgpu_vf_errors.write_count) {
+ index =admgpu_vf_errors.read_count % AMDGPU_VF_ERROR_ENTRY_SIZE;
+ data1 = AMDGIM_ERROR_CODE_FLAGS_TO_MAILBOX (admgpu_vf_errors.code[index], admgpu_vf_errors.flags[index]);
+ data2 = admgpu_vf_errors.data[index] & 0xFFFFFFFF;
+ data3 = (admgpu_vf_errors.data[index] >> 32) & 0xFFFFFFFF;
+
+ adev->virt.ops->trans_msg(adev, IDH_LOG_VF_ERROR, data1, data2, data3);
+ admgpu_vf_errors.read_count ++;
+ }
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h
new file mode 100644
index 000000000000..2a3278ec76ba
--- /dev/null
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vf_error.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2017 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 __VF_ERROR_H__
+#define __VF_ERROR_H__
+
+#define AMDGIM_ERROR_CODE_FLAGS_TO_MAILBOX(c,f) (((c & 0xFFFF) << 16) | (f & 0xFFFF))
+#define AMDGIM_ERROR_CODE(t,c) (((t&0xF)<<12)|(c&0xFFF))
+
+/* Please keep enum same as AMD GIM driver */
+enum AMDGIM_ERROR_VF {
+ AMDGIM_ERROR_VF_ATOMBIOS_INIT_FAIL = 0,
+ AMDGIM_ERROR_VF_NO_VBIOS,
+ AMDGIM_ERROR_VF_GPU_POST_ERROR,
+ AMDGIM_ERROR_VF_ATOMBIOS_GET_CLOCK_FAIL,
+ AMDGIM_ERROR_VF_FENCE_INIT_FAIL,
+
+ AMDGIM_ERROR_VF_AMDGPU_INIT_FAIL,
+ AMDGIM_ERROR_VF_IB_INIT_FAIL,
+ AMDGIM_ERROR_VF_AMDGPU_LATE_INIT_FAIL,
+ AMDGIM_ERROR_VF_ASIC_RESUME_FAIL,
+ AMDGIM_ERROR_VF_GPU_RESET_FAIL,
+
+ AMDGIM_ERROR_VF_TEST,
+ AMDGIM_ERROR_VF_MAX
+};
+
+enum AMDGIM_ERROR_CATEGORY {
+ AMDGIM_ERROR_CATEGORY_NON_USED = 0,
+ AMDGIM_ERROR_CATEGORY_GIM,
+ AMDGIM_ERROR_CATEGORY_PF,
+ AMDGIM_ERROR_CATEGORY_VF,
+ AMDGIM_ERROR_CATEGORY_VBIOS,
+ AMDGIM_ERROR_CATEGORY_MONITOR,
+
+ AMDGIM_ERROR_CATEGORY_MAX
+};
+
+void amdgpu_vf_error_put(uint16_t sub_error_code, uint16_t error_flags, uint64_t error_data);
+void amdgpu_vf_error_trans_all (struct amdgpu_device *adev);
+
+#endif /* __VF_ERROR_H__ */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
index 8a081e162d13..ab05121b9272 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
@@ -46,14 +46,14 @@ int amdgpu_allocate_static_csa(struct amdgpu_device *adev)
* address within META_DATA init package to support SRIOV gfx preemption.
*/
-int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm)
+int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+ struct amdgpu_bo_va **bo_va)
{
- int r;
- struct amdgpu_bo_va *bo_va;
struct ww_acquire_ctx ticket;
struct list_head list;
struct amdgpu_bo_list_entry pd;
struct ttm_validate_buffer csa_tv;
+ int r;
INIT_LIST_HEAD(&list);
INIT_LIST_HEAD(&csa_tv.head);
@@ -69,34 +69,33 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm)
return r;
}
- bo_va = amdgpu_vm_bo_add(adev, vm, adev->virt.csa_obj);
- if (!bo_va) {
+ *bo_va = amdgpu_vm_bo_add(adev, vm, adev->virt.csa_obj);
+ if (!*bo_va) {
ttm_eu_backoff_reservation(&ticket, &list);
DRM_ERROR("failed to create bo_va for static CSA\n");
return -ENOMEM;
}
- r = amdgpu_vm_alloc_pts(adev, bo_va->vm, AMDGPU_CSA_VADDR,
- AMDGPU_CSA_SIZE);
+ r = amdgpu_vm_alloc_pts(adev, (*bo_va)->base.vm, AMDGPU_CSA_VADDR,
+ AMDGPU_CSA_SIZE);
if (r) {
DRM_ERROR("failed to allocate pts for static CSA, err=%d\n", r);
- amdgpu_vm_bo_rmv(adev, bo_va);
+ amdgpu_vm_bo_rmv(adev, *bo_va);
ttm_eu_backoff_reservation(&ticket, &list);
return r;
}
- r = amdgpu_vm_bo_map(adev, bo_va, AMDGPU_CSA_VADDR, 0,AMDGPU_CSA_SIZE,
- AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE |
- AMDGPU_PTE_EXECUTABLE);
+ r = amdgpu_vm_bo_map(adev, *bo_va, AMDGPU_CSA_VADDR, 0, AMDGPU_CSA_SIZE,
+ AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE |
+ AMDGPU_PTE_EXECUTABLE);
if (r) {
DRM_ERROR("failed to do bo_map on static CSA, err=%d\n", r);
- amdgpu_vm_bo_rmv(adev, bo_va);
+ amdgpu_vm_bo_rmv(adev, *bo_va);
ttm_eu_backoff_reservation(&ticket, &list);
return r;
}
- vm->csa_bo_va = bo_va;
ttm_eu_backoff_reservation(&ticket, &list);
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
index 9e1062edb76e..afcfb8bcfb65 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
@@ -43,6 +43,7 @@ struct amdgpu_virt_ops {
int (*req_full_gpu)(struct amdgpu_device *adev, bool init);
int (*rel_full_gpu)(struct amdgpu_device *adev, bool init);
int (*reset_gpu)(struct amdgpu_device *adev);
+ void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3);
};
/* GPU virtualization */
@@ -89,7 +90,8 @@ static inline bool is_virtual_machine(void)
struct amdgpu_vm;
int amdgpu_allocate_static_csa(struct amdgpu_device *adev);
-int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm);
+int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+ struct amdgpu_bo_va **bo_va);
void amdgpu_virt_init_setting(struct amdgpu_device *adev);
uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg);
void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 5795f81369f0..6b1343e5541d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -77,8 +77,6 @@ struct amdgpu_pte_update_params {
void (*func)(struct amdgpu_pte_update_params *params, uint64_t pe,
uint64_t addr, unsigned count, uint32_t incr,
uint64_t flags);
- /* indicate update pt or its shadow */
- bool shadow;
/* The next two are used during VM update by CPU
* DMA addresses to use for mapping
* Kernel pointer of PD/PT BO that needs to be updated
@@ -161,11 +159,26 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
*/
static int amdgpu_vm_validate_level(struct amdgpu_vm_pt *parent,
int (*validate)(void *, struct amdgpu_bo *),
- void *param)
+ void *param, bool use_cpu_for_update,
+ struct ttm_bo_global *glob)
{
unsigned i;
int r;
+ if (parent->bo->shadow) {
+ struct amdgpu_bo *shadow = parent->bo->shadow;
+
+ r = amdgpu_ttm_bind(&shadow->tbo, &shadow->tbo.mem);
+ if (r)
+ return r;
+ }
+
+ if (use_cpu_for_update) {
+ r = amdgpu_bo_kmap(parent->bo, NULL);
+ if (r)
+ return r;
+ }
+
if (!parent->entries)
return 0;
@@ -179,11 +192,18 @@ static int amdgpu_vm_validate_level(struct amdgpu_vm_pt *parent,
if (r)
return r;
+ spin_lock(&glob->lru_lock);
+ ttm_bo_move_to_lru_tail(&entry->bo->tbo);
+ if (entry->bo->shadow)
+ ttm_bo_move_to_lru_tail(&entry->bo->shadow->tbo);
+ spin_unlock(&glob->lru_lock);
+
/*
* Recurse into the sub directory. This is harmless because we
* have only a maximum of 5 layers.
*/
- r = amdgpu_vm_validate_level(entry, validate, param);
+ r = amdgpu_vm_validate_level(entry, validate, param,
+ use_cpu_for_update, glob);
if (r)
return r;
}
@@ -214,54 +234,12 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
if (num_evictions == vm->last_eviction_counter)
return 0;
- return amdgpu_vm_validate_level(&vm->root, validate, param);
-}
-
-/**
- * amdgpu_vm_move_level_in_lru - move one level of PT BOs to the LRU tail
- *
- * @adev: amdgpu device instance
- * @vm: vm providing the BOs
- *
- * Move the PT BOs to the tail of the LRU.
- */
-static void amdgpu_vm_move_level_in_lru(struct amdgpu_vm_pt *parent)
-{
- unsigned i;
-
- if (!parent->entries)
- return;
-
- for (i = 0; i <= parent->last_entry_used; ++i) {
- struct amdgpu_vm_pt *entry = &parent->entries[i];
-
- if (!entry->bo)
- continue;
-
- ttm_bo_move_to_lru_tail(&entry->bo->tbo);
- amdgpu_vm_move_level_in_lru(entry);
- }
+ return amdgpu_vm_validate_level(&vm->root, validate, param,
+ vm->use_cpu_for_update,
+ adev->mman.bdev.glob);
}
/**
- * amdgpu_vm_move_pt_bos_in_lru - move the PT BOs to the LRU tail
- *
- * @adev: amdgpu device instance
- * @vm: vm providing the BOs
- *
- * Move the PT BOs to the tail of the LRU.
- */
-void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev,
- struct amdgpu_vm *vm)
-{
- struct ttm_bo_global *glob = adev->mman.bdev.glob;
-
- spin_lock(&glob->lru_lock);
- amdgpu_vm_move_level_in_lru(&vm->root);
- spin_unlock(&glob->lru_lock);
-}
-
- /**
* amdgpu_vm_alloc_levels - allocate the PD/PT levels
*
* @adev: amdgpu_device pointer
@@ -282,6 +260,7 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
unsigned pt_idx, from, to;
int r;
u64 flags;
+ uint64_t init_value = 0;
if (!parent->entries) {
unsigned num_entries = amdgpu_vm_num_entries(adev, level);
@@ -315,6 +294,12 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
flags |= (AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
AMDGPU_GEM_CREATE_SHADOW);
+ if (vm->pte_support_ats) {
+ init_value = AMDGPU_PTE_SYSTEM;
+ if (level != adev->vm_manager.num_level - 1)
+ init_value |= AMDGPU_PDE_PTE;
+ }
+
/* walk over the address space and allocate the page tables */
for (pt_idx = from; pt_idx <= to; ++pt_idx) {
struct reservation_object *resv = vm->root.bo->tbo.resv;
@@ -327,10 +312,18 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
AMDGPU_GPU_PAGE_SIZE, true,
AMDGPU_GEM_DOMAIN_VRAM,
flags,
- NULL, resv, &pt);
+ NULL, resv, init_value, &pt);
if (r)
return r;
+ if (vm->use_cpu_for_update) {
+ r = amdgpu_bo_kmap(pt, NULL);
+ if (r) {
+ amdgpu_bo_unref(&pt);
+ return r;
+ }
+ }
+
/* Keep a reference to the root directory to avoid
* freeing them up in the wrong order.
*/
@@ -424,7 +417,7 @@ static int amdgpu_vm_grab_reserved_vmid_locked(struct amdgpu_vm *vm,
struct dma_fence *updates = sync->last_vm_update;
int r = 0;
struct dma_fence *flushed, *tmp;
- bool needs_flush = false;
+ bool needs_flush = vm->use_cpu_for_update;
flushed = id->flushed_updates;
if ((amdgpu_vm_had_gpu_reset(adev, id)) ||
@@ -545,11 +538,11 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
}
kfree(fences);
- job->vm_needs_flush = false;
+ job->vm_needs_flush = vm->use_cpu_for_update;
/* Check if we can use a VMID already assigned to this VM */
list_for_each_entry_reverse(id, &id_mgr->ids_lru, list) {
struct dma_fence *flushed;
- bool needs_flush = false;
+ bool needs_flush = vm->use_cpu_for_update;
/* Check all the prerequisites to using this VMID */
if (amdgpu_vm_had_gpu_reset(adev, id))
@@ -745,7 +738,7 @@ static bool amdgpu_vm_is_large_bar(struct amdgpu_device *adev)
*
* Emit a VM flush when it is necessary.
*/
-int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job)
+int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_pipe_sync)
{
struct amdgpu_device *adev = ring->adev;
unsigned vmhub = ring->funcs->vmhub;
@@ -767,12 +760,15 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job)
vm_flush_needed = true;
}
- if (!vm_flush_needed && !gds_switch_needed)
+ if (!vm_flush_needed && !gds_switch_needed && !need_pipe_sync)
return 0;
if (ring->funcs->init_cond_exec)
patch_offset = amdgpu_ring_init_cond_exec(ring);
+ if (need_pipe_sync)
+ amdgpu_ring_emit_pipeline_sync(ring);
+
if (ring->funcs->emit_vm_flush && vm_flush_needed) {
struct dma_fence *fence;
@@ -874,8 +870,8 @@ struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm,
{
struct amdgpu_bo_va *bo_va;
- list_for_each_entry(bo_va, &bo->va, bo_list) {
- if (bo_va->vm == vm) {
+ list_for_each_entry(bo_va, &bo->va, base.bo_list) {
+ if (bo_va->base.vm == vm) {
return bo_va;
}
}
@@ -981,6 +977,8 @@ static void amdgpu_vm_cpu_set_ptes(struct amdgpu_pte_update_params *params,
unsigned int i;
uint64_t value;
+ trace_amdgpu_vm_set_ptes(pe, addr, count, incr, flags);
+
for (i = 0; i < count; i++) {
value = params->pages_addr ?
amdgpu_vm_map_gart(params->pages_addr, addr) :
@@ -989,19 +987,16 @@ static void amdgpu_vm_cpu_set_ptes(struct amdgpu_pte_update_params *params,
i, value, flags);
addr += incr;
}
-
- /* Flush HDP */
- mb();
- amdgpu_gart_flush_gpu_tlb(params->adev, 0);
}
-static int amdgpu_vm_bo_wait(struct amdgpu_device *adev, struct amdgpu_bo *bo)
+static int amdgpu_vm_wait_pd(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+ void *owner)
{
struct amdgpu_sync sync;
int r;
amdgpu_sync_create(&sync);
- amdgpu_sync_resv(adev, &sync, bo->tbo.resv, AMDGPU_FENCE_OWNER_VM);
+ amdgpu_sync_resv(adev, &sync, vm->root.bo->tbo.resv, owner);
r = amdgpu_sync_wait(&sync, true);
amdgpu_sync_free(&sync);
@@ -1042,23 +1037,14 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev,
params.adev = adev;
shadow = parent->bo->shadow;
- WARN_ON(vm->use_cpu_for_update && shadow);
- if (vm->use_cpu_for_update && !shadow) {
- r = amdgpu_bo_kmap(parent->bo, (void **)&pd_addr);
- if (r)
- return r;
- r = amdgpu_vm_bo_wait(adev, parent->bo);
- if (unlikely(r)) {
- amdgpu_bo_kunmap(parent->bo);
+ if (vm->use_cpu_for_update) {
+ pd_addr = (unsigned long)amdgpu_bo_kptr(parent->bo);
+ r = amdgpu_vm_wait_pd(adev, vm, AMDGPU_FENCE_OWNER_VM);
+ if (unlikely(r))
return r;
- }
+
params.func = amdgpu_vm_cpu_set_ptes;
} else {
- if (shadow) {
- r = amdgpu_ttm_bind(&shadow->tbo, &shadow->tbo.mem);
- if (r)
- return r;
- }
ring = container_of(vm->entity.sched, struct amdgpu_ring,
sched);
@@ -1094,21 +1080,14 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev,
if (bo == NULL)
continue;
- if (bo->shadow) {
- struct amdgpu_bo *pt_shadow = bo->shadow;
-
- r = amdgpu_ttm_bind(&pt_shadow->tbo,
- &pt_shadow->tbo.mem);
- if (r)
- return r;
- }
-
pt = amdgpu_bo_gpu_offset(bo);
pt = amdgpu_gart_get_vm_pde(adev, pt);
- if (parent->entries[pt_idx].addr == pt)
+ /* Don't update huge pages here */
+ if ((parent->entries[pt_idx].addr & AMDGPU_PDE_PTE) ||
+ parent->entries[pt_idx].addr == (pt | AMDGPU_PTE_VALID))
continue;
- parent->entries[pt_idx].addr = pt;
+ parent->entries[pt_idx].addr = pt | AMDGPU_PTE_VALID;
pde = pd_addr + pt_idx * 8;
if (((last_pde + 8 * count) != pde) ||
@@ -1146,28 +1125,29 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev,
count, incr, AMDGPU_PTE_VALID);
}
- if (params.func == amdgpu_vm_cpu_set_ptes)
- amdgpu_bo_kunmap(parent->bo);
- else if (params.ib->length_dw == 0) {
- amdgpu_job_free(job);
- } else {
- amdgpu_ring_pad_ib(ring, params.ib);
- amdgpu_sync_resv(adev, &job->sync, parent->bo->tbo.resv,
- AMDGPU_FENCE_OWNER_VM);
- if (shadow)
- amdgpu_sync_resv(adev, &job->sync, shadow->tbo.resv,
+ if (!vm->use_cpu_for_update) {
+ if (params.ib->length_dw == 0) {
+ amdgpu_job_free(job);
+ } else {
+ amdgpu_ring_pad_ib(ring, params.ib);
+ amdgpu_sync_resv(adev, &job->sync, parent->bo->tbo.resv,
AMDGPU_FENCE_OWNER_VM);
+ if (shadow)
+ amdgpu_sync_resv(adev, &job->sync,
+ shadow->tbo.resv,
+ AMDGPU_FENCE_OWNER_VM);
+
+ WARN_ON(params.ib->length_dw > ndw);
+ r = amdgpu_job_submit(job, ring, &vm->entity,
+ AMDGPU_FENCE_OWNER_VM, &fence);
+ if (r)
+ goto error_free;
- WARN_ON(params.ib->length_dw > ndw);
- r = amdgpu_job_submit(job, ring, &vm->entity,
- AMDGPU_FENCE_OWNER_VM, &fence);
- if (r)
- goto error_free;
-
- amdgpu_bo_fence(parent->bo, fence, true);
- dma_fence_put(vm->last_dir_update);
- vm->last_dir_update = dma_fence_get(fence);
- dma_fence_put(fence);
+ amdgpu_bo_fence(parent->bo, fence, true);
+ dma_fence_put(vm->last_dir_update);
+ vm->last_dir_update = dma_fence_get(fence);
+ dma_fence_put(fence);
+ }
}
/*
* Recurse into the subdirectories. This recursion is harmless because
@@ -1235,33 +1215,98 @@ int amdgpu_vm_update_directories(struct amdgpu_device *adev,
if (r)
amdgpu_vm_invalidate_level(&vm->root);
+ if (vm->use_cpu_for_update) {
+ /* Flush HDP */
+ mb();
+ amdgpu_gart_flush_gpu_tlb(adev, 0);
+ }
+
return r;
}
/**
- * amdgpu_vm_find_pt - find the page table for an address
+ * amdgpu_vm_find_entry - find the entry for an address
*
* @p: see amdgpu_pte_update_params definition
* @addr: virtual address in question
+ * @entry: resulting entry or NULL
+ * @parent: parent entry
*
- * Find the page table BO for a virtual address, return NULL when none found.
+ * Find the vm_pt entry and it's parent for the given address.
*/
-static struct amdgpu_bo *amdgpu_vm_get_pt(struct amdgpu_pte_update_params *p,
- uint64_t addr)
+void amdgpu_vm_get_entry(struct amdgpu_pte_update_params *p, uint64_t addr,
+ struct amdgpu_vm_pt **entry,
+ struct amdgpu_vm_pt **parent)
{
- struct amdgpu_vm_pt *entry = &p->vm->root;
unsigned idx, level = p->adev->vm_manager.num_level;
- while (entry->entries) {
+ *parent = NULL;
+ *entry = &p->vm->root;
+ while ((*entry)->entries) {
idx = addr >> (p->adev->vm_manager.block_size * level--);
- idx %= amdgpu_bo_size(entry->bo) / 8;
- entry = &entry->entries[idx];
+ idx %= amdgpu_bo_size((*entry)->bo) / 8;
+ *parent = *entry;
+ *entry = &(*entry)->entries[idx];
}
if (level)
- return NULL;
+ *entry = NULL;
+}
+
+/**
+ * amdgpu_vm_handle_huge_pages - handle updating the PD with huge pages
+ *
+ * @p: see amdgpu_pte_update_params definition
+ * @entry: vm_pt entry to check
+ * @parent: parent entry
+ * @nptes: number of PTEs updated with this operation
+ * @dst: destination address where the PTEs should point to
+ * @flags: access flags fro the PTEs
+ *
+ * Check if we can update the PD with a huge page.
+ */
+static void amdgpu_vm_handle_huge_pages(struct amdgpu_pte_update_params *p,
+ struct amdgpu_vm_pt *entry,
+ struct amdgpu_vm_pt *parent,
+ unsigned nptes, uint64_t dst,
+ uint64_t flags)
+{
+ bool use_cpu_update = (p->func == amdgpu_vm_cpu_set_ptes);
+ uint64_t pd_addr, pde;
+
+ /* In the case of a mixed PT the PDE must point to it*/
+ if (p->adev->asic_type < CHIP_VEGA10 ||
+ nptes != AMDGPU_VM_PTE_COUNT(p->adev) ||
+ p->func == amdgpu_vm_do_copy_ptes ||
+ !(flags & AMDGPU_PTE_VALID)) {
+
+ dst = amdgpu_bo_gpu_offset(entry->bo);
+ dst = amdgpu_gart_get_vm_pde(p->adev, dst);
+ flags = AMDGPU_PTE_VALID;
+ } else {
+ /* Set the huge page flag to stop scanning at this PDE */
+ flags |= AMDGPU_PDE_PTE;
+ }
+
+ if (entry->addr == (dst | flags))
+ return;
+
+ entry->addr = (dst | flags);
- return entry->bo;
+ if (use_cpu_update) {
+ pd_addr = (unsigned long)amdgpu_bo_kptr(parent->bo);
+ pde = pd_addr + (entry - parent->entries) * 8;
+ amdgpu_vm_cpu_set_ptes(p, pde, dst, 1, 0, flags);
+ } else {
+ if (parent->bo->shadow) {
+ pd_addr = amdgpu_bo_gpu_offset(parent->bo->shadow);
+ pde = pd_addr + (entry - parent->entries) * 8;
+ amdgpu_vm_do_set_ptes(p, pde, dst, 1, 0, flags);
+ }
+ pd_addr = amdgpu_bo_gpu_offset(parent->bo);
+ pde = pd_addr + (entry - parent->entries) * 8;
+ amdgpu_vm_do_set_ptes(p, pde, dst, 1, 0, flags);
+ }
}
/**
@@ -1287,49 +1332,44 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
uint64_t addr, pe_start;
struct amdgpu_bo *pt;
unsigned nptes;
- int r;
bool use_cpu_update = (params->func == amdgpu_vm_cpu_set_ptes);
-
/* walk over the address space and update the page tables */
- for (addr = start; addr < end; addr += nptes) {
- pt = amdgpu_vm_get_pt(params, addr);
- if (!pt) {
- pr_err("PT not found, aborting update_ptes\n");
- return -EINVAL;
- }
+ for (addr = start; addr < end; addr += nptes,
+ dst += nptes * AMDGPU_GPU_PAGE_SIZE) {
+ struct amdgpu_vm_pt *entry, *parent;
- if (params->shadow) {
- if (WARN_ONCE(use_cpu_update,
- "CPU VM update doesn't suuport shadow pages"))
- return 0;
-
- if (!pt->shadow)
- return 0;
- pt = pt->shadow;
- }
+ amdgpu_vm_get_entry(params, addr, &entry, &parent);
+ if (!entry)
+ return -ENOENT;
if ((addr & ~mask) == (end & ~mask))
nptes = end - addr;
else
nptes = AMDGPU_VM_PTE_COUNT(adev) - (addr & mask);
+ amdgpu_vm_handle_huge_pages(params, entry, parent,
+ nptes, dst, flags);
+ /* We don't need to update PTEs for huge pages */
+ if (entry->addr & AMDGPU_PDE_PTE)
+ continue;
+
+ pt = entry->bo;
if (use_cpu_update) {
- r = amdgpu_bo_kmap(pt, (void *)&pe_start);
- if (r)
- return r;
- } else
+ pe_start = (unsigned long)amdgpu_bo_kptr(pt);
+ } else {
+ if (pt->shadow) {
+ pe_start = amdgpu_bo_gpu_offset(pt->shadow);
+ pe_start += (addr & mask) * 8;
+ params->func(params, pe_start, dst, nptes,
+ AMDGPU_GPU_PAGE_SIZE, flags);
+ }
pe_start = amdgpu_bo_gpu_offset(pt);
+ }
pe_start += (addr & mask) * 8;
-
params->func(params, pe_start, dst, nptes,
AMDGPU_GPU_PAGE_SIZE, flags);
-
- dst += nptes * AMDGPU_GPU_PAGE_SIZE;
-
- if (use_cpu_update)
- amdgpu_bo_kunmap(pt);
}
return 0;
@@ -1370,10 +1410,9 @@ static int amdgpu_vm_frag_ptes(struct amdgpu_pte_update_params *params,
* Userspace can support this by aligning virtual base address and
* allocation size to the fragment size.
*/
-
- /* SI and newer are optimized for 64KB */
- uint64_t frag_flags = AMDGPU_PTE_FRAG(AMDGPU_LOG2_PAGES_PER_FRAG);
- uint64_t frag_align = 1 << AMDGPU_LOG2_PAGES_PER_FRAG;
+ unsigned pages_per_frag = params->adev->vm_manager.fragment_size;
+ uint64_t frag_flags = AMDGPU_PTE_FRAG(pages_per_frag);
+ uint64_t frag_align = 1 << pages_per_frag;
uint64_t frag_start = ALIGN(start, frag_align);
uint64_t frag_end = end & ~(frag_align - 1);
@@ -1445,6 +1484,10 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
params.vm = vm;
params.src = src;
+ /* sync to everything on unmapping */
+ if (!(flags & AMDGPU_PTE_VALID))
+ owner = AMDGPU_FENCE_OWNER_UNDEFINED;
+
if (vm->use_cpu_for_update) {
/* params.src is used as flag to indicate system Memory */
if (pages_addr)
@@ -1453,23 +1496,18 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
/* Wait for PT BOs to be free. PTs share the same resv. object
* as the root PD BO
*/
- r = amdgpu_vm_bo_wait(adev, vm->root.bo);
+ r = amdgpu_vm_wait_pd(adev, vm, owner);
if (unlikely(r))
return r;
params.func = amdgpu_vm_cpu_set_ptes;
params.pages_addr = pages_addr;
- params.shadow = false;
return amdgpu_vm_frag_ptes(&params, start, last + 1,
addr, flags);
}
ring = container_of(vm->entity.sched, struct amdgpu_ring, sched);
- /* sync to everything on unmapping */
- if (!(flags & AMDGPU_PTE_VALID))
- owner = AMDGPU_FENCE_OWNER_UNDEFINED;
-
nptes = last - start + 1;
/*
@@ -1481,6 +1519,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
/* padding, etc. */
ndw = 64;
+ /* one PDE write for each huge page */
+ ndw += ((nptes >> adev->vm_manager.block_size) + 1) * 6;
+
if (src) {
/* only copy commands needed */
ndw += ncmds * 7;
@@ -1542,11 +1583,6 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
if (r)
goto error_free;
- params.shadow = true;
- r = amdgpu_vm_frag_ptes(&params, start, last + 1, addr, flags);
- if (r)
- goto error_free;
- params.shadow = false;
r = amdgpu_vm_frag_ptes(&params, start, last + 1, addr, flags);
if (r)
goto error_free;
@@ -1565,6 +1601,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
error_free:
amdgpu_job_free(job);
+ amdgpu_vm_invalidate_level(&vm->root);
return r;
}
@@ -1687,7 +1724,8 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,
struct amdgpu_bo_va *bo_va,
bool clear)
{
- struct amdgpu_vm *vm = bo_va->vm;
+ struct amdgpu_bo *bo = bo_va->base.bo;
+ struct amdgpu_vm *vm = bo_va->base.vm;
struct amdgpu_bo_va_mapping *mapping;
dma_addr_t *pages_addr = NULL;
uint64_t gtt_flags, flags;
@@ -1696,27 +1734,27 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,
struct dma_fence *exclusive;
int r;
- if (clear || !bo_va->bo) {
+ if (clear || !bo_va->base.bo) {
mem = NULL;
nodes = NULL;
exclusive = NULL;
} else {
struct ttm_dma_tt *ttm;
- mem = &bo_va->bo->tbo.mem;
+ mem = &bo_va->base.bo->tbo.mem;
nodes = mem->mm_node;
if (mem->mem_type == TTM_PL_TT) {
- ttm = container_of(bo_va->bo->tbo.ttm, struct
- ttm_dma_tt, ttm);
+ ttm = container_of(bo_va->base.bo->tbo.ttm,
+ struct ttm_dma_tt, ttm);
pages_addr = ttm->dma_address;
}
- exclusive = reservation_object_get_excl(bo_va->bo->tbo.resv);
+ exclusive = reservation_object_get_excl(bo->tbo.resv);
}
- if (bo_va->bo) {
- flags = amdgpu_ttm_tt_pte_flags(adev, bo_va->bo->tbo.ttm, mem);
- gtt_flags = (amdgpu_ttm_is_bound(bo_va->bo->tbo.ttm) &&
- adev == amdgpu_ttm_adev(bo_va->bo->tbo.bdev)) ?
+ if (bo) {
+ flags = amdgpu_ttm_tt_pte_flags(adev, bo->tbo.ttm, mem);
+ gtt_flags = (amdgpu_ttm_is_bound(bo->tbo.ttm) &&
+ adev == amdgpu_ttm_adev(bo->tbo.bdev)) ?
flags : 0;
} else {
flags = 0x0;
@@ -1724,7 +1762,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,
}
spin_lock(&vm->status_lock);
- if (!list_empty(&bo_va->vm_status))
+ if (!list_empty(&bo_va->base.vm_status))
list_splice_init(&bo_va->valids, &bo_va->invalids);
spin_unlock(&vm->status_lock);
@@ -1747,11 +1785,17 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev,
spin_lock(&vm->status_lock);
list_splice_init(&bo_va->invalids, &bo_va->valids);
- list_del_init(&bo_va->vm_status);
+ list_del_init(&bo_va->base.vm_status);
if (clear)
- list_add(&bo_va->vm_status, &vm->cleared);
+ list_add(&bo_va->base.vm_status, &vm->cleared);
spin_unlock(&vm->status_lock);
+ if (vm->use_cpu_for_update) {
+ /* Flush HDP */
+ mb();
+ amdgpu_gart_flush_gpu_tlb(adev, 0);
+ }
+
return 0;
}
@@ -1905,15 +1949,19 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
struct amdgpu_bo_va_mapping *mapping;
struct dma_fence *f = NULL;
int r;
+ uint64_t init_pte_value = 0;
while (!list_empty(&vm->freed)) {
mapping = list_first_entry(&vm->freed,
struct amdgpu_bo_va_mapping, list);
list_del(&mapping->list);
+ if (vm->pte_support_ats)
+ init_pte_value = AMDGPU_PTE_SYSTEM;
+
r = amdgpu_vm_bo_update_mapping(adev, NULL, 0, NULL, vm,
mapping->start, mapping->last,
- 0, 0, &f);
+ init_pte_value, 0, &f);
amdgpu_vm_free_mapping(adev, vm, mapping, f);
if (r) {
dma_fence_put(f);
@@ -1933,26 +1981,26 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
}
/**
- * amdgpu_vm_clear_invalids - clear invalidated BOs in the PT
+ * amdgpu_vm_clear_moved - clear moved BOs in the PT
*
* @adev: amdgpu_device pointer
* @vm: requested vm
*
- * Make sure all invalidated BOs are cleared in the PT.
+ * Make sure all moved BOs are cleared in the PT.
* Returns 0 for success.
*
* PTs have to be reserved and mutex must be locked!
*/
-int amdgpu_vm_clear_invalids(struct amdgpu_device *adev,
- struct amdgpu_vm *vm, struct amdgpu_sync *sync)
+int amdgpu_vm_clear_moved(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+ struct amdgpu_sync *sync)
{
struct amdgpu_bo_va *bo_va = NULL;
int r = 0;
spin_lock(&vm->status_lock);
- while (!list_empty(&vm->invalidated)) {
- bo_va = list_first_entry(&vm->invalidated,
- struct amdgpu_bo_va, vm_status);
+ while (!list_empty(&vm->moved)) {
+ bo_va = list_first_entry(&vm->moved,
+ struct amdgpu_bo_va, base.vm_status);
spin_unlock(&vm->status_lock);
r = amdgpu_vm_bo_update(adev, bo_va, true);
@@ -1992,16 +2040,17 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
if (bo_va == NULL) {
return NULL;
}
- bo_va->vm = vm;
- bo_va->bo = bo;
+ bo_va->base.vm = vm;
+ bo_va->base.bo = bo;
+ INIT_LIST_HEAD(&bo_va->base.bo_list);
+ INIT_LIST_HEAD(&bo_va->base.vm_status);
+
bo_va->ref_count = 1;
- INIT_LIST_HEAD(&bo_va->bo_list);
INIT_LIST_HEAD(&bo_va->valids);
INIT_LIST_HEAD(&bo_va->invalids);
- INIT_LIST_HEAD(&bo_va->vm_status);
if (bo)
- list_add_tail(&bo_va->bo_list, &bo->va);
+ list_add_tail(&bo_va->base.bo_list, &bo->va);
return bo_va;
}
@@ -2026,7 +2075,8 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
uint64_t size, uint64_t flags)
{
struct amdgpu_bo_va_mapping *mapping, *tmp;
- struct amdgpu_vm *vm = bo_va->vm;
+ struct amdgpu_bo *bo = bo_va->base.bo;
+ struct amdgpu_vm *vm = bo_va->base.vm;
uint64_t eaddr;
/* validate the parameters */
@@ -2037,7 +2087,7 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
/* make sure object fit at this offset */
eaddr = saddr + size - 1;
if (saddr >= eaddr ||
- (bo_va->bo && offset + size > amdgpu_bo_size(bo_va->bo)))
+ (bo && offset + size > amdgpu_bo_size(bo)))
return -EINVAL;
saddr /= AMDGPU_GPU_PAGE_SIZE;
@@ -2047,7 +2097,7 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
if (tmp) {
/* bo and tmp overlap, invalid addr */
dev_err(adev->dev, "bo %p va 0x%010Lx-0x%010Lx conflict with "
- "0x%010Lx-0x%010Lx\n", bo_va->bo, saddr, eaddr,
+ "0x%010Lx-0x%010Lx\n", bo, saddr, eaddr,
tmp->start, tmp->last + 1);
return -EINVAL;
}
@@ -2092,7 +2142,8 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
uint64_t size, uint64_t flags)
{
struct amdgpu_bo_va_mapping *mapping;
- struct amdgpu_vm *vm = bo_va->vm;
+ struct amdgpu_bo *bo = bo_va->base.bo;
+ struct amdgpu_vm *vm = bo_va->base.vm;
uint64_t eaddr;
int r;
@@ -2104,7 +2155,7 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
/* make sure object fit at this offset */
eaddr = saddr + size - 1;
if (saddr >= eaddr ||
- (bo_va->bo && offset + size > amdgpu_bo_size(bo_va->bo)))
+ (bo && offset + size > amdgpu_bo_size(bo)))
return -EINVAL;
/* Allocate all the needed memory */
@@ -2112,7 +2163,7 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
if (!mapping)
return -ENOMEM;
- r = amdgpu_vm_bo_clear_mappings(adev, bo_va->vm, saddr, size);
+ r = amdgpu_vm_bo_clear_mappings(adev, bo_va->base.vm, saddr, size);
if (r) {
kfree(mapping);
return r;
@@ -2152,7 +2203,7 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
uint64_t saddr)
{
struct amdgpu_bo_va_mapping *mapping;
- struct amdgpu_vm *vm = bo_va->vm;
+ struct amdgpu_vm *vm = bo_va->base.vm;
bool valid = true;
saddr /= AMDGPU_GPU_PAGE_SIZE;
@@ -2300,12 +2351,12 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
struct amdgpu_bo_va *bo_va)
{
struct amdgpu_bo_va_mapping *mapping, *next;
- struct amdgpu_vm *vm = bo_va->vm;
+ struct amdgpu_vm *vm = bo_va->base.vm;
- list_del(&bo_va->bo_list);
+ list_del(&bo_va->base.bo_list);
spin_lock(&vm->status_lock);
- list_del(&bo_va->vm_status);
+ list_del(&bo_va->base.vm_status);
spin_unlock(&vm->status_lock);
list_for_each_entry_safe(mapping, next, &bo_va->valids, list) {
@@ -2337,13 +2388,14 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev,
struct amdgpu_bo *bo)
{
- struct amdgpu_bo_va *bo_va;
+ struct amdgpu_vm_bo_base *bo_base;
- list_for_each_entry(bo_va, &bo->va, bo_list) {
- spin_lock(&bo_va->vm->status_lock);
- if (list_empty(&bo_va->vm_status))
- list_add(&bo_va->vm_status, &bo_va->vm->invalidated);
- spin_unlock(&bo_va->vm->status_lock);
+ list_for_each_entry(bo_base, &bo->va, bo_list) {
+ spin_lock(&bo_base->vm->status_lock);
+ if (list_empty(&bo_base->vm_status))
+ list_add(&bo_base->vm_status,
+ &bo_base->vm->moved);
+ spin_unlock(&bo_base->vm->status_lock);
}
}
@@ -2361,12 +2413,26 @@ static uint32_t amdgpu_vm_get_block_size(uint64_t vm_size)
}
/**
- * amdgpu_vm_adjust_size - adjust vm size and block size
+ * amdgpu_vm_set_fragment_size - adjust fragment size in PTE
+ *
+ * @adev: amdgpu_device pointer
+ * @fragment_size_default: the default fragment size if it's set auto
+ */
+void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev, uint32_t fragment_size_default)
+{
+ if (amdgpu_vm_fragment_size == -1)
+ adev->vm_manager.fragment_size = fragment_size_default;
+ else
+ adev->vm_manager.fragment_size = amdgpu_vm_fragment_size;
+}
+
+/**
+ * amdgpu_vm_adjust_size - adjust vm size, block size and fragment size
*
* @adev: amdgpu_device pointer
* @vm_size: the default vm size if it's set auto
*/
-void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint64_t vm_size)
+void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint64_t vm_size, uint32_t fragment_size_default)
{
/* adjust vm size firstly */
if (amdgpu_vm_size == -1)
@@ -2381,8 +2447,11 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint64_t vm_size)
else
adev->vm_manager.block_size = amdgpu_vm_block_size;
- DRM_INFO("vm size is %llu GB, block size is %u-bit\n",
- adev->vm_manager.vm_size, adev->vm_manager.block_size);
+ amdgpu_vm_set_fragment_size(adev, fragment_size_default);
+
+ DRM_INFO("vm size is %llu GB, block size is %u-bit, fragment size is %u-bit\n",
+ adev->vm_manager.vm_size, adev->vm_manager.block_size,
+ adev->vm_manager.fragment_size);
}
/**
@@ -2404,13 +2473,14 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct amd_sched_rq *rq;
int r, i;
u64 flags;
+ uint64_t init_pde_value = 0;
vm->va = RB_ROOT;
vm->client_id = atomic64_inc_return(&adev->vm_manager.client_counter);
for (i = 0; i < AMDGPU_MAX_VMHUBS; i++)
vm->reserved_vmid[i] = NULL;
spin_lock_init(&vm->status_lock);
- INIT_LIST_HEAD(&vm->invalidated);
+ INIT_LIST_HEAD(&vm->moved);
INIT_LIST_HEAD(&vm->cleared);
INIT_LIST_HEAD(&vm->freed);
@@ -2425,10 +2495,17 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
if (r)
return r;
- if (vm_context == AMDGPU_VM_CONTEXT_COMPUTE)
+ vm->pte_support_ats = false;
+
+ if (vm_context == AMDGPU_VM_CONTEXT_COMPUTE) {
vm->use_cpu_for_update = !!(adev->vm_manager.vm_update_mode &
AMDGPU_VM_USE_CPU_FOR_COMPUTE);
- else
+
+ if (adev->asic_type == CHIP_RAVEN) {
+ vm->pte_support_ats = true;
+ init_pde_value = AMDGPU_PTE_SYSTEM | AMDGPU_PDE_PTE;
+ }
+ } else
vm->use_cpu_for_update = !!(adev->vm_manager.vm_update_mode &
AMDGPU_VM_USE_CPU_FOR_GFX);
DRM_DEBUG_DRIVER("VM update mode is %s\n",
@@ -2448,7 +2525,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
r = amdgpu_bo_create(adev, amdgpu_vm_bo_size(adev, 0), align, true,
AMDGPU_GEM_DOMAIN_VRAM,
flags,
- NULL, NULL, &vm->root.bo);
+ NULL, NULL, init_pde_value, &vm->root.bo);
if (r)
goto error_free_sched_entity;
@@ -2457,6 +2534,13 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
goto error_free_root;
vm->last_eviction_counter = atomic64_read(&adev->num_evictions);
+
+ if (vm->use_cpu_for_update) {
+ r = amdgpu_bo_kmap(vm->root.bo, NULL);
+ if (r)
+ goto error_free_root;
+ }
+
amdgpu_bo_unreserve(vm->root.bo);
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
index 936f158bc5ec..ba6691b58ee7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
@@ -50,9 +50,6 @@ struct amdgpu_bo_list_entry;
/* PTBs (Page Table Blocks) need to be aligned to 32K */
#define AMDGPU_VM_PTB_ALIGN_SIZE 32768
-/* LOG2 number of continuous pages for the fragment field */
-#define AMDGPU_LOG2_PAGES_PER_FRAG 4
-
#define AMDGPU_PTE_VALID (1ULL << 0)
#define AMDGPU_PTE_SYSTEM (1ULL << 1)
#define AMDGPU_PTE_SNOOPED (1ULL << 2)
@@ -68,6 +65,9 @@ struct amdgpu_bo_list_entry;
/* TILED for VEGA10, reserved for older ASICs */
#define AMDGPU_PTE_PRT (1ULL << 51)
+/* PDE is handled as PTE for VEGA10 */
+#define AMDGPU_PDE_PTE (1ULL << 54)
+
/* VEGA10 only */
#define AMDGPU_PTE_MTYPE(a) ((uint64_t)a << 57)
#define AMDGPU_PTE_MTYPE_MASK AMDGPU_PTE_MTYPE(3ULL)
@@ -94,6 +94,18 @@ struct amdgpu_bo_list_entry;
#define AMDGPU_VM_USE_CPU_FOR_GFX (1 << 0)
#define AMDGPU_VM_USE_CPU_FOR_COMPUTE (1 << 1)
+/* base structure for tracking BO usage in a VM */
+struct amdgpu_vm_bo_base {
+ /* constant after initialization */
+ struct amdgpu_vm *vm;
+ struct amdgpu_bo *bo;
+
+ /* protected by bo being reserved */
+ struct list_head bo_list;
+
+ /* protected by spinlock */
+ struct list_head vm_status;
+};
struct amdgpu_vm_pt {
struct amdgpu_bo *bo;
@@ -112,7 +124,7 @@ struct amdgpu_vm {
spinlock_t status_lock;
/* BOs moved, but not yet updated in the PT */
- struct list_head invalidated;
+ struct list_head moved;
/* BOs cleared in the PT because of a move */
struct list_head cleared;
@@ -135,11 +147,12 @@ struct amdgpu_vm {
u64 client_id;
/* dedicated to vm */
struct amdgpu_vm_id *reserved_vmid[AMDGPU_MAX_VMHUBS];
- /* each VM will map on CSA */
- struct amdgpu_bo_va *csa_bo_va;
/* Flag to indicate if VM tables are updated by CPU or GPU (SDMA) */
bool use_cpu_for_update;
+
+ /* Flag to indicate ATS support from PTE for GFX9 */
+ bool pte_support_ats;
};
struct amdgpu_vm_id {
@@ -182,6 +195,7 @@ struct amdgpu_vm_manager {
uint32_t num_level;
uint64_t vm_size;
uint32_t block_size;
+ uint32_t fragment_size;
/* vram base address for page table entry */
u64 vram_base_offset;
/* vm pte handling */
@@ -214,15 +228,13 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
int (*callback)(void *p, struct amdgpu_bo *bo),
void *param);
-void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev,
- struct amdgpu_vm *vm);
int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
struct amdgpu_vm *vm,
uint64_t saddr, uint64_t size);
int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
struct amdgpu_sync *sync, struct dma_fence *fence,
struct amdgpu_job *job);
-int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job);
+int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_pipe_sync);
void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vmhub,
unsigned vmid);
void amdgpu_vm_reset_all_ids(struct amdgpu_device *adev);
@@ -231,8 +243,8 @@ int amdgpu_vm_update_directories(struct amdgpu_device *adev,
int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
struct amdgpu_vm *vm,
struct dma_fence **fence);
-int amdgpu_vm_clear_invalids(struct amdgpu_device *adev, struct amdgpu_vm *vm,
- struct amdgpu_sync *sync);
+int amdgpu_vm_clear_moved(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+ struct amdgpu_sync *sync);
int amdgpu_vm_bo_update(struct amdgpu_device *adev,
struct amdgpu_bo_va *bo_va,
bool clear);
@@ -259,7 +271,10 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
uint64_t saddr, uint64_t size);
void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
struct amdgpu_bo_va *bo_va);
-void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint64_t vm_size);
+void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev,
+ uint32_t fragment_size_default);
+void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint64_t vm_size,
+ uint32_t fragment_size_default);
int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring,
struct amdgpu_job *job);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
index a2c59a08b2bd..26e900627971 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -28,6 +28,8 @@
struct amdgpu_vram_mgr {
struct drm_mm mm;
spinlock_t lock;
+ atomic64_t usage;
+ atomic64_t vis_usage;
};
/**
@@ -79,6 +81,27 @@ static int amdgpu_vram_mgr_fini(struct ttm_mem_type_manager *man)
}
/**
+ * amdgpu_vram_mgr_vis_size - Calculate visible node size
+ *
+ * @adev: amdgpu device structure
+ * @node: MM node structure
+ *
+ * Calculate how many bytes of the MM node are inside visible VRAM
+ */
+static u64 amdgpu_vram_mgr_vis_size(struct amdgpu_device *adev,
+ struct drm_mm_node *node)
+{
+ uint64_t start = node->start << PAGE_SHIFT;
+ uint64_t end = (node->size + node->start) << PAGE_SHIFT;
+
+ if (start >= adev->mc.visible_vram_size)
+ return 0;
+
+ return (end > adev->mc.visible_vram_size ?
+ adev->mc.visible_vram_size : end) - start;
+}
+
+/**
* amdgpu_vram_mgr_new - allocate new ranges
*
* @man: TTM memory type manager
@@ -93,11 +116,13 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,
const struct ttm_place *place,
struct ttm_mem_reg *mem)
{
+ struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);
struct amdgpu_vram_mgr *mgr = man->priv;
struct drm_mm *mm = &mgr->mm;
struct drm_mm_node *nodes;
enum drm_mm_insert_mode mode;
unsigned long lpfn, num_nodes, pages_per_node, pages_left;
+ uint64_t usage = 0, vis_usage = 0;
unsigned i;
int r;
@@ -142,6 +167,9 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,
if (unlikely(r))
goto error;
+ usage += nodes[i].size << PAGE_SHIFT;
+ vis_usage += amdgpu_vram_mgr_vis_size(adev, &nodes[i]);
+
/* Calculate a virtual BO start address to easily check if
* everything is CPU accessible.
*/
@@ -155,6 +183,9 @@ static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,
}
spin_unlock(&mgr->lock);
+ atomic64_add(usage, &mgr->usage);
+ atomic64_add(vis_usage, &mgr->vis_usage);
+
mem->mm_node = nodes;
return 0;
@@ -181,8 +212,10 @@ error:
static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man,
struct ttm_mem_reg *mem)
{
+ struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);
struct amdgpu_vram_mgr *mgr = man->priv;
struct drm_mm_node *nodes = mem->mm_node;
+ uint64_t usage = 0, vis_usage = 0;
unsigned pages = mem->num_pages;
if (!mem->mm_node)
@@ -192,31 +225,67 @@ static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man,
while (pages) {
pages -= nodes->size;
drm_mm_remove_node(nodes);
+ usage += nodes->size << PAGE_SHIFT;
+ vis_usage += amdgpu_vram_mgr_vis_size(adev, nodes);
++nodes;
}
spin_unlock(&mgr->lock);
+ atomic64_sub(usage, &mgr->usage);
+ atomic64_sub(vis_usage, &mgr->vis_usage);
+
kfree(mem->mm_node);
mem->mm_node = NULL;
}
/**
+ * amdgpu_vram_mgr_usage - how many bytes are used in this domain
+ *
+ * @man: TTM memory type manager
+ *
+ * Returns how many bytes are used in this domain.
+ */
+uint64_t amdgpu_vram_mgr_usage(struct ttm_mem_type_manager *man)
+{
+ struct amdgpu_vram_mgr *mgr = man->priv;
+
+ return atomic64_read(&mgr->usage);
+}
+
+/**
+ * amdgpu_vram_mgr_vis_usage - how many bytes are used in the visible part
+ *
+ * @man: TTM memory type manager
+ *
+ * Returns how many bytes are used in the visible part of VRAM
+ */
+uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_mem_type_manager *man)
+{
+ struct amdgpu_vram_mgr *mgr = man->priv;
+
+ return atomic64_read(&mgr->vis_usage);
+}
+
+/**
* amdgpu_vram_mgr_debug - dump VRAM table
*
* @man: TTM memory type manager
- * @prefix: text prefix
+ * @printer: DRM printer to use
*
* Dump the table content using printk.
*/
static void amdgpu_vram_mgr_debug(struct ttm_mem_type_manager *man,
- const char *prefix)
+ struct drm_printer *printer)
{
struct amdgpu_vram_mgr *mgr = man->priv;
- struct drm_printer p = drm_debug_printer(prefix);
spin_lock(&mgr->lock);
- drm_mm_print(&mgr->mm, &p);
+ drm_mm_print(&mgr->mm, printer);
spin_unlock(&mgr->lock);
+
+ drm_printf(printer, "man size:%llu pages, ram usage:%lluMB, vis usage:%lluMB\n",
+ man->size, amdgpu_vram_mgr_usage(man) >> 20,
+ amdgpu_vram_mgr_vis_usage(man) >> 20);
}
const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func = {
diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c
index 37a499ab30eb..567c4a5cf90c 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik.c
@@ -1824,21 +1824,14 @@ static int cik_common_suspend(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- amdgpu_amdkfd_suspend(adev);
-
return cik_common_hw_fini(adev);
}
static int cik_common_resume(void *handle)
{
- int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- r = cik_common_hw_init(adev);
- if (r)
- return r;
-
- return amdgpu_amdkfd_resume(adev);
+ return cik_common_hw_init(adev);
}
static bool cik_common_is_idle(void *handle)
diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
index c216e16826c9..f508f4d01e4a 100644
--- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c
@@ -342,6 +342,63 @@ static void cik_sdma_rlc_stop(struct amdgpu_device *adev)
}
/**
+ * cik_ctx_switch_enable - stop the async dma engines context switch
+ *
+ * @adev: amdgpu_device pointer
+ * @enable: enable/disable the DMA MEs context switch.
+ *
+ * Halt or unhalt the async dma engines context switch (VI).
+ */
+static void cik_ctx_switch_enable(struct amdgpu_device *adev, bool enable)
+{
+ u32 f32_cntl, phase_quantum = 0;
+ int i;
+
+ if (amdgpu_sdma_phase_quantum) {
+ unsigned value = amdgpu_sdma_phase_quantum;
+ unsigned unit = 0;
+
+ while (value > (SDMA0_PHASE0_QUANTUM__VALUE_MASK >>
+ SDMA0_PHASE0_QUANTUM__VALUE__SHIFT)) {
+ value = (value + 1) >> 1;
+ unit++;
+ }
+ if (unit > (SDMA0_PHASE0_QUANTUM__UNIT_MASK >>
+ SDMA0_PHASE0_QUANTUM__UNIT__SHIFT)) {
+ value = (SDMA0_PHASE0_QUANTUM__VALUE_MASK >>
+ SDMA0_PHASE0_QUANTUM__VALUE__SHIFT);
+ unit = (SDMA0_PHASE0_QUANTUM__UNIT_MASK >>
+ SDMA0_PHASE0_QUANTUM__UNIT__SHIFT);
+ WARN_ONCE(1,
+ "clamping sdma_phase_quantum to %uK clock cycles\n",
+ value << unit);
+ }
+ phase_quantum =
+ value << SDMA0_PHASE0_QUANTUM__VALUE__SHIFT |
+ unit << SDMA0_PHASE0_QUANTUM__UNIT__SHIFT;
+ }
+
+ for (i = 0; i < adev->sdma.num_instances; i++) {
+ f32_cntl = RREG32(mmSDMA0_CNTL + sdma_offsets[i]);
+ if (enable) {
+ f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
+ AUTO_CTXSW_ENABLE, 1);
+ if (amdgpu_sdma_phase_quantum) {
+ WREG32(mmSDMA0_PHASE0_QUANTUM + sdma_offsets[i],
+ phase_quantum);
+ WREG32(mmSDMA0_PHASE1_QUANTUM + sdma_offsets[i],
+ phase_quantum);
+ }
+ } else {
+ f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
+ AUTO_CTXSW_ENABLE, 0);
+ }
+
+ WREG32(mmSDMA0_CNTL + sdma_offsets[i], f32_cntl);
+ }
+}
+
+/**
* cik_sdma_enable - stop the async dma engines
*
* @adev: amdgpu_device pointer
@@ -537,6 +594,8 @@ static int cik_sdma_start(struct amdgpu_device *adev)
/* halt the engine before programing */
cik_sdma_enable(adev, false);
+ /* enable sdma ring preemption */
+ cik_ctx_switch_enable(adev, true);
/* start the gfx rings and rlc compute queues */
r = cik_sdma_gfx_resume(adev);
@@ -984,6 +1043,7 @@ static int cik_sdma_hw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ cik_ctx_switch_enable(adev, false);
cik_sdma_enable(adev, false);
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/clearstate_gfx9.h b/drivers/gpu/drm/amd/amdgpu/clearstate_gfx9.h
index 18fd01f3e4b2..003a131bad47 100644
--- a/drivers/gpu/drm/amd/amdgpu/clearstate_gfx9.h
+++ b/drivers/gpu/drm/amd/amdgpu/clearstate_gfx9.h
@@ -1,24 +1,25 @@
-
/*
-***************************************************************************************************
-*
-* Trade secret of Advanced Micro Devices, Inc.
-* Copyright (c) 2010 Advanced Micro Devices, Inc. (unpublished)
-*
-* All rights reserved. This notice is intended as a precaution against inadvertent publication and
-* does not imply publication or any waiver of confidentiality. The year included in the foregoing
-* notice is the year of creation of the work.
-*
-***************************************************************************************************
-*/
-/**
-***************************************************************************************************
-* @brief gfx9 Clearstate Definitions
-***************************************************************************************************
-*
-* Do not edit! This is a machine-generated file!
-*
-*/
+ * Copyright 2017 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.
+ *
+ */
static const unsigned int gfx9_SECT_CONTEXT_def_1[] =
{
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
index 9f78c03a2e31..4e519dc42916 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -484,134 +484,6 @@ static bool dce_v10_0_is_display_hung(struct amdgpu_device *adev)
return true;
}
-static void dce_v10_0_stop_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- u32 crtc_enabled, tmp;
- int i;
-
- save->vga_render_control = RREG32(mmVGA_RENDER_CONTROL);
- save->vga_hdp_control = RREG32(mmVGA_HDP_CONTROL);
-
- /* disable VGA render */
- tmp = RREG32(mmVGA_RENDER_CONTROL);
- tmp = REG_SET_FIELD(tmp, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0);
- WREG32(mmVGA_RENDER_CONTROL, tmp);
-
- /* blank the display controllers */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]),
- CRTC_CONTROL, CRTC_MASTER_EN);
- if (crtc_enabled) {
-#if 0
- u32 frame_count;
- int j;
-
- save->crtc_enabled[i] = true;
- tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN) == 0) {
- amdgpu_display_vblank_wait(adev, i);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
- tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 1);
- WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
- }
- /* wait for the next frame */
- frame_count = amdgpu_display_vblank_get_counter(adev, i);
- for (j = 0; j < adev->usec_timeout; j++) {
- if (amdgpu_display_vblank_get_counter(adev, i) != frame_count)
- break;
- udelay(1);
- }
- tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK) == 0) {
- tmp = REG_SET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK, 1);
- WREG32(mmGRPH_UPDATE + crtc_offsets[i], tmp);
- }
- tmp = RREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, MASTER_UPDATE_LOCK, MASTER_UPDATE_LOCK) == 0) {
- tmp = REG_SET_FIELD(tmp, MASTER_UPDATE_LOCK, MASTER_UPDATE_LOCK, 1);
- WREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
- }
-#else
- /* XXX this is a hack to avoid strange behavior with EFI on certain systems */
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
- tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]);
- tmp = REG_SET_FIELD(tmp, CRTC_CONTROL, CRTC_MASTER_EN, 0);
- WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
- save->crtc_enabled[i] = false;
- /* ***** */
-#endif
- } else {
- save->crtc_enabled[i] = false;
- }
- }
-}
-
-static void dce_v10_0_resume_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- u32 tmp, frame_count;
- int i, j;
-
- /* update crtc base addresses */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
- upper_32_bits(adev->mc.vram_start));
- WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
- upper_32_bits(adev->mc.vram_start));
- WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i],
- (u32)adev->mc.vram_start);
- WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i],
- (u32)adev->mc.vram_start);
-
- if (save->crtc_enabled[i]) {
- tmp = RREG32(mmMASTER_UPDATE_MODE + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, MASTER_UPDATE_MODE, MASTER_UPDATE_MODE) != 0) {
- tmp = REG_SET_FIELD(tmp, MASTER_UPDATE_MODE, MASTER_UPDATE_MODE, 0);
- WREG32(mmMASTER_UPDATE_MODE + crtc_offsets[i], tmp);
- }
- tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK)) {
- tmp = REG_SET_FIELD(tmp, GRPH_UPDATE, GRPH_UPDATE_LOCK, 0);
- WREG32(mmGRPH_UPDATE + crtc_offsets[i], tmp);
- }
- tmp = RREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, MASTER_UPDATE_LOCK, MASTER_UPDATE_LOCK)) {
- tmp = REG_SET_FIELD(tmp, MASTER_UPDATE_LOCK, MASTER_UPDATE_LOCK, 0);
- WREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
- }
- for (j = 0; j < adev->usec_timeout; j++) {
- tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, GRPH_UPDATE, GRPH_SURFACE_UPDATE_PENDING) == 0)
- break;
- udelay(1);
- }
- tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]);
- tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 0);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
- WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
- /* wait for the next frame */
- frame_count = amdgpu_display_vblank_get_counter(adev, i);
- for (j = 0; j < adev->usec_timeout; j++) {
- if (amdgpu_display_vblank_get_counter(adev, i) != frame_count)
- break;
- udelay(1);
- }
- }
- }
-
- WREG32(mmVGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(adev->mc.vram_start));
- WREG32(mmVGA_MEMORY_BASE_ADDRESS, lower_32_bits(adev->mc.vram_start));
-
- /* Unlock vga access */
- WREG32(mmVGA_HDP_CONTROL, save->vga_hdp_control);
- mdelay(1);
- WREG32(mmVGA_RENDER_CONTROL, save->vga_render_control);
-}
-
static void dce_v10_0_set_vga_render_state(struct amdgpu_device *adev,
bool render)
{
@@ -1867,7 +1739,7 @@ static void dce_v10_0_afmt_setmode(struct drm_encoder *encoder,
dce_v10_0_audio_write_sad_regs(encoder);
dce_v10_0_audio_write_latency_fields(encoder, mode);
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (err < 0) {
DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
return;
@@ -2267,6 +2139,7 @@ static void dce_v10_0_crtc_load_lut(struct drm_crtc *crtc)
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct amdgpu_device *adev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
u32 tmp;
@@ -2304,11 +2177,14 @@ static void dce_v10_0_crtc_load_lut(struct drm_crtc *crtc)
WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007);
WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0);
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
for (i = 0; i < 256; i++) {
WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset,
- (amdgpu_crtc->lut_r[i] << 20) |
- (amdgpu_crtc->lut_g[i] << 10) |
- (amdgpu_crtc->lut_b[i] << 0));
+ ((*r++ & 0xffc0) << 14) |
+ ((*g++ & 0xffc0) << 4) |
+ (*b++ >> 6));
}
tmp = RREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset);
@@ -2555,7 +2431,7 @@ static int dce_v10_0_crtc_cursor_set2(struct drm_crtc *crtc,
aobj = gem_to_amdgpu_bo(obj);
ret = amdgpu_bo_reserve(aobj, false);
if (ret != 0) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -2563,7 +2439,7 @@ static int dce_v10_0_crtc_cursor_set2(struct drm_crtc *crtc,
amdgpu_bo_unreserve(aobj);
if (ret) {
DRM_ERROR("Failed to pin new cursor BO (%d)\n", ret);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -2597,7 +2473,7 @@ unpin:
amdgpu_bo_unpin(aobj);
amdgpu_bo_unreserve(aobj);
}
- drm_gem_object_unreference_unlocked(amdgpu_crtc->cursor_bo);
+ drm_gem_object_put_unlocked(amdgpu_crtc->cursor_bo);
}
amdgpu_crtc->cursor_bo = obj;
@@ -2624,15 +2500,6 @@ static int dce_v10_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
- int i;
-
- /* userspace palettes are always correct as is */
- for (i = 0; i < size; i++) {
- amdgpu_crtc->lut_r[i] = red[i] >> 6;
- amdgpu_crtc->lut_g[i] = green[i] >> 6;
- amdgpu_crtc->lut_b[i] = blue[i] >> 6;
- }
dce_v10_0_crtc_load_lut(crtc);
return 0;
@@ -2844,14 +2711,12 @@ static const struct drm_crtc_helper_funcs dce_v10_0_crtc_helper_funcs = {
.mode_set_base_atomic = dce_v10_0_crtc_set_base_atomic,
.prepare = dce_v10_0_crtc_prepare,
.commit = dce_v10_0_crtc_commit,
- .load_lut = dce_v10_0_crtc_load_lut,
.disable = dce_v10_0_crtc_disable,
};
static int dce_v10_0_crtc_init(struct amdgpu_device *adev, int index)
{
struct amdgpu_crtc *amdgpu_crtc;
- int i;
amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
(AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
@@ -2869,12 +2734,6 @@ static int dce_v10_0_crtc_init(struct amdgpu_device *adev, int index)
adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width;
adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height;
- for (i = 0; i < 256; i++) {
- amdgpu_crtc->lut_r[i] = i << 2;
- amdgpu_crtc->lut_g[i] = i << 2;
- amdgpu_crtc->lut_b[i] = i << 2;
- }
-
switch (amdgpu_crtc->crtc_id) {
case 0:
default:
@@ -3025,6 +2884,8 @@ static int dce_v10_0_hw_init(void *handle)
dce_v10_0_init_golden_registers(adev);
+ /* disable vga render */
+ dce_v10_0_set_vga_render_state(adev, false);
/* init dig PHYs, disp eng pll */
amdgpu_atombios_encoder_init_dig(adev);
amdgpu_atombios_crtc_set_disp_eng_pll(adev, adev->clock.default_dispclk);
@@ -3737,7 +3598,6 @@ static void dce_v10_0_encoder_add(struct amdgpu_device *adev,
}
static const struct amdgpu_display_funcs dce_v10_0_display_funcs = {
- .set_vga_render_state = &dce_v10_0_set_vga_render_state,
.bandwidth_update = &dce_v10_0_bandwidth_update,
.vblank_get_counter = &dce_v10_0_vblank_get_counter,
.vblank_wait = &dce_v10_0_vblank_wait,
@@ -3750,8 +3610,6 @@ static const struct amdgpu_display_funcs dce_v10_0_display_funcs = {
.page_flip_get_scanoutpos = &dce_v10_0_crtc_get_scanoutpos,
.add_encoder = &dce_v10_0_encoder_add,
.add_connector = &amdgpu_connector_add,
- .stop_mc_access = &dce_v10_0_stop_mc_access,
- .resume_mc_access = &dce_v10_0_resume_mc_access,
};
static void dce_v10_0_set_display_funcs(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index 4bcf01dc567a..11edc75edaa9 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -499,79 +499,6 @@ static bool dce_v11_0_is_display_hung(struct amdgpu_device *adev)
return true;
}
-static void dce_v11_0_stop_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- u32 crtc_enabled, tmp;
- int i;
-
- save->vga_render_control = RREG32(mmVGA_RENDER_CONTROL);
- save->vga_hdp_control = RREG32(mmVGA_HDP_CONTROL);
-
- /* disable VGA render */
- tmp = RREG32(mmVGA_RENDER_CONTROL);
- tmp = REG_SET_FIELD(tmp, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0);
- WREG32(mmVGA_RENDER_CONTROL, tmp);
-
- /* blank the display controllers */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]),
- CRTC_CONTROL, CRTC_MASTER_EN);
- if (crtc_enabled) {
-#if 1
- save->crtc_enabled[i] = true;
- tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN) == 0) {
- /*it is correct only for RGB ; black is 0*/
- WREG32(mmCRTC_BLANK_DATA_COLOR + crtc_offsets[i], 0);
- tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 1);
- WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
- }
-#else
- /* XXX this is a hack to avoid strange behavior with EFI on certain systems */
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
- tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]);
- tmp = REG_SET_FIELD(tmp, CRTC_CONTROL, CRTC_MASTER_EN, 0);
- WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
- save->crtc_enabled[i] = false;
- /* ***** */
-#endif
- } else {
- save->crtc_enabled[i] = false;
- }
- }
-}
-
-static void dce_v11_0_resume_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- u32 tmp;
- int i;
-
- /* update crtc base addresses */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
- upper_32_bits(adev->mc.vram_start));
- WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i],
- (u32)adev->mc.vram_start);
-
- if (save->crtc_enabled[i]) {
- tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]);
- tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 0);
- WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
- }
- }
-
- WREG32(mmVGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(adev->mc.vram_start));
- WREG32(mmVGA_MEMORY_BASE_ADDRESS, lower_32_bits(adev->mc.vram_start));
-
- /* Unlock vga access */
- WREG32(mmVGA_HDP_CONTROL, save->vga_hdp_control);
- mdelay(1);
- WREG32(mmVGA_RENDER_CONTROL, save->vga_render_control);
-}
-
static void dce_v11_0_set_vga_render_state(struct amdgpu_device *adev,
bool render)
{
@@ -1851,7 +1778,7 @@ static void dce_v11_0_afmt_setmode(struct drm_encoder *encoder,
dce_v11_0_audio_write_sad_regs(encoder);
dce_v11_0_audio_write_latency_fields(encoder, mode);
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (err < 0) {
DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
return;
@@ -2251,6 +2178,7 @@ static void dce_v11_0_crtc_load_lut(struct drm_crtc *crtc)
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct amdgpu_device *adev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
u32 tmp;
@@ -2282,11 +2210,14 @@ static void dce_v11_0_crtc_load_lut(struct drm_crtc *crtc)
WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007);
WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0);
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
for (i = 0; i < 256; i++) {
WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset,
- (amdgpu_crtc->lut_r[i] << 20) |
- (amdgpu_crtc->lut_g[i] << 10) |
- (amdgpu_crtc->lut_b[i] << 0));
+ ((*r++ & 0xffc0) << 14) |
+ ((*g++ & 0xffc0) << 4) |
+ (*b++ >> 6));
}
tmp = RREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset);
@@ -2575,7 +2506,7 @@ static int dce_v11_0_crtc_cursor_set2(struct drm_crtc *crtc,
aobj = gem_to_amdgpu_bo(obj);
ret = amdgpu_bo_reserve(aobj, false);
if (ret != 0) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -2583,7 +2514,7 @@ static int dce_v11_0_crtc_cursor_set2(struct drm_crtc *crtc,
amdgpu_bo_unreserve(aobj);
if (ret) {
DRM_ERROR("Failed to pin new cursor BO (%d)\n", ret);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -2617,7 +2548,7 @@ unpin:
amdgpu_bo_unpin(aobj);
amdgpu_bo_unreserve(aobj);
}
- drm_gem_object_unreference_unlocked(amdgpu_crtc->cursor_bo);
+ drm_gem_object_put_unlocked(amdgpu_crtc->cursor_bo);
}
amdgpu_crtc->cursor_bo = obj;
@@ -2644,15 +2575,6 @@ static int dce_v11_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
- int i;
-
- /* userspace palettes are always correct as is */
- for (i = 0; i < size; i++) {
- amdgpu_crtc->lut_r[i] = red[i] >> 6;
- amdgpu_crtc->lut_g[i] = green[i] >> 6;
- amdgpu_crtc->lut_b[i] = blue[i] >> 6;
- }
dce_v11_0_crtc_load_lut(crtc);
return 0;
@@ -2892,14 +2814,12 @@ static const struct drm_crtc_helper_funcs dce_v11_0_crtc_helper_funcs = {
.mode_set_base_atomic = dce_v11_0_crtc_set_base_atomic,
.prepare = dce_v11_0_crtc_prepare,
.commit = dce_v11_0_crtc_commit,
- .load_lut = dce_v11_0_crtc_load_lut,
.disable = dce_v11_0_crtc_disable,
};
static int dce_v11_0_crtc_init(struct amdgpu_device *adev, int index)
{
struct amdgpu_crtc *amdgpu_crtc;
- int i;
amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
(AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
@@ -2917,12 +2837,6 @@ static int dce_v11_0_crtc_init(struct amdgpu_device *adev, int index)
adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width;
adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height;
- for (i = 0; i < 256; i++) {
- amdgpu_crtc->lut_r[i] = i << 2;
- amdgpu_crtc->lut_g[i] = i << 2;
- amdgpu_crtc->lut_b[i] = i << 2;
- }
-
switch (amdgpu_crtc->crtc_id) {
case 0:
default:
@@ -3086,6 +3000,8 @@ static int dce_v11_0_hw_init(void *handle)
dce_v11_0_init_golden_registers(adev);
+ /* disable vga render */
+ dce_v11_0_set_vga_render_state(adev, false);
/* init dig PHYs, disp eng pll */
amdgpu_atombios_crtc_powergate_init(adev);
amdgpu_atombios_encoder_init_dig(adev);
@@ -3806,7 +3722,6 @@ static void dce_v11_0_encoder_add(struct amdgpu_device *adev,
}
static const struct amdgpu_display_funcs dce_v11_0_display_funcs = {
- .set_vga_render_state = &dce_v11_0_set_vga_render_state,
.bandwidth_update = &dce_v11_0_bandwidth_update,
.vblank_get_counter = &dce_v11_0_vblank_get_counter,
.vblank_wait = &dce_v11_0_vblank_wait,
@@ -3819,8 +3734,6 @@ static const struct amdgpu_display_funcs dce_v11_0_display_funcs = {
.page_flip_get_scanoutpos = &dce_v11_0_crtc_get_scanoutpos,
.add_encoder = &dce_v11_0_encoder_add,
.add_connector = &amdgpu_connector_add,
- .stop_mc_access = &dce_v11_0_stop_mc_access,
- .resume_mc_access = &dce_v11_0_resume_mc_access,
};
static void dce_v11_0_set_display_funcs(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
index fd134a4629d7..a51e35f824a1 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
@@ -42,6 +42,7 @@
#include "dce/dce_6_0_d.h"
#include "dce/dce_6_0_sh_mask.h"
#include "gca/gfx_7_2_enum.h"
+#include "dce_v6_0.h"
#include "si_enums.h"
static void dce_v6_0_set_display_funcs(struct amdgpu_device *adev);
@@ -392,117 +393,6 @@ static u32 dce_v6_0_hpd_get_gpio_reg(struct amdgpu_device *adev)
return mmDC_GPIO_HPD_A;
}
-static u32 evergreen_get_vblank_counter(struct amdgpu_device* adev, int crtc)
-{
- if (crtc >= adev->mode_info.num_crtc)
- return 0;
- else
- return RREG32(mmCRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]);
-}
-
-static void dce_v6_0_stop_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- u32 crtc_enabled, tmp, frame_count;
- int i, j;
-
- save->vga_render_control = RREG32(mmVGA_RENDER_CONTROL);
- save->vga_hdp_control = RREG32(mmVGA_HDP_CONTROL);
-
- /* disable VGA render */
- WREG32(mmVGA_RENDER_CONTROL, 0);
-
- /* blank the display controllers */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- crtc_enabled = RREG32(mmCRTC_CONTROL + crtc_offsets[i]) & CRTC_CONTROL__CRTC_MASTER_EN_MASK;
- if (crtc_enabled) {
- save->crtc_enabled[i] = true;
- tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]);
-
- if (!(tmp & CRTC_BLANK_CONTROL__CRTC_BLANK_DATA_EN_MASK)) {
- dce_v6_0_vblank_wait(adev, i);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
- tmp |= CRTC_BLANK_CONTROL__CRTC_BLANK_DATA_EN_MASK;
- WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
- }
- /* wait for the next frame */
- frame_count = evergreen_get_vblank_counter(adev, i);
- for (j = 0; j < adev->usec_timeout; j++) {
- if (evergreen_get_vblank_counter(adev, i) != frame_count)
- break;
- udelay(1);
- }
-
- /* XXX this is a hack to avoid strange behavior with EFI on certain systems */
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
- tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]);
- tmp &= ~CRTC_CONTROL__CRTC_MASTER_EN_MASK;
- WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
- save->crtc_enabled[i] = false;
- /* ***** */
- } else {
- save->crtc_enabled[i] = false;
- }
- }
-}
-
-static void dce_v6_0_resume_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- u32 tmp;
- int i, j;
-
- /* update crtc base addresses */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
- upper_32_bits(adev->mc.vram_start));
- WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
- upper_32_bits(adev->mc.vram_start));
- WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i],
- (u32)adev->mc.vram_start);
- WREG32(mmGRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i],
- (u32)adev->mc.vram_start);
- }
-
- WREG32(mmVGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(adev->mc.vram_start));
- WREG32(mmVGA_MEMORY_BASE_ADDRESS, (u32)adev->mc.vram_start);
-
- /* unlock regs and wait for update */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- if (save->crtc_enabled[i]) {
- tmp = RREG32(mmMASTER_UPDATE_MODE + crtc_offsets[i]);
- if ((tmp & 0x7) != 0) {
- tmp &= ~0x7;
- WREG32(mmMASTER_UPDATE_MODE + crtc_offsets[i], tmp);
- }
- tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]);
- if (tmp & GRPH_UPDATE__GRPH_UPDATE_LOCK_MASK) {
- tmp &= ~GRPH_UPDATE__GRPH_UPDATE_LOCK_MASK;
- WREG32(mmGRPH_UPDATE + crtc_offsets[i], tmp);
- }
- tmp = RREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i]);
- if (tmp & 1) {
- tmp &= ~1;
- WREG32(mmMASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
- }
- for (j = 0; j < adev->usec_timeout; j++) {
- tmp = RREG32(mmGRPH_UPDATE + crtc_offsets[i]);
- if ((tmp & GRPH_UPDATE__GRPH_SURFACE_UPDATE_PENDING_MASK) == 0)
- break;
- udelay(1);
- }
- }
- }
-
- /* Unlock vga access */
- WREG32(mmVGA_HDP_CONTROL, save->vga_hdp_control);
- mdelay(1);
- WREG32(mmVGA_RENDER_CONTROL, save->vga_render_control);
-
-}
-
static void dce_v6_0_set_vga_render_state(struct amdgpu_device *adev,
bool render)
{
@@ -1597,7 +1487,7 @@ static void dce_v6_0_audio_set_avi_infoframe(struct drm_encoder *encoder,
ssize_t err;
u32 tmp;
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (err < 0) {
DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
return;
@@ -2182,6 +2072,7 @@ static void dce_v6_0_crtc_load_lut(struct drm_crtc *crtc)
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct amdgpu_device *adev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
DRM_DEBUG_KMS("%d\n", amdgpu_crtc->crtc_id);
@@ -2211,11 +2102,14 @@ static void dce_v6_0_crtc_load_lut(struct drm_crtc *crtc)
WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007);
WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0);
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
for (i = 0; i < 256; i++) {
WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset,
- (amdgpu_crtc->lut_r[i] << 20) |
- (amdgpu_crtc->lut_g[i] << 10) |
- (amdgpu_crtc->lut_b[i] << 0));
+ ((*r++ & 0xffc0) << 14) |
+ ((*g++ & 0xffc0) << 4) |
+ (*b++ >> 6));
}
WREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset,
@@ -2428,7 +2322,7 @@ static int dce_v6_0_crtc_cursor_set2(struct drm_crtc *crtc,
aobj = gem_to_amdgpu_bo(obj);
ret = amdgpu_bo_reserve(aobj, false);
if (ret != 0) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -2436,7 +2330,7 @@ static int dce_v6_0_crtc_cursor_set2(struct drm_crtc *crtc,
amdgpu_bo_unreserve(aobj);
if (ret) {
DRM_ERROR("Failed to pin new cursor BO (%d)\n", ret);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -2470,7 +2364,7 @@ unpin:
amdgpu_bo_unpin(aobj);
amdgpu_bo_unreserve(aobj);
}
- drm_gem_object_unreference_unlocked(amdgpu_crtc->cursor_bo);
+ drm_gem_object_put_unlocked(amdgpu_crtc->cursor_bo);
}
amdgpu_crtc->cursor_bo = obj;
@@ -2496,15 +2390,6 @@ static int dce_v6_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
- int i;
-
- /* userspace palettes are always correct as is */
- for (i = 0; i < size; i++) {
- amdgpu_crtc->lut_r[i] = red[i] >> 6;
- amdgpu_crtc->lut_g[i] = green[i] >> 6;
- amdgpu_crtc->lut_b[i] = blue[i] >> 6;
- }
dce_v6_0_crtc_load_lut(crtc);
return 0;
@@ -2712,14 +2597,12 @@ static const struct drm_crtc_helper_funcs dce_v6_0_crtc_helper_funcs = {
.mode_set_base_atomic = dce_v6_0_crtc_set_base_atomic,
.prepare = dce_v6_0_crtc_prepare,
.commit = dce_v6_0_crtc_commit,
- .load_lut = dce_v6_0_crtc_load_lut,
.disable = dce_v6_0_crtc_disable,
};
static int dce_v6_0_crtc_init(struct amdgpu_device *adev, int index)
{
struct amdgpu_crtc *amdgpu_crtc;
- int i;
amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
(AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
@@ -2737,12 +2620,6 @@ static int dce_v6_0_crtc_init(struct amdgpu_device *adev, int index)
adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width;
adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height;
- for (i = 0; i < 256; i++) {
- amdgpu_crtc->lut_r[i] = i << 2;
- amdgpu_crtc->lut_g[i] = i << 2;
- amdgpu_crtc->lut_b[i] = i << 2;
- }
-
amdgpu_crtc->crtc_offset = crtc_offsets[amdgpu_crtc->crtc_id];
amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
@@ -2873,6 +2750,8 @@ static int dce_v6_0_hw_init(void *handle)
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ /* disable vga render */
+ dce_v6_0_set_vga_render_state(adev, false);
/* init dig PHYs, disp eng pll */
amdgpu_atombios_encoder_init_dig(adev);
amdgpu_atombios_crtc_set_disp_eng_pll(adev, adev->clock.default_dispclk);
@@ -3525,7 +3404,6 @@ static void dce_v6_0_encoder_add(struct amdgpu_device *adev,
}
static const struct amdgpu_display_funcs dce_v6_0_display_funcs = {
- .set_vga_render_state = &dce_v6_0_set_vga_render_state,
.bandwidth_update = &dce_v6_0_bandwidth_update,
.vblank_get_counter = &dce_v6_0_vblank_get_counter,
.vblank_wait = &dce_v6_0_vblank_wait,
@@ -3538,8 +3416,6 @@ static const struct amdgpu_display_funcs dce_v6_0_display_funcs = {
.page_flip_get_scanoutpos = &dce_v6_0_crtc_get_scanoutpos,
.add_encoder = &dce_v6_0_encoder_add,
.add_connector = &amdgpu_connector_add,
- .stop_mc_access = &dce_v6_0_stop_mc_access,
- .resume_mc_access = &dce_v6_0_resume_mc_access,
};
static void dce_v6_0_set_display_funcs(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
index a9e869554627..9cf14b8b2db9 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -419,81 +419,6 @@ static bool dce_v8_0_is_display_hung(struct amdgpu_device *adev)
return true;
}
-static void dce_v8_0_stop_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- u32 crtc_enabled, tmp;
- int i;
-
- save->vga_render_control = RREG32(mmVGA_RENDER_CONTROL);
- save->vga_hdp_control = RREG32(mmVGA_HDP_CONTROL);
-
- /* disable VGA render */
- tmp = RREG32(mmVGA_RENDER_CONTROL);
- tmp = REG_SET_FIELD(tmp, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0);
- WREG32(mmVGA_RENDER_CONTROL, tmp);
-
- /* blank the display controllers */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- crtc_enabled = REG_GET_FIELD(RREG32(mmCRTC_CONTROL + crtc_offsets[i]),
- CRTC_CONTROL, CRTC_MASTER_EN);
- if (crtc_enabled) {
-#if 1
- save->crtc_enabled[i] = true;
- tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]);
- if (REG_GET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN) == 0) {
- /*it is correct only for RGB ; black is 0*/
- WREG32(mmCRTC_BLANK_DATA_COLOR + crtc_offsets[i], 0);
- tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 1);
- WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
- }
- mdelay(20);
-#else
- /* XXX this is a hack to avoid strange behavior with EFI on certain systems */
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 1);
- tmp = RREG32(mmCRTC_CONTROL + crtc_offsets[i]);
- tmp = REG_SET_FIELD(tmp, CRTC_CONTROL, CRTC_MASTER_EN, 0);
- WREG32(mmCRTC_CONTROL + crtc_offsets[i], tmp);
- WREG32(mmCRTC_UPDATE_LOCK + crtc_offsets[i], 0);
- save->crtc_enabled[i] = false;
- /* ***** */
-#endif
- } else {
- save->crtc_enabled[i] = false;
- }
- }
-}
-
-static void dce_v8_0_resume_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- u32 tmp;
- int i;
-
- /* update crtc base addresses */
- for (i = 0; i < adev->mode_info.num_crtc; i++) {
- WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
- upper_32_bits(adev->mc.vram_start));
- WREG32(mmGRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i],
- (u32)adev->mc.vram_start);
-
- if (save->crtc_enabled[i]) {
- tmp = RREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i]);
- tmp = REG_SET_FIELD(tmp, CRTC_BLANK_CONTROL, CRTC_BLANK_DATA_EN, 0);
- WREG32(mmCRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
- }
- mdelay(20);
- }
-
- WREG32(mmVGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(adev->mc.vram_start));
- WREG32(mmVGA_MEMORY_BASE_ADDRESS, lower_32_bits(adev->mc.vram_start));
-
- /* Unlock vga access */
- WREG32(mmVGA_HDP_CONTROL, save->vga_hdp_control);
- mdelay(1);
- WREG32(mmVGA_RENDER_CONTROL, save->vga_render_control);
-}
-
static void dce_v8_0_set_vga_render_state(struct amdgpu_device *adev,
bool render)
{
@@ -1750,7 +1675,7 @@ static void dce_v8_0_afmt_setmode(struct drm_encoder *encoder,
dce_v8_0_audio_write_sad_regs(encoder);
dce_v8_0_audio_write_latency_fields(encoder, mode);
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (err < 0) {
DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
return;
@@ -2124,6 +2049,7 @@ static void dce_v8_0_crtc_load_lut(struct drm_crtc *crtc)
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct amdgpu_device *adev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
DRM_DEBUG_KMS("%d\n", amdgpu_crtc->crtc_id);
@@ -2153,11 +2079,14 @@ static void dce_v8_0_crtc_load_lut(struct drm_crtc *crtc)
WREG32(mmDC_LUT_WRITE_EN_MASK + amdgpu_crtc->crtc_offset, 0x00000007);
WREG32(mmDC_LUT_RW_INDEX + amdgpu_crtc->crtc_offset, 0);
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
for (i = 0; i < 256; i++) {
WREG32(mmDC_LUT_30_COLOR + amdgpu_crtc->crtc_offset,
- (amdgpu_crtc->lut_r[i] << 20) |
- (amdgpu_crtc->lut_g[i] << 10) |
- (amdgpu_crtc->lut_b[i] << 0));
+ ((*r++ & 0xffc0) << 14) |
+ ((*g++ & 0xffc0) << 4) |
+ (*b++ >> 6));
}
WREG32(mmDEGAMMA_CONTROL + amdgpu_crtc->crtc_offset,
@@ -2406,7 +2335,7 @@ static int dce_v8_0_crtc_cursor_set2(struct drm_crtc *crtc,
aobj = gem_to_amdgpu_bo(obj);
ret = amdgpu_bo_reserve(aobj, false);
if (ret != 0) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -2414,7 +2343,7 @@ static int dce_v8_0_crtc_cursor_set2(struct drm_crtc *crtc,
amdgpu_bo_unreserve(aobj);
if (ret) {
DRM_ERROR("Failed to pin new cursor BO (%d)\n", ret);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -2448,7 +2377,7 @@ unpin:
amdgpu_bo_unpin(aobj);
amdgpu_bo_unreserve(aobj);
}
- drm_gem_object_unreference_unlocked(amdgpu_crtc->cursor_bo);
+ drm_gem_object_put_unlocked(amdgpu_crtc->cursor_bo);
}
amdgpu_crtc->cursor_bo = obj;
@@ -2475,15 +2404,6 @@ static int dce_v8_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
- int i;
-
- /* userspace palettes are always correct as is */
- for (i = 0; i < size; i++) {
- amdgpu_crtc->lut_r[i] = red[i] >> 6;
- amdgpu_crtc->lut_g[i] = green[i] >> 6;
- amdgpu_crtc->lut_b[i] = blue[i] >> 6;
- }
dce_v8_0_crtc_load_lut(crtc);
return 0;
@@ -2702,14 +2622,12 @@ static const struct drm_crtc_helper_funcs dce_v8_0_crtc_helper_funcs = {
.mode_set_base_atomic = dce_v8_0_crtc_set_base_atomic,
.prepare = dce_v8_0_crtc_prepare,
.commit = dce_v8_0_crtc_commit,
- .load_lut = dce_v8_0_crtc_load_lut,
.disable = dce_v8_0_crtc_disable,
};
static int dce_v8_0_crtc_init(struct amdgpu_device *adev, int index)
{
struct amdgpu_crtc *amdgpu_crtc;
- int i;
amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
(AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
@@ -2727,12 +2645,6 @@ static int dce_v8_0_crtc_init(struct amdgpu_device *adev, int index)
adev->ddev->mode_config.cursor_width = amdgpu_crtc->max_cursor_width;
adev->ddev->mode_config.cursor_height = amdgpu_crtc->max_cursor_height;
- for (i = 0; i < 256; i++) {
- amdgpu_crtc->lut_r[i] = i << 2;
- amdgpu_crtc->lut_g[i] = i << 2;
- amdgpu_crtc->lut_b[i] = i << 2;
- }
-
amdgpu_crtc->crtc_offset = crtc_offsets[amdgpu_crtc->crtc_id];
amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
@@ -2870,6 +2782,8 @@ static int dce_v8_0_hw_init(void *handle)
int i;
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ /* disable vga render */
+ dce_v8_0_set_vga_render_state(adev, false);
/* init dig PHYs, disp eng pll */
amdgpu_atombios_encoder_init_dig(adev);
amdgpu_atombios_crtc_set_disp_eng_pll(adev, adev->clock.default_dispclk);
@@ -3574,7 +3488,6 @@ static void dce_v8_0_encoder_add(struct amdgpu_device *adev,
}
static const struct amdgpu_display_funcs dce_v8_0_display_funcs = {
- .set_vga_render_state = &dce_v8_0_set_vga_render_state,
.bandwidth_update = &dce_v8_0_bandwidth_update,
.vblank_get_counter = &dce_v8_0_vblank_get_counter,
.vblank_wait = &dce_v8_0_vblank_wait,
@@ -3587,8 +3500,6 @@ static const struct amdgpu_display_funcs dce_v8_0_display_funcs = {
.page_flip_get_scanoutpos = &dce_v8_0_crtc_get_scanoutpos,
.add_encoder = &dce_v8_0_encoder_add,
.add_connector = &amdgpu_connector_add,
- .stop_mc_access = &dce_v8_0_stop_mc_access,
- .resume_mc_access = &dce_v8_0_resume_mc_access,
};
static void dce_v8_0_set_display_funcs(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
index 90bb08309a53..b9ee9073cb0d 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
@@ -95,62 +95,6 @@ static u32 dce_virtual_hpd_get_gpio_reg(struct amdgpu_device *adev)
return 0;
}
-static void dce_virtual_stop_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- switch (adev->asic_type) {
-#ifdef CONFIG_DRM_AMDGPU_SI
- case CHIP_TAHITI:
- case CHIP_PITCAIRN:
- case CHIP_VERDE:
- case CHIP_OLAND:
- dce_v6_0_disable_dce(adev);
- break;
-#endif
-#ifdef CONFIG_DRM_AMDGPU_CIK
- case CHIP_BONAIRE:
- case CHIP_HAWAII:
- case CHIP_KAVERI:
- case CHIP_KABINI:
- case CHIP_MULLINS:
- dce_v8_0_disable_dce(adev);
- break;
-#endif
- case CHIP_FIJI:
- case CHIP_TONGA:
- dce_v10_0_disable_dce(adev);
- break;
- case CHIP_CARRIZO:
- case CHIP_STONEY:
- case CHIP_POLARIS10:
- case CHIP_POLARIS11:
- case CHIP_POLARIS12:
- dce_v11_0_disable_dce(adev);
- break;
- case CHIP_TOPAZ:
-#ifdef CONFIG_DRM_AMDGPU_SI
- case CHIP_HAINAN:
-#endif
- /* no DCE */
- return;
- default:
- DRM_ERROR("Virtual display unsupported ASIC type: 0x%X\n", adev->asic_type);
- }
-
- return;
-}
-static void dce_virtual_resume_mc_access(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
-{
- return;
-}
-
-static void dce_virtual_set_vga_render_state(struct amdgpu_device *adev,
- bool render)
-{
- return;
-}
-
/**
* dce_virtual_bandwidth_update - program display watermarks
*
@@ -168,16 +112,6 @@ static int dce_virtual_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
u16 *green, u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
- int i;
-
- /* userspace palettes are always correct as is */
- for (i = 0; i < size; i++) {
- amdgpu_crtc->lut_r[i] = red[i] >> 6;
- amdgpu_crtc->lut_g[i] = green[i] >> 6;
- amdgpu_crtc->lut_b[i] = blue[i] >> 6;
- }
-
return 0;
}
@@ -289,11 +223,6 @@ static int dce_virtual_crtc_set_base(struct drm_crtc *crtc, int x, int y,
return 0;
}
-static void dce_virtual_crtc_load_lut(struct drm_crtc *crtc)
-{
- return;
-}
-
static int dce_virtual_crtc_set_base_atomic(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
int x, int y, enum mode_set_atomic state)
@@ -309,14 +238,12 @@ static const struct drm_crtc_helper_funcs dce_virtual_crtc_helper_funcs = {
.mode_set_base_atomic = dce_virtual_crtc_set_base_atomic,
.prepare = dce_virtual_crtc_prepare,
.commit = dce_virtual_crtc_commit,
- .load_lut = dce_virtual_crtc_load_lut,
.disable = dce_virtual_crtc_disable,
};
static int dce_virtual_crtc_init(struct amdgpu_device *adev, int index)
{
struct amdgpu_crtc *amdgpu_crtc;
- int i;
amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
(AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
@@ -329,12 +256,6 @@ static int dce_virtual_crtc_init(struct amdgpu_device *adev, int index)
amdgpu_crtc->crtc_id = index;
adev->mode_info.crtcs[index] = amdgpu_crtc;
- for (i = 0; i < 256; i++) {
- amdgpu_crtc->lut_r[i] = i << 2;
- amdgpu_crtc->lut_g[i] = i << 2;
- amdgpu_crtc->lut_b[i] = i << 2;
- }
-
amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
amdgpu_crtc->encoder = NULL;
amdgpu_crtc->connector = NULL;
@@ -522,6 +443,47 @@ static int dce_virtual_sw_fini(void *handle)
static int dce_virtual_hw_init(void *handle)
{
+ struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+
+ switch (adev->asic_type) {
+#ifdef CONFIG_DRM_AMDGPU_SI
+ case CHIP_TAHITI:
+ case CHIP_PITCAIRN:
+ case CHIP_VERDE:
+ case CHIP_OLAND:
+ dce_v6_0_disable_dce(adev);
+ break;
+#endif
+#ifdef CONFIG_DRM_AMDGPU_CIK
+ case CHIP_BONAIRE:
+ case CHIP_HAWAII:
+ case CHIP_KAVERI:
+ case CHIP_KABINI:
+ case CHIP_MULLINS:
+ dce_v8_0_disable_dce(adev);
+ break;
+#endif
+ case CHIP_FIJI:
+ case CHIP_TONGA:
+ dce_v10_0_disable_dce(adev);
+ break;
+ case CHIP_CARRIZO:
+ case CHIP_STONEY:
+ case CHIP_POLARIS11:
+ case CHIP_POLARIS10:
+ dce_v11_0_disable_dce(adev);
+ break;
+ case CHIP_TOPAZ:
+#ifdef CONFIG_DRM_AMDGPU_SI
+ case CHIP_HAINAN:
+#endif
+ /* no DCE */
+ break;
+ case CHIP_VEGA10:
+ break;
+ default:
+ DRM_ERROR("Virtual display unsupported ASIC type: 0x%X\n", adev->asic_type);
+ }
return 0;
}
@@ -677,7 +639,6 @@ static int dce_virtual_connector_encoder_init(struct amdgpu_device *adev,
}
static const struct amdgpu_display_funcs dce_virtual_display_funcs = {
- .set_vga_render_state = &dce_virtual_set_vga_render_state,
.bandwidth_update = &dce_virtual_bandwidth_update,
.vblank_get_counter = &dce_virtual_vblank_get_counter,
.vblank_wait = &dce_virtual_vblank_wait,
@@ -690,8 +651,6 @@ static const struct amdgpu_display_funcs dce_virtual_display_funcs = {
.page_flip_get_scanoutpos = &dce_virtual_crtc_get_scanoutpos,
.add_encoder = NULL,
.add_connector = NULL,
- .stop_mc_access = &dce_virtual_stop_mc_access,
- .resume_mc_access = &dce_virtual_resume_mc_access,
};
static void dce_virtual_set_display_funcs(struct amdgpu_device *adev)
@@ -809,7 +768,7 @@ static const struct amdgpu_irq_src_funcs dce_virtual_crtc_irq_funcs = {
static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev)
{
- adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_LAST;
+ adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_VBLANK6 + 1;
adev->crtc_irq.funcs = &dce_virtual_crtc_irq_funcs;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
index 5173ca1fd159..d228f5a99044 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
@@ -1573,7 +1573,7 @@ static void gfx_v6_0_gpu_init(struct amdgpu_device *adev)
static void gfx_v6_0_scratch_init(struct amdgpu_device *adev)
{
- adev->gfx.scratch.num_reg = 7;
+ adev->gfx.scratch.num_reg = 8;
adev->gfx.scratch.reg_base = mmSCRATCH_REG0;
adev->gfx.scratch.free_mask = (1u << adev->gfx.scratch.num_reg) - 1;
}
@@ -2217,40 +2217,9 @@ static void gfx_v6_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
static void gfx_v6_0_rlc_fini(struct amdgpu_device *adev)
{
- int r;
-
- if (adev->gfx.rlc.save_restore_obj) {
- r = amdgpu_bo_reserve(adev->gfx.rlc.save_restore_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve RLC sr bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.rlc.save_restore_obj);
- amdgpu_bo_unreserve(adev->gfx.rlc.save_restore_obj);
-
- amdgpu_bo_unref(&adev->gfx.rlc.save_restore_obj);
- adev->gfx.rlc.save_restore_obj = NULL;
- }
-
- if (adev->gfx.rlc.clear_state_obj) {
- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve RLC c bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-
- amdgpu_bo_unref(&adev->gfx.rlc.clear_state_obj);
- adev->gfx.rlc.clear_state_obj = NULL;
- }
-
- if (adev->gfx.rlc.cp_table_obj) {
- r = amdgpu_bo_reserve(adev->gfx.rlc.cp_table_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve RLC cp table bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.rlc.cp_table_obj);
- amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj);
-
- amdgpu_bo_unref(&adev->gfx.rlc.cp_table_obj);
- adev->gfx.rlc.cp_table_obj = NULL;
- }
+ amdgpu_bo_free_kernel(&adev->gfx.rlc.save_restore_obj, NULL, NULL);
+ amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, NULL, NULL);
+ amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj, NULL, NULL);
}
static int gfx_v6_0_rlc_init(struct amdgpu_device *adev)
@@ -2273,43 +2242,23 @@ static int gfx_v6_0_rlc_init(struct amdgpu_device *adev)
if (src_ptr) {
/* save restore block */
- if (adev->gfx.rlc.save_restore_obj == NULL) {
- r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
- NULL, NULL,
- &adev->gfx.rlc.save_restore_obj);
-
- if (r) {
- dev_warn(adev->dev, "(%d) create RLC sr bo failed\n", r);
- return r;
- }
- }
-
- r = amdgpu_bo_reserve(adev->gfx.rlc.save_restore_obj, false);
- if (unlikely(r != 0)) {
- gfx_v6_0_rlc_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.rlc.save_restore_obj, AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.save_restore_gpu_addr);
+ r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.save_restore_obj,
+ &adev->gfx.rlc.save_restore_gpu_addr,
+ (void **)&adev->gfx.rlc.sr_ptr);
if (r) {
- amdgpu_bo_unreserve(adev->gfx.rlc.save_restore_obj);
- dev_warn(adev->dev, "(%d) pin RLC sr bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create RLC sr bo failed\n",
+ r);
gfx_v6_0_rlc_fini(adev);
return r;
}
- r = amdgpu_bo_kmap(adev->gfx.rlc.save_restore_obj, (void **)&adev->gfx.rlc.sr_ptr);
- if (r) {
- dev_warn(adev->dev, "(%d) map RLC sr bo failed\n", r);
- gfx_v6_0_rlc_fini(adev);
- return r;
- }
/* write the sr buffer */
dst_ptr = adev->gfx.rlc.sr_ptr;
for (i = 0; i < adev->gfx.rlc.reg_list_size; i++)
dst_ptr[i] = cpu_to_le32(src_ptr[i]);
+
amdgpu_bo_kunmap(adev->gfx.rlc.save_restore_obj);
amdgpu_bo_unreserve(adev->gfx.rlc.save_restore_obj);
}
@@ -2319,39 +2268,17 @@ static int gfx_v6_0_rlc_init(struct amdgpu_device *adev)
adev->gfx.rlc.clear_state_size = gfx_v6_0_get_csb_size(adev);
dws = adev->gfx.rlc.clear_state_size + (256 / 4);
- if (adev->gfx.rlc.clear_state_obj == NULL) {
- r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
- NULL, NULL,
- &adev->gfx.rlc.clear_state_obj);
-
- if (r) {
- dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r);
- gfx_v6_0_rlc_fini(adev);
- return r;
- }
- }
- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
- if (unlikely(r != 0)) {
- gfx_v6_0_rlc_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj, AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.clear_state_gpu_addr);
+ r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.clear_state_obj,
+ &adev->gfx.rlc.clear_state_gpu_addr,
+ (void **)&adev->gfx.rlc.cs_ptr);
if (r) {
- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
- dev_warn(adev->dev, "(%d) pin RLC c bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r);
gfx_v6_0_rlc_fini(adev);
return r;
}
- r = amdgpu_bo_kmap(adev->gfx.rlc.clear_state_obj, (void **)&adev->gfx.rlc.cs_ptr);
- if (r) {
- dev_warn(adev->dev, "(%d) map RLC c bo failed\n", r);
- gfx_v6_0_rlc_fini(adev);
- return r;
- }
/* set up the cs buffer */
dst_ptr = adev->gfx.rlc.cs_ptr;
reg_list_mc_addr = adev->gfx.rlc.clear_state_gpu_addr + 256;
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
index 37b45e4403d1..00868764a0dd 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
@@ -1823,7 +1823,7 @@ static void gfx_v7_0_setup_rb(struct amdgpu_device *adev)
}
/**
- * gmc_v7_0_init_compute_vmid - gart enable
+ * gfx_v7_0_init_compute_vmid - gart enable
*
* @adev: amdgpu_device pointer
*
@@ -1833,7 +1833,7 @@ static void gfx_v7_0_setup_rb(struct amdgpu_device *adev)
#define DEFAULT_SH_MEM_BASES (0x6000)
#define FIRST_COMPUTE_VMID (8)
#define LAST_COMPUTE_VMID (16)
-static void gmc_v7_0_init_compute_vmid(struct amdgpu_device *adev)
+static void gfx_v7_0_init_compute_vmid(struct amdgpu_device *adev)
{
int i;
uint32_t sh_mem_config;
@@ -1921,6 +1921,7 @@ static void gfx_v7_0_gpu_init(struct amdgpu_device *adev)
ELEMENT_SIZE, 1);
sh_static_mem_cfg = REG_SET_FIELD(sh_static_mem_cfg, SH_STATIC_MEM_CONFIG,
INDEX_STRIDE, 3);
+ WREG32(mmSH_STATIC_MEM_CONFIG, sh_static_mem_cfg);
mutex_lock(&adev->srbm_mutex);
for (i = 0; i < adev->vm_manager.id_mgr[0].num_ids; i++) {
@@ -1934,12 +1935,11 @@ static void gfx_v7_0_gpu_init(struct amdgpu_device *adev)
WREG32(mmSH_MEM_APE1_BASE, 1);
WREG32(mmSH_MEM_APE1_LIMIT, 0);
WREG32(mmSH_MEM_BASES, sh_mem_base);
- WREG32(mmSH_STATIC_MEM_CONFIG, sh_static_mem_cfg);
}
cik_srbm_select(adev, 0, 0, 0, 0);
mutex_unlock(&adev->srbm_mutex);
- gmc_v7_0_init_compute_vmid(adev);
+ gfx_v7_0_init_compute_vmid(adev);
WREG32(mmSX_DEBUG_1, 0x20);
@@ -2021,7 +2021,7 @@ static void gfx_v7_0_gpu_init(struct amdgpu_device *adev)
*/
static void gfx_v7_0_scratch_init(struct amdgpu_device *adev)
{
- adev->gfx.scratch.num_reg = 7;
+ adev->gfx.scratch.num_reg = 8;
adev->gfx.scratch.reg_base = mmSCRATCH_REG0;
adev->gfx.scratch.free_mask = (1u << adev->gfx.scratch.num_reg) - 1;
}
@@ -2774,39 +2774,18 @@ static int gfx_v7_0_cp_compute_load_microcode(struct amdgpu_device *adev)
*/
static void gfx_v7_0_cp_compute_fini(struct amdgpu_device *adev)
{
- int i, r;
+ int i;
for (i = 0; i < adev->gfx.num_compute_rings; i++) {
struct amdgpu_ring *ring = &adev->gfx.compute_ring[i];
- if (ring->mqd_obj) {
- r = amdgpu_bo_reserve(ring->mqd_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve MQD bo failed\n", r);
-
- amdgpu_bo_unpin(ring->mqd_obj);
- amdgpu_bo_unreserve(ring->mqd_obj);
-
- amdgpu_bo_unref(&ring->mqd_obj);
- ring->mqd_obj = NULL;
- }
+ amdgpu_bo_free_kernel(&ring->mqd_obj, NULL, NULL);
}
}
static void gfx_v7_0_mec_fini(struct amdgpu_device *adev)
{
- int r;
-
- if (adev->gfx.mec.hpd_eop_obj) {
- r = amdgpu_bo_reserve(adev->gfx.mec.hpd_eop_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve HPD EOP bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.mec.hpd_eop_obj);
- amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj);
-
- amdgpu_bo_unref(&adev->gfx.mec.hpd_eop_obj);
- adev->gfx.mec.hpd_eop_obj = NULL;
- }
+ amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
}
static int gfx_v7_0_mec_init(struct amdgpu_device *adev)
@@ -2823,33 +2802,14 @@ static int gfx_v7_0_mec_init(struct amdgpu_device *adev)
/* allocate space for ALL pipes (even the ones we don't own) */
mec_hpd_size = adev->gfx.mec.num_mec * adev->gfx.mec.num_pipe_per_mec
* GFX7_MEC_HPD_SIZE * 2;
- if (adev->gfx.mec.hpd_eop_obj == NULL) {
- r = amdgpu_bo_create(adev,
- mec_hpd_size,
- PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
- &adev->gfx.mec.hpd_eop_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
- return r;
- }
- }
- r = amdgpu_bo_reserve(adev->gfx.mec.hpd_eop_obj, false);
- if (unlikely(r != 0)) {
- gfx_v7_0_mec_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.mec.hpd_eop_obj, AMDGPU_GEM_DOMAIN_GTT,
- &adev->gfx.mec.hpd_eop_gpu_addr);
- if (r) {
- dev_warn(adev->dev, "(%d) pin HDP EOP bo failed\n", r);
- gfx_v7_0_mec_fini(adev);
- return r;
- }
- r = amdgpu_bo_kmap(adev->gfx.mec.hpd_eop_obj, (void **)&hpd);
+ r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_GTT,
+ &adev->gfx.mec.hpd_eop_obj,
+ &adev->gfx.mec.hpd_eop_gpu_addr,
+ (void **)&hpd);
if (r) {
- dev_warn(adev->dev, "(%d) map HDP EOP bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create, pin or map of HDP EOP bo failed\n", r);
gfx_v7_0_mec_fini(adev);
return r;
}
@@ -3108,32 +3068,12 @@ static int gfx_v7_0_compute_queue_init(struct amdgpu_device *adev, int ring_id)
struct cik_mqd *mqd;
struct amdgpu_ring *ring = &adev->gfx.compute_ring[ring_id];
- if (ring->mqd_obj == NULL) {
- r = amdgpu_bo_create(adev,
- sizeof(struct cik_mqd),
- PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
- &ring->mqd_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create MQD bo failed\n", r);
- return r;
- }
- }
-
- r = amdgpu_bo_reserve(ring->mqd_obj, false);
- if (unlikely(r != 0))
- goto out;
-
- r = amdgpu_bo_pin(ring->mqd_obj, AMDGPU_GEM_DOMAIN_GTT,
- &mqd_gpu_addr);
- if (r) {
- dev_warn(adev->dev, "(%d) pin MQD bo failed\n", r);
- goto out_unreserve;
- }
- r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&mqd);
+ r = amdgpu_bo_create_reserved(adev, sizeof(struct cik_mqd), PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_GTT, &ring->mqd_obj,
+ &mqd_gpu_addr, (void **)&mqd);
if (r) {
- dev_warn(adev->dev, "(%d) map MQD bo failed\n", r);
- goto out_unreserve;
+ dev_warn(adev->dev, "(%d) create MQD bo failed\n", r);
+ return r;
}
mutex_lock(&adev->srbm_mutex);
@@ -3147,9 +3087,7 @@ static int gfx_v7_0_compute_queue_init(struct amdgpu_device *adev, int ring_id)
mutex_unlock(&adev->srbm_mutex);
amdgpu_bo_kunmap(ring->mqd_obj);
-out_unreserve:
amdgpu_bo_unreserve(ring->mqd_obj);
-out:
return 0;
}
@@ -3361,43 +3299,9 @@ static void gfx_v7_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
*/
static void gfx_v7_0_rlc_fini(struct amdgpu_device *adev)
{
- int r;
-
- /* save restore block */
- if (adev->gfx.rlc.save_restore_obj) {
- r = amdgpu_bo_reserve(adev->gfx.rlc.save_restore_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve RLC sr bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.rlc.save_restore_obj);
- amdgpu_bo_unreserve(adev->gfx.rlc.save_restore_obj);
-
- amdgpu_bo_unref(&adev->gfx.rlc.save_restore_obj);
- adev->gfx.rlc.save_restore_obj = NULL;
- }
-
- /* clear state block */
- if (adev->gfx.rlc.clear_state_obj) {
- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve RLC c bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-
- amdgpu_bo_unref(&adev->gfx.rlc.clear_state_obj);
- adev->gfx.rlc.clear_state_obj = NULL;
- }
-
- /* clear state block */
- if (adev->gfx.rlc.cp_table_obj) {
- r = amdgpu_bo_reserve(adev->gfx.rlc.cp_table_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve RLC cp table bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.rlc.cp_table_obj);
- amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj);
-
- amdgpu_bo_unref(&adev->gfx.rlc.cp_table_obj);
- adev->gfx.rlc.cp_table_obj = NULL;
- }
+ amdgpu_bo_free_kernel(&adev->gfx.rlc.save_restore_obj, NULL, NULL);
+ amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, NULL, NULL);
+ amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj, NULL, NULL);
}
static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
@@ -3432,39 +3336,17 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
if (src_ptr) {
/* save restore block */
- if (adev->gfx.rlc.save_restore_obj == NULL) {
- r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL,
- &adev->gfx.rlc.save_restore_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create RLC sr bo failed\n", r);
- return r;
- }
- }
-
- r = amdgpu_bo_reserve(adev->gfx.rlc.save_restore_obj, false);
- if (unlikely(r != 0)) {
- gfx_v7_0_rlc_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.rlc.save_restore_obj, AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.save_restore_gpu_addr);
+ r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.save_restore_obj,
+ &adev->gfx.rlc.save_restore_gpu_addr,
+ (void **)&adev->gfx.rlc.sr_ptr);
if (r) {
- amdgpu_bo_unreserve(adev->gfx.rlc.save_restore_obj);
- dev_warn(adev->dev, "(%d) pin RLC sr bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create, pin or map of RLC sr bo failed\n", r);
gfx_v7_0_rlc_fini(adev);
return r;
}
- r = amdgpu_bo_kmap(adev->gfx.rlc.save_restore_obj, (void **)&adev->gfx.rlc.sr_ptr);
- if (r) {
- dev_warn(adev->dev, "(%d) map RLC sr bo failed\n", r);
- gfx_v7_0_rlc_fini(adev);
- return r;
- }
/* write the sr buffer */
dst_ptr = adev->gfx.rlc.sr_ptr;
for (i = 0; i < adev->gfx.rlc.reg_list_size; i++)
@@ -3477,39 +3359,17 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
/* clear state block */
adev->gfx.rlc.clear_state_size = dws = gfx_v7_0_get_csb_size(adev);
- if (adev->gfx.rlc.clear_state_obj == NULL) {
- r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL,
- &adev->gfx.rlc.clear_state_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r);
- gfx_v7_0_rlc_fini(adev);
- return r;
- }
- }
- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
- if (unlikely(r != 0)) {
- gfx_v7_0_rlc_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj, AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.clear_state_gpu_addr);
+ r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.clear_state_obj,
+ &adev->gfx.rlc.clear_state_gpu_addr,
+ (void **)&adev->gfx.rlc.cs_ptr);
if (r) {
- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
- dev_warn(adev->dev, "(%d) pin RLC c bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r);
gfx_v7_0_rlc_fini(adev);
return r;
}
- r = amdgpu_bo_kmap(adev->gfx.rlc.clear_state_obj, (void **)&adev->gfx.rlc.cs_ptr);
- if (r) {
- dev_warn(adev->dev, "(%d) map RLC c bo failed\n", r);
- gfx_v7_0_rlc_fini(adev);
- return r;
- }
/* set up the cs buffer */
dst_ptr = adev->gfx.rlc.cs_ptr;
gfx_v7_0_get_csb_buffer(adev, dst_ptr);
@@ -3518,37 +3378,14 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev)
}
if (adev->gfx.rlc.cp_table_size) {
- if (adev->gfx.rlc.cp_table_obj == NULL) {
- r = amdgpu_bo_create(adev, adev->gfx.rlc.cp_table_size, PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL,
- &adev->gfx.rlc.cp_table_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create RLC cp table bo failed\n", r);
- gfx_v7_0_rlc_fini(adev);
- return r;
- }
- }
- r = amdgpu_bo_reserve(adev->gfx.rlc.cp_table_obj, false);
- if (unlikely(r != 0)) {
- dev_warn(adev->dev, "(%d) reserve RLC cp table bo failed\n", r);
- gfx_v7_0_rlc_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.rlc.cp_table_obj, AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.cp_table_gpu_addr);
- if (r) {
- amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj);
- dev_warn(adev->dev, "(%d) pin RLC cp_table bo failed\n", r);
- gfx_v7_0_rlc_fini(adev);
- return r;
- }
- r = amdgpu_bo_kmap(adev->gfx.rlc.cp_table_obj, (void **)&adev->gfx.rlc.cp_table_ptr);
+ r = amdgpu_bo_create_reserved(adev, adev->gfx.rlc.cp_table_size,
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.cp_table_obj,
+ &adev->gfx.rlc.cp_table_gpu_addr,
+ (void **)&adev->gfx.rlc.cp_table_ptr);
if (r) {
- dev_warn(adev->dev, "(%d) map RLC cp table bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create RLC cp table bo failed\n", r);
gfx_v7_0_rlc_fini(adev);
return r;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
index aa5a50f5eac8..832e592fcd07 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
@@ -193,8 +193,8 @@ static const u32 tonga_golden_common_all[] =
mmGB_ADDR_CONFIG, 0xffffffff, 0x22011003,
mmSPI_RESOURCE_RESERVE_CU_0, 0xffffffff, 0x00000800,
mmSPI_RESOURCE_RESERVE_CU_1, 0xffffffff, 0x00000800,
- mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00007FBF,
- mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00007FAF
+ mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00FF7FBF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00FF7FAF
};
static const u32 tonga_mgcg_cgcg_init[] =
@@ -303,8 +303,8 @@ static const u32 polaris11_golden_common_all[] =
mmGB_ADDR_CONFIG, 0xffffffff, 0x22011002,
mmSPI_RESOURCE_RESERVE_CU_0, 0xffffffff, 0x00000800,
mmSPI_RESOURCE_RESERVE_CU_1, 0xffffffff, 0x00000800,
- mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00007FBF,
- mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00007FAF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00FF7FBF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00FF7FAF,
};
static const u32 golden_settings_polaris10_a11[] =
@@ -336,8 +336,8 @@ static const u32 polaris10_golden_common_all[] =
mmGB_ADDR_CONFIG, 0xffffffff, 0x22011003,
mmSPI_RESOURCE_RESERVE_CU_0, 0xffffffff, 0x00000800,
mmSPI_RESOURCE_RESERVE_CU_1, 0xffffffff, 0x00000800,
- mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00007FBF,
- mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00007FAF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00FF7FBF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00FF7FAF,
};
static const u32 fiji_golden_common_all[] =
@@ -348,8 +348,8 @@ static const u32 fiji_golden_common_all[] =
mmGB_ADDR_CONFIG, 0xffffffff, 0x22011003,
mmSPI_RESOURCE_RESERVE_CU_0, 0xffffffff, 0x00000800,
mmSPI_RESOURCE_RESERVE_CU_1, 0xffffffff, 0x00000800,
- mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00007FBF,
- mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00007FAF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00FF7FBF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00FF7FAF,
mmGRBM_GFX_INDEX, 0xffffffff, 0xe0000000,
mmSPI_CONFIG_CNTL_1, 0x0000000f, 0x00000009,
};
@@ -436,8 +436,8 @@ static const u32 iceland_golden_common_all[] =
mmGB_ADDR_CONFIG, 0xffffffff, 0x22010001,
mmSPI_RESOURCE_RESERVE_CU_0, 0xffffffff, 0x00000800,
mmSPI_RESOURCE_RESERVE_CU_1, 0xffffffff, 0x00000800,
- mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00007FBF,
- mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00007FAF
+ mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00FF7FBF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00FF7FAF
};
static const u32 iceland_mgcg_cgcg_init[] =
@@ -532,8 +532,8 @@ static const u32 cz_golden_common_all[] =
mmGB_ADDR_CONFIG, 0xffffffff, 0x22010001,
mmSPI_RESOURCE_RESERVE_CU_0, 0xffffffff, 0x00000800,
mmSPI_RESOURCE_RESERVE_CU_1, 0xffffffff, 0x00000800,
- mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00007FBF,
- mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00007FAF
+ mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00FF7FBF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00FF7FAF
};
static const u32 cz_mgcg_cgcg_init[] =
@@ -637,8 +637,8 @@ static const u32 stoney_golden_common_all[] =
mmGB_ADDR_CONFIG, 0xffffffff, 0x12010001,
mmSPI_RESOURCE_RESERVE_CU_0, 0xffffffff, 0x00000800,
mmSPI_RESOURCE_RESERVE_CU_1, 0xffffffff, 0x00000800,
- mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00007FBF,
- mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00007FAF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_0, 0xffffffff, 0x00FF7FBF,
+ mmSPI_RESOURCE_RESERVE_EN_CU_1, 0xffffffff, 0x00FF7FAF,
};
static const u32 stoney_mgcg_cgcg_init[] =
@@ -750,7 +750,7 @@ static void gfx_v8_0_init_golden_registers(struct amdgpu_device *adev)
static void gfx_v8_0_scratch_init(struct amdgpu_device *adev)
{
- adev->gfx.scratch.num_reg = 7;
+ adev->gfx.scratch.num_reg = 8;
adev->gfx.scratch.reg_base = mmSCRATCH_REG0;
adev->gfx.scratch.free_mask = (1u << adev->gfx.scratch.num_reg) - 1;
}
@@ -1238,29 +1238,8 @@ static void cz_init_cp_jump_table(struct amdgpu_device *adev)
static void gfx_v8_0_rlc_fini(struct amdgpu_device *adev)
{
- int r;
-
- /* clear state block */
- if (adev->gfx.rlc.clear_state_obj) {
- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve RLC cbs bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
- amdgpu_bo_unref(&adev->gfx.rlc.clear_state_obj);
- adev->gfx.rlc.clear_state_obj = NULL;
- }
-
- /* jump table block */
- if (adev->gfx.rlc.cp_table_obj) {
- r = amdgpu_bo_reserve(adev->gfx.rlc.cp_table_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve RLC cp table bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.rlc.cp_table_obj);
- amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj);
- amdgpu_bo_unref(&adev->gfx.rlc.cp_table_obj);
- adev->gfx.rlc.cp_table_obj = NULL;
- }
+ amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, NULL, NULL);
+ amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj, NULL, NULL);
}
static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
@@ -1278,39 +1257,17 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
/* clear state block */
adev->gfx.rlc.clear_state_size = dws = gfx_v8_0_get_csb_size(adev);
- if (adev->gfx.rlc.clear_state_obj == NULL) {
- r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL,
- &adev->gfx.rlc.clear_state_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r);
- gfx_v8_0_rlc_fini(adev);
- return r;
- }
- }
- r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
- if (unlikely(r != 0)) {
- gfx_v8_0_rlc_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj, AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.clear_state_gpu_addr);
+ r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.clear_state_obj,
+ &adev->gfx.rlc.clear_state_gpu_addr,
+ (void **)&adev->gfx.rlc.cs_ptr);
if (r) {
- amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
- dev_warn(adev->dev, "(%d) pin RLC cbs bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r);
gfx_v8_0_rlc_fini(adev);
return r;
}
- r = amdgpu_bo_kmap(adev->gfx.rlc.clear_state_obj, (void **)&adev->gfx.rlc.cs_ptr);
- if (r) {
- dev_warn(adev->dev, "(%d) map RLC cbs bo failed\n", r);
- gfx_v8_0_rlc_fini(adev);
- return r;
- }
/* set up the cs buffer */
dst_ptr = adev->gfx.rlc.cs_ptr;
gfx_v8_0_get_csb_buffer(adev, dst_ptr);
@@ -1321,34 +1278,13 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
if ((adev->asic_type == CHIP_CARRIZO) ||
(adev->asic_type == CHIP_STONEY)) {
adev->gfx.rlc.cp_table_size = ALIGN(96 * 5 * 4, 2048) + (64 * 1024); /* JT + GDS */
- if (adev->gfx.rlc.cp_table_obj == NULL) {
- r = amdgpu_bo_create(adev, adev->gfx.rlc.cp_table_size, PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_VRAM,
- AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
- AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
- NULL, NULL,
- &adev->gfx.rlc.cp_table_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create RLC cp table bo failed\n", r);
- return r;
- }
- }
-
- r = amdgpu_bo_reserve(adev->gfx.rlc.cp_table_obj, false);
- if (unlikely(r != 0)) {
- dev_warn(adev->dev, "(%d) reserve RLC cp table bo failed\n", r);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.rlc.cp_table_obj, AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.cp_table_gpu_addr);
- if (r) {
- amdgpu_bo_unreserve(adev->gfx.rlc.cp_table_obj);
- dev_warn(adev->dev, "(%d) pin RLC cp table bo failed\n", r);
- return r;
- }
- r = amdgpu_bo_kmap(adev->gfx.rlc.cp_table_obj, (void **)&adev->gfx.rlc.cp_table_ptr);
+ r = amdgpu_bo_create_reserved(adev, adev->gfx.rlc.cp_table_size,
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.cp_table_obj,
+ &adev->gfx.rlc.cp_table_gpu_addr,
+ (void **)&adev->gfx.rlc.cp_table_ptr);
if (r) {
- dev_warn(adev->dev, "(%d) map RLC cp table bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create RLC cp table bo failed\n", r);
return r;
}
@@ -1363,17 +1299,7 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
static void gfx_v8_0_mec_fini(struct amdgpu_device *adev)
{
- int r;
-
- if (adev->gfx.mec.hpd_eop_obj) {
- r = amdgpu_bo_reserve(adev->gfx.mec.hpd_eop_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve HPD EOP bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.mec.hpd_eop_obj);
- amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj);
- amdgpu_bo_unref(&adev->gfx.mec.hpd_eop_obj);
- adev->gfx.mec.hpd_eop_obj = NULL;
- }
+ amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
}
static int gfx_v8_0_mec_init(struct amdgpu_device *adev)
@@ -1389,34 +1315,13 @@ static int gfx_v8_0_mec_init(struct amdgpu_device *adev)
mec_hpd_size = adev->gfx.num_compute_rings * GFX8_MEC_HPD_SIZE;
- if (adev->gfx.mec.hpd_eop_obj == NULL) {
- r = amdgpu_bo_create(adev,
- mec_hpd_size,
- PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
- &adev->gfx.mec.hpd_eop_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
- return r;
- }
- }
-
- r = amdgpu_bo_reserve(adev->gfx.mec.hpd_eop_obj, false);
- if (unlikely(r != 0)) {
- gfx_v8_0_mec_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.mec.hpd_eop_obj, AMDGPU_GEM_DOMAIN_GTT,
- &adev->gfx.mec.hpd_eop_gpu_addr);
+ r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_GTT,
+ &adev->gfx.mec.hpd_eop_obj,
+ &adev->gfx.mec.hpd_eop_gpu_addr,
+ (void **)&hpd);
if (r) {
- dev_warn(adev->dev, "(%d) pin HDP EOP bo failed\n", r);
- gfx_v8_0_mec_fini(adev);
- return r;
- }
- r = amdgpu_bo_kmap(adev->gfx.mec.hpd_eop_obj, (void **)&hpd);
- if (r) {
- dev_warn(adev->dev, "(%d) map HDP EOP bo failed\n", r);
- gfx_v8_0_mec_fini(adev);
+ dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
return r;
}
@@ -3802,6 +3707,8 @@ static void gfx_v8_0_gpu_init(struct amdgpu_device *adev)
ELEMENT_SIZE, 1);
sh_static_mem_cfg = REG_SET_FIELD(sh_static_mem_cfg, SH_STATIC_MEM_CONFIG,
INDEX_STRIDE, 3);
+ WREG32(mmSH_STATIC_MEM_CONFIG, sh_static_mem_cfg);
+
mutex_lock(&adev->srbm_mutex);
for (i = 0; i < adev->vm_manager.id_mgr[0].num_ids; i++) {
vi_srbm_select(adev, 0, 0, 0, i);
@@ -3825,7 +3732,6 @@ static void gfx_v8_0_gpu_init(struct amdgpu_device *adev)
WREG32(mmSH_MEM_APE1_BASE, 1);
WREG32(mmSH_MEM_APE1_LIMIT, 0);
- WREG32(mmSH_STATIC_MEM_CONFIG, sh_static_mem_cfg);
}
vi_srbm_select(adev, 0, 0, 0, 0);
mutex_unlock(&adev->srbm_mutex);
@@ -4564,7 +4470,7 @@ static int gfx_v8_0_kiq_kcq_enable(struct amdgpu_device *adev)
/* This situation may be hit in the future if a new HW
* generation exposes more than 64 queues. If so, the
* definition of queue_mask needs updating */
- if (WARN_ON(i > (sizeof(queue_mask)*8))) {
+ if (WARN_ON(i >= (sizeof(queue_mask)*8))) {
DRM_ERROR("Invalid KCQ enabled: %d\n", i);
break;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
index 3a0b69b09ed6..69182eeca264 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -116,7 +116,9 @@ static const u32 golden_settings_gc_9_0[] =
SOC15_REG_OFFSET(GC, 0, mmRLC_GPM_UTCL1_CNTL_2), 0x08000000, 0x08000080,
SOC15_REG_OFFSET(GC, 0, mmRLC_PREWALKER_UTCL1_CNTL), 0x08000000, 0x08000080,
SOC15_REG_OFFSET(GC, 0, mmRLC_SPM_UTCL1_CNTL), 0x08000000, 0x08000080,
+ SOC15_REG_OFFSET(GC, 0, mmSH_MEM_CONFIG), 0x00001000, 0x00001000,
SOC15_REG_OFFSET(GC, 0, mmSPI_CONFIG_CNTL_1), 0x0000000f, 0x01000107,
+ SOC15_REG_OFFSET(GC, 0, mmSQC_CONFIG), 0x03000000, 0x020a2000,
SOC15_REG_OFFSET(GC, 0, mmTA_CNTL_AUX), 0xfffffeef, 0x010b0000,
SOC15_REG_OFFSET(GC, 0, mmTCP_CHAN_STEER_HI), 0xffffffff, 0x4a2c0e68,
SOC15_REG_OFFSET(GC, 0, mmTCP_CHAN_STEER_LO), 0xffffffff, 0xb5d3f197,
@@ -211,7 +213,7 @@ static void gfx_v9_0_init_golden_registers(struct amdgpu_device *adev)
static void gfx_v9_0_scratch_init(struct amdgpu_device *adev)
{
- adev->gfx.scratch.num_reg = 7;
+ adev->gfx.scratch.num_reg = 8;
adev->gfx.scratch.reg_base = SOC15_REG_OFFSET(GC, 0, mmSCRATCH_REG0);
adev->gfx.scratch.free_mask = (1u << adev->gfx.scratch.num_reg) - 1;
}
@@ -772,18 +774,16 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev)
if (cs_data) {
/* clear state block */
adev->gfx.rlc.clear_state_size = dws = gfx_v9_0_get_csb_size(adev);
- if (adev->gfx.rlc.clear_state_obj == NULL) {
- r = amdgpu_bo_create_kernel(adev, dws * 4, PAGE_SIZE,
- AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.clear_state_obj,
- &adev->gfx.rlc.clear_state_gpu_addr,
- (void **)&adev->gfx.rlc.cs_ptr);
- if (r) {
- dev_err(adev->dev,
- "(%d) failed to create rlc csb bo\n", r);
- gfx_v9_0_rlc_fini(adev);
- return r;
- }
+ r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.clear_state_obj,
+ &adev->gfx.rlc.clear_state_gpu_addr,
+ (void **)&adev->gfx.rlc.cs_ptr);
+ if (r) {
+ dev_err(adev->dev, "(%d) failed to create rlc csb bo\n",
+ r);
+ gfx_v9_0_rlc_fini(adev);
+ return r;
}
/* set up the cs buffer */
dst_ptr = adev->gfx.rlc.cs_ptr;
@@ -795,18 +795,16 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev)
if (adev->asic_type == CHIP_RAVEN) {
/* TODO: double check the cp_table_size for RV */
adev->gfx.rlc.cp_table_size = ALIGN(96 * 5 * 4, 2048) + (64 * 1024); /* JT + GDS */
- if (adev->gfx.rlc.cp_table_obj == NULL) {
- r = amdgpu_bo_create_kernel(adev, adev->gfx.rlc.cp_table_size,
- PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
- &adev->gfx.rlc.cp_table_obj,
- &adev->gfx.rlc.cp_table_gpu_addr,
- (void **)&adev->gfx.rlc.cp_table_ptr);
- if (r) {
- dev_err(adev->dev,
- "(%d) failed to create cp table bo\n", r);
- gfx_v9_0_rlc_fini(adev);
- return r;
- }
+ r = amdgpu_bo_create_reserved(adev, adev->gfx.rlc.cp_table_size,
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
+ &adev->gfx.rlc.cp_table_obj,
+ &adev->gfx.rlc.cp_table_gpu_addr,
+ (void **)&adev->gfx.rlc.cp_table_ptr);
+ if (r) {
+ dev_err(adev->dev,
+ "(%d) failed to create cp table bo\n", r);
+ gfx_v9_0_rlc_fini(adev);
+ return r;
}
rv_init_cp_jump_table(adev);
@@ -821,28 +819,8 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev)
static void gfx_v9_0_mec_fini(struct amdgpu_device *adev)
{
- int r;
-
- if (adev->gfx.mec.hpd_eop_obj) {
- r = amdgpu_bo_reserve(adev->gfx.mec.hpd_eop_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve HPD EOP bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.mec.hpd_eop_obj);
- amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj);
-
- amdgpu_bo_unref(&adev->gfx.mec.hpd_eop_obj);
- adev->gfx.mec.hpd_eop_obj = NULL;
- }
- if (adev->gfx.mec.mec_fw_obj) {
- r = amdgpu_bo_reserve(adev->gfx.mec.mec_fw_obj, true);
- if (unlikely(r != 0))
- dev_warn(adev->dev, "(%d) reserve mec firmware bo failed\n", r);
- amdgpu_bo_unpin(adev->gfx.mec.mec_fw_obj);
- amdgpu_bo_unreserve(adev->gfx.mec.mec_fw_obj);
-
- amdgpu_bo_unref(&adev->gfx.mec.mec_fw_obj);
- adev->gfx.mec.mec_fw_obj = NULL;
- }
+ amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
+ amdgpu_bo_free_kernel(&adev->gfx.mec.mec_fw_obj, NULL, NULL);
}
static int gfx_v9_0_mec_init(struct amdgpu_device *adev)
@@ -862,33 +840,13 @@ static int gfx_v9_0_mec_init(struct amdgpu_device *adev)
amdgpu_gfx_compute_queue_acquire(adev);
mec_hpd_size = adev->gfx.num_compute_rings * GFX9_MEC_HPD_SIZE;
- if (adev->gfx.mec.hpd_eop_obj == NULL) {
- r = amdgpu_bo_create(adev,
- mec_hpd_size,
- PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
- &adev->gfx.mec.hpd_eop_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
- return r;
- }
- }
-
- r = amdgpu_bo_reserve(adev->gfx.mec.hpd_eop_obj, false);
- if (unlikely(r != 0)) {
- gfx_v9_0_mec_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.mec.hpd_eop_obj, AMDGPU_GEM_DOMAIN_GTT,
- &adev->gfx.mec.hpd_eop_gpu_addr);
+ r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE,
+ AMDGPU_GEM_DOMAIN_GTT,
+ &adev->gfx.mec.hpd_eop_obj,
+ &adev->gfx.mec.hpd_eop_gpu_addr,
+ (void **)&hpd);
if (r) {
- dev_warn(adev->dev, "(%d) pin HDP EOP bo failed\n", r);
- gfx_v9_0_mec_fini(adev);
- return r;
- }
- r = amdgpu_bo_kmap(adev->gfx.mec.hpd_eop_obj, (void **)&hpd);
- if (r) {
- dev_warn(adev->dev, "(%d) map HDP EOP bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
gfx_v9_0_mec_fini(adev);
return r;
}
@@ -905,42 +863,22 @@ static int gfx_v9_0_mec_init(struct amdgpu_device *adev)
le32_to_cpu(mec_hdr->header.ucode_array_offset_bytes));
fw_size = le32_to_cpu(mec_hdr->header.ucode_size_bytes) / 4;
- if (adev->gfx.mec.mec_fw_obj == NULL) {
- r = amdgpu_bo_create(adev,
- mec_hdr->header.ucode_size_bytes,
- PAGE_SIZE, true,
- AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
- &adev->gfx.mec.mec_fw_obj);
- if (r) {
- dev_warn(adev->dev, "(%d) create mec firmware bo failed\n", r);
- return r;
- }
- }
-
- r = amdgpu_bo_reserve(adev->gfx.mec.mec_fw_obj, false);
- if (unlikely(r != 0)) {
- gfx_v9_0_mec_fini(adev);
- return r;
- }
- r = amdgpu_bo_pin(adev->gfx.mec.mec_fw_obj, AMDGPU_GEM_DOMAIN_GTT,
- &adev->gfx.mec.mec_fw_gpu_addr);
+ r = amdgpu_bo_create_reserved(adev, mec_hdr->header.ucode_size_bytes,
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
+ &adev->gfx.mec.mec_fw_obj,
+ &adev->gfx.mec.mec_fw_gpu_addr,
+ (void **)&fw);
if (r) {
- dev_warn(adev->dev, "(%d) pin mec firmware bo failed\n", r);
- gfx_v9_0_mec_fini(adev);
- return r;
- }
- r = amdgpu_bo_kmap(adev->gfx.mec.mec_fw_obj, (void **)&fw);
- if (r) {
- dev_warn(adev->dev, "(%d) map firmware bo failed\n", r);
+ dev_warn(adev->dev, "(%d) create mec firmware bo failed\n", r);
gfx_v9_0_mec_fini(adev);
return r;
}
+
memcpy(fw, fw_data, fw_size);
amdgpu_bo_kunmap(adev->gfx.mec.mec_fw_obj);
amdgpu_bo_unreserve(adev->gfx.mec.mec_fw_obj);
-
return 0;
}
@@ -1475,21 +1413,23 @@ static void gfx_v9_0_tiling_mode_table_init(struct amdgpu_device *adev)
static void gfx_v9_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, u32 sh_num, u32 instance)
{
- u32 data = REG_SET_FIELD(0, GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES, 1);
+ u32 data;
- if ((se_num == 0xffffffff) && (sh_num == 0xffffffff)) {
- data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_BROADCAST_WRITES, 1);
- data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SE_BROADCAST_WRITES, 1);
- } else if (se_num == 0xffffffff) {
- data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_INDEX, sh_num);
+ if (instance == 0xffffffff)
+ data = REG_SET_FIELD(0, GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES, 1);
+ else
+ data = REG_SET_FIELD(0, GRBM_GFX_INDEX, INSTANCE_INDEX, instance);
+
+ if (se_num == 0xffffffff)
data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SE_BROADCAST_WRITES, 1);
- } else if (sh_num == 0xffffffff) {
- data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_BROADCAST_WRITES, 1);
+ else
data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SE_INDEX, se_num);
- } else {
+
+ if (sh_num == 0xffffffff)
+ data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_BROADCAST_WRITES, 1);
+ else
data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_INDEX, sh_num);
- data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SE_INDEX, se_num);
- }
+
WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, data);
}
@@ -2217,7 +2157,7 @@ static int gfx_v9_0_cp_gfx_start(struct amdgpu_device *adev)
struct amdgpu_ring *ring = &adev->gfx.gfx_ring[0];
const struct cs_section_def *sect = NULL;
const struct cs_extent_def *ext = NULL;
- int r, i;
+ int r, i, tmp;
/* init the CP */
WREG32_SOC15(GC, 0, mmCP_MAX_CONTEXT, adev->gfx.config.max_hw_contexts - 1);
@@ -2225,7 +2165,7 @@ static int gfx_v9_0_cp_gfx_start(struct amdgpu_device *adev)
gfx_v9_0_cp_gfx_enable(adev, true);
- r = amdgpu_ring_alloc(ring, gfx_v9_0_get_csb_size(adev) + 4);
+ r = amdgpu_ring_alloc(ring, gfx_v9_0_get_csb_size(adev) + 4 + 3);
if (r) {
DRM_ERROR("amdgpu: cp failed to lock ring (%d).\n", r);
return r;
@@ -2263,6 +2203,12 @@ static int gfx_v9_0_cp_gfx_start(struct amdgpu_device *adev)
amdgpu_ring_write(ring, 0x8000);
amdgpu_ring_write(ring, 0x8000);
+ amdgpu_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG,1));
+ tmp = (PACKET3_SET_UCONFIG_REG_INDEX_TYPE |
+ (SOC15_REG_OFFSET(GC, 0, mmVGT_INDEX_TYPE) - PACKET3_SET_UCONFIG_REG_START));
+ amdgpu_ring_write(ring, tmp);
+ amdgpu_ring_write(ring, 0);
+
amdgpu_ring_commit(ring);
return 0;
@@ -2425,7 +2371,7 @@ static int gfx_v9_0_kiq_kcq_enable(struct amdgpu_device *adev)
/* This situation may be hit in the future if a new HW
* generation exposes more than 64 queues. If so, the
* definition of queue_mask needs updating */
- if (WARN_ON(i > (sizeof(queue_mask)*8))) {
+ if (WARN_ON(i >= (sizeof(queue_mask)*8))) {
DRM_ERROR("Invalid KCQ enabled: %d\n", i);
break;
}
@@ -4156,7 +4102,7 @@ static int gfx_v9_0_kiq_irq(struct amdgpu_device *adev,
return 0;
}
-const struct amd_ip_funcs gfx_v9_0_ip_funcs = {
+static const struct amd_ip_funcs gfx_v9_0_ip_funcs = {
.name = "gfx_v9_0",
.early_init = gfx_v9_0_early_init,
.late_init = gfx_v9_0_late_init,
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.h b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.h
index 56ef652a575d..fa5a3fbaf6ab 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.h
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.h
@@ -24,7 +24,6 @@
#ifndef __GFX_V9_0_H__
#define __GFX_V9_0_H__
-extern const struct amd_ip_funcs gfx_v9_0_ip_funcs;
extern const struct amdgpu_ip_block_version gfx_v9_0_ip_block;
void gfx_v9_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, u32 sh_num);
diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c
index a42f483767e7..4f2788b61a08 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c
@@ -58,14 +58,14 @@ static void gfxhub_v1_0_init_gart_aperture_regs(struct amdgpu_device *adev)
gfxhub_v1_0_init_gart_pt_regs(adev);
WREG32_SOC15(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32,
- (u32)(adev->mc.gtt_start >> 12));
+ (u32)(adev->mc.gart_start >> 12));
WREG32_SOC15(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32,
- (u32)(adev->mc.gtt_start >> 44));
+ (u32)(adev->mc.gart_start >> 44));
WREG32_SOC15(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32,
- (u32)(adev->mc.gtt_end >> 12));
+ (u32)(adev->mc.gart_end >> 12));
WREG32_SOC15(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32,
- (u32)(adev->mc.gtt_end >> 44));
+ (u32)(adev->mc.gart_end >> 44));
}
static void gfxhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)
@@ -124,12 +124,12 @@ static void gfxhub_v1_0_init_tlb_regs(struct amdgpu_device *adev)
static void gfxhub_v1_0_init_cache_regs(struct amdgpu_device *adev)
{
- uint32_t tmp;
+ uint32_t tmp, field;
/* Setup L2 cache */
tmp = RREG32_SOC15(GC, 0, mmVM_L2_CNTL);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 1);
- tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING, 0);
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING, 1);
/* XXX for emulation, Refer to closed source code.*/
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, L2_PDE0_CACHE_TAG_GENERATION_MODE,
0);
@@ -143,7 +143,10 @@ static void gfxhub_v1_0_init_cache_regs(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
WREG32_SOC15(GC, 0, mmVM_L2_CNTL2, tmp);
+ field = adev->vm_manager.fragment_size;
tmp = mmVM_L2_CNTL3_DEFAULT;
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, field);
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
WREG32_SOC15(GC, 0, mmVM_L2_CNTL3, tmp);
tmp = mmVM_L2_CNTL4_DEFAULT;
@@ -206,6 +209,9 @@ static void gfxhub_v1_0_setup_vmid_config(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
PAGE_TABLE_BLOCK_SIZE,
adev->vm_manager.block_size - 9);
+ /* Send no-retry XNACK on fault to suppress VM fault storm. */
+ tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
+ RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
WREG32_SOC15_OFFSET(GC, 0, mmVM_CONTEXT1_CNTL, i, tmp);
WREG32_SOC15_OFFSET(GC, 0, mmVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32, i*2, 0);
WREG32_SOC15_OFFSET(GC, 0, mmVM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32, i*2, 0);
diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.h b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.h
index d2dbb085f480..206e29cad753 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.h
+++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.h
@@ -30,7 +30,5 @@ void gfxhub_v1_0_set_fault_enable_default(struct amdgpu_device *adev,
bool value);
void gfxhub_v1_0_init(struct amdgpu_device *adev);
u64 gfxhub_v1_0_get_mc_fb_offset(struct amdgpu_device *adev);
-extern const struct amd_ip_funcs gfxhub_v1_0_ip_funcs;
-extern const struct amdgpu_ip_block_version gfxhub_v1_0_ip_block;
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
index d0214d942bfc..12b0c4cd7a5a 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
@@ -66,14 +66,10 @@ static const u32 crtc_offsets[6] =
SI_CRTC5_REGISTER_OFFSET
};
-static void gmc_v6_0_mc_stop(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
+static void gmc_v6_0_mc_stop(struct amdgpu_device *adev)
{
u32 blackout;
- if (adev->mode_info.num_crtc)
- amdgpu_display_stop_mc_access(adev, save);
-
gmc_v6_0_wait_for_idle((void *)adev);
blackout = RREG32(mmMC_SHARED_BLACKOUT_CNTL);
@@ -90,8 +86,7 @@ static void gmc_v6_0_mc_stop(struct amdgpu_device *adev,
}
-static void gmc_v6_0_mc_resume(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
+static void gmc_v6_0_mc_resume(struct amdgpu_device *adev)
{
u32 tmp;
@@ -103,10 +98,6 @@ static void gmc_v6_0_mc_resume(struct amdgpu_device *adev,
tmp = REG_SET_FIELD(0, BIF_FB_EN, FB_READ_EN, 1);
tmp = REG_SET_FIELD(tmp, BIF_FB_EN, FB_WRITE_EN, 1);
WREG32(mmBIF_FB_EN, tmp);
-
- if (adev->mode_info.num_crtc)
- amdgpu_display_resume_mc_access(adev, save);
-
}
static int gmc_v6_0_init_microcode(struct amdgpu_device *adev)
@@ -228,20 +219,20 @@ static int gmc_v6_0_mc_load_microcode(struct amdgpu_device *adev)
static void gmc_v6_0_vram_gtt_location(struct amdgpu_device *adev,
struct amdgpu_mc *mc)
{
+ u64 base = RREG32(mmMC_VM_FB_LOCATION) & 0xFFFF;
+ base <<= 24;
+
if (mc->mc_vram_size > 0xFFC0000000ULL) {
dev_warn(adev->dev, "limiting VRAM\n");
mc->real_vram_size = 0xFFC0000000ULL;
mc->mc_vram_size = 0xFFC0000000ULL;
}
- amdgpu_vram_location(adev, &adev->mc, 0);
- adev->mc.gtt_base_align = 0;
- amdgpu_gtt_location(adev, mc);
+ amdgpu_vram_location(adev, &adev->mc, base);
+ amdgpu_gart_location(adev, mc);
}
static void gmc_v6_0_mc_program(struct amdgpu_device *adev)
{
- struct amdgpu_mode_mc_save save;
- u32 tmp;
int i, j;
/* Initialize HDP */
@@ -254,16 +245,23 @@ static void gmc_v6_0_mc_program(struct amdgpu_device *adev)
}
WREG32(mmHDP_REG_COHERENCY_FLUSH_CNTL, 0);
- if (adev->mode_info.num_crtc)
- amdgpu_display_set_vga_render_state(adev, false);
-
- gmc_v6_0_mc_stop(adev, &save);
-
if (gmc_v6_0_wait_for_idle((void *)adev)) {
dev_warn(adev->dev, "Wait for MC idle timedout !\n");
}
- WREG32(mmVGA_HDP_CONTROL, VGA_HDP_CONTROL__VGA_MEMORY_DISABLE_MASK);
+ if (adev->mode_info.num_crtc) {
+ u32 tmp;
+
+ /* Lockout access through VGA aperture*/
+ tmp = RREG32(mmVGA_HDP_CONTROL);
+ tmp |= VGA_HDP_CONTROL__VGA_MEMORY_DISABLE_MASK;
+ WREG32(mmVGA_HDP_CONTROL, tmp);
+
+ /* disable VGA render */
+ tmp = RREG32(mmVGA_RENDER_CONTROL);
+ tmp &= ~VGA_VSTATUS_CNTL;
+ WREG32(mmVGA_RENDER_CONTROL, tmp);
+ }
/* Update configuration */
WREG32(mmMC_VM_SYSTEM_APERTURE_LOW_ADDR,
adev->mc.vram_start >> 12);
@@ -271,13 +269,6 @@ static void gmc_v6_0_mc_program(struct amdgpu_device *adev)
adev->mc.vram_end >> 12);
WREG32(mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
adev->vram_scratch.gpu_addr >> 12);
- tmp = ((adev->mc.vram_end >> 24) & 0xFFFF) << 16;
- tmp |= ((adev->mc.vram_start >> 24) & 0xFFFF);
- WREG32(mmMC_VM_FB_LOCATION, tmp);
- /* XXX double check these! */
- WREG32(mmHDP_NONSURFACE_BASE, (adev->mc.vram_start >> 8));
- WREG32(mmHDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
- WREG32(mmHDP_NONSURFACE_SIZE, 0x3FFFFFFF);
WREG32(mmMC_VM_AGP_BASE, 0);
WREG32(mmMC_VM_AGP_TOP, 0x0FFFFFFF);
WREG32(mmMC_VM_AGP_BOT, 0x0FFFFFFF);
@@ -285,7 +276,6 @@ static void gmc_v6_0_mc_program(struct amdgpu_device *adev)
if (gmc_v6_0_wait_for_idle((void *)adev)) {
dev_warn(adev->dev, "Wait for MC idle timedout !\n");
}
- gmc_v6_0_mc_resume(adev, &save);
}
static int gmc_v6_0_mc_init(struct amdgpu_device *adev)
@@ -342,15 +332,7 @@ static int gmc_v6_0_mc_init(struct amdgpu_device *adev)
adev->mc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
adev->mc.visible_vram_size = adev->mc.aper_size;
- /* unless the user had overridden it, set the gart
- * size equal to the 1024 or vram, whichever is larger.
- */
- if (amdgpu_gart_size == -1)
- adev->mc.gtt_size = max((AMDGPU_DEFAULT_GTT_SIZE_MB << 20),
- adev->mc.mc_vram_size);
- else
- adev->mc.gtt_size = (uint64_t)amdgpu_gart_size << 20;
-
+ amdgpu_gart_set_defaults(adev);
gmc_v6_0_vram_gtt_location(adev, &adev->mc);
return 0;
@@ -479,6 +461,7 @@ static void gmc_v6_0_set_prt(struct amdgpu_device *adev, bool enable)
static int gmc_v6_0_gart_enable(struct amdgpu_device *adev)
{
int r, i;
+ u32 field;
if (adev->gart.robj == NULL) {
dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
@@ -506,13 +489,15 @@ static int gmc_v6_0_gart_enable(struct amdgpu_device *adev)
WREG32(mmVM_L2_CNTL2,
VM_L2_CNTL2__INVALIDATE_ALL_L1_TLBS_MASK |
VM_L2_CNTL2__INVALIDATE_L2_CACHE_MASK);
+
+ field = adev->vm_manager.fragment_size;
WREG32(mmVM_L2_CNTL3,
VM_L2_CNTL3__L2_CACHE_BIGK_ASSOCIATIVITY_MASK |
- (4UL << VM_L2_CNTL3__BANK_SELECT__SHIFT) |
- (4UL << VM_L2_CNTL3__L2_CACHE_BIGK_FRAGMENT_SIZE__SHIFT));
+ (field << VM_L2_CNTL3__BANK_SELECT__SHIFT) |
+ (field << VM_L2_CNTL3__L2_CACHE_BIGK_FRAGMENT_SIZE__SHIFT));
/* setup context0 */
- WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12);
- WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gtt_end >> 12);
+ WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gart_start >> 12);
+ WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gart_end >> 12);
WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12);
WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
(u32)(adev->dummy_page.addr >> 12));
@@ -559,7 +544,7 @@ static int gmc_v6_0_gart_enable(struct amdgpu_device *adev)
gmc_v6_0_gart_flush_gpu_tlb(adev, 0);
dev_info(adev->dev, "PCIE GART of %uM enabled (table at 0x%016llX).\n",
- (unsigned)(adev->mc.gtt_size >> 20),
+ (unsigned)(adev->mc.gart_size >> 20),
(unsigned long long)adev->gart.table_addr);
adev->gart.ready = true;
return 0;
@@ -829,7 +814,7 @@ static int gmc_v6_0_sw_init(void *handle)
if (r)
return r;
- amdgpu_vm_adjust_size(adev, 64);
+ amdgpu_vm_adjust_size(adev, 64, 4);
adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18;
adev->mc.mc_mask = 0xffffffffffULL;
@@ -987,7 +972,6 @@ static int gmc_v6_0_wait_for_idle(void *handle)
static int gmc_v6_0_soft_reset(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- struct amdgpu_mode_mc_save save;
u32 srbm_soft_reset = 0;
u32 tmp = RREG32(mmSRBM_STATUS);
@@ -1003,7 +987,7 @@ static int gmc_v6_0_soft_reset(void *handle)
}
if (srbm_soft_reset) {
- gmc_v6_0_mc_stop(adev, &save);
+ gmc_v6_0_mc_stop(adev);
if (gmc_v6_0_wait_for_idle(adev)) {
dev_warn(adev->dev, "Wait for GMC idle timed out !\n");
}
@@ -1023,7 +1007,7 @@ static int gmc_v6_0_soft_reset(void *handle)
udelay(50);
- gmc_v6_0_mc_resume(adev, &save);
+ gmc_v6_0_mc_resume(adev);
udelay(50);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
index 7e9ea53edf8b..e42c1ad3af5e 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
@@ -37,6 +37,9 @@
#include "oss/oss_2_0_d.h"
#include "oss/oss_2_0_sh_mask.h"
+#include "dce/dce_8_0_d.h"
+#include "dce/dce_8_0_sh_mask.h"
+
#include "amdgpu_atombios.h"
static void gmc_v7_0_set_gart_funcs(struct amdgpu_device *adev);
@@ -76,14 +79,10 @@ static void gmc_v7_0_init_golden_registers(struct amdgpu_device *adev)
}
}
-static void gmc_v7_0_mc_stop(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
+static void gmc_v7_0_mc_stop(struct amdgpu_device *adev)
{
u32 blackout;
- if (adev->mode_info.num_crtc)
- amdgpu_display_stop_mc_access(adev, save);
-
gmc_v7_0_wait_for_idle((void *)adev);
blackout = RREG32(mmMC_SHARED_BLACKOUT_CNTL);
@@ -99,8 +98,7 @@ static void gmc_v7_0_mc_stop(struct amdgpu_device *adev,
udelay(100);
}
-static void gmc_v7_0_mc_resume(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
+static void gmc_v7_0_mc_resume(struct amdgpu_device *adev)
{
u32 tmp;
@@ -112,9 +110,6 @@ static void gmc_v7_0_mc_resume(struct amdgpu_device *adev,
tmp = REG_SET_FIELD(0, BIF_FB_EN, FB_READ_EN, 1);
tmp = REG_SET_FIELD(tmp, BIF_FB_EN, FB_WRITE_EN, 1);
WREG32(mmBIF_FB_EN, tmp);
-
- if (adev->mode_info.num_crtc)
- amdgpu_display_resume_mc_access(adev, save);
}
/**
@@ -242,15 +237,17 @@ static int gmc_v7_0_mc_load_microcode(struct amdgpu_device *adev)
static void gmc_v7_0_vram_gtt_location(struct amdgpu_device *adev,
struct amdgpu_mc *mc)
{
+ u64 base = RREG32(mmMC_VM_FB_LOCATION) & 0xFFFF;
+ base <<= 24;
+
if (mc->mc_vram_size > 0xFFC0000000ULL) {
/* leave room for at least 1024M GTT */
dev_warn(adev->dev, "limiting VRAM\n");
mc->real_vram_size = 0xFFC0000000ULL;
mc->mc_vram_size = 0xFFC0000000ULL;
}
- amdgpu_vram_location(adev, &adev->mc, 0);
- adev->mc.gtt_base_align = 0;
- amdgpu_gtt_location(adev, mc);
+ amdgpu_vram_location(adev, &adev->mc, base);
+ amdgpu_gart_location(adev, mc);
}
/**
@@ -263,7 +260,6 @@ static void gmc_v7_0_vram_gtt_location(struct amdgpu_device *adev,
*/
static void gmc_v7_0_mc_program(struct amdgpu_device *adev)
{
- struct amdgpu_mode_mc_save save;
u32 tmp;
int i, j;
@@ -277,13 +273,20 @@ static void gmc_v7_0_mc_program(struct amdgpu_device *adev)
}
WREG32(mmHDP_REG_COHERENCY_FLUSH_CNTL, 0);
- if (adev->mode_info.num_crtc)
- amdgpu_display_set_vga_render_state(adev, false);
-
- gmc_v7_0_mc_stop(adev, &save);
if (gmc_v7_0_wait_for_idle((void *)adev)) {
dev_warn(adev->dev, "Wait for MC idle timedout !\n");
}
+ if (adev->mode_info.num_crtc) {
+ /* Lockout access through VGA aperture*/
+ tmp = RREG32(mmVGA_HDP_CONTROL);
+ tmp = REG_SET_FIELD(tmp, VGA_HDP_CONTROL, VGA_MEMORY_DISABLE, 1);
+ WREG32(mmVGA_HDP_CONTROL, tmp);
+
+ /* disable VGA render */
+ tmp = RREG32(mmVGA_RENDER_CONTROL);
+ tmp = REG_SET_FIELD(tmp, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0);
+ WREG32(mmVGA_RENDER_CONTROL, tmp);
+ }
/* Update configuration */
WREG32(mmMC_VM_SYSTEM_APERTURE_LOW_ADDR,
adev->mc.vram_start >> 12);
@@ -291,20 +294,12 @@ static void gmc_v7_0_mc_program(struct amdgpu_device *adev)
adev->mc.vram_end >> 12);
WREG32(mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
adev->vram_scratch.gpu_addr >> 12);
- tmp = ((adev->mc.vram_end >> 24) & 0xFFFF) << 16;
- tmp |= ((adev->mc.vram_start >> 24) & 0xFFFF);
- WREG32(mmMC_VM_FB_LOCATION, tmp);
- /* XXX double check these! */
- WREG32(mmHDP_NONSURFACE_BASE, (adev->mc.vram_start >> 8));
- WREG32(mmHDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
- WREG32(mmHDP_NONSURFACE_SIZE, 0x3FFFFFFF);
WREG32(mmMC_VM_AGP_BASE, 0);
WREG32(mmMC_VM_AGP_TOP, 0x0FFFFFFF);
WREG32(mmMC_VM_AGP_BOT, 0x0FFFFFFF);
if (gmc_v7_0_wait_for_idle((void *)adev)) {
dev_warn(adev->dev, "Wait for MC idle timedout !\n");
}
- gmc_v7_0_mc_resume(adev, &save);
WREG32(mmBIF_FB_EN, BIF_FB_EN__FB_READ_EN_MASK | BIF_FB_EN__FB_WRITE_EN_MASK);
@@ -391,15 +386,7 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev)
if (adev->mc.visible_vram_size > adev->mc.real_vram_size)
adev->mc.visible_vram_size = adev->mc.real_vram_size;
- /* unless the user had overridden it, set the gart
- * size equal to the 1024 or vram, whichever is larger.
- */
- if (amdgpu_gart_size == -1)
- adev->mc.gtt_size = max((AMDGPU_DEFAULT_GTT_SIZE_MB << 20),
- adev->mc.mc_vram_size);
- else
- adev->mc.gtt_size = (uint64_t)amdgpu_gart_size << 20;
-
+ amdgpu_gart_set_defaults(adev);
gmc_v7_0_vram_gtt_location(adev, &adev->mc);
return 0;
@@ -575,7 +562,7 @@ static void gmc_v7_0_set_prt(struct amdgpu_device *adev, bool enable)
static int gmc_v7_0_gart_enable(struct amdgpu_device *adev)
{
int r, i;
- u32 tmp;
+ u32 tmp, field;
if (adev->gart.robj == NULL) {
dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
@@ -605,14 +592,16 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(0, VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
WREG32(mmVM_L2_CNTL2, tmp);
+
+ field = adev->vm_manager.fragment_size;
tmp = RREG32(mmVM_L2_CNTL3);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY, 1);
- tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 4);
- tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, 4);
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, field);
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, field);
WREG32(mmVM_L2_CNTL3, tmp);
/* setup context0 */
- WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12);
- WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gtt_end >> 12);
+ WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gart_start >> 12);
+ WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gart_end >> 12);
WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12);
WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
(u32)(adev->dummy_page.addr >> 12));
@@ -666,7 +655,7 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev)
gmc_v7_0_gart_flush_gpu_tlb(adev, 0);
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
- (unsigned)(adev->mc.gtt_size >> 20),
+ (unsigned)(adev->mc.gart_size >> 20),
(unsigned long long)adev->gart.table_addr);
adev->gart.ready = true;
return 0;
@@ -961,7 +950,7 @@ static int gmc_v7_0_sw_init(void *handle)
* Currently set to 4GB ((1 << 20) 4k pages).
* Max GPUVM size for cayman and SI is 40 bits.
*/
- amdgpu_vm_adjust_size(adev, 64);
+ amdgpu_vm_adjust_size(adev, 64, 4);
adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18;
/* Set the internal MC address mask
@@ -1138,7 +1127,6 @@ static int gmc_v7_0_wait_for_idle(void *handle)
static int gmc_v7_0_soft_reset(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- struct amdgpu_mode_mc_save save;
u32 srbm_soft_reset = 0;
u32 tmp = RREG32(mmSRBM_STATUS);
@@ -1154,7 +1142,7 @@ static int gmc_v7_0_soft_reset(void *handle)
}
if (srbm_soft_reset) {
- gmc_v7_0_mc_stop(adev, &save);
+ gmc_v7_0_mc_stop(adev);
if (gmc_v7_0_wait_for_idle((void *)adev)) {
dev_warn(adev->dev, "Wait for GMC idle timed out !\n");
}
@@ -1175,7 +1163,7 @@ static int gmc_v7_0_soft_reset(void *handle)
/* Wait a little for things to settle down */
udelay(50);
- gmc_v7_0_mc_resume(adev, &save);
+ gmc_v7_0_mc_resume(adev);
udelay(50);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
index cc9f88057cd5..7ca2dae8237a 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -35,6 +35,9 @@
#include "oss/oss_3_0_d.h"
#include "oss/oss_3_0_sh_mask.h"
+#include "dce/dce_10_0_d.h"
+#include "dce/dce_10_0_sh_mask.h"
+
#include "vid.h"
#include "vi.h"
@@ -161,14 +164,10 @@ static void gmc_v8_0_init_golden_registers(struct amdgpu_device *adev)
}
}
-static void gmc_v8_0_mc_stop(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
+static void gmc_v8_0_mc_stop(struct amdgpu_device *adev)
{
u32 blackout;
- if (adev->mode_info.num_crtc)
- amdgpu_display_stop_mc_access(adev, save);
-
gmc_v8_0_wait_for_idle(adev);
blackout = RREG32(mmMC_SHARED_BLACKOUT_CNTL);
@@ -184,8 +183,7 @@ static void gmc_v8_0_mc_stop(struct amdgpu_device *adev,
udelay(100);
}
-static void gmc_v8_0_mc_resume(struct amdgpu_device *adev,
- struct amdgpu_mode_mc_save *save)
+static void gmc_v8_0_mc_resume(struct amdgpu_device *adev)
{
u32 tmp;
@@ -197,9 +195,6 @@ static void gmc_v8_0_mc_resume(struct amdgpu_device *adev,
tmp = REG_SET_FIELD(0, BIF_FB_EN, FB_READ_EN, 1);
tmp = REG_SET_FIELD(tmp, BIF_FB_EN, FB_WRITE_EN, 1);
WREG32(mmBIF_FB_EN, tmp);
-
- if (adev->mode_info.num_crtc)
- amdgpu_display_resume_mc_access(adev, save);
}
/**
@@ -404,15 +399,20 @@ static int gmc_v8_0_polaris_mc_load_microcode(struct amdgpu_device *adev)
static void gmc_v8_0_vram_gtt_location(struct amdgpu_device *adev,
struct amdgpu_mc *mc)
{
+ u64 base = 0;
+
+ if (!amdgpu_sriov_vf(adev))
+ base = RREG32(mmMC_VM_FB_LOCATION) & 0xFFFF;
+ base <<= 24;
+
if (mc->mc_vram_size > 0xFFC0000000ULL) {
/* leave room for at least 1024M GTT */
dev_warn(adev->dev, "limiting VRAM\n");
mc->real_vram_size = 0xFFC0000000ULL;
mc->mc_vram_size = 0xFFC0000000ULL;
}
- amdgpu_vram_location(adev, &adev->mc, 0);
- adev->mc.gtt_base_align = 0;
- amdgpu_gtt_location(adev, mc);
+ amdgpu_vram_location(adev, &adev->mc, base);
+ amdgpu_gart_location(adev, mc);
}
/**
@@ -425,7 +425,6 @@ static void gmc_v8_0_vram_gtt_location(struct amdgpu_device *adev,
*/
static void gmc_v8_0_mc_program(struct amdgpu_device *adev)
{
- struct amdgpu_mode_mc_save save;
u32 tmp;
int i, j;
@@ -439,13 +438,20 @@ static void gmc_v8_0_mc_program(struct amdgpu_device *adev)
}
WREG32(mmHDP_REG_COHERENCY_FLUSH_CNTL, 0);
- if (adev->mode_info.num_crtc)
- amdgpu_display_set_vga_render_state(adev, false);
-
- gmc_v8_0_mc_stop(adev, &save);
if (gmc_v8_0_wait_for_idle((void *)adev)) {
dev_warn(adev->dev, "Wait for MC idle timedout !\n");
}
+ if (adev->mode_info.num_crtc) {
+ /* Lockout access through VGA aperture*/
+ tmp = RREG32(mmVGA_HDP_CONTROL);
+ tmp = REG_SET_FIELD(tmp, VGA_HDP_CONTROL, VGA_MEMORY_DISABLE, 1);
+ WREG32(mmVGA_HDP_CONTROL, tmp);
+
+ /* disable VGA render */
+ tmp = RREG32(mmVGA_RENDER_CONTROL);
+ tmp = REG_SET_FIELD(tmp, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0);
+ WREG32(mmVGA_RENDER_CONTROL, tmp);
+ }
/* Update configuration */
WREG32(mmMC_VM_SYSTEM_APERTURE_LOW_ADDR,
adev->mc.vram_start >> 12);
@@ -453,20 +459,23 @@ static void gmc_v8_0_mc_program(struct amdgpu_device *adev)
adev->mc.vram_end >> 12);
WREG32(mmMC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
adev->vram_scratch.gpu_addr >> 12);
- tmp = ((adev->mc.vram_end >> 24) & 0xFFFF) << 16;
- tmp |= ((adev->mc.vram_start >> 24) & 0xFFFF);
- WREG32(mmMC_VM_FB_LOCATION, tmp);
- /* XXX double check these! */
- WREG32(mmHDP_NONSURFACE_BASE, (adev->mc.vram_start >> 8));
- WREG32(mmHDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
- WREG32(mmHDP_NONSURFACE_SIZE, 0x3FFFFFFF);
+
+ if (amdgpu_sriov_vf(adev)) {
+ tmp = ((adev->mc.vram_end >> 24) & 0xFFFF) << 16;
+ tmp |= ((adev->mc.vram_start >> 24) & 0xFFFF);
+ WREG32(mmMC_VM_FB_LOCATION, tmp);
+ /* XXX double check these! */
+ WREG32(mmHDP_NONSURFACE_BASE, (adev->mc.vram_start >> 8));
+ WREG32(mmHDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
+ WREG32(mmHDP_NONSURFACE_SIZE, 0x3FFFFFFF);
+ }
+
WREG32(mmMC_VM_AGP_BASE, 0);
WREG32(mmMC_VM_AGP_TOP, 0x0FFFFFFF);
WREG32(mmMC_VM_AGP_BOT, 0x0FFFFFFF);
if (gmc_v8_0_wait_for_idle((void *)adev)) {
dev_warn(adev->dev, "Wait for MC idle timedout !\n");
}
- gmc_v8_0_mc_resume(adev, &save);
WREG32(mmBIF_FB_EN, BIF_FB_EN__FB_READ_EN_MASK | BIF_FB_EN__FB_WRITE_EN_MASK);
@@ -553,15 +562,7 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev)
if (adev->mc.visible_vram_size > adev->mc.real_vram_size)
adev->mc.visible_vram_size = adev->mc.real_vram_size;
- /* unless the user had overridden it, set the gart
- * size equal to the 1024 or vram, whichever is larger.
- */
- if (amdgpu_gart_size == -1)
- adev->mc.gtt_size = max((AMDGPU_DEFAULT_GTT_SIZE_MB << 20),
- adev->mc.mc_vram_size);
- else
- adev->mc.gtt_size = (uint64_t)amdgpu_gart_size << 20;
-
+ amdgpu_gart_set_defaults(adev);
gmc_v8_0_vram_gtt_location(adev, &adev->mc);
return 0;
@@ -761,7 +762,7 @@ static void gmc_v8_0_set_prt(struct amdgpu_device *adev, bool enable)
static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
{
int r, i;
- u32 tmp;
+ u32 tmp, field;
if (adev->gart.robj == NULL) {
dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
@@ -792,10 +793,12 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS, 1);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
WREG32(mmVM_L2_CNTL2, tmp);
+
+ field = adev->vm_manager.fragment_size;
tmp = RREG32(mmVM_L2_CNTL3);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY, 1);
- tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 4);
- tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, 4);
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, field);
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, field);
WREG32(mmVM_L2_CNTL3, tmp);
/* XXX: set to enable PTE/PDE in system memory */
tmp = RREG32(mmVM_L2_CNTL4);
@@ -813,8 +816,8 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL4, VMC_TAP_CONTEXT1_PTE_REQUEST_SNOOP, 0);
WREG32(mmVM_L2_CNTL4, tmp);
/* setup context0 */
- WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12);
- WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gtt_end >> 12);
+ WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gart_start >> 12);
+ WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gart_end >> 12);
WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12);
WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
(u32)(adev->dummy_page.addr >> 12));
@@ -869,7 +872,7 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev)
gmc_v8_0_gart_flush_gpu_tlb(adev, 0);
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
- (unsigned)(adev->mc.gtt_size >> 20),
+ (unsigned)(adev->mc.gart_size >> 20),
(unsigned long long)adev->gart.table_addr);
adev->gart.ready = true;
return 0;
@@ -1045,7 +1048,7 @@ static int gmc_v8_0_sw_init(void *handle)
* Currently set to 4GB ((1 << 20) 4k pages).
* Max GPUVM size for cayman and SI is 40 bits.
*/
- amdgpu_vm_adjust_size(adev, 64);
+ amdgpu_vm_adjust_size(adev, 64, 4);
adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18;
/* Set the internal MC address mask
@@ -1260,7 +1263,7 @@ static int gmc_v8_0_pre_soft_reset(void *handle)
if (!adev->mc.srbm_soft_reset)
return 0;
- gmc_v8_0_mc_stop(adev, &adev->mc.save);
+ gmc_v8_0_mc_stop(adev);
if (gmc_v8_0_wait_for_idle(adev)) {
dev_warn(adev->dev, "Wait for GMC idle timed out !\n");
}
@@ -1306,7 +1309,7 @@ static int gmc_v8_0_post_soft_reset(void *handle)
if (!adev->mc.srbm_soft_reset)
return 0;
- gmc_v8_0_mc_resume(adev, &adev->mc.save);
+ gmc_v8_0_mc_resume(adev);
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
index 175ba5f9691c..2769c2b3b56e 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -23,11 +23,14 @@
#include <linux/firmware.h>
#include "amdgpu.h"
#include "gmc_v9_0.h"
+#include "amdgpu_atomfirmware.h"
#include "vega10/soc15ip.h"
#include "vega10/HDP/hdp_4_0_offset.h"
#include "vega10/HDP/hdp_4_0_sh_mask.h"
#include "vega10/GC/gc_9_0_sh_mask.h"
+#include "vega10/DC/dce_12_0_offset.h"
+#include "vega10/DC/dce_12_0_sh_mask.h"
#include "vega10/vega10_enum.h"
#include "soc15_common.h"
@@ -419,8 +422,7 @@ static void gmc_v9_0_vram_gtt_location(struct amdgpu_device *adev,
if (!amdgpu_sriov_vf(adev))
base = mmhub_v1_0_get_fb_location(adev);
amdgpu_vram_location(adev, &adev->mc, base);
- adev->mc.gtt_base_align = 0;
- amdgpu_gtt_location(adev, mc);
+ amdgpu_gart_location(adev, mc);
/* base offset of vram pages */
if (adev->flags & AMD_IS_APU)
adev->vm_manager.vram_base_offset = gfxhub_v1_0_get_mc_fb_offset(adev);
@@ -442,43 +444,46 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev)
u32 tmp;
int chansize, numchan;
- /* hbm memory channel size */
- chansize = 128;
-
- tmp = RREG32_SOC15(DF, 0, mmDF_CS_AON0_DramBaseAddress0);
- tmp &= DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK;
- tmp >>= DF_CS_AON0_DramBaseAddress0__IntLvNumChan__SHIFT;
- switch (tmp) {
- case 0:
- default:
- numchan = 1;
- break;
- case 1:
- numchan = 2;
- break;
- case 2:
- numchan = 0;
- break;
- case 3:
- numchan = 4;
- break;
- case 4:
- numchan = 0;
- break;
- case 5:
- numchan = 8;
- break;
- case 6:
- numchan = 0;
- break;
- case 7:
- numchan = 16;
- break;
- case 8:
- numchan = 2;
- break;
+ adev->mc.vram_width = amdgpu_atomfirmware_get_vram_width(adev);
+ if (!adev->mc.vram_width) {
+ /* hbm memory channel size */
+ chansize = 128;
+
+ tmp = RREG32_SOC15(DF, 0, mmDF_CS_AON0_DramBaseAddress0);
+ tmp &= DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK;
+ tmp >>= DF_CS_AON0_DramBaseAddress0__IntLvNumChan__SHIFT;
+ switch (tmp) {
+ case 0:
+ default:
+ numchan = 1;
+ break;
+ case 1:
+ numchan = 2;
+ break;
+ case 2:
+ numchan = 0;
+ break;
+ case 3:
+ numchan = 4;
+ break;
+ case 4:
+ numchan = 0;
+ break;
+ case 5:
+ numchan = 8;
+ break;
+ case 6:
+ numchan = 0;
+ break;
+ case 7:
+ numchan = 16;
+ break;
+ case 8:
+ numchan = 2;
+ break;
+ }
+ adev->mc.vram_width = numchan * chansize;
}
- adev->mc.vram_width = numchan * chansize;
/* Could aper size report 0 ? */
adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
@@ -494,15 +499,7 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev)
if (adev->mc.visible_vram_size > adev->mc.real_vram_size)
adev->mc.visible_vram_size = adev->mc.real_vram_size;
- /* unless the user had overridden it, set the gart
- * size equal to the 1024 or vram, whichever is larger.
- */
- if (amdgpu_gart_size == -1)
- adev->mc.gtt_size = max((AMDGPU_DEFAULT_GTT_SIZE_MB << 20),
- adev->mc.mc_vram_size);
- else
- adev->mc.gtt_size = (uint64_t)amdgpu_gart_size << 20;
-
+ amdgpu_gart_set_defaults(adev);
gmc_v9_0_vram_gtt_location(adev, &adev->mc);
return 0;
@@ -537,10 +534,21 @@ static int gmc_v9_0_sw_init(void *handle)
spin_lock_init(&adev->mc.invalidate_lock);
- if (adev->flags & AMD_IS_APU) {
+ switch (adev->asic_type) {
+ case CHIP_RAVEN:
adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
- amdgpu_vm_adjust_size(adev, 64);
- } else {
+ if (adev->rev_id == 0x0 || adev->rev_id == 0x1) {
+ adev->vm_manager.vm_size = 1U << 18;
+ adev->vm_manager.block_size = 9;
+ adev->vm_manager.num_level = 3;
+ amdgpu_vm_set_fragment_size(adev, 9);
+ } else {
+ /* vm_size is 64GB for legacy 2-level page support */
+ amdgpu_vm_adjust_size(adev, 64, 9);
+ adev->vm_manager.num_level = 1;
+ }
+ break;
+ case CHIP_VEGA10:
/* XXX Don't know how to get VRAM type yet. */
adev->mc.vram_type = AMDGPU_VRAM_TYPE_HBM;
/*
@@ -550,11 +558,18 @@ static int gmc_v9_0_sw_init(void *handle)
*/
adev->vm_manager.vm_size = 1U << 18;
adev->vm_manager.block_size = 9;
- DRM_INFO("vm size is %llu GB, block size is %u-bit\n",
- adev->vm_manager.vm_size,
- adev->vm_manager.block_size);
+ adev->vm_manager.num_level = 3;
+ amdgpu_vm_set_fragment_size(adev, 9);
+ break;
+ default:
+ break;
}
+ DRM_INFO("vm size is %llu GB, block size is %u-bit,fragment size is %u-bit\n",
+ adev->vm_manager.vm_size,
+ adev->vm_manager.block_size,
+ adev->vm_manager.fragment_size);
+
/* This interrupt is VMC page fault.*/
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_VMC, 0,
&adev->mc.vm_fault);
@@ -619,11 +634,6 @@ static int gmc_v9_0_sw_init(void *handle)
adev->vm_manager.id_mgr[AMDGPU_GFXHUB].num_ids = AMDGPU_NUM_OF_VMIDS;
adev->vm_manager.id_mgr[AMDGPU_MMHUB].num_ids = AMDGPU_NUM_OF_VMIDS;
- /* TODO: fix num_level for APU when updating vm size and block size */
- if (adev->flags & AMD_IS_APU)
- adev->vm_manager.num_level = 1;
- else
- adev->vm_manager.num_level = 3;
amdgpu_vm_manager_init(adev);
return 0;
@@ -731,7 +741,7 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev)
gmc_v9_0_gart_flush_gpu_tlb(adev, 0);
DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
- (unsigned)(adev->mc.gtt_size >> 20),
+ (unsigned)(adev->mc.gart_size >> 20),
(unsigned long long)adev->gart.table_addr);
adev->gart.ready = true;
return 0;
@@ -745,6 +755,20 @@ static int gmc_v9_0_hw_init(void *handle)
/* The sequence of these two function calls matters.*/
gmc_v9_0_init_golden_registers(adev);
+ if (adev->mode_info.num_crtc) {
+ u32 tmp;
+
+ /* Lockout access through VGA aperture*/
+ tmp = RREG32_SOC15(DCE, 0, mmVGA_HDP_CONTROL);
+ tmp = REG_SET_FIELD(tmp, VGA_HDP_CONTROL, VGA_MEMORY_DISABLE, 1);
+ WREG32_SOC15(DCE, 0, mmVGA_HDP_CONTROL, tmp);
+
+ /* disable VGA render */
+ tmp = RREG32_SOC15(DCE, 0, mmVGA_RENDER_CONTROL);
+ tmp = REG_SET_FIELD(tmp, VGA_RENDER_CONTROL, VGA_VSTATUS_CNTL, 0);
+ WREG32_SOC15(DCE, 0, mmVGA_RENDER_CONTROL, tmp);
+ }
+
r = gmc_v9_0_gart_enable(adev);
return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
index 9804318f3488..4395a4f12149 100644
--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
@@ -69,14 +69,14 @@ static void mmhub_v1_0_init_gart_aperture_regs(struct amdgpu_device *adev)
mmhub_v1_0_init_gart_pt_regs(adev);
WREG32_SOC15(MMHUB, 0, mmVM_CONTEXT0_PAGE_TABLE_START_ADDR_LO32,
- (u32)(adev->mc.gtt_start >> 12));
+ (u32)(adev->mc.gart_start >> 12));
WREG32_SOC15(MMHUB, 0, mmVM_CONTEXT0_PAGE_TABLE_START_ADDR_HI32,
- (u32)(adev->mc.gtt_start >> 44));
+ (u32)(adev->mc.gart_start >> 44));
WREG32_SOC15(MMHUB, 0, mmVM_CONTEXT0_PAGE_TABLE_END_ADDR_LO32,
- (u32)(adev->mc.gtt_end >> 12));
+ (u32)(adev->mc.gart_end >> 12));
WREG32_SOC15(MMHUB, 0, mmVM_CONTEXT0_PAGE_TABLE_END_ADDR_HI32,
- (u32)(adev->mc.gtt_end >> 44));
+ (u32)(adev->mc.gart_end >> 44));
}
static void mmhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev)
@@ -138,12 +138,12 @@ static void mmhub_v1_0_init_tlb_regs(struct amdgpu_device *adev)
static void mmhub_v1_0_init_cache_regs(struct amdgpu_device *adev)
{
- uint32_t tmp;
+ uint32_t tmp, field;
/* Setup L2 cache */
tmp = RREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL);
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 1);
- tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING, 0);
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING, 1);
/* XXX for emulation, Refer to closed source code.*/
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, L2_PDE0_CACHE_TAG_GENERATION_MODE,
0);
@@ -157,7 +157,10 @@ static void mmhub_v1_0_init_cache_regs(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1);
WREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL2, tmp);
+ field = adev->vm_manager.fragment_size;
tmp = mmVM_L2_CNTL3_DEFAULT;
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, field);
+ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
WREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL3, tmp);
tmp = mmVM_L2_CNTL4_DEFAULT;
@@ -222,6 +225,9 @@ static void mmhub_v1_0_setup_vmid_config(struct amdgpu_device *adev)
tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
PAGE_TABLE_BLOCK_SIZE,
adev->vm_manager.block_size - 9);
+ /* Send no-retry XNACK on fault to suppress VM fault storm. */
+ tmp = REG_SET_FIELD(tmp, VM_CONTEXT1_CNTL,
+ RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
WREG32_SOC15_OFFSET(MMHUB, 0, mmVM_CONTEXT1_CNTL, i, tmp);
WREG32_SOC15_OFFSET(MMHUB, 0, mmVM_CONTEXT1_PAGE_TABLE_START_ADDR_LO32, i*2, 0);
WREG32_SOC15_OFFSET(MMHUB, 0, mmVM_CONTEXT1_PAGE_TABLE_START_ADDR_HI32, i*2, 0);
@@ -245,28 +251,28 @@ static void mmhub_v1_0_program_invalidation(struct amdgpu_device *adev)
}
struct pctl_data {
- uint32_t index;
- uint32_t data;
+ uint32_t index;
+ uint32_t data;
};
-const struct pctl_data pctl0_data[] = {
- {0x0, 0x7a640},
- {0x9, 0x2a64a},
- {0xd, 0x2a680},
- {0x11, 0x6a684},
- {0x19, 0xea68e},
- {0x29, 0xa69e},
- {0x2b, 0x34a6c0},
- {0x61, 0x83a707},
- {0xe6, 0x8a7a4},
- {0xf0, 0x1a7b8},
- {0xf3, 0xfa7cc},
- {0x104, 0x17a7dd},
- {0x11d, 0xa7dc},
- {0x11f, 0x12a7f5},
- {0x133, 0xa808},
- {0x135, 0x12a810},
- {0x149, 0x7a82c}
+static const struct pctl_data pctl0_data[] = {
+ {0x0, 0x7a640},
+ {0x9, 0x2a64a},
+ {0xd, 0x2a680},
+ {0x11, 0x6a684},
+ {0x19, 0xea68e},
+ {0x29, 0xa69e},
+ {0x2b, 0x34a6c0},
+ {0x61, 0x83a707},
+ {0xe6, 0x8a7a4},
+ {0xf0, 0x1a7b8},
+ {0xf3, 0xfa7cc},
+ {0x104, 0x17a7dd},
+ {0x11d, 0xa7dc},
+ {0x11f, 0x12a7f5},
+ {0x133, 0xa808},
+ {0x135, 0x12a810},
+ {0x149, 0x7a82c}
};
#define PCTL0_DATA_LEN (sizeof(pctl0_data)/sizeof(pctl0_data[0]))
@@ -274,32 +280,39 @@ const struct pctl_data pctl0_data[] = {
#define PCTL0_STCTRL_REG_SAVE_RANGE0_BASE 0xa640
#define PCTL0_STCTRL_REG_SAVE_RANGE0_LIMIT 0xa833
-const struct pctl_data pctl1_data[] = {
- {0x0, 0x39a000},
- {0x3b, 0x44a040},
- {0x81, 0x2a08d},
- {0x85, 0x6ba094},
- {0xf2, 0x18a100},
- {0x10c, 0x4a132},
- {0x112, 0xca141},
- {0x120, 0x2fa158},
- {0x151, 0x17a1d0},
- {0x16a, 0x1a1e9},
- {0x16d, 0x13a1ec},
- {0x182, 0x7a201},
- {0x18b, 0x3a20a},
- {0x190, 0x7a580},
- {0x199, 0xa590},
- {0x19b, 0x4a594},
- {0x1a1, 0x1a59c},
- {0x1a4, 0x7a82c},
- {0x1ad, 0xfa7cc},
- {0x1be, 0x17a7dd},
- {0x1d7, 0x12a810}
+static const struct pctl_data pctl1_data[] = {
+ {0x0, 0x39a000},
+ {0x3b, 0x44a040},
+ {0x81, 0x2a08d},
+ {0x85, 0x6ba094},
+ {0xf2, 0x18a100},
+ {0x10c, 0x4a132},
+ {0x112, 0xca141},
+ {0x120, 0x2fa158},
+ {0x151, 0x17a1d0},
+ {0x16a, 0x1a1e9},
+ {0x16d, 0x13a1ec},
+ {0x182, 0x7a201},
+ {0x18b, 0x3a20a},
+ {0x190, 0x7a580},
+ {0x199, 0xa590},
+ {0x19b, 0x4a594},
+ {0x1a1, 0x1a59c},
+ {0x1a4, 0x7a82c},
+ {0x1ad, 0xfa7cc},
+ {0x1be, 0x17a7dd},
+ {0x1d7, 0x12a810},
+ {0x1eb, 0x4000a7e1},
+ {0x1ec, 0x5000a7f5},
+ {0x1ed, 0x4000a7e2},
+ {0x1ee, 0x5000a7dc},
+ {0x1ef, 0x4000a7e3},
+ {0x1f0, 0x5000a7f6},
+ {0x1f1, 0x5000a7e4}
};
#define PCTL1_DATA_LEN (sizeof(pctl1_data)/sizeof(pctl1_data[0]))
-#define PCTL1_RENG_EXEC_END_PTR 0x1ea
+#define PCTL1_RENG_EXEC_END_PTR 0x1f1
#define PCTL1_STCTRL_REG_SAVE_RANGE0_BASE 0xa000
#define PCTL1_STCTRL_REG_SAVE_RANGE0_LIMIT 0xa20d
#define PCTL1_STCTRL_REG_SAVE_RANGE1_BASE 0xa580
diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h
index 57bb940c0ecd..5d38229baf69 100644
--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h
+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.h
@@ -36,7 +36,4 @@ void mmhub_v1_0_initialize_power_gating(struct amdgpu_device *adev);
void mmhub_v1_0_update_power_gating(struct amdgpu_device *adev,
bool enable);
-extern const struct amd_ip_funcs mmhub_v1_0_ip_funcs;
-extern const struct amdgpu_ip_block_version mmhub_v1_0_ip_block;
-
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
index bde3ca3c21c1..2812d88a8bdd 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
@@ -72,21 +72,6 @@ static void xgpu_ai_mailbox_set_valid(struct amdgpu_device *adev, bool val)
reg);
}
-static void xgpu_ai_mailbox_trans_msg(struct amdgpu_device *adev,
- enum idh_request req)
-{
- u32 reg;
-
- reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
- mmBIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW0));
- reg = REG_SET_FIELD(reg, BIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW0,
- MSGBUF_DATA, req);
- WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW0),
- reg);
-
- xgpu_ai_mailbox_set_valid(adev, true);
-}
-
static int xgpu_ai_mailbox_rcv_msg(struct amdgpu_device *adev,
enum idh_event event)
{
@@ -154,13 +139,25 @@ static int xgpu_ai_poll_msg(struct amdgpu_device *adev, enum idh_event event)
return r;
}
-
-static int xgpu_ai_send_access_requests(struct amdgpu_device *adev,
- enum idh_request req)
-{
+static void xgpu_ai_mailbox_trans_msg (struct amdgpu_device *adev,
+ enum idh_request req, u32 data1, u32 data2, u32 data3) {
+ u32 reg;
int r;
- xgpu_ai_mailbox_trans_msg(adev, req);
+ reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
+ mmBIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW0));
+ reg = REG_SET_FIELD(reg, BIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW0,
+ MSGBUF_DATA, req);
+ WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW0),
+ reg);
+ WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW1),
+ data1);
+ WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW2),
+ data2);
+ WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW3),
+ data3);
+
+ xgpu_ai_mailbox_set_valid(adev, true);
/* start to poll ack */
r = xgpu_ai_poll_ack(adev);
@@ -168,6 +165,14 @@ static int xgpu_ai_send_access_requests(struct amdgpu_device *adev,
pr_err("Doesn't get ack from pf, continue\n");
xgpu_ai_mailbox_set_valid(adev, false);
+}
+
+static int xgpu_ai_send_access_requests(struct amdgpu_device *adev,
+ enum idh_request req)
+{
+ int r;
+
+ xgpu_ai_mailbox_trans_msg(adev, req, 0, 0, 0);
/* start to check msg if request is idh_req_gpu_init_access */
if (req == IDH_REQ_GPU_INIT_ACCESS ||
@@ -342,4 +347,5 @@ const struct amdgpu_virt_ops xgpu_ai_virt_ops = {
.req_full_gpu = xgpu_ai_request_full_gpu_access,
.rel_full_gpu = xgpu_ai_release_full_gpu_access,
.reset_gpu = xgpu_ai_request_reset,
+ .trans_msg = xgpu_ai_mailbox_trans_msg,
};
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h
index 9aefc44d2c34..1e91b9a1c591 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h
@@ -31,7 +31,9 @@ enum idh_request {
IDH_REL_GPU_INIT_ACCESS,
IDH_REQ_GPU_FINI_ACCESS,
IDH_REL_GPU_FINI_ACCESS,
- IDH_REQ_GPU_RESET_ACCESS
+ IDH_REQ_GPU_RESET_ACCESS,
+
+ IDH_LOG_VF_ERROR = 200,
};
enum idh_event {
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c
index 171a658135b5..c25a831f94ec 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c
@@ -613,4 +613,5 @@ const struct amdgpu_virt_ops xgpu_vi_virt_ops = {
.req_full_gpu = xgpu_vi_request_full_gpu_access,
.rel_full_gpu = xgpu_vi_release_full_gpu_access,
.reset_gpu = xgpu_vi_request_reset,
+ .trans_msg = NULL, /* Does not need to trans VF errors to host. */
};
diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h
index 2db741131bc6..c791d73d2d54 100644
--- a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h
+++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.h
@@ -32,7 +32,9 @@ enum idh_request {
IDH_REL_GPU_INIT_ACCESS,
IDH_REQ_GPU_FINI_ACCESS,
IDH_REL_GPU_FINI_ACCESS,
- IDH_REQ_GPU_RESET_ACCESS
+ IDH_REQ_GPU_RESET_ACCESS,
+
+ IDH_LOG_VF_ERROR = 200,
};
/* VI mailbox messages data */
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c
index 1e272f785def..045988b18bc3 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c
@@ -32,6 +32,7 @@
#define smnCPM_CONTROL 0x11180460
#define smnPCIE_CNTL2 0x11180070
+#define smnPCIE_CONFIG_CNTL 0x11180044
u32 nbio_v6_1_get_rev_id(struct amdgpu_device *adev)
{
@@ -67,7 +68,7 @@ void nbio_v6_1_mc_access_enable(struct amdgpu_device *adev, bool enable)
void nbio_v6_1_hdp_flush(struct amdgpu_device *adev)
{
- WREG32_SOC15(NBIO, 0, mmBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL, 0);
+ WREG32_SOC15_NO_KIQ(NBIO, 0, mmBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL, 0);
}
u32 nbio_v6_1_get_memsize(struct amdgpu_device *adev)
@@ -256,3 +257,15 @@ void nbio_v6_1_detect_hw_virt(struct amdgpu_device *adev)
adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
}
}
+
+void nbio_v6_1_init_registers(struct amdgpu_device *adev)
+{
+ uint32_t def, data;
+
+ def = data = RREG32_PCIE(smnPCIE_CONFIG_CNTL);
+ data = REG_SET_FIELD(data, PCIE_CONFIG_CNTL, CI_SWUS_MAX_READ_REQUEST_SIZE_MODE, 1);
+ data = REG_SET_FIELD(data, PCIE_CONFIG_CNTL, CI_SWUS_MAX_READ_REQUEST_SIZE_PRIV, 1);
+
+ if (def != data)
+ WREG32_PCIE(smnPCIE_CONFIG_CNTL, data);
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h
index f6f8bc045518..686e4b4d296a 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.h
@@ -50,5 +50,6 @@ void nbio_v6_1_update_medium_grain_clock_gating(struct amdgpu_device *adev, bool
void nbio_v6_1_update_medium_grain_light_sleep(struct amdgpu_device *adev, bool enable);
void nbio_v6_1_get_clockgating_state(struct amdgpu_device *adev, u32 *flags);
void nbio_v6_1_detect_hw_virt(struct amdgpu_device *adev);
+void nbio_v6_1_init_registers(struct amdgpu_device *adev);
#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c
index aa04632523fa..11b70d601922 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c
@@ -65,7 +65,7 @@ void nbio_v7_0_mc_access_enable(struct amdgpu_device *adev, bool enable)
void nbio_v7_0_hdp_flush(struct amdgpu_device *adev)
{
- WREG32_SOC15(NBIO, 0, mmHDP_MEM_COHERENCY_FLUSH_CNTL, 0);
+ WREG32_SOC15_NO_KIQ(NBIO, 0, mmHDP_MEM_COHERENCY_FLUSH_CNTL, 0);
}
u32 nbio_v7_0_get_memsize(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
index 2258323a3c26..f7cf994b1da2 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
@@ -86,6 +86,52 @@ psp_v10_0_get_fw_type(struct amdgpu_firmware_info *ucode, enum psp_gfx_fw_type *
return 0;
}
+int psp_v10_0_init_microcode(struct psp_context *psp)
+{
+ struct amdgpu_device *adev = psp->adev;
+ const char *chip_name;
+ char fw_name[30];
+ int err = 0;
+ const struct psp_firmware_header_v1_0 *hdr;
+
+ DRM_DEBUG("\n");
+
+ switch (adev->asic_type) {
+ case CHIP_RAVEN:
+ chip_name = "raven";
+ break;
+ default: BUG();
+ }
+
+ snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_asd.bin", chip_name);
+ err = request_firmware(&adev->psp.asd_fw, fw_name, adev->dev);
+ if (err)
+ goto out;
+
+ err = amdgpu_ucode_validate(adev->psp.asd_fw);
+ if (err)
+ goto out;
+
+ hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.asd_fw->data;
+ adev->psp.asd_fw_version = le32_to_cpu(hdr->header.ucode_version);
+ adev->psp.asd_feature_version = le32_to_cpu(hdr->ucode_feature_version);
+ adev->psp.asd_ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
+ adev->psp.asd_start_addr = (uint8_t *)hdr +
+ le32_to_cpu(hdr->header.ucode_array_offset_bytes);
+
+ return 0;
+out:
+ if (err) {
+ dev_err(adev->dev,
+ "psp v10.0: Failed to load firmware \"%s\"\n",
+ fw_name);
+ release_firmware(adev->psp.asd_fw);
+ adev->psp.asd_fw = NULL;
+ }
+
+ return err;
+}
+
int psp_v10_0_prep_cmd_buf(struct amdgpu_firmware_info *ucode, struct psp_gfx_cmd_resp *cmd)
{
int ret;
@@ -110,7 +156,6 @@ int psp_v10_0_prep_cmd_buf(struct amdgpu_firmware_info *ucode, struct psp_gfx_cm
int psp_v10_0_ring_init(struct psp_context *psp, enum psp_ring_type ring_type)
{
int ret = 0;
- unsigned int psp_ring_reg = 0;
struct psp_ring *ring;
struct amdgpu_device *adev = psp->adev;
@@ -130,6 +175,16 @@ int psp_v10_0_ring_init(struct psp_context *psp, enum psp_ring_type ring_type)
return ret;
}
+ return 0;
+}
+
+int psp_v10_0_ring_create(struct psp_context *psp, enum psp_ring_type ring_type)
+{
+ int ret = 0;
+ unsigned int psp_ring_reg = 0;
+ struct psp_ring *ring = &psp->km_ring;
+ struct amdgpu_device *adev = psp->adev;
+
/* Write low address of the ring to C2PMSG_69 */
psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr);
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_69, psp_ring_reg);
@@ -143,13 +198,42 @@ int psp_v10_0_ring_init(struct psp_context *psp, enum psp_ring_type ring_type)
psp_ring_reg = ring_type;
psp_ring_reg = psp_ring_reg << 16;
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, psp_ring_reg);
+
+ /* There might be handshake issue with hardware which needs delay */
+ mdelay(20);
+
/* Wait for response flag (bit 31) in C2PMSG_64 */
- psp_ring_reg = 0;
- while ((psp_ring_reg & 0x80000000) == 0) {
- psp_ring_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64);
- }
+ ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
+ 0x80000000, 0x8000FFFF, false);
- return 0;
+ return ret;
+}
+
+int psp_v10_0_ring_destroy(struct psp_context *psp, enum psp_ring_type ring_type)
+{
+ int ret = 0;
+ struct psp_ring *ring;
+ unsigned int psp_ring_reg = 0;
+ struct amdgpu_device *adev = psp->adev;
+
+ ring = &psp->km_ring;
+
+ /* Write the ring destroy command to C2PMSG_64 */
+ psp_ring_reg = 3 << 16;
+ WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, psp_ring_reg);
+
+ /* There might be handshake issue with hardware which needs delay */
+ mdelay(20);
+
+ /* Wait for response flag (bit 31) in C2PMSG_64 */
+ ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
+ 0x80000000, 0x80000000, false);
+
+ amdgpu_bo_free_kernel(&adev->firmware.rbuf,
+ &ring->ring_mem_mc_addr,
+ (void **)&ring->ring_mem);
+
+ return ret;
}
int psp_v10_0_cmd_submit(struct psp_context *psp,
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.h b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.h
index 2022b7b7151e..e76cde2f01f9 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.h
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.h
@@ -27,10 +27,15 @@
#include "amdgpu_psp.h"
+extern int psp_v10_0_init_microcode(struct psp_context *psp);
extern int psp_v10_0_prep_cmd_buf(struct amdgpu_firmware_info *ucode,
struct psp_gfx_cmd_resp *cmd);
extern int psp_v10_0_ring_init(struct psp_context *psp,
enum psp_ring_type ring_type);
+extern int psp_v10_0_ring_create(struct psp_context *psp,
+ enum psp_ring_type ring_type);
+extern int psp_v10_0_ring_destroy(struct psp_context *psp,
+ enum psp_ring_type ring_type);
extern int psp_v10_0_cmd_submit(struct psp_context *psp,
struct amdgpu_firmware_info *ucode,
uint64_t cmd_buf_mc_addr, uint64_t fence_mc_addr,
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
index c98d77d0c8f8..2a535a4b8d5b 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c
@@ -237,11 +237,9 @@ int psp_v3_1_bootloader_load_sos(struct psp_context *psp)
/* there might be handshake issue with hardware which needs delay */
mdelay(20);
-#if 0
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_81),
RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81),
0, true);
-#endif
return ret;
}
@@ -341,10 +339,10 @@ int psp_v3_1_ring_destroy(struct psp_context *psp, enum psp_ring_type ring_type)
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64),
0x80000000, 0x80000000, false);
- if (ring->ring_mem)
- amdgpu_bo_free_kernel(&adev->firmware.rbuf,
- &ring->ring_mem_mc_addr,
- (void **)&ring->ring_mem);
+ amdgpu_bo_free_kernel(&adev->firmware.rbuf,
+ &ring->ring_mem_mc_addr,
+ (void **)&ring->ring_mem);
+
return ret;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
index 1d766ae98dc8..b1de44f22824 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
@@ -551,17 +551,53 @@ static void sdma_v3_0_rlc_stop(struct amdgpu_device *adev)
*/
static void sdma_v3_0_ctx_switch_enable(struct amdgpu_device *adev, bool enable)
{
- u32 f32_cntl;
+ u32 f32_cntl, phase_quantum = 0;
int i;
+ if (amdgpu_sdma_phase_quantum) {
+ unsigned value = amdgpu_sdma_phase_quantum;
+ unsigned unit = 0;
+
+ while (value > (SDMA0_PHASE0_QUANTUM__VALUE_MASK >>
+ SDMA0_PHASE0_QUANTUM__VALUE__SHIFT)) {
+ value = (value + 1) >> 1;
+ unit++;
+ }
+ if (unit > (SDMA0_PHASE0_QUANTUM__UNIT_MASK >>
+ SDMA0_PHASE0_QUANTUM__UNIT__SHIFT)) {
+ value = (SDMA0_PHASE0_QUANTUM__VALUE_MASK >>
+ SDMA0_PHASE0_QUANTUM__VALUE__SHIFT);
+ unit = (SDMA0_PHASE0_QUANTUM__UNIT_MASK >>
+ SDMA0_PHASE0_QUANTUM__UNIT__SHIFT);
+ WARN_ONCE(1,
+ "clamping sdma_phase_quantum to %uK clock cycles\n",
+ value << unit);
+ }
+ phase_quantum =
+ value << SDMA0_PHASE0_QUANTUM__VALUE__SHIFT |
+ unit << SDMA0_PHASE0_QUANTUM__UNIT__SHIFT;
+ }
+
for (i = 0; i < adev->sdma.num_instances; i++) {
f32_cntl = RREG32(mmSDMA0_CNTL + sdma_offsets[i]);
- if (enable)
+ if (enable) {
f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
AUTO_CTXSW_ENABLE, 1);
- else
+ f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
+ ATC_L1_ENABLE, 1);
+ if (amdgpu_sdma_phase_quantum) {
+ WREG32(mmSDMA0_PHASE0_QUANTUM + sdma_offsets[i],
+ phase_quantum);
+ WREG32(mmSDMA0_PHASE1_QUANTUM + sdma_offsets[i],
+ phase_quantum);
+ }
+ } else {
f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
AUTO_CTXSW_ENABLE, 0);
+ f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
+ ATC_L1_ENABLE, 1);
+ }
+
WREG32(mmSDMA0_CNTL + sdma_offsets[i], f32_cntl);
}
}
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index 4a65697ccc94..fd7c72aaafa6 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -291,6 +291,8 @@ static void sdma_v4_0_ring_set_wptr(struct amdgpu_ring *ring)
DRM_DEBUG("Setting write pointer\n");
if (ring->use_doorbell) {
+ u64 *wb = (u64 *)&adev->wb.wb[ring->wptr_offs];
+
DRM_DEBUG("Using doorbell -- "
"wptr_offs == 0x%08x "
"lower_32_bits(ring->wptr) << 2 == 0x%08x "
@@ -299,8 +301,7 @@ static void sdma_v4_0_ring_set_wptr(struct amdgpu_ring *ring)
lower_32_bits(ring->wptr << 2),
upper_32_bits(ring->wptr << 2));
/* XXX check if swapping is necessary on BE */
- adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr << 2);
- adev->wb.wb[ring->wptr_offs + 1] = upper_32_bits(ring->wptr << 2);
+ WRITE_ONCE(*wb, (ring->wptr << 2));
DRM_DEBUG("calling WDOORBELL64(0x%08x, 0x%016llx)\n",
ring->doorbell_index, ring->wptr << 2);
WDOORBELL64(ring->doorbell_index, ring->wptr << 2);
@@ -493,13 +494,45 @@ static void sdma_v4_0_rlc_stop(struct amdgpu_device *adev)
*/
static void sdma_v4_0_ctx_switch_enable(struct amdgpu_device *adev, bool enable)
{
- u32 f32_cntl;
+ u32 f32_cntl, phase_quantum = 0;
int i;
+ if (amdgpu_sdma_phase_quantum) {
+ unsigned value = amdgpu_sdma_phase_quantum;
+ unsigned unit = 0;
+
+ while (value > (SDMA0_PHASE0_QUANTUM__VALUE_MASK >>
+ SDMA0_PHASE0_QUANTUM__VALUE__SHIFT)) {
+ value = (value + 1) >> 1;
+ unit++;
+ }
+ if (unit > (SDMA0_PHASE0_QUANTUM__UNIT_MASK >>
+ SDMA0_PHASE0_QUANTUM__UNIT__SHIFT)) {
+ value = (SDMA0_PHASE0_QUANTUM__VALUE_MASK >>
+ SDMA0_PHASE0_QUANTUM__VALUE__SHIFT);
+ unit = (SDMA0_PHASE0_QUANTUM__UNIT_MASK >>
+ SDMA0_PHASE0_QUANTUM__UNIT__SHIFT);
+ WARN_ONCE(1,
+ "clamping sdma_phase_quantum to %uK clock cycles\n",
+ value << unit);
+ }
+ phase_quantum =
+ value << SDMA0_PHASE0_QUANTUM__VALUE__SHIFT |
+ unit << SDMA0_PHASE0_QUANTUM__UNIT__SHIFT;
+ }
+
for (i = 0; i < adev->sdma.num_instances; i++) {
f32_cntl = RREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_CNTL));
f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
AUTO_CTXSW_ENABLE, enable ? 1 : 0);
+ if (enable && amdgpu_sdma_phase_quantum) {
+ WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_PHASE0_QUANTUM),
+ phase_quantum);
+ WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_PHASE1_QUANTUM),
+ phase_quantum);
+ WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_PHASE2_QUANTUM),
+ phase_quantum);
+ }
WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_CNTL), f32_cntl);
}
@@ -541,12 +574,13 @@ static void sdma_v4_0_enable(struct amdgpu_device *adev, bool enable)
static int sdma_v4_0_gfx_resume(struct amdgpu_device *adev)
{
struct amdgpu_ring *ring;
- u32 rb_cntl, ib_cntl;
+ u32 rb_cntl, ib_cntl, wptr_poll_cntl;
u32 rb_bufsz;
u32 wb_offset;
u32 doorbell;
u32 doorbell_offset;
u32 temp;
+ u64 wptr_gpu_addr;
int i, r;
for (i = 0; i < adev->sdma.num_instances; i++) {
@@ -628,6 +662,19 @@ static int sdma_v4_0_gfx_resume(struct amdgpu_device *adev)
WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_F32_CNTL), temp);
}
+ /* setup the wptr shadow polling */
+ wptr_gpu_addr = adev->wb.gpu_addr + (ring->wptr_offs * 4);
+ WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_ADDR_LO),
+ lower_32_bits(wptr_gpu_addr));
+ WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_ADDR_HI),
+ upper_32_bits(wptr_gpu_addr));
+ wptr_poll_cntl = RREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_CNTL));
+ if (amdgpu_sriov_vf(adev))
+ wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, SDMA0_GFX_RB_WPTR_POLL_CNTL, F32_POLL_ENABLE, 1);
+ else
+ wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, SDMA0_GFX_RB_WPTR_POLL_CNTL, F32_POLL_ENABLE, 0);
+ WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_CNTL), wptr_poll_cntl);
+
/* enable DMA RB */
rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 1);
WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_CNTL), rb_cntl);
@@ -655,6 +702,7 @@ static int sdma_v4_0_gfx_resume(struct amdgpu_device *adev)
if (adev->mman.buffer_funcs_ring == ring)
amdgpu_ttm_set_active_vram_size(adev, adev->mc.real_vram_size);
+
}
return 0;
@@ -751,15 +799,12 @@ static int sdma_v4_0_load_microcode(struct amdgpu_device *adev)
const struct sdma_firmware_header_v1_0 *hdr;
const __le32 *fw_data;
u32 fw_size;
- u32 digest_size = 0;
int i, j;
/* halt the MEs */
sdma_v4_0_enable(adev, false);
for (i = 0; i < adev->sdma.num_instances; i++) {
- uint16_t version_major;
- uint16_t version_minor;
if (!adev->sdma.instance[i].fw)
return -EINVAL;
@@ -767,23 +812,12 @@ static int sdma_v4_0_load_microcode(struct amdgpu_device *adev)
amdgpu_ucode_print_sdma_hdr(&hdr->header);
fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
- version_major = le16_to_cpu(hdr->header.header_version_major);
- version_minor = le16_to_cpu(hdr->header.header_version_minor);
-
- if (version_major == 1 && version_minor >= 1) {
- const struct sdma_firmware_header_v1_1 *sdma_v1_1_hdr = (const struct sdma_firmware_header_v1_1 *) hdr;
- digest_size = le32_to_cpu(sdma_v1_1_hdr->digest_size);
- }
-
- fw_size -= digest_size;
-
fw_data = (const __le32 *)
(adev->sdma.instance[i].fw->data +
le32_to_cpu(hdr->header.ucode_array_offset_bytes));
WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_UCODE_ADDR), 0);
-
for (j = 0; j < fw_size; j++)
WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_UCODE_DATA), le32_to_cpup(fw_data++));
diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c
index f45fb0f022b3..8284d5dbfc30 100644
--- a/drivers/gpu/drm/amd/amdgpu/si.c
+++ b/drivers/gpu/drm/amd/amdgpu/si.c
@@ -1150,6 +1150,33 @@ static bool si_read_disabled_bios(struct amdgpu_device *adev)
return r;
}
+#define mmROM_INDEX 0x2A
+#define mmROM_DATA 0x2B
+
+static bool si_read_bios_from_rom(struct amdgpu_device *adev,
+ u8 *bios, u32 length_bytes)
+{
+ u32 *dw_ptr;
+ u32 i, length_dw;
+
+ if (bios == NULL)
+ return false;
+ if (length_bytes == 0)
+ return false;
+ /* APU vbios image is part of sbios image */
+ if (adev->flags & AMD_IS_APU)
+ return false;
+
+ dw_ptr = (u32 *)bios;
+ length_dw = ALIGN(length_bytes, 4) / 4;
+ /* set rom index to 0 */
+ WREG32(mmROM_INDEX, 0);
+ for (i = 0; i < length_dw; i++)
+ dw_ptr[i] = RREG32(mmROM_DATA);
+
+ return true;
+}
+
//xxx: not implemented
static int si_asic_reset(struct amdgpu_device *adev)
{
@@ -1206,6 +1233,7 @@ static void si_detect_hw_virtualization(struct amdgpu_device *adev)
static const struct amdgpu_asic_funcs si_asic_funcs =
{
.read_disabled_bios = &si_read_disabled_bios,
+ .read_bios_from_rom = &si_read_bios_from_rom,
.read_register = &si_read_register,
.reset = &si_asic_reset,
.set_vga_state = &si_vga_set_state,
@@ -1385,6 +1413,7 @@ static void si_init_golden_registers(struct amdgpu_device *adev)
amdgpu_program_register_sequence(adev,
pitcairn_mgcg_cgcg_init,
(const u32)ARRAY_SIZE(pitcairn_mgcg_cgcg_init));
+ break;
case CHIP_VERDE:
amdgpu_program_register_sequence(adev,
verde_golden_registers,
@@ -1409,6 +1438,7 @@ static void si_init_golden_registers(struct amdgpu_device *adev)
amdgpu_program_register_sequence(adev,
oland_mgcg_cgcg_init,
(const u32)ARRAY_SIZE(oland_mgcg_cgcg_init));
+ break;
case CHIP_HAINAN:
amdgpu_program_register_sequence(adev,
hainan_golden_registers,
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
index a7ad8390981c..d63873f3f574 100644
--- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
@@ -2055,6 +2055,7 @@ static void si_initialize_powertune_defaults(struct amdgpu_device *adev)
case 0x682C:
si_pi->cac_weights = cac_weights_cape_verde_pro;
si_pi->dte_data = dte_data_sun_xt;
+ update_dte_from_pl2 = true;
break;
case 0x6825:
case 0x6827:
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
index a7341d88a320..f2c3a49f73a0 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -25,7 +25,7 @@
#include <linux/module.h>
#include <drm/drmP.h>
#include "amdgpu.h"
-#include "amdgpu_atomfirmware.h"
+#include "amdgpu_atombios.h"
#include "amdgpu_ih.h"
#include "amdgpu_uvd.h"
#include "amdgpu_vce.h"
@@ -62,8 +62,6 @@
#include "dce_virtual.h"
#include "mxgpu_ai.h"
-MODULE_FIRMWARE("amdgpu/vega10_smc.bin");
-
#define mmFabricConfigAccessControl 0x0410
#define mmFabricConfigAccessControl_BASE_IDX 0
#define mmFabricConfigAccessControl_DEFAULT 0x00000000
@@ -198,6 +196,50 @@ static void soc15_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
}
+static u32 soc15_gc_cac_rreg(struct amdgpu_device *adev, u32 reg)
+{
+ unsigned long flags;
+ u32 r;
+
+ spin_lock_irqsave(&adev->gc_cac_idx_lock, flags);
+ WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg));
+ r = RREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA);
+ spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags);
+ return r;
+}
+
+static void soc15_gc_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&adev->gc_cac_idx_lock, flags);
+ WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg));
+ WREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA, (v));
+ spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags);
+}
+
+static u32 soc15_se_cac_rreg(struct amdgpu_device *adev, u32 reg)
+{
+ unsigned long flags;
+ u32 r;
+
+ spin_lock_irqsave(&adev->se_cac_idx_lock, flags);
+ WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg));
+ r = RREG32_SOC15(GC, 0, mmSE_CAC_IND_DATA);
+ spin_unlock_irqrestore(&adev->se_cac_idx_lock, flags);
+ return r;
+}
+
+static void soc15_se_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&adev->se_cac_idx_lock, flags);
+ WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg));
+ WREG32_SOC15(GC, 0, mmSE_CAC_IND_DATA, (v));
+ spin_unlock_irqrestore(&adev->se_cac_idx_lock, flags);
+}
+
static u32 soc15_get_config_memsize(struct amdgpu_device *adev)
{
if (adev->flags & AMD_IS_APU)
@@ -392,11 +434,11 @@ static void soc15_gpu_pci_config_reset(struct amdgpu_device *adev)
static int soc15_asic_reset(struct amdgpu_device *adev)
{
- amdgpu_atomfirmware_scratch_regs_engine_hung(adev, true);
+ amdgpu_atombios_scratch_regs_engine_hung(adev, true);
soc15_gpu_pci_config_reset(adev);
- amdgpu_atomfirmware_scratch_regs_engine_hung(adev, false);
+ amdgpu_atombios_scratch_regs_engine_hung(adev, false);
return 0;
}
@@ -524,13 +566,6 @@ static uint32_t soc15_get_rev_id(struct amdgpu_device *adev)
return nbio_v6_1_get_rev_id(adev);
}
-
-int gmc_v9_0_mc_wait_for_idle(struct amdgpu_device *adev)
-{
- /* to be implemented in MC IP*/
- return 0;
-}
-
static const struct amdgpu_asic_funcs soc15_asic_funcs =
{
.read_disabled_bios = &soc15_read_disabled_bios,
@@ -557,6 +592,10 @@ static int soc15_common_early_init(void *handle)
adev->uvd_ctx_wreg = &soc15_uvd_ctx_wreg;
adev->didt_rreg = &soc15_didt_rreg;
adev->didt_wreg = &soc15_didt_wreg;
+ adev->gc_cac_rreg = &soc15_gc_cac_rreg;
+ adev->gc_cac_wreg = &soc15_gc_cac_wreg;
+ adev->se_cac_rreg = &soc15_se_cac_rreg;
+ adev->se_cac_wreg = &soc15_se_cac_wreg;
adev->asic_funcs = &soc15_asic_funcs;
@@ -681,6 +720,9 @@ static int soc15_common_hw_init(void *handle)
soc15_pcie_gen3_enable(adev);
/* enable aspm */
soc15_program_aspm(adev);
+ /* setup nbio registers */
+ if (!(adev->flags & AMD_IS_APU))
+ nbio_v6_1_init_registers(adev);
/* enable the doorbell aperture */
soc15_enable_doorbell_aperture(adev, true);
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15_common.h b/drivers/gpu/drm/amd/amdgpu/soc15_common.h
index e2d330eed952..7a8e4e28abb2 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15_common.h
+++ b/drivers/gpu/drm/amd/amdgpu/soc15_common.h
@@ -77,6 +77,13 @@ struct nbio_pcie_index_data {
(3 == reg##_BASE_IDX ? ip##_BASE__INST##inst##_SEG3 + reg : \
(ip##_BASE__INST##inst##_SEG4 + reg))))), value)
+#define WREG32_SOC15_NO_KIQ(ip, inst, reg, value) \
+ WREG32_NO_KIQ( (0 == reg##_BASE_IDX ? ip##_BASE__INST##inst##_SEG0 + reg : \
+ (1 == reg##_BASE_IDX ? ip##_BASE__INST##inst##_SEG1 + reg : \
+ (2 == reg##_BASE_IDX ? ip##_BASE__INST##inst##_SEG2 + reg : \
+ (3 == reg##_BASE_IDX ? ip##_BASE__INST##inst##_SEG3 + reg : \
+ (ip##_BASE__INST##inst##_SEG4 + reg))))), value)
+
#define WREG32_SOC15_OFFSET(ip, inst, reg, offset, value) \
WREG32( (0 == reg##_BASE_IDX ? ip##_BASE__INST##inst##_SEG0 + reg : \
(1 == reg##_BASE_IDX ? ip##_BASE__INST##inst##_SEG1 + reg : \
diff --git a/drivers/gpu/drm/amd/amdgpu/soc15d.h b/drivers/gpu/drm/amd/amdgpu/soc15d.h
index e79befd80eed..7f408f85fdb6 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15d.h
+++ b/drivers/gpu/drm/amd/amdgpu/soc15d.h
@@ -250,6 +250,7 @@
#define PACKET3_SET_UCONFIG_REG 0x79
#define PACKET3_SET_UCONFIG_REG_START 0x0000c000
#define PACKET3_SET_UCONFIG_REG_END 0x0000c400
+#define PACKET3_SET_UCONFIG_REG_INDEX_TYPE (2 << 28)
#define PACKET3_SCRATCH_RAM_WRITE 0x7D
#define PACKET3_SCRATCH_RAM_READ 0x7E
#define PACKET3_LOAD_CONST_RAM 0x80
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
index 987b958368ac..23a85750edd6 100644
--- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
@@ -165,6 +165,9 @@ static int uvd_v7_0_enc_ring_test_ring(struct amdgpu_ring *ring)
unsigned i;
int r;
+ if (amdgpu_sriov_vf(adev))
+ return 0;
+
r = amdgpu_ring_alloc(ring, 16);
if (r) {
DRM_ERROR("amdgpu: uvd enc failed to lock ring %d (%d).\n",
@@ -432,13 +435,19 @@ static int uvd_v7_0_sw_init(void *handle)
return r;
}
-
for (i = 0; i < adev->uvd.num_enc_rings; ++i) {
ring = &adev->uvd.ring_enc[i];
sprintf(ring->name, "uvd_enc%d", i);
if (amdgpu_sriov_vf(adev)) {
ring->use_doorbell = true;
- ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING0_1 * 2;
+
+ /* currently only use the first enconding ring for
+ * sriov, so set unused location for other unused rings.
+ */
+ if (i == 0)
+ ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING0_1 * 2;
+ else
+ ring->doorbell_index = AMDGPU_DOORBELL64_UVD_RING2_3 * 2 + 1;
}
r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.irq, 0);
if (r)
@@ -685,6 +694,11 @@ static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev,
/* 4, set resp to zero */
WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_RESP, 0);
+ WDOORBELL32(adev->uvd.ring_enc[0].doorbell_index, 0);
+ adev->wb.wb[adev->uvd.ring_enc[0].wptr_offs] = 0;
+ adev->uvd.ring_enc[0].wptr = 0;
+ adev->uvd.ring_enc[0].wptr_old = 0;
+
/* 5, kick off the initialization and wait until VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero */
WREG32_SOC15(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_HOST, 0x10000001);
@@ -702,7 +716,6 @@ static int uvd_v7_0_mmsch_start(struct amdgpu_device *adev,
dev_err(adev->dev, "failed to init MMSCH, mmVCE_MMSCH_VF_MAILBOX_RESP = %x\n", data);
return -EBUSY;
}
- WDOORBELL32(adev->uvd.ring_enc[0].doorbell_index, 0);
return 0;
}
@@ -736,11 +749,9 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev)
init_table += header->uvd_table_offset;
ring = &adev->uvd.ring;
+ ring->wptr = 0;
size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4);
- /* disable clock gating */
- MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS),
- ~UVD_POWER_STATUS__UVD_PG_MODE_MASK, 0);
MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS),
0xFFFFFFFF, 0x00000004);
/* mc resume*/
@@ -777,12 +788,6 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev)
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE2),
AMDGPU_UVD_STACK_SIZE + (AMDGPU_UVD_SESSION_SIZE * 40));
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_UDEC_ADDR_CONFIG),
- adev->gfx.config.gb_addr_config);
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_UDEC_DB_ADDR_CONFIG),
- adev->gfx.config.gb_addr_config);
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_UDEC_DBW_ADDR_CONFIG),
- adev->gfx.config.gb_addr_config);
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_GP_SCRATCH4), adev->uvd.max_handles);
/* mc resume end*/
@@ -819,17 +824,6 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev)
UVD_LMI_CTRL__REQ_MODE_MASK |
0x00100000L));
- /* disable byte swapping */
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_SWAP_CNTL), 0);
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MP_SWAP_CNTL), 0);
-
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_MUXA0), 0x40c2040);
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_MUXA1), 0x0);
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_MUXB0), 0x40c2040);
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_MUXB1), 0x0);
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_ALU), 0);
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MPC_SET_MUX), 0x88);
-
/* take all subblocks out of reset, except VCPU */
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
@@ -838,15 +832,6 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev)
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CNTL),
UVD_VCPU_CNTL__CLK_EN_MASK);
- /* enable UMC */
- MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2),
- ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, 0);
-
- /* boot up the VCPU */
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0);
-
- MMSCH_V1_0_INSERT_DIRECT_POLL(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), 0x02, 0x02);
-
/* enable master interrupt */
MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN),
~(UVD_MASTINT_EN__VCPU_EN_MASK|UVD_MASTINT_EN__SYS_EN_MASK),
@@ -859,40 +844,31 @@ static int uvd_v7_0_sriov_start(struct amdgpu_device *adev)
/* force RBC into idle state */
size = order_base_2(ring->ring_size);
tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, size);
- tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
- tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0);
- tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
- tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), tmp);
- /* set the write pointer delay */
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_WPTR_CNTL), 0);
-
- /* set the wb address */
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_RPTR_ADDR),
- (upper_32_bits(ring->gpu_addr) >> 2));
-
- /* programm the RB_BASE for ring buffer */
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW),
- lower_32_bits(ring->gpu_addr));
- MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH),
- upper_32_bits(ring->gpu_addr));
-
- ring->wptr = 0;
ring = &adev->uvd.ring_enc[0];
+ ring->wptr = 0;
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_BASE_LO), ring->gpu_addr);
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_BASE_HI), upper_32_bits(ring->gpu_addr));
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_SIZE), ring->ring_size / 4);
+ /* boot up the VCPU */
+ MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0);
+
+ /* enable UMC */
+ MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2),
+ ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK, 0);
+
+ MMSCH_V1_0_INSERT_DIRECT_POLL(SOC15_REG_OFFSET(UVD, 0, mmUVD_STATUS), 0x02, 0x02);
+
/* add end packet */
memcpy((void *)init_table, &end, sizeof(struct mmsch_v1_0_cmd_end));
table_size += sizeof(struct mmsch_v1_0_cmd_end) / 4;
header->uvd_table_size = table_size;
- return uvd_v7_0_mmsch_start(adev, &adev->virt.mm_table);
}
- return -EINVAL; /* already initializaed ? */
+ return uvd_v7_0_mmsch_start(adev, &adev->virt.mm_table);
}
/**
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
index 1ecd6bb90c1f..11134d5f7443 100644
--- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
@@ -173,6 +173,11 @@ static int vce_v4_0_mmsch_start(struct amdgpu_device *adev,
/* 4, set resp to zero */
WREG32(SOC15_REG_OFFSET(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_RESP), 0);
+ WDOORBELL32(adev->vce.ring[0].doorbell_index, 0);
+ adev->wb.wb[adev->vce.ring[0].wptr_offs] = 0;
+ adev->vce.ring[0].wptr = 0;
+ adev->vce.ring[0].wptr_old = 0;
+
/* 5, kick off the initialization and wait until VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero */
WREG32(SOC15_REG_OFFSET(VCE, 0, mmVCE_MMSCH_VF_MAILBOX_HOST), 0x10000001);
@@ -190,7 +195,6 @@ static int vce_v4_0_mmsch_start(struct amdgpu_device *adev,
dev_err(adev->dev, "failed to init MMSCH, mmVCE_MMSCH_VF_MAILBOX_RESP = %x\n", data);
return -EBUSY;
}
- WDOORBELL32(adev->vce.ring[0].doorbell_index, 0);
return 0;
}
@@ -274,7 +278,8 @@ static int vce_v4_0_sriov_start(struct amdgpu_device *adev)
MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_LMI_CTRL2), ~0x100, 0);
MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_SYS_INT_EN),
- 0xffffffff, VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
+ VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK,
+ VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
/* end of MC_RESUME */
MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_STATUS),
@@ -296,11 +301,9 @@ static int vce_v4_0_sriov_start(struct amdgpu_device *adev)
memcpy((void *)init_table, &end, sizeof(struct mmsch_v1_0_cmd_end));
table_size += sizeof(struct mmsch_v1_0_cmd_end) / 4;
header->vce_table_size = table_size;
-
- return vce_v4_0_mmsch_start(adev, &adev->virt.mm_table);
}
- return -EINVAL; /* already initializaed ? */
+ return vce_v4_0_mmsch_start(adev, &adev->virt.mm_table);
}
/**
@@ -443,12 +446,14 @@ static int vce_v4_0_sw_init(void *handle)
if (amdgpu_sriov_vf(adev)) {
/* DOORBELL only works under SRIOV */
ring->use_doorbell = true;
+
+ /* currently only use the first encoding ring for sriov,
+ * so set unused location for other unused rings.
+ */
if (i == 0)
- ring->doorbell_index = AMDGPU_DOORBELL64_RING0_1 * 2;
- else if (i == 1)
- ring->doorbell_index = AMDGPU_DOORBELL64_RING2_3 * 2;
+ ring->doorbell_index = AMDGPU_DOORBELL64_VCE_RING0_1 * 2;
else
- ring->doorbell_index = AMDGPU_DOORBELL64_RING2_3 * 2 + 1;
+ ring->doorbell_index = AMDGPU_DOORBELL64_VCE_RING2_3 * 2 + 1;
}
r = amdgpu_ring_init(adev, ring, 512, &adev->vce.irq, 0);
if (r)
@@ -990,11 +995,13 @@ static int vce_v4_0_set_interrupt_state(struct amdgpu_device *adev,
{
uint32_t val = 0;
- if (state == AMDGPU_IRQ_STATE_ENABLE)
- val |= VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK;
+ if (!amdgpu_sriov_vf(adev)) {
+ if (state == AMDGPU_IRQ_STATE_ENABLE)
+ val |= VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK;
- WREG32_P(SOC15_REG_OFFSET(VCE, 0, mmVCE_SYS_INT_EN), val,
- ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
+ WREG32_P(SOC15_REG_OFFSET(VCE, 0, mmVCE_SYS_INT_EN), val,
+ ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
+ }
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index 6cac291c96da..9ff69b90df36 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -1028,8 +1028,7 @@ static int vi_common_early_init(void *handle)
/* rev0 hardware requires workarounds to support PG */
adev->pg_flags = 0;
if (adev->rev_id != 0x00 || CZ_REV_BRISTOL(adev->pdev->revision)) {
- adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
- AMD_PG_SUPPORT_GFX_SMG |
+ adev->pg_flags |= AMD_PG_SUPPORT_GFX_SMG |
AMD_PG_SUPPORT_GFX_PIPELINE |
AMD_PG_SUPPORT_CP |
AMD_PG_SUPPORT_UVD |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index 6316aad43a73..e4a8c2e52cb2 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -142,12 +142,12 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
struct kfd_ioctl_create_queue_args *args)
{
if (args->queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) {
- pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n");
+ pr_err("Queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n");
return -EINVAL;
}
if (args->queue_priority > KFD_MAX_QUEUE_PRIORITY) {
- pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n");
+ pr_err("Queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n");
return -EINVAL;
}
@@ -155,26 +155,26 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
(!access_ok(VERIFY_WRITE,
(const void __user *) args->ring_base_address,
sizeof(uint64_t)))) {
- pr_err("kfd: can't access ring base address\n");
+ pr_err("Can't access ring base address\n");
return -EFAULT;
}
if (!is_power_of_2(args->ring_size) && (args->ring_size != 0)) {
- pr_err("kfd: ring size must be a power of 2 or 0\n");
+ pr_err("Ring size must be a power of 2 or 0\n");
return -EINVAL;
}
if (!access_ok(VERIFY_WRITE,
(const void __user *) args->read_pointer_address,
sizeof(uint32_t))) {
- pr_err("kfd: can't access read pointer\n");
+ pr_err("Can't access read pointer\n");
return -EFAULT;
}
if (!access_ok(VERIFY_WRITE,
(const void __user *) args->write_pointer_address,
sizeof(uint32_t))) {
- pr_err("kfd: can't access write pointer\n");
+ pr_err("Can't access write pointer\n");
return -EFAULT;
}
@@ -182,7 +182,7 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
!access_ok(VERIFY_WRITE,
(const void __user *) args->eop_buffer_address,
sizeof(uint32_t))) {
- pr_debug("kfd: can't access eop buffer");
+ pr_debug("Can't access eop buffer");
return -EFAULT;
}
@@ -190,7 +190,7 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
!access_ok(VERIFY_WRITE,
(const void __user *) args->ctx_save_restore_address,
sizeof(uint32_t))) {
- pr_debug("kfd: can't access ctx save restore buffer");
+ pr_debug("Can't access ctx save restore buffer");
return -EFAULT;
}
@@ -219,27 +219,27 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
else
q_properties->format = KFD_QUEUE_FORMAT_PM4;
- pr_debug("Queue Percentage (%d, %d)\n",
+ pr_debug("Queue Percentage: %d, %d\n",
q_properties->queue_percent, args->queue_percentage);
- pr_debug("Queue Priority (%d, %d)\n",
+ pr_debug("Queue Priority: %d, %d\n",
q_properties->priority, args->queue_priority);
- pr_debug("Queue Address (0x%llX, 0x%llX)\n",
+ pr_debug("Queue Address: 0x%llX, 0x%llX\n",
q_properties->queue_address, args->ring_base_address);
- pr_debug("Queue Size (0x%llX, %u)\n",
+ pr_debug("Queue Size: 0x%llX, %u\n",
q_properties->queue_size, args->ring_size);
- pr_debug("Queue r/w Pointers (0x%llX, 0x%llX)\n",
- (uint64_t) q_properties->read_ptr,
- (uint64_t) q_properties->write_ptr);
+ pr_debug("Queue r/w Pointers: %p, %p\n",
+ q_properties->read_ptr,
+ q_properties->write_ptr);
- pr_debug("Queue Format (%d)\n", q_properties->format);
+ pr_debug("Queue Format: %d\n", q_properties->format);
- pr_debug("Queue EOP (0x%llX)\n", q_properties->eop_ring_buffer_address);
+ pr_debug("Queue EOP: 0x%llX\n", q_properties->eop_ring_buffer_address);
- pr_debug("Queue CTX save arex (0x%llX)\n",
+ pr_debug("Queue CTX save area: 0x%llX\n",
q_properties->ctx_save_restore_area_address);
return 0;
@@ -257,16 +257,16 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
memset(&q_properties, 0, sizeof(struct queue_properties));
- pr_debug("kfd: creating queue ioctl\n");
+ pr_debug("Creating queue ioctl\n");
err = set_queue_properties_from_user(&q_properties, args);
if (err)
return err;
- pr_debug("kfd: looking for gpu id 0x%x\n", args->gpu_id);
+ pr_debug("Looking for gpu id 0x%x\n", args->gpu_id);
dev = kfd_device_by_id(args->gpu_id);
- if (dev == NULL) {
- pr_debug("kfd: gpu id 0x%x was not found\n", args->gpu_id);
+ if (!dev) {
+ pr_debug("Could not find gpu id 0x%x\n", args->gpu_id);
return -EINVAL;
}
@@ -278,7 +278,7 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
goto err_bind_process;
}
- pr_debug("kfd: creating queue for PASID %d on GPU 0x%x\n",
+ pr_debug("Creating queue for PASID %d on gpu 0x%x\n",
p->pasid,
dev->id);
@@ -296,15 +296,15 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
mutex_unlock(&p->mutex);
- pr_debug("kfd: queue id %d was created successfully\n", args->queue_id);
+ pr_debug("Queue id %d was created successfully\n", args->queue_id);
- pr_debug("ring buffer address == 0x%016llX\n",
+ pr_debug("Ring buffer address == 0x%016llX\n",
args->ring_base_address);
- pr_debug("read ptr address == 0x%016llX\n",
+ pr_debug("Read ptr address == 0x%016llX\n",
args->read_pointer_address);
- pr_debug("write ptr address == 0x%016llX\n",
+ pr_debug("Write ptr address == 0x%016llX\n",
args->write_pointer_address);
return 0;
@@ -321,7 +321,7 @@ static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p,
int retval;
struct kfd_ioctl_destroy_queue_args *args = data;
- pr_debug("kfd: destroying queue id %d for PASID %d\n",
+ pr_debug("Destroying queue id %d for pasid %d\n",
args->queue_id,
p->pasid);
@@ -341,12 +341,12 @@ static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p,
struct queue_properties properties;
if (args->queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) {
- pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n");
+ pr_err("Queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n");
return -EINVAL;
}
if (args->queue_priority > KFD_MAX_QUEUE_PRIORITY) {
- pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n");
+ pr_err("Queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n");
return -EINVAL;
}
@@ -354,12 +354,12 @@ static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p,
(!access_ok(VERIFY_WRITE,
(const void __user *) args->ring_base_address,
sizeof(uint64_t)))) {
- pr_err("kfd: can't access ring base address\n");
+ pr_err("Can't access ring base address\n");
return -EFAULT;
}
if (!is_power_of_2(args->ring_size) && (args->ring_size != 0)) {
- pr_err("kfd: ring size must be a power of 2 or 0\n");
+ pr_err("Ring size must be a power of 2 or 0\n");
return -EINVAL;
}
@@ -368,7 +368,7 @@ static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p,
properties.queue_percent = args->queue_percentage;
properties.priority = args->queue_priority;
- pr_debug("kfd: updating queue id %d for PASID %d\n",
+ pr_debug("Updating queue id %d for pasid %d\n",
args->queue_id, p->pasid);
mutex_lock(&p->mutex);
@@ -400,7 +400,7 @@ static int kfd_ioctl_set_memory_policy(struct file *filep,
}
dev = kfd_device_by_id(args->gpu_id);
- if (dev == NULL)
+ if (!dev)
return -EINVAL;
mutex_lock(&p->mutex);
@@ -443,7 +443,7 @@ static int kfd_ioctl_dbg_register(struct file *filep,
long status = 0;
dev = kfd_device_by_id(args->gpu_id);
- if (dev == NULL)
+ if (!dev)
return -EINVAL;
if (dev->device_info->asic_family == CHIP_CARRIZO) {
@@ -460,12 +460,11 @@ static int kfd_ioctl_dbg_register(struct file *filep,
*/
pdd = kfd_bind_process_to_device(dev, p);
if (IS_ERR(pdd)) {
- mutex_unlock(&p->mutex);
- mutex_unlock(kfd_get_dbgmgr_mutex());
- return PTR_ERR(pdd);
+ status = PTR_ERR(pdd);
+ goto out;
}
- if (dev->dbgmgr == NULL) {
+ if (!dev->dbgmgr) {
/* In case of a legal call, we have no dbgmgr yet */
create_ok = kfd_dbgmgr_create(&dbgmgr_ptr, dev);
if (create_ok) {
@@ -480,6 +479,7 @@ static int kfd_ioctl_dbg_register(struct file *filep,
status = -EINVAL;
}
+out:
mutex_unlock(&p->mutex);
mutex_unlock(kfd_get_dbgmgr_mutex());
@@ -494,7 +494,7 @@ static int kfd_ioctl_dbg_unregister(struct file *filep,
long status;
dev = kfd_device_by_id(args->gpu_id);
- if (dev == NULL)
+ if (!dev)
return -EINVAL;
if (dev->device_info->asic_family == CHIP_CARRIZO) {
@@ -505,7 +505,7 @@ static int kfd_ioctl_dbg_unregister(struct file *filep,
mutex_lock(kfd_get_dbgmgr_mutex());
status = kfd_dbgmgr_unregister(dev->dbgmgr, p);
- if (status == 0) {
+ if (!status) {
kfd_dbgmgr_destroy(dev->dbgmgr);
dev->dbgmgr = NULL;
}
@@ -539,7 +539,7 @@ static int kfd_ioctl_dbg_address_watch(struct file *filep,
memset((void *) &aw_info, 0, sizeof(struct dbg_address_watch_info));
dev = kfd_device_by_id(args->gpu_id);
- if (dev == NULL)
+ if (!dev)
return -EINVAL;
if (dev->device_info->asic_family == CHIP_CARRIZO) {
@@ -580,8 +580,8 @@ static int kfd_ioctl_dbg_address_watch(struct file *filep,
args_idx += sizeof(aw_info.watch_address) * aw_info.num_watch_points;
if (args_idx >= args->buf_size_in_bytes - sizeof(*args)) {
- kfree(args_buff);
- return -EINVAL;
+ status = -EINVAL;
+ goto out;
}
watch_mask_value = (uint64_t) args_buff[args_idx];
@@ -604,8 +604,8 @@ static int kfd_ioctl_dbg_address_watch(struct file *filep,
}
if (args_idx >= args->buf_size_in_bytes - sizeof(args)) {
- kfree(args_buff);
- return -EINVAL;
+ status = -EINVAL;
+ goto out;
}
/* Currently HSA Event is not supported for DBG */
@@ -617,6 +617,7 @@ static int kfd_ioctl_dbg_address_watch(struct file *filep,
mutex_unlock(kfd_get_dbgmgr_mutex());
+out:
kfree(args_buff);
return status;
@@ -646,7 +647,7 @@ static int kfd_ioctl_dbg_wave_control(struct file *filep,
sizeof(wac_info.trapId);
dev = kfd_device_by_id(args->gpu_id);
- if (dev == NULL)
+ if (!dev)
return -EINVAL;
if (dev->device_info->asic_family == CHIP_CARRIZO) {
@@ -782,8 +783,9 @@ static int kfd_ioctl_get_process_apertures(struct file *filp,
"scratch_limit %llX\n", pdd->scratch_limit);
args->num_of_nodes++;
- } while ((pdd = kfd_get_next_process_device_data(p, pdd)) != NULL &&
- (args->num_of_nodes < NUM_OF_SUPPORTED_GPUS));
+
+ pdd = kfd_get_next_process_device_data(p, pdd);
+ } while (pdd && (args->num_of_nodes < NUM_OF_SUPPORTED_GPUS));
}
mutex_unlock(&p->mutex);
@@ -846,9 +848,84 @@ static int kfd_ioctl_wait_events(struct file *filp, struct kfd_process *p,
return err;
}
+static int kfd_ioctl_set_scratch_backing_va(struct file *filep,
+ struct kfd_process *p, void *data)
+{
+ struct kfd_ioctl_set_scratch_backing_va_args *args = data;
+ struct kfd_process_device *pdd;
+ struct kfd_dev *dev;
+ long err;
+
+ dev = kfd_device_by_id(args->gpu_id);
+ if (!dev)
+ return -EINVAL;
+
+ mutex_lock(&p->mutex);
+
+ pdd = kfd_bind_process_to_device(dev, p);
+ if (IS_ERR(pdd)) {
+ err = PTR_ERR(pdd);
+ goto bind_process_to_device_fail;
+ }
+
+ pdd->qpd.sh_hidden_private_base = args->va_addr;
+
+ mutex_unlock(&p->mutex);
+
+ if (sched_policy == KFD_SCHED_POLICY_NO_HWS && pdd->qpd.vmid != 0)
+ dev->kfd2kgd->set_scratch_backing_va(
+ dev->kgd, args->va_addr, pdd->qpd.vmid);
+
+ return 0;
+
+bind_process_to_device_fail:
+ mutex_unlock(&p->mutex);
+ return err;
+}
+
+static int kfd_ioctl_get_tile_config(struct file *filep,
+ struct kfd_process *p, void *data)
+{
+ struct kfd_ioctl_get_tile_config_args *args = data;
+ struct kfd_dev *dev;
+ struct tile_config config;
+ int err = 0;
+
+ dev = kfd_device_by_id(args->gpu_id);
+
+ dev->kfd2kgd->get_tile_config(dev->kgd, &config);
+
+ args->gb_addr_config = config.gb_addr_config;
+ args->num_banks = config.num_banks;
+ args->num_ranks = config.num_ranks;
+
+ if (args->num_tile_configs > config.num_tile_configs)
+ args->num_tile_configs = config.num_tile_configs;
+ err = copy_to_user((void __user *)args->tile_config_ptr,
+ config.tile_config_ptr,
+ args->num_tile_configs * sizeof(uint32_t));
+ if (err) {
+ args->num_tile_configs = 0;
+ return -EFAULT;
+ }
+
+ if (args->num_macro_tile_configs > config.num_macro_tile_configs)
+ args->num_macro_tile_configs =
+ config.num_macro_tile_configs;
+ err = copy_to_user((void __user *)args->macro_tile_config_ptr,
+ config.macro_tile_config_ptr,
+ args->num_macro_tile_configs * sizeof(uint32_t));
+ if (err) {
+ args->num_macro_tile_configs = 0;
+ return -EFAULT;
+ }
+
+ return 0;
+}
#define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \
- [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl}
+ [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, \
+ .cmd_drv = 0, .name = #ioctl}
/** Ioctl table */
static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
@@ -899,6 +976,12 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_WAVE_CONTROL,
kfd_ioctl_dbg_wave_control, 0),
+
+ AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_SCRATCH_BACKING_VA,
+ kfd_ioctl_set_scratch_backing_va, 0),
+
+ AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_TILE_CONFIG,
+ kfd_ioctl_get_tile_config, 0)
};
#define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c
index d5e19b5fbbfb..0aa021aa0aa1 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c
@@ -42,8 +42,6 @@
static void dbgdev_address_watch_disable_nodiq(struct kfd_dev *dev)
{
- BUG_ON(!dev || !dev->kfd2kgd);
-
dev->kfd2kgd->address_watch_disable(dev->kgd);
}
@@ -62,7 +60,8 @@ static int dbgdev_diq_submit_ib(struct kfd_dbgdev *dbgdev,
unsigned int *ib_packet_buff;
int status;
- BUG_ON(!dbgdev || !dbgdev->kq || !packet_buff || !size_in_bytes);
+ if (WARN_ON(!size_in_bytes))
+ return -EINVAL;
kq = dbgdev->kq;
@@ -77,8 +76,8 @@ static int dbgdev_diq_submit_ib(struct kfd_dbgdev *dbgdev,
status = kq->ops.acquire_packet_buffer(kq,
pq_packets_size_in_bytes / sizeof(uint32_t),
&ib_packet_buff);
- if (status != 0) {
- pr_err("amdkfd: acquire_packet_buffer failed\n");
+ if (status) {
+ pr_err("acquire_packet_buffer failed\n");
return status;
}
@@ -115,8 +114,8 @@ static int dbgdev_diq_submit_ib(struct kfd_dbgdev *dbgdev,
status = kfd_gtt_sa_allocate(dbgdev->dev, sizeof(uint64_t),
&mem_obj);
- if (status != 0) {
- pr_err("amdkfd: Failed to allocate GART memory\n");
+ if (status) {
+ pr_err("Failed to allocate GART memory\n");
kq->ops.rollback_packet(kq);
return status;
}
@@ -168,8 +167,6 @@ static int dbgdev_diq_submit_ib(struct kfd_dbgdev *dbgdev,
static int dbgdev_register_nodiq(struct kfd_dbgdev *dbgdev)
{
- BUG_ON(!dbgdev);
-
/*
* no action is needed in this case,
* just make sure diq will not be used
@@ -187,14 +184,12 @@ static int dbgdev_register_diq(struct kfd_dbgdev *dbgdev)
struct kernel_queue *kq = NULL;
int status;
- BUG_ON(!dbgdev || !dbgdev->pqm || !dbgdev->dev);
-
status = pqm_create_queue(dbgdev->pqm, dbgdev->dev, NULL,
&properties, 0, KFD_QUEUE_TYPE_DIQ,
&qid);
if (status) {
- pr_err("amdkfd: Failed to create DIQ\n");
+ pr_err("Failed to create DIQ\n");
return status;
}
@@ -202,8 +197,8 @@ static int dbgdev_register_diq(struct kfd_dbgdev *dbgdev)
kq = pqm_get_kernel_queue(dbgdev->pqm, qid);
- if (kq == NULL) {
- pr_err("amdkfd: Error getting DIQ\n");
+ if (!kq) {
+ pr_err("Error getting DIQ\n");
pqm_destroy_queue(dbgdev->pqm, qid);
return -EFAULT;
}
@@ -215,8 +210,6 @@ static int dbgdev_register_diq(struct kfd_dbgdev *dbgdev)
static int dbgdev_unregister_nodiq(struct kfd_dbgdev *dbgdev)
{
- BUG_ON(!dbgdev || !dbgdev->dev);
-
/* disable watch address */
dbgdev_address_watch_disable_nodiq(dbgdev->dev);
return 0;
@@ -227,8 +220,6 @@ static int dbgdev_unregister_diq(struct kfd_dbgdev *dbgdev)
/* todo - disable address watch */
int status;
- BUG_ON(!dbgdev || !dbgdev->pqm || !dbgdev->kq);
-
status = pqm_destroy_queue(dbgdev->pqm,
dbgdev->kq->queue->properties.queue_id);
dbgdev->kq = NULL;
@@ -245,14 +236,12 @@ static void dbgdev_address_watch_set_registers(
{
union ULARGE_INTEGER addr;
- BUG_ON(!adw_info || !addrHi || !addrLo || !cntl);
-
addr.quad_part = 0;
addrHi->u32All = 0;
addrLo->u32All = 0;
cntl->u32All = 0;
- if (adw_info->watch_mask != NULL)
+ if (adw_info->watch_mask)
cntl->bitfields.mask =
(uint32_t) (adw_info->watch_mask[index] &
ADDRESS_WATCH_REG_CNTL_DEFAULT_MASK);
@@ -279,7 +268,7 @@ static void dbgdev_address_watch_set_registers(
}
static int dbgdev_address_watch_nodiq(struct kfd_dbgdev *dbgdev,
- struct dbg_address_watch_info *adw_info)
+ struct dbg_address_watch_info *adw_info)
{
union TCP_WATCH_ADDR_H_BITS addrHi;
union TCP_WATCH_ADDR_L_BITS addrLo;
@@ -287,13 +276,11 @@ static int dbgdev_address_watch_nodiq(struct kfd_dbgdev *dbgdev,
struct kfd_process_device *pdd;
unsigned int i;
- BUG_ON(!dbgdev || !dbgdev->dev || !adw_info);
-
/* taking the vmid for that process on the safe way using pdd */
pdd = kfd_get_process_device_data(dbgdev->dev,
adw_info->process);
if (!pdd) {
- pr_err("amdkfd: Failed to get pdd for wave control no DIQ\n");
+ pr_err("Failed to get pdd for wave control no DIQ\n");
return -EFAULT;
}
@@ -303,17 +290,16 @@ static int dbgdev_address_watch_nodiq(struct kfd_dbgdev *dbgdev,
if ((adw_info->num_watch_points > MAX_WATCH_ADDRESSES) ||
(adw_info->num_watch_points == 0)) {
- pr_err("amdkfd: num_watch_points is invalid\n");
+ pr_err("num_watch_points is invalid\n");
return -EINVAL;
}
- if ((adw_info->watch_mode == NULL) ||
- (adw_info->watch_address == NULL)) {
- pr_err("amdkfd: adw_info fields are not valid\n");
+ if (!adw_info->watch_mode || !adw_info->watch_address) {
+ pr_err("adw_info fields are not valid\n");
return -EINVAL;
}
- for (i = 0 ; i < adw_info->num_watch_points ; i++) {
+ for (i = 0; i < adw_info->num_watch_points; i++) {
dbgdev_address_watch_set_registers(adw_info, &addrHi, &addrLo,
&cntl, i, pdd->qpd.vmid);
@@ -348,7 +334,7 @@ static int dbgdev_address_watch_nodiq(struct kfd_dbgdev *dbgdev,
}
static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
- struct dbg_address_watch_info *adw_info)
+ struct dbg_address_watch_info *adw_info)
{
struct pm4__set_config_reg *packets_vec;
union TCP_WATCH_ADDR_H_BITS addrHi;
@@ -363,28 +349,25 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
/* we do not control the vmid in DIQ mode, just a place holder */
unsigned int vmid = 0;
- BUG_ON(!dbgdev || !dbgdev->dev || !adw_info);
-
addrHi.u32All = 0;
addrLo.u32All = 0;
cntl.u32All = 0;
if ((adw_info->num_watch_points > MAX_WATCH_ADDRESSES) ||
(adw_info->num_watch_points == 0)) {
- pr_err("amdkfd: num_watch_points is invalid\n");
+ pr_err("num_watch_points is invalid\n");
return -EINVAL;
}
- if ((NULL == adw_info->watch_mode) ||
- (NULL == adw_info->watch_address)) {
- pr_err("amdkfd: adw_info fields are not valid\n");
+ if (!adw_info->watch_mode || !adw_info->watch_address) {
+ pr_err("adw_info fields are not valid\n");
return -EINVAL;
}
status = kfd_gtt_sa_allocate(dbgdev->dev, ib_size, &mem_obj);
- if (status != 0) {
- pr_err("amdkfd: Failed to allocate GART memory\n");
+ if (status) {
+ pr_err("Failed to allocate GART memory\n");
return status;
}
@@ -442,8 +425,6 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
i,
ADDRESS_WATCH_REG_CNTL);
- aw_reg_add_dword /= sizeof(uint32_t);
-
packets_vec[0].bitfields2.reg_offset =
aw_reg_add_dword - AMD_CONFIG_REG_BASE;
@@ -455,8 +436,6 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
i,
ADDRESS_WATCH_REG_ADDR_HI);
- aw_reg_add_dword /= sizeof(uint32_t);
-
packets_vec[1].bitfields2.reg_offset =
aw_reg_add_dword - AMD_CONFIG_REG_BASE;
packets_vec[1].reg_data[0] = addrHi.u32All;
@@ -467,8 +446,6 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
i,
ADDRESS_WATCH_REG_ADDR_LO);
- aw_reg_add_dword /= sizeof(uint32_t);
-
packets_vec[2].bitfields2.reg_offset =
aw_reg_add_dword - AMD_CONFIG_REG_BASE;
packets_vec[2].reg_data[0] = addrLo.u32All;
@@ -485,8 +462,6 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
i,
ADDRESS_WATCH_REG_CNTL);
- aw_reg_add_dword /= sizeof(uint32_t);
-
packets_vec[3].bitfields2.reg_offset =
aw_reg_add_dword - AMD_CONFIG_REG_BASE;
packets_vec[3].reg_data[0] = cntl.u32All;
@@ -498,8 +473,8 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev,
packet_buff_uint,
ib_size);
- if (status != 0) {
- pr_err("amdkfd: Failed to submit IB to DIQ\n");
+ if (status) {
+ pr_err("Failed to submit IB to DIQ\n");
break;
}
}
@@ -518,8 +493,6 @@ static int dbgdev_wave_control_set_registers(
union GRBM_GFX_INDEX_BITS reg_gfx_index;
struct HsaDbgWaveMsgAMDGen2 *pMsg;
- BUG_ON(!wac_info || !in_reg_sq_cmd || !in_reg_gfx_index);
-
reg_sq_cmd.u32All = 0;
reg_gfx_index.u32All = 0;
pMsg = &wac_info->dbgWave_msg.DbgWaveMsg.WaveMsgInfoGen2;
@@ -620,18 +593,16 @@ static int dbgdev_wave_control_diq(struct kfd_dbgdev *dbgdev,
struct pm4__set_config_reg *packets_vec;
size_t ib_size = sizeof(struct pm4__set_config_reg) * 3;
- BUG_ON(!dbgdev || !wac_info);
-
reg_sq_cmd.u32All = 0;
status = dbgdev_wave_control_set_registers(wac_info, &reg_sq_cmd,
&reg_gfx_index);
if (status) {
- pr_err("amdkfd: Failed to set wave control registers\n");
+ pr_err("Failed to set wave control registers\n");
return status;
}
- /* we do not control the VMID in DIQ,so reset it to a known value */
+ /* we do not control the VMID in DIQ, so reset it to a known value */
reg_sq_cmd.bits.vm_id = 0;
pr_debug("\t\t %30s\n", "* * * * * * * * * * * * * * * * * *");
@@ -667,7 +638,7 @@ static int dbgdev_wave_control_diq(struct kfd_dbgdev *dbgdev,
status = kfd_gtt_sa_allocate(dbgdev->dev, ib_size, &mem_obj);
if (status != 0) {
- pr_err("amdkfd: Failed to allocate GART memory\n");
+ pr_err("Failed to allocate GART memory\n");
return status;
}
@@ -719,8 +690,8 @@ static int dbgdev_wave_control_diq(struct kfd_dbgdev *dbgdev,
packet_buff_uint,
ib_size);
- if (status != 0)
- pr_err("amdkfd: Failed to submit IB to DIQ\n");
+ if (status)
+ pr_err("Failed to submit IB to DIQ\n");
kfd_gtt_sa_free(dbgdev->dev, mem_obj);
@@ -735,21 +706,19 @@ static int dbgdev_wave_control_nodiq(struct kfd_dbgdev *dbgdev,
union GRBM_GFX_INDEX_BITS reg_gfx_index;
struct kfd_process_device *pdd;
- BUG_ON(!dbgdev || !dbgdev->dev || !wac_info);
-
reg_sq_cmd.u32All = 0;
/* taking the VMID for that process on the safe way using PDD */
pdd = kfd_get_process_device_data(dbgdev->dev, wac_info->process);
if (!pdd) {
- pr_err("amdkfd: Failed to get pdd for wave control no DIQ\n");
+ pr_err("Failed to get pdd for wave control no DIQ\n");
return -EFAULT;
}
status = dbgdev_wave_control_set_registers(wac_info, &reg_sq_cmd,
&reg_gfx_index);
if (status) {
- pr_err("amdkfd: Failed to set wave control registers\n");
+ pr_err("Failed to set wave control registers\n");
return status;
}
@@ -818,12 +787,13 @@ int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p)
/* Scan all registers in the range ATC_VMID8_PASID_MAPPING ..
* ATC_VMID15_PASID_MAPPING
- * to check which VMID the current process is mapped to. */
+ * to check which VMID the current process is mapped to.
+ */
for (vmid = first_vmid_to_scan; vmid <= last_vmid_to_scan; vmid++) {
if (dev->kfd2kgd->get_atc_vmid_pasid_mapping_valid
(dev->kgd, vmid)) {
- if (dev->kfd2kgd->get_atc_vmid_pasid_mapping_valid
+ if (dev->kfd2kgd->get_atc_vmid_pasid_mapping_pasid
(dev->kgd, vmid) == p->pasid) {
pr_debug("Killing wave fronts of vmid %d and pasid %d\n",
vmid, p->pasid);
@@ -833,7 +803,7 @@ int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p)
}
if (vmid > last_vmid_to_scan) {
- pr_err("amdkfd: didn't found vmid for pasid (%d)\n", p->pasid);
+ pr_err("Didn't find vmid for pasid %d\n", p->pasid);
return -EFAULT;
}
@@ -860,8 +830,6 @@ int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p)
void kfd_dbgdev_init(struct kfd_dbgdev *pdbgdev, struct kfd_dev *pdev,
enum DBGDEV_TYPE type)
{
- BUG_ON(!pdbgdev || !pdev);
-
pdbgdev->dev = pdev;
pdbgdev->kq = NULL;
pdbgdev->type = type;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c b/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c
index 56d676396342..3da25f7bda6b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c
@@ -44,8 +44,6 @@ struct mutex *kfd_get_dbgmgr_mutex(void)
static void kfd_dbgmgr_uninitialize(struct kfd_dbgmgr *pmgr)
{
- BUG_ON(!pmgr);
-
kfree(pmgr->dbgdev);
pmgr->dbgdev = NULL;
@@ -55,7 +53,7 @@ static void kfd_dbgmgr_uninitialize(struct kfd_dbgmgr *pmgr)
void kfd_dbgmgr_destroy(struct kfd_dbgmgr *pmgr)
{
- if (pmgr != NULL) {
+ if (pmgr) {
kfd_dbgmgr_uninitialize(pmgr);
kfree(pmgr);
}
@@ -66,12 +64,12 @@ bool kfd_dbgmgr_create(struct kfd_dbgmgr **ppmgr, struct kfd_dev *pdev)
enum DBGDEV_TYPE type = DBGDEV_TYPE_DIQ;
struct kfd_dbgmgr *new_buff;
- BUG_ON(pdev == NULL);
- BUG_ON(!pdev->init_complete);
+ if (WARN_ON(!pdev->init_complete))
+ return false;
new_buff = kfd_alloc_struct(new_buff);
if (!new_buff) {
- pr_err("amdkfd: Failed to allocate dbgmgr instance\n");
+ pr_err("Failed to allocate dbgmgr instance\n");
return false;
}
@@ -79,7 +77,7 @@ bool kfd_dbgmgr_create(struct kfd_dbgmgr **ppmgr, struct kfd_dev *pdev)
new_buff->dev = pdev;
new_buff->dbgdev = kfd_alloc_struct(new_buff->dbgdev);
if (!new_buff->dbgdev) {
- pr_err("amdkfd: Failed to allocate dbgdev instance\n");
+ pr_err("Failed to allocate dbgdev instance\n");
kfree(new_buff);
return false;
}
@@ -96,8 +94,6 @@ bool kfd_dbgmgr_create(struct kfd_dbgmgr **ppmgr, struct kfd_dev *pdev)
long kfd_dbgmgr_register(struct kfd_dbgmgr *pmgr, struct kfd_process *p)
{
- BUG_ON(!p || !pmgr || !pmgr->dbgdev);
-
if (pmgr->pasid != 0) {
pr_debug("H/W debugger is already active using pasid %d\n",
pmgr->pasid);
@@ -118,8 +114,6 @@ long kfd_dbgmgr_register(struct kfd_dbgmgr *pmgr, struct kfd_process *p)
long kfd_dbgmgr_unregister(struct kfd_dbgmgr *pmgr, struct kfd_process *p)
{
- BUG_ON(!p || !pmgr || !pmgr->dbgdev);
-
/* Is the requests coming from the already registered process? */
if (pmgr->pasid != p->pasid) {
pr_debug("H/W debugger is not registered by calling pasid %d\n",
@@ -137,8 +131,6 @@ long kfd_dbgmgr_unregister(struct kfd_dbgmgr *pmgr, struct kfd_process *p)
long kfd_dbgmgr_wave_control(struct kfd_dbgmgr *pmgr,
struct dbg_wave_control_info *wac_info)
{
- BUG_ON(!pmgr || !pmgr->dbgdev || !wac_info);
-
/* Is the requests coming from the already registered process? */
if (pmgr->pasid != wac_info->process->pasid) {
pr_debug("H/W debugger support was not registered for requester pasid %d\n",
@@ -152,9 +144,6 @@ long kfd_dbgmgr_wave_control(struct kfd_dbgmgr *pmgr,
long kfd_dbgmgr_address_watch(struct kfd_dbgmgr *pmgr,
struct dbg_address_watch_info *adw_info)
{
- BUG_ON(!pmgr || !pmgr->dbgdev || !adw_info);
-
-
/* Is the requests coming from the already registered process? */
if (pmgr->pasid != adw_info->process->pasid) {
pr_debug("H/W debugger support was not registered for requester pasid %d\n",
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h b/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h
index 257a745ad0b5..a04a1fe1d0d9 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h
@@ -30,13 +30,11 @@
#pragma pack(push, 4)
enum HSA_DBG_WAVEOP {
- HSA_DBG_WAVEOP_HALT = 1, /* Halts a wavefront */
- HSA_DBG_WAVEOP_RESUME = 2, /* Resumes a wavefront */
- HSA_DBG_WAVEOP_KILL = 3, /* Kills a wavefront */
- HSA_DBG_WAVEOP_DEBUG = 4, /* Causes wavefront to enter
- debug mode */
- HSA_DBG_WAVEOP_TRAP = 5, /* Causes wavefront to take
- a trap */
+ HSA_DBG_WAVEOP_HALT = 1, /* Halts a wavefront */
+ HSA_DBG_WAVEOP_RESUME = 2, /* Resumes a wavefront */
+ HSA_DBG_WAVEOP_KILL = 3, /* Kills a wavefront */
+ HSA_DBG_WAVEOP_DEBUG = 4, /* Causes wavefront to enter dbg mode */
+ HSA_DBG_WAVEOP_TRAP = 5, /* Causes wavefront to take a trap */
HSA_DBG_NUM_WAVEOP = 5,
HSA_DBG_MAX_WAVEOP = 0xFFFFFFFF
};
@@ -81,15 +79,13 @@ struct HsaDbgWaveMsgAMDGen2 {
uint32_t UserData:8; /* user data */
uint32_t ShaderArray:1; /* Shader array */
uint32_t Priv:1; /* Privileged */
- uint32_t Reserved0:4; /* This field is reserved,
- should be 0 */
+ uint32_t Reserved0:4; /* Reserved, should be 0 */
uint32_t WaveId:4; /* wave id */
uint32_t SIMD:2; /* SIMD id */
uint32_t HSACU:4; /* Compute unit */
uint32_t ShaderEngine:2;/* Shader engine */
uint32_t MessageType:2; /* see HSA_DBG_WAVEMSG_TYPE */
- uint32_t Reserved1:4; /* This field is reserved,
- should be 0 */
+ uint32_t Reserved1:4; /* Reserved, should be 0 */
} ui32;
uint32_t Value;
};
@@ -121,20 +117,23 @@ struct HsaDbgWaveMessage {
* in the user mode instruction stream. The OS scheduler event is typically
* associated and signaled by an interrupt issued by the GPU, but other HSA
* system interrupt conditions from other HW (e.g. IOMMUv2) may be surfaced
- * by the KFD by this mechanism, too. */
+ * by the KFD by this mechanism, too.
+ */
/* these are the new definitions for events */
enum HSA_EVENTTYPE {
HSA_EVENTTYPE_SIGNAL = 0, /* user-mode generated GPU signal */
HSA_EVENTTYPE_NODECHANGE = 1, /* HSA node change (attach/detach) */
HSA_EVENTTYPE_DEVICESTATECHANGE = 2, /* HSA device state change
- (start/stop) */
+ * (start/stop)
+ */
HSA_EVENTTYPE_HW_EXCEPTION = 3, /* GPU shader exception event */
HSA_EVENTTYPE_SYSTEM_EVENT = 4, /* GPU SYSCALL with parameter info */
HSA_EVENTTYPE_DEBUG_EVENT = 5, /* GPU signal for debugging */
HSA_EVENTTYPE_PROFILE_EVENT = 6,/* GPU signal for profiling */
HSA_EVENTTYPE_QUEUE_EVENT = 7, /* GPU signal queue idle state
- (EOP pm4) */
+ * (EOP pm4)
+ */
/* ... */
HSA_EVENTTYPE_MAXID,
HSA_EVENTTYPE_TYPE_SIZE = 0xFFFFFFFF
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index 88187bfc5ea3..61fff25b4ce7 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -26,7 +26,7 @@
#include <linux/slab.h>
#include "kfd_priv.h"
#include "kfd_device_queue_manager.h"
-#include "kfd_pm4_headers.h"
+#include "kfd_pm4_headers_vi.h"
#define MQD_SIZE_ALIGNED 768
@@ -98,11 +98,14 @@ static const struct kfd_device_info *lookup_device_info(unsigned short did)
for (i = 0; i < ARRAY_SIZE(supported_devices); i++) {
if (supported_devices[i].did == did) {
- BUG_ON(supported_devices[i].device_info == NULL);
+ WARN_ON(!supported_devices[i].device_info);
return supported_devices[i].device_info;
}
}
+ dev_warn(kfd_device, "DID %04x is missing in supported_devices\n",
+ did);
+
return NULL;
}
@@ -114,8 +117,10 @@ struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd,
const struct kfd_device_info *device_info =
lookup_device_info(pdev->device);
- if (!device_info)
+ if (!device_info) {
+ dev_err(kfd_device, "kgd2kfd_probe failed\n");
return NULL;
+ }
kfd = kzalloc(sizeof(*kfd), GFP_KERNEL);
if (!kfd)
@@ -152,15 +157,16 @@ static bool device_iommu_pasid_init(struct kfd_dev *kfd)
}
if ((iommu_info.flags & required_iommu_flags) != required_iommu_flags) {
- dev_err(kfd_device, "error required iommu flags ats(%i), pri(%i), pasid(%i)\n",
+ dev_err(kfd_device, "error required iommu flags ats %i, pri %i, pasid %i\n",
(iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_ATS_SUP) != 0,
(iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_PRI_SUP) != 0,
- (iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_PASID_SUP) != 0);
+ (iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_PASID_SUP)
+ != 0);
return false;
}
pasid_limit = min_t(unsigned int,
- (unsigned int)1 << kfd->device_info->max_pasid_bits,
+ (unsigned int)(1 << kfd->device_info->max_pasid_bits),
iommu_info.max_pasids);
/*
* last pasid is used for kernel queues doorbells
@@ -211,9 +217,8 @@ static int iommu_invalid_ppr_cb(struct pci_dev *pdev, int pasid,
flags);
dev = kfd_device_by_pci_dev(pdev);
- BUG_ON(dev == NULL);
-
- kfd_signal_iommu_event(dev, pasid, address,
+ if (!WARN_ON(!dev))
+ kfd_signal_iommu_event(dev, pasid, address,
flags & PPR_FAULT_WRITE, flags & PPR_FAULT_EXEC);
return AMD_IOMMU_INV_PRI_RSP_INVALID;
@@ -226,10 +231,6 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
kfd->shared_resources = *gpu_resources;
- /* We only use the first MEC */
- if (kfd->shared_resources.num_mec > 1)
- kfd->shared_resources.num_mec = 1;
-
/* calculate max size of mqds needed for queues */
size = max_num_of_queues_per_device *
kfd->device_info->mqd_size_aligned;
@@ -238,9 +239,9 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
* calculate max size of runlist packet.
* There can be only 2 packets at once
*/
- size += (KFD_MAX_NUM_OF_PROCESSES * sizeof(struct pm4_map_process) +
- max_num_of_queues_per_device *
- sizeof(struct pm4_map_queues) + sizeof(struct pm4_runlist)) * 2;
+ size += (KFD_MAX_NUM_OF_PROCESSES * sizeof(struct pm4_mes_map_process) +
+ max_num_of_queues_per_device * sizeof(struct pm4_mes_map_queues)
+ + sizeof(struct pm4_mes_runlist)) * 2;
/* Add size of HIQ & DIQ */
size += KFD_KERNEL_QUEUE_SIZE * 2;
@@ -251,42 +252,37 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
if (kfd->kfd2kgd->init_gtt_mem_allocation(
kfd->kgd, size, &kfd->gtt_mem,
&kfd->gtt_start_gpu_addr, &kfd->gtt_start_cpu_ptr)){
- dev_err(kfd_device,
- "Could not allocate %d bytes for device (%x:%x)\n",
- size, kfd->pdev->vendor, kfd->pdev->device);
+ dev_err(kfd_device, "Could not allocate %d bytes\n", size);
goto out;
}
- dev_info(kfd_device,
- "Allocated %d bytes on gart for device(%x:%x)\n",
- size, kfd->pdev->vendor, kfd->pdev->device);
+ dev_info(kfd_device, "Allocated %d bytes on gart\n", size);
/* Initialize GTT sa with 512 byte chunk size */
if (kfd_gtt_sa_init(kfd, size, 512) != 0) {
- dev_err(kfd_device,
- "Error initializing gtt sub-allocator\n");
+ dev_err(kfd_device, "Error initializing gtt sub-allocator\n");
goto kfd_gtt_sa_init_error;
}
- kfd_doorbell_init(kfd);
-
- if (kfd_topology_add_device(kfd) != 0) {
+ if (kfd_doorbell_init(kfd)) {
dev_err(kfd_device,
- "Error adding device (%x:%x) to topology\n",
- kfd->pdev->vendor, kfd->pdev->device);
+ "Error initializing doorbell aperture\n");
+ goto kfd_doorbell_error;
+ }
+
+ if (kfd_topology_add_device(kfd)) {
+ dev_err(kfd_device, "Error adding device to topology\n");
goto kfd_topology_add_device_error;
}
if (kfd_interrupt_init(kfd)) {
- dev_err(kfd_device,
- "Error initializing interrupts for device (%x:%x)\n",
- kfd->pdev->vendor, kfd->pdev->device);
+ dev_err(kfd_device, "Error initializing interrupts\n");
goto kfd_interrupt_error;
}
if (!device_iommu_pasid_init(kfd)) {
dev_err(kfd_device,
- "Error initializing iommuv2 for device (%x:%x)\n",
+ "Error initializing iommuv2 for device %x:%x\n",
kfd->pdev->vendor, kfd->pdev->device);
goto device_iommu_pasid_error;
}
@@ -296,15 +292,13 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
kfd->dqm = device_queue_manager_init(kfd);
if (!kfd->dqm) {
- dev_err(kfd_device,
- "Error initializing queue manager for device (%x:%x)\n",
- kfd->pdev->vendor, kfd->pdev->device);
+ dev_err(kfd_device, "Error initializing queue manager\n");
goto device_queue_manager_error;
}
- if (kfd->dqm->ops.start(kfd->dqm) != 0) {
+ if (kfd->dqm->ops.start(kfd->dqm)) {
dev_err(kfd_device,
- "Error starting queuen manager for device (%x:%x)\n",
+ "Error starting queue manager for device %x:%x\n",
kfd->pdev->vendor, kfd->pdev->device);
goto dqm_start_error;
}
@@ -312,10 +306,10 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
kfd->dbgmgr = NULL;
kfd->init_complete = true;
- dev_info(kfd_device, "added device (%x:%x)\n", kfd->pdev->vendor,
+ dev_info(kfd_device, "added device %x:%x\n", kfd->pdev->vendor,
kfd->pdev->device);
- pr_debug("kfd: Starting kfd with the following scheduling policy %d\n",
+ pr_debug("Starting kfd with the following scheduling policy %d\n",
sched_policy);
goto out;
@@ -329,11 +323,13 @@ device_iommu_pasid_error:
kfd_interrupt_error:
kfd_topology_remove_device(kfd);
kfd_topology_add_device_error:
+ kfd_doorbell_fini(kfd);
+kfd_doorbell_error:
kfd_gtt_sa_fini(kfd);
kfd_gtt_sa_init_error:
kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem);
dev_err(kfd_device,
- "device (%x:%x) NOT added due to errors\n",
+ "device %x:%x NOT added due to errors\n",
kfd->pdev->vendor, kfd->pdev->device);
out:
return kfd->init_complete;
@@ -346,6 +342,7 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd)
amd_iommu_free_device(kfd->pdev);
kfd_interrupt_exit(kfd);
kfd_topology_remove_device(kfd);
+ kfd_doorbell_fini(kfd);
kfd_gtt_sa_fini(kfd);
kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem);
}
@@ -355,8 +352,6 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd)
void kgd2kfd_suspend(struct kfd_dev *kfd)
{
- BUG_ON(kfd == NULL);
-
if (kfd->init_complete) {
kfd->dqm->ops.stop(kfd->dqm);
amd_iommu_set_invalidate_ctx_cb(kfd->pdev, NULL);
@@ -370,14 +365,15 @@ int kgd2kfd_resume(struct kfd_dev *kfd)
unsigned int pasid_limit;
int err;
- BUG_ON(kfd == NULL);
-
pasid_limit = kfd_get_pasid_limit();
if (kfd->init_complete) {
err = amd_iommu_init_device(kfd->pdev, pasid_limit);
- if (err < 0)
+ if (err < 0) {
+ dev_err(kfd_device, "failed to initialize iommu\n");
return -ENXIO;
+ }
+
amd_iommu_set_invalidate_ctx_cb(kfd->pdev,
iommu_pasid_shutdown_callback);
amd_iommu_set_invalid_ppr_cb(kfd->pdev, iommu_invalid_ppr_cb);
@@ -406,26 +402,27 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry)
static int kfd_gtt_sa_init(struct kfd_dev *kfd, unsigned int buf_size,
unsigned int chunk_size)
{
- unsigned int num_of_bits;
+ unsigned int num_of_longs;
- BUG_ON(!kfd);
- BUG_ON(!kfd->gtt_mem);
- BUG_ON(buf_size < chunk_size);
- BUG_ON(buf_size == 0);
- BUG_ON(chunk_size == 0);
+ if (WARN_ON(buf_size < chunk_size))
+ return -EINVAL;
+ if (WARN_ON(buf_size == 0))
+ return -EINVAL;
+ if (WARN_ON(chunk_size == 0))
+ return -EINVAL;
kfd->gtt_sa_chunk_size = chunk_size;
kfd->gtt_sa_num_of_chunks = buf_size / chunk_size;
- num_of_bits = kfd->gtt_sa_num_of_chunks / BITS_PER_BYTE;
- BUG_ON(num_of_bits == 0);
+ num_of_longs = (kfd->gtt_sa_num_of_chunks + BITS_PER_LONG - 1) /
+ BITS_PER_LONG;
- kfd->gtt_sa_bitmap = kzalloc(num_of_bits, GFP_KERNEL);
+ kfd->gtt_sa_bitmap = kcalloc(num_of_longs, sizeof(long), GFP_KERNEL);
if (!kfd->gtt_sa_bitmap)
return -ENOMEM;
- pr_debug("kfd: gtt_sa_num_of_chunks = %d, gtt_sa_bitmap = %p\n",
+ pr_debug("gtt_sa_num_of_chunks = %d, gtt_sa_bitmap = %p\n",
kfd->gtt_sa_num_of_chunks, kfd->gtt_sa_bitmap);
mutex_init(&kfd->gtt_sa_lock);
@@ -459,8 +456,6 @@ int kfd_gtt_sa_allocate(struct kfd_dev *kfd, unsigned int size,
{
unsigned int found, start_search, cur_size;
- BUG_ON(!kfd);
-
if (size == 0)
return -EINVAL;
@@ -471,7 +466,7 @@ int kfd_gtt_sa_allocate(struct kfd_dev *kfd, unsigned int size,
if ((*mem_obj) == NULL)
return -ENOMEM;
- pr_debug("kfd: allocated mem_obj = %p for size = %d\n", *mem_obj, size);
+ pr_debug("Allocated mem_obj = %p for size = %d\n", *mem_obj, size);
start_search = 0;
@@ -483,7 +478,7 @@ kfd_gtt_restart_search:
kfd->gtt_sa_num_of_chunks,
start_search);
- pr_debug("kfd: found = %d\n", found);
+ pr_debug("Found = %d\n", found);
/* If there wasn't any free chunk, bail out */
if (found == kfd->gtt_sa_num_of_chunks)
@@ -501,12 +496,12 @@ kfd_gtt_restart_search:
found,
kfd->gtt_sa_chunk_size);
- pr_debug("kfd: gpu_addr = %p, cpu_addr = %p\n",
+ pr_debug("gpu_addr = %p, cpu_addr = %p\n",
(uint64_t *) (*mem_obj)->gpu_addr, (*mem_obj)->cpu_ptr);
/* If we need only one chunk, mark it as allocated and get out */
if (size <= kfd->gtt_sa_chunk_size) {
- pr_debug("kfd: single bit\n");
+ pr_debug("Single bit\n");
set_bit(found, kfd->gtt_sa_bitmap);
goto kfd_gtt_out;
}
@@ -541,7 +536,7 @@ kfd_gtt_restart_search:
} while (cur_size > 0);
- pr_debug("kfd: range_start = %d, range_end = %d\n",
+ pr_debug("range_start = %d, range_end = %d\n",
(*mem_obj)->range_start, (*mem_obj)->range_end);
/* Mark the chunks as allocated */
@@ -555,7 +550,7 @@ kfd_gtt_out:
return 0;
kfd_gtt_no_free_chunk:
- pr_debug("kfd: allocation failed with mem_obj = %p\n", mem_obj);
+ pr_debug("Allocation failed with mem_obj = %p\n", mem_obj);
mutex_unlock(&kfd->gtt_sa_lock);
kfree(mem_obj);
return -ENOMEM;
@@ -565,13 +560,11 @@ int kfd_gtt_sa_free(struct kfd_dev *kfd, struct kfd_mem_obj *mem_obj)
{
unsigned int bit;
- BUG_ON(!kfd);
-
/* Act like kfree when trying to free a NULL object */
if (!mem_obj)
return 0;
- pr_debug("kfd: free mem_obj = %p, range_start = %d, range_end = %d\n",
+ pr_debug("Free mem_obj = %p, range_start = %d, range_end = %d\n",
mem_obj, mem_obj->range_start, mem_obj->range_end);
mutex_lock(&kfd->gtt_sa_lock);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 955aa304ff48..53a66e821624 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -77,29 +77,19 @@ static bool is_pipe_enabled(struct device_queue_manager *dqm, int mec, int pipe)
return false;
}
-unsigned int get_mec_num(struct device_queue_manager *dqm)
-{
- BUG_ON(!dqm || !dqm->dev);
-
- return dqm->dev->shared_resources.num_mec;
-}
-
unsigned int get_queues_num(struct device_queue_manager *dqm)
{
- BUG_ON(!dqm || !dqm->dev);
return bitmap_weight(dqm->dev->shared_resources.queue_bitmap,
KGD_MAX_QUEUES);
}
unsigned int get_queues_per_pipe(struct device_queue_manager *dqm)
{
- BUG_ON(!dqm || !dqm->dev);
return dqm->dev->shared_resources.num_queue_per_pipe;
}
unsigned int get_pipes_per_mec(struct device_queue_manager *dqm)
{
- BUG_ON(!dqm || !dqm->dev);
return dqm->dev->shared_resources.num_pipe_per_mec;
}
@@ -128,7 +118,7 @@ static int allocate_vmid(struct device_queue_manager *dqm,
/* Kaveri kfd vmid's starts from vmid 8 */
allocated_vmid = bit + KFD_VMID_START_OFFSET;
- pr_debug("kfd: vmid allocation %d\n", allocated_vmid);
+ pr_debug("vmid allocation %d\n", allocated_vmid);
qpd->vmid = allocated_vmid;
q->properties.vmid = allocated_vmid;
@@ -159,42 +149,38 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
{
int retval;
- BUG_ON(!dqm || !q || !qpd || !allocated_vmid);
-
- pr_debug("kfd: In func %s\n", __func__);
print_queue(q);
mutex_lock(&dqm->lock);
if (dqm->total_queue_count >= max_num_of_queues_per_device) {
- pr_warn("amdkfd: Can't create new usermode queue because %d queues were already created\n",
+ pr_warn("Can't create new usermode queue because %d queues were already created\n",
dqm->total_queue_count);
- mutex_unlock(&dqm->lock);
- return -EPERM;
+ retval = -EPERM;
+ goto out_unlock;
}
if (list_empty(&qpd->queues_list)) {
retval = allocate_vmid(dqm, qpd, q);
- if (retval != 0) {
- mutex_unlock(&dqm->lock);
- return retval;
- }
+ if (retval)
+ goto out_unlock;
}
*allocated_vmid = qpd->vmid;
q->properties.vmid = qpd->vmid;
if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE)
retval = create_compute_queue_nocpsch(dqm, q, qpd);
- if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
+ else if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
retval = create_sdma_queue_nocpsch(dqm, q, qpd);
+ else
+ retval = -EINVAL;
- if (retval != 0) {
+ if (retval) {
if (list_empty(&qpd->queues_list)) {
deallocate_vmid(dqm, qpd, q);
*allocated_vmid = 0;
}
- mutex_unlock(&dqm->lock);
- return retval;
+ goto out_unlock;
}
list_add(&q->list, &qpd->queues_list);
@@ -212,8 +198,9 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm,
pr_debug("Total of %d queues are accountable so far\n",
dqm->total_queue_count);
+out_unlock:
mutex_unlock(&dqm->lock);
- return 0;
+ return retval;
}
static int allocate_hqd(struct device_queue_manager *dqm, struct queue *q)
@@ -223,7 +210,8 @@ static int allocate_hqd(struct device_queue_manager *dqm, struct queue *q)
set = false;
- for (pipe = dqm->next_pipe_to_allocate, i = 0; i < get_pipes_per_mec(dqm);
+ for (pipe = dqm->next_pipe_to_allocate, i = 0;
+ i < get_pipes_per_mec(dqm);
pipe = ((pipe + 1) % get_pipes_per_mec(dqm)), ++i) {
if (!is_pipe_enabled(dqm, 0, pipe))
@@ -246,8 +234,7 @@ static int allocate_hqd(struct device_queue_manager *dqm, struct queue *q)
if (!set)
return -EBUSY;
- pr_debug("kfd: DQM %s hqd slot - pipe (%d) queue(%d)\n",
- __func__, q->pipe, q->queue);
+ pr_debug("hqd slot - pipe %d, queue %d\n", q->pipe, q->queue);
/* horizontal hqd allocation */
dqm->next_pipe_to_allocate = (pipe + 1) % get_pipes_per_mec(dqm);
@@ -267,36 +254,38 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm,
int retval;
struct mqd_manager *mqd;
- BUG_ON(!dqm || !q || !qpd);
-
mqd = dqm->ops.get_mqd_manager(dqm, KFD_MQD_TYPE_COMPUTE);
- if (mqd == NULL)
+ if (!mqd)
return -ENOMEM;
retval = allocate_hqd(dqm, q);
- if (retval != 0)
+ if (retval)
return retval;
retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
&q->gart_mqd_addr, &q->properties);
- if (retval != 0) {
- deallocate_hqd(dqm, q);
- return retval;
- }
+ if (retval)
+ goto out_deallocate_hqd;
- pr_debug("kfd: loading mqd to hqd on pipe (%d) queue (%d)\n",
- q->pipe,
- q->queue);
+ pr_debug("Loading mqd to hqd on pipe %d, queue %d\n",
+ q->pipe, q->queue);
- retval = mqd->load_mqd(mqd, q->mqd, q->pipe,
- q->queue, (uint32_t __user *) q->properties.write_ptr);
- if (retval != 0) {
- deallocate_hqd(dqm, q);
- mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
- return retval;
- }
+ dqm->dev->kfd2kgd->set_scratch_backing_va(
+ dqm->dev->kgd, qpd->sh_hidden_private_base, qpd->vmid);
+
+ retval = mqd->load_mqd(mqd, q->mqd, q->pipe, q->queue, &q->properties,
+ q->process->mm);
+ if (retval)
+ goto out_uninit_mqd;
return 0;
+
+out_uninit_mqd:
+ mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
+out_deallocate_hqd:
+ deallocate_hqd(dqm, q);
+
+ return retval;
}
static int destroy_queue_nocpsch(struct device_queue_manager *dqm,
@@ -306,12 +295,8 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm,
int retval;
struct mqd_manager *mqd;
- BUG_ON(!dqm || !q || !q->mqd || !qpd);
-
retval = 0;
- pr_debug("kfd: In Func %s\n", __func__);
-
mutex_lock(&dqm->lock);
if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE) {
@@ -330,7 +315,7 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm,
dqm->sdma_queue_count--;
deallocate_sdma_queue(dqm, q->sdma_id);
} else {
- pr_debug("q->properties.type is invalid (%d)\n",
+ pr_debug("q->properties.type %d is invalid\n",
q->properties.type);
retval = -EINVAL;
goto out;
@@ -341,7 +326,7 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm,
QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS,
q->pipe, q->queue);
- if (retval != 0)
+ if (retval)
goto out;
mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
@@ -371,14 +356,12 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
struct mqd_manager *mqd;
bool prev_active = false;
- BUG_ON(!dqm || !q || !q->mqd);
-
mutex_lock(&dqm->lock);
mqd = dqm->ops.get_mqd_manager(dqm,
get_mqd_type_from_queue_type(q->properties.type));
- if (mqd == NULL) {
- mutex_unlock(&dqm->lock);
- return -ENOMEM;
+ if (!mqd) {
+ retval = -ENOMEM;
+ goto out_unlock;
}
if (q->properties.is_active)
@@ -392,12 +375,13 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
retval = mqd->update_mqd(mqd, q->mqd, &q->properties);
if ((q->properties.is_active) && (!prev_active))
dqm->queue_count++;
- else if ((!q->properties.is_active) && (prev_active))
+ else if (!q->properties.is_active && prev_active)
dqm->queue_count--;
if (sched_policy != KFD_SCHED_POLICY_NO_HWS)
retval = execute_queues_cpsch(dqm, false);
+out_unlock:
mutex_unlock(&dqm->lock);
return retval;
}
@@ -407,15 +391,16 @@ static struct mqd_manager *get_mqd_manager_nocpsch(
{
struct mqd_manager *mqd;
- BUG_ON(!dqm || type >= KFD_MQD_TYPE_MAX);
+ if (WARN_ON(type >= KFD_MQD_TYPE_MAX))
+ return NULL;
- pr_debug("kfd: In func %s mqd type %d\n", __func__, type);
+ pr_debug("mqd type %d\n", type);
mqd = dqm->mqds[type];
if (!mqd) {
mqd = mqd_manager_init(type, dqm->dev);
- if (mqd == NULL)
- pr_err("kfd: mqd manager is NULL");
+ if (!mqd)
+ pr_err("mqd manager is NULL");
dqm->mqds[type] = mqd;
}
@@ -428,11 +413,7 @@ static int register_process_nocpsch(struct device_queue_manager *dqm,
struct device_process_node *n;
int retval;
- BUG_ON(!dqm || !qpd);
-
- pr_debug("kfd: In func %s\n", __func__);
-
- n = kzalloc(sizeof(struct device_process_node), GFP_KERNEL);
+ n = kzalloc(sizeof(*n), GFP_KERNEL);
if (!n)
return -ENOMEM;
@@ -456,10 +437,6 @@ static int unregister_process_nocpsch(struct device_queue_manager *dqm,
int retval;
struct device_process_node *cur, *next;
- BUG_ON(!dqm || !qpd);
-
- pr_debug("In func %s\n", __func__);
-
pr_debug("qpd->queues_list is %s\n",
list_empty(&qpd->queues_list) ? "empty" : "not empty");
@@ -500,51 +477,39 @@ static void init_interrupts(struct device_queue_manager *dqm)
{
unsigned int i;
- BUG_ON(dqm == NULL);
-
for (i = 0 ; i < get_pipes_per_mec(dqm) ; i++)
if (is_pipe_enabled(dqm, 0, i))
dqm->dev->kfd2kgd->init_interrupts(dqm->dev->kgd, i);
}
-static int init_scheduler(struct device_queue_manager *dqm)
-{
- int retval = 0;
-
- BUG_ON(!dqm);
-
- pr_debug("kfd: In %s\n", __func__);
-
- return retval;
-}
-
static int initialize_nocpsch(struct device_queue_manager *dqm)
{
- int i;
+ int pipe, queue;
- BUG_ON(!dqm);
+ pr_debug("num of pipes: %d\n", get_pipes_per_mec(dqm));
- pr_debug("kfd: In func %s num of pipes: %d\n",
- __func__, get_pipes_per_mec(dqm));
+ dqm->allocated_queues = kcalloc(get_pipes_per_mec(dqm),
+ sizeof(unsigned int), GFP_KERNEL);
+ if (!dqm->allocated_queues)
+ return -ENOMEM;
mutex_init(&dqm->lock);
INIT_LIST_HEAD(&dqm->queues);
dqm->queue_count = dqm->next_pipe_to_allocate = 0;
dqm->sdma_queue_count = 0;
- dqm->allocated_queues = kcalloc(get_pipes_per_mec(dqm),
- sizeof(unsigned int), GFP_KERNEL);
- if (!dqm->allocated_queues) {
- mutex_destroy(&dqm->lock);
- return -ENOMEM;
- }
- for (i = 0; i < get_pipes_per_mec(dqm); i++)
- dqm->allocated_queues[i] = (1 << get_queues_per_pipe(dqm)) - 1;
+ for (pipe = 0; pipe < get_pipes_per_mec(dqm); pipe++) {
+ int pipe_offset = pipe * get_queues_per_pipe(dqm);
+
+ for (queue = 0; queue < get_queues_per_pipe(dqm); queue++)
+ if (test_bit(pipe_offset + queue,
+ dqm->dev->shared_resources.queue_bitmap))
+ dqm->allocated_queues[pipe] |= 1 << queue;
+ }
dqm->vmid_bitmap = (1 << VMID_PER_DEVICE) - 1;
dqm->sdma_bitmap = (1 << CIK_SDMA_QUEUES) - 1;
- init_scheduler(dqm);
return 0;
}
@@ -552,9 +517,7 @@ static void uninitialize_nocpsch(struct device_queue_manager *dqm)
{
int i;
- BUG_ON(!dqm);
-
- BUG_ON(dqm->queue_count > 0 || dqm->processes_count > 0);
+ WARN_ON(dqm->queue_count > 0 || dqm->processes_count > 0);
kfree(dqm->allocated_queues);
for (i = 0 ; i < KFD_MQD_TYPE_MAX ; i++)
@@ -611,33 +574,34 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm,
return -ENOMEM;
retval = allocate_sdma_queue(dqm, &q->sdma_id);
- if (retval != 0)
+ if (retval)
return retval;
q->properties.sdma_queue_id = q->sdma_id % CIK_SDMA_QUEUES_PER_ENGINE;
q->properties.sdma_engine_id = q->sdma_id / CIK_SDMA_ENGINE_NUM;
- pr_debug("kfd: sdma id is: %d\n", q->sdma_id);
- pr_debug(" sdma queue id: %d\n", q->properties.sdma_queue_id);
- pr_debug(" sdma engine id: %d\n", q->properties.sdma_engine_id);
+ pr_debug("SDMA id is: %d\n", q->sdma_id);
+ pr_debug("SDMA queue id: %d\n", q->properties.sdma_queue_id);
+ pr_debug("SDMA engine id: %d\n", q->properties.sdma_engine_id);
dqm->ops_asic_specific.init_sdma_vm(dqm, q, qpd);
retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
&q->gart_mqd_addr, &q->properties);
- if (retval != 0) {
- deallocate_sdma_queue(dqm, q->sdma_id);
- return retval;
- }
+ if (retval)
+ goto out_deallocate_sdma_queue;
- retval = mqd->load_mqd(mqd, q->mqd, 0,
- 0, NULL);
- if (retval != 0) {
- deallocate_sdma_queue(dqm, q->sdma_id);
- mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
- return retval;
- }
+ retval = mqd->load_mqd(mqd, q->mqd, 0, 0, &q->properties, NULL);
+ if (retval)
+ goto out_uninit_mqd;
return 0;
+
+out_uninit_mqd:
+ mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
+out_deallocate_sdma_queue:
+ deallocate_sdma_queue(dqm, q->sdma_id);
+
+ return retval;
}
/*
@@ -649,10 +613,6 @@ static int set_sched_resources(struct device_queue_manager *dqm)
int i, mec;
struct scheduling_resources res;
- BUG_ON(!dqm);
-
- pr_debug("kfd: In func %s\n", __func__);
-
res.vmid_mask = (1 << VMID_PER_DEVICE) - 1;
res.vmid_mask <<= KFD_VMID_START_OFFSET;
@@ -670,8 +630,9 @@ static int set_sched_resources(struct device_queue_manager *dqm)
/* This situation may be hit in the future if a new HW
* generation exposes more than 64 queues. If so, the
- * definition of res.queue_mask needs updating */
- if (WARN_ON(i > (sizeof(res.queue_mask)*8))) {
+ * definition of res.queue_mask needs updating
+ */
+ if (WARN_ON(i >= (sizeof(res.queue_mask)*8))) {
pr_err("Invalid queue enabled by amdgpu: %d\n", i);
break;
}
@@ -681,9 +642,9 @@ static int set_sched_resources(struct device_queue_manager *dqm)
res.gws_mask = res.oac_mask = res.gds_heap_base =
res.gds_heap_size = 0;
- pr_debug("kfd: scheduling resources:\n"
- " vmid mask: 0x%8X\n"
- " queue mask: 0x%8llX\n",
+ pr_debug("Scheduling resources:\n"
+ "vmid mask: 0x%8X\n"
+ "queue mask: 0x%8llX\n",
res.vmid_mask, res.queue_mask);
return pm_send_set_resources(&dqm->packets, &res);
@@ -693,10 +654,7 @@ static int initialize_cpsch(struct device_queue_manager *dqm)
{
int retval;
- BUG_ON(!dqm);
-
- pr_debug("kfd: In func %s num of pipes: %d\n",
- __func__, get_pipes_per_mec(dqm));
+ pr_debug("num of pipes: %d\n", get_pipes_per_mec(dqm));
mutex_init(&dqm->lock);
INIT_LIST_HEAD(&dqm->queues);
@@ -704,13 +662,9 @@ static int initialize_cpsch(struct device_queue_manager *dqm)
dqm->sdma_queue_count = 0;
dqm->active_runlist = false;
retval = dqm->ops_asic_specific.initialize(dqm);
- if (retval != 0)
- goto fail_init_pipelines;
-
- return 0;
+ if (retval)
+ mutex_destroy(&dqm->lock);
-fail_init_pipelines:
- mutex_destroy(&dqm->lock);
return retval;
}
@@ -719,25 +673,23 @@ static int start_cpsch(struct device_queue_manager *dqm)
struct device_process_node *node;
int retval;
- BUG_ON(!dqm);
-
retval = 0;
retval = pm_init(&dqm->packets, dqm);
- if (retval != 0)
+ if (retval)
goto fail_packet_manager_init;
retval = set_sched_resources(dqm);
- if (retval != 0)
+ if (retval)
goto fail_set_sched_resources;
- pr_debug("kfd: allocating fence memory\n");
+ pr_debug("Allocating fence memory\n");
/* allocate fence memory on the gart */
retval = kfd_gtt_sa_allocate(dqm->dev, sizeof(*dqm->fence_addr),
&dqm->fence_mem);
- if (retval != 0)
+ if (retval)
goto fail_allocate_vidmem;
dqm->fence_addr = dqm->fence_mem->cpu_ptr;
@@ -765,8 +717,6 @@ static int stop_cpsch(struct device_queue_manager *dqm)
struct device_process_node *node;
struct kfd_process_device *pdd;
- BUG_ON(!dqm);
-
destroy_queues_cpsch(dqm, true, true);
list_for_each_entry(node, &dqm->queues, list) {
@@ -783,13 +733,9 @@ static int create_kernel_queue_cpsch(struct device_queue_manager *dqm,
struct kernel_queue *kq,
struct qcm_process_device *qpd)
{
- BUG_ON(!dqm || !kq || !qpd);
-
- pr_debug("kfd: In func %s\n", __func__);
-
mutex_lock(&dqm->lock);
if (dqm->total_queue_count >= max_num_of_queues_per_device) {
- pr_warn("amdkfd: Can't create new kernel queue because %d queues were already created\n",
+ pr_warn("Can't create new kernel queue because %d queues were already created\n",
dqm->total_queue_count);
mutex_unlock(&dqm->lock);
return -EPERM;
@@ -816,10 +762,6 @@ static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm,
struct kernel_queue *kq,
struct qcm_process_device *qpd)
{
- BUG_ON(!dqm || !kq);
-
- pr_debug("kfd: In %s\n", __func__);
-
mutex_lock(&dqm->lock);
/* here we actually preempt the DIQ */
destroy_queues_cpsch(dqm, true, false);
@@ -851,8 +793,6 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
int retval;
struct mqd_manager *mqd;
- BUG_ON(!dqm || !q || !qpd);
-
retval = 0;
if (allocate_vmid)
@@ -861,7 +801,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
mutex_lock(&dqm->lock);
if (dqm->total_queue_count >= max_num_of_queues_per_device) {
- pr_warn("amdkfd: Can't create new usermode queue because %d queues were already created\n",
+ pr_warn("Can't create new usermode queue because %d queues were already created\n",
dqm->total_queue_count);
retval = -EPERM;
goto out;
@@ -873,15 +813,15 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
mqd = dqm->ops.get_mqd_manager(dqm,
get_mqd_type_from_queue_type(q->properties.type));
- if (mqd == NULL) {
- mutex_unlock(&dqm->lock);
- return -ENOMEM;
+ if (!mqd) {
+ retval = -ENOMEM;
+ goto out;
}
dqm->ops_asic_specific.init_sdma_vm(dqm, q, qpd);
retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
&q->gart_mqd_addr, &q->properties);
- if (retval != 0)
+ if (retval)
goto out;
list_add(&q->list, &qpd->queues_list);
@@ -891,7 +831,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
}
if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
- dqm->sdma_queue_count++;
+ dqm->sdma_queue_count++;
/*
* Unconditionally increment this counter, regardless of the queue's
* type or whether the queue is active.
@@ -910,12 +850,11 @@ int amdkfd_fence_wait_timeout(unsigned int *fence_addr,
unsigned int fence_value,
unsigned long timeout)
{
- BUG_ON(!fence_addr);
timeout += jiffies;
while (*fence_addr != fence_value) {
if (time_after(jiffies, timeout)) {
- pr_err("kfd: qcm fence wait loop timeout expired\n");
+ pr_err("qcm fence wait loop timeout expired\n");
return -ETIME;
}
schedule();
@@ -939,8 +878,6 @@ static int destroy_queues_cpsch(struct device_queue_manager *dqm,
enum kfd_preempt_type_filter preempt_type;
struct kfd_process_device *pdd;
- BUG_ON(!dqm);
-
retval = 0;
if (lock)
@@ -948,7 +885,7 @@ static int destroy_queues_cpsch(struct device_queue_manager *dqm,
if (!dqm->active_runlist)
goto out;
- pr_debug("kfd: Before destroying queues, sdma queue count is : %u\n",
+ pr_debug("Before destroying queues, sdma queue count is : %u\n",
dqm->sdma_queue_count);
if (dqm->sdma_queue_count > 0) {
@@ -962,7 +899,7 @@ static int destroy_queues_cpsch(struct device_queue_manager *dqm,
retval = pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_COMPUTE,
preempt_type, 0, false, 0);
- if (retval != 0)
+ if (retval)
goto out;
*dqm->fence_addr = KFD_FENCE_INIT;
@@ -971,7 +908,7 @@ static int destroy_queues_cpsch(struct device_queue_manager *dqm,
/* should be timed out */
retval = amdkfd_fence_wait_timeout(dqm->fence_addr, KFD_FENCE_COMPLETED,
QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS);
- if (retval != 0) {
+ if (retval) {
pdd = kfd_get_process_device_data(dqm->dev,
kfd_get_process(current));
pdd->reset_wavefronts = true;
@@ -990,14 +927,12 @@ static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock)
{
int retval;
- BUG_ON(!dqm);
-
if (lock)
mutex_lock(&dqm->lock);
retval = destroy_queues_cpsch(dqm, false, false);
- if (retval != 0) {
- pr_err("kfd: the cp might be in an unrecoverable state due to an unsuccessful queues preemption");
+ if (retval) {
+ pr_err("The cp might be in an unrecoverable state due to an unsuccessful queues preemption");
goto out;
}
@@ -1012,8 +947,8 @@ static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock)
}
retval = pm_send_runlist(&dqm->packets, &dqm->queues);
- if (retval != 0) {
- pr_err("kfd: failed to execute runlist");
+ if (retval) {
+ pr_err("failed to execute runlist");
goto out;
}
dqm->active_runlist = true;
@@ -1032,8 +967,6 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm,
struct mqd_manager *mqd;
bool preempt_all_queues;
- BUG_ON(!dqm || !qpd || !q);
-
preempt_all_queues = false;
retval = 0;
@@ -1105,8 +1038,6 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm,
{
bool retval;
- pr_debug("kfd: In func %s\n", __func__);
-
mutex_lock(&dqm->lock);
if (alternate_aperture_size == 0) {
@@ -1127,14 +1058,11 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm,
uint64_t base = (uintptr_t)alternate_aperture_base;
uint64_t limit = base + alternate_aperture_size - 1;
- if (limit <= base)
- goto out;
-
- if ((base & APE1_FIXED_BITS_MASK) != 0)
- goto out;
-
- if ((limit & APE1_FIXED_BITS_MASK) != APE1_LIMIT_ALIGNMENT)
+ if (limit <= base || (base & APE1_FIXED_BITS_MASK) != 0 ||
+ (limit & APE1_FIXED_BITS_MASK) != APE1_LIMIT_ALIGNMENT) {
+ retval = false;
goto out;
+ }
qpd->sh_mem_ape1_base = base >> 16;
qpd->sh_mem_ape1_limit = limit >> 16;
@@ -1151,27 +1079,22 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm,
if ((sched_policy == KFD_SCHED_POLICY_NO_HWS) && (qpd->vmid != 0))
program_sh_mem_settings(dqm, qpd);
- pr_debug("kfd: sh_mem_config: 0x%x, ape1_base: 0x%x, ape1_limit: 0x%x\n",
+ pr_debug("sh_mem_config: 0x%x, ape1_base: 0x%x, ape1_limit: 0x%x\n",
qpd->sh_mem_config, qpd->sh_mem_ape1_base,
qpd->sh_mem_ape1_limit);
- mutex_unlock(&dqm->lock);
- return retval;
-
out:
mutex_unlock(&dqm->lock);
- return false;
+ return retval;
}
struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
{
struct device_queue_manager *dqm;
- BUG_ON(!dev);
+ pr_debug("Loading device queue manager\n");
- pr_debug("kfd: loading device queue manager\n");
-
- dqm = kzalloc(sizeof(struct device_queue_manager), GFP_KERNEL);
+ dqm = kzalloc(sizeof(*dqm), GFP_KERNEL);
if (!dqm)
return NULL;
@@ -1209,8 +1132,8 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
dqm->ops.set_cache_memory_policy = set_cache_memory_policy;
break;
default:
- BUG();
- break;
+ pr_err("Invalid scheduling policy %d\n", sched_policy);
+ goto out_free;
}
switch (dev->device_info->asic_family) {
@@ -1223,18 +1146,16 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
break;
}
- if (dqm->ops.initialize(dqm) != 0) {
- kfree(dqm);
- return NULL;
- }
+ if (!dqm->ops.initialize(dqm))
+ return dqm;
- return dqm;
+out_free:
+ kfree(dqm);
+ return NULL;
}
void device_queue_manager_uninit(struct device_queue_manager *dqm)
{
- BUG_ON(!dqm);
-
dqm->ops.uninitialize(dqm);
kfree(dqm);
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
index 66b9615bc3c1..faf820a06400 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
@@ -180,7 +180,6 @@ void device_queue_manager_init_cik(struct device_queue_manager_asic_ops *ops);
void device_queue_manager_init_vi(struct device_queue_manager_asic_ops *ops);
void program_sh_mem_settings(struct device_queue_manager *dqm,
struct qcm_process_device *qpd);
-unsigned int get_mec_num(struct device_queue_manager *dqm);
unsigned int get_queues_num(struct device_queue_manager *dqm);
unsigned int get_queues_per_pipe(struct device_queue_manager *dqm);
unsigned int get_pipes_per_mec(struct device_queue_manager *dqm);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c
index 48dc0561b402..72c3cbabc0a7 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c
@@ -24,6 +24,7 @@
#include "kfd_device_queue_manager.h"
#include "cik_regs.h"
#include "oss/oss_2_4_sh_mask.h"
+#include "gca/gfx_7_2_sh_mask.h"
static bool set_cache_memory_policy_cik(struct device_queue_manager *dqm,
struct qcm_process_device *qpd,
@@ -65,7 +66,7 @@ static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble)
* for LDS/Scratch and GPUVM.
*/
- BUG_ON((top_address_nybble & 1) || top_address_nybble > 0xE ||
+ WARN_ON((top_address_nybble & 1) || top_address_nybble > 0xE ||
top_address_nybble == 0);
return PRIVATE_BASE(top_address_nybble << 12) |
@@ -104,8 +105,6 @@ static int register_process_cik(struct device_queue_manager *dqm,
struct kfd_process_device *pdd;
unsigned int temp;
- BUG_ON(!dqm || !qpd);
-
pdd = qpd_to_pdd(qpd);
/* check if sh_mem_config register already configured */
@@ -125,9 +124,10 @@ static int register_process_cik(struct device_queue_manager *dqm,
} else {
temp = get_sh_mem_bases_nybble_64(pdd);
qpd->sh_mem_bases = compute_sh_mem_bases_64bit(temp);
+ qpd->sh_mem_config |= 1 << SH_MEM_CONFIG__PRIVATE_ATC__SHIFT;
}
- pr_debug("kfd: is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n",
+ pr_debug("is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n",
qpd->pqm->process->is_32bit_user_mode, temp, qpd->sh_mem_bases);
return 0;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c
index 7e9cae9d349b..40e9ddd096cd 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c
@@ -67,7 +67,7 @@ static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble)
* for LDS/Scratch and GPUVM.
*/
- BUG_ON((top_address_nybble & 1) || top_address_nybble > 0xE ||
+ WARN_ON((top_address_nybble & 1) || top_address_nybble > 0xE ||
top_address_nybble == 0);
return top_address_nybble << 12 |
@@ -110,8 +110,6 @@ static int register_process_vi(struct device_queue_manager *dqm,
struct kfd_process_device *pdd;
unsigned int temp;
- BUG_ON(!dqm || !qpd);
-
pdd = qpd_to_pdd(qpd);
/* check if sh_mem_config register already configured */
@@ -137,9 +135,11 @@ static int register_process_vi(struct device_queue_manager *dqm,
qpd->sh_mem_bases = compute_sh_mem_bases_64bit(temp);
qpd->sh_mem_config |= SH_MEM_ADDRESS_MODE_HSA64 <<
SH_MEM_CONFIG__ADDRESS_MODE__SHIFT;
+ qpd->sh_mem_config |= 1 <<
+ SH_MEM_CONFIG__PRIVATE_ATC__SHIFT;
}
- pr_debug("kfd: is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n",
+ pr_debug("is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n",
qpd->pqm->process->is_32bit_user_mode, temp, qpd->sh_mem_bases);
return 0;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
index 453c5d66e5c3..acf4d2a977ad 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
@@ -59,7 +59,7 @@ static inline size_t doorbell_process_allocation(void)
}
/* Doorbell calculations for device init. */
-void kfd_doorbell_init(struct kfd_dev *kfd)
+int kfd_doorbell_init(struct kfd_dev *kfd)
{
size_t doorbell_start_offset;
size_t doorbell_aperture_size;
@@ -95,26 +95,35 @@ void kfd_doorbell_init(struct kfd_dev *kfd)
kfd->doorbell_kernel_ptr = ioremap(kfd->doorbell_base,
doorbell_process_allocation());
- BUG_ON(!kfd->doorbell_kernel_ptr);
+ if (!kfd->doorbell_kernel_ptr)
+ return -ENOMEM;
- pr_debug("kfd: doorbell initialization:\n");
- pr_debug("kfd: doorbell base == 0x%08lX\n",
+ pr_debug("Doorbell initialization:\n");
+ pr_debug("doorbell base == 0x%08lX\n",
(uintptr_t)kfd->doorbell_base);
- pr_debug("kfd: doorbell_id_offset == 0x%08lX\n",
+ pr_debug("doorbell_id_offset == 0x%08lX\n",
kfd->doorbell_id_offset);
- pr_debug("kfd: doorbell_process_limit == 0x%08lX\n",
+ pr_debug("doorbell_process_limit == 0x%08lX\n",
doorbell_process_limit);
- pr_debug("kfd: doorbell_kernel_offset == 0x%08lX\n",
+ pr_debug("doorbell_kernel_offset == 0x%08lX\n",
(uintptr_t)kfd->doorbell_base);
- pr_debug("kfd: doorbell aperture size == 0x%08lX\n",
+ pr_debug("doorbell aperture size == 0x%08lX\n",
kfd->shared_resources.doorbell_aperture_size);
- pr_debug("kfd: doorbell kernel address == 0x%08lX\n",
+ pr_debug("doorbell kernel address == 0x%08lX\n",
(uintptr_t)kfd->doorbell_kernel_ptr);
+
+ return 0;
+}
+
+void kfd_doorbell_fini(struct kfd_dev *kfd)
+{
+ if (kfd->doorbell_kernel_ptr)
+ iounmap(kfd->doorbell_kernel_ptr);
}
int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma)
@@ -131,7 +140,7 @@ int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma)
/* Find kfd device according to gpu id */
dev = kfd_device_by_id(vma->vm_pgoff);
- if (dev == NULL)
+ if (!dev)
return -EINVAL;
/* Calculate physical address of doorbell */
@@ -142,12 +151,11 @@ int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma)
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- pr_debug("kfd: mapping doorbell page in %s\n"
+ pr_debug("Mapping doorbell page\n"
" target user address == 0x%08llX\n"
" physical address == 0x%08llX\n"
" vm_flags == 0x%04lX\n"
" size == 0x%04lX\n",
- __func__,
(unsigned long long) vma->vm_start, address, vma->vm_flags,
doorbell_process_allocation());
@@ -166,8 +174,6 @@ u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
{
u32 inx;
- BUG_ON(!kfd || !doorbell_off);
-
mutex_lock(&kfd->doorbell_mutex);
inx = find_first_zero_bit(kfd->doorbell_available_index,
KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
@@ -185,7 +191,7 @@ u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
*doorbell_off = KERNEL_DOORBELL_PASID * (doorbell_process_allocation() /
sizeof(u32)) + inx;
- pr_debug("kfd: get kernel queue doorbell\n"
+ pr_debug("Get kernel queue doorbell\n"
" doorbell offset == 0x%08X\n"
" kernel address == 0x%08lX\n",
*doorbell_off, (uintptr_t)(kfd->doorbell_kernel_ptr + inx));
@@ -197,8 +203,6 @@ void kfd_release_kernel_doorbell(struct kfd_dev *kfd, u32 __iomem *db_addr)
{
unsigned int inx;
- BUG_ON(!kfd || !db_addr);
-
inx = (unsigned int)(db_addr - kfd->doorbell_kernel_ptr);
mutex_lock(&kfd->doorbell_mutex);
@@ -210,7 +214,7 @@ inline void write_kernel_doorbell(u32 __iomem *db, u32 value)
{
if (db) {
writel(value, db);
- pr_debug("writing %d to doorbell address 0x%p\n", value, db);
+ pr_debug("Writing %d to doorbell address 0x%p\n", value, db);
}
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
index d1ce83d73a87..5979158c3f7b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
@@ -110,7 +110,7 @@ static bool allocate_free_slot(struct kfd_process *process,
*out_page = page;
*out_slot_index = slot;
- pr_debug("allocated event signal slot in page %p, slot %d\n",
+ pr_debug("Allocated event signal slot in page %p, slot %d\n",
page, slot);
return true;
@@ -155,9 +155,9 @@ static bool allocate_signal_page(struct file *devkfd, struct kfd_process *p)
struct signal_page,
event_pages)->page_index + 1;
- pr_debug("allocated new event signal page at %p, for process %p\n",
+ pr_debug("Allocated new event signal page at %p, for process %p\n",
page, p);
- pr_debug("page index is %d\n", page->page_index);
+ pr_debug("Page index is %d\n", page->page_index);
list_add(&page->event_pages, &p->signal_event_pages);
@@ -194,7 +194,8 @@ static void release_event_notification_slot(struct signal_page *page,
page->free_slots++;
/* We don't free signal pages, they are retained by the process
- * and reused until it exits. */
+ * and reused until it exits.
+ */
}
static struct signal_page *lookup_signal_page_by_index(struct kfd_process *p,
@@ -246,7 +247,7 @@ static u32 make_nonsignal_event_id(struct kfd_process *p)
for (id = p->next_nonsignal_event_id;
id < KFD_LAST_NONSIGNAL_EVENT_ID &&
- lookup_event_by_id(p, id) != NULL;
+ lookup_event_by_id(p, id);
id++)
;
@@ -265,7 +266,7 @@ static u32 make_nonsignal_event_id(struct kfd_process *p)
for (id = KFD_FIRST_NONSIGNAL_EVENT_ID;
id < KFD_LAST_NONSIGNAL_EVENT_ID &&
- lookup_event_by_id(p, id) != NULL;
+ lookup_event_by_id(p, id);
id++)
;
@@ -291,13 +292,13 @@ static int create_signal_event(struct file *devkfd,
struct kfd_event *ev)
{
if (p->signal_event_count == KFD_SIGNAL_EVENT_LIMIT) {
- pr_warn("amdkfd: Signal event wasn't created because limit was reached\n");
+ pr_warn("Signal event wasn't created because limit was reached\n");
return -ENOMEM;
}
if (!allocate_event_notification_slot(devkfd, p, &ev->signal_page,
&ev->signal_slot_index)) {
- pr_warn("amdkfd: Signal event wasn't created because out of kernel memory\n");
+ pr_warn("Signal event wasn't created because out of kernel memory\n");
return -ENOMEM;
}
@@ -309,11 +310,7 @@ static int create_signal_event(struct file *devkfd,
ev->event_id = make_signal_event_id(ev->signal_page,
ev->signal_slot_index);
- pr_debug("signal event number %zu created with id %d, address %p\n",
- p->signal_event_count, ev->event_id,
- ev->user_signal_address);
-
- pr_debug("signal event number %zu created with id %d, address %p\n",
+ pr_debug("Signal event number %zu created with id %d, address %p\n",
p->signal_event_count, ev->event_id,
ev->user_signal_address);
@@ -345,7 +342,7 @@ void kfd_event_init_process(struct kfd_process *p)
static void destroy_event(struct kfd_process *p, struct kfd_event *ev)
{
- if (ev->signal_page != NULL) {
+ if (ev->signal_page) {
release_event_notification_slot(ev->signal_page,
ev->signal_slot_index);
p->signal_event_count--;
@@ -584,7 +581,7 @@ void kfd_signal_event_interrupt(unsigned int pasid, uint32_t partial_id,
* search faster.
*/
struct signal_page *page;
- unsigned i;
+ unsigned int i;
list_for_each_entry(page, &p->signal_event_pages, event_pages)
for (i = 0; i < SLOTS_PER_PAGE; i++)
@@ -816,7 +813,7 @@ int kfd_event_mmap(struct kfd_process *p, struct vm_area_struct *vma)
/* check required size is logical */
if (get_order(KFD_SIGNAL_EVENT_LIMIT * 8) !=
get_order(vma->vm_end - vma->vm_start)) {
- pr_err("amdkfd: event page mmap requested illegal size\n");
+ pr_err("Event page mmap requested illegal size\n");
return -EINVAL;
}
@@ -825,7 +822,7 @@ int kfd_event_mmap(struct kfd_process *p, struct vm_area_struct *vma)
page = lookup_signal_page_by_index(p, page_index);
if (!page) {
/* Probably KFD bug, but mmap is user-accessible. */
- pr_debug("signal page could not be found for page_index %u\n",
+ pr_debug("Signal page could not be found for page_index %u\n",
page_index);
return -EINVAL;
}
@@ -836,7 +833,7 @@ int kfd_event_mmap(struct kfd_process *p, struct vm_area_struct *vma)
vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE
| VM_DONTDUMP | VM_PFNMAP;
- pr_debug("mapping signal page\n");
+ pr_debug("Mapping signal page\n");
pr_debug(" start user address == 0x%08lx\n", vma->vm_start);
pr_debug(" end user address == 0x%08lx\n", vma->vm_end);
pr_debug(" pfn == 0x%016lX\n", pfn);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
index 2b655103ba79..c59384bbbc5f 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
@@ -304,7 +304,7 @@ int kfd_init_apertures(struct kfd_process *process)
id < NUM_OF_SUPPORTED_GPUS) {
pdd = kfd_create_process_device_data(dev, process);
- if (pdd == NULL) {
+ if (!pdd) {
pr_err("Failed to create process device data\n");
return -1;
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
index 7f134aa9bfd3..70b3a99cffc2 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
@@ -179,7 +179,7 @@ static void interrupt_wq(struct work_struct *work)
bool interrupt_is_wanted(struct kfd_dev *dev, const uint32_t *ih_ring_entry)
{
/* integer and bitwise OR so there is no boolean short-circuiting */
- unsigned wanted = 0;
+ unsigned int wanted = 0;
wanted |= dev->device_info->event_interrupt_class->interrupt_isr(dev,
ih_ring_entry);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
index d135cd002a95..681b639f5133 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
@@ -41,11 +41,11 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
int retval;
union PM4_MES_TYPE_3_HEADER nop;
- BUG_ON(!kq || !dev);
- BUG_ON(type != KFD_QUEUE_TYPE_DIQ && type != KFD_QUEUE_TYPE_HIQ);
+ if (WARN_ON(type != KFD_QUEUE_TYPE_DIQ && type != KFD_QUEUE_TYPE_HIQ))
+ return false;
- pr_debug("amdkfd: In func %s initializing queue type %d size %d\n",
- __func__, KFD_QUEUE_TYPE_HIQ, queue_size);
+ pr_debug("Initializing queue type %d size %d\n", KFD_QUEUE_TYPE_HIQ,
+ queue_size);
memset(&prop, 0, sizeof(prop));
memset(&nop, 0, sizeof(nop));
@@ -63,23 +63,23 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
KFD_MQD_TYPE_HIQ);
break;
default:
- BUG();
- break;
+ pr_err("Invalid queue type %d\n", type);
+ return false;
}
- if (kq->mqd == NULL)
+ if (!kq->mqd)
return false;
prop.doorbell_ptr = kfd_get_kernel_doorbell(dev, &prop.doorbell_off);
- if (prop.doorbell_ptr == NULL) {
- pr_err("amdkfd: error init doorbell");
+ if (!prop.doorbell_ptr) {
+ pr_err("Failed to initialize doorbell");
goto err_get_kernel_doorbell;
}
retval = kfd_gtt_sa_allocate(dev, queue_size, &kq->pq);
if (retval != 0) {
- pr_err("amdkfd: error init pq queues size (%d)\n", queue_size);
+ pr_err("Failed to init pq queues size %d\n", queue_size);
goto err_pq_allocate_vidmem;
}
@@ -87,7 +87,7 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
kq->pq_gpu_addr = kq->pq->gpu_addr;
retval = kq->ops_asic_specific.initialize(kq, dev, type, queue_size);
- if (retval == false)
+ if (!retval)
goto err_eop_allocate_vidmem;
retval = kfd_gtt_sa_allocate(dev, sizeof(*kq->rptr_kernel),
@@ -139,11 +139,12 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
/* assign HIQ to HQD */
if (type == KFD_QUEUE_TYPE_HIQ) {
- pr_debug("assigning hiq to hqd\n");
+ pr_debug("Assigning hiq to hqd\n");
kq->queue->pipe = KFD_CIK_HIQ_PIPE;
kq->queue->queue = KFD_CIK_HIQ_QUEUE;
kq->mqd->load_mqd(kq->mqd, kq->queue->mqd, kq->queue->pipe,
- kq->queue->queue, NULL);
+ kq->queue->queue, &kq->queue->properties,
+ NULL);
} else {
/* allocate fence for DIQ */
@@ -180,8 +181,6 @@ err_get_kernel_doorbell:
static void uninitialize(struct kernel_queue *kq)
{
- BUG_ON(!kq);
-
if (kq->queue->properties.type == KFD_QUEUE_TYPE_HIQ)
kq->mqd->destroy_mqd(kq->mqd,
NULL,
@@ -211,8 +210,6 @@ static int acquire_packet_buffer(struct kernel_queue *kq,
uint32_t wptr, rptr;
unsigned int *queue_address;
- BUG_ON(!kq || !buffer_ptr);
-
rptr = *kq->rptr_kernel;
wptr = *kq->wptr_kernel;
queue_address = (unsigned int *)kq->pq_kernel_addr;
@@ -252,11 +249,7 @@ static void submit_packet(struct kernel_queue *kq)
{
#ifdef DEBUG
int i;
-#endif
-
- BUG_ON(!kq);
-#ifdef DEBUG
for (i = *kq->wptr_kernel; i < kq->pending_wptr; i++) {
pr_debug("0x%2X ", kq->pq_kernel_addr[i]);
if (i % 15 == 0)
@@ -272,7 +265,6 @@ static void submit_packet(struct kernel_queue *kq)
static void rollback_packet(struct kernel_queue *kq)
{
- BUG_ON(!kq);
kq->pending_wptr = *kq->queue->properties.write_ptr;
}
@@ -281,9 +273,7 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
{
struct kernel_queue *kq;
- BUG_ON(!dev);
-
- kq = kzalloc(sizeof(struct kernel_queue), GFP_KERNEL);
+ kq = kzalloc(sizeof(*kq), GFP_KERNEL);
if (!kq)
return NULL;
@@ -304,7 +294,7 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
}
if (!kq->ops.initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE)) {
- pr_err("amdkfd: failed to init kernel queue\n");
+ pr_err("Failed to init kernel queue\n");
kfree(kq);
return NULL;
}
@@ -313,32 +303,37 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
void kernel_queue_uninit(struct kernel_queue *kq)
{
- BUG_ON(!kq);
-
kq->ops.uninitialize(kq);
kfree(kq);
}
+/* FIXME: Can this test be removed? */
static __attribute__((unused)) void test_kq(struct kfd_dev *dev)
{
struct kernel_queue *kq;
uint32_t *buffer, i;
int retval;
- BUG_ON(!dev);
-
- pr_err("amdkfd: starting kernel queue test\n");
+ pr_err("Starting kernel queue test\n");
kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ);
- BUG_ON(!kq);
+ if (unlikely(!kq)) {
+ pr_err(" Failed to initialize HIQ\n");
+ pr_err("Kernel queue test failed\n");
+ return;
+ }
retval = kq->ops.acquire_packet_buffer(kq, 5, &buffer);
- BUG_ON(retval != 0);
+ if (unlikely(retval != 0)) {
+ pr_err(" Failed to acquire packet buffer\n");
+ pr_err("Kernel queue test failed\n");
+ return;
+ }
for (i = 0; i < 5; i++)
buffer[i] = kq->nop_packet;
kq->ops.submit_packet(kq);
- pr_err("amdkfd: ending kernel queue test\n");
+ pr_err("Ending kernel queue test\n");
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c
index 850a5623661f..0d73bea22c45 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_module.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c
@@ -61,7 +61,8 @@ MODULE_PARM_DESC(send_sigterm,
static int amdkfd_init_completed;
-int kgd2kfd_init(unsigned interface_version, const struct kgd2kfd_calls **g2f)
+int kgd2kfd_init(unsigned int interface_version,
+ const struct kgd2kfd_calls **g2f)
{
if (!amdkfd_init_completed)
return -EPROBE_DEFER;
@@ -90,7 +91,7 @@ static int __init kfd_module_init(void)
/* Verify module parameters */
if ((sched_policy < KFD_SCHED_POLICY_HWS) ||
(sched_policy > KFD_SCHED_POLICY_NO_HWS)) {
- pr_err("kfd: sched_policy has invalid value\n");
+ pr_err("sched_policy has invalid value\n");
return -1;
}
@@ -98,13 +99,13 @@ static int __init kfd_module_init(void)
if ((max_num_of_queues_per_device < 1) ||
(max_num_of_queues_per_device >
KFD_MAX_NUM_OF_QUEUES_PER_DEVICE)) {
- pr_err("kfd: max_num_of_queues_per_device must be between 1 to KFD_MAX_NUM_OF_QUEUES_PER_DEVICE\n");
+ pr_err("max_num_of_queues_per_device must be between 1 to KFD_MAX_NUM_OF_QUEUES_PER_DEVICE\n");
return -1;
}
err = kfd_pasid_init();
if (err < 0)
- goto err_pasid;
+ return err;
err = kfd_chardev_init();
if (err < 0)
@@ -126,7 +127,6 @@ err_topology:
kfd_chardev_exit();
err_ioctl:
kfd_pasid_exit();
-err_pasid:
return err;
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
index 213a71e0b6c7..1f3a6ba7eed2 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
@@ -67,7 +67,8 @@ struct mqd_manager {
int (*load_mqd)(struct mqd_manager *mm, void *mqd,
uint32_t pipe_id, uint32_t queue_id,
- uint32_t __user *wptr);
+ struct queue_properties *p,
+ struct mm_struct *mms);
int (*update_mqd)(struct mqd_manager *mm, void *mqd,
struct queue_properties *q);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
index 6acc4313363e..44ffd23348fc 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
@@ -44,10 +44,6 @@ static int init_mqd(struct mqd_manager *mm, void **mqd,
struct cik_mqd *m;
int retval;
- BUG_ON(!mm || !q || !mqd);
-
- pr_debug("kfd: In func %s\n", __func__);
-
retval = kfd_gtt_sa_allocate(mm->dev, sizeof(struct cik_mqd),
mqd_mem_obj);
@@ -101,7 +97,7 @@ static int init_mqd(struct mqd_manager *mm, void **mqd,
m->cp_hqd_iq_rptr = AQL_ENABLE;
*mqd = m;
- if (gart_addr != NULL)
+ if (gart_addr)
*gart_addr = addr;
retval = mm->update_mqd(mm, m, q);
@@ -115,8 +111,6 @@ static int init_mqd_sdma(struct mqd_manager *mm, void **mqd,
int retval;
struct cik_sdma_rlc_registers *m;
- BUG_ON(!mm || !mqd || !mqd_mem_obj);
-
retval = kfd_gtt_sa_allocate(mm->dev,
sizeof(struct cik_sdma_rlc_registers),
mqd_mem_obj);
@@ -129,7 +123,7 @@ static int init_mqd_sdma(struct mqd_manager *mm, void **mqd,
memset(m, 0, sizeof(struct cik_sdma_rlc_registers));
*mqd = m;
- if (gart_addr != NULL)
+ if (gart_addr)
*gart_addr = (*mqd_mem_obj)->gpu_addr;
retval = mm->update_mqd(mm, m, q);
@@ -140,27 +134,31 @@ static int init_mqd_sdma(struct mqd_manager *mm, void **mqd,
static void uninit_mqd(struct mqd_manager *mm, void *mqd,
struct kfd_mem_obj *mqd_mem_obj)
{
- BUG_ON(!mm || !mqd);
kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
}
static void uninit_mqd_sdma(struct mqd_manager *mm, void *mqd,
struct kfd_mem_obj *mqd_mem_obj)
{
- BUG_ON(!mm || !mqd);
kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
}
static int load_mqd(struct mqd_manager *mm, void *mqd, uint32_t pipe_id,
- uint32_t queue_id, uint32_t __user *wptr)
+ uint32_t queue_id, struct queue_properties *p,
+ struct mm_struct *mms)
{
- return mm->dev->kfd2kgd->hqd_load
- (mm->dev->kgd, mqd, pipe_id, queue_id, wptr);
+ /* AQL write pointer counts in 64B packets, PM4/CP counts in dwords. */
+ uint32_t wptr_shift = (p->format == KFD_QUEUE_FORMAT_AQL ? 4 : 0);
+ uint32_t wptr_mask = (uint32_t)((p->queue_size / sizeof(uint32_t)) - 1);
+
+ return mm->dev->kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id,
+ (uint32_t __user *)p->write_ptr,
+ wptr_shift, wptr_mask, mms);
}
static int load_mqd_sdma(struct mqd_manager *mm, void *mqd,
- uint32_t pipe_id, uint32_t queue_id,
- uint32_t __user *wptr)
+ uint32_t pipe_id, uint32_t queue_id,
+ struct queue_properties *p, struct mm_struct *mms)
{
return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd);
}
@@ -170,10 +168,6 @@ static int update_mqd(struct mqd_manager *mm, void *mqd,
{
struct cik_mqd *m;
- BUG_ON(!mm || !q || !mqd);
-
- pr_debug("kfd: In func %s\n", __func__);
-
m = get_mqd(mqd);
m->cp_hqd_pq_control = DEFAULT_RPTR_BLOCK_SIZE |
DEFAULT_MIN_AVAIL_SIZE | PQ_ATC_EN;
@@ -188,21 +182,17 @@ static int update_mqd(struct mqd_manager *mm, void *mqd,
m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8);
m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr);
m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
- m->cp_hqd_pq_doorbell_control = DOORBELL_EN |
- DOORBELL_OFFSET(q->doorbell_off);
+ m->cp_hqd_pq_doorbell_control = DOORBELL_OFFSET(q->doorbell_off);
m->cp_hqd_vmid = q->vmid;
- if (q->format == KFD_QUEUE_FORMAT_AQL) {
+ if (q->format == KFD_QUEUE_FORMAT_AQL)
m->cp_hqd_pq_control |= NO_UPDATE_RPTR;
- }
- m->cp_hqd_active = 0;
q->is_active = false;
if (q->queue_size > 0 &&
q->queue_address != 0 &&
q->queue_percent > 0) {
- m->cp_hqd_active = 1;
q->is_active = true;
}
@@ -214,8 +204,6 @@ static int update_mqd_sdma(struct mqd_manager *mm, void *mqd,
{
struct cik_sdma_rlc_registers *m;
- BUG_ON(!mm || !mqd || !q);
-
m = get_sdma_mqd(mqd);
m->sdma_rlc_rb_cntl = ffs(q->queue_size / sizeof(unsigned int)) <<
SDMA0_RLC0_RB_CNTL__RB_SIZE__SHIFT |
@@ -254,7 +242,7 @@ static int destroy_mqd(struct mqd_manager *mm, void *mqd,
unsigned int timeout, uint32_t pipe_id,
uint32_t queue_id)
{
- return mm->dev->kfd2kgd->hqd_destroy(mm->dev->kgd, type, timeout,
+ return mm->dev->kfd2kgd->hqd_destroy(mm->dev->kgd, mqd, type, timeout,
pipe_id, queue_id);
}
@@ -301,10 +289,6 @@ static int init_mqd_hiq(struct mqd_manager *mm, void **mqd,
struct cik_mqd *m;
int retval;
- BUG_ON(!mm || !q || !mqd || !mqd_mem_obj);
-
- pr_debug("kfd: In func %s\n", __func__);
-
retval = kfd_gtt_sa_allocate(mm->dev, sizeof(struct cik_mqd),
mqd_mem_obj);
@@ -359,10 +343,6 @@ static int update_mqd_hiq(struct mqd_manager *mm, void *mqd,
{
struct cik_mqd *m;
- BUG_ON(!mm || !q || !mqd);
-
- pr_debug("kfd: In func %s\n", __func__);
-
m = get_mqd(mqd);
m->cp_hqd_pq_control = DEFAULT_RPTR_BLOCK_SIZE |
DEFAULT_MIN_AVAIL_SIZE |
@@ -400,8 +380,6 @@ struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd)
{
struct cik_sdma_rlc_registers *m;
- BUG_ON(!mqd);
-
m = (struct cik_sdma_rlc_registers *)mqd;
return m;
@@ -412,12 +390,10 @@ struct mqd_manager *mqd_manager_init_cik(enum KFD_MQD_TYPE type,
{
struct mqd_manager *mqd;
- BUG_ON(!dev);
- BUG_ON(type >= KFD_MQD_TYPE_MAX);
-
- pr_debug("kfd: In func %s\n", __func__);
+ if (WARN_ON(type >= KFD_MQD_TYPE_MAX))
+ return NULL;
- mqd = kzalloc(sizeof(struct mqd_manager), GFP_KERNEL);
+ mqd = kzalloc(sizeof(*mqd), GFP_KERNEL);
if (!mqd)
return NULL;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
index a9b9882a9a77..73cbfe186dd2 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
@@ -85,7 +85,7 @@ static int init_mqd(struct mqd_manager *mm, void **mqd,
m->cp_hqd_iq_rptr = 1;
*mqd = m;
- if (gart_addr != NULL)
+ if (gart_addr)
*gart_addr = addr;
retval = mm->update_mqd(mm, m, q);
@@ -94,10 +94,15 @@ static int init_mqd(struct mqd_manager *mm, void **mqd,
static int load_mqd(struct mqd_manager *mm, void *mqd,
uint32_t pipe_id, uint32_t queue_id,
- uint32_t __user *wptr)
+ struct queue_properties *p, struct mm_struct *mms)
{
- return mm->dev->kfd2kgd->hqd_load
- (mm->dev->kgd, mqd, pipe_id, queue_id, wptr);
+ /* AQL write pointer counts in 64B packets, PM4/CP counts in dwords. */
+ uint32_t wptr_shift = (p->format == KFD_QUEUE_FORMAT_AQL ? 4 : 0);
+ uint32_t wptr_mask = (uint32_t)((p->queue_size / sizeof(uint32_t)) - 1);
+
+ return mm->dev->kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id,
+ (uint32_t __user *)p->write_ptr,
+ wptr_shift, wptr_mask, mms);
}
static int __update_mqd(struct mqd_manager *mm, void *mqd,
@@ -106,10 +111,6 @@ static int __update_mqd(struct mqd_manager *mm, void *mqd,
{
struct vi_mqd *m;
- BUG_ON(!mm || !q || !mqd);
-
- pr_debug("kfd: In func %s\n", __func__);
-
m = get_mqd(mqd);
m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT |
@@ -117,7 +118,7 @@ static int __update_mqd(struct mqd_manager *mm, void *mqd,
mtype << CP_HQD_PQ_CONTROL__MTYPE__SHIFT;
m->cp_hqd_pq_control |=
ffs(q->queue_size / sizeof(unsigned int)) - 1 - 1;
- pr_debug("kfd: cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control);
+ pr_debug("cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control);
m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8);
@@ -126,10 +127,9 @@ static int __update_mqd(struct mqd_manager *mm, void *mqd,
m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
m->cp_hqd_pq_doorbell_control =
- 1 << CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_EN__SHIFT |
q->doorbell_off <<
CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT;
- pr_debug("kfd: cp_hqd_pq_doorbell_control 0x%x\n",
+ pr_debug("cp_hqd_pq_doorbell_control 0x%x\n",
m->cp_hqd_pq_doorbell_control);
m->cp_hqd_eop_control = atc_bit << CP_HQD_EOP_CONTROL__EOP_ATC__SHIFT |
@@ -139,8 +139,15 @@ static int __update_mqd(struct mqd_manager *mm, void *mqd,
3 << CP_HQD_IB_CONTROL__MIN_IB_AVAIL_SIZE__SHIFT |
mtype << CP_HQD_IB_CONTROL__MTYPE__SHIFT;
- m->cp_hqd_eop_control |=
- ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1;
+ /*
+ * HW does not clamp this field correctly. Maximum EOP queue size
+ * is constrained by per-SE EOP done signal count, which is 8-bit.
+ * Limit is 0xFF EOP entries (= 0x7F8 dwords). CP will not submit
+ * more than (EOP entry count - 1) so a queue size of 0x800 dwords
+ * is safe, giving a maximum field value of 0xA.
+ */
+ m->cp_hqd_eop_control |= min(0xA,
+ ffs(q->eop_ring_buffer_size / sizeof(unsigned int)) - 1 - 1);
m->cp_hqd_eop_base_addr_lo =
lower_32_bits(q->eop_ring_buffer_address >> 8);
m->cp_hqd_eop_base_addr_hi =
@@ -156,12 +163,10 @@ static int __update_mqd(struct mqd_manager *mm, void *mqd,
2 << CP_HQD_PQ_CONTROL__SLOT_BASED_WPTR__SHIFT;
}
- m->cp_hqd_active = 0;
q->is_active = false;
if (q->queue_size > 0 &&
q->queue_address != 0 &&
q->queue_percent > 0) {
- m->cp_hqd_active = 1;
q->is_active = true;
}
@@ -181,14 +186,13 @@ static int destroy_mqd(struct mqd_manager *mm, void *mqd,
uint32_t queue_id)
{
return mm->dev->kfd2kgd->hqd_destroy
- (mm->dev->kgd, type, timeout,
+ (mm->dev->kgd, mqd, type, timeout,
pipe_id, queue_id);
}
static void uninit_mqd(struct mqd_manager *mm, void *mqd,
struct kfd_mem_obj *mqd_mem_obj)
{
- BUG_ON(!mm || !mqd);
kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
}
@@ -238,12 +242,10 @@ struct mqd_manager *mqd_manager_init_vi(enum KFD_MQD_TYPE type,
{
struct mqd_manager *mqd;
- BUG_ON(!dev);
- BUG_ON(type >= KFD_MQD_TYPE_MAX);
-
- pr_debug("kfd: In func %s\n", __func__);
+ if (WARN_ON(type >= KFD_MQD_TYPE_MAX))
+ return NULL;
- mqd = kzalloc(sizeof(struct mqd_manager), GFP_KERNEL);
+ mqd = kzalloc(sizeof(*mqd), GFP_KERNEL);
if (!mqd)
return NULL;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
index 7131998848d7..1d312603de9f 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
@@ -26,7 +26,6 @@
#include "kfd_device_queue_manager.h"
#include "kfd_kernel_queue.h"
#include "kfd_priv.h"
-#include "kfd_pm4_headers.h"
#include "kfd_pm4_headers_vi.h"
#include "kfd_pm4_opcodes.h"
@@ -35,7 +34,8 @@ static inline void inc_wptr(unsigned int *wptr, unsigned int increment_bytes,
{
unsigned int temp = *wptr + increment_bytes / sizeof(uint32_t);
- BUG_ON((temp * sizeof(uint32_t)) > buffer_size_bytes);
+ WARN((temp * sizeof(uint32_t)) > buffer_size_bytes,
+ "Runlist IB overflow");
*wptr = temp;
}
@@ -43,12 +43,12 @@ static unsigned int build_pm4_header(unsigned int opcode, size_t packet_size)
{
union PM4_MES_TYPE_3_HEADER header;
- header.u32all = 0;
+ header.u32All = 0;
header.opcode = opcode;
header.count = packet_size/sizeof(uint32_t) - 2;
header.type = PM4_TYPE_3;
- return header.u32all;
+ return header.u32All;
}
static void pm_calc_rlib_size(struct packet_manager *pm,
@@ -58,8 +58,6 @@ static void pm_calc_rlib_size(struct packet_manager *pm,
unsigned int process_count, queue_count;
unsigned int map_queue_size;
- BUG_ON(!pm || !rlib_size || !over_subscription);
-
process_count = pm->dqm->processes_count;
queue_count = pm->dqm->queue_count;
@@ -67,15 +65,12 @@ static void pm_calc_rlib_size(struct packet_manager *pm,
*over_subscription = false;
if ((process_count > 1) || queue_count > get_queues_num(pm->dqm)) {
*over_subscription = true;
- pr_debug("kfd: over subscribed runlist\n");
+ pr_debug("Over subscribed runlist\n");
}
- map_queue_size =
- (pm->dqm->dev->device_info->asic_family == CHIP_CARRIZO) ?
- sizeof(struct pm4_mes_map_queues) :
- sizeof(struct pm4_map_queues);
+ map_queue_size = sizeof(struct pm4_mes_map_queues);
/* calculate run list ib allocation size */
- *rlib_size = process_count * sizeof(struct pm4_map_process) +
+ *rlib_size = process_count * sizeof(struct pm4_mes_map_process) +
queue_count * map_queue_size;
/*
@@ -83,9 +78,9 @@ static void pm_calc_rlib_size(struct packet_manager *pm,
* when over subscription
*/
if (*over_subscription)
- *rlib_size += sizeof(struct pm4_runlist);
+ *rlib_size += sizeof(struct pm4_mes_runlist);
- pr_debug("kfd: runlist ib size %d\n", *rlib_size);
+ pr_debug("runlist ib size %d\n", *rlib_size);
}
static int pm_allocate_runlist_ib(struct packet_manager *pm,
@@ -96,17 +91,16 @@ static int pm_allocate_runlist_ib(struct packet_manager *pm,
{
int retval;
- BUG_ON(!pm);
- BUG_ON(pm->allocated);
- BUG_ON(is_over_subscription == NULL);
+ if (WARN_ON(pm->allocated))
+ return -EINVAL;
pm_calc_rlib_size(pm, rl_buffer_size, is_over_subscription);
retval = kfd_gtt_sa_allocate(pm->dqm->dev, *rl_buffer_size,
&pm->ib_buffer_obj);
- if (retval != 0) {
- pr_err("kfd: failed to allocate runlist IB\n");
+ if (retval) {
+ pr_err("Failed to allocate runlist IB\n");
return retval;
}
@@ -121,15 +115,16 @@ static int pm_allocate_runlist_ib(struct packet_manager *pm,
static int pm_create_runlist(struct packet_manager *pm, uint32_t *buffer,
uint64_t ib, size_t ib_size_in_dwords, bool chain)
{
- struct pm4_runlist *packet;
+ struct pm4_mes_runlist *packet;
- BUG_ON(!pm || !buffer || !ib);
+ if (WARN_ON(!ib))
+ return -EFAULT;
- packet = (struct pm4_runlist *)buffer;
+ packet = (struct pm4_mes_runlist *)buffer;
- memset(buffer, 0, sizeof(struct pm4_runlist));
- packet->header.u32all = build_pm4_header(IT_RUN_LIST,
- sizeof(struct pm4_runlist));
+ memset(buffer, 0, sizeof(struct pm4_mes_runlist));
+ packet->header.u32All = build_pm4_header(IT_RUN_LIST,
+ sizeof(struct pm4_mes_runlist));
packet->bitfields4.ib_size = ib_size_in_dwords;
packet->bitfields4.chain = chain ? 1 : 0;
@@ -144,20 +139,16 @@ static int pm_create_runlist(struct packet_manager *pm, uint32_t *buffer,
static int pm_create_map_process(struct packet_manager *pm, uint32_t *buffer,
struct qcm_process_device *qpd)
{
- struct pm4_map_process *packet;
+ struct pm4_mes_map_process *packet;
struct queue *cur;
uint32_t num_queues;
- BUG_ON(!pm || !buffer || !qpd);
-
- packet = (struct pm4_map_process *)buffer;
-
- pr_debug("kfd: In func %s\n", __func__);
+ packet = (struct pm4_mes_map_process *)buffer;
- memset(buffer, 0, sizeof(struct pm4_map_process));
+ memset(buffer, 0, sizeof(struct pm4_mes_map_process));
- packet->header.u32all = build_pm4_header(IT_MAP_PROCESS,
- sizeof(struct pm4_map_process));
+ packet->header.u32All = build_pm4_header(IT_MAP_PROCESS,
+ sizeof(struct pm4_mes_map_process));
packet->bitfields2.diq_enable = (qpd->is_debug) ? 1 : 0;
packet->bitfields2.process_quantum = 1;
packet->bitfields2.pasid = qpd->pqm->process->pasid;
@@ -175,27 +166,26 @@ static int pm_create_map_process(struct packet_manager *pm, uint32_t *buffer,
packet->sh_mem_ape1_base = qpd->sh_mem_ape1_base;
packet->sh_mem_ape1_limit = qpd->sh_mem_ape1_limit;
+ /* TODO: scratch support */
+ packet->sh_hidden_private_base_vmid = 0;
+
packet->gds_addr_lo = lower_32_bits(qpd->gds_context_area);
packet->gds_addr_hi = upper_32_bits(qpd->gds_context_area);
return 0;
}
-static int pm_create_map_queue_vi(struct packet_manager *pm, uint32_t *buffer,
+static int pm_create_map_queue(struct packet_manager *pm, uint32_t *buffer,
struct queue *q, bool is_static)
{
struct pm4_mes_map_queues *packet;
bool use_static = is_static;
- BUG_ON(!pm || !buffer || !q);
-
- pr_debug("kfd: In func %s\n", __func__);
-
packet = (struct pm4_mes_map_queues *)buffer;
- memset(buffer, 0, sizeof(struct pm4_map_queues));
+ memset(buffer, 0, sizeof(struct pm4_mes_map_queues));
- packet->header.u32all = build_pm4_header(IT_MAP_QUEUES,
- sizeof(struct pm4_map_queues));
+ packet->header.u32All = build_pm4_header(IT_MAP_QUEUES,
+ sizeof(struct pm4_mes_map_queues));
packet->bitfields2.alloc_format =
alloc_format__mes_map_queues__one_per_pipe_vi;
packet->bitfields2.num_queues = 1;
@@ -223,10 +213,8 @@ static int pm_create_map_queue_vi(struct packet_manager *pm, uint32_t *buffer,
use_static = false; /* no static queues under SDMA */
break;
default:
- pr_err("kfd: in %s queue type %d\n", __func__,
- q->properties.type);
- BUG();
- break;
+ WARN(1, "queue type %d", q->properties.type);
+ return -EINVAL;
}
packet->bitfields3.doorbell_offset =
q->properties.doorbell_off;
@@ -246,68 +234,6 @@ static int pm_create_map_queue_vi(struct packet_manager *pm, uint32_t *buffer,
return 0;
}
-static int pm_create_map_queue(struct packet_manager *pm, uint32_t *buffer,
- struct queue *q, bool is_static)
-{
- struct pm4_map_queues *packet;
- bool use_static = is_static;
-
- BUG_ON(!pm || !buffer || !q);
-
- pr_debug("kfd: In func %s\n", __func__);
-
- packet = (struct pm4_map_queues *)buffer;
- memset(buffer, 0, sizeof(struct pm4_map_queues));
-
- packet->header.u32all = build_pm4_header(IT_MAP_QUEUES,
- sizeof(struct pm4_map_queues));
- packet->bitfields2.alloc_format =
- alloc_format__mes_map_queues__one_per_pipe;
- packet->bitfields2.num_queues = 1;
- packet->bitfields2.queue_sel =
- queue_sel__mes_map_queues__map_to_hws_determined_queue_slots;
-
- packet->bitfields2.vidmem = (q->properties.is_interop) ?
- vidmem__mes_map_queues__uses_video_memory :
- vidmem__mes_map_queues__uses_no_video_memory;
-
- switch (q->properties.type) {
- case KFD_QUEUE_TYPE_COMPUTE:
- case KFD_QUEUE_TYPE_DIQ:
- packet->bitfields2.engine_sel =
- engine_sel__mes_map_queues__compute;
- break;
- case KFD_QUEUE_TYPE_SDMA:
- packet->bitfields2.engine_sel =
- engine_sel__mes_map_queues__sdma0;
- use_static = false; /* no static queues under SDMA */
- break;
- default:
- BUG();
- break;
- }
-
- packet->mes_map_queues_ordinals[0].bitfields3.doorbell_offset =
- q->properties.doorbell_off;
-
- packet->mes_map_queues_ordinals[0].bitfields3.is_static =
- (use_static) ? 1 : 0;
-
- packet->mes_map_queues_ordinals[0].mqd_addr_lo =
- lower_32_bits(q->gart_mqd_addr);
-
- packet->mes_map_queues_ordinals[0].mqd_addr_hi =
- upper_32_bits(q->gart_mqd_addr);
-
- packet->mes_map_queues_ordinals[0].wptr_addr_lo =
- lower_32_bits((uint64_t)q->properties.write_ptr);
-
- packet->mes_map_queues_ordinals[0].wptr_addr_hi =
- upper_32_bits((uint64_t)q->properties.write_ptr);
-
- return 0;
-}
-
static int pm_create_runlist_ib(struct packet_manager *pm,
struct list_head *queues,
uint64_t *rl_gpu_addr,
@@ -322,19 +248,16 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
struct kernel_queue *kq;
bool is_over_subscription;
- BUG_ON(!pm || !queues || !rl_size_bytes || !rl_gpu_addr);
-
rl_wptr = retval = proccesses_mapped = 0;
retval = pm_allocate_runlist_ib(pm, &rl_buffer, rl_gpu_addr,
&alloc_size_bytes, &is_over_subscription);
- if (retval != 0)
+ if (retval)
return retval;
*rl_size_bytes = alloc_size_bytes;
- pr_debug("kfd: In func %s\n", __func__);
- pr_debug("kfd: building runlist ib process count: %d queues count %d\n",
+ pr_debug("Building runlist ib process count: %d queues count %d\n",
pm->dqm->processes_count, pm->dqm->queue_count);
/* build the run list ib packet */
@@ -342,42 +265,35 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
qpd = cur->qpd;
/* build map process packet */
if (proccesses_mapped >= pm->dqm->processes_count) {
- pr_debug("kfd: not enough space left in runlist IB\n");
+ pr_debug("Not enough space left in runlist IB\n");
pm_release_ib(pm);
return -ENOMEM;
}
retval = pm_create_map_process(pm, &rl_buffer[rl_wptr], qpd);
- if (retval != 0)
+ if (retval)
return retval;
proccesses_mapped++;
- inc_wptr(&rl_wptr, sizeof(struct pm4_map_process),
+ inc_wptr(&rl_wptr, sizeof(struct pm4_mes_map_process),
alloc_size_bytes);
list_for_each_entry(kq, &qpd->priv_queue_list, list) {
if (!kq->queue->properties.is_active)
continue;
- pr_debug("kfd: static_queue, mapping kernel q %d, is debug status %d\n",
+ pr_debug("static_queue, mapping kernel q %d, is debug status %d\n",
kq->queue->queue, qpd->is_debug);
- if (pm->dqm->dev->device_info->asic_family ==
- CHIP_CARRIZO)
- retval = pm_create_map_queue_vi(pm,
- &rl_buffer[rl_wptr],
- kq->queue,
- qpd->is_debug);
- else
- retval = pm_create_map_queue(pm,
+ retval = pm_create_map_queue(pm,
&rl_buffer[rl_wptr],
kq->queue,
qpd->is_debug);
- if (retval != 0)
+ if (retval)
return retval;
inc_wptr(&rl_wptr,
- sizeof(struct pm4_map_queues),
+ sizeof(struct pm4_mes_map_queues),
alloc_size_bytes);
}
@@ -385,51 +301,44 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
if (!q->properties.is_active)
continue;
- pr_debug("kfd: static_queue, mapping user queue %d, is debug status %d\n",
+ pr_debug("static_queue, mapping user queue %d, is debug status %d\n",
q->queue, qpd->is_debug);
- if (pm->dqm->dev->device_info->asic_family ==
- CHIP_CARRIZO)
- retval = pm_create_map_queue_vi(pm,
- &rl_buffer[rl_wptr],
- q,
- qpd->is_debug);
- else
- retval = pm_create_map_queue(pm,
+ retval = pm_create_map_queue(pm,
&rl_buffer[rl_wptr],
q,
qpd->is_debug);
- if (retval != 0)
+ if (retval)
return retval;
inc_wptr(&rl_wptr,
- sizeof(struct pm4_map_queues),
+ sizeof(struct pm4_mes_map_queues),
alloc_size_bytes);
}
}
- pr_debug("kfd: finished map process and queues to runlist\n");
+ pr_debug("Finished map process and queues to runlist\n");
if (is_over_subscription)
- pm_create_runlist(pm, &rl_buffer[rl_wptr], *rl_gpu_addr,
- alloc_size_bytes / sizeof(uint32_t), true);
+ retval = pm_create_runlist(pm, &rl_buffer[rl_wptr],
+ *rl_gpu_addr,
+ alloc_size_bytes / sizeof(uint32_t),
+ true);
for (i = 0; i < alloc_size_bytes / sizeof(uint32_t); i++)
pr_debug("0x%2X ", rl_buffer[i]);
pr_debug("\n");
- return 0;
+ return retval;
}
int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm)
{
- BUG_ON(!dqm);
-
pm->dqm = dqm;
mutex_init(&pm->lock);
pm->priv_queue = kernel_queue_init(dqm->dev, KFD_QUEUE_TYPE_HIQ);
- if (pm->priv_queue == NULL) {
+ if (!pm->priv_queue) {
mutex_destroy(&pm->lock);
return -ENOMEM;
}
@@ -440,8 +349,6 @@ int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm)
void pm_uninit(struct packet_manager *pm)
{
- BUG_ON(!pm);
-
mutex_destroy(&pm->lock);
kernel_queue_uninit(pm->priv_queue);
}
@@ -449,25 +356,22 @@ void pm_uninit(struct packet_manager *pm)
int pm_send_set_resources(struct packet_manager *pm,
struct scheduling_resources *res)
{
- struct pm4_set_resources *packet;
-
- BUG_ON(!pm || !res);
-
- pr_debug("kfd: In func %s\n", __func__);
+ struct pm4_mes_set_resources *packet;
+ int retval = 0;
mutex_lock(&pm->lock);
pm->priv_queue->ops.acquire_packet_buffer(pm->priv_queue,
sizeof(*packet) / sizeof(uint32_t),
- (unsigned int **)&packet);
- if (packet == NULL) {
- mutex_unlock(&pm->lock);
- pr_err("kfd: failed to allocate buffer on kernel queue\n");
- return -ENOMEM;
+ (unsigned int **)&packet);
+ if (!packet) {
+ pr_err("Failed to allocate buffer on kernel queue\n");
+ retval = -ENOMEM;
+ goto out;
}
- memset(packet, 0, sizeof(struct pm4_set_resources));
- packet->header.u32all = build_pm4_header(IT_SET_RESOURCES,
- sizeof(struct pm4_set_resources));
+ memset(packet, 0, sizeof(struct pm4_mes_set_resources));
+ packet->header.u32All = build_pm4_header(IT_SET_RESOURCES,
+ sizeof(struct pm4_mes_set_resources));
packet->bitfields2.queue_type =
queue_type__mes_set_resources__hsa_interface_queue_hiq;
@@ -485,9 +389,10 @@ int pm_send_set_resources(struct packet_manager *pm,
pm->priv_queue->ops.submit_packet(pm->priv_queue);
+out:
mutex_unlock(&pm->lock);
- return 0;
+ return retval;
}
int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues)
@@ -497,26 +402,24 @@ int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues)
size_t rl_ib_size, packet_size_dwords;
int retval;
- BUG_ON(!pm || !dqm_queues);
-
retval = pm_create_runlist_ib(pm, dqm_queues, &rl_gpu_ib_addr,
&rl_ib_size);
- if (retval != 0)
+ if (retval)
goto fail_create_runlist_ib;
- pr_debug("kfd: runlist IB address: 0x%llX\n", rl_gpu_ib_addr);
+ pr_debug("runlist IB address: 0x%llX\n", rl_gpu_ib_addr);
- packet_size_dwords = sizeof(struct pm4_runlist) / sizeof(uint32_t);
+ packet_size_dwords = sizeof(struct pm4_mes_runlist) / sizeof(uint32_t);
mutex_lock(&pm->lock);
retval = pm->priv_queue->ops.acquire_packet_buffer(pm->priv_queue,
packet_size_dwords, &rl_buffer);
- if (retval != 0)
+ if (retval)
goto fail_acquire_packet_buffer;
retval = pm_create_runlist(pm, rl_buffer, rl_gpu_ib_addr,
rl_ib_size / sizeof(uint32_t), false);
- if (retval != 0)
+ if (retval)
goto fail_create_runlist;
pm->priv_queue->ops.submit_packet(pm->priv_queue);
@@ -530,8 +433,7 @@ fail_create_runlist:
fail_acquire_packet_buffer:
mutex_unlock(&pm->lock);
fail_create_runlist_ib:
- if (pm->allocated)
- pm_release_ib(pm);
+ pm_release_ib(pm);
return retval;
}
@@ -539,20 +441,21 @@ int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
uint32_t fence_value)
{
int retval;
- struct pm4_query_status *packet;
+ struct pm4_mes_query_status *packet;
- BUG_ON(!pm || !fence_address);
+ if (WARN_ON(!fence_address))
+ return -EFAULT;
mutex_lock(&pm->lock);
retval = pm->priv_queue->ops.acquire_packet_buffer(
pm->priv_queue,
- sizeof(struct pm4_query_status) / sizeof(uint32_t),
+ sizeof(struct pm4_mes_query_status) / sizeof(uint32_t),
(unsigned int **)&packet);
- if (retval != 0)
+ if (retval)
goto fail_acquire_packet_buffer;
- packet->header.u32all = build_pm4_header(IT_QUERY_STATUS,
- sizeof(struct pm4_query_status));
+ packet->header.u32All = build_pm4_header(IT_QUERY_STATUS,
+ sizeof(struct pm4_mes_query_status));
packet->bitfields2.context_id = 0;
packet->bitfields2.interrupt_sel =
@@ -566,9 +469,6 @@ int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
packet->data_lo = lower_32_bits((uint64_t)fence_value);
pm->priv_queue->ops.submit_packet(pm->priv_queue);
- mutex_unlock(&pm->lock);
-
- return 0;
fail_acquire_packet_buffer:
mutex_unlock(&pm->lock);
@@ -582,24 +482,22 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
{
int retval;
uint32_t *buffer;
- struct pm4_unmap_queues *packet;
-
- BUG_ON(!pm);
+ struct pm4_mes_unmap_queues *packet;
mutex_lock(&pm->lock);
retval = pm->priv_queue->ops.acquire_packet_buffer(
pm->priv_queue,
- sizeof(struct pm4_unmap_queues) / sizeof(uint32_t),
+ sizeof(struct pm4_mes_unmap_queues) / sizeof(uint32_t),
&buffer);
- if (retval != 0)
+ if (retval)
goto err_acquire_packet_buffer;
- packet = (struct pm4_unmap_queues *)buffer;
- memset(buffer, 0, sizeof(struct pm4_unmap_queues));
- pr_debug("kfd: static_queue: unmapping queues: mode is %d , reset is %d , type is %d\n",
+ packet = (struct pm4_mes_unmap_queues *)buffer;
+ memset(buffer, 0, sizeof(struct pm4_mes_unmap_queues));
+ pr_debug("static_queue: unmapping queues: mode is %d , reset is %d , type is %d\n",
mode, reset, type);
- packet->header.u32all = build_pm4_header(IT_UNMAP_QUEUES,
- sizeof(struct pm4_unmap_queues));
+ packet->header.u32All = build_pm4_header(IT_UNMAP_QUEUES,
+ sizeof(struct pm4_mes_unmap_queues));
switch (type) {
case KFD_QUEUE_TYPE_COMPUTE:
case KFD_QUEUE_TYPE_DIQ:
@@ -611,8 +509,9 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
engine_sel__mes_unmap_queues__sdma0 + sdma_engine;
break;
default:
- BUG();
- break;
+ WARN(1, "queue type %d", type);
+ retval = -EINVAL;
+ goto err_invalid;
}
if (reset)
@@ -636,16 +535,17 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
break;
case KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES:
packet->bitfields2.queue_sel =
- queue_sel__mes_unmap_queues__perform_request_on_all_active_queues;
+ queue_sel__mes_unmap_queues__unmap_all_queues;
break;
case KFD_PREEMPT_TYPE_FILTER_DYNAMIC_QUEUES:
/* in this case, we do not preempt static queues */
packet->bitfields2.queue_sel =
- queue_sel__mes_unmap_queues__perform_request_on_dynamic_queues_only;
+ queue_sel__mes_unmap_queues__unmap_all_non_static_queues;
break;
default:
- BUG();
- break;
+ WARN(1, "filter %d", mode);
+ retval = -EINVAL;
+ goto err_invalid;
}
pm->priv_queue->ops.submit_packet(pm->priv_queue);
@@ -653,6 +553,8 @@ int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
mutex_unlock(&pm->lock);
return 0;
+err_invalid:
+ pm->priv_queue->ops.rollback_packet(pm->priv_queue);
err_acquire_packet_buffer:
mutex_unlock(&pm->lock);
return retval;
@@ -660,8 +562,6 @@ err_acquire_packet_buffer:
void pm_release_ib(struct packet_manager *pm)
{
- BUG_ON(!pm);
-
mutex_lock(&pm->lock);
if (pm->allocated) {
kfd_gtt_sa_free(pm->dqm->dev, pm->ib_buffer_obj);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c
index 6cfe7f1f18cf..1e06de0bc673 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c
@@ -32,7 +32,8 @@ int kfd_pasid_init(void)
{
pasid_limit = KFD_MAX_NUM_OF_PROCESSES;
- pasid_bitmap = kcalloc(BITS_TO_LONGS(pasid_limit), sizeof(long), GFP_KERNEL);
+ pasid_bitmap = kcalloc(BITS_TO_LONGS(pasid_limit), sizeof(long),
+ GFP_KERNEL);
if (!pasid_bitmap)
return -ENOMEM;
@@ -91,6 +92,6 @@ unsigned int kfd_pasid_alloc(void)
void kfd_pasid_free(unsigned int pasid)
{
- BUG_ON(pasid == 0 || pasid >= pasid_limit);
- clear_bit(pasid, pasid_bitmap);
+ if (!WARN_ON(pasid == 0 || pasid >= pasid_limit))
+ clear_bit(pasid, pasid_bitmap);
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h
index 5b393f3e34a9..e50f73d25de6 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h
@@ -28,112 +28,19 @@
#define PM4_MES_HEADER_DEFINED
union PM4_MES_TYPE_3_HEADER {
struct {
- uint32_t reserved1:8; /* < reserved */
- uint32_t opcode:8; /* < IT opcode */
- uint32_t count:14; /* < number of DWORDs - 1
- * in the information body.
- */
- uint32_t type:2; /* < packet identifier.
- * It should be 3 for type 3 packets
- */
+ /* reserved */
+ uint32_t reserved1:8;
+ /* IT opcode */
+ uint32_t opcode:8;
+ /* number of DWORDs - 1 in the information body */
+ uint32_t count:14;
+ /* packet identifier. It should be 3 for type 3 packets */
+ uint32_t type:2;
};
uint32_t u32all;
};
#endif /* PM4_MES_HEADER_DEFINED */
-/* --------------------MES_SET_RESOURCES-------------------- */
-
-#ifndef PM4_MES_SET_RESOURCES_DEFINED
-#define PM4_MES_SET_RESOURCES_DEFINED
-enum set_resources_queue_type_enum {
- queue_type__mes_set_resources__kernel_interface_queue_kiq = 0,
- queue_type__mes_set_resources__hsa_interface_queue_hiq = 1,
- queue_type__mes_set_resources__hsa_debug_interface_queue = 4
-};
-
-struct pm4_set_resources {
- union {
- union PM4_MES_TYPE_3_HEADER header; /* header */
- uint32_t ordinal1;
- };
-
- union {
- struct {
- uint32_t vmid_mask:16;
- uint32_t unmap_latency:8;
- uint32_t reserved1:5;
- enum set_resources_queue_type_enum queue_type:3;
- } bitfields2;
- uint32_t ordinal2;
- };
-
- uint32_t queue_mask_lo;
- uint32_t queue_mask_hi;
- uint32_t gws_mask_lo;
- uint32_t gws_mask_hi;
-
- union {
- struct {
- uint32_t oac_mask:16;
- uint32_t reserved2:16;
- } bitfields7;
- uint32_t ordinal7;
- };
-
- union {
- struct {
- uint32_t gds_heap_base:6;
- uint32_t reserved3:5;
- uint32_t gds_heap_size:6;
- uint32_t reserved4:15;
- } bitfields8;
- uint32_t ordinal8;
- };
-
-};
-#endif
-
-/*--------------------MES_RUN_LIST-------------------- */
-
-#ifndef PM4_MES_RUN_LIST_DEFINED
-#define PM4_MES_RUN_LIST_DEFINED
-
-struct pm4_runlist {
- union {
- union PM4_MES_TYPE_3_HEADER header; /* header */
- uint32_t ordinal1;
- };
-
- union {
- struct {
- uint32_t reserved1:2;
- uint32_t ib_base_lo:30;
- } bitfields2;
- uint32_t ordinal2;
- };
-
- union {
- struct {
- uint32_t ib_base_hi:16;
- uint32_t reserved2:16;
- } bitfields3;
- uint32_t ordinal3;
- };
-
- union {
- struct {
- uint32_t ib_size:20;
- uint32_t chain:1;
- uint32_t offload_polling:1;
- uint32_t reserved3:1;
- uint32_t valid:1;
- uint32_t reserved4:8;
- } bitfields4;
- uint32_t ordinal4;
- };
-
-};
-#endif
/*--------------------MES_MAP_PROCESS-------------------- */
@@ -186,217 +93,58 @@ struct pm4_map_process {
};
#endif
-/*--------------------MES_MAP_QUEUES--------------------*/
-
-#ifndef PM4_MES_MAP_QUEUES_DEFINED
-#define PM4_MES_MAP_QUEUES_DEFINED
-enum map_queues_queue_sel_enum {
- queue_sel__mes_map_queues__map_to_specified_queue_slots = 0,
- queue_sel__mes_map_queues__map_to_hws_determined_queue_slots = 1,
- queue_sel__mes_map_queues__enable_process_queues = 2
-};
+#ifndef PM4_MES_MAP_PROCESS_DEFINED_KV_SCRATCH
+#define PM4_MES_MAP_PROCESS_DEFINED_KV_SCRATCH
-enum map_queues_vidmem_enum {
- vidmem__mes_map_queues__uses_no_video_memory = 0,
- vidmem__mes_map_queues__uses_video_memory = 1
-};
-
-enum map_queues_alloc_format_enum {
- alloc_format__mes_map_queues__one_per_pipe = 0,
- alloc_format__mes_map_queues__all_on_one_pipe = 1
-};
-
-enum map_queues_engine_sel_enum {
- engine_sel__mes_map_queues__compute = 0,
- engine_sel__mes_map_queues__sdma0 = 2,
- engine_sel__mes_map_queues__sdma1 = 3
-};
-
-struct pm4_map_queues {
+struct pm4_map_process_scratch_kv {
union {
- union PM4_MES_TYPE_3_HEADER header; /* header */
- uint32_t ordinal1;
- };
-
- union {
- struct {
- uint32_t reserved1:4;
- enum map_queues_queue_sel_enum queue_sel:2;
- uint32_t reserved2:2;
- uint32_t vmid:4;
- uint32_t reserved3:4;
- enum map_queues_vidmem_enum vidmem:2;
- uint32_t reserved4:6;
- enum map_queues_alloc_format_enum alloc_format:2;
- enum map_queues_engine_sel_enum engine_sel:3;
- uint32_t num_queues:3;
- } bitfields2;
- uint32_t ordinal2;
- };
-
- struct {
- union {
- struct {
- uint32_t is_static:1;
- uint32_t reserved5:1;
- uint32_t doorbell_offset:21;
- uint32_t reserved6:3;
- uint32_t queue:6;
- } bitfields3;
- uint32_t ordinal3;
- };
-
- uint32_t mqd_addr_lo;
- uint32_t mqd_addr_hi;
- uint32_t wptr_addr_lo;
- uint32_t wptr_addr_hi;
-
- } mes_map_queues_ordinals[1]; /* 1..N of these ordinal groups */
-
-};
-#endif
-
-/*--------------------MES_QUERY_STATUS--------------------*/
-
-#ifndef PM4_MES_QUERY_STATUS_DEFINED
-#define PM4_MES_QUERY_STATUS_DEFINED
-enum query_status_interrupt_sel_enum {
- interrupt_sel__mes_query_status__completion_status = 0,
- interrupt_sel__mes_query_status__process_status = 1,
- interrupt_sel__mes_query_status__queue_status = 2
-};
-
-enum query_status_command_enum {
- command__mes_query_status__interrupt_only = 0,
- command__mes_query_status__fence_only_immediate = 1,
- command__mes_query_status__fence_only_after_write_ack = 2,
- command__mes_query_status__fence_wait_for_write_ack_send_interrupt = 3
-};
-
-enum query_status_engine_sel_enum {
- engine_sel__mes_query_status__compute = 0,
- engine_sel__mes_query_status__sdma0_queue = 2,
- engine_sel__mes_query_status__sdma1_queue = 3
-};
-
-struct pm4_query_status {
- union {
- union PM4_MES_TYPE_3_HEADER header; /* header */
- uint32_t ordinal1;
- };
-
- union {
- struct {
- uint32_t context_id:28;
- enum query_status_interrupt_sel_enum interrupt_sel:2;
- enum query_status_command_enum command:2;
- } bitfields2;
- uint32_t ordinal2;
+ union PM4_MES_TYPE_3_HEADER header; /* header */
+ uint32_t ordinal1;
};
union {
struct {
uint32_t pasid:16;
- uint32_t reserved1:16;
- } bitfields3a;
- struct {
- uint32_t reserved2:2;
- uint32_t doorbell_offset:21;
- uint32_t reserved3:3;
- enum query_status_engine_sel_enum engine_sel:3;
- uint32_t reserved4:3;
- } bitfields3b;
- uint32_t ordinal3;
- };
-
- uint32_t addr_lo;
- uint32_t addr_hi;
- uint32_t data_lo;
- uint32_t data_hi;
-};
-#endif
-
-/*--------------------MES_UNMAP_QUEUES--------------------*/
-
-#ifndef PM4_MES_UNMAP_QUEUES_DEFINED
-#define PM4_MES_UNMAP_QUEUES_DEFINED
-enum unmap_queues_action_enum {
- action__mes_unmap_queues__preempt_queues = 0,
- action__mes_unmap_queues__reset_queues = 1,
- action__mes_unmap_queues__disable_process_queues = 2
-};
-
-enum unmap_queues_queue_sel_enum {
- queue_sel__mes_unmap_queues__perform_request_on_specified_queues = 0,
- queue_sel__mes_unmap_queues__perform_request_on_pasid_queues = 1,
- queue_sel__mes_unmap_queues__perform_request_on_all_active_queues = 2,
- queue_sel__mes_unmap_queues__perform_request_on_dynamic_queues_only = 3
-};
-
-enum unmap_queues_engine_sel_enum {
- engine_sel__mes_unmap_queues__compute = 0,
- engine_sel__mes_unmap_queues__sdma0 = 2,
- engine_sel__mes_unmap_queues__sdma1 = 3
-};
-
-struct pm4_unmap_queues {
- union {
- union PM4_MES_TYPE_3_HEADER header; /* header */
- uint32_t ordinal1;
- };
-
- union {
- struct {
- enum unmap_queues_action_enum action:2;
- uint32_t reserved1:2;
- enum unmap_queues_queue_sel_enum queue_sel:2;
- uint32_t reserved2:20;
- enum unmap_queues_engine_sel_enum engine_sel:3;
- uint32_t num_queues:3;
+ uint32_t reserved1:8;
+ uint32_t diq_enable:1;
+ uint32_t process_quantum:7;
} bitfields2;
uint32_t ordinal2;
};
union {
struct {
- uint32_t pasid:16;
- uint32_t reserved3:16;
- } bitfields3a;
- struct {
- uint32_t reserved4:2;
- uint32_t doorbell_offset0:21;
- uint32_t reserved5:9;
- } bitfields3b;
+ uint32_t page_table_base:28;
+ uint32_t reserved2:4;
+ } bitfields3;
uint32_t ordinal3;
};
- union {
- struct {
- uint32_t reserved6:2;
- uint32_t doorbell_offset1:21;
- uint32_t reserved7:9;
- } bitfields4;
- uint32_t ordinal4;
- };
-
- union {
- struct {
- uint32_t reserved8:2;
- uint32_t doorbell_offset2:21;
- uint32_t reserved9:9;
- } bitfields5;
- uint32_t ordinal5;
- };
+ uint32_t reserved3;
+ uint32_t sh_mem_bases;
+ uint32_t sh_mem_config;
+ uint32_t sh_mem_ape1_base;
+ uint32_t sh_mem_ape1_limit;
+ uint32_t sh_hidden_private_base_vmid;
+ uint32_t reserved4;
+ uint32_t reserved5;
+ uint32_t gds_addr_lo;
+ uint32_t gds_addr_hi;
union {
struct {
- uint32_t reserved10:2;
- uint32_t doorbell_offset3:21;
- uint32_t reserved11:9;
- } bitfields6;
- uint32_t ordinal6;
+ uint32_t num_gws:6;
+ uint32_t reserved6:2;
+ uint32_t num_oac:4;
+ uint32_t reserved7:4;
+ uint32_t gds_size:6;
+ uint32_t num_queues:10;
+ } bitfields14;
+ uint32_t ordinal14;
};
+ uint32_t completion_signal_lo32;
+uint32_t completion_signal_hi32;
};
#endif
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_vi.h b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_vi.h
index 08c721922812..7c8d9b357749 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_vi.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_vi.h
@@ -30,10 +30,12 @@ union PM4_MES_TYPE_3_HEADER {
struct {
uint32_t reserved1 : 8; /* < reserved */
uint32_t opcode : 8; /* < IT opcode */
- uint32_t count : 14;/* < number of DWORDs - 1 in the
- information body. */
- uint32_t type : 2; /* < packet identifier.
- It should be 3 for type 3 packets */
+ uint32_t count : 14;/* < Number of DWORDS - 1 in the
+ * information body
+ */
+ uint32_t type : 2; /* < packet identifier
+ * It should be 3 for type 3 packets
+ */
};
uint32_t u32All;
};
@@ -124,9 +126,10 @@ struct pm4_mes_runlist {
uint32_t ib_size:20;
uint32_t chain:1;
uint32_t offload_polling:1;
- uint32_t reserved3:1;
+ uint32_t reserved2:1;
uint32_t valid:1;
- uint32_t reserved4:8;
+ uint32_t process_cnt:4;
+ uint32_t reserved3:4;
} bitfields4;
uint32_t ordinal4;
};
@@ -141,8 +144,8 @@ struct pm4_mes_runlist {
struct pm4_mes_map_process {
union {
- union PM4_MES_TYPE_3_HEADER header; /* header */
- uint32_t ordinal1;
+ union PM4_MES_TYPE_3_HEADER header; /* header */
+ uint32_t ordinal1;
};
union {
@@ -153,36 +156,48 @@ struct pm4_mes_map_process {
uint32_t process_quantum:7;
} bitfields2;
uint32_t ordinal2;
-};
+ };
union {
struct {
uint32_t page_table_base:28;
- uint32_t reserved2:4;
+ uint32_t reserved3:4;
} bitfields3;
uint32_t ordinal3;
};
+ uint32_t reserved;
+
uint32_t sh_mem_bases;
+ uint32_t sh_mem_config;
uint32_t sh_mem_ape1_base;
uint32_t sh_mem_ape1_limit;
- uint32_t sh_mem_config;
+
+ uint32_t sh_hidden_private_base_vmid;
+
+ uint32_t reserved2;
+ uint32_t reserved3;
+
uint32_t gds_addr_lo;
uint32_t gds_addr_hi;
union {
struct {
uint32_t num_gws:6;
- uint32_t reserved3:2;
+ uint32_t reserved4:2;
uint32_t num_oac:4;
- uint32_t reserved4:4;
+ uint32_t reserved5:4;
uint32_t gds_size:6;
uint32_t num_queues:10;
} bitfields10;
uint32_t ordinal10;
};
+ uint32_t completion_signal_lo;
+ uint32_t completion_signal_hi;
+
};
+
#endif
/*--------------------MES_MAP_QUEUES--------------------*/
@@ -335,7 +350,7 @@ enum mes_unmap_queues_engine_sel_enum {
engine_sel__mes_unmap_queues__sdmal = 3
};
-struct PM4_MES_UNMAP_QUEUES {
+struct pm4_mes_unmap_queues {
union {
union PM4_MES_TYPE_3_HEADER header; /* header */
uint32_t ordinal1;
@@ -395,4 +410,101 @@ struct PM4_MES_UNMAP_QUEUES {
};
#endif
+#ifndef PM4_MEC_RELEASE_MEM_DEFINED
+#define PM4_MEC_RELEASE_MEM_DEFINED
+enum RELEASE_MEM_event_index_enum {
+ event_index___release_mem__end_of_pipe = 5,
+ event_index___release_mem__shader_done = 6
+};
+
+enum RELEASE_MEM_cache_policy_enum {
+ cache_policy___release_mem__lru = 0,
+ cache_policy___release_mem__stream = 1,
+ cache_policy___release_mem__bypass = 2
+};
+
+enum RELEASE_MEM_dst_sel_enum {
+ dst_sel___release_mem__memory_controller = 0,
+ dst_sel___release_mem__tc_l2 = 1,
+ dst_sel___release_mem__queue_write_pointer_register = 2,
+ dst_sel___release_mem__queue_write_pointer_poll_mask_bit = 3
+};
+
+enum RELEASE_MEM_int_sel_enum {
+ int_sel___release_mem__none = 0,
+ int_sel___release_mem__send_interrupt_only = 1,
+ int_sel___release_mem__send_interrupt_after_write_confirm = 2,
+ int_sel___release_mem__send_data_after_write_confirm = 3
+};
+
+enum RELEASE_MEM_data_sel_enum {
+ data_sel___release_mem__none = 0,
+ data_sel___release_mem__send_32_bit_low = 1,
+ data_sel___release_mem__send_64_bit_data = 2,
+ data_sel___release_mem__send_gpu_clock_counter = 3,
+ data_sel___release_mem__send_cp_perfcounter_hi_lo = 4,
+ data_sel___release_mem__store_gds_data_to_memory = 5
+};
+
+struct pm4_mec_release_mem {
+ union {
+ union PM4_MES_TYPE_3_HEADER header; /*header */
+ unsigned int ordinal1;
+ };
+
+ union {
+ struct {
+ unsigned int event_type:6;
+ unsigned int reserved1:2;
+ enum RELEASE_MEM_event_index_enum event_index:4;
+ unsigned int tcl1_vol_action_ena:1;
+ unsigned int tc_vol_action_ena:1;
+ unsigned int reserved2:1;
+ unsigned int tc_wb_action_ena:1;
+ unsigned int tcl1_action_ena:1;
+ unsigned int tc_action_ena:1;
+ unsigned int reserved3:6;
+ unsigned int atc:1;
+ enum RELEASE_MEM_cache_policy_enum cache_policy:2;
+ unsigned int reserved4:5;
+ } bitfields2;
+ unsigned int ordinal2;
+ };
+
+ union {
+ struct {
+ unsigned int reserved5:16;
+ enum RELEASE_MEM_dst_sel_enum dst_sel:2;
+ unsigned int reserved6:6;
+ enum RELEASE_MEM_int_sel_enum int_sel:3;
+ unsigned int reserved7:2;
+ enum RELEASE_MEM_data_sel_enum data_sel:3;
+ } bitfields3;
+ unsigned int ordinal3;
+ };
+
+ union {
+ struct {
+ unsigned int reserved8:2;
+ unsigned int address_lo_32b:30;
+ } bitfields4;
+ struct {
+ unsigned int reserved9:3;
+ unsigned int address_lo_64b:29;
+ } bitfields5;
+ unsigned int ordinal4;
+ };
+
+ unsigned int address_hi;
+
+ unsigned int data_lo;
+
+ unsigned int data_hi;
+};
+#endif
+
+enum {
+ CACHE_FLUSH_AND_INV_TS_EVENT = 0x00000014
+};
+
#endif
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index 4750cabe4252..b397ec726400 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -239,11 +239,6 @@ enum kfd_preempt_type_filter {
KFD_PREEMPT_TYPE_FILTER_BY_PASID
};
-enum kfd_preempt_type {
- KFD_PREEMPT_TYPE_WAVEFRONT,
- KFD_PREEMPT_TYPE_WAVEFRONT_RESET
-};
-
/**
* enum kfd_queue_type
*
@@ -294,13 +289,13 @@ enum kfd_queue_format {
* @write_ptr: Defines the number of dwords written to the ring buffer.
*
* @doorbell_ptr: This field aim is to notify the H/W of new packet written to
- * the queue ring buffer. This field should be similar to write_ptr and the user
- * should update this field after he updated the write_ptr.
+ * the queue ring buffer. This field should be similar to write_ptr and the
+ * user should update this field after he updated the write_ptr.
*
* @doorbell_off: The doorbell offset in the doorbell pci-bar.
*
- * @is_interop: Defines if this is a interop queue. Interop queue means that the
- * queue can access both graphics and compute resources.
+ * @is_interop: Defines if this is a interop queue. Interop queue means that
+ * the queue can access both graphics and compute resources.
*
* @is_active: Defines if the queue is active or not.
*
@@ -352,9 +347,10 @@ struct queue_properties {
* @properties: The queue properties.
*
* @mec: Used only in no cp scheduling mode and identifies to micro engine id
- * that the queue should be execute on.
+ * that the queue should be execute on.
*
- * @pipe: Used only in no cp scheduling mode and identifies the queue's pipe id.
+ * @pipe: Used only in no cp scheduling mode and identifies the queue's pipe
+ * id.
*
* @queue: Used only in no cp scheduliong mode and identifies the queue's slot.
*
@@ -436,6 +432,7 @@ struct qcm_process_device {
uint32_t gds_size;
uint32_t num_gws;
uint32_t num_oac;
+ uint32_t sh_hidden_private_base;
};
/* Data that is per-process-per device. */
@@ -520,8 +517,8 @@ struct kfd_process {
struct mutex event_mutex;
/* All events in process hashed by ID, linked on kfd_event.events. */
DECLARE_HASHTABLE(events, 4);
- struct list_head signal_event_pages; /* struct slot_page_header.
- event_pages */
+ /* struct slot_page_header.event_pages */
+ struct list_head signal_event_pages;
u32 next_nonsignal_event_id;
size_t signal_event_count;
};
@@ -559,8 +556,10 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
struct kfd_process *p);
/* Process device data iterator */
-struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p);
-struct kfd_process_device *kfd_get_next_process_device_data(struct kfd_process *p,
+struct kfd_process_device *kfd_get_first_process_device_data(
+ struct kfd_process *p);
+struct kfd_process_device *kfd_get_next_process_device_data(
+ struct kfd_process *p,
struct kfd_process_device *pdd);
bool kfd_has_process_device_data(struct kfd_process *p);
@@ -573,7 +572,8 @@ unsigned int kfd_pasid_alloc(void);
void kfd_pasid_free(unsigned int pasid);
/* Doorbells */
-void kfd_doorbell_init(struct kfd_dev *kfd);
+int kfd_doorbell_init(struct kfd_dev *kfd);
+void kfd_doorbell_fini(struct kfd_dev *kfd);
int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma);
u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
unsigned int *doorbell_off);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index 035bbc98a63d..c74cf22a1ed9 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -79,9 +79,7 @@ struct kfd_process *kfd_create_process(const struct task_struct *thread)
{
struct kfd_process *process;
- BUG_ON(!kfd_process_wq);
-
- if (thread->mm == NULL)
+ if (!thread->mm)
return ERR_PTR(-EINVAL);
/* Only the pthreads threading model is supported. */
@@ -101,7 +99,7 @@ struct kfd_process *kfd_create_process(const struct task_struct *thread)
/* A prior open of /dev/kfd could have already created the process. */
process = find_process(thread);
if (process)
- pr_debug("kfd: process already found\n");
+ pr_debug("Process already found\n");
if (!process)
process = create_process(thread);
@@ -117,7 +115,7 @@ struct kfd_process *kfd_get_process(const struct task_struct *thread)
{
struct kfd_process *process;
- if (thread->mm == NULL)
+ if (!thread->mm)
return ERR_PTR(-EINVAL);
/* Only the pthreads threading model is supported. */
@@ -202,10 +200,8 @@ static void kfd_process_destroy_delayed(struct rcu_head *rcu)
struct kfd_process_release_work *work;
struct kfd_process *p;
- BUG_ON(!kfd_process_wq);
-
p = container_of(rcu, struct kfd_process, rcu);
- BUG_ON(atomic_read(&p->mm->mm_count) <= 0);
+ WARN_ON(atomic_read(&p->mm->mm_count) <= 0);
mmdrop(p->mm);
@@ -229,7 +225,8 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn,
* mmu_notifier srcu is read locked
*/
p = container_of(mn, struct kfd_process, mmu_notifier);
- BUG_ON(p->mm != mm);
+ if (WARN_ON(p->mm != mm))
+ return;
mutex_lock(&kfd_processes_mutex);
hash_del_rcu(&p->kfd_processes);
@@ -250,7 +247,7 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn,
kfd_dbgmgr_destroy(pdd->dev->dbgmgr);
if (pdd->reset_wavefronts) {
- pr_warn("amdkfd: Resetting all wave fronts\n");
+ pr_warn("Resetting all wave fronts\n");
dbgdev_wave_reset_wavefronts(pdd->dev, p);
pdd->reset_wavefronts = false;
}
@@ -407,8 +404,6 @@ void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid)
struct kfd_process *p;
struct kfd_process_device *pdd;
- BUG_ON(dev == NULL);
-
/*
* Look for the process that matches the pasid. If there is no such
* process, we either released it in amdkfd's own notifier, or there
@@ -449,14 +444,16 @@ void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid)
mutex_unlock(&p->mutex);
}
-struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p)
+struct kfd_process_device *kfd_get_first_process_device_data(
+ struct kfd_process *p)
{
return list_first_entry(&p->per_device_data,
struct kfd_process_device,
per_device_list);
}
-struct kfd_process_device *kfd_get_next_process_device_data(struct kfd_process *p,
+struct kfd_process_device *kfd_get_next_process_device_data(
+ struct kfd_process *p,
struct kfd_process_device *pdd)
{
if (list_is_last(&pdd->per_device_list, &p->per_device_data))
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
index 32cdf2b483db..1cae95e2b13a 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -32,12 +32,9 @@ static inline struct process_queue_node *get_queue_by_qid(
{
struct process_queue_node *pqn;
- BUG_ON(!pqm);
-
list_for_each_entry(pqn, &pqm->queues, process_queue_list) {
- if (pqn->q && pqn->q->properties.queue_id == qid)
- return pqn;
- if (pqn->kq && pqn->kq->queue->properties.queue_id == qid)
+ if ((pqn->q && pqn->q->properties.queue_id == qid) ||
+ (pqn->kq && pqn->kq->queue->properties.queue_id == qid))
return pqn;
}
@@ -49,17 +46,13 @@ static int find_available_queue_slot(struct process_queue_manager *pqm,
{
unsigned long found;
- BUG_ON(!pqm || !qid);
-
- pr_debug("kfd: in %s\n", __func__);
-
found = find_first_zero_bit(pqm->queue_slot_bitmap,
KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
- pr_debug("kfd: the new slot id %lu\n", found);
+ pr_debug("The new slot id %lu\n", found);
if (found >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) {
- pr_info("amdkfd: Can not open more queues for process with pasid %d\n",
+ pr_info("Cannot open more queues for process with pasid %d\n",
pqm->process->pasid);
return -ENOMEM;
}
@@ -72,13 +65,11 @@ static int find_available_queue_slot(struct process_queue_manager *pqm,
int pqm_init(struct process_queue_manager *pqm, struct kfd_process *p)
{
- BUG_ON(!pqm);
-
INIT_LIST_HEAD(&pqm->queues);
pqm->queue_slot_bitmap =
kzalloc(DIV_ROUND_UP(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS,
BITS_PER_BYTE), GFP_KERNEL);
- if (pqm->queue_slot_bitmap == NULL)
+ if (!pqm->queue_slot_bitmap)
return -ENOMEM;
pqm->process = p;
@@ -90,10 +81,6 @@ void pqm_uninit(struct process_queue_manager *pqm)
int retval;
struct process_queue_node *pqn, *next;
- BUG_ON(!pqm);
-
- pr_debug("In func %s\n", __func__);
-
list_for_each_entry_safe(pqn, next, &pqm->queues, process_queue_list) {
retval = pqm_destroy_queue(
pqm,
@@ -102,7 +89,7 @@ void pqm_uninit(struct process_queue_manager *pqm)
pqn->kq->queue->properties.queue_id);
if (retval != 0) {
- pr_err("kfd: failed to destroy queue\n");
+ pr_err("failed to destroy queue\n");
return;
}
}
@@ -117,8 +104,6 @@ static int create_cp_queue(struct process_queue_manager *pqm,
{
int retval;
- retval = 0;
-
/* Doorbell initialized in user space*/
q_properties->doorbell_ptr = NULL;
@@ -131,16 +116,13 @@ static int create_cp_queue(struct process_queue_manager *pqm,
retval = init_queue(q, q_properties);
if (retval != 0)
- goto err_init_queue;
+ return retval;
(*q)->device = dev;
(*q)->process = pqm->process;
- pr_debug("kfd: PQM After init queue");
-
- return retval;
+ pr_debug("PQM After init queue");
-err_init_queue:
return retval;
}
@@ -161,8 +143,6 @@ int pqm_create_queue(struct process_queue_manager *pqm,
int num_queues = 0;
struct queue *cur;
- BUG_ON(!pqm || !dev || !properties || !qid);
-
memset(&q_properties, 0, sizeof(struct queue_properties));
memcpy(&q_properties, properties, sizeof(struct queue_properties));
q = NULL;
@@ -185,7 +165,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,
list_for_each_entry(cur, &pdd->qpd.queues_list, list)
num_queues++;
if (num_queues >= dev->device_info->max_no_of_hqd/2)
- return (-ENOSPC);
+ return -ENOSPC;
}
retval = find_available_queue_slot(pqm, qid);
@@ -197,7 +177,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,
dev->dqm->ops.register_process(dev->dqm, &pdd->qpd);
}
- pqn = kzalloc(sizeof(struct process_queue_node), GFP_KERNEL);
+ pqn = kzalloc(sizeof(*pqn), GFP_KERNEL);
if (!pqn) {
retval = -ENOMEM;
goto err_allocate_pqn;
@@ -210,7 +190,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,
if ((sched_policy == KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION) &&
((dev->dqm->processes_count >= VMID_PER_DEVICE) ||
(dev->dqm->queue_count >= get_queues_num(dev->dqm)))) {
- pr_err("kfd: over-subscription is not allowed in radeon_kfd.sched_policy == 1\n");
+ pr_err("Over-subscription is not allowed in radeon_kfd.sched_policy == 1\n");
retval = -EPERM;
goto err_create_queue;
}
@@ -227,7 +207,7 @@ int pqm_create_queue(struct process_queue_manager *pqm,
break;
case KFD_QUEUE_TYPE_DIQ:
kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_DIQ);
- if (kq == NULL) {
+ if (!kq) {
retval = -ENOMEM;
goto err_create_queue;
}
@@ -238,22 +218,22 @@ int pqm_create_queue(struct process_queue_manager *pqm,
kq, &pdd->qpd);
break;
default:
- BUG();
- break;
+ WARN(1, "Invalid queue type %d", type);
+ retval = -EINVAL;
}
if (retval != 0) {
- pr_debug("Error dqm create queue\n");
+ pr_err("DQM create queue failed\n");
goto err_create_queue;
}
- pr_debug("kfd: PQM After DQM create queue\n");
+ pr_debug("PQM After DQM create queue\n");
list_add(&pqn->process_queue_list, &pqm->queues);
if (q) {
*properties = q->properties;
- pr_debug("kfd: PQM done creating queue\n");
+ pr_debug("PQM done creating queue\n");
print_queue_properties(properties);
}
@@ -279,14 +259,11 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid)
dqm = NULL;
- BUG_ON(!pqm);
retval = 0;
- pr_debug("kfd: In Func %s\n", __func__);
-
pqn = get_queue_by_qid(pqm, qid);
- if (pqn == NULL) {
- pr_err("kfd: queue id does not match any known queue\n");
+ if (!pqn) {
+ pr_err("Queue id does not match any known queue\n");
return -EINVAL;
}
@@ -295,7 +272,8 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid)
dev = pqn->kq->dev;
if (pqn->q)
dev = pqn->q->device;
- BUG_ON(!dev);
+ if (WARN_ON(!dev))
+ return -ENODEV;
pdd = kfd_get_process_device_data(dev, pqm->process);
if (!pdd) {
@@ -335,12 +313,9 @@ int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid,
int retval;
struct process_queue_node *pqn;
- BUG_ON(!pqm);
-
pqn = get_queue_by_qid(pqm, qid);
if (!pqn) {
- pr_debug("amdkfd: No queue %d exists for update operation\n",
- qid);
+ pr_debug("No queue %d exists for update operation\n", qid);
return -EFAULT;
}
@@ -363,8 +338,6 @@ struct kernel_queue *pqm_get_kernel_queue(
{
struct process_queue_node *pqn;
- BUG_ON(!pqm);
-
pqn = get_queue_by_qid(pqm, qid);
if (pqn && pqn->kq)
return pqn->kq;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
index 0ab197077f2d..a5315d4f1c95 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
@@ -65,17 +65,15 @@ void print_queue(struct queue *q)
int init_queue(struct queue **q, const struct queue_properties *properties)
{
- struct queue *tmp;
+ struct queue *tmp_q;
- BUG_ON(!q);
-
- tmp = kzalloc(sizeof(struct queue), GFP_KERNEL);
- if (!tmp)
+ tmp_q = kzalloc(sizeof(*tmp_q), GFP_KERNEL);
+ if (!tmp_q)
return -ENOMEM;
- memcpy(&tmp->properties, properties, sizeof(struct queue_properties));
+ memcpy(&tmp_q->properties, properties, sizeof(*properties));
- *q = tmp;
+ *q = tmp_q;
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
index 1e5064749959..19ce59028d6b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -108,9 +108,6 @@ static int kfd_topology_get_crat_acpi(void *crat_image, size_t *size)
static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev,
struct crat_subtype_computeunit *cu)
{
- BUG_ON(!dev);
- BUG_ON(!cu);
-
dev->node_props.cpu_cores_count = cu->num_cpu_cores;
dev->node_props.cpu_core_id_base = cu->processor_id_low;
if (cu->hsa_capability & CRAT_CU_FLAGS_IOMMU_PRESENT)
@@ -123,9 +120,6 @@ static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev,
static void kfd_populated_cu_info_gpu(struct kfd_topology_device *dev,
struct crat_subtype_computeunit *cu)
{
- BUG_ON(!dev);
- BUG_ON(!cu);
-
dev->node_props.simd_id_base = cu->processor_id_low;
dev->node_props.simd_count = cu->num_simd_cores;
dev->node_props.lds_size_in_kb = cu->lds_size_in_kb;
@@ -148,8 +142,6 @@ static int kfd_parse_subtype_cu(struct crat_subtype_computeunit *cu)
struct kfd_topology_device *dev;
int i = 0;
- BUG_ON(!cu);
-
pr_info("Found CU entry in CRAT table with proximity_domain=%d caps=%x\n",
cu->proximity_domain, cu->hsa_capability);
list_for_each_entry(dev, &topology_device_list, list) {
@@ -177,8 +169,6 @@ static int kfd_parse_subtype_mem(struct crat_subtype_memory *mem)
struct kfd_topology_device *dev;
int i = 0;
- BUG_ON(!mem);
-
pr_info("Found memory entry in CRAT table with proximity_domain=%d\n",
mem->promixity_domain);
list_for_each_entry(dev, &topology_device_list, list) {
@@ -223,8 +213,6 @@ static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache)
struct kfd_topology_device *dev;
uint32_t id;
- BUG_ON(!cache);
-
id = cache->processor_id_low;
pr_info("Found cache entry in CRAT table with processor_id=%d\n", id);
@@ -274,8 +262,6 @@ static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink)
uint32_t id_from;
uint32_t id_to;
- BUG_ON(!iolink);
-
id_from = iolink->proximity_domain_from;
id_to = iolink->proximity_domain_to;
@@ -323,8 +309,6 @@ static int kfd_parse_subtype(struct crat_subtype_generic *sub_type_hdr)
struct crat_subtype_iolink *iolink;
int ret = 0;
- BUG_ON(!sub_type_hdr);
-
switch (sub_type_hdr->type) {
case CRAT_SUBTYPE_COMPUTEUNIT_AFFINITY:
cu = (struct crat_subtype_computeunit *)sub_type_hdr;
@@ -368,8 +352,6 @@ static void kfd_release_topology_device(struct kfd_topology_device *dev)
struct kfd_cache_properties *cache;
struct kfd_iolink_properties *iolink;
- BUG_ON(!dev);
-
list_del(&dev->list);
while (dev->mem_props.next != &dev->mem_props) {
@@ -416,7 +398,7 @@ static struct kfd_topology_device *kfd_create_topology_device(void)
struct kfd_topology_device *dev;
dev = kfd_alloc_struct(dev);
- if (dev == NULL) {
+ if (!dev) {
pr_err("No memory to allocate a topology device");
return NULL;
}
@@ -666,7 +648,7 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr,
dev->node_props.simd_count);
if (dev->mem_bank_count < dev->node_props.mem_banks_count) {
- pr_info_once("kfd: mem_banks_count truncated from %d to %d\n",
+ pr_info_once("mem_banks_count truncated from %d to %d\n",
dev->node_props.mem_banks_count,
dev->mem_bank_count);
sysfs_show_32bit_prop(buffer, "mem_banks_count",
@@ -763,8 +745,6 @@ static void kfd_remove_sysfs_node_entry(struct kfd_topology_device *dev)
struct kfd_cache_properties *cache;
struct kfd_mem_properties *mem;
- BUG_ON(!dev);
-
if (dev->kobj_iolink) {
list_for_each_entry(iolink, &dev->io_link_props, list)
if (iolink->kobj) {
@@ -819,12 +799,12 @@ static int kfd_build_sysfs_node_entry(struct kfd_topology_device *dev,
int ret;
uint32_t i;
- BUG_ON(!dev);
+ if (WARN_ON(dev->kobj_node))
+ return -EEXIST;
/*
* Creating the sysfs folders
*/
- BUG_ON(dev->kobj_node);
dev->kobj_node = kfd_alloc_struct(dev->kobj_node);
if (!dev->kobj_node)
return -ENOMEM;
@@ -957,7 +937,7 @@ static int kfd_topology_update_sysfs(void)
int ret;
pr_info("Creating topology SYSFS entries\n");
- if (sys_props.kobj_topology == NULL) {
+ if (!sys_props.kobj_topology) {
sys_props.kobj_topology =
kfd_alloc_struct(sys_props.kobj_topology);
if (!sys_props.kobj_topology)
@@ -1117,10 +1097,8 @@ static struct kfd_topology_device *kfd_assign_gpu(struct kfd_dev *gpu)
struct kfd_topology_device *dev;
struct kfd_topology_device *out_dev = NULL;
- BUG_ON(!gpu);
-
list_for_each_entry(dev, &topology_device_list, list)
- if (dev->gpu == NULL && dev->node_props.simd_count > 0) {
+ if (!dev->gpu && (dev->node_props.simd_count > 0)) {
dev->gpu = gpu;
out_dev = dev;
break;
@@ -1143,11 +1121,9 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
struct kfd_topology_device *dev;
int res;
- BUG_ON(!gpu);
-
gpu_id = kfd_generate_gpu_id(gpu);
- pr_debug("kfd: Adding new GPU (ID: 0x%x) to topology\n", gpu_id);
+ pr_debug("Adding new GPU (ID: 0x%x) to topology\n", gpu_id);
down_write(&topology_lock);
/*
@@ -1170,8 +1146,8 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
* GPU vBIOS
*/
- /*
- * Update the SYSFS tree, since we added another topology device
+ /* Update the SYSFS tree, since we added another topology
+ * device
*/
if (kfd_topology_update_sysfs() < 0)
kfd_topology_release_sysfs();
@@ -1190,7 +1166,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
if (dev->gpu->device_info->asic_family == CHIP_CARRIZO) {
dev->node_props.capability |= HSA_CAP_DOORBELL_PACKET_TYPE;
- pr_info("amdkfd: adding doorbell packet type capability\n");
+ pr_info("Adding doorbell packet type capability\n");
}
res = 0;
@@ -1210,8 +1186,6 @@ int kfd_topology_remove_device(struct kfd_dev *gpu)
uint32_t gpu_id;
int res = -ENODEV;
- BUG_ON(!gpu);
-
down_write(&topology_lock);
list_for_each_entry(dev, &topology_device_list, list)
diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
index 0021a1c63356..837296db9628 100644
--- a/drivers/gpu/drm/amd/include/atomfirmware.h
+++ b/drivers/gpu/drm/amd/include/atomfirmware.h
@@ -1233,6 +1233,69 @@ struct atom_asic_profiling_info_v4_1
uint32_t phyclk2gfxclk_c;
};
+struct atom_asic_profiling_info_v4_2 {
+ struct atom_common_table_header table_header;
+ uint32_t maxvddc;
+ uint32_t minvddc;
+ uint32_t avfs_meannsigma_acontant0;
+ uint32_t avfs_meannsigma_acontant1;
+ uint32_t avfs_meannsigma_acontant2;
+ uint16_t avfs_meannsigma_dc_tol_sigma;
+ uint16_t avfs_meannsigma_platform_mean;
+ uint16_t avfs_meannsigma_platform_sigma;
+ uint32_t gb_vdroop_table_cksoff_a0;
+ uint32_t gb_vdroop_table_cksoff_a1;
+ uint32_t gb_vdroop_table_cksoff_a2;
+ uint32_t gb_vdroop_table_ckson_a0;
+ uint32_t gb_vdroop_table_ckson_a1;
+ uint32_t gb_vdroop_table_ckson_a2;
+ uint32_t avfsgb_fuse_table_cksoff_m1;
+ uint32_t avfsgb_fuse_table_cksoff_m2;
+ uint32_t avfsgb_fuse_table_cksoff_b;
+ uint32_t avfsgb_fuse_table_ckson_m1;
+ uint32_t avfsgb_fuse_table_ckson_m2;
+ uint32_t avfsgb_fuse_table_ckson_b;
+ uint16_t max_voltage_0_25mv;
+ uint8_t enable_gb_vdroop_table_cksoff;
+ uint8_t enable_gb_vdroop_table_ckson;
+ uint8_t enable_gb_fuse_table_cksoff;
+ uint8_t enable_gb_fuse_table_ckson;
+ uint16_t psm_age_comfactor;
+ uint8_t enable_apply_avfs_cksoff_voltage;
+ uint8_t reserved;
+ uint32_t dispclk2gfxclk_a;
+ uint32_t dispclk2gfxclk_b;
+ uint32_t dispclk2gfxclk_c;
+ uint32_t pixclk2gfxclk_a;
+ uint32_t pixclk2gfxclk_b;
+ uint32_t pixclk2gfxclk_c;
+ uint32_t dcefclk2gfxclk_a;
+ uint32_t dcefclk2gfxclk_b;
+ uint32_t dcefclk2gfxclk_c;
+ uint32_t phyclk2gfxclk_a;
+ uint32_t phyclk2gfxclk_b;
+ uint32_t phyclk2gfxclk_c;
+ uint32_t acg_gb_vdroop_table_a0;
+ uint32_t acg_gb_vdroop_table_a1;
+ uint32_t acg_gb_vdroop_table_a2;
+ uint32_t acg_avfsgb_fuse_table_m1;
+ uint32_t acg_avfsgb_fuse_table_m2;
+ uint32_t acg_avfsgb_fuse_table_b;
+ uint8_t enable_acg_gb_vdroop_table;
+ uint8_t enable_acg_gb_fuse_table;
+ uint32_t acg_dispclk2gfxclk_a;
+ uint32_t acg_dispclk2gfxclk_b;
+ uint32_t acg_dispclk2gfxclk_c;
+ uint32_t acg_pixclk2gfxclk_a;
+ uint32_t acg_pixclk2gfxclk_b;
+ uint32_t acg_pixclk2gfxclk_c;
+ uint32_t acg_dcefclk2gfxclk_a;
+ uint32_t acg_dcefclk2gfxclk_b;
+ uint32_t acg_dcefclk2gfxclk_c;
+ uint32_t acg_phyclk2gfxclk_a;
+ uint32_t acg_phyclk2gfxclk_b;
+ uint32_t acg_phyclk2gfxclk_c;
+};
/*
***************************************************************************
diff --git a/drivers/gpu/drm/amd/include/cgs_common.h b/drivers/gpu/drm/amd/include/cgs_common.h
index 0a94f749e3c0..0214f63f52fc 100644
--- a/drivers/gpu/drm/amd/include/cgs_common.h
+++ b/drivers/gpu/drm/amd/include/cgs_common.h
@@ -50,6 +50,7 @@ enum cgs_ind_reg {
CGS_IND_REG__UVD_CTX,
CGS_IND_REG__DIDT,
CGS_IND_REG_GC_CAC,
+ CGS_IND_REG_SE_CAC,
CGS_IND_REG__AUDIO_ENDPT
};
@@ -406,6 +407,8 @@ typedef int (*cgs_is_virtualization_enabled_t)(void *cgs_device);
typedef int (*cgs_enter_safe_mode)(struct cgs_device *cgs_device, bool en);
+typedef void (*cgs_lock_grbm_idx)(struct cgs_device *cgs_device, bool lock);
+
struct cgs_ops {
/* memory management calls (similar to KFD interface) */
cgs_alloc_gpu_mem_t alloc_gpu_mem;
@@ -441,6 +444,7 @@ struct cgs_ops {
cgs_query_system_info query_system_info;
cgs_is_virtualization_enabled_t is_virtualization_enabled;
cgs_enter_safe_mode enter_safe_mode;
+ cgs_lock_grbm_idx lock_grbm_idx;
};
struct cgs_os_ops; /* To be define in OS-specific CGS header */
@@ -517,4 +521,6 @@ struct cgs_device
#define cgs_enter_safe_mode(cgs_device, en) \
CGS_CALL(enter_safe_mode, cgs_device, en)
+#define cgs_lock_grbm_idx(cgs_device, lock) \
+ CGS_CALL(lock_grbm_idx, cgs_device, lock)
#endif /* _CGS_COMMON_H */
diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
index 91ef1484b3bb..94277cb734d2 100644
--- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
@@ -41,6 +41,11 @@ struct kgd_dev;
struct kgd_mem;
+enum kfd_preempt_type {
+ KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN = 0,
+ KFD_PREEMPT_TYPE_WAVEFRONT_RESET,
+};
+
enum kgd_memory_pool {
KGD_POOL_SYSTEM_CACHEABLE = 1,
KGD_POOL_SYSTEM_WRITECOMBINE = 2,
@@ -63,9 +68,6 @@ struct kgd2kfd_shared_resources {
/* Bit n == 1 means VMID n is available for KFD. */
unsigned int compute_vmid_bitmap;
- /* number of mec available from the hardware */
- uint32_t num_mec;
-
/* number of pipes per mec */
uint32_t num_pipe_per_mec;
@@ -85,6 +87,17 @@ struct kgd2kfd_shared_resources {
size_t doorbell_start_offset;
};
+struct tile_config {
+ uint32_t *tile_config_ptr;
+ uint32_t *macro_tile_config_ptr;
+ uint32_t num_tile_configs;
+ uint32_t num_macro_tile_configs;
+
+ uint32_t gb_addr_config;
+ uint32_t num_banks;
+ uint32_t num_ranks;
+};
+
/**
* struct kfd2kgd_calls
*
@@ -126,6 +139,11 @@ struct kgd2kfd_shared_resources {
*
* @get_fw_version: Returns FW versions from the header
*
+ * @set_scratch_backing_va: Sets VA for scratch backing memory of a VMID.
+ * Only used for no cp scheduling mode
+ *
+ * @get_tile_config: Returns GPU-specific tiling mode information
+ *
* This structure contains function pointers to services that the kgd driver
* provides to amdkfd driver.
*
@@ -156,14 +174,16 @@ struct kfd2kgd_calls {
int (*init_interrupts)(struct kgd_dev *kgd, uint32_t pipe_id);
int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
- uint32_t queue_id, uint32_t __user *wptr);
+ uint32_t queue_id, uint32_t __user *wptr,
+ uint32_t wptr_shift, uint32_t wptr_mask,
+ struct mm_struct *mm);
int (*hqd_sdma_load)(struct kgd_dev *kgd, void *mqd);
bool (*hqd_is_occupied)(struct kgd_dev *kgd, uint64_t queue_address,
uint32_t pipe_id, uint32_t queue_id);
- int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type,
+ int (*hqd_destroy)(struct kgd_dev *kgd, void *mqd, uint32_t reset_type,
unsigned int timeout, uint32_t pipe_id,
uint32_t queue_id);
@@ -195,6 +215,9 @@ struct kfd2kgd_calls {
uint16_t (*get_fw_version)(struct kgd_dev *kgd,
enum kgd_engine_type type);
+ void (*set_scratch_backing_va)(struct kgd_dev *kgd,
+ uint64_t va, uint32_t vmid);
+ int (*get_tile_config)(struct kgd_dev *kgd, struct tile_config *config);
};
/**
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
index 0b74da3dca8b..bc839ff0bdd0 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
@@ -1240,13 +1240,18 @@ static int cz_phm_force_dpm_highest(struct pp_hwmgr *hwmgr)
{
struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
- if (cz_hwmgr->sclk_dpm.soft_min_clk !=
- cz_hwmgr->sclk_dpm.soft_max_clk)
- smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
- PPSMC_MSG_SetSclkSoftMin,
- cz_get_sclk_level(hwmgr,
- cz_hwmgr->sclk_dpm.soft_max_clk,
- PPSMC_MSG_SetSclkSoftMin));
+ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+ PPSMC_MSG_SetSclkSoftMin,
+ cz_get_sclk_level(hwmgr,
+ cz_hwmgr->sclk_dpm.soft_max_clk,
+ PPSMC_MSG_SetSclkSoftMin));
+
+ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+ PPSMC_MSG_SetSclkSoftMax,
+ cz_get_sclk_level(hwmgr,
+ cz_hwmgr->sclk_dpm.soft_max_clk,
+ PPSMC_MSG_SetSclkSoftMax));
+
return 0;
}
@@ -1292,17 +1297,55 @@ static int cz_phm_force_dpm_lowest(struct pp_hwmgr *hwmgr)
{
struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
- if (cz_hwmgr->sclk_dpm.soft_min_clk !=
- cz_hwmgr->sclk_dpm.soft_max_clk) {
- cz_hwmgr->sclk_dpm.soft_max_clk =
- cz_hwmgr->sclk_dpm.soft_min_clk;
+ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+ PPSMC_MSG_SetSclkSoftMax,
+ cz_get_sclk_level(hwmgr,
+ cz_hwmgr->sclk_dpm.soft_min_clk,
+ PPSMC_MSG_SetSclkSoftMax));
- smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+ PPSMC_MSG_SetSclkSoftMin,
+ cz_get_sclk_level(hwmgr,
+ cz_hwmgr->sclk_dpm.soft_min_clk,
+ PPSMC_MSG_SetSclkSoftMin));
+
+ return 0;
+}
+
+static int cz_phm_force_dpm_sclk(struct pp_hwmgr *hwmgr, uint32_t sclk)
+{
+ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+ PPSMC_MSG_SetSclkSoftMin,
+ cz_get_sclk_level(hwmgr,
+ sclk,
+ PPSMC_MSG_SetSclkSoftMin));
+
+ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
PPSMC_MSG_SetSclkSoftMax,
cz_get_sclk_level(hwmgr,
- cz_hwmgr->sclk_dpm.soft_max_clk,
+ sclk,
PPSMC_MSG_SetSclkSoftMax));
+ return 0;
+}
+
+static int cz_get_profiling_clk(struct pp_hwmgr *hwmgr, uint32_t *sclk)
+{
+ struct phm_clock_voltage_dependency_table *table =
+ hwmgr->dyn_state.vddc_dependency_on_sclk;
+ int32_t tmp_sclk;
+ int32_t count;
+
+ tmp_sclk = table->entries[table->count-1].clk * 70 / 100;
+
+ for (count = table->count-1; count >= 0; count--) {
+ if (tmp_sclk >= table->entries[count].clk) {
+ tmp_sclk = table->entries[count].clk;
+ *sclk = tmp_sclk;
+ break;
+ }
}
+ if (count < 0)
+ *sclk = table->entries[0].clk;
return 0;
}
@@ -1310,30 +1353,70 @@ static int cz_phm_force_dpm_lowest(struct pp_hwmgr *hwmgr)
static int cz_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
enum amd_dpm_forced_level level)
{
+ uint32_t sclk = 0;
int ret = 0;
+ uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
+ AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
+ AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
+
+ if (level == hwmgr->dpm_level)
+ return ret;
+
+ if (!(hwmgr->dpm_level & profile_mode_mask)) {
+ /* enter profile mode, save current level, disable gfx cg*/
+ if (level & profile_mode_mask) {
+ hwmgr->saved_dpm_level = hwmgr->dpm_level;
+ cgs_set_clockgating_state(hwmgr->device,
+ AMD_IP_BLOCK_TYPE_GFX,
+ AMD_CG_STATE_UNGATE);
+ }
+ } else {
+ /* exit profile mode, restore level, enable gfx cg*/
+ if (!(level & profile_mode_mask)) {
+ if (level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT)
+ level = hwmgr->saved_dpm_level;
+ cgs_set_clockgating_state(hwmgr->device,
+ AMD_IP_BLOCK_TYPE_GFX,
+ AMD_CG_STATE_GATE);
+ }
+ }
switch (level) {
case AMD_DPM_FORCED_LEVEL_HIGH:
+ case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
ret = cz_phm_force_dpm_highest(hwmgr);
if (ret)
return ret;
+ hwmgr->dpm_level = level;
break;
case AMD_DPM_FORCED_LEVEL_LOW:
+ case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
ret = cz_phm_force_dpm_lowest(hwmgr);
if (ret)
return ret;
+ hwmgr->dpm_level = level;
break;
case AMD_DPM_FORCED_LEVEL_AUTO:
ret = cz_phm_unforce_dpm_levels(hwmgr);
if (ret)
return ret;
+ hwmgr->dpm_level = level;
+ break;
+ case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
+ ret = cz_get_profiling_clk(hwmgr, &sclk);
+ if (ret)
+ return ret;
+ hwmgr->dpm_level = level;
+ cz_phm_force_dpm_sclk(hwmgr, sclk);
+ break;
+ case AMD_DPM_FORCED_LEVEL_MANUAL:
+ hwmgr->dpm_level = level;
break;
+ case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
default:
break;
}
- hwmgr->dpm_level = level;
-
return ret;
}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
index d025653c7823..9547f265a8bb 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c
@@ -557,9 +557,8 @@ uint16_t phm_find_closest_vddci(struct pp_atomctrl_voltage_table *vddci_table, u
return vddci_table->entries[i].value;
}
- PP_ASSERT_WITH_CODE(false,
- "VDDCI is larger than max VDDCI in VDDCI Voltage Table!",
- return vddci_table->entries[i-1].value);
+ pr_debug("vddci is larger than max value in vddci_table\n");
+ return vddci_table->entries[i-1].value;
}
int phm_find_boot_level(void *table,
@@ -583,26 +582,26 @@ int phm_get_sclk_for_voltage_evv(struct pp_hwmgr *hwmgr,
phm_ppt_v1_voltage_lookup_table *lookup_table,
uint16_t virtual_voltage_id, int32_t *sclk)
{
- uint8_t entryId;
- uint8_t voltageId;
+ uint8_t entry_id;
+ uint8_t voltage_id;
struct phm_ppt_v1_information *table_info =
(struct phm_ppt_v1_information *)(hwmgr->pptable);
PP_ASSERT_WITH_CODE(lookup_table->count != 0, "Lookup table is empty", return -EINVAL);
/* search for leakage voltage ID 0xff01 ~ 0xff08 and sckl */
- for (entryId = 0; entryId < table_info->vdd_dep_on_sclk->count; entryId++) {
- voltageId = table_info->vdd_dep_on_sclk->entries[entryId].vddInd;
- if (lookup_table->entries[voltageId].us_vdd == virtual_voltage_id)
+ for (entry_id = 0; entry_id < table_info->vdd_dep_on_sclk->count; entry_id++) {
+ voltage_id = table_info->vdd_dep_on_sclk->entries[entry_id].vddInd;
+ if (lookup_table->entries[voltage_id].us_vdd == virtual_voltage_id)
break;
}
- PP_ASSERT_WITH_CODE(entryId < table_info->vdd_dep_on_sclk->count,
- "Can't find requested voltage id in vdd_dep_on_sclk table!",
- return -EINVAL;
- );
+ if (entry_id >= table_info->vdd_dep_on_sclk->count) {
+ pr_debug("Can't find requested voltage id in vdd_dep_on_sclk table\n");
+ return -EINVAL;
+ }
- *sclk = table_info->vdd_dep_on_sclk->entries[entryId].clk;
+ *sclk = table_info->vdd_dep_on_sclk->entries[entry_id].clk;
return 0;
}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c
index 720d5006ff62..c062844b15f3 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.c
@@ -142,7 +142,7 @@ int pp_atomfwctrl_get_voltage_table_v4(struct pp_hwmgr *hwmgr,
}
} else if (voltage_mode == VOLTAGE_OBJ_SVID2) {
voltage_table->psi1_enable =
- voltage_object->svid2_voltage_obj.loadline_psi1 & 0x1;
+ (voltage_object->svid2_voltage_obj.loadline_psi1 & 0x20) >> 5;
voltage_table->psi0_enable =
voltage_object->svid2_voltage_obj.psi0_enable & 0x1;
voltage_table->max_vid_step =
@@ -276,7 +276,10 @@ int pp_atomfwctrl_get_avfs_information(struct pp_hwmgr *hwmgr,
struct pp_atomfwctrl_avfs_parameters *param)
{
uint16_t idx;
+ uint8_t format_revision, content_revision;
+
struct atom_asic_profiling_info_v4_1 *profile;
+ struct atom_asic_profiling_info_v4_2 *profile_v4_2;
idx = GetIndexIntoMasterDataTable(asic_profiling_info);
profile = (struct atom_asic_profiling_info_v4_1 *)
@@ -286,76 +289,172 @@ int pp_atomfwctrl_get_avfs_information(struct pp_hwmgr *hwmgr,
if (!profile)
return -1;
- param->ulMaxVddc = le32_to_cpu(profile->maxvddc);
- param->ulMinVddc = le32_to_cpu(profile->minvddc);
- param->ulMeanNsigmaAcontant0 =
- le32_to_cpu(profile->avfs_meannsigma_acontant0);
- param->ulMeanNsigmaAcontant1 =
- le32_to_cpu(profile->avfs_meannsigma_acontant1);
- param->ulMeanNsigmaAcontant2 =
- le32_to_cpu(profile->avfs_meannsigma_acontant2);
- param->usMeanNsigmaDcTolSigma =
- le16_to_cpu(profile->avfs_meannsigma_dc_tol_sigma);
- param->usMeanNsigmaPlatformMean =
- le16_to_cpu(profile->avfs_meannsigma_platform_mean);
- param->usMeanNsigmaPlatformSigma =
- le16_to_cpu(profile->avfs_meannsigma_platform_sigma);
- param->ulGbVdroopTableCksoffA0 =
- le32_to_cpu(profile->gb_vdroop_table_cksoff_a0);
- param->ulGbVdroopTableCksoffA1 =
- le32_to_cpu(profile->gb_vdroop_table_cksoff_a1);
- param->ulGbVdroopTableCksoffA2 =
- le32_to_cpu(profile->gb_vdroop_table_cksoff_a2);
- param->ulGbVdroopTableCksonA0 =
- le32_to_cpu(profile->gb_vdroop_table_ckson_a0);
- param->ulGbVdroopTableCksonA1 =
- le32_to_cpu(profile->gb_vdroop_table_ckson_a1);
- param->ulGbVdroopTableCksonA2 =
- le32_to_cpu(profile->gb_vdroop_table_ckson_a2);
- param->ulGbFuseTableCksoffM1 =
- le32_to_cpu(profile->avfsgb_fuse_table_cksoff_m1);
- param->ulGbFuseTableCksoffM2 =
- le32_to_cpu(profile->avfsgb_fuse_table_cksoff_m2);
- param->ulGbFuseTableCksoffB =
- le32_to_cpu(profile->avfsgb_fuse_table_cksoff_b);
- param->ulGbFuseTableCksonM1 =
- le32_to_cpu(profile->avfsgb_fuse_table_ckson_m1);
- param->ulGbFuseTableCksonM2 =
- le32_to_cpu(profile->avfsgb_fuse_table_ckson_m2);
- param->ulGbFuseTableCksonB =
- le32_to_cpu(profile->avfsgb_fuse_table_ckson_b);
-
- param->ucEnableGbVdroopTableCkson =
- profile->enable_gb_vdroop_table_ckson;
- param->ucEnableGbFuseTableCkson =
- profile->enable_gb_fuse_table_ckson;
- param->usPsmAgeComfactor =
- le16_to_cpu(profile->psm_age_comfactor);
-
- param->ulDispclk2GfxclkM1 =
- le32_to_cpu(profile->dispclk2gfxclk_a);
- param->ulDispclk2GfxclkM2 =
- le32_to_cpu(profile->dispclk2gfxclk_b);
- param->ulDispclk2GfxclkB =
- le32_to_cpu(profile->dispclk2gfxclk_c);
- param->ulDcefclk2GfxclkM1 =
- le32_to_cpu(profile->dcefclk2gfxclk_a);
- param->ulDcefclk2GfxclkM2 =
- le32_to_cpu(profile->dcefclk2gfxclk_b);
- param->ulDcefclk2GfxclkB =
- le32_to_cpu(profile->dcefclk2gfxclk_c);
- param->ulPixelclk2GfxclkM1 =
- le32_to_cpu(profile->pixclk2gfxclk_a);
- param->ulPixelclk2GfxclkM2 =
- le32_to_cpu(profile->pixclk2gfxclk_b);
- param->ulPixelclk2GfxclkB =
- le32_to_cpu(profile->pixclk2gfxclk_c);
- param->ulPhyclk2GfxclkM1 =
- le32_to_cpu(profile->phyclk2gfxclk_a);
- param->ulPhyclk2GfxclkM2 =
- le32_to_cpu(profile->phyclk2gfxclk_b);
- param->ulPhyclk2GfxclkB =
- le32_to_cpu(profile->phyclk2gfxclk_c);
+ format_revision = ((struct atom_common_table_header *)profile)->format_revision;
+ content_revision = ((struct atom_common_table_header *)profile)->content_revision;
+
+ if (format_revision == 4 && content_revision == 1) {
+ param->ulMaxVddc = le32_to_cpu(profile->maxvddc);
+ param->ulMinVddc = le32_to_cpu(profile->minvddc);
+ param->ulMeanNsigmaAcontant0 =
+ le32_to_cpu(profile->avfs_meannsigma_acontant0);
+ param->ulMeanNsigmaAcontant1 =
+ le32_to_cpu(profile->avfs_meannsigma_acontant1);
+ param->ulMeanNsigmaAcontant2 =
+ le32_to_cpu(profile->avfs_meannsigma_acontant2);
+ param->usMeanNsigmaDcTolSigma =
+ le16_to_cpu(profile->avfs_meannsigma_dc_tol_sigma);
+ param->usMeanNsigmaPlatformMean =
+ le16_to_cpu(profile->avfs_meannsigma_platform_mean);
+ param->usMeanNsigmaPlatformSigma =
+ le16_to_cpu(profile->avfs_meannsigma_platform_sigma);
+ param->ulGbVdroopTableCksoffA0 =
+ le32_to_cpu(profile->gb_vdroop_table_cksoff_a0);
+ param->ulGbVdroopTableCksoffA1 =
+ le32_to_cpu(profile->gb_vdroop_table_cksoff_a1);
+ param->ulGbVdroopTableCksoffA2 =
+ le32_to_cpu(profile->gb_vdroop_table_cksoff_a2);
+ param->ulGbVdroopTableCksonA0 =
+ le32_to_cpu(profile->gb_vdroop_table_ckson_a0);
+ param->ulGbVdroopTableCksonA1 =
+ le32_to_cpu(profile->gb_vdroop_table_ckson_a1);
+ param->ulGbVdroopTableCksonA2 =
+ le32_to_cpu(profile->gb_vdroop_table_ckson_a2);
+ param->ulGbFuseTableCksoffM1 =
+ le32_to_cpu(profile->avfsgb_fuse_table_cksoff_m1);
+ param->ulGbFuseTableCksoffM2 =
+ le32_to_cpu(profile->avfsgb_fuse_table_cksoff_m2);
+ param->ulGbFuseTableCksoffB =
+ le32_to_cpu(profile->avfsgb_fuse_table_cksoff_b);
+ param->ulGbFuseTableCksonM1 =
+ le32_to_cpu(profile->avfsgb_fuse_table_ckson_m1);
+ param->ulGbFuseTableCksonM2 =
+ le32_to_cpu(profile->avfsgb_fuse_table_ckson_m2);
+ param->ulGbFuseTableCksonB =
+ le32_to_cpu(profile->avfsgb_fuse_table_ckson_b);
+
+ param->ucEnableGbVdroopTableCkson =
+ profile->enable_gb_vdroop_table_ckson;
+ param->ucEnableGbFuseTableCkson =
+ profile->enable_gb_fuse_table_ckson;
+ param->usPsmAgeComfactor =
+ le16_to_cpu(profile->psm_age_comfactor);
+
+ param->ulDispclk2GfxclkM1 =
+ le32_to_cpu(profile->dispclk2gfxclk_a);
+ param->ulDispclk2GfxclkM2 =
+ le32_to_cpu(profile->dispclk2gfxclk_b);
+ param->ulDispclk2GfxclkB =
+ le32_to_cpu(profile->dispclk2gfxclk_c);
+ param->ulDcefclk2GfxclkM1 =
+ le32_to_cpu(profile->dcefclk2gfxclk_a);
+ param->ulDcefclk2GfxclkM2 =
+ le32_to_cpu(profile->dcefclk2gfxclk_b);
+ param->ulDcefclk2GfxclkB =
+ le32_to_cpu(profile->dcefclk2gfxclk_c);
+ param->ulPixelclk2GfxclkM1 =
+ le32_to_cpu(profile->pixclk2gfxclk_a);
+ param->ulPixelclk2GfxclkM2 =
+ le32_to_cpu(profile->pixclk2gfxclk_b);
+ param->ulPixelclk2GfxclkB =
+ le32_to_cpu(profile->pixclk2gfxclk_c);
+ param->ulPhyclk2GfxclkM1 =
+ le32_to_cpu(profile->phyclk2gfxclk_a);
+ param->ulPhyclk2GfxclkM2 =
+ le32_to_cpu(profile->phyclk2gfxclk_b);
+ param->ulPhyclk2GfxclkB =
+ le32_to_cpu(profile->phyclk2gfxclk_c);
+ param->ulAcgGbVdroopTableA0 = 0;
+ param->ulAcgGbVdroopTableA1 = 0;
+ param->ulAcgGbVdroopTableA2 = 0;
+ param->ulAcgGbFuseTableM1 = 0;
+ param->ulAcgGbFuseTableM2 = 0;
+ param->ulAcgGbFuseTableB = 0;
+ param->ucAcgEnableGbVdroopTable = 0;
+ param->ucAcgEnableGbFuseTable = 0;
+ } else if (format_revision == 4 && content_revision == 2) {
+ profile_v4_2 = (struct atom_asic_profiling_info_v4_2 *)profile;
+ param->ulMaxVddc = le32_to_cpu(profile_v4_2->maxvddc);
+ param->ulMinVddc = le32_to_cpu(profile_v4_2->minvddc);
+ param->ulMeanNsigmaAcontant0 =
+ le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant0);
+ param->ulMeanNsigmaAcontant1 =
+ le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant1);
+ param->ulMeanNsigmaAcontant2 =
+ le32_to_cpu(profile_v4_2->avfs_meannsigma_acontant2);
+ param->usMeanNsigmaDcTolSigma =
+ le16_to_cpu(profile_v4_2->avfs_meannsigma_dc_tol_sigma);
+ param->usMeanNsigmaPlatformMean =
+ le16_to_cpu(profile_v4_2->avfs_meannsigma_platform_mean);
+ param->usMeanNsigmaPlatformSigma =
+ le16_to_cpu(profile_v4_2->avfs_meannsigma_platform_sigma);
+ param->ulGbVdroopTableCksoffA0 =
+ le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a0);
+ param->ulGbVdroopTableCksoffA1 =
+ le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a1);
+ param->ulGbVdroopTableCksoffA2 =
+ le32_to_cpu(profile_v4_2->gb_vdroop_table_cksoff_a2);
+ param->ulGbVdroopTableCksonA0 =
+ le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a0);
+ param->ulGbVdroopTableCksonA1 =
+ le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a1);
+ param->ulGbVdroopTableCksonA2 =
+ le32_to_cpu(profile_v4_2->gb_vdroop_table_ckson_a2);
+ param->ulGbFuseTableCksoffM1 =
+ le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_m1);
+ param->ulGbFuseTableCksoffM2 =
+ le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_m2);
+ param->ulGbFuseTableCksoffB =
+ le32_to_cpu(profile_v4_2->avfsgb_fuse_table_cksoff_b);
+ param->ulGbFuseTableCksonM1 =
+ le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_m1);
+ param->ulGbFuseTableCksonM2 =
+ le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_m2);
+ param->ulGbFuseTableCksonB =
+ le32_to_cpu(profile_v4_2->avfsgb_fuse_table_ckson_b);
+
+ param->ucEnableGbVdroopTableCkson =
+ profile_v4_2->enable_gb_vdroop_table_ckson;
+ param->ucEnableGbFuseTableCkson =
+ profile_v4_2->enable_gb_fuse_table_ckson;
+ param->usPsmAgeComfactor =
+ le16_to_cpu(profile_v4_2->psm_age_comfactor);
+
+ param->ulDispclk2GfxclkM1 =
+ le32_to_cpu(profile_v4_2->dispclk2gfxclk_a);
+ param->ulDispclk2GfxclkM2 =
+ le32_to_cpu(profile_v4_2->dispclk2gfxclk_b);
+ param->ulDispclk2GfxclkB =
+ le32_to_cpu(profile_v4_2->dispclk2gfxclk_c);
+ param->ulDcefclk2GfxclkM1 =
+ le32_to_cpu(profile_v4_2->dcefclk2gfxclk_a);
+ param->ulDcefclk2GfxclkM2 =
+ le32_to_cpu(profile_v4_2->dcefclk2gfxclk_b);
+ param->ulDcefclk2GfxclkB =
+ le32_to_cpu(profile_v4_2->dcefclk2gfxclk_c);
+ param->ulPixelclk2GfxclkM1 =
+ le32_to_cpu(profile_v4_2->pixclk2gfxclk_a);
+ param->ulPixelclk2GfxclkM2 =
+ le32_to_cpu(profile_v4_2->pixclk2gfxclk_b);
+ param->ulPixelclk2GfxclkB =
+ le32_to_cpu(profile_v4_2->pixclk2gfxclk_c);
+ param->ulPhyclk2GfxclkM1 =
+ le32_to_cpu(profile->phyclk2gfxclk_a);
+ param->ulPhyclk2GfxclkM2 =
+ le32_to_cpu(profile_v4_2->phyclk2gfxclk_b);
+ param->ulPhyclk2GfxclkB =
+ le32_to_cpu(profile_v4_2->phyclk2gfxclk_c);
+ param->ulAcgGbVdroopTableA0 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a0);
+ param->ulAcgGbVdroopTableA1 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a1);
+ param->ulAcgGbVdroopTableA2 = le32_to_cpu(profile_v4_2->acg_gb_vdroop_table_a2);
+ param->ulAcgGbFuseTableM1 = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_m1);
+ param->ulAcgGbFuseTableM2 = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_m2);
+ param->ulAcgGbFuseTableB = le32_to_cpu(profile_v4_2->acg_avfsgb_fuse_table_b);
+ param->ucAcgEnableGbVdroopTable = le32_to_cpu(profile_v4_2->enable_acg_gb_vdroop_table);
+ param->ucAcgEnableGbFuseTable = le32_to_cpu(profile_v4_2->enable_acg_gb_fuse_table);
+ } else {
+ pr_info("Invalid VBIOS AVFS ProfilingInfo Revision!\n");
+ return -EINVAL;
+ }
return 0;
}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h
index 81908b5cfd5f..8e6b1f0ddebc 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomfwctrl.h
@@ -109,6 +109,14 @@ struct pp_atomfwctrl_avfs_parameters {
uint32_t ulPhyclk2GfxclkM1;
uint32_t ulPhyclk2GfxclkM2;
uint32_t ulPhyclk2GfxclkB;
+ uint32_t ulAcgGbVdroopTableA0;
+ uint32_t ulAcgGbVdroopTableA1;
+ uint32_t ulAcgGbVdroopTableA2;
+ uint32_t ulAcgGbFuseTableM1;
+ uint32_t ulAcgGbFuseTableM2;
+ uint32_t ulAcgGbFuseTableB;
+ uint32_t ucAcgEnableGbVdroopTable;
+ uint32_t ucAcgEnableGbFuseTable;
};
struct pp_atomfwctrl_gpio_parameters {
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c
index 4c7f430b36eb..edc5fb6412d9 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c
@@ -265,6 +265,15 @@ static int rv_tf_set_clock_limit(struct pp_hwmgr *hwmgr, void *input,
}
} */
+ if (((hwmgr->uvd_arbiter.vclk_soft_min / 100) != rv_data->vclk_soft_min) ||
+ ((hwmgr->uvd_arbiter.dclk_soft_min / 100) != rv_data->dclk_soft_min)) {
+ rv_data->vclk_soft_min = hwmgr->uvd_arbiter.vclk_soft_min / 100;
+ rv_data->dclk_soft_min = hwmgr->uvd_arbiter.dclk_soft_min / 100;
+ smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
+ PPSMC_MSG_SetSoftMinVcn,
+ (rv_data->vclk_soft_min << 16) | rv_data->vclk_soft_min);
+ }
+
if((hwmgr->gfx_arbiter.sclk_hard_min != 0) &&
((hwmgr->gfx_arbiter.sclk_hard_min / 100) != rv_data->soc_actual_hard_min_freq)) {
smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h
index afb852295a15..2472b50e54cf 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h
@@ -280,6 +280,8 @@ struct rv_hwmgr {
uint32_t f_actual_hard_min_freq;
uint32_t fabric_actual_soft_min_freq;
+ uint32_t vclk_soft_min;
+ uint32_t dclk_soft_min;
uint32_t gfx_actual_soft_min_freq;
bool vcn_power_gated;
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
index 1f01020ce3a9..c2743233ba10 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
@@ -1962,9 +1962,6 @@ static int smu7_thermal_parameter_init(struct pp_hwmgr *hwmgr)
temp_reg = PHM_SET_FIELD(temp_reg, CNB_PWRMGT_CNTL, DPM_ENABLED, 0x1);
break;
default:
- PP_ASSERT_WITH_CODE(0,
- "Failed to setup PCC HW register! Wrong GPIO assigned for VDDC_PCC_GPIO_PINID!",
- );
break;
}
cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixCNB_PWRMGT_CNTL, temp_reg);
@@ -4630,6 +4627,15 @@ static int smu7_set_power_profile_state(struct pp_hwmgr *hwmgr,
static int smu7_avfs_control(struct pp_hwmgr *hwmgr, bool enable)
{
+ struct pp_smumgr *smumgr = (struct pp_smumgr *)(hwmgr->smumgr);
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
+
+ if (smu_data == NULL)
+ return -EINVAL;
+
+ if (smu_data->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED)
+ return 0;
+
if (enable) {
if (!PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device,
CGS_IND_REG__SMC, FEATURE_STATUS, AVS_ON))
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
index d6f097f44b6c..9d71a259d97d 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c
@@ -78,6 +78,8 @@ uint32_t channel_number[] = {1, 2, 0, 4, 0, 8, 0, 16, 2};
#define DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK 0x000000F0L
#define DF_CS_AON0_DramBaseAddress0__IntLvAddrSel_MASK 0x00000700L
#define DF_CS_AON0_DramBaseAddress0__DramBaseAddr_MASK 0xFFFFF000L
+static int vega10_force_clock_level(struct pp_hwmgr *hwmgr,
+ enum pp_clock_type type, uint32_t mask);
const ULONG PhwVega10_Magic = (ULONG)(PHM_VIslands_Magic);
@@ -146,6 +148,19 @@ static void vega10_set_default_registry_data(struct pp_hwmgr *hwmgr)
data->registry_data.vr1hot_enabled = 1;
data->registry_data.regulator_hot_gpio_support = 1;
+ data->registry_data.didt_support = 1;
+ if (data->registry_data.didt_support) {
+ data->registry_data.didt_mode = 6;
+ data->registry_data.sq_ramping_support = 1;
+ data->registry_data.db_ramping_support = 0;
+ data->registry_data.td_ramping_support = 0;
+ data->registry_data.tcp_ramping_support = 0;
+ data->registry_data.dbr_ramping_support = 0;
+ data->registry_data.edc_didt_support = 1;
+ data->registry_data.gc_didt_support = 0;
+ data->registry_data.psm_didt_support = 0;
+ }
+
data->display_voltage_mode = PPVEGA10_VEGA10DISPLAYVOLTAGEMODE_DFLT;
data->dcef_clk_quad_eqn_a = PPREGKEY_VEGA10QUADRATICEQUATION_DFLT;
data->dcef_clk_quad_eqn_b = PPREGKEY_VEGA10QUADRATICEQUATION_DFLT;
@@ -223,6 +238,8 @@ static int vega10_set_features_platform_caps(struct pp_hwmgr *hwmgr)
phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_PowerContainment);
phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+ PHM_PlatformCaps_DiDtSupport);
+ phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_SQRamping);
phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_DBRamping);
@@ -230,6 +247,34 @@ static int vega10_set_features_platform_caps(struct pp_hwmgr *hwmgr)
PHM_PlatformCaps_TDRamping);
phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_TCPRamping);
+ phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+ PHM_PlatformCaps_DBRRamping);
+ phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+ PHM_PlatformCaps_DiDtEDCEnable);
+ phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+ PHM_PlatformCaps_GCEDC);
+ phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
+ PHM_PlatformCaps_PSM);
+
+ if (data->registry_data.didt_support) {
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DiDtSupport);
+ if (data->registry_data.sq_ramping_support)
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SQRamping);
+ if (data->registry_data.db_ramping_support)
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DBRamping);
+ if (data->registry_data.td_ramping_support)
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_TDRamping);
+ if (data->registry_data.tcp_ramping_support)
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_TCPRamping);
+ if (data->registry_data.dbr_ramping_support)
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DBRRamping);
+ if (data->registry_data.edc_didt_support)
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DiDtEDCEnable);
+ if (data->registry_data.gc_didt_support)
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_GCEDC);
+ if (data->registry_data.psm_didt_support)
+ phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PSM);
+ }
if (data->registry_data.power_containment_support)
phm_cap_set(hwmgr->platform_descriptor.platformCaps,
@@ -321,8 +366,8 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr)
FEATURE_LED_DISPLAY_BIT;
data->smu_features[GNLD_FAN_CONTROL].smu_feature_id =
FEATURE_FAN_CONTROL_BIT;
- data->smu_features[GNLD_VOLTAGE_CONTROLLER].smu_feature_id =
- FEATURE_VOLTAGE_CONTROLLER_BIT;
+ data->smu_features[GNLD_ACG].smu_feature_id = FEATURE_ACG_BIT;
+ data->smu_features[GNLD_DIDT].smu_feature_id = FEATURE_GFX_EDC_BIT;
if (!data->registry_data.prefetcher_dpm_key_disabled)
data->smu_features[GNLD_DPM_PREFETCHER].supported = true;
@@ -386,6 +431,15 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr)
if (data->registry_data.vr0hot_enabled)
data->smu_features[GNLD_VR0HOT].supported = true;
+ smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_GetSmuVersion);
+ vega10_read_arg_from_smc(hwmgr->smumgr, &(data->smu_version));
+ /* ACG firmware has major version 5 */
+ if ((data->smu_version & 0xff000000) == 0x5000000)
+ data->smu_features[GNLD_ACG].supported = true;
+
+ if (data->registry_data.didt_support)
+ data->smu_features[GNLD_DIDT].supported = true;
+
}
#ifdef PPLIB_VEGA10_EVV_SUPPORT
@@ -2128,15 +2182,9 @@ static int vega10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
pp_table->AvfsGbCksOff.m2_shift = 12;
pp_table->AvfsGbCksOff.b_shift = 0;
- for (i = 0; i < dep_table->count; i++) {
- if (dep_table->entries[i].sclk_offset == 0)
- pp_table->StaticVoltageOffsetVid[i] = 248;
- else
- pp_table->StaticVoltageOffsetVid[i] =
- (uint8_t)(dep_table->entries[i].sclk_offset *
- VOLTAGE_VID_OFFSET_SCALE2 /
- VOLTAGE_VID_OFFSET_SCALE1);
- }
+ for (i = 0; i < dep_table->count; i++)
+ pp_table->StaticVoltageOffsetVid[i] =
+ convert_to_vid((uint8_t)(dep_table->entries[i].sclk_offset));
if ((PPREGKEY_VEGA10QUADRATICEQUATION_DFLT !=
data->disp_clk_quad_eqn_a) &&
@@ -2228,6 +2276,21 @@ static int vega10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].m1_shift = 24;
pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].m2_shift = 12;
pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].b_shift = 12;
+
+ pp_table->AcgBtcGbVdroopTable.a0 = avfs_params.ulAcgGbVdroopTableA0;
+ pp_table->AcgBtcGbVdroopTable.a0_shift = 20;
+ pp_table->AcgBtcGbVdroopTable.a1 = avfs_params.ulAcgGbVdroopTableA1;
+ pp_table->AcgBtcGbVdroopTable.a1_shift = 20;
+ pp_table->AcgBtcGbVdroopTable.a2 = avfs_params.ulAcgGbVdroopTableA2;
+ pp_table->AcgBtcGbVdroopTable.a2_shift = 20;
+
+ pp_table->AcgAvfsGb.m1 = avfs_params.ulAcgGbFuseTableM1;
+ pp_table->AcgAvfsGb.m2 = avfs_params.ulAcgGbFuseTableM2;
+ pp_table->AcgAvfsGb.b = avfs_params.ulAcgGbFuseTableB;
+ pp_table->AcgAvfsGb.m1_shift = 0;
+ pp_table->AcgAvfsGb.m2_shift = 0;
+ pp_table->AcgAvfsGb.b_shift = 0;
+
} else {
data->smu_features[GNLD_AVFS].supported = false;
}
@@ -2236,6 +2299,55 @@ static int vega10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
return 0;
}
+static int vega10_acg_enable(struct pp_hwmgr *hwmgr)
+{
+ struct vega10_hwmgr *data =
+ (struct vega10_hwmgr *)(hwmgr->backend);
+ uint32_t agc_btc_response;
+
+ if (data->smu_features[GNLD_ACG].supported) {
+ if (0 == vega10_enable_smc_features(hwmgr->smumgr, true,
+ data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_bitmap))
+ data->smu_features[GNLD_DPM_PREFETCHER].enabled = true;
+
+ smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_InitializeAcg);
+
+ smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_RunAcgBtc);
+ vega10_read_arg_from_smc(hwmgr->smumgr, &agc_btc_response);
+
+ if (1 == agc_btc_response) {
+ if (1 == data->acg_loop_state)
+ smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_RunAcgInClosedLoop);
+ else if (2 == data->acg_loop_state)
+ smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_RunAcgInOpenLoop);
+ if (0 == vega10_enable_smc_features(hwmgr->smumgr, true,
+ data->smu_features[GNLD_ACG].smu_feature_bitmap))
+ data->smu_features[GNLD_ACG].enabled = true;
+ } else {
+ pr_info("[ACG_Enable] ACG BTC Returned Failed Status!\n");
+ data->smu_features[GNLD_ACG].enabled = false;
+ }
+ }
+
+ return 0;
+}
+
+static int vega10_acg_disable(struct pp_hwmgr *hwmgr)
+{
+ struct vega10_hwmgr *data =
+ (struct vega10_hwmgr *)(hwmgr->backend);
+
+ if (data->smu_features[GNLD_ACG].supported) {
+ if (data->smu_features[GNLD_ACG].enabled) {
+ if (0 == vega10_enable_smc_features(hwmgr->smumgr, false,
+ data->smu_features[GNLD_ACG].smu_feature_bitmap))
+ data->smu_features[GNLD_ACG].enabled = false;
+ }
+ }
+
+ return 0;
+}
+
static int vega10_populate_gpio_parameters(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
@@ -2410,6 +2522,9 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
pp_table->DisplayDpmVoltageMode =
(uint8_t)(table_info->uc_dcef_dpm_voltage_mode);
+ data->vddc_voltage_table.psi0_enable = voltage_table.psi0_enable;
+ data->vddc_voltage_table.psi1_enable = voltage_table.psi1_enable;
+
if (data->registry_data.ulv_support &&
table_info->us_ulv_voltage_offset) {
result = vega10_populate_ulv_state(hwmgr);
@@ -2506,7 +2621,7 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
result = vega10_avfs_enable(hwmgr, true);
PP_ASSERT_WITH_CODE(!result, "Attempt to enable AVFS feature Failed!",
return result);
-
+ vega10_acg_enable(hwmgr);
vega10_save_default_power_profile(hwmgr);
return 0;
@@ -2838,6 +2953,11 @@ static int vega10_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
PP_ASSERT_WITH_CODE(!tmp_result,
"Failed to start DPM!", result = tmp_result);
+ /* enable didt, do not abort if failed didt */
+ tmp_result = vega10_enable_didt_config(hwmgr);
+ PP_ASSERT(!tmp_result,
+ "Failed to enable didt config!");
+
tmp_result = vega10_enable_power_containment(hwmgr);
PP_ASSERT_WITH_CODE(!tmp_result,
"Failed to enable power containment!",
@@ -3584,10 +3704,22 @@ static void vega10_apply_dal_minimum_voltage_request(
return;
}
+static int vega10_get_soc_index_for_max_uclk(struct pp_hwmgr *hwmgr)
+{
+ struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_table_on_mclk;
+ struct phm_ppt_v2_information *table_info =
+ (struct phm_ppt_v2_information *)(hwmgr->pptable);
+
+ vdd_dep_table_on_mclk = table_info->vdd_dep_on_mclk;
+
+ return vdd_dep_table_on_mclk->entries[NUM_UCLK_DPM_LEVELS - 1].vddInd + 1;
+}
+
static int vega10_upload_dpm_bootup_level(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data =
(struct vega10_hwmgr *)(hwmgr->backend);
+ uint32_t socclk_idx;
vega10_apply_dal_minimum_voltage_request(hwmgr);
@@ -3608,13 +3740,22 @@ static int vega10_upload_dpm_bootup_level(struct pp_hwmgr *hwmgr)
if (!data->registry_data.mclk_dpm_key_disabled) {
if (data->smc_state_table.mem_boot_level !=
data->dpm_table.mem_table.dpm_state.soft_min_level) {
+ if (data->smc_state_table.mem_boot_level == NUM_UCLK_DPM_LEVELS - 1) {
+ socclk_idx = vega10_get_soc_index_for_max_uclk(hwmgr);
PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc_with_parameter(
- hwmgr->smumgr,
- PPSMC_MSG_SetSoftMinUclkByIndex,
- data->smc_state_table.mem_boot_level),
- "Failed to set soft min mclk index!",
- return -EINVAL);
-
+ hwmgr->smumgr,
+ PPSMC_MSG_SetSoftMinSocclkByIndex,
+ socclk_idx),
+ "Failed to set soft min uclk index!",
+ return -EINVAL);
+ } else {
+ PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc_with_parameter(
+ hwmgr->smumgr,
+ PPSMC_MSG_SetSoftMinUclkByIndex,
+ data->smc_state_table.mem_boot_level),
+ "Failed to set soft min uclk index!",
+ return -EINVAL);
+ }
data->dpm_table.mem_table.dpm_state.soft_min_level =
data->smc_state_table.mem_boot_level;
}
@@ -4021,7 +4162,7 @@ static int vega10_notify_smc_display_config_after_ps_adjustment(
pr_info("Attempt to set Hard Min for DCEFCLK Failed!");
}
} else {
- pr_info("Cannot find requested DCEFCLK!");
+ pr_debug("Cannot find requested DCEFCLK!");
}
if (min_clocks.memoryClock != 0) {
@@ -4103,34 +4244,30 @@ static int vega10_unforce_dpm_levels(struct pp_hwmgr *hwmgr)
return 0;
}
-static int vega10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
- enum amd_dpm_forced_level level)
+static int vega10_get_profiling_clk_mask(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level,
+ uint32_t *sclk_mask, uint32_t *mclk_mask, uint32_t *soc_mask)
{
- int ret = 0;
+ struct phm_ppt_v2_information *table_info =
+ (struct phm_ppt_v2_information *)(hwmgr->pptable);
- switch (level) {
- case AMD_DPM_FORCED_LEVEL_HIGH:
- ret = vega10_force_dpm_highest(hwmgr);
- if (ret)
- return ret;
- break;
- case AMD_DPM_FORCED_LEVEL_LOW:
- ret = vega10_force_dpm_lowest(hwmgr);
- if (ret)
- return ret;
- break;
- case AMD_DPM_FORCED_LEVEL_AUTO:
- ret = vega10_unforce_dpm_levels(hwmgr);
- if (ret)
- return ret;
- break;
- default:
- break;
+ if (table_info->vdd_dep_on_sclk->count > VEGA10_UMD_PSTATE_GFXCLK_LEVEL &&
+ table_info->vdd_dep_on_socclk->count > VEGA10_UMD_PSTATE_SOCCLK_LEVEL &&
+ table_info->vdd_dep_on_mclk->count > VEGA10_UMD_PSTATE_MCLK_LEVEL) {
+ *sclk_mask = VEGA10_UMD_PSTATE_GFXCLK_LEVEL;
+ *soc_mask = VEGA10_UMD_PSTATE_SOCCLK_LEVEL;
+ *mclk_mask = VEGA10_UMD_PSTATE_MCLK_LEVEL;
}
- hwmgr->dpm_level = level;
-
- return ret;
+ if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) {
+ *sclk_mask = 0;
+ } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) {
+ *mclk_mask = 0;
+ } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) {
+ *sclk_mask = table_info->vdd_dep_on_sclk->count - 1;
+ *soc_mask = table_info->vdd_dep_on_socclk->count - 1;
+ *mclk_mask = table_info->vdd_dep_on_mclk->count - 1;
+ }
+ return 0;
}
static int vega10_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
@@ -4157,6 +4294,86 @@ static int vega10_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
return result;
}
+static int vega10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
+ enum amd_dpm_forced_level level)
+{
+ int ret = 0;
+ uint32_t sclk_mask = 0;
+ uint32_t mclk_mask = 0;
+ uint32_t soc_mask = 0;
+ uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
+ AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
+ AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK |
+ AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
+
+ if (level == hwmgr->dpm_level)
+ return ret;
+
+ if (!(hwmgr->dpm_level & profile_mode_mask)) {
+ /* enter profile mode, save current level, disable gfx cg*/
+ if (level & profile_mode_mask) {
+ hwmgr->saved_dpm_level = hwmgr->dpm_level;
+ cgs_set_clockgating_state(hwmgr->device,
+ AMD_IP_BLOCK_TYPE_GFX,
+ AMD_CG_STATE_UNGATE);
+ }
+ } else {
+ /* exit profile mode, restore level, enable gfx cg*/
+ if (!(level & profile_mode_mask)) {
+ if (level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT)
+ level = hwmgr->saved_dpm_level;
+ cgs_set_clockgating_state(hwmgr->device,
+ AMD_IP_BLOCK_TYPE_GFX,
+ AMD_CG_STATE_GATE);
+ }
+ }
+
+ switch (level) {
+ case AMD_DPM_FORCED_LEVEL_HIGH:
+ ret = vega10_force_dpm_highest(hwmgr);
+ if (ret)
+ return ret;
+ hwmgr->dpm_level = level;
+ break;
+ case AMD_DPM_FORCED_LEVEL_LOW:
+ ret = vega10_force_dpm_lowest(hwmgr);
+ if (ret)
+ return ret;
+ hwmgr->dpm_level = level;
+ break;
+ case AMD_DPM_FORCED_LEVEL_AUTO:
+ ret = vega10_unforce_dpm_levels(hwmgr);
+ if (ret)
+ return ret;
+ hwmgr->dpm_level = level;
+ break;
+ case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
+ case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
+ case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
+ case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
+ ret = vega10_get_profiling_clk_mask(hwmgr, level, &sclk_mask, &mclk_mask, &soc_mask);
+ if (ret)
+ return ret;
+ hwmgr->dpm_level = level;
+ vega10_force_clock_level(hwmgr, PP_SCLK, 1<<sclk_mask);
+ vega10_force_clock_level(hwmgr, PP_MCLK, 1<<mclk_mask);
+ break;
+ case AMD_DPM_FORCED_LEVEL_MANUAL:
+ hwmgr->dpm_level = level;
+ break;
+ case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
+ default:
+ break;
+ }
+
+ if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK && hwmgr->saved_dpm_level != AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
+ vega10_set_fan_control_mode(hwmgr, AMD_FAN_CTRL_NONE);
+ else if (level != AMD_DPM_FORCED_LEVEL_PROFILE_PEAK && hwmgr->saved_dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
+ vega10_set_fan_control_mode(hwmgr, AMD_FAN_CTRL_AUTO);
+
+ return 0;
+}
+
static int vega10_get_fan_control_mode(struct pp_hwmgr *hwmgr)
{
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
@@ -4402,7 +4619,9 @@ static int vega10_force_clock_level(struct pp_hwmgr *hwmgr,
struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
int i;
- if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
+ if (hwmgr->dpm_level & (AMD_DPM_FORCED_LEVEL_AUTO |
+ AMD_DPM_FORCED_LEVEL_LOW |
+ AMD_DPM_FORCED_LEVEL_HIGH))
return -EINVAL;
switch (type) {
@@ -4667,6 +4886,10 @@ static int vega10_disable_dpm_tasks(struct pp_hwmgr *hwmgr)
PP_ASSERT_WITH_CODE((tmp_result == 0),
"Failed to disable power containment!", result = tmp_result);
+ tmp_result = vega10_disable_didt_config(hwmgr);
+ PP_ASSERT_WITH_CODE((tmp_result == 0),
+ "Failed to disable didt config!", result = tmp_result);
+
tmp_result = vega10_avfs_enable(hwmgr, false);
PP_ASSERT_WITH_CODE((tmp_result == 0),
"Failed to disable AVFS!", result = tmp_result);
@@ -4683,6 +4906,9 @@ static int vega10_disable_dpm_tasks(struct pp_hwmgr *hwmgr)
PP_ASSERT_WITH_CODE((tmp_result == 0),
"Failed to disable ulv!", result = tmp_result);
+ tmp_result = vega10_acg_disable(hwmgr);
+ PP_ASSERT_WITH_CODE((tmp_result == 0),
+ "Failed to disable acg!", result = tmp_result);
return result;
}
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h
index 6e5c5b99593b..676cd7735883 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.h
@@ -64,7 +64,9 @@ enum {
GNLD_FW_CTF,
GNLD_LED_DISPLAY,
GNLD_FAN_CONTROL,
- GNLD_VOLTAGE_CONTROLLER,
+ GNLD_FEATURE_FAST_PPT_BIT,
+ GNLD_DIDT,
+ GNLD_ACG,
GNLD_FEATURES_MAX
};
@@ -230,7 +232,9 @@ struct vega10_registry_data {
uint8_t cac_support;
uint8_t clock_stretcher_support;
uint8_t db_ramping_support;
+ uint8_t didt_mode;
uint8_t didt_support;
+ uint8_t edc_didt_support;
uint8_t dynamic_state_patching_support;
uint8_t enable_pkg_pwr_tracking_feature;
uint8_t enable_tdc_limit_feature;
@@ -263,6 +267,9 @@ struct vega10_registry_data {
uint8_t tcp_ramping_support;
uint8_t tdc_support;
uint8_t td_ramping_support;
+ uint8_t dbr_ramping_support;
+ uint8_t gc_didt_support;
+ uint8_t psm_didt_support;
uint8_t thermal_out_gpio_support;
uint8_t thermal_support;
uint8_t fw_ctf_enabled;
@@ -381,6 +388,8 @@ struct vega10_hwmgr {
struct vega10_smc_state_table smc_state_table;
uint32_t config_telemetry;
+ uint32_t smu_version;
+ uint32_t acg_loop_state;
};
#define VEGA10_DPM2_NEAR_TDP_DEC 10
@@ -425,6 +434,10 @@ struct vega10_hwmgr {
#define PPVEGA10_VEGA10UCLKCLKAVERAGEALPHA_DFLT 25 /* 10% * 255 = 25 */
#define PPVEGA10_VEGA10GFXACTIVITYAVERAGEALPHA_DFLT 25 /* 10% * 255 = 25 */
+#define VEGA10_UMD_PSTATE_GFXCLK_LEVEL 0x3
+#define VEGA10_UMD_PSTATE_SOCCLK_LEVEL 0x3
+#define VEGA10_UMD_PSTATE_MCLK_LEVEL 0x2
+
extern int tonga_initializa_dynamic_state_adjustment_rule_settings(struct pp_hwmgr *hwmgr);
extern int tonga_hwmgr_backend_fini(struct pp_hwmgr *hwmgr);
extern int tonga_get_mc_microcode_version (struct pp_hwmgr *hwmgr);
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c
index 3f72268e99bb..e7fa67063cdc 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.c
@@ -26,7 +26,1298 @@
#include "vega10_powertune.h"
#include "vega10_smumgr.h"
#include "vega10_ppsmc.h"
+#include "vega10_inc.h"
#include "pp_debug.h"
+#include "pp_soc15.h"
+
+static const struct vega10_didt_config_reg SEDiDtTuningCtrlConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* DIDT_SQ */
+ { ixDIDT_SQ_TUNING_CTRL, DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_HI_MASK, DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_HI__SHIFT, 0x3853 },
+ { ixDIDT_SQ_TUNING_CTRL, DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_LO_MASK, DIDT_SQ_TUNING_CTRL__MAX_POWER_DELTA_LO__SHIFT, 0x3153 },
+
+ /* DIDT_TD */
+ { ixDIDT_TD_TUNING_CTRL, DIDT_TD_TUNING_CTRL__MAX_POWER_DELTA_HI_MASK, DIDT_TD_TUNING_CTRL__MAX_POWER_DELTA_HI__SHIFT, 0x0dde },
+ { ixDIDT_TD_TUNING_CTRL, DIDT_TD_TUNING_CTRL__MAX_POWER_DELTA_LO_MASK, DIDT_TD_TUNING_CTRL__MAX_POWER_DELTA_LO__SHIFT, 0x0dde },
+
+ /* DIDT_TCP */
+ { ixDIDT_TCP_TUNING_CTRL, DIDT_TCP_TUNING_CTRL__MAX_POWER_DELTA_HI_MASK, DIDT_TCP_TUNING_CTRL__MAX_POWER_DELTA_HI__SHIFT, 0x3dde },
+ { ixDIDT_TCP_TUNING_CTRL, DIDT_TCP_TUNING_CTRL__MAX_POWER_DELTA_LO_MASK, DIDT_TCP_TUNING_CTRL__MAX_POWER_DELTA_LO__SHIFT, 0x3dde },
+
+ /* DIDT_DB */
+ { ixDIDT_DB_TUNING_CTRL, DIDT_DB_TUNING_CTRL__MAX_POWER_DELTA_HI_MASK, DIDT_DB_TUNING_CTRL__MAX_POWER_DELTA_HI__SHIFT, 0x3dde },
+ { ixDIDT_DB_TUNING_CTRL, DIDT_DB_TUNING_CTRL__MAX_POWER_DELTA_LO_MASK, DIDT_DB_TUNING_CTRL__MAX_POWER_DELTA_LO__SHIFT, 0x3dde },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEDiDtCtrl3Config_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /*DIDT_SQ_CTRL3 */
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__GC_DIDT_ENABLE_MASK, DIDT_SQ_CTRL3__GC_DIDT_ENABLE__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__GC_DIDT_CLK_EN_OVERRIDE_MASK, DIDT_SQ_CTRL3__GC_DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__THROTTLE_POLICY_MASK, DIDT_SQ_CTRL3__THROTTLE_POLICY__SHIFT, 0x0003 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__DIDT_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_SQ_CTRL3__DIDT_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__DIDT_POWER_LEVEL_LOWBIT_MASK, DIDT_SQ_CTRL3__DIDT_POWER_LEVEL_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__DIDT_STALL_PATTERN_BIT_NUMS_MASK, DIDT_SQ_CTRL3__DIDT_STALL_PATTERN_BIT_NUMS__SHIFT, 0x0003 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__GC_DIDT_LEVEL_COMB_EN_MASK, DIDT_SQ_CTRL3__GC_DIDT_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__SE_DIDT_LEVEL_COMB_EN_MASK, DIDT_SQ_CTRL3__SE_DIDT_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__QUALIFY_STALL_EN_MASK, DIDT_SQ_CTRL3__QUALIFY_STALL_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__DIDT_STALL_SEL_MASK, DIDT_SQ_CTRL3__DIDT_STALL_SEL__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__DIDT_FORCE_STALL_MASK, DIDT_SQ_CTRL3__DIDT_FORCE_STALL__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL3, DIDT_SQ_CTRL3__DIDT_STALL_DELAY_EN_MASK, DIDT_SQ_CTRL3__DIDT_STALL_DELAY_EN__SHIFT, 0x0000 },
+
+ /*DIDT_TCP_CTRL3 */
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__GC_DIDT_ENABLE_MASK, DIDT_TCP_CTRL3__GC_DIDT_ENABLE__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__GC_DIDT_CLK_EN_OVERRIDE_MASK, DIDT_TCP_CTRL3__GC_DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__THROTTLE_POLICY_MASK, DIDT_TCP_CTRL3__THROTTLE_POLICY__SHIFT, 0x0003 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__DIDT_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_TCP_CTRL3__DIDT_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__DIDT_POWER_LEVEL_LOWBIT_MASK, DIDT_TCP_CTRL3__DIDT_POWER_LEVEL_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__DIDT_STALL_PATTERN_BIT_NUMS_MASK, DIDT_TCP_CTRL3__DIDT_STALL_PATTERN_BIT_NUMS__SHIFT, 0x0003 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__GC_DIDT_LEVEL_COMB_EN_MASK, DIDT_TCP_CTRL3__GC_DIDT_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__SE_DIDT_LEVEL_COMB_EN_MASK, DIDT_TCP_CTRL3__SE_DIDT_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__QUALIFY_STALL_EN_MASK, DIDT_TCP_CTRL3__QUALIFY_STALL_EN__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__DIDT_STALL_SEL_MASK, DIDT_TCP_CTRL3__DIDT_STALL_SEL__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__DIDT_FORCE_STALL_MASK, DIDT_TCP_CTRL3__DIDT_FORCE_STALL__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL3, DIDT_TCP_CTRL3__DIDT_STALL_DELAY_EN_MASK, DIDT_TCP_CTRL3__DIDT_STALL_DELAY_EN__SHIFT, 0x0000 },
+
+ /*DIDT_TD_CTRL3 */
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__GC_DIDT_ENABLE_MASK, DIDT_TD_CTRL3__GC_DIDT_ENABLE__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__GC_DIDT_CLK_EN_OVERRIDE_MASK, DIDT_TD_CTRL3__GC_DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__THROTTLE_POLICY_MASK, DIDT_TD_CTRL3__THROTTLE_POLICY__SHIFT, 0x0003 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__DIDT_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_TD_CTRL3__DIDT_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__DIDT_POWER_LEVEL_LOWBIT_MASK, DIDT_TD_CTRL3__DIDT_POWER_LEVEL_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__DIDT_STALL_PATTERN_BIT_NUMS_MASK, DIDT_TD_CTRL3__DIDT_STALL_PATTERN_BIT_NUMS__SHIFT, 0x0003 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__GC_DIDT_LEVEL_COMB_EN_MASK, DIDT_TD_CTRL3__GC_DIDT_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__SE_DIDT_LEVEL_COMB_EN_MASK, DIDT_TD_CTRL3__SE_DIDT_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__QUALIFY_STALL_EN_MASK, DIDT_TD_CTRL3__QUALIFY_STALL_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__DIDT_STALL_SEL_MASK, DIDT_TD_CTRL3__DIDT_STALL_SEL__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__DIDT_FORCE_STALL_MASK, DIDT_TD_CTRL3__DIDT_FORCE_STALL__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL3, DIDT_TD_CTRL3__DIDT_STALL_DELAY_EN_MASK, DIDT_TD_CTRL3__DIDT_STALL_DELAY_EN__SHIFT, 0x0000 },
+
+ /*DIDT_DB_CTRL3 */
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__GC_DIDT_ENABLE_MASK, DIDT_DB_CTRL3__GC_DIDT_ENABLE__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__GC_DIDT_CLK_EN_OVERRIDE_MASK, DIDT_DB_CTRL3__GC_DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__THROTTLE_POLICY_MASK, DIDT_DB_CTRL3__THROTTLE_POLICY__SHIFT, 0x0003 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__DIDT_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_DB_CTRL3__DIDT_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__DIDT_POWER_LEVEL_LOWBIT_MASK, DIDT_DB_CTRL3__DIDT_POWER_LEVEL_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__DIDT_STALL_PATTERN_BIT_NUMS_MASK, DIDT_DB_CTRL3__DIDT_STALL_PATTERN_BIT_NUMS__SHIFT, 0x0003 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__GC_DIDT_LEVEL_COMB_EN_MASK, DIDT_DB_CTRL3__GC_DIDT_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__SE_DIDT_LEVEL_COMB_EN_MASK, DIDT_DB_CTRL3__SE_DIDT_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__QUALIFY_STALL_EN_MASK, DIDT_DB_CTRL3__QUALIFY_STALL_EN__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__DIDT_STALL_SEL_MASK, DIDT_DB_CTRL3__DIDT_STALL_SEL__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__DIDT_FORCE_STALL_MASK, DIDT_DB_CTRL3__DIDT_FORCE_STALL__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL3, DIDT_DB_CTRL3__DIDT_STALL_DELAY_EN_MASK, DIDT_DB_CTRL3__DIDT_STALL_DELAY_EN__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEDiDtCtrl2Config_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* DIDT_SQ */
+ { ixDIDT_SQ_CTRL2, DIDT_SQ_CTRL2__MAX_POWER_DELTA_MASK, DIDT_SQ_CTRL2__MAX_POWER_DELTA__SHIFT, 0x3853 },
+ { ixDIDT_SQ_CTRL2, DIDT_SQ_CTRL2__SHORT_TERM_INTERVAL_SIZE_MASK, DIDT_SQ_CTRL2__SHORT_TERM_INTERVAL_SIZE__SHIFT, 0x00c0 },
+ { ixDIDT_SQ_CTRL2, DIDT_SQ_CTRL2__LONG_TERM_INTERVAL_RATIO_MASK, DIDT_SQ_CTRL2__LONG_TERM_INTERVAL_RATIO__SHIFT, 0x0000 },
+
+ /* DIDT_TD */
+ { ixDIDT_TD_CTRL2, DIDT_TD_CTRL2__MAX_POWER_DELTA_MASK, DIDT_TD_CTRL2__MAX_POWER_DELTA__SHIFT, 0x3fff },
+ { ixDIDT_TD_CTRL2, DIDT_TD_CTRL2__SHORT_TERM_INTERVAL_SIZE_MASK, DIDT_TD_CTRL2__SHORT_TERM_INTERVAL_SIZE__SHIFT, 0x00c0 },
+ { ixDIDT_TD_CTRL2, DIDT_TD_CTRL2__LONG_TERM_INTERVAL_RATIO_MASK, DIDT_TD_CTRL2__LONG_TERM_INTERVAL_RATIO__SHIFT, 0x0001 },
+
+ /* DIDT_TCP */
+ { ixDIDT_TCP_CTRL2, DIDT_TCP_CTRL2__MAX_POWER_DELTA_MASK, DIDT_TCP_CTRL2__MAX_POWER_DELTA__SHIFT, 0x3dde },
+ { ixDIDT_TCP_CTRL2, DIDT_TCP_CTRL2__SHORT_TERM_INTERVAL_SIZE_MASK, DIDT_TCP_CTRL2__SHORT_TERM_INTERVAL_SIZE__SHIFT, 0x00c0 },
+ { ixDIDT_TCP_CTRL2, DIDT_TCP_CTRL2__LONG_TERM_INTERVAL_RATIO_MASK, DIDT_TCP_CTRL2__LONG_TERM_INTERVAL_RATIO__SHIFT, 0x0001 },
+
+ /* DIDT_DB */
+ { ixDIDT_DB_CTRL2, DIDT_DB_CTRL2__MAX_POWER_DELTA_MASK, DIDT_DB_CTRL2__MAX_POWER_DELTA__SHIFT, 0x3dde },
+ { ixDIDT_DB_CTRL2, DIDT_DB_CTRL2__SHORT_TERM_INTERVAL_SIZE_MASK, DIDT_DB_CTRL2__SHORT_TERM_INTERVAL_SIZE__SHIFT, 0x00c0 },
+ { ixDIDT_DB_CTRL2, DIDT_DB_CTRL2__LONG_TERM_INTERVAL_RATIO_MASK, DIDT_DB_CTRL2__LONG_TERM_INTERVAL_RATIO__SHIFT, 0x0001 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEDiDtCtrl1Config_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* DIDT_SQ */
+ { ixDIDT_SQ_CTRL1, DIDT_SQ_CTRL1__MIN_POWER_MASK, DIDT_SQ_CTRL1__MIN_POWER__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL1, DIDT_SQ_CTRL1__MAX_POWER_MASK, DIDT_SQ_CTRL1__MAX_POWER__SHIFT, 0xffff },
+ /* DIDT_TD */
+ { ixDIDT_TD_CTRL1, DIDT_TD_CTRL1__MIN_POWER_MASK, DIDT_TD_CTRL1__MIN_POWER__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL1, DIDT_TD_CTRL1__MAX_POWER_MASK, DIDT_TD_CTRL1__MAX_POWER__SHIFT, 0xffff },
+ /* DIDT_TCP */
+ { ixDIDT_TCP_CTRL1, DIDT_TCP_CTRL1__MIN_POWER_MASK, DIDT_TCP_CTRL1__MIN_POWER__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL1, DIDT_TCP_CTRL1__MAX_POWER_MASK, DIDT_TCP_CTRL1__MAX_POWER__SHIFT, 0xffff },
+ /* DIDT_DB */
+ { ixDIDT_DB_CTRL1, DIDT_DB_CTRL1__MIN_POWER_MASK, DIDT_DB_CTRL1__MIN_POWER__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL1, DIDT_DB_CTRL1__MAX_POWER_MASK, DIDT_DB_CTRL1__MAX_POWER__SHIFT, 0xffff },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+
+static const struct vega10_didt_config_reg SEDiDtWeightConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* DIDT_SQ */
+ { ixDIDT_SQ_WEIGHT0_3, 0xFFFFFFFF, 0, 0x2B363B1A },
+ { ixDIDT_SQ_WEIGHT4_7, 0xFFFFFFFF, 0, 0x270B2432 },
+ { ixDIDT_SQ_WEIGHT8_11, 0xFFFFFFFF, 0, 0x00000018 },
+
+ /* DIDT_TD */
+ { ixDIDT_TD_WEIGHT0_3, 0xFFFFFFFF, 0, 0x2B1D220F },
+ { ixDIDT_TD_WEIGHT4_7, 0xFFFFFFFF, 0, 0x00007558 },
+ { ixDIDT_TD_WEIGHT8_11, 0xFFFFFFFF, 0, 0x00000000 },
+
+ /* DIDT_TCP */
+ { ixDIDT_TCP_WEIGHT0_3, 0xFFFFFFFF, 0, 0x5ACE160D },
+ { ixDIDT_TCP_WEIGHT4_7, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TCP_WEIGHT8_11, 0xFFFFFFFF, 0, 0x00000000 },
+
+ /* DIDT_DB */
+ { ixDIDT_DB_WEIGHT0_3, 0xFFFFFFFF, 0, 0x0E152A0F },
+ { ixDIDT_DB_WEIGHT4_7, 0xFFFFFFFF, 0, 0x09061813 },
+ { ixDIDT_DB_WEIGHT8_11, 0xFFFFFFFF, 0, 0x00000013 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEDiDtCtrl0Config_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* DIDT_SQ */
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_CTRL_EN_MASK, DIDT_SQ_CTRL0__DIDT_CTRL_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__PHASE_OFFSET_MASK, DIDT_SQ_CTRL0__PHASE_OFFSET__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_CTRL_RST_MASK, DIDT_SQ_CTRL0__DIDT_CTRL_RST__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK, DIDT_SQ_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_STALL_CTRL_EN_MASK, DIDT_SQ_CTRL0__DIDT_STALL_CTRL_EN__SHIFT, 0x0001 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_TUNING_CTRL_EN_MASK, DIDT_SQ_CTRL0__DIDT_TUNING_CTRL_EN__SHIFT, 0x0001 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_STALL_AUTO_RELEASE_EN_MASK, DIDT_SQ_CTRL0__DIDT_STALL_AUTO_RELEASE_EN__SHIFT, 0x0001 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_HI_POWER_THRESHOLD_MASK, DIDT_SQ_CTRL0__DIDT_HI_POWER_THRESHOLD__SHIFT, 0xffff },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_AUTO_MPD_EN_MASK, DIDT_SQ_CTRL0__DIDT_AUTO_MPD_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_STALL_EVENT_EN_MASK, DIDT_SQ_CTRL0__DIDT_STALL_EVENT_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_CTRL0, DIDT_SQ_CTRL0__DIDT_STALL_EVENT_COUNTER_CLEAR_MASK, DIDT_SQ_CTRL0__DIDT_STALL_EVENT_COUNTER_CLEAR__SHIFT, 0x0000 },
+ /* DIDT_TD */
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_CTRL_EN_MASK, DIDT_TD_CTRL0__DIDT_CTRL_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__PHASE_OFFSET_MASK, DIDT_TD_CTRL0__PHASE_OFFSET__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_CTRL_RST_MASK, DIDT_TD_CTRL0__DIDT_CTRL_RST__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK, DIDT_TD_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_STALL_CTRL_EN_MASK, DIDT_TD_CTRL0__DIDT_STALL_CTRL_EN__SHIFT, 0x0001 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_TUNING_CTRL_EN_MASK, DIDT_TD_CTRL0__DIDT_TUNING_CTRL_EN__SHIFT, 0x0001 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_STALL_AUTO_RELEASE_EN_MASK, DIDT_TD_CTRL0__DIDT_STALL_AUTO_RELEASE_EN__SHIFT, 0x0001 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_HI_POWER_THRESHOLD_MASK, DIDT_TD_CTRL0__DIDT_HI_POWER_THRESHOLD__SHIFT, 0xffff },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_AUTO_MPD_EN_MASK, DIDT_TD_CTRL0__DIDT_AUTO_MPD_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_STALL_EVENT_EN_MASK, DIDT_TD_CTRL0__DIDT_STALL_EVENT_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_CTRL0, DIDT_TD_CTRL0__DIDT_STALL_EVENT_COUNTER_CLEAR_MASK, DIDT_TD_CTRL0__DIDT_STALL_EVENT_COUNTER_CLEAR__SHIFT, 0x0000 },
+ /* DIDT_TCP */
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_CTRL_EN_MASK, DIDT_TCP_CTRL0__DIDT_CTRL_EN__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__PHASE_OFFSET_MASK, DIDT_TCP_CTRL0__PHASE_OFFSET__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_CTRL_RST_MASK, DIDT_TCP_CTRL0__DIDT_CTRL_RST__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK, DIDT_TCP_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_STALL_CTRL_EN_MASK, DIDT_TCP_CTRL0__DIDT_STALL_CTRL_EN__SHIFT, 0x0001 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_TUNING_CTRL_EN_MASK, DIDT_TCP_CTRL0__DIDT_TUNING_CTRL_EN__SHIFT, 0x0001 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_STALL_AUTO_RELEASE_EN_MASK, DIDT_TCP_CTRL0__DIDT_STALL_AUTO_RELEASE_EN__SHIFT, 0x0001 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_HI_POWER_THRESHOLD_MASK, DIDT_TCP_CTRL0__DIDT_HI_POWER_THRESHOLD__SHIFT, 0xffff },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_AUTO_MPD_EN_MASK, DIDT_TCP_CTRL0__DIDT_AUTO_MPD_EN__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_STALL_EVENT_EN_MASK, DIDT_TCP_CTRL0__DIDT_STALL_EVENT_EN__SHIFT, 0x0000 },
+ { ixDIDT_TCP_CTRL0, DIDT_TCP_CTRL0__DIDT_STALL_EVENT_COUNTER_CLEAR_MASK, DIDT_TCP_CTRL0__DIDT_STALL_EVENT_COUNTER_CLEAR__SHIFT, 0x0000 },
+ /* DIDT_DB */
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_CTRL_EN_MASK, DIDT_DB_CTRL0__DIDT_CTRL_EN__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__PHASE_OFFSET_MASK, DIDT_DB_CTRL0__PHASE_OFFSET__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_CTRL_RST_MASK, DIDT_DB_CTRL0__DIDT_CTRL_RST__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK, DIDT_DB_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_STALL_CTRL_EN_MASK, DIDT_DB_CTRL0__DIDT_STALL_CTRL_EN__SHIFT, 0x0001 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_TUNING_CTRL_EN_MASK, DIDT_DB_CTRL0__DIDT_TUNING_CTRL_EN__SHIFT, 0x0001 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_STALL_AUTO_RELEASE_EN_MASK, DIDT_DB_CTRL0__DIDT_STALL_AUTO_RELEASE_EN__SHIFT, 0x0001 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_HI_POWER_THRESHOLD_MASK, DIDT_DB_CTRL0__DIDT_HI_POWER_THRESHOLD__SHIFT, 0xffff },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_AUTO_MPD_EN_MASK, DIDT_DB_CTRL0__DIDT_AUTO_MPD_EN__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_STALL_EVENT_EN_MASK, DIDT_DB_CTRL0__DIDT_STALL_EVENT_EN__SHIFT, 0x0000 },
+ { ixDIDT_DB_CTRL0, DIDT_DB_CTRL0__DIDT_STALL_EVENT_COUNTER_CLEAR_MASK, DIDT_DB_CTRL0__DIDT_STALL_EVENT_COUNTER_CLEAR__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+
+static const struct vega10_didt_config_reg SEDiDtStallCtrlConfig_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* DIDT_SQ */
+ { ixDIDT_SQ_STALL_CTRL, DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_HI_MASK, DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_HI__SHIFT, 0x0004 },
+ { ixDIDT_SQ_STALL_CTRL, DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_LO_MASK, DIDT_SQ_STALL_CTRL__DIDT_STALL_DELAY_LO__SHIFT, 0x0004 },
+ { ixDIDT_SQ_STALL_CTRL, DIDT_SQ_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_HI_MASK, DIDT_SQ_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_HI__SHIFT, 0x000a },
+ { ixDIDT_SQ_STALL_CTRL, DIDT_SQ_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_LO_MASK, DIDT_SQ_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_LO__SHIFT, 0x000a },
+
+ /* DIDT_TD */
+ { ixDIDT_TD_STALL_CTRL, DIDT_TD_STALL_CTRL__DIDT_STALL_DELAY_HI_MASK, DIDT_TD_STALL_CTRL__DIDT_STALL_DELAY_HI__SHIFT, 0x0001 },
+ { ixDIDT_TD_STALL_CTRL, DIDT_TD_STALL_CTRL__DIDT_STALL_DELAY_LO_MASK, DIDT_TD_STALL_CTRL__DIDT_STALL_DELAY_LO__SHIFT, 0x0001 },
+ { ixDIDT_TD_STALL_CTRL, DIDT_TD_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_HI_MASK, DIDT_TD_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_HI__SHIFT, 0x000a },
+ { ixDIDT_TD_STALL_CTRL, DIDT_TD_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_LO_MASK, DIDT_TD_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_LO__SHIFT, 0x000a },
+
+ /* DIDT_TCP */
+ { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_HI_MASK, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_HI__SHIFT, 0x0001 },
+ { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_LO_MASK, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_LO__SHIFT, 0x0001 },
+ { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_HI_MASK, DIDT_TCP_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_HI__SHIFT, 0x000a },
+ { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_LO_MASK, DIDT_TCP_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_LO__SHIFT, 0x000a },
+
+ /* DIDT_DB */
+ { ixDIDT_DB_STALL_CTRL, DIDT_DB_STALL_CTRL__DIDT_STALL_DELAY_HI_MASK, DIDT_DB_STALL_CTRL__DIDT_STALL_DELAY_HI__SHIFT, 0x0004 },
+ { ixDIDT_DB_STALL_CTRL, DIDT_DB_STALL_CTRL__DIDT_STALL_DELAY_LO_MASK, DIDT_DB_STALL_CTRL__DIDT_STALL_DELAY_LO__SHIFT, 0x0004 },
+ { ixDIDT_DB_STALL_CTRL, DIDT_DB_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_HI_MASK, DIDT_DB_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_HI__SHIFT, 0x000a },
+ { ixDIDT_DB_STALL_CTRL, DIDT_DB_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_LO_MASK, DIDT_DB_STALL_CTRL__DIDT_MAX_STALLS_ALLOWED_LO__SHIFT, 0x000a },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEDiDtStallPatternConfig_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* DIDT_SQ_STALL_PATTERN_1_2 */
+ { ixDIDT_SQ_STALL_PATTERN_1_2, DIDT_SQ_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_1_MASK, DIDT_SQ_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_1__SHIFT, 0x0001 },
+ { ixDIDT_SQ_STALL_PATTERN_1_2, DIDT_SQ_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_2_MASK, DIDT_SQ_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_2__SHIFT, 0x0001 },
+
+ /* DIDT_SQ_STALL_PATTERN_3_4 */
+ { ixDIDT_SQ_STALL_PATTERN_3_4, DIDT_SQ_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_3_MASK, DIDT_SQ_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_3__SHIFT, 0x0001 },
+ { ixDIDT_SQ_STALL_PATTERN_3_4, DIDT_SQ_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_4_MASK, DIDT_SQ_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_4__SHIFT, 0x0001 },
+
+ /* DIDT_SQ_STALL_PATTERN_5_6 */
+ { ixDIDT_SQ_STALL_PATTERN_5_6, DIDT_SQ_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_5_MASK, DIDT_SQ_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_5__SHIFT, 0x0000 },
+ { ixDIDT_SQ_STALL_PATTERN_5_6, DIDT_SQ_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_6_MASK, DIDT_SQ_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_6__SHIFT, 0x0000 },
+
+ /* DIDT_SQ_STALL_PATTERN_7 */
+ { ixDIDT_SQ_STALL_PATTERN_7, DIDT_SQ_STALL_PATTERN_7__DIDT_STALL_PATTERN_7_MASK, DIDT_SQ_STALL_PATTERN_7__DIDT_STALL_PATTERN_7__SHIFT, 0x0000 },
+
+ /* DIDT_TCP_STALL_PATTERN_1_2 */
+ { ixDIDT_TCP_STALL_PATTERN_1_2, DIDT_TCP_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_1_MASK, DIDT_TCP_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_1__SHIFT, 0x0001 },
+ { ixDIDT_TCP_STALL_PATTERN_1_2, DIDT_TCP_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_2_MASK, DIDT_TCP_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_2__SHIFT, 0x0001 },
+
+ /* DIDT_TCP_STALL_PATTERN_3_4 */
+ { ixDIDT_TCP_STALL_PATTERN_3_4, DIDT_TCP_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_3_MASK, DIDT_TCP_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_3__SHIFT, 0x0001 },
+ { ixDIDT_TCP_STALL_PATTERN_3_4, DIDT_TCP_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_4_MASK, DIDT_TCP_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_4__SHIFT, 0x0001 },
+
+ /* DIDT_TCP_STALL_PATTERN_5_6 */
+ { ixDIDT_TCP_STALL_PATTERN_5_6, DIDT_TCP_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_5_MASK, DIDT_TCP_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_5__SHIFT, 0x0000 },
+ { ixDIDT_TCP_STALL_PATTERN_5_6, DIDT_TCP_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_6_MASK, DIDT_TCP_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_6__SHIFT, 0x0000 },
+
+ /* DIDT_TCP_STALL_PATTERN_7 */
+ { ixDIDT_TCP_STALL_PATTERN_7, DIDT_TCP_STALL_PATTERN_7__DIDT_STALL_PATTERN_7_MASK, DIDT_TCP_STALL_PATTERN_7__DIDT_STALL_PATTERN_7__SHIFT, 0x0000 },
+
+ /* DIDT_TD_STALL_PATTERN_1_2 */
+ { ixDIDT_TD_STALL_PATTERN_1_2, DIDT_TD_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_1_MASK, DIDT_TD_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_1__SHIFT, 0x0001 },
+ { ixDIDT_TD_STALL_PATTERN_1_2, DIDT_TD_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_2_MASK, DIDT_TD_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_2__SHIFT, 0x0001 },
+
+ /* DIDT_TD_STALL_PATTERN_3_4 */
+ { ixDIDT_TD_STALL_PATTERN_3_4, DIDT_TD_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_3_MASK, DIDT_TD_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_3__SHIFT, 0x0001 },
+ { ixDIDT_TD_STALL_PATTERN_3_4, DIDT_TD_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_4_MASK, DIDT_TD_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_4__SHIFT, 0x0001 },
+
+ /* DIDT_TD_STALL_PATTERN_5_6 */
+ { ixDIDT_TD_STALL_PATTERN_5_6, DIDT_TD_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_5_MASK, DIDT_TD_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_5__SHIFT, 0x0000 },
+ { ixDIDT_TD_STALL_PATTERN_5_6, DIDT_TD_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_6_MASK, DIDT_TD_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_6__SHIFT, 0x0000 },
+
+ /* DIDT_TD_STALL_PATTERN_7 */
+ { ixDIDT_TD_STALL_PATTERN_7, DIDT_TD_STALL_PATTERN_7__DIDT_STALL_PATTERN_7_MASK, DIDT_TD_STALL_PATTERN_7__DIDT_STALL_PATTERN_7__SHIFT, 0x0000 },
+
+ /* DIDT_DB_STALL_PATTERN_1_2 */
+ { ixDIDT_DB_STALL_PATTERN_1_2, DIDT_DB_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_1_MASK, DIDT_DB_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_1__SHIFT, 0x0001 },
+ { ixDIDT_DB_STALL_PATTERN_1_2, DIDT_DB_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_2_MASK, DIDT_DB_STALL_PATTERN_1_2__DIDT_STALL_PATTERN_2__SHIFT, 0x0001 },
+
+ /* DIDT_DB_STALL_PATTERN_3_4 */
+ { ixDIDT_DB_STALL_PATTERN_3_4, DIDT_DB_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_3_MASK, DIDT_DB_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_3__SHIFT, 0x0001 },
+ { ixDIDT_DB_STALL_PATTERN_3_4, DIDT_DB_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_4_MASK, DIDT_DB_STALL_PATTERN_3_4__DIDT_STALL_PATTERN_4__SHIFT, 0x0001 },
+
+ /* DIDT_DB_STALL_PATTERN_5_6 */
+ { ixDIDT_DB_STALL_PATTERN_5_6, DIDT_DB_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_5_MASK, DIDT_DB_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_5__SHIFT, 0x0000 },
+ { ixDIDT_DB_STALL_PATTERN_5_6, DIDT_DB_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_6_MASK, DIDT_DB_STALL_PATTERN_5_6__DIDT_STALL_PATTERN_6__SHIFT, 0x0000 },
+
+ /* DIDT_DB_STALL_PATTERN_7 */
+ { ixDIDT_DB_STALL_PATTERN_7, DIDT_DB_STALL_PATTERN_7__DIDT_STALL_PATTERN_7_MASK, DIDT_DB_STALL_PATTERN_7__DIDT_STALL_PATTERN_7__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SELCacConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ */
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x00060021 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x00860021 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x01060021 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x01860021 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x02060021 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x02860021 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x03060021 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x03860021 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x04060021 },
+ /* TD */
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x000E0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x008E0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x010E0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x018E0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x020E0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x028E0020 },
+ /* TCP */
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x001c0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x009c0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x011c0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x019c0020 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x021c0020 },
+ /* DB */
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x00200008 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x00820008 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x01020008 },
+ { ixSE_CAC_CNTL, 0xFFFFFFFF, 0, 0x01820008 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+
+static const struct vega10_didt_config_reg SEEDCStallPatternConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ */
+ { ixDIDT_SQ_EDC_STALL_PATTERN_1_2, 0xFFFFFFFF, 0, 0x00030001 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_3_4, 0xFFFFFFFF, 0, 0x000F0007 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_5_6, 0xFFFFFFFF, 0, 0x003F001F },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_7, 0xFFFFFFFF, 0, 0x0000007F },
+ /* TD */
+ { ixDIDT_TD_EDC_STALL_PATTERN_1_2, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TD_EDC_STALL_PATTERN_3_4, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TD_EDC_STALL_PATTERN_5_6, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TD_EDC_STALL_PATTERN_7, 0xFFFFFFFF, 0, 0x00000000 },
+ /* TCP */
+ { ixDIDT_TCP_EDC_STALL_PATTERN_1_2, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TCP_EDC_STALL_PATTERN_3_4, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TCP_EDC_STALL_PATTERN_5_6, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TCP_EDC_STALL_PATTERN_7, 0xFFFFFFFF, 0, 0x00000000 },
+ /* DB */
+ { ixDIDT_DB_EDC_STALL_PATTERN_1_2, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_DB_EDC_STALL_PATTERN_3_4, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_DB_EDC_STALL_PATTERN_5_6, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_DB_EDC_STALL_PATTERN_7, 0xFFFFFFFF, 0, 0x00000000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEEDCForceStallPatternConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ */
+ { ixDIDT_SQ_EDC_STALL_PATTERN_1_2, 0xFFFFFFFF, 0, 0x00000015 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_3_4, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_5_6, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_7, 0xFFFFFFFF, 0, 0x00000000 },
+ /* TD */
+ { ixDIDT_TD_EDC_STALL_PATTERN_1_2, 0xFFFFFFFF, 0, 0x00000015 },
+ { ixDIDT_TD_EDC_STALL_PATTERN_3_4, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TD_EDC_STALL_PATTERN_5_6, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TD_EDC_STALL_PATTERN_7, 0xFFFFFFFF, 0, 0x00000000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEEDCStallDelayConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ */
+ { ixDIDT_SQ_EDC_STALL_DELAY_1, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_2, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_3, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_4, 0xFFFFFFFF, 0, 0x00000000 },
+ /* TD */
+ { ixDIDT_TD_EDC_STALL_DELAY_1, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TD_EDC_STALL_DELAY_2, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TD_EDC_STALL_DELAY_3, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TD_EDC_STALL_DELAY_4, 0xFFFFFFFF, 0, 0x00000000 },
+ /* TCP */
+ { ixDIDT_TCP_EDC_STALL_DELAY_1, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TCP_EDC_STALL_DELAY_2, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TCP_EDC_STALL_DELAY_3, 0xFFFFFFFF, 0, 0x00000000 },
+ { ixDIDT_TCP_EDC_STALL_DELAY_4, 0xFFFFFFFF, 0, 0x00000000 },
+ /* DB */
+ { ixDIDT_DB_EDC_STALL_DELAY_1, 0xFFFFFFFF, 0, 0x00000000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEEDCThresholdConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { ixDIDT_SQ_EDC_THRESHOLD, 0xFFFFFFFF, 0, 0x0000010E },
+ { ixDIDT_TD_EDC_THRESHOLD, 0xFFFFFFFF, 0, 0xFFFFFFFF },
+ { ixDIDT_TCP_EDC_THRESHOLD, 0xFFFFFFFF, 0, 0xFFFFFFFF },
+ { ixDIDT_DB_EDC_THRESHOLD, 0xFFFFFFFF, 0, 0xFFFFFFFF },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEEDCCtrlResetConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ */
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_EN_MASK, DIDT_SQ_EDC_CTRL__EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_SW_RST_MASK, DIDT_SQ_EDC_CTRL__EDC_SW_RST__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE_MASK, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL_MASK, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS_MASK, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA_MASK, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEEDCCtrlConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ */
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_EN_MASK, DIDT_SQ_EDC_CTRL__EDC_EN__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_SW_RST_MASK, DIDT_SQ_EDC_CTRL__EDC_SW_RST__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE_MASK, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL_MASK, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0004 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS_MASK, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS__SHIFT, 0x0006 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA_MASK, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg SEEDCCtrlForceStallConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ */
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_EN_MASK, DIDT_SQ_EDC_CTRL__EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_SW_RST_MASK, DIDT_SQ_EDC_CTRL__EDC_SW_RST__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE_MASK, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL_MASK, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS_MASK, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS__SHIFT, 0x000C },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA_MASK, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN__SHIFT, 0x0001 },
+
+ /* TD */
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__EDC_EN_MASK, DIDT_TD_EDC_CTRL__EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__EDC_SW_RST_MASK, DIDT_TD_EDC_CTRL__EDC_SW_RST__SHIFT, 0x0000 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__EDC_CLK_EN_OVERRIDE_MASK, DIDT_TD_EDC_CTRL__EDC_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__EDC_FORCE_STALL_MASK, DIDT_TD_EDC_CTRL__EDC_FORCE_STALL__SHIFT, 0x0001 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_TD_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0001 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS_MASK, DIDT_TD_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS__SHIFT, 0x000E },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA_MASK, DIDT_TD_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA__SHIFT, 0x0000 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__GC_EDC_EN_MASK, DIDT_TD_EDC_CTRL__GC_EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__GC_EDC_STALL_POLICY_MASK, DIDT_TD_EDC_CTRL__GC_EDC_STALL_POLICY__SHIFT, 0x0000 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__GC_EDC_LEVEL_COMB_EN_MASK, DIDT_TD_EDC_CTRL__GC_EDC_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_TD_EDC_CTRL, DIDT_TD_EDC_CTRL__SE_EDC_LEVEL_COMB_EN_MASK, DIDT_TD_EDC_CTRL__SE_EDC_LEVEL_COMB_EN__SHIFT, 0x0001 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg GCDiDtDroopCtrlConfig_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { mmGC_DIDT_DROOP_CTRL, GC_DIDT_DROOP_CTRL__DIDT_DROOP_LEVEL_EN_MASK, GC_DIDT_DROOP_CTRL__DIDT_DROOP_LEVEL_EN__SHIFT, 0x0000 },
+ { mmGC_DIDT_DROOP_CTRL, GC_DIDT_DROOP_CTRL__DIDT_DROOP_THRESHOLD_MASK, GC_DIDT_DROOP_CTRL__DIDT_DROOP_THRESHOLD__SHIFT, 0x0000 },
+ { mmGC_DIDT_DROOP_CTRL, GC_DIDT_DROOP_CTRL__DIDT_DROOP_LEVEL_INDEX_MASK, GC_DIDT_DROOP_CTRL__DIDT_DROOP_LEVEL_INDEX__SHIFT, 0x0000 },
+ { mmGC_DIDT_DROOP_CTRL, GC_DIDT_DROOP_CTRL__DIDT_LEVEL_SEL_MASK, GC_DIDT_DROOP_CTRL__DIDT_LEVEL_SEL__SHIFT, 0x0000 },
+ { mmGC_DIDT_DROOP_CTRL, GC_DIDT_DROOP_CTRL__DIDT_DROOP_LEVEL_OVERFLOW_MASK, GC_DIDT_DROOP_CTRL__DIDT_DROOP_LEVEL_OVERFLOW__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg GCDiDtCtrl0Config_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { mmGC_DIDT_CTRL0, GC_DIDT_CTRL0__DIDT_CTRL_EN_MASK, GC_DIDT_CTRL0__DIDT_CTRL_EN__SHIFT, 0x0000 },
+ { mmGC_DIDT_CTRL0, GC_DIDT_CTRL0__PHASE_OFFSET_MASK, GC_DIDT_CTRL0__PHASE_OFFSET__SHIFT, 0x0000 },
+ { mmGC_DIDT_CTRL0, GC_DIDT_CTRL0__DIDT_SW_RST_MASK, GC_DIDT_CTRL0__DIDT_SW_RST__SHIFT, 0x0000 },
+ { mmGC_DIDT_CTRL0, GC_DIDT_CTRL0__DIDT_CLK_EN_OVERRIDE_MASK, GC_DIDT_CTRL0__DIDT_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { mmGC_DIDT_CTRL0, GC_DIDT_CTRL0__DIDT_TRIGGER_THROTTLE_LOWBIT_MASK, GC_DIDT_CTRL0__DIDT_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { 0xFFFFFFFF } /* End of list */
+};
+
+
+static const struct vega10_didt_config_reg PSMSEEDCStallPatternConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ EDC STALL PATTERNs */
+ { ixDIDT_SQ_EDC_STALL_PATTERN_1_2, DIDT_SQ_EDC_STALL_PATTERN_1_2__EDC_STALL_PATTERN_1_MASK, DIDT_SQ_EDC_STALL_PATTERN_1_2__EDC_STALL_PATTERN_1__SHIFT, 0x0101 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_1_2, DIDT_SQ_EDC_STALL_PATTERN_1_2__EDC_STALL_PATTERN_2_MASK, DIDT_SQ_EDC_STALL_PATTERN_1_2__EDC_STALL_PATTERN_2__SHIFT, 0x0101 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_3_4, DIDT_SQ_EDC_STALL_PATTERN_3_4__EDC_STALL_PATTERN_3_MASK, DIDT_SQ_EDC_STALL_PATTERN_3_4__EDC_STALL_PATTERN_3__SHIFT, 0x1111 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_3_4, DIDT_SQ_EDC_STALL_PATTERN_3_4__EDC_STALL_PATTERN_4_MASK, DIDT_SQ_EDC_STALL_PATTERN_3_4__EDC_STALL_PATTERN_4__SHIFT, 0x1111 },
+
+ { ixDIDT_SQ_EDC_STALL_PATTERN_5_6, DIDT_SQ_EDC_STALL_PATTERN_5_6__EDC_STALL_PATTERN_5_MASK, DIDT_SQ_EDC_STALL_PATTERN_5_6__EDC_STALL_PATTERN_5__SHIFT, 0x1515 },
+ { ixDIDT_SQ_EDC_STALL_PATTERN_5_6, DIDT_SQ_EDC_STALL_PATTERN_5_6__EDC_STALL_PATTERN_6_MASK, DIDT_SQ_EDC_STALL_PATTERN_5_6__EDC_STALL_PATTERN_6__SHIFT, 0x1515 },
+
+ { ixDIDT_SQ_EDC_STALL_PATTERN_7, DIDT_SQ_EDC_STALL_PATTERN_7__EDC_STALL_PATTERN_7_MASK, DIDT_SQ_EDC_STALL_PATTERN_7__EDC_STALL_PATTERN_7__SHIFT, 0x5555 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg PSMSEEDCStallDelayConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ EDC STALL DELAYs */
+ { ixDIDT_SQ_EDC_STALL_DELAY_1, DIDT_SQ_EDC_STALL_DELAY_1__EDC_STALL_DELAY_SQ0_MASK, DIDT_SQ_EDC_STALL_DELAY_1__EDC_STALL_DELAY_SQ0__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_1, DIDT_SQ_EDC_STALL_DELAY_1__EDC_STALL_DELAY_SQ1_MASK, DIDT_SQ_EDC_STALL_DELAY_1__EDC_STALL_DELAY_SQ1__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_1, DIDT_SQ_EDC_STALL_DELAY_1__EDC_STALL_DELAY_SQ2_MASK, DIDT_SQ_EDC_STALL_DELAY_1__EDC_STALL_DELAY_SQ2__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_1, DIDT_SQ_EDC_STALL_DELAY_1__EDC_STALL_DELAY_SQ3_MASK, DIDT_SQ_EDC_STALL_DELAY_1__EDC_STALL_DELAY_SQ3__SHIFT, 0x0000 },
+
+ { ixDIDT_SQ_EDC_STALL_DELAY_2, DIDT_SQ_EDC_STALL_DELAY_2__EDC_STALL_DELAY_SQ4_MASK, DIDT_SQ_EDC_STALL_DELAY_2__EDC_STALL_DELAY_SQ4__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_2, DIDT_SQ_EDC_STALL_DELAY_2__EDC_STALL_DELAY_SQ5_MASK, DIDT_SQ_EDC_STALL_DELAY_2__EDC_STALL_DELAY_SQ5__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_2, DIDT_SQ_EDC_STALL_DELAY_2__EDC_STALL_DELAY_SQ6_MASK, DIDT_SQ_EDC_STALL_DELAY_2__EDC_STALL_DELAY_SQ6__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_2, DIDT_SQ_EDC_STALL_DELAY_2__EDC_STALL_DELAY_SQ7_MASK, DIDT_SQ_EDC_STALL_DELAY_2__EDC_STALL_DELAY_SQ7__SHIFT, 0x0000 },
+
+ { ixDIDT_SQ_EDC_STALL_DELAY_3, DIDT_SQ_EDC_STALL_DELAY_3__EDC_STALL_DELAY_SQ8_MASK, DIDT_SQ_EDC_STALL_DELAY_3__EDC_STALL_DELAY_SQ8__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_3, DIDT_SQ_EDC_STALL_DELAY_3__EDC_STALL_DELAY_SQ9_MASK, DIDT_SQ_EDC_STALL_DELAY_3__EDC_STALL_DELAY_SQ9__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_3, DIDT_SQ_EDC_STALL_DELAY_3__EDC_STALL_DELAY_SQ10_MASK, DIDT_SQ_EDC_STALL_DELAY_3__EDC_STALL_DELAY_SQ10__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_3, DIDT_SQ_EDC_STALL_DELAY_3__EDC_STALL_DELAY_SQ11_MASK, DIDT_SQ_EDC_STALL_DELAY_3__EDC_STALL_DELAY_SQ11__SHIFT, 0x0000 },
+
+ { ixDIDT_SQ_EDC_STALL_DELAY_4, DIDT_SQ_EDC_STALL_DELAY_4__EDC_STALL_DELAY_SQ12_MASK, DIDT_SQ_EDC_STALL_DELAY_4__EDC_STALL_DELAY_SQ12__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_4, DIDT_SQ_EDC_STALL_DELAY_4__EDC_STALL_DELAY_SQ12_MASK, DIDT_SQ_EDC_STALL_DELAY_4__EDC_STALL_DELAY_SQ13__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_4, DIDT_SQ_EDC_STALL_DELAY_4__EDC_STALL_DELAY_SQ14_MASK, DIDT_SQ_EDC_STALL_DELAY_4__EDC_STALL_DELAY_SQ14__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_STALL_DELAY_4, DIDT_SQ_EDC_STALL_DELAY_4__EDC_STALL_DELAY_SQ15_MASK, DIDT_SQ_EDC_STALL_DELAY_4__EDC_STALL_DELAY_SQ15__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg PSMSEEDCThresholdConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ EDC THRESHOLD */
+ { ixDIDT_SQ_EDC_THRESHOLD, DIDT_SQ_EDC_THRESHOLD__EDC_THRESHOLD_MASK, DIDT_SQ_EDC_THRESHOLD__EDC_THRESHOLD__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg PSMSEEDCCtrlResetConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ EDC CTRL */
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_EN_MASK, DIDT_SQ_EDC_CTRL__EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_SW_RST_MASK, DIDT_SQ_EDC_CTRL__EDC_SW_RST__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE_MASK, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL_MASK, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS_MASK, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA_MASK, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg PSMSEEDCCtrlConfig_Vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ /* SQ EDC CTRL */
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_EN_MASK, DIDT_SQ_EDC_CTRL__EDC_EN__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_SW_RST_MASK, DIDT_SQ_EDC_CTRL__EDC_SW_RST__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE_MASK, DIDT_SQ_EDC_CTRL__EDC_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL_MASK, DIDT_SQ_EDC_CTRL__EDC_FORCE_STALL__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT_MASK, DIDT_SQ_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS_MASK, DIDT_SQ_EDC_CTRL__EDC_STALL_PATTERN_BIT_NUMS__SHIFT, 0x000E },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA_MASK, DIDT_SQ_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA__SHIFT, 0x0000 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_EN__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_STALL_POLICY__SHIFT, 0x0003 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__GC_EDC_LEVEL_COMB_EN__SHIFT, 0x0001 },
+ { ixDIDT_SQ_EDC_CTRL, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN_MASK, DIDT_SQ_EDC_CTRL__SE_EDC_LEVEL_COMB_EN__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg PSMGCEDCThresholdConfig_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { mmGC_EDC_THRESHOLD, GC_EDC_THRESHOLD__EDC_THRESHOLD_MASK, GC_EDC_THRESHOLD__EDC_THRESHOLD__SHIFT, 0x0000000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg PSMGCEDCDroopCtrlConfig_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { mmGC_EDC_DROOP_CTRL, GC_EDC_DROOP_CTRL__EDC_DROOP_LEVEL_EN_MASK, GC_EDC_DROOP_CTRL__EDC_DROOP_LEVEL_EN__SHIFT, 0x0001 },
+ { mmGC_EDC_DROOP_CTRL, GC_EDC_DROOP_CTRL__EDC_DROOP_THRESHOLD_MASK, GC_EDC_DROOP_CTRL__EDC_DROOP_THRESHOLD__SHIFT, 0x0384 },
+ { mmGC_EDC_DROOP_CTRL, GC_EDC_DROOP_CTRL__EDC_DROOP_LEVEL_INDEX_MASK, GC_EDC_DROOP_CTRL__EDC_DROOP_LEVEL_INDEX__SHIFT, 0x0001 },
+ { mmGC_EDC_DROOP_CTRL, GC_EDC_DROOP_CTRL__AVG_PSM_SEL_MASK, GC_EDC_DROOP_CTRL__AVG_PSM_SEL__SHIFT, 0x0001 },
+ { mmGC_EDC_DROOP_CTRL, GC_EDC_DROOP_CTRL__EDC_LEVEL_SEL_MASK, GC_EDC_DROOP_CTRL__EDC_LEVEL_SEL__SHIFT, 0x0001 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg PSMGCEDCCtrlResetConfig_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_EN_MASK, GC_EDC_CTRL__EDC_EN__SHIFT, 0x0000 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_SW_RST_MASK, GC_EDC_CTRL__EDC_SW_RST__SHIFT, 0x0001 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_CLK_EN_OVERRIDE_MASK, GC_EDC_CTRL__EDC_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_FORCE_STALL_MASK, GC_EDC_CTRL__EDC_FORCE_STALL__SHIFT, 0x0000 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT_MASK, GC_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA_MASK, GC_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg PSMGCEDCCtrlConfig_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_EN_MASK, GC_EDC_CTRL__EDC_EN__SHIFT, 0x0001 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_SW_RST_MASK, GC_EDC_CTRL__EDC_SW_RST__SHIFT, 0x0000 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_CLK_EN_OVERRIDE_MASK, GC_EDC_CTRL__EDC_CLK_EN_OVERRIDE__SHIFT, 0x0000 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_FORCE_STALL_MASK, GC_EDC_CTRL__EDC_FORCE_STALL__SHIFT, 0x0000 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT_MASK, GC_EDC_CTRL__EDC_TRIGGER_THROTTLE_LOWBIT__SHIFT, 0x0000 },
+ { mmGC_EDC_CTRL, GC_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA_MASK, GC_EDC_CTRL__EDC_ALLOW_WRITE_PWRDELTA__SHIFT, 0x0000 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg AvfsPSMResetConfig_vega10[]=
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { 0x16A02, 0xFFFFFFFF, 0x0, 0x0000005F },
+ { 0x16A05, 0xFFFFFFFF, 0x0, 0x00000001 },
+ { 0x16A06, 0x00000001, 0x0, 0x02000000 },
+ { 0x16A01, 0xFFFFFFFF, 0x0, 0x00003027 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static const struct vega10_didt_config_reg AvfsPSMInitConfig_vega10[] =
+{
+/* ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Offset Mask Shift Value
+ * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+ { 0x16A05, 0xFFFFFFFF, 0x18, 0x00000001 },
+ { 0x16A05, 0xFFFFFFFF, 0x8, 0x00000003 },
+ { 0x16A05, 0xFFFFFFFF, 0xa, 0x00000006 },
+ { 0x16A05, 0xFFFFFFFF, 0x7, 0x00000000 },
+ { 0x16A06, 0xFFFFFFFF, 0x18, 0x00000001 },
+ { 0x16A06, 0xFFFFFFFF, 0x19, 0x00000001 },
+ { 0x16A01, 0xFFFFFFFF, 0x0, 0x00003027 },
+
+ { 0xFFFFFFFF } /* End of list */
+};
+
+static int vega10_program_didt_config_registers(struct pp_hwmgr *hwmgr, const struct vega10_didt_config_reg *config_regs, enum vega10_didt_config_reg_type reg_type)
+{
+ uint32_t data;
+
+ PP_ASSERT_WITH_CODE((config_regs != NULL), "[vega10_program_didt_config_registers] Invalid config register table!", return -EINVAL);
+
+ while (config_regs->offset != 0xFFFFFFFF) {
+ switch (reg_type) {
+ case VEGA10_CONFIGREG_DIDT:
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, config_regs->offset);
+ data &= ~config_regs->mask;
+ data |= ((config_regs->value << config_regs->shift) & config_regs->mask);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, config_regs->offset, data);
+ break;
+ case VEGA10_CONFIGREG_GCCAC:
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG_GC_CAC, config_regs->offset);
+ data &= ~config_regs->mask;
+ data |= ((config_regs->value << config_regs->shift) & config_regs->mask);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG_GC_CAC, config_regs->offset, data);
+ break;
+ case VEGA10_CONFIGREG_SECAC:
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG_SE_CAC, config_regs->offset);
+ data &= ~config_regs->mask;
+ data |= ((config_regs->value << config_regs->shift) & config_regs->mask);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG_SE_CAC, config_regs->offset, data);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ config_regs++;
+ }
+
+ return 0;
+}
+
+static int vega10_program_gc_didt_config_registers(struct pp_hwmgr *hwmgr, const struct vega10_didt_config_reg *config_regs)
+{
+ uint32_t data;
+
+ while (config_regs->offset != 0xFFFFFFFF) {
+ data = cgs_read_register(hwmgr->device, config_regs->offset);
+ data &= ~config_regs->mask;
+ data |= ((config_regs->value << config_regs->shift) & config_regs->mask);
+ cgs_write_register(hwmgr->device, config_regs->offset, data);
+ config_regs++;
+ }
+
+ return 0;
+}
+
+static void vega10_didt_set_mask(struct pp_hwmgr *hwmgr, const bool enable)
+{
+ uint32_t data;
+ int result;
+ uint32_t en = (enable ? 1 : 0);
+ uint32_t didt_block_info = SQ_IR_MASK | TCP_IR_MASK | TD_PCC_MASK;
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SQRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_SQ_CTRL0);
+ data &= ~DIDT_SQ_CTRL0__DIDT_CTRL_EN_MASK;
+ data |= ((en << DIDT_SQ_CTRL0__DIDT_CTRL_EN__SHIFT) & DIDT_SQ_CTRL0__DIDT_CTRL_EN_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_SQ_CTRL0, data);
+ didt_block_info &= ~SQ_Enable_MASK;
+ didt_block_info |= en << SQ_Enable_SHIFT;
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DBRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DB_CTRL0);
+ data &= ~DIDT_DB_CTRL0__DIDT_CTRL_EN_MASK;
+ data |= ((en << DIDT_DB_CTRL0__DIDT_CTRL_EN__SHIFT) & DIDT_DB_CTRL0__DIDT_CTRL_EN_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DB_CTRL0, data);
+ didt_block_info &= ~DB_Enable_MASK;
+ didt_block_info |= en << DB_Enable_SHIFT;
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_TDRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TD_CTRL0);
+ data &= ~DIDT_TD_CTRL0__DIDT_CTRL_EN_MASK;
+ data |= ((en << DIDT_TD_CTRL0__DIDT_CTRL_EN__SHIFT) & DIDT_TD_CTRL0__DIDT_CTRL_EN_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TD_CTRL0, data);
+ didt_block_info &= ~TD_Enable_MASK;
+ didt_block_info |= en << TD_Enable_SHIFT;
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_TCPRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TCP_CTRL0);
+ data &= ~DIDT_TCP_CTRL0__DIDT_CTRL_EN_MASK;
+ data |= ((en << DIDT_TCP_CTRL0__DIDT_CTRL_EN__SHIFT) & DIDT_TCP_CTRL0__DIDT_CTRL_EN_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TCP_CTRL0, data);
+ didt_block_info &= ~TCP_Enable_MASK;
+ didt_block_info |= en << TCP_Enable_SHIFT;
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DBRRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DBR_CTRL0);
+ data &= ~DIDT_DBR_CTRL0__DIDT_CTRL_EN_MASK;
+ data |= ((en << DIDT_DBR_CTRL0__DIDT_CTRL_EN__SHIFT) & DIDT_DBR_CTRL0__DIDT_CTRL_EN_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DBR_CTRL0, data);
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DiDtEDCEnable)) {
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SQRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_SQ_EDC_CTRL);
+ data &= ~DIDT_SQ_EDC_CTRL__EDC_EN_MASK;
+ data |= ((en << DIDT_SQ_EDC_CTRL__EDC_EN__SHIFT) & DIDT_SQ_EDC_CTRL__EDC_EN_MASK);
+ data &= ~DIDT_SQ_EDC_CTRL__EDC_SW_RST_MASK;
+ data |= ((~en << DIDT_SQ_EDC_CTRL__EDC_SW_RST__SHIFT) & DIDT_SQ_EDC_CTRL__EDC_SW_RST_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_SQ_EDC_CTRL, data);
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DBRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DB_EDC_CTRL);
+ data &= ~DIDT_DB_EDC_CTRL__EDC_EN_MASK;
+ data |= ((en << DIDT_DB_EDC_CTRL__EDC_EN__SHIFT) & DIDT_DB_EDC_CTRL__EDC_EN_MASK);
+ data &= ~DIDT_DB_EDC_CTRL__EDC_SW_RST_MASK;
+ data |= ((~en << DIDT_DB_EDC_CTRL__EDC_SW_RST__SHIFT) & DIDT_DB_EDC_CTRL__EDC_SW_RST_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DB_EDC_CTRL, data);
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_TDRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TD_EDC_CTRL);
+ data &= ~DIDT_TD_EDC_CTRL__EDC_EN_MASK;
+ data |= ((en << DIDT_TD_EDC_CTRL__EDC_EN__SHIFT) & DIDT_TD_EDC_CTRL__EDC_EN_MASK);
+ data &= ~DIDT_TD_EDC_CTRL__EDC_SW_RST_MASK;
+ data |= ((~en << DIDT_TD_EDC_CTRL__EDC_SW_RST__SHIFT) & DIDT_TD_EDC_CTRL__EDC_SW_RST_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TD_EDC_CTRL, data);
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_TCPRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TCP_EDC_CTRL);
+ data &= ~DIDT_TCP_EDC_CTRL__EDC_EN_MASK;
+ data |= ((en << DIDT_TCP_EDC_CTRL__EDC_EN__SHIFT) & DIDT_TCP_EDC_CTRL__EDC_EN_MASK);
+ data &= ~DIDT_TCP_EDC_CTRL__EDC_SW_RST_MASK;
+ data |= ((~en << DIDT_TCP_EDC_CTRL__EDC_SW_RST__SHIFT) & DIDT_TCP_EDC_CTRL__EDC_SW_RST_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_TCP_EDC_CTRL, data);
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DBRRamping)) {
+ data = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DBR_EDC_CTRL);
+ data &= ~DIDT_DBR_EDC_CTRL__EDC_EN_MASK;
+ data |= ((en << DIDT_DBR_EDC_CTRL__EDC_EN__SHIFT) & DIDT_DBR_EDC_CTRL__EDC_EN_MASK);
+ data &= ~DIDT_DBR_EDC_CTRL__EDC_SW_RST_MASK;
+ data |= ((~en << DIDT_DBR_EDC_CTRL__EDC_SW_RST__SHIFT) & DIDT_DBR_EDC_CTRL__EDC_SW_RST_MASK);
+ cgs_write_ind_register(hwmgr->device, CGS_IND_REG__DIDT, ixDIDT_DBR_EDC_CTRL, data);
+ }
+ }
+
+ if (enable) {
+ /* For Vega10, SMC does not support any mask yet. */
+ result = smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, PPSMC_MSG_ConfigureGfxDidt, didt_block_info);
+ PP_ASSERT((0 == result), "[EnableDiDtConfig] SMC Configure Gfx Didt Failed!");
+ }
+}
+
+static int vega10_enable_cac_driving_se_didt_config(struct pp_hwmgr *hwmgr)
+{
+ int result;
+ uint32_t num_se = 0, count, data;
+ struct cgs_system_info sys_info = {0};
+ uint32_t reg;
+
+ sys_info.size = sizeof(struct cgs_system_info);
+ sys_info.info_id = CGS_SYSTEM_INFO_GFX_SE_INFO;
+ if (cgs_query_system_info(hwmgr->device, &sys_info) == 0)
+ num_se = sys_info.value;
+
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ cgs_lock_grbm_idx(hwmgr->device, true);
+ reg = soc15_get_register_offset(GC_HWID, 0, mmGRBM_GFX_INDEX_BASE_IDX, mmGRBM_GFX_INDEX);
+ for (count = 0; count < num_se; count++) {
+ data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT);
+ cgs_write_register(hwmgr->device, reg, data);
+
+ result = vega10_program_didt_config_registers(hwmgr, SEDiDtStallCtrlConfig_vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtStallPatternConfig_vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtWeightConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtCtrl1Config_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtCtrl2Config_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtCtrl3Config_vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtTuningCtrlConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SELCacConfig_Vega10, VEGA10_CONFIGREG_SECAC);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtCtrl0Config_Vega10, VEGA10_CONFIGREG_DIDT);
+
+ if (0 != result)
+ break;
+ }
+ cgs_write_register(hwmgr->device, reg, 0xE0000000);
+ cgs_lock_grbm_idx(hwmgr->device, false);
+
+ vega10_didt_set_mask(hwmgr, true);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ return 0;
+}
+
+static int vega10_disable_cac_driving_se_didt_config(struct pp_hwmgr *hwmgr)
+{
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ vega10_didt_set_mask(hwmgr, false);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ return 0;
+}
+
+static int vega10_enable_psm_gc_didt_config(struct pp_hwmgr *hwmgr)
+{
+ int result;
+ uint32_t num_se = 0, count, data;
+ struct cgs_system_info sys_info = {0};
+ uint32_t reg;
+
+ sys_info.size = sizeof(struct cgs_system_info);
+ sys_info.info_id = CGS_SYSTEM_INFO_GFX_SE_INFO;
+ if (cgs_query_system_info(hwmgr->device, &sys_info) == 0)
+ num_se = sys_info.value;
+
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ cgs_lock_grbm_idx(hwmgr->device, true);
+ reg = soc15_get_register_offset(GC_HWID, 0, mmGRBM_GFX_INDEX_BASE_IDX, mmGRBM_GFX_INDEX);
+ for (count = 0; count < num_se; count++) {
+ data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT);
+ cgs_write_register(hwmgr->device, reg, data);
+
+ result = vega10_program_didt_config_registers(hwmgr, SEDiDtStallCtrlConfig_vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtStallPatternConfig_vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtCtrl3Config_vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEDiDtCtrl0Config_Vega10, VEGA10_CONFIGREG_DIDT);
+ if (0 != result)
+ break;
+ }
+ cgs_write_register(hwmgr->device, reg, 0xE0000000);
+ cgs_lock_grbm_idx(hwmgr->device, false);
+
+ vega10_didt_set_mask(hwmgr, true);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ vega10_program_gc_didt_config_registers(hwmgr, GCDiDtDroopCtrlConfig_vega10);
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_GCEDC))
+ vega10_program_gc_didt_config_registers(hwmgr, GCDiDtCtrl0Config_vega10);
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PSM))
+ vega10_program_gc_didt_config_registers(hwmgr, AvfsPSMInitConfig_vega10);
+
+ return 0;
+}
+
+static int vega10_disable_psm_gc_didt_config(struct pp_hwmgr *hwmgr)
+{
+ uint32_t data;
+
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ vega10_didt_set_mask(hwmgr, false);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_GCEDC)) {
+ data = 0x00000000;
+ cgs_write_register(hwmgr->device, mmGC_DIDT_CTRL0, data);
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PSM))
+ vega10_program_gc_didt_config_registers(hwmgr, AvfsPSMResetConfig_vega10);
+
+ return 0;
+}
+
+static int vega10_enable_se_edc_config(struct pp_hwmgr *hwmgr)
+{
+ int result;
+ uint32_t num_se = 0, count, data;
+ struct cgs_system_info sys_info = {0};
+ uint32_t reg;
+
+ sys_info.size = sizeof(struct cgs_system_info);
+ sys_info.info_id = CGS_SYSTEM_INFO_GFX_SE_INFO;
+ if (cgs_query_system_info(hwmgr->device, &sys_info) == 0)
+ num_se = sys_info.value;
+
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ cgs_lock_grbm_idx(hwmgr->device, true);
+ reg = soc15_get_register_offset(GC_HWID, 0, mmGRBM_GFX_INDEX_BASE_IDX, mmGRBM_GFX_INDEX);
+ for (count = 0; count < num_se; count++) {
+ data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT);
+ cgs_write_register(hwmgr->device, reg, data);
+ result = vega10_program_didt_config_registers(hwmgr, SEDiDtWeightConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEEDCStallPatternConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEEDCStallDelayConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEEDCThresholdConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEEDCCtrlResetConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEEDCCtrlConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+
+ if (0 != result)
+ break;
+ }
+ cgs_write_register(hwmgr->device, reg, 0xE0000000);
+ cgs_lock_grbm_idx(hwmgr->device, false);
+
+ vega10_didt_set_mask(hwmgr, true);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ return 0;
+}
+
+static int vega10_disable_se_edc_config(struct pp_hwmgr *hwmgr)
+{
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ vega10_didt_set_mask(hwmgr, false);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ return 0;
+}
+
+static int vega10_enable_psm_gc_edc_config(struct pp_hwmgr *hwmgr)
+{
+ int result;
+ uint32_t num_se = 0;
+ uint32_t count, data;
+ struct cgs_system_info sys_info = {0};
+ uint32_t reg;
+
+ sys_info.size = sizeof(struct cgs_system_info);
+ sys_info.info_id = CGS_SYSTEM_INFO_GFX_SE_INFO;
+ if (cgs_query_system_info(hwmgr->device, &sys_info) == 0)
+ num_se = sys_info.value;
+
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ vega10_program_gc_didt_config_registers(hwmgr, AvfsPSMResetConfig_vega10);
+
+ cgs_lock_grbm_idx(hwmgr->device, true);
+ reg = soc15_get_register_offset(GC_HWID, 0, mmGRBM_GFX_INDEX_BASE_IDX, mmGRBM_GFX_INDEX);
+ for (count = 0; count < num_se; count++) {
+ data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT);
+ cgs_write_register(hwmgr->device, reg, data);
+ result |= vega10_program_didt_config_registers(hwmgr, PSMSEEDCStallPatternConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, PSMSEEDCStallDelayConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, PSMSEEDCCtrlResetConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, PSMSEEDCCtrlConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+
+ if (0 != result)
+ break;
+ }
+ cgs_write_register(hwmgr->device, reg, 0xE0000000);
+ cgs_lock_grbm_idx(hwmgr->device, false);
+
+ vega10_didt_set_mask(hwmgr, true);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ vega10_program_gc_didt_config_registers(hwmgr, PSMGCEDCDroopCtrlConfig_vega10);
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_GCEDC)) {
+ vega10_program_gc_didt_config_registers(hwmgr, PSMGCEDCCtrlResetConfig_vega10);
+ vega10_program_gc_didt_config_registers(hwmgr, PSMGCEDCCtrlConfig_vega10);
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PSM))
+ vega10_program_gc_didt_config_registers(hwmgr, AvfsPSMInitConfig_vega10);
+
+ return 0;
+}
+
+static int vega10_disable_psm_gc_edc_config(struct pp_hwmgr *hwmgr)
+{
+ uint32_t data;
+
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ vega10_didt_set_mask(hwmgr, false);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_GCEDC)) {
+ data = 0x00000000;
+ cgs_write_register(hwmgr->device, mmGC_EDC_CTRL, data);
+ }
+
+ if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PSM))
+ vega10_program_gc_didt_config_registers(hwmgr, AvfsPSMResetConfig_vega10);
+
+ return 0;
+}
+
+static int vega10_enable_se_edc_force_stall_config(struct pp_hwmgr *hwmgr)
+{
+ uint32_t reg;
+ int result;
+
+ cgs_enter_safe_mode(hwmgr->device, true);
+
+ cgs_lock_grbm_idx(hwmgr->device, true);
+ reg = soc15_get_register_offset(GC_HWID, 0, mmGRBM_GFX_INDEX_BASE_IDX, mmGRBM_GFX_INDEX);
+ cgs_write_register(hwmgr->device, reg, 0xE0000000);
+ cgs_lock_grbm_idx(hwmgr->device, false);
+
+ result = vega10_program_didt_config_registers(hwmgr, SEEDCForceStallPatternConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ result |= vega10_program_didt_config_registers(hwmgr, SEEDCCtrlForceStallConfig_Vega10, VEGA10_CONFIGREG_DIDT);
+ if (0 != result)
+ return result;
+
+ vega10_didt_set_mask(hwmgr, false);
+
+ cgs_enter_safe_mode(hwmgr->device, false);
+
+ return 0;
+}
+
+static int vega10_disable_se_edc_force_stall_config(struct pp_hwmgr *hwmgr)
+{
+ int result;
+
+ result = vega10_disable_se_edc_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[DisableDiDtConfig] Pre DIDT disable clock gating failed!", return result);
+
+ return 0;
+}
+
+int vega10_enable_didt_config(struct pp_hwmgr *hwmgr)
+{
+ int result = 0;
+ struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
+
+ if (data->smu_features[GNLD_DIDT].supported) {
+ if (data->smu_features[GNLD_DIDT].enabled)
+ PP_DBG_LOG("[EnableDiDtConfig] Feature DiDt Already enabled!\n");
+
+ switch (data->registry_data.didt_mode) {
+ case 0:
+ result = vega10_enable_cac_driving_se_didt_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[EnableDiDt] Attempt to enable DiDt Mode 0 Failed!", return result);
+ break;
+ case 2:
+ result = vega10_enable_psm_gc_didt_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[EnableDiDt] Attempt to enable DiDt Mode 2 Failed!", return result);
+ break;
+ case 3:
+ result = vega10_enable_se_edc_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[EnableDiDt] Attempt to enable DiDt Mode 3 Failed!", return result);
+ break;
+ case 1:
+ case 4:
+ case 5:
+ result = vega10_enable_psm_gc_edc_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[EnableDiDt] Attempt to enable DiDt Mode 5 Failed!", return result);
+ break;
+ case 6:
+ result = vega10_enable_se_edc_force_stall_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[EnableDiDt] Attempt to enable DiDt Mode 6 Failed!", return result);
+ break;
+ default:
+ result = -EINVAL;
+ break;
+ }
+
+ if (0 == result) {
+ PP_ASSERT_WITH_CODE((!vega10_enable_smc_features(hwmgr->smumgr, true, data->smu_features[GNLD_DIDT].smu_feature_bitmap)),
+ "[EnableDiDtConfig] Attempt to Enable DiDt feature Failed!", return result);
+ data->smu_features[GNLD_DIDT].enabled = true;
+ }
+ }
+
+ return result;
+}
+
+int vega10_disable_didt_config(struct pp_hwmgr *hwmgr)
+{
+ int result = 0;
+ struct vega10_hwmgr *data = (struct vega10_hwmgr *)(hwmgr->backend);
+
+ if (data->smu_features[GNLD_DIDT].supported) {
+ if (!data->smu_features[GNLD_DIDT].enabled)
+ PP_DBG_LOG("[DisableDiDtConfig] Feature DiDt Already Disabled!\n");
+
+ switch (data->registry_data.didt_mode) {
+ case 0:
+ result = vega10_disable_cac_driving_se_didt_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[DisableDiDt] Attempt to disable DiDt Mode 0 Failed!", return result);
+ break;
+ case 2:
+ result = vega10_disable_psm_gc_didt_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[DisableDiDt] Attempt to disable DiDt Mode 2 Failed!", return result);
+ break;
+ case 3:
+ result = vega10_disable_se_edc_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[DisableDiDt] Attempt to disable DiDt Mode 3 Failed!", return result);
+ break;
+ case 1:
+ case 4:
+ case 5:
+ result = vega10_disable_psm_gc_edc_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[DisableDiDt] Attempt to disable DiDt Mode 5 Failed!", return result);
+ break;
+ case 6:
+ result = vega10_disable_se_edc_force_stall_config(hwmgr);
+ PP_ASSERT_WITH_CODE((0 == result), "[DisableDiDt] Attempt to disable DiDt Mode 6 Failed!", return result);
+ break;
+ default:
+ result = -EINVAL;
+ break;
+ }
+
+ if (0 == result) {
+ PP_ASSERT_WITH_CODE((0 != vega10_enable_smc_features(hwmgr->smumgr, false, data->smu_features[GNLD_DIDT].smu_feature_bitmap)),
+ "[DisableDiDtConfig] Attempt to Disable DiDt feature Failed!", return result);
+ data->smu_features[GNLD_DIDT].enabled = false;
+ }
+ }
+
+ return result;
+}
void vega10_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr)
{
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.h
index 9ecaa27c0bb5..b95771ab89cd 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.h
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_powertune.h
@@ -31,6 +31,12 @@ enum vega10_pt_config_reg_type {
VEGA10_CONFIGREG_MAX
};
+enum vega10_didt_config_reg_type {
+ VEGA10_CONFIGREG_DIDT = 0,
+ VEGA10_CONFIGREG_GCCAC,
+ VEGA10_CONFIGREG_SECAC
+};
+
/* PowerContainment Features */
#define POWERCONTAINMENT_FEATURE_DTE 0x00000001
#define POWERCONTAINMENT_FEATURE_TDCLimit 0x00000002
@@ -44,6 +50,13 @@ struct vega10_pt_config_reg {
enum vega10_pt_config_reg_type type;
};
+struct vega10_didt_config_reg {
+ uint32_t offset;
+ uint32_t mask;
+ uint32_t shift;
+ uint32_t value;
+};
+
struct vega10_pt_defaults {
uint8_t SviLoadLineEn;
uint8_t SviLoadLineVddC;
@@ -62,5 +75,8 @@ int vega10_set_power_limit(struct pp_hwmgr *hwmgr, uint32_t n);
int vega10_power_control_set_level(struct pp_hwmgr *hwmgr);
int vega10_disable_power_containment(struct pp_hwmgr *hwmgr);
+int vega10_enable_didt_config(struct pp_hwmgr *hwmgr);
+int vega10_disable_didt_config(struct pp_hwmgr *hwmgr);
+
#endif /* _VEGA10_POWERTUNE_H_ */
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c
index 1623644ea49a..e343df190375 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_processpptables.c
@@ -31,6 +31,8 @@
#include "cgs_common.h"
#include "vega10_pptable.h"
+#define NUM_DSPCLK_LEVELS 8
+
static void set_hw_cap(struct pp_hwmgr *hwmgr, bool enable,
enum phm_platform_caps cap)
{
@@ -644,11 +646,11 @@ static int get_gfxclk_voltage_dependency_table(
return 0;
}
-static int get_dcefclk_voltage_dependency_table(
+static int get_pix_clk_voltage_dependency_table(
struct pp_hwmgr *hwmgr,
struct phm_ppt_v1_clock_voltage_dependency_table
**pp_vega10_clk_dep_table,
- const ATOM_Vega10_DCEFCLK_Dependency_Table *clk_dep_table)
+ const ATOM_Vega10_PIXCLK_Dependency_Table *clk_dep_table)
{
uint32_t table_size, i;
struct phm_ppt_v1_clock_voltage_dependency_table
@@ -681,6 +683,76 @@ static int get_dcefclk_voltage_dependency_table(
return 0;
}
+static int get_dcefclk_voltage_dependency_table(
+ struct pp_hwmgr *hwmgr,
+ struct phm_ppt_v1_clock_voltage_dependency_table
+ **pp_vega10_clk_dep_table,
+ const ATOM_Vega10_DCEFCLK_Dependency_Table *clk_dep_table)
+{
+ uint32_t table_size, i;
+ uint8_t num_entries;
+ struct phm_ppt_v1_clock_voltage_dependency_table
+ *clk_table;
+ struct cgs_system_info sys_info = {0};
+ uint32_t dev_id;
+ uint32_t rev_id;
+
+ PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0),
+ "Invalid PowerPlay Table!", return -1);
+
+/*
+ * workaround needed to add another DPM level for pioneer cards
+ * as VBIOS is locked down.
+ * This DPM level was added to support 3DPM monitors @ 4K120Hz
+ *
+ */
+ sys_info.size = sizeof(struct cgs_system_info);
+ sys_info.info_id = CGS_SYSTEM_INFO_PCIE_DEV;
+ cgs_query_system_info(hwmgr->device, &sys_info);
+ dev_id = (uint32_t)sys_info.value;
+
+ sys_info.size = sizeof(struct cgs_system_info);
+ sys_info.info_id = CGS_SYSTEM_INFO_PCIE_REV;
+ cgs_query_system_info(hwmgr->device, &sys_info);
+ rev_id = (uint32_t)sys_info.value;
+
+ if (dev_id == 0x6863 && rev_id == 0 &&
+ clk_dep_table->entries[clk_dep_table->ucNumEntries - 1].ulClk < 90000)
+ num_entries = clk_dep_table->ucNumEntries + 1 > NUM_DSPCLK_LEVELS ?
+ NUM_DSPCLK_LEVELS : clk_dep_table->ucNumEntries + 1;
+ else
+ num_entries = clk_dep_table->ucNumEntries;
+
+
+ table_size = sizeof(uint32_t) +
+ sizeof(phm_ppt_v1_clock_voltage_dependency_record) *
+ num_entries;
+
+ clk_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)
+ kzalloc(table_size, GFP_KERNEL);
+
+ if (!clk_table)
+ return -ENOMEM;
+
+ clk_table->count = (uint32_t)num_entries;
+
+ for (i = 0; i < clk_dep_table->ucNumEntries; i++) {
+ clk_table->entries[i].vddInd =
+ clk_dep_table->entries[i].ucVddInd;
+ clk_table->entries[i].clk =
+ le32_to_cpu(clk_dep_table->entries[i].ulClk);
+ }
+
+ if (i < num_entries) {
+ clk_table->entries[i].vddInd = clk_dep_table->entries[i-1].ucVddInd;
+ clk_table->entries[i].clk = 90000;
+ }
+
+ *pp_vega10_clk_dep_table = clk_table;
+
+ return 0;
+}
+
static int get_pcie_table(struct pp_hwmgr *hwmgr,
struct phm_ppt_v1_pcie_table **vega10_pcie_table,
const Vega10_PPTable_Generic_SubTable_Header *table)
@@ -862,21 +934,21 @@ static int init_powerplay_extended_tables(
gfxclk_dep_table);
if (!result && powerplay_table->usPixclkDependencyTableOffset)
- result = get_dcefclk_voltage_dependency_table(hwmgr,
+ result = get_pix_clk_voltage_dependency_table(hwmgr,
&pp_table_info->vdd_dep_on_pixclk,
- (const ATOM_Vega10_DCEFCLK_Dependency_Table*)
+ (const ATOM_Vega10_PIXCLK_Dependency_Table*)
pixclk_dep_table);
if (!result && powerplay_table->usPhyClkDependencyTableOffset)
- result = get_dcefclk_voltage_dependency_table(hwmgr,
+ result = get_pix_clk_voltage_dependency_table(hwmgr,
&pp_table_info->vdd_dep_on_phyclk,
- (const ATOM_Vega10_DCEFCLK_Dependency_Table *)
+ (const ATOM_Vega10_PIXCLK_Dependency_Table *)
phyclk_dep_table);
if (!result && powerplay_table->usDispClkDependencyTableOffset)
- result = get_dcefclk_voltage_dependency_table(hwmgr,
+ result = get_pix_clk_voltage_dependency_table(hwmgr,
&pp_table_info->vdd_dep_on_dispclk,
- (const ATOM_Vega10_DCEFCLK_Dependency_Table *)
+ (const ATOM_Vega10_PIXCLK_Dependency_Table *)
dispclk_dep_table);
if (!result && powerplay_table->usDcefclkDependencyTableOffset)
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
index e7ab8eb8a0cf..d44243441d28 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c
@@ -321,10 +321,7 @@ int vega10_fan_ctrl_reset_fan_speed_to_default(struct pp_hwmgr *hwmgr)
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_MicrocodeFanControl)) {
- result = vega10_fan_ctrl_set_static_mode(hwmgr,
- FDO_PWM_MODE_STATIC);
- if (!result)
- result = vega10_fan_ctrl_start_smc_fan_control(hwmgr);
+ result = vega10_fan_ctrl_start_smc_fan_control(hwmgr);
} else
result = vega10_fan_ctrl_set_default_mode(hwmgr);
@@ -633,7 +630,6 @@ int tf_vega10_thermal_start_smc_fan_control(struct pp_hwmgr *hwmgr,
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_MicrocodeFanControl)) {
vega10_fan_ctrl_start_smc_fan_control(hwmgr);
- vega10_fan_ctrl_set_static_mode(hwmgr, FDO_PWM_MODE_STATIC);
}
return 0;
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
index a1ebe1014492..a4c8b09b6f14 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
@@ -164,9 +164,14 @@ enum phm_platform_caps {
PHM_PlatformCaps_EnablePlatformPowerManagement, /* indicates that Platform Power Management feature is supported */
PHM_PlatformCaps_SurpriseRemoval, /* indicates that surprise removal feature is requested */
PHM_PlatformCaps_NewCACVoltage, /* indicates new CAC voltage table support */
+ PHM_PlatformCaps_DiDtSupport, /* for dI/dT feature */
PHM_PlatformCaps_DBRamping, /* for dI/dT feature */
PHM_PlatformCaps_TDRamping, /* for dI/dT feature */
PHM_PlatformCaps_TCPRamping, /* for dI/dT feature */
+ PHM_PlatformCaps_DBRRamping, /* for dI/dT feature */
+ PHM_PlatformCaps_DiDtEDCEnable, /* for dI/dT feature */
+ PHM_PlatformCaps_GCEDC, /* for dI/dT feature */
+ PHM_PlatformCaps_PSM, /* for dI/dT feature */
PHM_PlatformCaps_EnableSMU7ThermalManagement, /* SMC will manage thermal events */
PHM_PlatformCaps_FPS, /* FPS support */
PHM_PlatformCaps_ACP, /* ACP support */
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
index 47e57bd2c36f..91b0105e8240 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
@@ -128,6 +128,8 @@ struct phm_uvd_arbiter {
uint32_t dclk;
uint32_t vclk_ceiling;
uint32_t dclk_ceiling;
+ uint32_t vclk_soft_min;
+ uint32_t dclk_soft_min;
};
struct phm_vce_arbiter {
diff --git a/drivers/gpu/drm/amd/powerplay/inc/pp_debug.h b/drivers/gpu/drm/amd/powerplay/inc/pp_debug.h
index f3f9ebb631a5..822cd8b5bf90 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/pp_debug.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/pp_debug.h
@@ -42,6 +42,12 @@
} \
} while (0)
+#define PP_ASSERT(cond, msg) \
+ do { \
+ if (!(cond)) { \
+ pr_warn("%s\n", msg); \
+ } \
+ } while (0)
#define PP_DBG_LOG(fmt, ...) \
do { \
diff --git a/drivers/gpu/drm/amd/powerplay/inc/pp_soc15.h b/drivers/gpu/drm/amd/powerplay/inc/pp_soc15.h
index 227d999b6bd1..a511611ec7e0 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/pp_soc15.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/pp_soc15.h
@@ -41,6 +41,8 @@ inline static uint32_t soc15_get_register_offset(
reg = MP1_BASE.instance[inst].segment[segment] + offset;
else if (hw_id == DF_HWID)
reg = DF_BASE.instance[inst].segment[segment] + offset;
+ else if (hw_id == GC_HWID)
+ reg = GC_BASE.instance[inst].segment[segment] + offset;
return reg;
}
diff --git a/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h b/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h
index e0e106f1b23a..901c960cfe21 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h
@@ -66,7 +66,12 @@
#define PPSMC_MSG_SetMinVddcrSocVoltage 0x22
#define PPSMC_MSG_SetMinVideoFclkFreq 0x23
#define PPSMC_MSG_SetMinDeepSleepDcefclk 0x24
-#define PPSMC_Message_Count 0x25
+#define PPSMC_MSG_ForcePowerDownGfx 0x25
+#define PPSMC_MSG_SetPhyclkVoltageByFreq 0x26
+#define PPSMC_MSG_SetDppclkVoltageByFreq 0x27
+#define PPSMC_MSG_SetSoftMinVcn 0x28
+#define PPSMC_Message_Count 0x29
+
typedef uint16_t PPSMC_Result;
typedef int PPSMC_Msg;
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu9.h b/drivers/gpu/drm/amd/powerplay/inc/smu9.h
index 9ef2490c7c2e..550ed675027a 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smu9.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu9.h
@@ -55,9 +55,9 @@
#define FEATURE_FW_CTF_BIT 23
#define FEATURE_LED_DISPLAY_BIT 24
#define FEATURE_FAN_CONTROL_BIT 25
-#define FEATURE_VOLTAGE_CONTROLLER_BIT 26
-#define FEATURE_SPARE_27_BIT 27
-#define FEATURE_SPARE_28_BIT 28
+#define FEATURE_FAST_PPT_BIT 26
+#define FEATURE_GFX_EDC_BIT 27
+#define FEATURE_ACG_BIT 28
#define FEATURE_SPARE_29_BIT 29
#define FEATURE_SPARE_30_BIT 30
#define FEATURE_SPARE_31_BIT 31
@@ -90,9 +90,10 @@
#define FFEATURE_FW_CTF_MASK (1 << FEATURE_FW_CTF_BIT )
#define FFEATURE_LED_DISPLAY_MASK (1 << FEATURE_LED_DISPLAY_BIT )
#define FFEATURE_FAN_CONTROL_MASK (1 << FEATURE_FAN_CONTROL_BIT )
-#define FFEATURE_VOLTAGE_CONTROLLER_MASK (1 << FEATURE_VOLTAGE_CONTROLLER_BIT )
-#define FFEATURE_SPARE_27_MASK (1 << FEATURE_SPARE_27_BIT )
-#define FFEATURE_SPARE_28_MASK (1 << FEATURE_SPARE_28_BIT )
+
+#define FEATURE_FAST_PPT_MASK (1 << FAST_PPT_BIT )
+#define FEATURE_GFX_EDC_MASK (1 << FEATURE_GFX_EDC_BIT )
+#define FEATURE_ACG_MASK (1 << FEATURE_ACG_BIT )
#define FFEATURE_SPARE_29_MASK (1 << FEATURE_SPARE_29_BIT )
#define FFEATURE_SPARE_30_MASK (1 << FEATURE_SPARE_30_BIT )
#define FFEATURE_SPARE_31_MASK (1 << FEATURE_SPARE_31_BIT )
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu9_driver_if.h b/drivers/gpu/drm/amd/powerplay/inc/smu9_driver_if.h
index 532186b6f941..f6d6c61f796a 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smu9_driver_if.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu9_driver_if.h
@@ -312,7 +312,10 @@ typedef struct {
PllSetting_t GfxBoostState;
- uint32_t Reserved[14];
+ uint8_t AcgEnable[NUM_GFXCLK_DPM_LEVELS];
+ GbVdroopTable_t AcgBtcGbVdroopTable;
+ QuadraticInt_t AcgAvfsGb;
+ uint32_t Reserved[4];
/* Padding - ignore */
uint32_t MmHubPadding[7]; /* SMU internal use */
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h
index 976e942ec694..5d61cc9d4554 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h
@@ -131,6 +131,7 @@ struct pp_smumgr_func {
bool (*is_dpm_running)(struct pp_hwmgr *hwmgr);
int (*populate_requested_graphic_levels)(struct pp_hwmgr *hwmgr,
struct amd_pp_profile *request);
+ bool (*is_hw_avfs_present)(struct pp_smumgr *smumgr);
};
struct pp_smumgr {
@@ -202,6 +203,8 @@ extern bool smum_is_dpm_running(struct pp_hwmgr *hwmgr);
extern int smum_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr,
struct amd_pp_profile *request);
+extern bool smum_is_hw_avfs_present(struct pp_smumgr *smumgr);
+
#define SMUM_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT
#define SMUM_FIELD_MASK(reg, field) reg##__##field##_MASK
diff --git a/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h b/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h
index b4af9e85dfa5..cb070ebc7de1 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/vega10_ppsmc.h
@@ -124,6 +124,10 @@ typedef uint16_t PPSMC_Result;
#define PPSMC_MSG_NumOfDisplays 0x56
#define PPSMC_MSG_ReadSerialNumTop32 0x58
#define PPSMC_MSG_ReadSerialNumBottom32 0x59
+#define PPSMC_MSG_RunAcgBtc 0x5C
+#define PPSMC_MSG_RunAcgInClosedLoop 0x5D
+#define PPSMC_MSG_RunAcgInOpenLoop 0x5E
+#define PPSMC_MSG_InitializeAcg 0x5F
#define PPSMC_MSG_GetCurrPkgPwr 0x61
#define PPSMC_Message_Count 0x62
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c
index 6a320b27aefd..8712f093d6d9 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.c
@@ -2129,6 +2129,25 @@ int fiji_thermal_setup_fan_table(struct pp_hwmgr *hwmgr)
return 0;
}
+
+int fiji_thermal_avfs_enable(struct pp_hwmgr *hwmgr)
+{
+ int ret;
+ struct pp_smumgr *smumgr = (struct pp_smumgr *)(hwmgr->smumgr);
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
+
+ if (smu_data->avfs.avfs_btc_status != AVFS_BTC_ENABLEAVFS)
+ return 0;
+
+ ret = smum_send_msg_to_smc(smumgr, PPSMC_MSG_EnableAvfs);
+
+ if (!ret)
+ /* If this param is not changed, this function could fire unnecessarily */
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_COMPLETED_PREVIOUSLY;
+
+ return ret;
+}
+
static int fiji_program_mem_timing_parameters(struct pp_hwmgr *hwmgr)
{
struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.h b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.h
index 0e9e1f2d7238..d9c72d992e30 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.h
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smc.h
@@ -48,5 +48,6 @@ int fiji_initialize_mc_reg_table(struct pp_hwmgr *hwmgr);
bool fiji_is_dpm_running(struct pp_hwmgr *hwmgr);
int fiji_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr,
struct amd_pp_profile *request);
+int fiji_thermal_avfs_enable(struct pp_hwmgr *hwmgr);
#endif
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
index a1cb78552cf6..6ae948fc524f 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c
@@ -161,56 +161,47 @@ static int fiji_start_smu_in_non_protection_mode(struct pp_smumgr *smumgr)
static int fiji_setup_pwr_virus(struct pp_smumgr *smumgr)
{
- int i, result = -1;
+ int i;
+ int result = -EINVAL;
uint32_t reg, data;
- const PWR_Command_Table *virus = PwrVirusTable;
- struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
- priv->avfs.AvfsBtcStatus = AVFS_LOAD_VIRUS;
- for (i = 0; (i < PWR_VIRUS_TABLE_SIZE); i++) {
- switch (virus->command) {
+ const PWR_Command_Table *pvirus = PwrVirusTable;
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
+
+ for (i = 0; i < PWR_VIRUS_TABLE_SIZE; i++) {
+ switch (pvirus->command) {
case PwrCmdWrite:
- reg = virus->reg;
- data = virus->data;
+ reg = pvirus->reg;
+ data = pvirus->data;
cgs_write_register(smumgr->device, reg, data);
break;
+
case PwrCmdEnd:
- priv->avfs.AvfsBtcStatus = AVFS_BTC_VIRUS_LOADED;
result = 0;
break;
+
default:
- pr_err("Table Exit with Invalid Command!");
- priv->avfs.AvfsBtcStatus = AVFS_BTC_VIRUS_FAIL;
- result = -1;
+ pr_info("Table Exit with Invalid Command!");
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_VIRUS_FAIL;
+ result = -EINVAL;
break;
}
- virus++;
+ pvirus++;
}
+
return result;
}
static int fiji_start_avfs_btc(struct pp_smumgr *smumgr)
{
int result = 0;
- struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_STARTED;
- if (priv->avfs.AvfsBtcParam) {
- if (!smum_send_msg_to_smc_with_parameter(smumgr,
- PPSMC_MSG_PerformBtc, priv->avfs.AvfsBtcParam)) {
- if (!smum_send_msg_to_smc(smumgr, PPSMC_MSG_EnableAvfs)) {
- priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_UNSAVED;
- result = 0;
- } else {
- pr_err("[AVFS][fiji_start_avfs_btc] Attempt"
- " to Enable AVFS Failed!");
- smum_send_msg_to_smc(smumgr, PPSMC_MSG_DisableAvfs);
- result = -1;
- }
- } else {
- pr_err("[AVFS][fiji_start_avfs_btc] "
- "PerformBTC SMU msg failed");
- result = -1;
+ if (0 != smu_data->avfs.avfs_btc_param) {
+ if (0 != smu7_send_msg_to_smc_with_parameter(smumgr,
+ PPSMC_MSG_PerformBtc, smu_data->avfs.avfs_btc_param)) {
+ pr_info("[AVFS][Fiji_PerformBtc] PerformBTC SMU msg failed");
+ result = -EINVAL;
}
}
/* Soft-Reset to reset the engine before loading uCode */
@@ -224,42 +215,6 @@ static int fiji_start_avfs_btc(struct pp_smumgr *smumgr)
return result;
}
-static int fiji_setup_pm_fuse_for_avfs(struct pp_smumgr *smumgr)
-{
- int result = 0;
- uint32_t table_start;
- uint32_t charz_freq_addr, inversion_voltage_addr, charz_freq;
- uint16_t inversion_voltage;
-
- charz_freq = 0x30750000; /* In 10KHz units 0x00007530 Actual value */
- inversion_voltage = 0x1A04; /* mV Q14.2 0x41A Actual value */
-
- PP_ASSERT_WITH_CODE(0 == smu7_read_smc_sram_dword(smumgr,
- SMU7_FIRMWARE_HEADER_LOCATION + offsetof(SMU73_Firmware_Header,
- PmFuseTable), &table_start, 0x40000),
- "[AVFS][Fiji_SetupGfxLvlStruct] SMU could not communicate "
- "starting address of PmFuse structure",
- return -1;);
-
- charz_freq_addr = table_start +
- offsetof(struct SMU73_Discrete_PmFuses, PsmCharzFreq);
- inversion_voltage_addr = table_start +
- offsetof(struct SMU73_Discrete_PmFuses, InversionVoltage);
-
- result = smu7_copy_bytes_to_smc(smumgr, charz_freq_addr,
- (uint8_t *)(&charz_freq), sizeof(charz_freq), 0x40000);
- PP_ASSERT_WITH_CODE(0 == result,
- "[AVFS][fiji_setup_pm_fuse_for_avfs] charz_freq could not "
- "be populated.", return -1;);
-
- result = smu7_copy_bytes_to_smc(smumgr, inversion_voltage_addr,
- (uint8_t *)(&inversion_voltage), sizeof(inversion_voltage), 0x40000);
- PP_ASSERT_WITH_CODE(0 == result, "[AVFS][fiji_setup_pm_fuse_for_avfs] "
- "charz_freq could not be populated.", return -1;);
-
- return result;
-}
-
static int fiji_setup_graphics_level_structure(struct pp_smumgr *smumgr)
{
int32_t vr_config;
@@ -298,93 +253,41 @@ static int fiji_setup_graphics_level_structure(struct pp_smumgr *smumgr)
return 0;
}
-/* Work in Progress */
-static int fiji_restore_vft_table(struct pp_smumgr *smumgr)
-{
- struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
-
- if (AVFS_BTC_COMPLETED_SAVED == priv->avfs.AvfsBtcStatus) {
- priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_RESTORED;
- return 0;
- } else
- return -EINVAL;
-}
-
-/* Work in Progress */
-static int fiji_save_vft_table(struct pp_smumgr *smumgr)
-{
- struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
-
- if (AVFS_BTC_COMPLETED_SAVED == priv->avfs.AvfsBtcStatus) {
- priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_RESTORED;
- return 0;
- } else
- return -EINVAL;
-}
-
static int fiji_avfs_event_mgr(struct pp_smumgr *smumgr, bool smu_started)
{
- struct fiji_smumgr *priv = (struct fiji_smumgr *)(smumgr->backend);
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
- switch (priv->avfs.AvfsBtcStatus) {
- case AVFS_BTC_COMPLETED_SAVED: /*S3 State - Pre SMU Start */
- priv->avfs.AvfsBtcStatus = AVFS_BTC_RESTOREVFT_FAILED;
- PP_ASSERT_WITH_CODE(0 == fiji_restore_vft_table(smumgr),
- "[AVFS][fiji_avfs_event_mgr] Could not Copy Graphics "
- "Level table over to SMU",
- return -1;);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_RESTORED;
- break;
- case AVFS_BTC_COMPLETED_RESTORED: /*S3 State - Post SMU Start*/
- priv->avfs.AvfsBtcStatus = AVFS_BTC_SMUMSG_ERROR;
- PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(smumgr,
- 0x666),
- "[AVFS][fiji_avfs_event_mgr] SMU did not respond "
- "correctly to VftTableIsValid Msg",
- return -1;);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_SMUMSG_ERROR;
- PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(smumgr,
- PPSMC_MSG_EnableAvfs),
- "[AVFS][fiji_avfs_event_mgr] SMU did not respond "
- "correctly to EnableAvfs Message Msg",
- return -1;);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_SAVED;
+ switch (smu_data->avfs.avfs_btc_status) {
+ case AVFS_BTC_COMPLETED_PREVIOUSLY:
break;
+
case AVFS_BTC_BOOT: /*Cold Boot State - Post SMU Start*/
if (!smu_started)
break;
- priv->avfs.AvfsBtcStatus = AVFS_BTC_FAILED;
- PP_ASSERT_WITH_CODE(0 == fiji_setup_pm_fuse_for_avfs(smumgr),
- "[AVFS][fiji_avfs_event_mgr] Failure at "
- "fiji_setup_pm_fuse_for_avfs",
- return -1;);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_DPMTABLESETUP_FAILED;
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_FAILED;
PP_ASSERT_WITH_CODE(0 == fiji_setup_graphics_level_structure(smumgr),
"[AVFS][fiji_avfs_event_mgr] Could not Copy Graphics Level"
" table over to SMU",
- return -1;);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_VIRUS_FAIL;
+ return -EINVAL;);
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_VIRUS_FAIL;
PP_ASSERT_WITH_CODE(0 == fiji_setup_pwr_virus(smumgr),
"[AVFS][fiji_avfs_event_mgr] Could not setup "
"Pwr Virus for AVFS ",
- return -1;);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_FAILED;
+ return -EINVAL;);
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_FAILED;
PP_ASSERT_WITH_CODE(0 == fiji_start_avfs_btc(smumgr),
"[AVFS][fiji_avfs_event_mgr] Failure at "
"fiji_start_avfs_btc. AVFS Disabled",
- return -1;);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_SAVEVFT_FAILED;
- PP_ASSERT_WITH_CODE(0 == fiji_save_vft_table(smumgr),
- "[AVFS][fiji_avfs_event_mgr] Could not save VFT Table",
- return -1;);
- priv->avfs.AvfsBtcStatus = AVFS_BTC_COMPLETED_SAVED;
+ return -EINVAL;);
+
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_ENABLEAVFS;
break;
case AVFS_BTC_DISABLED: /* Do nothing */
- break;
case AVFS_BTC_NOTSUPPORTED: /* Do nothing */
+ case AVFS_BTC_ENABLEAVFS:
break;
default:
- pr_err("[AVFS] Something is broken. See log!");
+ pr_err("AVFS failed status is %x !\n", smu_data->avfs.avfs_btc_status);
break;
}
return 0;
@@ -477,19 +380,6 @@ static int fiji_smu_init(struct pp_smumgr *smumgr)
if (smu7_init(smumgr))
return -EINVAL;
- fiji_priv->avfs.AvfsBtcStatus = AVFS_BTC_BOOT;
- if (fiji_is_hw_avfs_present(smumgr))
- /* AVFS Parameter
- * 0 - BTC DC disabled, BTC AC disabled
- * 1 - BTC DC enabled, BTC AC disabled
- * 2 - BTC DC disabled, BTC AC enabled
- * 3 - BTC DC enabled, BTC AC enabled
- * Default is 0 - BTC DC disabled, BTC AC disabled
- */
- fiji_priv->avfs.AvfsBtcParam = 0;
- else
- fiji_priv->avfs.AvfsBtcStatus = AVFS_BTC_NOTSUPPORTED;
-
for (i = 0; i < SMU73_MAX_LEVELS_GRAPHICS; i++)
fiji_priv->activity_target[i] = 30;
@@ -514,10 +404,12 @@ const struct pp_smumgr_func fiji_smu_funcs = {
.init_smc_table = fiji_init_smc_table,
.update_sclk_threshold = fiji_update_sclk_threshold,
.thermal_setup_fan_table = fiji_thermal_setup_fan_table,
+ .thermal_avfs_enable = fiji_thermal_avfs_enable,
.populate_all_graphic_levels = fiji_populate_all_graphic_levels,
.populate_all_memory_levels = fiji_populate_all_memory_levels,
.get_mac_definition = fiji_get_mac_definition,
.initialize_mc_reg_table = fiji_initialize_mc_reg_table,
.is_dpm_running = fiji_is_dpm_running,
.populate_requested_graphic_levels = fiji_populate_requested_graphic_levels,
+ .is_hw_avfs_present = fiji_is_hw_avfs_present,
};
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h
index adcbdfb209be..175bf9f8ef9c 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h
@@ -28,17 +28,8 @@
#include "smu7_smumgr.h"
-
-struct fiji_smu_avfs {
- enum AVFS_BTC_STATUS AvfsBtcStatus;
- uint32_t AvfsBtcParam;
-};
-
-
struct fiji_smumgr {
struct smu7_smumgr smu7_data;
-
- struct fiji_smu_avfs avfs;
struct SMU73_Discrete_DpmTable smc_state_table;
struct SMU73_Discrete_Ulv ulv_setting;
struct SMU73_Discrete_PmFuses power_tune_table;
@@ -47,7 +38,5 @@ struct fiji_smumgr {
};
-
-
#endif
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c
index f68e759e8be2..99a00bd39256 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smc.c
@@ -1498,7 +1498,7 @@ static int polaris10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
table_info->vdd_dep_on_sclk;
- if (smu_data->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED)
+ if (((struct smu7_smumgr *)smu_data)->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED)
return result;
result = atomctrl_get_avfs_information(hwmgr, &avfs_params);
@@ -1889,7 +1889,7 @@ int polaris10_thermal_avfs_enable(struct pp_hwmgr *hwmgr)
{
int ret;
struct pp_smumgr *smumgr = (struct pp_smumgr *)(hwmgr->smumgr);
- struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(smumgr->backend);
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
if (smu_data->avfs.avfs_btc_status == AVFS_BTC_NOTSUPPORTED)
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
index 9616cedc139c..75f43dadc56b 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
@@ -60,16 +60,14 @@ static const SMU74_Discrete_GraphicsLevel avfs_graphics_level_polaris10[8] = {
static const SMU74_Discrete_MemoryLevel avfs_memory_level_polaris10 = {
0x100ea446, 0, 0x30750000, 0x01, 0x01, 0x01, 0x00, 0x00, 0x64, 0x00, 0x00, 0x1f00, 0x00, 0x00};
-
static int polaris10_setup_pwr_virus(struct pp_smumgr *smumgr)
{
int i;
- int result = -1;
+ int result = -EINVAL;
uint32_t reg, data;
const PWR_Command_Table *pvirus = pwr_virus_table;
- struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(smumgr->backend);
-
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
for (i = 0; i < PWR_VIRUS_TABLE_SIZE; i++) {
switch (pvirus->command) {
@@ -86,7 +84,7 @@ static int polaris10_setup_pwr_virus(struct pp_smumgr *smumgr)
default:
pr_info("Table Exit with Invalid Command!");
smu_data->avfs.avfs_btc_status = AVFS_BTC_VIRUS_FAIL;
- result = -1;
+ result = -EINVAL;
break;
}
pvirus++;
@@ -98,7 +96,7 @@ static int polaris10_setup_pwr_virus(struct pp_smumgr *smumgr)
static int polaris10_perform_btc(struct pp_smumgr *smumgr)
{
int result = 0;
- struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(smumgr->backend);
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
if (0 != smu_data->avfs.avfs_btc_param) {
if (0 != smu7_send_msg_to_smc_with_parameter(smumgr, PPSMC_MSG_PerformBtc, smu_data->avfs.avfs_btc_param)) {
@@ -172,10 +170,11 @@ static int polaris10_setup_graphics_level_structure(struct pp_smumgr *smumgr)
return 0;
}
+
static int
polaris10_avfs_event_mgr(struct pp_smumgr *smumgr, bool SMU_VFT_INTACT)
{
- struct polaris10_smumgr *smu_data = (struct polaris10_smumgr *)(smumgr->backend);
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(smumgr->backend);
switch (smu_data->avfs.avfs_btc_status) {
case AVFS_BTC_COMPLETED_PREVIOUSLY:
@@ -185,30 +184,31 @@ polaris10_avfs_event_mgr(struct pp_smumgr *smumgr, bool SMU_VFT_INTACT)
smu_data->avfs.avfs_btc_status = AVFS_BTC_DPMTABLESETUP_FAILED;
PP_ASSERT_WITH_CODE(0 == polaris10_setup_graphics_level_structure(smumgr),
- "[AVFS][Polaris10_AVFSEventMgr] Could not Copy Graphics Level table over to SMU",
- return -1);
+ "[AVFS][Polaris10_AVFSEventMgr] Could not Copy Graphics Level table over to SMU",
+ return -EINVAL);
if (smu_data->avfs.avfs_btc_param > 1) {
pr_info("[AVFS][Polaris10_AVFSEventMgr] AC BTC has not been successfully verified on Fiji. There may be in this setting.");
smu_data->avfs.avfs_btc_status = AVFS_BTC_VIRUS_FAIL;
- PP_ASSERT_WITH_CODE(-1 == polaris10_setup_pwr_virus(smumgr),
+ PP_ASSERT_WITH_CODE(0 == polaris10_setup_pwr_virus(smumgr),
"[AVFS][Polaris10_AVFSEventMgr] Could not setup Pwr Virus for AVFS ",
- return -1);
+ return -EINVAL);
}
smu_data->avfs.avfs_btc_status = AVFS_BTC_FAILED;
PP_ASSERT_WITH_CODE(0 == polaris10_perform_btc(smumgr),
"[AVFS][Polaris10_AVFSEventMgr] Failure at SmuPolaris10_PerformBTC. AVFS Disabled",
- return -1);
-
+ return -EINVAL);
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_ENABLEAVFS;
break;
case AVFS_BTC_DISABLED:
+ case AVFS_BTC_ENABLEAVFS:
case AVFS_BTC_NOTSUPPORTED:
break;
default:
- pr_info("[AVFS] Something is broken. See log!");
+ pr_err("AVFS failed status is %x!\n", smu_data->avfs.avfs_btc_status);
break;
}
@@ -376,11 +376,6 @@ static int polaris10_smu_init(struct pp_smumgr *smumgr)
if (smu7_init(smumgr))
return -EINVAL;
- if (polaris10_is_hw_avfs_present(smumgr))
- smu_data->avfs.avfs_btc_status = AVFS_BTC_BOOT;
- else
- smu_data->avfs.avfs_btc_status = AVFS_BTC_NOTSUPPORTED;
-
for (i = 0; i < SMU74_MAX_LEVELS_GRAPHICS; i++)
smu_data->activity_target[i] = PPPOLARIS10_TARGETACTIVITY_DFLT;
@@ -410,4 +405,5 @@ const struct pp_smumgr_func polaris10_smu_funcs = {
.get_mac_definition = polaris10_get_mac_definition,
.is_dpm_running = polaris10_is_dpm_running,
.populate_requested_graphic_levels = polaris10_populate_requested_graphic_levels,
+ .is_hw_avfs_present = polaris10_is_hw_avfs_present,
};
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.h
index 49ebf1d5a53c..5e19c24b0561 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.h
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.h
@@ -32,11 +32,6 @@
#define SMC_RAM_END 0x40000
-struct polaris10_avfs {
- enum AVFS_BTC_STATUS avfs_btc_status;
- uint32_t avfs_btc_param;
-};
-
struct polaris10_pt_defaults {
uint8_t SviLoadLineEn;
uint8_t SviLoadLineVddC;
@@ -51,8 +46,6 @@ struct polaris10_pt_defaults {
uint16_t BAPMTI_RC[SMU74_DTE_ITERATIONS * SMU74_DTE_SOURCES * SMU74_DTE_SINKS];
};
-
-
struct polaris10_range_table {
uint32_t trans_lower_frequency; /* in 10khz */
uint32_t trans_upper_frequency;
@@ -61,14 +54,13 @@ struct polaris10_range_table {
struct polaris10_smumgr {
struct smu7_smumgr smu7_data;
uint8_t protected_mode;
- struct polaris10_avfs avfs;
SMU74_Discrete_DpmTable smc_state_table;
struct SMU74_Discrete_Ulv ulv_setting;
struct SMU74_Discrete_PmFuses power_tune_table;
struct polaris10_range_table range_table[NUM_SCLK_RANGE];
const struct polaris10_pt_defaults *power_tune_defaults;
- uint32_t activity_target[SMU74_MAX_LEVELS_GRAPHICS];
- uint32_t bif_sclk_table[SMU74_MAX_LEVELS_LINK];
+ uint32_t activity_target[SMU74_MAX_LEVELS_GRAPHICS];
+ uint32_t bif_sclk_table[SMU74_MAX_LEVELS_LINK];
};
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c
index 35ac27681415..76347ff6d655 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c
@@ -540,7 +540,6 @@ int smu7_upload_smu_firmware_image(struct pp_smumgr *smumgr)
return result;
}
-
int smu7_init(struct pp_smumgr *smumgr)
{
struct smu7_smumgr *smu_data;
@@ -596,6 +595,11 @@ int smu7_init(struct pp_smumgr *smumgr)
(cgs_handle_t)smu_data->smu_buffer.handle);
return -EINVAL);
+ if (smum_is_hw_avfs_present(smumgr))
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_BOOT;
+ else
+ smu_data->avfs.avfs_btc_status = AVFS_BTC_NOTSUPPORTED;
+
return 0;
}
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h
index 919be435b49c..ee5e32d2921e 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h
@@ -37,6 +37,11 @@ struct smu7_buffer_entry {
unsigned long handle;
};
+struct smu7_avfs {
+ enum AVFS_BTC_STATUS avfs_btc_status;
+ uint32_t avfs_btc_param;
+};
+
struct smu7_smumgr {
uint8_t *header;
uint8_t *mec_image;
@@ -50,7 +55,8 @@ struct smu7_smumgr {
uint32_t arb_table_start;
uint32_t ulv_setting_starts;
uint8_t security_hard_key;
- uint32_t acpi_optimization;
+ uint32_t acpi_optimization;
+ struct smu7_avfs avfs;
};
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
index bcc61ffd13cb..3bdf6478de7f 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
@@ -43,7 +43,8 @@ MODULE_FIRMWARE("amdgpu/polaris11_smc.bin");
MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin");
MODULE_FIRMWARE("amdgpu/polaris11_k_smc.bin");
MODULE_FIRMWARE("amdgpu/polaris12_smc.bin");
-
+MODULE_FIRMWARE("amdgpu/vega10_smc.bin");
+MODULE_FIRMWARE("amdgpu/vega10_acg_smc.bin");
int smum_early_init(struct pp_instance *handle)
{
@@ -403,3 +404,11 @@ int smum_populate_requested_graphic_levels(struct pp_hwmgr *hwmgr,
return 0;
}
+
+bool smum_is_hw_avfs_present(struct pp_smumgr *smumgr)
+{
+ if (smumgr->smumgr_funcs->is_hw_avfs_present)
+ return smumgr->smumgr_funcs->is_hw_avfs_present(smumgr);
+
+ return false;
+}
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c
index 269678443862..408514c965a0 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/vega10_smumgr.c
@@ -356,6 +356,9 @@ int vega10_set_tools_address(struct pp_smumgr *smumgr)
static int vega10_verify_smc_interface(struct pp_smumgr *smumgr)
{
uint32_t smc_driver_if_version;
+ struct cgs_system_info sys_info = {0};
+ uint32_t dev_id;
+ uint32_t rev_id;
PP_ASSERT_WITH_CODE(!vega10_send_msg_to_smc(smumgr,
PPSMC_MSG_GetDriverIfVersion),
@@ -363,12 +366,27 @@ static int vega10_verify_smc_interface(struct pp_smumgr *smumgr)
return -EINVAL);
vega10_read_arg_from_smc(smumgr, &smc_driver_if_version);
- if (smc_driver_if_version != SMU9_DRIVER_IF_VERSION) {
- pr_err("Your firmware(0x%x) doesn't match \
- SMU9_DRIVER_IF_VERSION(0x%x). \
- Please update your firmware!\n",
- smc_driver_if_version, SMU9_DRIVER_IF_VERSION);
- return -EINVAL;
+ sys_info.size = sizeof(struct cgs_system_info);
+ sys_info.info_id = CGS_SYSTEM_INFO_PCIE_DEV;
+ cgs_query_system_info(smumgr->device, &sys_info);
+ dev_id = (uint32_t)sys_info.value;
+
+ sys_info.size = sizeof(struct cgs_system_info);
+ sys_info.info_id = CGS_SYSTEM_INFO_PCIE_REV;
+ cgs_query_system_info(smumgr->device, &sys_info);
+ rev_id = (uint32_t)sys_info.value;
+
+ if (!((dev_id == 0x687f) &&
+ ((rev_id == 0xc0) ||
+ (rev_id == 0xc1) ||
+ (rev_id == 0xc3)))) {
+ if (smc_driver_if_version != SMU9_DRIVER_IF_VERSION) {
+ pr_err("Your firmware(0x%x) doesn't match \
+ SMU9_DRIVER_IF_VERSION(0x%x). \
+ Please update your firmware!\n",
+ smc_driver_if_version, SMU9_DRIVER_IF_VERSION);
+ return -EINVAL;
+ }
}
return 0;
diff --git a/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h b/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h
index dbd4fd3a810b..8bd38102b58e 100644
--- a/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h
+++ b/drivers/gpu/drm/amd/scheduler/gpu_sched_trace.h
@@ -16,16 +16,16 @@ TRACE_EVENT(amd_sched_job,
TP_ARGS(sched_job),
TP_STRUCT__entry(
__field(struct amd_sched_entity *, entity)
- __field(struct amd_sched_job *, sched_job)
__field(struct dma_fence *, fence)
__field(const char *, name)
+ __field(uint64_t, id)
__field(u32, job_count)
__field(int, hw_job_count)
),
TP_fast_assign(
__entry->entity = sched_job->s_entity;
- __entry->sched_job = sched_job;
+ __entry->id = sched_job->id;
__entry->fence = &sched_job->s_fence->finished;
__entry->name = sched_job->sched->name;
__entry->job_count = kfifo_len(
@@ -33,8 +33,9 @@ TRACE_EVENT(amd_sched_job,
__entry->hw_job_count = atomic_read(
&sched_job->sched->hw_rq_count);
),
- TP_printk("entity=%p, sched job=%p, fence=%p, ring=%s, job count:%u, hw job count:%d",
- __entry->entity, __entry->sched_job, __entry->fence, __entry->name,
+ TP_printk("entity=%p, id=%llu, fence=%p, ring=%s, job count:%u, hw job count:%d",
+ __entry->entity, __entry->id,
+ __entry->fence, __entry->name,
__entry->job_count, __entry->hw_job_count)
);
diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c
index ad9a95916f1f..16903dc7fe0d 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -64,6 +64,20 @@ static const struct drm_crtc_funcs arc_pgu_crtc_funcs = {
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
};
+static enum drm_mode_status arc_pgu_crtc_mode_valid(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode)
+{
+ struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
+ long rate, clk_rate = mode->clock * 1000;
+ long diff = clk_rate / 200; /* +-0.5% allowed by HDMI spec */
+
+ rate = clk_round_rate(arcpgu->clk, clk_rate);
+ if ((max(rate, clk_rate) - min(rate, clk_rate) < diff) && (rate > 0))
+ return MODE_OK;
+
+ return MODE_NOCLOCK;
+}
+
static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc)
{
struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
@@ -106,7 +120,8 @@ static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc)
clk_set_rate(arcpgu->clk, m->crtc_clock * 1000);
}
-static void arc_pgu_crtc_enable(struct drm_crtc *crtc)
+static void arc_pgu_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
@@ -116,7 +131,8 @@ static void arc_pgu_crtc_enable(struct drm_crtc *crtc)
ARCPGU_CTRL_ENABLE_MASK);
}
-static void arc_pgu_crtc_disable(struct drm_crtc *crtc)
+static void arc_pgu_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
@@ -129,20 +145,6 @@ static void arc_pgu_crtc_disable(struct drm_crtc *crtc)
~ARCPGU_CTRL_ENABLE_MASK);
}
-static int arc_pgu_crtc_atomic_check(struct drm_crtc *crtc,
- struct drm_crtc_state *state)
-{
- struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
- struct drm_display_mode *mode = &state->adjusted_mode;
- long rate, clk_rate = mode->clock * 1000;
-
- rate = clk_round_rate(arcpgu->clk, clk_rate);
- if (rate != clk_rate)
- return -EINVAL;
-
- return 0;
-}
-
static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
struct drm_crtc_state *state)
{
@@ -158,15 +160,13 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs arc_pgu_crtc_helper_funcs = {
+ .mode_valid = arc_pgu_crtc_mode_valid,
.mode_set = drm_helper_crtc_mode_set,
.mode_set_base = drm_helper_crtc_mode_set_base,
.mode_set_nofb = arc_pgu_crtc_mode_set_nofb,
- .enable = arc_pgu_crtc_enable,
- .disable = arc_pgu_crtc_disable,
- .prepare = arc_pgu_crtc_disable,
- .commit = arc_pgu_crtc_enable,
- .atomic_check = arc_pgu_crtc_atomic_check,
.atomic_begin = arc_pgu_crtc_atomic_begin,
+ .atomic_enable = arc_pgu_crtc_atomic_enable,
+ .atomic_disable = arc_pgu_crtc_atomic_disable,
};
static void arc_pgu_plane_atomic_update(struct drm_plane *plane,
@@ -218,6 +218,7 @@ static struct drm_plane *arc_pgu_plane_init(struct drm_device *drm)
ret = drm_universal_plane_init(drm, plane, 0xff, &arc_pgu_plane_funcs,
formats, ARRAY_SIZE(formats),
+ NULL,
DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret)
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index 3e43a5d4fb09..289eda54e5aa 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -31,7 +31,7 @@ static void arcpgu_fb_output_poll_changed(struct drm_device *dev)
drm_fbdev_cma_hotplug_event(arcpgu->fbdev);
}
-static struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = {
+static const struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = {
.fb_create = drm_fb_cma_create,
.output_poll_changed = arcpgu_fb_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
@@ -48,29 +48,7 @@ static void arcpgu_setup_mode_config(struct drm_device *drm)
drm->mode_config.funcs = &arcpgu_drm_modecfg_funcs;
}
-static int arcpgu_gem_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- int ret;
-
- ret = drm_gem_mmap(filp, vma);
- if (ret)
- return ret;
-
- vma->vm_page_prot = pgprot_noncached(vm_get_page_prot(vma->vm_flags));
- return 0;
-}
-
-static const struct file_operations arcpgu_drm_ops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .unlocked_ioctl = drm_ioctl,
- .compat_ioctl = drm_compat_ioctl,
- .poll = drm_poll,
- .read = drm_read,
- .llseek = no_llseek,
- .mmap = arcpgu_gem_mmap,
-};
+DEFINE_DRM_GEM_CMA_FOPS(arcpgu_drm_ops);
static void arcpgu_lastclose(struct drm_device *drm)
{
@@ -142,7 +120,7 @@ static int arcpgu_load(struct drm_device *drm)
return -ENODEV;
}
- platform_set_drvdata(pdev, arcpgu);
+ platform_set_drvdata(pdev, drm);
return 0;
}
@@ -160,11 +138,37 @@ static int arcpgu_unload(struct drm_device *drm)
return 0;
}
+#ifdef CONFIG_DEBUG_FS
+static int arcpgu_show_pxlclock(struct seq_file *m, void *arg)
+{
+ struct drm_info_node *node = (struct drm_info_node *)m->private;
+ struct drm_device *drm = node->minor->dev;
+ struct arcpgu_drm_private *arcpgu = drm->dev_private;
+ unsigned long clkrate = clk_get_rate(arcpgu->clk);
+ unsigned long mode_clock = arcpgu->crtc.mode.crtc_clock * 1000;
+
+ seq_printf(m, "hw : %lu\n", clkrate);
+ seq_printf(m, "mode: %lu\n", mode_clock);
+ return 0;
+}
+
+static struct drm_info_list arcpgu_debugfs_list[] = {
+ { "clocks", arcpgu_show_pxlclock, 0 },
+ { "fb", drm_fb_cma_debugfs_show, 0 },
+};
+
+static int arcpgu_debugfs_init(struct drm_minor *minor)
+{
+ return drm_debugfs_create_files(arcpgu_debugfs_list,
+ ARRAY_SIZE(arcpgu_debugfs_list), minor->debugfs_root, minor);
+}
+#endif
+
static struct drm_driver arcpgu_drm_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
DRIVER_ATOMIC,
.lastclose = arcpgu_lastclose,
- .name = "drm-arcpgu",
+ .name = "arcpgu",
.desc = "ARC PGU Controller",
.date = "20160219",
.major = 1,
@@ -172,8 +176,6 @@ static struct drm_driver arcpgu_drm_driver = {
.patchlevel = 0,
.fops = &arcpgu_drm_ops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_free_object_unlocked = drm_gem_cma_free_object,
@@ -185,6 +187,9 @@ static struct drm_driver arcpgu_drm_driver = {
.gem_prime_vmap = drm_gem_cma_prime_vmap,
.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
.gem_prime_mmap = drm_gem_cma_prime_mmap,
+#ifdef CONFIG_DEBUG_FS
+ .debugfs_init = arcpgu_debugfs_init,
+#endif
};
static int arcpgu_probe(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index d67b6f15e8b8..72b22b805412 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -165,7 +165,8 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
clk_set_rate(hdlcd->clk, m->crtc_clock * 1000);
}
-static void hdlcd_crtc_enable(struct drm_crtc *crtc)
+static void hdlcd_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
@@ -175,7 +176,8 @@ static void hdlcd_crtc_enable(struct drm_crtc *crtc)
drm_crtc_vblank_on(crtc);
}
-static void hdlcd_crtc_disable(struct drm_crtc *crtc)
+static void hdlcd_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
@@ -218,10 +220,10 @@ static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = {
- .enable = hdlcd_crtc_enable,
- .disable = hdlcd_crtc_disable,
.atomic_check = hdlcd_crtc_atomic_check,
.atomic_begin = hdlcd_crtc_atomic_begin,
+ .atomic_enable = hdlcd_crtc_atomic_enable,
+ .atomic_disable = hdlcd_crtc_atomic_disable,
};
static int hdlcd_plane_atomic_check(struct drm_plane *plane,
@@ -313,6 +315,7 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm)
ret = drm_universal_plane_init(drm, plane, 0xff, &hdlcd_plane_funcs,
formats, ARRAY_SIZE(formats),
+ NULL,
DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) {
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index d3da87fbd85a..f9bda7b0d2ec 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -253,8 +253,6 @@ static struct drm_driver hdlcd_driver = {
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_export = drm_gem_prime_export,
@@ -343,7 +341,6 @@ err_register:
}
err_fbdev:
drm_kms_helper_poll_fini(drm);
- drm_vblank_cleanup(drm);
err_vblank:
pm_runtime_disable(drm->dev);
err_pm_active:
@@ -375,7 +372,6 @@ static void hdlcd_drm_unbind(struct device *dev)
component_unbind_all(dev, drm);
of_node_put(hdlcd->crtc.port);
hdlcd->crtc.port = NULL;
- drm_vblank_cleanup(drm);
pm_runtime_get_sync(drm->dev);
drm_irq_uninstall(drm);
pm_runtime_put_sync(drm->dev);
diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c
index 4bb38a21efec..3615d18a7ddf 100644
--- a/drivers/gpu/drm/arm/malidp_crtc.c
+++ b/drivers/gpu/drm/arm/malidp_crtc.c
@@ -46,7 +46,8 @@ static enum drm_mode_status malidp_crtc_mode_valid(struct drm_crtc *crtc,
return MODE_OK;
}
-static void malidp_crtc_enable(struct drm_crtc *crtc)
+static void malidp_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
struct malidp_hw_device *hwdev = malidp->dev;
@@ -69,7 +70,8 @@ static void malidp_crtc_enable(struct drm_crtc *crtc)
drm_crtc_vblank_on(crtc);
}
-static void malidp_crtc_disable(struct drm_crtc *crtc)
+static void malidp_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
struct malidp_hw_device *hwdev = malidp->dev;
@@ -408,9 +410,9 @@ static int malidp_crtc_atomic_check(struct drm_crtc *crtc,
static const struct drm_crtc_helper_funcs malidp_crtc_helper_funcs = {
.mode_valid = malidp_crtc_mode_valid,
- .enable = malidp_crtc_enable,
- .disable = malidp_crtc_disable,
.atomic_check = malidp_crtc_atomic_check,
+ .atomic_enable = malidp_crtc_atomic_enable,
+ .atomic_disable = malidp_crtc_atomic_disable,
};
static struct drm_crtc_state *malidp_crtc_duplicate_state(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 01b13d219917..1a57cc28955e 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -225,7 +225,7 @@ static void malidp_atomic_commit_tail(struct drm_atomic_state *state)
drm_atomic_helper_commit_modeset_disables(drm, state);
- for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
+ for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
malidp_atomic_commit_update_gamma(crtc, old_crtc_state);
malidp_atomic_commit_update_coloradj(crtc, old_crtc_state);
malidp_atomic_commit_se_config(crtc, old_crtc_state);
@@ -331,8 +331,6 @@ static struct drm_driver malidp_driver = {
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_export = drm_gem_prime_export,
diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
index 600fa7bd7f52..94e7e3fa3408 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -128,7 +128,6 @@ static void malidp_plane_atomic_print_state(struct drm_printer *p,
static const struct drm_plane_funcs malidp_de_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
- .set_property = drm_atomic_helper_plane_set_property,
.destroy = malidp_de_plane_destroy,
.reset = malidp_plane_reset,
.atomic_duplicate_state = malidp_duplicate_plane_state,
@@ -398,7 +397,7 @@ int malidp_de_planes_init(struct drm_device *drm)
DRM_PLANE_TYPE_OVERLAY;
ret = drm_universal_plane_init(drm, &plane->base, crtcs,
&malidp_de_plane_funcs, formats,
- n, plane_type, NULL);
+ n, NULL, plane_type, NULL);
if (ret < 0)
goto cleanup;
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 4fe19fde84f9..2a4d163ac76f 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -334,16 +334,6 @@ static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary);
}
-void armada_drm_crtc_gamma_set(struct drm_crtc *crtc, u16 r, u16 g, u16 b,
- int idx)
-{
-}
-
-void armada_drm_crtc_gamma_get(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
- int idx)
-{
-}
-
/* The mode_config.mutex will be held for this call */
static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms)
{
@@ -1150,13 +1140,13 @@ int armada_drm_plane_init(struct armada_plane *plane)
return 0;
}
-static struct drm_prop_enum_list armada_drm_csc_yuv_enum_list[] = {
+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 struct drm_prop_enum_list armada_drm_csc_rgb_enum_list[] = {
+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" },
@@ -1269,6 +1259,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
&armada_primary_plane_funcs,
armada_primary_formats,
ARRAY_SIZE(armada_primary_formats),
+ NULL,
DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) {
kfree(primary);
@@ -1329,8 +1320,7 @@ armada_lcd_bind(struct device *dev, struct device *master, void *data)
port = of_get_child_by_name(parent, "port");
of_node_put(np);
if (!port) {
- dev_err(dev, "no port node found in %s\n",
- parent->full_name);
+ dev_err(dev, "no port node found in %pOF\n", parent);
return -ENXIO;
}
@@ -1364,7 +1354,7 @@ static int armada_lcd_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id armada_lcd_of_match[] = {
+static const struct of_device_id armada_lcd_of_match[] = {
{
.compatible = "marvell,dove-lcd",
.data = &armada510_ops,
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 7e8906d3ae26..bab11f483575 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -102,8 +102,6 @@ struct armada_crtc {
};
#define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
-void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int);
-void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int);
void armada_drm_crtc_update_regs(struct armada_crtc *, struct armada_regs *);
void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc,
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index e618fab7f519..0b3227c039d7 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -232,8 +232,8 @@ static void armada_add_endpoints(struct device *dev,
of_node_put(remote);
continue;
} else if (!of_device_is_available(remote->parent)) {
- dev_warn(dev, "parent device of %s is not available\n",
- remote->full_name);
+ dev_warn(dev, "parent device of %pOF is not available\n",
+ remote);
of_node_put(remote);
continue;
}
diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c
index 602dfead8eef..29c7d047b152 100644
--- a/drivers/gpu/drm/armada/armada_fbdev.c
+++ b/drivers/gpu/drm/armada/armada_fbdev.c
@@ -81,7 +81,6 @@ static int armada_fb_create(struct drm_fb_helper *fbh,
strlcpy(info->fix.id, "armada-drmfb", sizeof(info->fix.id));
info->par = fbh;
- info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &armada_fb_ops;
info->fix.smem_start = obj->phys_addr;
info->fix.smem_len = obj->obj.size;
@@ -118,8 +117,6 @@ static int armada_fb_probe(struct drm_fb_helper *fbh,
}
static const struct drm_fb_helper_funcs armada_fb_helper_funcs = {
- .gamma_set = armada_drm_crtc_gamma_set,
- .gamma_get = armada_drm_crtc_gamma_get,
.fb_probe = armada_fb_probe,
};
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index e9a29df4b443..edc44910d79f 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -388,7 +388,7 @@ static const uint32_t armada_ovl_formats[] = {
DRM_FORMAT_BGR565,
};
-static struct drm_prop_enum_list armada_drm_colorkey_enum_list[] = {
+static const struct drm_prop_enum_list armada_drm_colorkey_enum_list[] = {
{ CKMODE_DISABLE, "disabled" },
{ CKMODE_Y, "Y component" },
{ CKMODE_U, "U component" },
@@ -460,6 +460,7 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
&armada_ovl_plane_funcs,
armada_ovl_formats,
ARRAY_SIZE(armada_ovl_formats),
+ NULL,
DRM_PLANE_TYPE_OVERLAY, NULL);
if (ret) {
kfree(dplane);
diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c
index 76f07f38b941..749646ae365f 100644
--- a/drivers/gpu/drm/ast/ast_dp501.c
+++ b/drivers/gpu/drm/ast/ast_dp501.c
@@ -4,16 +4,11 @@
#include "ast_drv.h"
MODULE_FIRMWARE("ast_dp501_fw.bin");
-int ast_load_dp501_microcode(struct drm_device *dev)
+static int ast_load_dp501_microcode(struct drm_device *dev)
{
struct ast_private *ast = dev->dev_private;
- static char *fw_name = "ast_dp501_fw.bin";
- int err;
- err = request_firmware(&ast->dp501_fw, fw_name, dev->dev);
- if (err)
- return err;
- return 0;
+ return request_firmware(&ast->dp501_fw, "ast_dp501_fw.bin", dev->dev);
}
static void send_ack(struct ast_private *ast)
@@ -187,7 +182,7 @@ bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size)
return false;
}
-bool ast_launch_m68k(struct drm_device *dev)
+static bool ast_launch_m68k(struct drm_device *dev)
{
struct ast_private *ast = dev->dev_private;
u32 i, data, len = 0;
@@ -201,7 +196,11 @@ bool ast_launch_m68k(struct drm_device *dev)
if (ast->dp501_fw_addr) {
fw_addr = ast->dp501_fw_addr;
len = 32*1024;
- } else if (ast->dp501_fw) {
+ } else {
+ if (!ast->dp501_fw &&
+ ast_load_dp501_microcode(dev) < 0)
+ return false;
+
fw_addr = (u8 *)ast->dp501_fw->data;
len = ast->dp501_fw->size;
}
@@ -432,3 +431,11 @@ void ast_init_3rdtx(struct drm_device *dev)
}
}
}
+
+void ast_release_firmware(struct drm_device *dev)
+{
+ struct ast_private *ast = dev->dev_private;
+
+ release_firmware(ast->dp501_fw);
+ ast->dp501_fw = NULL;
+}
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index fd7c9eec92e4..69dab82a3771 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -197,7 +197,6 @@ static struct drm_driver driver = {
.load = ast_driver_load,
.unload = ast_driver_unload,
- .set_busid = drm_pci_set_busid,
.fops = &ast_fops,
.name = DRIVER_NAME,
@@ -210,7 +209,6 @@ static struct drm_driver driver = {
.gem_free_object_unlocked = ast_gem_free_object,
.dumb_create = ast_dumb_create,
.dumb_map_offset = ast_dumb_mmap_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
};
@@ -221,11 +219,11 @@ static int __init ast_init(void)
if (ast_modeset == 0)
return -EINVAL;
- return drm_pci_init(&driver, &ast_pci_driver);
+ return pci_register_driver(&ast_pci_driver);
}
static void __exit ast_exit(void)
{
- drm_pci_exit(&driver, &ast_pci_driver);
+ pci_unregister_driver(&ast_pci_driver);
}
module_init(ast_init);
diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
index 8880f0b62e9c..e6c4cd3dc50e 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -245,7 +245,6 @@ struct ast_connector {
struct ast_crtc {
struct drm_crtc base;
- u8 lut_r[256], lut_g[256], lut_b[256];
struct drm_gem_object *cursor_bo;
uint64_t cursor_addr;
int cursor_width, cursor_height;
@@ -401,11 +400,10 @@ void ast_post_gpu(struct drm_device *dev);
u32 ast_mindwm(struct ast_private *ast, u32 r);
void ast_moutdwm(struct ast_private *ast, u32 r, u32 v);
/* ast dp501 */
-int ast_load_dp501_microcode(struct drm_device *dev);
void ast_set_dp501_video_output(struct drm_device *dev, u8 mode);
-bool ast_launch_m68k(struct drm_device *dev);
bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size);
bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata);
u8 ast_get_dp501_max_clk(struct drm_device *dev);
void ast_init_3rdtx(struct drm_device *dev);
+void ast_release_firmware(struct drm_device *dev);
#endif
diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c
index 4ad4acd0ccab..0cd827e11fa2 100644
--- a/drivers/gpu/drm/ast/ast_fb.c
+++ b/drivers/gpu/drm/ast/ast_fb.c
@@ -231,7 +231,6 @@ static int astfb_create(struct drm_fb_helper *helper,
strcpy(info->fix.id, "astdrmfb");
- info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &astfb_ops;
info->apertures->ranges[0].base = pci_resource_start(dev->pdev, 0);
@@ -255,27 +254,7 @@ out:
return ret;
}
-static void ast_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
- struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
- ast_crtc->lut_r[regno] = red >> 8;
- ast_crtc->lut_g[regno] = green >> 8;
- ast_crtc->lut_b[regno] = blue >> 8;
-}
-
-static void ast_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno)
-{
- struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
- *red = ast_crtc->lut_r[regno] << 8;
- *green = ast_crtc->lut_g[regno] << 8;
- *blue = ast_crtc->lut_b[regno] << 8;
-}
-
static const struct drm_fb_helper_funcs ast_fb_helper_funcs = {
- .gamma_set = ast_fb_gamma_set,
- .gamma_get = ast_fb_gamma_get,
.fb_probe = astfb_create,
};
@@ -287,7 +266,7 @@ static void ast_fbdev_destroy(struct drm_device *dev,
drm_fb_helper_unregister_fbi(&afbdev->helper);
if (afb->obj) {
- drm_gem_object_unreference_unlocked(afb->obj);
+ drm_gem_object_put_unlocked(afb->obj);
afb->obj = NULL;
}
drm_fb_helper_fini(&afbdev->helper);
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index 262c2c0e43b4..dac355812adc 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -387,9 +387,9 @@ static void ast_user_framebuffer_destroy(struct drm_framebuffer *fb)
{
struct ast_framebuffer *ast_fb = to_ast_framebuffer(fb);
- drm_gem_object_unreference_unlocked(ast_fb->obj);
+ drm_gem_object_put_unlocked(ast_fb->obj);
drm_framebuffer_cleanup(fb);
- kfree(fb);
+ kfree(ast_fb);
}
static const struct drm_framebuffer_funcs ast_fb_funcs = {
@@ -429,13 +429,13 @@ ast_user_framebuffer_create(struct drm_device *dev,
ast_fb = kzalloc(sizeof(*ast_fb), GFP_KERNEL);
if (!ast_fb) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(-ENOMEM);
}
ret = ast_framebuffer_init(dev, ast_fb, mode_cmd, obj);
if (ret) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
kfree(ast_fb);
return ERR_PTR(ret);
}
@@ -576,6 +576,7 @@ void ast_driver_unload(struct drm_device *dev)
{
struct ast_private *ast = dev->dev_private;
+ ast_release_firmware(dev);
kfree(ast->dp501_fw_addr);
ast_mode_fini(dev);
ast_fbdev_fini(dev);
@@ -627,7 +628,7 @@ int ast_dumb_create(struct drm_file *file,
return ret;
ret = drm_gem_handle_create(file, gobj, &handle);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (ret)
return ret;
@@ -675,7 +676,7 @@ ast_dumb_mmap_offset(struct drm_file *file,
bo = gem_to_ast_bo(obj);
*offset = ast_bo_mmap_offset(bo);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return 0;
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index aaef0a652f10..6f3849ec0c1d 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -63,15 +63,18 @@ static inline void ast_load_palette_index(struct ast_private *ast,
static void ast_crtc_load_lut(struct drm_crtc *crtc)
{
struct ast_private *ast = crtc->dev->dev_private;
- struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
+ u16 *r, *g, *b;
int i;
if (!crtc->enabled)
return;
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
+
for (i = 0; i < 256; i++)
- ast_load_palette_index(ast, i, ast_crtc->lut_r[i],
- ast_crtc->lut_g[i], ast_crtc->lut_b[i]);
+ ast_load_palette_index(ast, i, *r++ >> 8, *g++ >> 8, *b++ >> 8);
}
static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mode *mode,
@@ -613,7 +616,23 @@ static int ast_crtc_mode_set(struct drm_crtc *crtc,
static void ast_crtc_disable(struct drm_crtc *crtc)
{
+ int ret;
+ DRM_DEBUG_KMS("\n");
+ ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+ if (crtc->primary->fb) {
+ struct ast_framebuffer *ast_fb = to_ast_framebuffer(crtc->primary->fb);
+ struct drm_gem_object *obj = ast_fb->obj;
+ struct ast_bo *bo = gem_to_ast_bo(obj);
+
+ ret = ast_bo_reserve(bo, false);
+ if (ret)
+ return;
+
+ ast_bo_push_sysram(bo);
+ ast_bo_unreserve(bo);
+ }
+ crtc->primary->fb = NULL;
}
static void ast_crtc_prepare(struct drm_crtc *crtc)
@@ -633,7 +652,6 @@ static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
.mode_set = ast_crtc_mode_set,
.mode_set_base = ast_crtc_mode_set_base,
.disable = ast_crtc_disable,
- .load_lut = ast_crtc_load_lut,
.prepare = ast_crtc_prepare,
.commit = ast_crtc_commit,
@@ -648,15 +666,6 @@ static int ast_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
- int i;
-
- /* userspace palettes are always correct as is */
- for (i = 0; i < size; i++) {
- ast_crtc->lut_r[i] = red[i] >> 8;
- ast_crtc->lut_g[i] = green[i] >> 8;
- ast_crtc->lut_b[i] = blue[i] >> 8;
- }
ast_crtc_load_lut(crtc);
return 0;
@@ -681,7 +690,6 @@ static const struct drm_crtc_funcs ast_crtc_funcs = {
static int ast_crtc_init(struct drm_device *dev)
{
struct ast_crtc *crtc;
- int i;
crtc = kzalloc(sizeof(struct ast_crtc), GFP_KERNEL);
if (!crtc)
@@ -690,12 +698,6 @@ static int ast_crtc_init(struct drm_device *dev)
drm_crtc_init(dev, &crtc->base, &ast_crtc_funcs);
drm_mode_crtc_set_gamma_size(&crtc->base, 256);
drm_crtc_helper_add(&crtc->base, &ast_crtc_helper_funcs);
-
- for (i = 0; i < 256; i++) {
- crtc->lut_r[i] = i;
- crtc->lut_g[i] = i;
- crtc->lut_b[i] = i;
- }
return 0;
}
@@ -948,7 +950,7 @@ static void ast_cursor_fini(struct drm_device *dev)
{
struct ast_private *ast = dev->dev_private;
ttm_bo_kunmap(&ast->cache_kmap);
- drm_gem_object_unreference_unlocked(ast->cursor_cache);
+ drm_gem_object_put_unlocked(ast->cursor_cache);
}
int ast_mode_init(struct drm_device *dev)
@@ -1213,10 +1215,10 @@ static int ast_cursor_set(struct drm_crtc *crtc,
ast_show_cursor(crtc);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return 0;
fail:
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_ttm.c
index 58084985e6cf..696a15dc2f3f 100644
--- a/drivers/gpu/drm/ast/ast_ttm.c
+++ b/drivers/gpu/drm/ast/ast_ttm.c
@@ -323,10 +323,8 @@ int ast_bo_create(struct drm_device *dev, int size, int align,
return -ENOMEM;
ret = drm_gem_object_init(dev, &astbo->gem, size);
- if (ret) {
- kfree(astbo);
- return ret;
- }
+ if (ret)
+ goto error;
astbo->bo.bdev = &ast->ttm.bdev;
@@ -340,10 +338,13 @@ int ast_bo_create(struct drm_device *dev, int size, int align,
align >> PAGE_SHIFT, false, NULL, acc_size,
NULL, NULL, ast_bo_ttm_destroy);
if (ret)
- return ret;
+ goto error;
*pastbo = astbo;
return 0;
+error:
+ kfree(astbo);
+ return ret;
}
static inline u64 ast_bo_gpu_offset(struct ast_bo *bo)
@@ -376,7 +377,7 @@ int ast_bo_pin(struct ast_bo *bo, u32 pl_flag, u64 *gpu_addr)
int ast_bo_unpin(struct ast_bo *bo)
{
- int i, ret;
+ int i;
if (!bo->pin_count) {
DRM_ERROR("unpin bad %p\n", bo);
return 0;
@@ -387,11 +388,7 @@ int ast_bo_unpin(struct ast_bo *bo)
for (i = 0; i < bo->placement.num_placement ; i++)
bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
- ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false);
- if (ret)
- return ret;
-
- return 0;
+ return ttm_bo_validate(&bo->bo, &bo->placement, false, false);
}
int ast_bo_push_sysram(struct ast_bo *bo)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index 53489859997b..d73281095fac 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -149,7 +149,8 @@ atmel_hlcdc_crtc_mode_valid(struct drm_crtc *c,
return atmel_hlcdc_dc_mode_valid(crtc->dc, mode);
}
-static void atmel_hlcdc_crtc_disable(struct drm_crtc *c)
+static void atmel_hlcdc_crtc_atomic_disable(struct drm_crtc *c,
+ struct drm_crtc_state *old_state)
{
struct drm_device *dev = c->dev;
struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c);
@@ -183,7 +184,8 @@ static void atmel_hlcdc_crtc_disable(struct drm_crtc *c)
pm_runtime_put_sync(dev->dev);
}
-static void atmel_hlcdc_crtc_enable(struct drm_crtc *c)
+static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c,
+ struct drm_crtc_state *old_state)
{
struct drm_device *dev = c->dev;
struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c);
@@ -235,7 +237,7 @@ static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
crtc = drm_crtc_to_atmel_hlcdc_crtc(state->crtc);
- for_each_connector_in_state(state->state, connector, cstate, i) {
+ for_each_new_connector_in_state(state->state, connector, cstate, i) {
struct drm_display_info *info = &connector->display_info;
unsigned int supported_fmts = 0;
int j;
@@ -319,11 +321,11 @@ static const struct drm_crtc_helper_funcs lcdc_crtc_helper_funcs = {
.mode_set = drm_helper_crtc_mode_set,
.mode_set_nofb = atmel_hlcdc_crtc_mode_set_nofb,
.mode_set_base = drm_helper_crtc_mode_set_base,
- .disable = atmel_hlcdc_crtc_disable,
- .enable = atmel_hlcdc_crtc_enable,
.atomic_check = atmel_hlcdc_crtc_atomic_check,
.atomic_begin = atmel_hlcdc_crtc_atomic_begin,
.atomic_flush = atmel_hlcdc_crtc_atomic_flush,
+ .atomic_enable = atmel_hlcdc_crtc_atomic_enable,
+ .atomic_disable = atmel_hlcdc_crtc_atomic_disable,
};
static void atmel_hlcdc_crtc_destroy(struct drm_crtc *c)
@@ -429,6 +431,7 @@ static const struct drm_crtc_funcs atmel_hlcdc_crtc_funcs = {
.atomic_destroy_state = atmel_hlcdc_crtc_destroy_state,
.enable_vblank = atmel_hlcdc_crtc_enable_vblank,
.disable_vblank = atmel_hlcdc_crtc_disable_vblank,
+ .gamma_set = drm_atomic_helper_legacy_gamma_set,
};
int atmel_hlcdc_crtc_create(struct drm_device *dev)
@@ -484,6 +487,10 @@ int atmel_hlcdc_crtc_create(struct drm_device *dev)
drm_crtc_helper_add(&crtc->base, &lcdc_crtc_helper_funcs);
drm_crtc_vblank_reset(&crtc->base);
+ drm_mode_crtc_set_gamma_size(&crtc->base, ATMEL_HLCDC_CLUT_SIZE);
+ drm_crtc_enable_color_mgmt(&crtc->base, 0, false,
+ ATMEL_HLCDC_CLUT_SIZE);
+
dc->crtc = &crtc->base;
return 0;
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index 30dbffdb45a3..74d66e11f688 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -42,6 +42,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9n12_layers[] = {
.default_color = 3,
.general_config = 4,
},
+ .clut_offset = 0x400,
},
};
@@ -73,6 +74,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
.disc_pos = 5,
.disc_size = 6,
},
+ .clut_offset = 0x400,
},
{
.name = "overlay1",
@@ -91,6 +93,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
.chroma_key_mask = 8,
.general_config = 9,
},
+ .clut_offset = 0x800,
},
{
.name = "high-end-overlay",
@@ -112,6 +115,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
.scaler_config = 13,
.csc = 14,
},
+ .clut_offset = 0x1000,
},
{
.name = "cursor",
@@ -131,6 +135,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
.chroma_key_mask = 8,
.general_config = 9,
},
+ .clut_offset = 0x1400,
},
};
@@ -162,6 +167,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.disc_pos = 5,
.disc_size = 6,
},
+ .clut_offset = 0x600,
},
{
.name = "overlay1",
@@ -180,6 +186,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.chroma_key_mask = 8,
.general_config = 9,
},
+ .clut_offset = 0xa00,
},
{
.name = "overlay2",
@@ -198,6 +205,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.chroma_key_mask = 8,
.general_config = 9,
},
+ .clut_offset = 0xe00,
},
{
.name = "high-end-overlay",
@@ -223,6 +231,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
},
.csc = 14,
},
+ .clut_offset = 0x1200,
},
{
.name = "cursor",
@@ -244,6 +253,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.general_config = 9,
.scaler_config = 13,
},
+ .clut_offset = 0x1600,
},
};
@@ -275,6 +285,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
.disc_pos = 5,
.disc_size = 6,
},
+ .clut_offset = 0x600,
},
{
.name = "overlay1",
@@ -293,6 +304,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
.chroma_key_mask = 8,
.general_config = 9,
},
+ .clut_offset = 0xa00,
},
{
.name = "overlay2",
@@ -311,6 +323,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
.chroma_key_mask = 8,
.general_config = 9,
},
+ .clut_offset = 0xe00,
},
{
.name = "high-end-overlay",
@@ -336,6 +349,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
},
.csc = 14,
},
+ .clut_offset = 0x1200,
},
};
@@ -451,8 +465,7 @@ static void atmel_hlcdc_fb_output_poll_changed(struct drm_device *dev)
{
struct atmel_hlcdc_dc *dc = dev->dev_private;
- if (dc->fbdev)
- drm_fbdev_cma_hotplug_event(dc->fbdev);
+ drm_fbdev_cma_hotplug_event(dc->fbdev);
}
struct atmel_hlcdc_dc_commit {
@@ -526,14 +539,13 @@ static int atmel_hlcdc_dc_atomic_commit(struct drm_device *dev,
dc->commit.pending = true;
spin_unlock(&dc->commit.wait.lock);
- if (ret) {
- kfree(commit);
- goto error;
- }
+ if (ret)
+ goto err_free;
- /* Swap the state, this is the point of no return. */
- drm_atomic_helper_swap_state(state, true);
+ /* We have our own synchronization through the commit lock. */
+ BUG_ON(drm_atomic_helper_swap_state(state, false) < 0);
+ /* Swap state succeeded, this is the point of no return. */
drm_atomic_state_get(state);
if (async)
queue_work(dc->wq, &commit->work);
@@ -542,6 +554,8 @@ static int atmel_hlcdc_dc_atomic_commit(struct drm_device *dev,
return 0;
+err_free:
+ kfree(commit);
error:
drm_atomic_helper_cleanup_planes(dev, state);
return ret;
@@ -747,8 +761,6 @@ static struct drm_driver atmel_hlcdc_dc_driver = {
.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
.gem_prime_mmap = drm_gem_cma_prime_mmap,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.fops = &fops,
.name = "atmel-hlcdc",
.desc = "Atmel HLCD Controller DRM",
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
index b0596a84c1b8..4237b0446721 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
@@ -88,6 +88,11 @@
#define ATMEL_HLCDC_YUV422SWP BIT(17)
#define ATMEL_HLCDC_DSCALEOPT BIT(20)
+#define ATMEL_HLCDC_C1_MODE ATMEL_HLCDC_CLUT_MODE(0)
+#define ATMEL_HLCDC_C2_MODE ATMEL_HLCDC_CLUT_MODE(1)
+#define ATMEL_HLCDC_C4_MODE ATMEL_HLCDC_CLUT_MODE(2)
+#define ATMEL_HLCDC_C8_MODE ATMEL_HLCDC_CLUT_MODE(3)
+
#define ATMEL_HLCDC_XRGB4444_MODE ATMEL_HLCDC_RGB_MODE(0)
#define ATMEL_HLCDC_ARGB4444_MODE ATMEL_HLCDC_RGB_MODE(1)
#define ATMEL_HLCDC_RGBA4444_MODE ATMEL_HLCDC_RGB_MODE(2)
@@ -142,6 +147,8 @@
#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE BIT(2)
#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_OVERRUN BIT(3)
+#define ATMEL_HLCDC_CLUT_SIZE 256
+
#define ATMEL_HLCDC_MAX_LAYERS 6
/**
@@ -259,6 +266,7 @@ struct atmel_hlcdc_layer_desc {
int id;
int regs_offset;
int cfgs_offset;
+ int clut_offset;
struct atmel_hlcdc_formats *formats;
struct atmel_hlcdc_layer_cfg_layout layout;
int max_width;
@@ -414,6 +422,14 @@ static inline u32 atmel_hlcdc_layer_read_cfg(struct atmel_hlcdc_layer *layer,
(cfgid * sizeof(u32)));
}
+static inline void atmel_hlcdc_layer_write_clut(struct atmel_hlcdc_layer *layer,
+ unsigned int c, u32 val)
+{
+ regmap_write(layer->regmap,
+ layer->desc->clut_offset + c * sizeof(u32),
+ val);
+}
+
static inline void atmel_hlcdc_layer_init(struct atmel_hlcdc_layer *layer,
const struct atmel_hlcdc_layer_desc *desc,
struct regmap *regmap)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index 1124200bb280..703c2d13603f 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -83,6 +83,7 @@ drm_plane_state_to_atmel_hlcdc_plane_state(struct drm_plane_state *s)
#define SUBPIXEL_MASK 0xffff
static uint32_t rgb_formats[] = {
+ DRM_FORMAT_C8,
DRM_FORMAT_XRGB4444,
DRM_FORMAT_ARGB4444,
DRM_FORMAT_RGBA4444,
@@ -100,6 +101,7 @@ struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_formats = {
};
static uint32_t rgb_and_yuv_formats[] = {
+ DRM_FORMAT_C8,
DRM_FORMAT_XRGB4444,
DRM_FORMAT_ARGB4444,
DRM_FORMAT_RGBA4444,
@@ -128,6 +130,9 @@ struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_and_yuv_formats = {
static int atmel_hlcdc_format_to_plane_mode(u32 format, u32 *mode)
{
switch (format) {
+ case DRM_FORMAT_C8:
+ *mode = ATMEL_HLCDC_C8_MODE;
+ break;
case DRM_FORMAT_XRGB4444:
*mode = ATMEL_HLCDC_XRGB4444_MODE;
break;
@@ -424,6 +429,29 @@ static void atmel_hlcdc_plane_update_format(struct atmel_hlcdc_plane *plane,
ATMEL_HLCDC_LAYER_FORMAT_CFG, cfg);
}
+static void atmel_hlcdc_plane_update_clut(struct atmel_hlcdc_plane *plane)
+{
+ struct drm_crtc *crtc = plane->base.crtc;
+ struct drm_color_lut *lut;
+ int idx;
+
+ if (!crtc || !crtc->state)
+ return;
+
+ if (!crtc->state->color_mgmt_changed || !crtc->state->gamma_lut)
+ return;
+
+ lut = (struct drm_color_lut *)crtc->state->gamma_lut->data;
+
+ for (idx = 0; idx < ATMEL_HLCDC_CLUT_SIZE; idx++, lut++) {
+ u32 val = ((lut->red << 8) & 0xff0000) |
+ (lut->green & 0xff00) |
+ (lut->blue >> 8);
+
+ atmel_hlcdc_layer_write_clut(&plane->layer, idx, val);
+ }
+}
+
static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
struct atmel_hlcdc_plane_state *state)
{
@@ -768,6 +796,7 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
atmel_hlcdc_plane_update_pos_and_size(plane, state);
atmel_hlcdc_plane_update_general_settings(plane, state);
atmel_hlcdc_plane_update_format(plane, state);
+ atmel_hlcdc_plane_update_clut(plane);
atmel_hlcdc_plane_update_buffers(plane, state);
atmel_hlcdc_plane_update_disc_area(plane, state);
@@ -809,7 +838,7 @@ static void atmel_hlcdc_plane_destroy(struct drm_plane *p)
struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
if (plane->base.fb)
- drm_framebuffer_unreference(plane->base.fb);
+ drm_framebuffer_put(plane->base.fb);
drm_plane_cleanup(p);
}
@@ -911,7 +940,7 @@ void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
desc->name);
}
-static struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = {
+static const struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = {
.atomic_check = atmel_hlcdc_plane_atomic_check,
.atomic_update = atmel_hlcdc_plane_atomic_update,
.atomic_disable = atmel_hlcdc_plane_atomic_disable,
@@ -958,7 +987,7 @@ static void atmel_hlcdc_plane_reset(struct drm_plane *p)
state = drm_plane_state_to_atmel_hlcdc_plane_state(p->state);
if (state->base.fb)
- drm_framebuffer_unreference(state->base.fb);
+ drm_framebuffer_put(state->base.fb);
kfree(state);
p->state = NULL;
@@ -996,7 +1025,7 @@ atmel_hlcdc_plane_atomic_duplicate_state(struct drm_plane *p)
}
if (copy->base.fb)
- drm_framebuffer_reference(copy->base.fb);
+ drm_framebuffer_get(copy->base.fb);
return &copy->base;
}
@@ -1015,15 +1044,14 @@ static void atmel_hlcdc_plane_atomic_destroy_state(struct drm_plane *p,
}
if (s->fb)
- drm_framebuffer_unreference(s->fb);
+ drm_framebuffer_put(s->fb);
kfree(state);
}
-static struct drm_plane_funcs layer_plane_funcs = {
+static const struct drm_plane_funcs layer_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
- .set_property = drm_atomic_helper_plane_set_property,
.destroy = atmel_hlcdc_plane_destroy,
.reset = atmel_hlcdc_plane_reset,
.atomic_duplicate_state = atmel_hlcdc_plane_atomic_duplicate_state,
@@ -1058,7 +1086,8 @@ static int atmel_hlcdc_plane_create(struct drm_device *dev,
ret = drm_universal_plane_init(dev, &plane->base, 0,
&layer_plane_funcs,
desc->formats->formats,
- desc->formats->nformats, type, NULL);
+ desc->formats->nformats,
+ NULL, type, NULL);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c
index aa342515ddf4..7b20318483e4 100644
--- a/drivers/gpu/drm/bochs/bochs_drv.c
+++ b/drivers/gpu/drm/bochs/bochs_drv.c
@@ -84,7 +84,6 @@ static struct drm_driver bochs_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET,
.load = bochs_load,
.unload = bochs_unload,
- .set_busid = drm_pci_set_busid,
.fops = &bochs_fops,
.name = "bochs-drm",
.desc = "bochs dispi vga interface (qemu stdvga)",
@@ -94,7 +93,6 @@ static struct drm_driver bochs_driver = {
.gem_free_object_unlocked = bochs_gem_free_object,
.dumb_create = bochs_dumb_create,
.dumb_map_offset = bochs_dumb_mmap_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
};
/* ---------------------------------------------------------------------- */
@@ -224,12 +222,12 @@ static int __init bochs_init(void)
if (bochs_modeset == 0)
return -EINVAL;
- return drm_pci_init(&bochs_driver, &bochs_pci_driver);
+ return pci_register_driver(&bochs_pci_driver);
}
static void __exit bochs_exit(void)
{
- drm_pci_exit(&bochs_driver, &bochs_pci_driver);
+ pci_unregister_driver(&bochs_pci_driver);
}
module_init(bochs_init);
diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c
index c38deffa14de..14eb8d0d5a00 100644
--- a/drivers/gpu/drm/bochs/bochs_fbdev.c
+++ b/drivers/gpu/drm/bochs/bochs_fbdev.c
@@ -23,9 +23,9 @@ static int bochsfb_mmap(struct fb_info *info,
static struct fb_ops bochsfb_ops = {
.owner = THIS_MODULE,
DRM_FB_HELPER_DEFAULT_OPS,
- .fb_fillrect = drm_fb_helper_sys_fillrect,
- .fb_copyarea = drm_fb_helper_sys_copyarea,
- .fb_imageblit = drm_fb_helper_sys_imageblit,
+ .fb_fillrect = drm_fb_helper_cfb_fillrect,
+ .fb_copyarea = drm_fb_helper_cfb_copyarea,
+ .fb_imageblit = drm_fb_helper_cfb_imageblit,
.fb_mmap = bochsfb_mmap,
};
@@ -118,7 +118,6 @@ static int bochsfb_create(struct drm_fb_helper *helper,
strcpy(info->fix.id, "bochsdrmfb");
- info->flags = FBINFO_DEFAULT;
info->fbops = &bochsfb_ops;
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index f75ab6278113..b2431aee7887 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -785,8 +785,7 @@ adv7511_connector_detect(struct drm_connector *connector, bool force)
return adv7511_detect(adv, connector);
}
-static struct drm_connector_funcs adv7511_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
+static const struct drm_connector_funcs adv7511_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = adv7511_connector_detect,
.destroy = drm_connector_cleanup,
@@ -857,7 +856,7 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge)
return ret;
}
-static struct drm_bridge_funcs adv7511_bridge_funcs = {
+static const struct drm_bridge_funcs adv7511_bridge_funcs = {
.enable = adv7511_bridge_enable,
.disable = adv7511_bridge_disable,
.mode_set = adv7511_bridge_mode_set,
@@ -1126,11 +1125,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
adv7511->bridge.funcs = &adv7511_bridge_funcs;
adv7511->bridge.of_node = dev->of_node;
- ret = drm_bridge_add(&adv7511->bridge);
- if (ret) {
- dev_err(dev, "failed to add adv7511 bridge\n");
- goto err_unregister_cec;
- }
+ drm_bridge_add(&adv7511->bridge);
adv7511_audio_init(dev, adv7511);
diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix-anx78xx.c
index 9006578b9789..9385eb0b1ee4 100644
--- a/drivers/gpu/drm/bridge/analogix-anx78xx.c
+++ b/drivers/gpu/drm/bridge/analogix-anx78xx.c
@@ -1002,7 +1002,6 @@ static enum drm_connector_status anx78xx_detect(struct drm_connector *connector,
}
static const struct drm_connector_funcs anx78xx_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = anx78xx_detect,
.destroy = drm_connector_cleanup,
@@ -1097,7 +1096,8 @@ static void anx78xx_bridge_mode_set(struct drm_bridge *bridge,
mutex_lock(&anx78xx->lock);
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, adjusted_mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, adjusted_mode,
+ false);
if (err) {
DRM_ERROR("Failed to setup AVI infoframe: %d\n", err);
goto unlock;
@@ -1438,11 +1438,7 @@ static int anx78xx_i2c_probe(struct i2c_client *client,
anx78xx->bridge.funcs = &anx78xx_bridge_funcs;
- err = drm_bridge_add(&anx78xx->bridge);
- if (err < 0) {
- DRM_ERROR("Failed to add drm bridge: %d\n", err);
- goto err_poweroff;
- }
+ drm_bridge_add(&anx78xx->bridge);
/* If cable is pulled out, just poweroff and wait for HPD event */
if (!gpiod_get_value(anx78xx->pdata.gpiod_hpd))
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 4c758ed51939..5dd3f1cd074a 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1005,7 +1005,6 @@ analogix_dp_detect(struct drm_connector *connector, bool force)
}
static const struct drm_connector_funcs analogix_dp_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = analogix_dp_detect,
.destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c b/drivers/gpu/drm/bridge/dumb-vga-dac.c
index 831a606c4706..de5e7dee7ad6 100644
--- a/drivers/gpu/drm/bridge/dumb-vga-dac.c
+++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c
@@ -92,7 +92,6 @@ dumb_vga_connector_detect(struct drm_connector *connector, bool force)
}
static const struct drm_connector_funcs dumb_vga_con_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = dumb_vga_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
@@ -177,7 +176,6 @@ static struct i2c_adapter *dumb_vga_retrieve_ddc(struct device *dev)
static int dumb_vga_probe(struct platform_device *pdev)
{
struct dumb_vga *vga;
- int ret;
vga = devm_kzalloc(&pdev->dev, sizeof(*vga), GFP_KERNEL);
if (!vga)
@@ -186,7 +184,7 @@ static int dumb_vga_probe(struct platform_device *pdev)
vga->vdd = devm_regulator_get_optional(&pdev->dev, "vdd");
if (IS_ERR(vga->vdd)) {
- ret = PTR_ERR(vga->vdd);
+ int ret = PTR_ERR(vga->vdd);
if (ret == -EPROBE_DEFER)
return -EPROBE_DEFER;
vga->vdd = NULL;
@@ -207,11 +205,9 @@ static int dumb_vga_probe(struct platform_device *pdev)
vga->bridge.funcs = &dumb_vga_bridge_funcs;
vga->bridge.of_node = pdev->dev.of_node;
- ret = drm_bridge_add(&vga->bridge);
- if (ret && !IS_ERR(vga->ddc))
- i2c_put_adapter(vga->ddc);
+ drm_bridge_add(&vga->bridge);
- return ret;
+ return 0;
}
static int dumb_vga_remove(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
index 11f11086a68f..7ccadba7c98c 100644
--- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
+++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
@@ -193,7 +193,6 @@ static enum drm_connector_status ge_b850v3_lvds_detect(
}
static const struct drm_connector_funcs ge_b850v3_lvds_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = ge_b850v3_lvds_detect,
.destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/bridge/nxp-ptn3460.c b/drivers/gpu/drm/bridge/nxp-ptn3460.c
index 4f64e717e01b..d64a3283822a 100644
--- a/drivers/gpu/drm/bridge/nxp-ptn3460.c
+++ b/drivers/gpu/drm/bridge/nxp-ptn3460.c
@@ -238,7 +238,6 @@ static const struct drm_connector_helper_funcs ptn3460_connector_helper_funcs =
};
static const struct drm_connector_funcs ptn3460_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
@@ -332,11 +331,7 @@ static int ptn3460_probe(struct i2c_client *client,
ptn_bridge->bridge.funcs = &ptn3460_bridge_funcs;
ptn_bridge->bridge.of_node = dev->of_node;
- ret = drm_bridge_add(&ptn_bridge->bridge);
- if (ret) {
- DRM_ERROR("Failed to add bridge\n");
- return ret;
- }
+ drm_bridge_add(&ptn_bridge->bridge);
i2c_set_clientdata(client, ptn_bridge);
diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
index 67fe19e5a9c6..e0cca19b4044 100644
--- a/drivers/gpu/drm/bridge/panel.c
+++ b/drivers/gpu/drm/bridge/panel.c
@@ -50,7 +50,6 @@ panel_bridge_connector_helper_funcs = {
};
static const struct drm_connector_funcs panel_bridge_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
@@ -158,7 +157,6 @@ struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel,
u32 connector_type)
{
struct panel_bridge *panel_bridge;
- int ret;
if (!panel)
return ERR_PTR(-EINVAL);
@@ -176,9 +174,7 @@ struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel,
panel_bridge->bridge.of_node = panel->dev->of_node;
#endif
- ret = drm_bridge_add(&panel_bridge->bridge);
- if (ret)
- return ERR_PTR(ret);
+ drm_bridge_add(&panel_bridge->bridge);
return &panel_bridge->bridge;
}
@@ -198,3 +194,33 @@ void drm_panel_bridge_remove(struct drm_bridge *bridge)
devm_kfree(panel_bridge->panel->dev, bridge);
}
EXPORT_SYMBOL(drm_panel_bridge_remove);
+
+static void devm_drm_panel_bridge_release(struct device *dev, void *res)
+{
+ struct drm_bridge **bridge = res;
+
+ drm_panel_bridge_remove(*bridge);
+}
+
+struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev,
+ struct drm_panel *panel,
+ u32 connector_type)
+{
+ struct drm_bridge **ptr, *bridge;
+
+ ptr = devres_alloc(devm_drm_panel_bridge_release, sizeof(*ptr),
+ GFP_KERNEL);
+ if (!ptr)
+ return ERR_PTR(-ENOMEM);
+
+ bridge = drm_panel_bridge_add(panel, connector_type);
+ if (!IS_ERR(bridge)) {
+ *ptr = bridge;
+ devres_add(dev, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return bridge;
+}
+EXPORT_SYMBOL(devm_drm_panel_bridge_add);
diff --git a/drivers/gpu/drm/bridge/parade-ps8622.c b/drivers/gpu/drm/bridge/parade-ps8622.c
index 6f22f9fec9bf..81198f5e9afa 100644
--- a/drivers/gpu/drm/bridge/parade-ps8622.c
+++ b/drivers/gpu/drm/bridge/parade-ps8622.c
@@ -476,7 +476,6 @@ static const struct drm_connector_helper_funcs ps8622_connector_helper_funcs = {
};
static const struct drm_connector_funcs ps8622_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
@@ -598,11 +597,7 @@ static int ps8622_probe(struct i2c_client *client,
ps8622->bridge.funcs = &ps8622_bridge_funcs;
ps8622->bridge.of_node = dev->of_node;
- ret = drm_bridge_add(&ps8622->bridge);
- if (ret) {
- DRM_ERROR("Failed to add bridge\n");
- return ret;
- }
+ drm_bridge_add(&ps8622->bridge);
i2c_set_clientdata(client, ps8622);
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
index 9b87067c022c..b1ab4ab09532 100644
--- a/drivers/gpu/drm/bridge/sii902x.c
+++ b/drivers/gpu/drm/bridge/sii902x.c
@@ -124,7 +124,6 @@ sii902x_connector_detect(struct drm_connector *connector, bool force)
}
static const struct drm_connector_funcs sii902x_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = sii902x_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
@@ -269,7 +268,7 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge,
if (ret)
return;
- ret = drm_hdmi_avi_infoframe_from_display_mode(&frame, adj);
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame, adj, false);
if (ret < 0) {
DRM_ERROR("couldn't fill AVI infoframe\n");
return;
@@ -418,11 +417,7 @@ static int sii902x_probe(struct i2c_client *client,
sii902x->bridge.funcs = &sii902x_bridge_funcs;
sii902x->bridge.of_node = dev->of_node;
- ret = drm_bridge_add(&sii902x->bridge);
- if (ret) {
- dev_err(dev, "Failed to add drm_bridge\n");
- return ret;
- }
+ drm_bridge_add(&sii902x->bridge);
i2c_set_clientdata(client, sii902x);
diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig
index 53e78d092d18..3cc53b44186e 100644
--- a/drivers/gpu/drm/bridge/synopsys/Kconfig
+++ b/drivers/gpu/drm/bridge/synopsys/Kconfig
@@ -2,6 +2,7 @@ config DRM_DW_HDMI
tristate
select DRM_KMS_HELPER
select REGMAP_MMIO
+ select CEC_CORE if CEC_NOTIFIER
config DRM_DW_HDMI_AHB_AUDIO
tristate "Synopsys Designware AHB Audio interface"
@@ -22,3 +23,18 @@ config DRM_DW_HDMI_I2S_AUDIO
help
Support the I2S Audio interface which is part of the Synopsys
Designware HDMI block.
+
+config DRM_DW_HDMI_CEC
+ tristate "Synopsis Designware CEC interface"
+ depends on DRM_DW_HDMI
+ select CEC_CORE
+ select CEC_NOTIFIER
+ help
+ Support the CE interface which is part of the Synopsys
+ Designware HDMI block.
+
+config DRM_DW_MIPI_DSI
+ tristate
+ select DRM_KMS_HELPER
+ select DRM_MIPI_DSI
+ select DRM_PANEL_BRIDGE
diff --git a/drivers/gpu/drm/bridge/synopsys/Makefile b/drivers/gpu/drm/bridge/synopsys/Makefile
index 17aa7a65b57e..5dad97d920be 100644
--- a/drivers/gpu/drm/bridge/synopsys/Makefile
+++ b/drivers/gpu/drm/bridge/synopsys/Makefile
@@ -3,3 +3,6 @@
obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw-hdmi-i2s-audio.o
+obj-$(CONFIG_DRM_DW_HDMI_CEC) += dw-hdmi-cec.o
+
+obj-$(CONFIG_DRM_DW_MIPI_DSI) += dw-mipi-dsi.o
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
index 8f2d1379c880..cf3f0caf9c63 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
@@ -517,7 +517,7 @@ static snd_pcm_uframes_t dw_hdmi_pointer(struct snd_pcm_substream *substream)
return bytes_to_frames(runtime, dw->buf_offset);
}
-static struct snd_pcm_ops snd_dw_hdmi_ops = {
+static const struct snd_pcm_ops snd_dw_hdmi_ops = {
.open = dw_hdmi_open,
.close = dw_hdmi_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
new file mode 100644
index 000000000000..6c323510f128
--- /dev/null
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
@@ -0,0 +1,327 @@
+/*
+ * Designware HDMI CEC driver
+ *
+ * Copyright (C) 2015-2017 Russell King.
+ *
+ * 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 <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include <drm/drm_edid.h>
+
+#include <media/cec.h>
+#include <media/cec-notifier.h>
+
+#include "dw-hdmi-cec.h"
+
+enum {
+ HDMI_IH_CEC_STAT0 = 0x0106,
+ HDMI_IH_MUTE_CEC_STAT0 = 0x0186,
+
+ HDMI_CEC_CTRL = 0x7d00,
+ CEC_CTRL_START = BIT(0),
+ CEC_CTRL_FRAME_TYP = 3 << 1,
+ CEC_CTRL_RETRY = 0 << 1,
+ CEC_CTRL_NORMAL = 1 << 1,
+ CEC_CTRL_IMMED = 2 << 1,
+
+ HDMI_CEC_STAT = 0x7d01,
+ CEC_STAT_DONE = BIT(0),
+ CEC_STAT_EOM = BIT(1),
+ CEC_STAT_NACK = BIT(2),
+ CEC_STAT_ARBLOST = BIT(3),
+ CEC_STAT_ERROR_INIT = BIT(4),
+ CEC_STAT_ERROR_FOLL = BIT(5),
+ CEC_STAT_WAKEUP = BIT(6),
+
+ HDMI_CEC_MASK = 0x7d02,
+ HDMI_CEC_POLARITY = 0x7d03,
+ HDMI_CEC_INT = 0x7d04,
+ HDMI_CEC_ADDR_L = 0x7d05,
+ HDMI_CEC_ADDR_H = 0x7d06,
+ HDMI_CEC_TX_CNT = 0x7d07,
+ HDMI_CEC_RX_CNT = 0x7d08,
+ HDMI_CEC_TX_DATA0 = 0x7d10,
+ HDMI_CEC_RX_DATA0 = 0x7d20,
+ HDMI_CEC_LOCK = 0x7d30,
+ HDMI_CEC_WKUPCTRL = 0x7d31,
+};
+
+struct dw_hdmi_cec {
+ struct dw_hdmi *hdmi;
+ const struct dw_hdmi_cec_ops *ops;
+ u32 addresses;
+ struct cec_adapter *adap;
+ struct cec_msg rx_msg;
+ unsigned int tx_status;
+ bool tx_done;
+ bool rx_done;
+ struct cec_notifier *notify;
+ int irq;
+};
+
+static void dw_hdmi_write(struct dw_hdmi_cec *cec, u8 val, int offset)
+{
+ cec->ops->write(cec->hdmi, val, offset);
+}
+
+static u8 dw_hdmi_read(struct dw_hdmi_cec *cec, int offset)
+{
+ return cec->ops->read(cec->hdmi, offset);
+}
+
+static int dw_hdmi_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
+{
+ struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
+
+ if (logical_addr == CEC_LOG_ADDR_INVALID)
+ cec->addresses = 0;
+ else
+ cec->addresses |= BIT(logical_addr) | BIT(15);
+
+ dw_hdmi_write(cec, cec->addresses & 255, HDMI_CEC_ADDR_L);
+ dw_hdmi_write(cec, cec->addresses >> 8, HDMI_CEC_ADDR_H);
+
+ return 0;
+}
+
+static int dw_hdmi_cec_transmit(struct cec_adapter *adap, u8 attempts,
+ u32 signal_free_time, struct cec_msg *msg)
+{
+ struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
+ unsigned int i, ctrl;
+
+ switch (signal_free_time) {
+ case CEC_SIGNAL_FREE_TIME_RETRY:
+ ctrl = CEC_CTRL_RETRY;
+ break;
+ case CEC_SIGNAL_FREE_TIME_NEW_INITIATOR:
+ default:
+ ctrl = CEC_CTRL_NORMAL;
+ break;
+ case CEC_SIGNAL_FREE_TIME_NEXT_XFER:
+ ctrl = CEC_CTRL_IMMED;
+ break;
+ }
+
+ for (i = 0; i < msg->len; i++)
+ dw_hdmi_write(cec, msg->msg[i], HDMI_CEC_TX_DATA0 + i);
+
+ dw_hdmi_write(cec, msg->len, HDMI_CEC_TX_CNT);
+ dw_hdmi_write(cec, ctrl | CEC_CTRL_START, HDMI_CEC_CTRL);
+
+ return 0;
+}
+
+static irqreturn_t dw_hdmi_cec_hardirq(int irq, void *data)
+{
+ struct cec_adapter *adap = data;
+ struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
+ unsigned int stat = dw_hdmi_read(cec, HDMI_IH_CEC_STAT0);
+ irqreturn_t ret = IRQ_HANDLED;
+
+ if (stat == 0)
+ return IRQ_NONE;
+
+ dw_hdmi_write(cec, stat, HDMI_IH_CEC_STAT0);
+
+ if (stat & CEC_STAT_ERROR_INIT) {
+ cec->tx_status = CEC_TX_STATUS_ERROR;
+ cec->tx_done = true;
+ ret = IRQ_WAKE_THREAD;
+ } else if (stat & CEC_STAT_DONE) {
+ cec->tx_status = CEC_TX_STATUS_OK;
+ cec->tx_done = true;
+ ret = IRQ_WAKE_THREAD;
+ } else if (stat & CEC_STAT_NACK) {
+ cec->tx_status = CEC_TX_STATUS_NACK;
+ cec->tx_done = true;
+ ret = IRQ_WAKE_THREAD;
+ }
+
+ if (stat & CEC_STAT_EOM) {
+ unsigned int len, i;
+
+ len = dw_hdmi_read(cec, HDMI_CEC_RX_CNT);
+ if (len > sizeof(cec->rx_msg.msg))
+ len = sizeof(cec->rx_msg.msg);
+
+ for (i = 0; i < len; i++)
+ cec->rx_msg.msg[i] =
+ dw_hdmi_read(cec, HDMI_CEC_RX_DATA0 + i);
+
+ dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
+
+ cec->rx_msg.len = len;
+ smp_wmb();
+ cec->rx_done = true;
+
+ ret = IRQ_WAKE_THREAD;
+ }
+
+ return ret;
+}
+
+static irqreturn_t dw_hdmi_cec_thread(int irq, void *data)
+{
+ struct cec_adapter *adap = data;
+ struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
+
+ if (cec->tx_done) {
+ cec->tx_done = false;
+ cec_transmit_attempt_done(adap, cec->tx_status);
+ }
+ if (cec->rx_done) {
+ cec->rx_done = false;
+ smp_rmb();
+ cec_received_msg(adap, &cec->rx_msg);
+ }
+ return IRQ_HANDLED;
+}
+
+static int dw_hdmi_cec_enable(struct cec_adapter *adap, bool enable)
+{
+ struct dw_hdmi_cec *cec = cec_get_drvdata(adap);
+
+ if (!enable) {
+ dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
+ dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
+ dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
+
+ cec->ops->disable(cec->hdmi);
+ } else {
+ unsigned int irqs;
+
+ dw_hdmi_write(cec, 0, HDMI_CEC_CTRL);
+ dw_hdmi_write(cec, ~0, HDMI_IH_CEC_STAT0);
+ dw_hdmi_write(cec, 0, HDMI_CEC_LOCK);
+
+ dw_hdmi_cec_log_addr(cec->adap, CEC_LOG_ADDR_INVALID);
+
+ cec->ops->enable(cec->hdmi);
+
+ irqs = CEC_STAT_ERROR_INIT | CEC_STAT_NACK | CEC_STAT_EOM |
+ CEC_STAT_DONE;
+ dw_hdmi_write(cec, irqs, HDMI_CEC_POLARITY);
+ dw_hdmi_write(cec, ~irqs, HDMI_CEC_MASK);
+ dw_hdmi_write(cec, ~irqs, HDMI_IH_MUTE_CEC_STAT0);
+ }
+ return 0;
+}
+
+static const struct cec_adap_ops dw_hdmi_cec_ops = {
+ .adap_enable = dw_hdmi_cec_enable,
+ .adap_log_addr = dw_hdmi_cec_log_addr,
+ .adap_transmit = dw_hdmi_cec_transmit,
+};
+
+static void dw_hdmi_cec_del(void *data)
+{
+ struct dw_hdmi_cec *cec = data;
+
+ cec_delete_adapter(cec->adap);
+}
+
+static int dw_hdmi_cec_probe(struct platform_device *pdev)
+{
+ struct dw_hdmi_cec_data *data = dev_get_platdata(&pdev->dev);
+ struct dw_hdmi_cec *cec;
+ int ret;
+
+ if (!data)
+ return -ENXIO;
+
+ /*
+ * Our device is just a convenience - we want to link to the real
+ * hardware device here, so that userspace can see the association
+ * between the HDMI hardware and its associated CEC chardev.
+ */
+ cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
+ if (!cec)
+ return -ENOMEM;
+
+ cec->irq = data->irq;
+ cec->ops = data->ops;
+ cec->hdmi = data->hdmi;
+
+ platform_set_drvdata(pdev, cec);
+
+ dw_hdmi_write(cec, 0, HDMI_CEC_TX_CNT);
+ dw_hdmi_write(cec, ~0, HDMI_CEC_MASK);
+ dw_hdmi_write(cec, ~0, HDMI_IH_MUTE_CEC_STAT0);
+ dw_hdmi_write(cec, 0, HDMI_CEC_POLARITY);
+
+ cec->adap = cec_allocate_adapter(&dw_hdmi_cec_ops, cec, "dw_hdmi",
+ CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT |
+ CEC_CAP_RC | CEC_CAP_PASSTHROUGH,
+ CEC_MAX_LOG_ADDRS);
+ if (IS_ERR(cec->adap))
+ return PTR_ERR(cec->adap);
+
+ /* override the module pointer */
+ cec->adap->owner = THIS_MODULE;
+
+ ret = devm_add_action(&pdev->dev, dw_hdmi_cec_del, cec);
+ if (ret) {
+ cec_delete_adapter(cec->adap);
+ return ret;
+ }
+
+ ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
+ dw_hdmi_cec_hardirq,
+ dw_hdmi_cec_thread, IRQF_SHARED,
+ "dw-hdmi-cec", cec->adap);
+ if (ret < 0)
+ return ret;
+
+ cec->notify = cec_notifier_get(pdev->dev.parent);
+ if (!cec->notify)
+ return -ENOMEM;
+
+ ret = cec_register_adapter(cec->adap, pdev->dev.parent);
+ if (ret < 0) {
+ cec_notifier_put(cec->notify);
+ return ret;
+ }
+
+ /*
+ * CEC documentation says we must not call cec_delete_adapter
+ * after a successful call to cec_register_adapter().
+ */
+ devm_remove_action(&pdev->dev, dw_hdmi_cec_del, cec);
+
+ cec_register_cec_notifier(cec->adap, cec->notify);
+
+ return 0;
+}
+
+static int dw_hdmi_cec_remove(struct platform_device *pdev)
+{
+ struct dw_hdmi_cec *cec = platform_get_drvdata(pdev);
+
+ cec_unregister_adapter(cec->adap);
+ cec_notifier_put(cec->notify);
+
+ return 0;
+}
+
+static struct platform_driver dw_hdmi_cec_driver = {
+ .probe = dw_hdmi_cec_probe,
+ .remove = dw_hdmi_cec_remove,
+ .driver = {
+ .name = "dw-hdmi-cec",
+ },
+};
+module_platform_driver(dw_hdmi_cec_driver);
+
+MODULE_AUTHOR("Russell King <rmk+kernel@armlinux.org.uk>");
+MODULE_DESCRIPTION("Synopsys Designware HDMI CEC driver for i.MX");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS(PLATFORM_MODULE_PREFIX "dw-hdmi-cec");
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
new file mode 100644
index 000000000000..cf4dc121a2c4
--- /dev/null
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.h
@@ -0,0 +1,19 @@
+#ifndef DW_HDMI_CEC_H
+#define DW_HDMI_CEC_H
+
+struct dw_hdmi;
+
+struct dw_hdmi_cec_ops {
+ void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
+ u8 (*read)(struct dw_hdmi *hdmi, int offset);
+ void (*enable)(struct dw_hdmi *hdmi);
+ void (*disable)(struct dw_hdmi *hdmi);
+};
+
+struct dw_hdmi_cec_data {
+ struct dw_hdmi *hdmi;
+ const struct dw_hdmi_cec_ops *ops;
+ int irq;
+};
+
+#endif
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index b2cf59f54c88..3b7e5c59a5e9 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -1,7 +1,8 @@
/*
* dw-hdmi-i2s-audio.c
*
- * Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ * Copyright (c) 2017 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
*
* 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
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index ead11242c4b9..bf14214fa464 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -35,8 +35,12 @@
#include "dw-hdmi.h"
#include "dw-hdmi-audio.h"
+#include "dw-hdmi-cec.h"
+
+#include <media/cec-notifier.h>
#define DDC_SEGMENT_ADDR 0x30
+
#define HDMI_EDID_LEN 512
enum hdmi_datamap {
@@ -130,6 +134,7 @@ struct dw_hdmi {
unsigned int version;
struct platform_device *audio;
+ struct platform_device *cec;
struct device *dev;
struct clk *isfr_clk;
struct clk *iahb_clk;
@@ -163,6 +168,7 @@ struct dw_hdmi {
bool bridge_is_on; /* indicates the bridge is on */
bool rxsense; /* rxsense state */
u8 phy_mask; /* desired phy int mask settings */
+ u8 mc_clkdis; /* clock disable register */
spinlock_t audio_lock;
struct mutex audio_mutex;
@@ -175,6 +181,8 @@ struct dw_hdmi {
struct regmap *regm;
void (*enable_audio)(struct dw_hdmi *hdmi);
void (*disable_audio)(struct dw_hdmi *hdmi);
+
+ struct cec_notifier *cec_notifier;
};
#define HDMI_IH_PHY_STAT0_RX_SENSE \
@@ -546,8 +554,11 @@ EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate);
static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable)
{
- hdmi_modb(hdmi, enable ? 0 : HDMI_MC_CLKDIS_AUDCLK_DISABLE,
- HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
+ if (enable)
+ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
+ else
+ hdmi->mc_clkdis |= HDMI_MC_CLKDIS_AUDCLK_DISABLE;
+ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
}
static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi)
@@ -1317,7 +1328,7 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
u8 val;
/* Initialise info frame from DRM mode */
- drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format))
frame.colorspace = HDMI_COLORSPACE_YUV444;
@@ -1569,8 +1580,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
/* HDMI Initialization Step B.4 */
static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
{
- u8 clkdis;
-
/* control period minimum duration */
hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
@@ -1582,17 +1591,21 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
/* Enable pixel clock and tmds data path */
- clkdis = 0x7F;
- clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
- hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
+ hdmi->mc_clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE |
+ HDMI_MC_CLKDIS_CSCCLK_DISABLE |
+ HDMI_MC_CLKDIS_AUDCLK_DISABLE |
+ HDMI_MC_CLKDIS_PREPCLK_DISABLE |
+ HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
+ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
+ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
- clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
- hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
+ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
+ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
/* Enable csc path */
if (is_color_space_conversion(hdmi)) {
- clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
- hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
+ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
+ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
}
/* Enable color space conversion if needed */
@@ -1783,7 +1796,6 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
- hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK);
hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
@@ -1896,6 +1908,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
drm_mode_connector_update_edid_property(connector, edid);
+ cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
ret = drm_add_edid_modes(connector, edid);
/* Store the ELD */
drm_edid_to_eld(connector, edid);
@@ -1920,7 +1933,6 @@ static void dw_hdmi_connector_force(struct drm_connector *connector)
}
static const struct drm_connector_funcs dw_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = dw_hdmi_connector_detect,
.destroy = drm_connector_cleanup,
@@ -2119,11 +2131,16 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
* ask the source to re-read the EDID.
*/
if (intr_stat &
- (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD))
+ (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
__dw_hdmi_setup_rx_sense(hdmi,
phy_stat & HDMI_PHY_HPD,
phy_stat & HDMI_PHY_RX_SENSE);
+ if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
+ cec_notifier_set_phys_addr(hdmi->cec_notifier,
+ CEC_PHYS_ADDR_INVALID);
+ }
+
if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
dev_dbg(hdmi->dev, "EVENT=%s\n",
phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
@@ -2170,6 +2187,7 @@ static const struct dw_hdmi_phy_data dw_hdmi_phys[] = {
.name = "DWC HDMI 2.0 TX PHY",
.gen = 2,
.has_svsret = true,
+ .configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
}, {
.type = DW_HDMI_PHY_VENDOR_PHY,
.name = "Vendor PHY",
@@ -2219,6 +2237,29 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
return -ENODEV;
}
+static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi)
+{
+ mutex_lock(&hdmi->mutex);
+ hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
+ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
+ mutex_unlock(&hdmi->mutex);
+}
+
+static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
+{
+ mutex_lock(&hdmi->mutex);
+ hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
+ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
+ mutex_unlock(&hdmi->mutex);
+}
+
+static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
+ .write = hdmi_writeb,
+ .read = hdmi_readb,
+ .enable = dw_hdmi_cec_enable,
+ .disable = dw_hdmi_cec_disable,
+};
+
static const struct regmap_config hdmi_regmap_8bit_config = {
.reg_bits = 32,
.val_bits = 8,
@@ -2241,6 +2282,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
struct device_node *np = dev->of_node;
struct platform_device_info pdevinfo;
struct device_node *ddc_node;
+ struct dw_hdmi_cec_data cec;
struct dw_hdmi *hdmi;
struct resource *iores = NULL;
int irq;
@@ -2261,6 +2303,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
hdmi->disabled = true;
hdmi->rxsense = true;
hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE);
+ hdmi->mc_clkdis = 0x7f;
mutex_init(&hdmi->mutex);
mutex_init(&hdmi->audio_mutex);
@@ -2376,6 +2419,12 @@ __dw_hdmi_probe(struct platform_device *pdev,
if (ret)
goto err_iahb;
+ hdmi->cec_notifier = cec_notifier_get(dev);
+ if (!hdmi->cec_notifier) {
+ ret = -ENOMEM;
+ goto err_iahb;
+ }
+
/*
* To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
* N and cts values before enabling phy
@@ -2438,6 +2487,19 @@ __dw_hdmi_probe(struct platform_device *pdev,
hdmi->audio = platform_device_register_full(&pdevinfo);
}
+ if (config0 & HDMI_CONFIG0_CEC) {
+ cec.hdmi = hdmi;
+ cec.ops = &dw_hdmi_cec_ops;
+ cec.irq = irq;
+
+ pdevinfo.name = "dw-hdmi-cec";
+ pdevinfo.data = &cec;
+ pdevinfo.size_data = sizeof(cec);
+ pdevinfo.dma_mask = 0;
+
+ hdmi->cec = platform_device_register_full(&pdevinfo);
+ }
+
/* Reset HDMI DDC I2C master controller and mute I2CM interrupts */
if (hdmi->i2c)
dw_hdmi_i2c_init(hdmi);
@@ -2452,6 +2514,9 @@ err_iahb:
hdmi->ddc = NULL;
}
+ if (hdmi->cec_notifier)
+ cec_notifier_put(hdmi->cec_notifier);
+
clk_disable_unprepare(hdmi->iahb_clk);
err_isfr:
clk_disable_unprepare(hdmi->isfr_clk);
@@ -2465,10 +2530,15 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
{
if (hdmi->audio && !IS_ERR(hdmi->audio))
platform_device_unregister(hdmi->audio);
+ if (!IS_ERR(hdmi->cec))
+ platform_device_unregister(hdmi->cec);
/* Disable all interrupts */
hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
+ if (hdmi->cec_notifier)
+ cec_notifier_put(hdmi->cec_notifier);
+
clk_disable_unprepare(hdmi->iahb_clk);
clk_disable_unprepare(hdmi->isfr_clk);
@@ -2485,17 +2555,12 @@ int dw_hdmi_probe(struct platform_device *pdev,
const struct dw_hdmi_plat_data *plat_data)
{
struct dw_hdmi *hdmi;
- int ret;
hdmi = __dw_hdmi_probe(pdev, plat_data);
if (IS_ERR(hdmi))
return PTR_ERR(hdmi);
- ret = drm_bridge_add(&hdmi->bridge);
- if (ret < 0) {
- __dw_hdmi_remove(hdmi);
- return ret;
- }
+ drm_bridge_add(&hdmi->bridge);
return 0;
}
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
index c59f87e1483e..9d90eb9c46e5 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
@@ -478,51 +478,6 @@
#define HDMI_A_PRESETUP 0x501A
#define HDMI_A_SRM_BASE 0x5020
-/* CEC Engine Registers */
-#define HDMI_CEC_CTRL 0x7D00
-#define HDMI_CEC_STAT 0x7D01
-#define HDMI_CEC_MASK 0x7D02
-#define HDMI_CEC_POLARITY 0x7D03
-#define HDMI_CEC_INT 0x7D04
-#define HDMI_CEC_ADDR_L 0x7D05
-#define HDMI_CEC_ADDR_H 0x7D06
-#define HDMI_CEC_TX_CNT 0x7D07
-#define HDMI_CEC_RX_CNT 0x7D08
-#define HDMI_CEC_TX_DATA0 0x7D10
-#define HDMI_CEC_TX_DATA1 0x7D11
-#define HDMI_CEC_TX_DATA2 0x7D12
-#define HDMI_CEC_TX_DATA3 0x7D13
-#define HDMI_CEC_TX_DATA4 0x7D14
-#define HDMI_CEC_TX_DATA5 0x7D15
-#define HDMI_CEC_TX_DATA6 0x7D16
-#define HDMI_CEC_TX_DATA7 0x7D17
-#define HDMI_CEC_TX_DATA8 0x7D18
-#define HDMI_CEC_TX_DATA9 0x7D19
-#define HDMI_CEC_TX_DATA10 0x7D1a
-#define HDMI_CEC_TX_DATA11 0x7D1b
-#define HDMI_CEC_TX_DATA12 0x7D1c
-#define HDMI_CEC_TX_DATA13 0x7D1d
-#define HDMI_CEC_TX_DATA14 0x7D1e
-#define HDMI_CEC_TX_DATA15 0x7D1f
-#define HDMI_CEC_RX_DATA0 0x7D20
-#define HDMI_CEC_RX_DATA1 0x7D21
-#define HDMI_CEC_RX_DATA2 0x7D22
-#define HDMI_CEC_RX_DATA3 0x7D23
-#define HDMI_CEC_RX_DATA4 0x7D24
-#define HDMI_CEC_RX_DATA5 0x7D25
-#define HDMI_CEC_RX_DATA6 0x7D26
-#define HDMI_CEC_RX_DATA7 0x7D27
-#define HDMI_CEC_RX_DATA8 0x7D28
-#define HDMI_CEC_RX_DATA9 0x7D29
-#define HDMI_CEC_RX_DATA10 0x7D2a
-#define HDMI_CEC_RX_DATA11 0x7D2b
-#define HDMI_CEC_RX_DATA12 0x7D2c
-#define HDMI_CEC_RX_DATA13 0x7D2d
-#define HDMI_CEC_RX_DATA14 0x7D2e
-#define HDMI_CEC_RX_DATA15 0x7D2f
-#define HDMI_CEC_LOCK 0x7D30
-#define HDMI_CEC_WKUPCTRL 0x7D31
-
/* I2C Master Registers (E-DDC) */
#define HDMI_I2CM_SLAVE 0x7E00
#define HDMI_I2CM_ADDRESS 0x7E01
@@ -555,6 +510,7 @@ enum {
/* CONFIG0_ID field values */
HDMI_CONFIG0_I2S = 0x10,
+ HDMI_CONFIG0_CEC = 0x02,
/* CONFIG1_ID field values */
HDMI_CONFIG1_AHB = 0x01,
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
new file mode 100644
index 000000000000..63c7a01b7053
--- /dev/null
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -0,0 +1,981 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (C) STMicroelectronics SA 2017
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Modified by Philippe Cornu <philippe.cornu@st.com>
+ * This generic Synopsys DesignWare MIPI DSI host driver is based on the
+ * Rockchip version from rockchip/dw-mipi-dsi.c with phy & bridge APIs.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_of.h>
+#include <drm/bridge/dw_mipi_dsi.h>
+#include <video/mipi_display.h>
+
+#define DSI_VERSION 0x00
+#define DSI_PWR_UP 0x04
+#define RESET 0
+#define POWERUP BIT(0)
+
+#define DSI_CLKMGR_CFG 0x08
+#define TO_CLK_DIVIDSION(div) (((div) & 0xff) << 8)
+#define TX_ESC_CLK_DIVIDSION(div) (((div) & 0xff) << 0)
+
+#define DSI_DPI_VCID 0x0c
+#define DPI_VID(vid) (((vid) & 0x3) << 0)
+
+#define DSI_DPI_COLOR_CODING 0x10
+#define EN18_LOOSELY BIT(8)
+#define DPI_COLOR_CODING_16BIT_1 0x0
+#define DPI_COLOR_CODING_16BIT_2 0x1
+#define DPI_COLOR_CODING_16BIT_3 0x2
+#define DPI_COLOR_CODING_18BIT_1 0x3
+#define DPI_COLOR_CODING_18BIT_2 0x4
+#define DPI_COLOR_CODING_24BIT 0x5
+
+#define DSI_DPI_CFG_POL 0x14
+#define COLORM_ACTIVE_LOW BIT(4)
+#define SHUTD_ACTIVE_LOW BIT(3)
+#define HSYNC_ACTIVE_LOW BIT(2)
+#define VSYNC_ACTIVE_LOW BIT(1)
+#define DATAEN_ACTIVE_LOW BIT(0)
+
+#define DSI_DPI_LP_CMD_TIM 0x18
+#define OUTVACT_LPCMD_TIME(p) (((p) & 0xff) << 16)
+#define INVACT_LPCMD_TIME(p) ((p) & 0xff)
+
+#define DSI_DBI_CFG 0x20
+#define DSI_DBI_CMDSIZE 0x28
+
+#define DSI_PCKHDL_CFG 0x2c
+#define EN_CRC_RX BIT(4)
+#define EN_ECC_RX BIT(3)
+#define EN_BTA BIT(2)
+#define EN_EOTP_RX BIT(1)
+#define EN_EOTP_TX BIT(0)
+
+#define DSI_MODE_CFG 0x34
+#define ENABLE_VIDEO_MODE 0
+#define ENABLE_CMD_MODE BIT(0)
+
+#define DSI_VID_MODE_CFG 0x38
+#define FRAME_BTA_ACK BIT(14)
+#define ENABLE_LOW_POWER (0x3f << 8)
+#define ENABLE_LOW_POWER_MASK (0x3f << 8)
+#define VID_MODE_TYPE_NON_BURST_SYNC_PULSES 0x0
+#define VID_MODE_TYPE_NON_BURST_SYNC_EVENTS 0x1
+#define VID_MODE_TYPE_BURST 0x2
+#define VID_MODE_TYPE_MASK 0x3
+
+#define DSI_VID_PKT_SIZE 0x3c
+#define VID_PKT_SIZE(p) (((p) & 0x3fff) << 0)
+#define VID_PKT_MAX_SIZE 0x3fff
+
+#define DSI_VID_HSA_TIME 0x48
+#define DSI_VID_HBP_TIME 0x4c
+#define DSI_VID_HLINE_TIME 0x50
+#define DSI_VID_VSA_LINES 0x54
+#define DSI_VID_VBP_LINES 0x58
+#define DSI_VID_VFP_LINES 0x5c
+#define DSI_VID_VACTIVE_LINES 0x60
+#define DSI_CMD_MODE_CFG 0x68
+#define MAX_RD_PKT_SIZE_LP BIT(24)
+#define DCS_LW_TX_LP BIT(19)
+#define DCS_SR_0P_TX_LP BIT(18)
+#define DCS_SW_1P_TX_LP BIT(17)
+#define DCS_SW_0P_TX_LP BIT(16)
+#define GEN_LW_TX_LP BIT(14)
+#define GEN_SR_2P_TX_LP BIT(13)
+#define GEN_SR_1P_TX_LP BIT(12)
+#define GEN_SR_0P_TX_LP BIT(11)
+#define GEN_SW_2P_TX_LP BIT(10)
+#define GEN_SW_1P_TX_LP BIT(9)
+#define GEN_SW_0P_TX_LP BIT(8)
+#define EN_ACK_RQST BIT(1)
+#define EN_TEAR_FX BIT(0)
+
+#define CMD_MODE_ALL_LP (MAX_RD_PKT_SIZE_LP | \
+ DCS_LW_TX_LP | \
+ DCS_SR_0P_TX_LP | \
+ DCS_SW_1P_TX_LP | \
+ DCS_SW_0P_TX_LP | \
+ GEN_LW_TX_LP | \
+ GEN_SR_2P_TX_LP | \
+ GEN_SR_1P_TX_LP | \
+ GEN_SR_0P_TX_LP | \
+ GEN_SW_2P_TX_LP | \
+ GEN_SW_1P_TX_LP | \
+ GEN_SW_0P_TX_LP)
+
+#define DSI_GEN_HDR 0x6c
+#define GEN_HDATA(data) (((data) & 0xffff) << 8)
+#define GEN_HDATA_MASK (0xffff << 8)
+#define GEN_HTYPE(type) (((type) & 0xff) << 0)
+#define GEN_HTYPE_MASK 0xff
+
+#define DSI_GEN_PLD_DATA 0x70
+
+#define DSI_CMD_PKT_STATUS 0x74
+#define GEN_CMD_EMPTY BIT(0)
+#define GEN_CMD_FULL BIT(1)
+#define GEN_PLD_W_EMPTY BIT(2)
+#define GEN_PLD_W_FULL BIT(3)
+#define GEN_PLD_R_EMPTY BIT(4)
+#define GEN_PLD_R_FULL BIT(5)
+#define GEN_RD_CMD_BUSY BIT(6)
+
+#define DSI_TO_CNT_CFG 0x78
+#define HSTX_TO_CNT(p) (((p) & 0xffff) << 16)
+#define LPRX_TO_CNT(p) ((p) & 0xffff)
+
+#define DSI_BTA_TO_CNT 0x8c
+#define DSI_LPCLK_CTRL 0x94
+#define AUTO_CLKLANE_CTRL BIT(1)
+#define PHY_TXREQUESTCLKHS BIT(0)
+
+#define DSI_PHY_TMR_LPCLK_CFG 0x98
+#define PHY_CLKHS2LP_TIME(lbcc) (((lbcc) & 0x3ff) << 16)
+#define PHY_CLKLP2HS_TIME(lbcc) ((lbcc) & 0x3ff)
+
+#define DSI_PHY_TMR_CFG 0x9c
+#define PHY_HS2LP_TIME(lbcc) (((lbcc) & 0xff) << 24)
+#define PHY_LP2HS_TIME(lbcc) (((lbcc) & 0xff) << 16)
+#define MAX_RD_TIME(lbcc) ((lbcc) & 0x7fff)
+
+#define DSI_PHY_RSTZ 0xa0
+#define PHY_DISFORCEPLL 0
+#define PHY_ENFORCEPLL BIT(3)
+#define PHY_DISABLECLK 0
+#define PHY_ENABLECLK BIT(2)
+#define PHY_RSTZ 0
+#define PHY_UNRSTZ BIT(1)
+#define PHY_SHUTDOWNZ 0
+#define PHY_UNSHUTDOWNZ BIT(0)
+
+#define DSI_PHY_IF_CFG 0xa4
+#define N_LANES(n) ((((n) - 1) & 0x3) << 0)
+#define PHY_STOP_WAIT_TIME(cycle) (((cycle) & 0xff) << 8)
+
+#define DSI_PHY_STATUS 0xb0
+#define LOCK BIT(0)
+#define STOP_STATE_CLK_LANE BIT(2)
+
+#define DSI_PHY_TST_CTRL0 0xb4
+#define PHY_TESTCLK BIT(1)
+#define PHY_UNTESTCLK 0
+#define PHY_TESTCLR BIT(0)
+#define PHY_UNTESTCLR 0
+
+#define DSI_PHY_TST_CTRL1 0xb8
+#define PHY_TESTEN BIT(16)
+#define PHY_UNTESTEN 0
+#define PHY_TESTDOUT(n) (((n) & 0xff) << 8)
+#define PHY_TESTDIN(n) (((n) & 0xff) << 0)
+
+#define DSI_INT_ST0 0xbc
+#define DSI_INT_ST1 0xc0
+#define DSI_INT_MSK0 0xc4
+#define DSI_INT_MSK1 0xc8
+
+#define PHY_STATUS_TIMEOUT_US 10000
+#define CMD_PKT_STATUS_TIMEOUT_US 20000
+
+struct dw_mipi_dsi {
+ struct drm_bridge bridge;
+ struct mipi_dsi_host dsi_host;
+ struct drm_bridge *panel_bridge;
+ bool is_panel_bridge;
+ struct device *dev;
+ void __iomem *base;
+
+ struct clk *pclk;
+
+ unsigned int lane_mbps; /* per lane */
+ u32 channel;
+ u32 lanes;
+ u32 format;
+ unsigned long mode_flags;
+
+ const struct dw_mipi_dsi_plat_data *plat_data;
+};
+
+/*
+ * The controller should generate 2 frames before
+ * preparing the peripheral.
+ */
+static void dw_mipi_dsi_wait_for_two_frames(struct drm_display_mode *mode)
+{
+ int refresh, two_frames;
+
+ refresh = drm_mode_vrefresh(mode);
+ two_frames = DIV_ROUND_UP(MSEC_PER_SEC, refresh) * 2;
+ msleep(two_frames);
+}
+
+static inline struct dw_mipi_dsi *host_to_dsi(struct mipi_dsi_host *host)
+{
+ return container_of(host, struct dw_mipi_dsi, dsi_host);
+}
+
+static inline struct dw_mipi_dsi *bridge_to_dsi(struct drm_bridge *bridge)
+{
+ return container_of(bridge, struct dw_mipi_dsi, bridge);
+}
+
+static inline void dsi_write(struct dw_mipi_dsi *dsi, u32 reg, u32 val)
+{
+ writel(val, dsi->base + reg);
+}
+
+static inline u32 dsi_read(struct dw_mipi_dsi *dsi, u32 reg)
+{
+ return readl(dsi->base + reg);
+}
+
+static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
+ struct mipi_dsi_device *device)
+{
+ struct dw_mipi_dsi *dsi = host_to_dsi(host);
+ struct drm_bridge *bridge;
+ struct drm_panel *panel;
+ int ret;
+
+ if (device->lanes > dsi->plat_data->max_data_lanes) {
+ dev_err(dsi->dev, "the number of data lanes(%u) is too many\n",
+ device->lanes);
+ return -EINVAL;
+ }
+
+ dsi->lanes = device->lanes;
+ dsi->channel = device->channel;
+ dsi->format = device->format;
+ dsi->mode_flags = device->mode_flags;
+
+ ret = drm_of_find_panel_or_bridge(host->dev->of_node, 1, 0,
+ &panel, &bridge);
+ if (ret)
+ return ret;
+
+ if (panel) {
+ bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DSI);
+ if (IS_ERR(bridge))
+ return PTR_ERR(bridge);
+ dsi->is_panel_bridge = true;
+ }
+
+ dsi->panel_bridge = bridge;
+
+ drm_bridge_add(&dsi->bridge);
+
+ return 0;
+}
+
+static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,
+ struct mipi_dsi_device *device)
+{
+ struct dw_mipi_dsi *dsi = host_to_dsi(host);
+
+ if (dsi->is_panel_bridge)
+ drm_panel_bridge_remove(dsi->panel_bridge);
+
+ drm_bridge_remove(&dsi->bridge);
+
+ return 0;
+}
+
+static void dw_mipi_message_config(struct dw_mipi_dsi *dsi,
+ const struct mipi_dsi_msg *msg)
+{
+ bool lpm = msg->flags & MIPI_DSI_MSG_USE_LPM;
+ u32 val = 0;
+
+ if (msg->flags & MIPI_DSI_MSG_REQ_ACK)
+ val |= EN_ACK_RQST;
+ if (lpm)
+ val |= CMD_MODE_ALL_LP;
+
+ dsi_write(dsi, DSI_LPCLK_CTRL, lpm ? 0 : PHY_TXREQUESTCLKHS);
+ dsi_write(dsi, DSI_CMD_MODE_CFG, val);
+}
+
+static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
+{
+ int ret;
+ u32 val, mask;
+
+ ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
+ val, !(val & GEN_CMD_FULL), 1000,
+ CMD_PKT_STATUS_TIMEOUT_US);
+ if (ret < 0) {
+ dev_err(dsi->dev, "failed to get available command FIFO\n");
+ return ret;
+ }
+
+ dsi_write(dsi, DSI_GEN_HDR, hdr_val);
+
+ mask = GEN_CMD_EMPTY | GEN_PLD_W_EMPTY;
+ ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
+ val, (val & mask) == mask,
+ 1000, CMD_PKT_STATUS_TIMEOUT_US);
+ if (ret < 0) {
+ dev_err(dsi->dev, "failed to write command FIFO\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi,
+ const struct mipi_dsi_msg *msg)
+{
+ const u8 *tx_buf = msg->tx_buf;
+ u16 data = 0;
+ u32 val;
+
+ if (msg->tx_len > 0)
+ data |= tx_buf[0];
+ if (msg->tx_len > 1)
+ data |= tx_buf[1] << 8;
+
+ if (msg->tx_len > 2) {
+ dev_err(dsi->dev, "too long tx buf length %zu for short write\n",
+ msg->tx_len);
+ return -EINVAL;
+ }
+
+ val = GEN_HDATA(data) | GEN_HTYPE(msg->type);
+ return dw_mipi_dsi_gen_pkt_hdr_write(dsi, val);
+}
+
+static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
+ const struct mipi_dsi_msg *msg)
+{
+ const u8 *tx_buf = msg->tx_buf;
+ int len = msg->tx_len, pld_data_bytes = sizeof(u32), ret;
+ u32 hdr_val = GEN_HDATA(msg->tx_len) | GEN_HTYPE(msg->type);
+ u32 remainder;
+ u32 val;
+
+ if (msg->tx_len < 3) {
+ dev_err(dsi->dev, "wrong tx buf length %zu for long write\n",
+ msg->tx_len);
+ return -EINVAL;
+ }
+
+ while (DIV_ROUND_UP(len, pld_data_bytes)) {
+ if (len < pld_data_bytes) {
+ remainder = 0;
+ memcpy(&remainder, tx_buf, len);
+ dsi_write(dsi, DSI_GEN_PLD_DATA, remainder);
+ len = 0;
+ } else {
+ memcpy(&remainder, tx_buf, pld_data_bytes);
+ dsi_write(dsi, DSI_GEN_PLD_DATA, remainder);
+ tx_buf += pld_data_bytes;
+ len -= pld_data_bytes;
+ }
+
+ ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
+ val, !(val & GEN_PLD_W_FULL), 1000,
+ CMD_PKT_STATUS_TIMEOUT_US);
+ if (ret < 0) {
+ dev_err(dsi->dev,
+ "failed to get available write payload FIFO\n");
+ return ret;
+ }
+ }
+
+ return dw_mipi_dsi_gen_pkt_hdr_write(dsi, hdr_val);
+}
+
+static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
+ const struct mipi_dsi_msg *msg)
+{
+ struct dw_mipi_dsi *dsi = host_to_dsi(host);
+ int ret;
+
+ /*
+ * TODO dw drv improvements
+ * use mipi_dsi_create_packet() instead of all following
+ * functions and code (no switch cases, no
+ * dw_mipi_dsi_dcs_short_write(), only the loop in long_write...)
+ * and use packet.header...
+ */
+ dw_mipi_message_config(dsi, msg);
+
+ switch (msg->type) {
+ case MIPI_DSI_DCS_SHORT_WRITE:
+ case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
+ case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
+ ret = dw_mipi_dsi_dcs_short_write(dsi, msg);
+ break;
+ case MIPI_DSI_DCS_LONG_WRITE:
+ ret = dw_mipi_dsi_dcs_long_write(dsi, msg);
+ break;
+ default:
+ dev_err(dsi->dev, "unsupported message type 0x%02x\n",
+ msg->type);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static const struct mipi_dsi_host_ops dw_mipi_dsi_host_ops = {
+ .attach = dw_mipi_dsi_host_attach,
+ .detach = dw_mipi_dsi_host_detach,
+ .transfer = dw_mipi_dsi_host_transfer,
+};
+
+static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi)
+{
+ u32 val;
+
+ /*
+ * TODO dw drv improvements
+ * enabling low power is panel-dependent, we should use the
+ * panel configuration here...
+ */
+ val = ENABLE_LOW_POWER;
+
+ if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
+ val |= VID_MODE_TYPE_BURST;
+ else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
+ val |= VID_MODE_TYPE_NON_BURST_SYNC_PULSES;
+ else
+ val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS;
+
+ dsi_write(dsi, DSI_VID_MODE_CFG, val);
+}
+
+static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi,
+ unsigned long mode_flags)
+{
+ dsi_write(dsi, DSI_PWR_UP, RESET);
+
+ if (mode_flags & MIPI_DSI_MODE_VIDEO) {
+ dsi_write(dsi, DSI_MODE_CFG, ENABLE_VIDEO_MODE);
+ dw_mipi_dsi_video_mode_config(dsi);
+ dsi_write(dsi, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS);
+ } else {
+ dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE);
+ }
+
+ dsi_write(dsi, DSI_PWR_UP, POWERUP);
+}
+
+static void dw_mipi_dsi_disable(struct dw_mipi_dsi *dsi)
+{
+ dsi_write(dsi, DSI_PWR_UP, RESET);
+ dsi_write(dsi, DSI_PHY_RSTZ, PHY_RSTZ);
+}
+
+static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi)
+{
+ /*
+ * The maximum permitted escape clock is 20MHz and it is derived from
+ * lanebyteclk, which is running at "lane_mbps / 8". Thus we want:
+ *
+ * (lane_mbps >> 3) / esc_clk_division < 20
+ * which is:
+ * (lane_mbps >> 3) / 20 > esc_clk_division
+ */
+ u32 esc_clk_division = (dsi->lane_mbps >> 3) / 20 + 1;
+
+ dsi_write(dsi, DSI_PWR_UP, RESET);
+
+ /*
+ * TODO dw drv improvements
+ * timeout clock division should be computed with the
+ * high speed transmission counter timeout and byte lane...
+ */
+ dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVIDSION(10) |
+ TX_ESC_CLK_DIVIDSION(esc_clk_division));
+}
+
+static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,
+ struct drm_display_mode *mode)
+{
+ u32 val = 0, color = 0;
+
+ switch (dsi->format) {
+ case MIPI_DSI_FMT_RGB888:
+ color = DPI_COLOR_CODING_24BIT;
+ break;
+ case MIPI_DSI_FMT_RGB666:
+ color = DPI_COLOR_CODING_18BIT_2 | EN18_LOOSELY;
+ break;
+ case MIPI_DSI_FMT_RGB666_PACKED:
+ color = DPI_COLOR_CODING_18BIT_1;
+ break;
+ case MIPI_DSI_FMT_RGB565:
+ color = DPI_COLOR_CODING_16BIT_1;
+ break;
+ }
+
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ val |= VSYNC_ACTIVE_LOW;
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ val |= HSYNC_ACTIVE_LOW;
+
+ dsi_write(dsi, DSI_DPI_VCID, DPI_VID(dsi->channel));
+ dsi_write(dsi, DSI_DPI_COLOR_CODING, color);
+ dsi_write(dsi, DSI_DPI_CFG_POL, val);
+ /*
+ * TODO dw drv improvements
+ * largest packet sizes during hfp or during vsa/vpb/vfp
+ * should be computed according to byte lane, lane number and only
+ * if sending lp cmds in high speed is enable (PHY_TXREQUESTCLKHS)
+ */
+ dsi_write(dsi, DSI_DPI_LP_CMD_TIM, OUTVACT_LPCMD_TIME(4)
+ | INVACT_LPCMD_TIME(4));
+}
+
+static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi)
+{
+ dsi_write(dsi, DSI_PCKHDL_CFG, EN_CRC_RX | EN_ECC_RX | EN_BTA);
+}
+
+static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi,
+ struct drm_display_mode *mode)
+{
+ /*
+ * TODO dw drv improvements
+ * only burst mode is supported here. For non-burst video modes,
+ * we should compute DSI_VID_PKT_SIZE, DSI_VCCR.NUMC &
+ * DSI_VNPCR.NPSIZE... especially because this driver supports
+ * non-burst video modes, see dw_mipi_dsi_video_mode_config()...
+ */
+ dsi_write(dsi, DSI_VID_PKT_SIZE, VID_PKT_SIZE(mode->hdisplay));
+}
+
+static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi)
+{
+ /*
+ * TODO dw drv improvements
+ * compute high speed transmission counter timeout according
+ * to the timeout clock division (TO_CLK_DIVIDSION) and byte lane...
+ */
+ dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000));
+ /*
+ * TODO dw drv improvements
+ * the Bus-Turn-Around Timeout Counter should be computed
+ * according to byte lane...
+ */
+ dsi_write(dsi, DSI_BTA_TO_CNT, 0xd00);
+ dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE);
+}
+
+/* Get lane byte clock cycles. */
+static u32 dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi,
+ struct drm_display_mode *mode,
+ u32 hcomponent)
+{
+ u32 frac, lbcc;
+
+ lbcc = hcomponent * dsi->lane_mbps * MSEC_PER_SEC / 8;
+
+ frac = lbcc % mode->clock;
+ lbcc = lbcc / mode->clock;
+ if (frac)
+ lbcc++;
+
+ return lbcc;
+}
+
+static void dw_mipi_dsi_line_timer_config(struct dw_mipi_dsi *dsi,
+ struct drm_display_mode *mode)
+{
+ u32 htotal, hsa, hbp, lbcc;
+
+ htotal = mode->htotal;
+ hsa = mode->hsync_end - mode->hsync_start;
+ hbp = mode->htotal - mode->hsync_end;
+
+ /*
+ * TODO dw drv improvements
+ * computations below may be improved...
+ */
+ lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, htotal);
+ dsi_write(dsi, DSI_VID_HLINE_TIME, lbcc);
+
+ lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, hsa);
+ dsi_write(dsi, DSI_VID_HSA_TIME, lbcc);
+
+ lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, hbp);
+ dsi_write(dsi, DSI_VID_HBP_TIME, lbcc);
+}
+
+static void dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi *dsi,
+ struct drm_display_mode *mode)
+{
+ u32 vactive, vsa, vfp, vbp;
+
+ vactive = mode->vdisplay;
+ vsa = mode->vsync_end - mode->vsync_start;
+ vfp = mode->vsync_start - mode->vdisplay;
+ vbp = mode->vtotal - mode->vsync_end;
+
+ dsi_write(dsi, DSI_VID_VACTIVE_LINES, vactive);
+ dsi_write(dsi, DSI_VID_VSA_LINES, vsa);
+ dsi_write(dsi, DSI_VID_VFP_LINES, vfp);
+ dsi_write(dsi, DSI_VID_VBP_LINES, vbp);
+}
+
+static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi)
+{
+ /*
+ * TODO dw drv improvements
+ * data & clock lane timers should be computed according to panel
+ * blankings and to the automatic clock lane control mode...
+ * note: DSI_PHY_TMR_CFG.MAX_RD_TIME should be in line with
+ * DSI_CMD_MODE_CFG.MAX_RD_PKT_SIZE_LP (see CMD_MODE_ALL_LP)
+ */
+ dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME(0x40)
+ | PHY_LP2HS_TIME(0x40) | MAX_RD_TIME(10000));
+
+ dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG, PHY_CLKHS2LP_TIME(0x40)
+ | PHY_CLKLP2HS_TIME(0x40));
+}
+
+static void dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi)
+{
+ /*
+ * TODO dw drv improvements
+ * stop wait time should be the maximum between host dsi
+ * and panel stop wait times
+ */
+ dsi_write(dsi, DSI_PHY_IF_CFG, PHY_STOP_WAIT_TIME(0x20) |
+ N_LANES(dsi->lanes));
+}
+
+static void dw_mipi_dsi_dphy_init(struct dw_mipi_dsi *dsi)
+{
+ /* Clear PHY state */
+ dsi_write(dsi, DSI_PHY_RSTZ, PHY_DISFORCEPLL | PHY_DISABLECLK
+ | PHY_RSTZ | PHY_SHUTDOWNZ);
+ dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
+ dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLR);
+ dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
+}
+
+static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi *dsi)
+{
+ u32 val;
+ int ret;
+
+ dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK |
+ PHY_UNRSTZ | PHY_UNSHUTDOWNZ);
+
+ ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
+ val, val & LOCK, 1000, PHY_STATUS_TIMEOUT_US);
+ if (ret < 0)
+ DRM_DEBUG_DRIVER("failed to wait phy lock state\n");
+
+ ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
+ val, val & STOP_STATE_CLK_LANE, 1000,
+ PHY_STATUS_TIMEOUT_US);
+ if (ret < 0)
+ DRM_DEBUG_DRIVER("failed to wait phy clk lane stop state\n");
+}
+
+static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)
+{
+ dsi_read(dsi, DSI_INT_ST0);
+ dsi_read(dsi, DSI_INT_ST1);
+ dsi_write(dsi, DSI_INT_MSK0, 0);
+ dsi_write(dsi, DSI_INT_MSK1, 0);
+}
+
+static void dw_mipi_dsi_bridge_post_disable(struct drm_bridge *bridge)
+{
+ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
+
+ /*
+ * Switch to command mode before panel-bridge post_disable &
+ * panel unprepare.
+ * Note: panel-bridge disable & panel disable has been called
+ * before by the drm framework.
+ */
+ dw_mipi_dsi_set_mode(dsi, 0);
+
+ /*
+ * TODO Only way found to call panel-bridge post_disable &
+ * panel unprepare before the dsi "final" disable...
+ * This needs to be fixed in the drm_bridge framework and the API
+ * needs to be updated to manage our own call chains...
+ */
+ dsi->panel_bridge->funcs->post_disable(dsi->panel_bridge);
+
+ dw_mipi_dsi_disable(dsi);
+ clk_disable_unprepare(dsi->pclk);
+ pm_runtime_put(dsi->dev);
+}
+
+void dw_mipi_dsi_bridge_mode_set(struct drm_bridge *bridge,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
+ const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
+ void *priv_data = dsi->plat_data->priv_data;
+ int ret;
+
+ clk_prepare_enable(dsi->pclk);
+
+ ret = phy_ops->get_lane_mbps(priv_data, mode, dsi->mode_flags,
+ dsi->lanes, dsi->format, &dsi->lane_mbps);
+ if (ret)
+ DRM_DEBUG_DRIVER("Phy get_lane_mbps() failed\n");
+
+ pm_runtime_get_sync(dsi->dev);
+ dw_mipi_dsi_init(dsi);
+ dw_mipi_dsi_dpi_config(dsi, mode);
+ dw_mipi_dsi_packet_handler_config(dsi);
+ dw_mipi_dsi_video_mode_config(dsi);
+ dw_mipi_dsi_video_packet_config(dsi, mode);
+ dw_mipi_dsi_command_mode_config(dsi);
+ dw_mipi_dsi_line_timer_config(dsi, mode);
+ dw_mipi_dsi_vertical_timing_config(dsi, mode);
+
+ dw_mipi_dsi_dphy_init(dsi);
+ dw_mipi_dsi_dphy_timing_config(dsi);
+ dw_mipi_dsi_dphy_interface_config(dsi);
+
+ dw_mipi_dsi_clear_err(dsi);
+
+ ret = phy_ops->init(priv_data);
+ if (ret)
+ DRM_DEBUG_DRIVER("Phy init() failed\n");
+
+ dw_mipi_dsi_dphy_enable(dsi);
+
+ dw_mipi_dsi_wait_for_two_frames(mode);
+
+ /* Switch to cmd mode for panel-bridge pre_enable & panel prepare */
+ dw_mipi_dsi_set_mode(dsi, 0);
+}
+
+static void dw_mipi_dsi_bridge_enable(struct drm_bridge *bridge)
+{
+ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
+
+ /* Switch to video mode for panel-bridge enable & panel enable */
+ dw_mipi_dsi_set_mode(dsi, MIPI_DSI_MODE_VIDEO);
+}
+
+static enum drm_mode_status
+dw_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode)
+{
+ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
+ const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data;
+ enum drm_mode_status mode_status = MODE_OK;
+
+ if (pdata->mode_valid)
+ mode_status = pdata->mode_valid(pdata->priv_data, mode);
+
+ return mode_status;
+}
+
+static int dw_mipi_dsi_bridge_attach(struct drm_bridge *bridge)
+{
+ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
+
+ if (!bridge->encoder) {
+ DRM_ERROR("Parent encoder object not found\n");
+ return -ENODEV;
+ }
+
+ /* Set the encoder type as caller does not know it */
+ bridge->encoder->encoder_type = DRM_MODE_ENCODER_DSI;
+
+ /* Attach the panel-bridge to the dsi bridge */
+ return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, bridge);
+}
+
+static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
+ .mode_set = dw_mipi_dsi_bridge_mode_set,
+ .enable = dw_mipi_dsi_bridge_enable,
+ .post_disable = dw_mipi_dsi_bridge_post_disable,
+ .mode_valid = dw_mipi_dsi_bridge_mode_valid,
+ .attach = dw_mipi_dsi_bridge_attach,
+};
+
+static struct dw_mipi_dsi *
+__dw_mipi_dsi_probe(struct platform_device *pdev,
+ const struct dw_mipi_dsi_plat_data *plat_data)
+{
+ struct device *dev = &pdev->dev;
+ struct reset_control *apb_rst;
+ struct dw_mipi_dsi *dsi;
+ struct resource *res;
+ int ret;
+
+ dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
+ if (!dsi)
+ return ERR_PTR(-ENOMEM);
+
+ dsi->dev = dev;
+ dsi->plat_data = plat_data;
+
+ if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps) {
+ DRM_ERROR("Phy not properly configured\n");
+ return ERR_PTR(-ENODEV);
+ }
+
+ if (!plat_data->base) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return ERR_PTR(-ENODEV);
+
+ dsi->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(dsi->base))
+ return ERR_PTR(-ENODEV);
+
+ } else {
+ dsi->base = plat_data->base;
+ }
+
+ dsi->pclk = devm_clk_get(dev, "pclk");
+ if (IS_ERR(dsi->pclk)) {
+ ret = PTR_ERR(dsi->pclk);
+ dev_err(dev, "Unable to get pclk: %d\n", ret);
+ return ERR_PTR(ret);
+ }
+
+ /*
+ * Note that the reset was not defined in the initial device tree, so
+ * we have to be prepared for it not being found.
+ */
+ apb_rst = devm_reset_control_get(dev, "apb");
+ if (IS_ERR(apb_rst)) {
+ ret = PTR_ERR(apb_rst);
+ if (ret == -ENOENT) {
+ apb_rst = NULL;
+ } else {
+ dev_err(dev, "Unable to get reset control: %d\n", ret);
+ return ERR_PTR(ret);
+ }
+ }
+
+ if (apb_rst) {
+ ret = clk_prepare_enable(dsi->pclk);
+ if (ret) {
+ dev_err(dev, "%s: Failed to enable pclk\n", __func__);
+ return ERR_PTR(ret);
+ }
+
+ reset_control_assert(apb_rst);
+ usleep_range(10, 20);
+ reset_control_deassert(apb_rst);
+
+ clk_disable_unprepare(dsi->pclk);
+ }
+
+ pm_runtime_enable(dev);
+
+ dsi->dsi_host.ops = &dw_mipi_dsi_host_ops;
+ dsi->dsi_host.dev = dev;
+ ret = mipi_dsi_host_register(&dsi->dsi_host);
+ if (ret) {
+ dev_err(dev, "Failed to register MIPI host: %d\n", ret);
+ return ERR_PTR(ret);
+ }
+
+ dsi->bridge.driver_private = dsi;
+ dsi->bridge.funcs = &dw_mipi_dsi_bridge_funcs;
+#ifdef CONFIG_OF
+ dsi->bridge.of_node = pdev->dev.of_node;
+#endif
+
+ dev_set_drvdata(dev, dsi);
+
+ return dsi;
+}
+
+static void __dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi)
+{
+ pm_runtime_disable(dsi->dev);
+}
+
+/*
+ * Probe/remove API, used from platforms based on the DRM bridge API.
+ */
+int dw_mipi_dsi_probe(struct platform_device *pdev,
+ const struct dw_mipi_dsi_plat_data *plat_data)
+{
+ struct dw_mipi_dsi *dsi;
+
+ dsi = __dw_mipi_dsi_probe(pdev, plat_data);
+ if (IS_ERR(dsi))
+ return PTR_ERR(dsi);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi_probe);
+
+void dw_mipi_dsi_remove(struct platform_device *pdev)
+{
+ struct dw_mipi_dsi *dsi = platform_get_drvdata(pdev);
+
+ mipi_dsi_host_unregister(&dsi->dsi_host);
+
+ __dw_mipi_dsi_remove(dsi);
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi_remove);
+
+/*
+ * Bind/unbind API, used from platforms based on the component framework.
+ */
+int dw_mipi_dsi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
+ const struct dw_mipi_dsi_plat_data *plat_data)
+{
+ struct dw_mipi_dsi *dsi;
+ int ret;
+
+ dsi = __dw_mipi_dsi_probe(pdev, plat_data);
+ if (IS_ERR(dsi))
+ return PTR_ERR(dsi);
+
+ ret = drm_bridge_attach(encoder, &dsi->bridge, NULL);
+ if (ret) {
+ dw_mipi_dsi_remove(pdev);
+ DRM_ERROR("Failed to initialize bridge with drm\n");
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi_bind);
+
+void dw_mipi_dsi_unbind(struct device *dev)
+{
+ struct dw_mipi_dsi *dsi = dev_get_drvdata(dev);
+
+ __dw_mipi_dsi_remove(dsi);
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi_unbind);
+
+MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
+MODULE_AUTHOR("Philippe Cornu <philippe.cornu@st.com>");
+MODULE_DESCRIPTION("DW MIPI DSI host controller driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:dw-mipi-dsi");
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
index 5c26488e7a2d..8571cfd877c5 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -1160,7 +1160,6 @@ static const struct drm_connector_helper_funcs tc_connector_helper_funcs = {
};
static const struct drm_connector_funcs tc_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
@@ -1255,7 +1254,7 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
/* port@2 is the output port */
ret = drm_of_find_panel_or_bridge(dev->of_node, 2, 0, &tc->panel, NULL);
- if (ret)
+ if (ret && ret != -ENODEV)
return ret;
/* Shut down GPIO is optional */
@@ -1325,11 +1324,7 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
tc->bridge.funcs = &tc_bridge_funcs;
tc->bridge.of_node = dev->of_node;
- ret = drm_bridge_add(&tc->bridge);
- if (ret) {
- dev_err(dev, "Failed to add drm_bridge: %d\n", ret);
- goto err_unregister_aux;
- }
+ drm_bridge_add(&tc->bridge);
i2c_set_clientdata(client, tc);
diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c
index eee4efda829e..acb857030951 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -102,7 +102,6 @@ tfp410_connector_detect(struct drm_connector *connector, bool force)
}
static const struct drm_connector_funcs tfp410_con_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = tfp410_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
@@ -237,11 +236,7 @@ static int tfp410_init(struct device *dev)
}
}
- ret = drm_bridge_add(&dvi->bridge);
- if (ret) {
- dev_err(dev, "drm_bridge_add() failed: %d\n", ret);
- goto fail;
- }
+ drm_bridge_add(&dvi->bridge);
return 0;
fail:
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c
index d893ea21a359..69c4e352dd78 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.c
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -132,7 +132,6 @@ static struct drm_driver driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM,
.load = cirrus_driver_load,
.unload = cirrus_driver_unload,
- .set_busid = drm_pci_set_busid,
.fops = &cirrus_driver_fops,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
@@ -143,7 +142,6 @@ static struct drm_driver driver = {
.gem_free_object_unlocked = cirrus_gem_free_object,
.dumb_create = cirrus_dumb_create,
.dumb_map_offset = cirrus_dumb_mmap_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
};
static const struct dev_pm_ops cirrus_pm_ops = {
@@ -166,12 +164,12 @@ static int __init cirrus_init(void)
if (cirrus_modeset == 0)
return -EINVAL;
- return drm_pci_init(&driver, &cirrus_pci_driver);
+ return pci_register_driver(&cirrus_pci_driver);
}
static void __exit cirrus_exit(void)
{
- drm_pci_exit(&driver, &cirrus_pci_driver);
+ pci_unregister_driver(&cirrus_pci_driver);
}
module_init(cirrus_init);
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h
index 8690352d96f7..be2d7e488062 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.h
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.h
@@ -96,7 +96,6 @@
struct cirrus_crtc {
struct drm_crtc base;
- u8 lut_r[256], lut_g[256], lut_b[256];
int last_dpms;
bool enabled;
};
@@ -180,13 +179,6 @@ cirrus_bo(struct ttm_buffer_object *bo)
#define to_cirrus_obj(x) container_of(x, struct cirrus_gem_object, base)
#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
- /* cirrus_mode.c */
-void cirrus_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno);
-void cirrus_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno);
-
-
/* cirrus_main.c */
int cirrus_device_init(struct cirrus_device *cdev,
struct drm_device *ddev,
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
index 7fa58eeadc9d..32fbfba2c623 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -215,7 +215,6 @@ static int cirrusfb_create(struct drm_fb_helper *helper,
strcpy(info->fix.id, "cirrusdrmfb");
- info->flags = FBINFO_DEFAULT;
info->fbops = &cirrusfb_ops;
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
@@ -252,7 +251,7 @@ static int cirrus_fbdev_destroy(struct drm_device *dev,
drm_fb_helper_unregister_fbi(&gfbdev->helper);
if (gfb->obj) {
- drm_gem_object_unreference_unlocked(gfb->obj);
+ drm_gem_object_put_unlocked(gfb->obj);
gfb->obj = NULL;
}
@@ -265,8 +264,6 @@ static int cirrus_fbdev_destroy(struct drm_device *dev,
}
static const struct drm_fb_helper_funcs cirrus_fb_helper_funcs = {
- .gamma_set = cirrus_crtc_fb_gamma_set,
- .gamma_get = cirrus_crtc_fb_gamma_get,
.fb_probe = cirrusfb_create,
};
diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c
index e7fc95f63dca..b5f528543956 100644
--- a/drivers/gpu/drm/cirrus/cirrus_main.c
+++ b/drivers/gpu/drm/cirrus/cirrus_main.c
@@ -18,7 +18,7 @@ static void cirrus_user_framebuffer_destroy(struct drm_framebuffer *fb)
{
struct cirrus_framebuffer *cirrus_fb = to_cirrus_framebuffer(fb);
- drm_gem_object_unreference_unlocked(cirrus_fb->obj);
+ drm_gem_object_put_unlocked(cirrus_fb->obj);
drm_framebuffer_cleanup(fb);
kfree(fb);
}
@@ -67,13 +67,13 @@ cirrus_user_framebuffer_create(struct drm_device *dev,
cirrus_fb = kzalloc(sizeof(*cirrus_fb), GFP_KERNEL);
if (!cirrus_fb) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(-ENOMEM);
}
ret = cirrus_framebuffer_init(dev, cirrus_fb, mode_cmd, obj);
if (ret) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
kfree(cirrus_fb);
return ERR_PTR(ret);
}
@@ -261,7 +261,7 @@ int cirrus_dumb_create(struct drm_file *file,
return ret;
ret = drm_gem_handle_create(file, gobj, &handle);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (ret)
return ret;
@@ -310,7 +310,7 @@ cirrus_dumb_mmap_offset(struct drm_file *file,
bo = gem_to_cirrus_bo(obj);
*offset = cirrus_bo_mmap_offset(bo);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return 0;
}
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 53f6f0f84206..a4c4a465b385 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -31,25 +31,6 @@
* This file contains setup code for the CRTC.
*/
-static void cirrus_crtc_load_lut(struct drm_crtc *crtc)
-{
- struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc);
- struct drm_device *dev = crtc->dev;
- struct cirrus_device *cdev = dev->dev_private;
- int i;
-
- if (!crtc->enabled)
- return;
-
- for (i = 0; i < CIRRUS_LUT_SIZE; i++) {
- /* VGA registers */
- WREG8(PALETTE_INDEX, i);
- WREG8(PALETTE_DATA, cirrus_crtc->lut_r[i]);
- WREG8(PALETTE_DATA, cirrus_crtc->lut_g[i]);
- WREG8(PALETTE_DATA, cirrus_crtc->lut_b[i]);
- }
-}
-
/*
* The DRM core requires DPMS functions, but they make little sense in our
* case and so are just stubs
@@ -330,15 +311,25 @@ static int cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct cirrus_device *cdev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
- for (i = 0; i < size; i++) {
- cirrus_crtc->lut_r[i] = red[i];
- cirrus_crtc->lut_g[i] = green[i];
- cirrus_crtc->lut_b[i] = blue[i];
+ if (!crtc->enabled)
+ return 0;
+
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
+
+ for (i = 0; i < CIRRUS_LUT_SIZE; i++) {
+ /* VGA registers */
+ WREG8(PALETTE_INDEX, i);
+ WREG8(PALETTE_DATA, *r++ >> 8);
+ WREG8(PALETTE_DATA, *g++ >> 8);
+ WREG8(PALETTE_DATA, *b++ >> 8);
}
- cirrus_crtc_load_lut(crtc);
return 0;
}
@@ -365,7 +356,6 @@ static const struct drm_crtc_helper_funcs cirrus_helper_funcs = {
.mode_set_base = cirrus_crtc_mode_set_base,
.prepare = cirrus_crtc_prepare,
.commit = cirrus_crtc_commit,
- .load_lut = cirrus_crtc_load_lut,
};
/* CRTC setup */
@@ -373,7 +363,6 @@ static void cirrus_crtc_init(struct drm_device *dev)
{
struct cirrus_device *cdev = dev->dev_private;
struct cirrus_crtc *cirrus_crtc;
- int i;
cirrus_crtc = kzalloc(sizeof(struct cirrus_crtc) +
(CIRRUSFB_CONN_LIMIT * sizeof(struct drm_connector *)),
@@ -387,37 +376,9 @@ static void cirrus_crtc_init(struct drm_device *dev)
drm_mode_crtc_set_gamma_size(&cirrus_crtc->base, CIRRUS_LUT_SIZE);
cdev->mode_info.crtc = cirrus_crtc;
- for (i = 0; i < CIRRUS_LUT_SIZE; i++) {
- cirrus_crtc->lut_r[i] = i;
- cirrus_crtc->lut_g[i] = i;
- cirrus_crtc->lut_b[i] = i;
- }
-
drm_crtc_helper_add(&cirrus_crtc->base, &cirrus_helper_funcs);
}
-/** Sets the color ramps on behalf of fbcon */
-void cirrus_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
- struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc);
-
- cirrus_crtc->lut_r[regno] = red;
- cirrus_crtc->lut_g[regno] = green;
- cirrus_crtc->lut_b[regno] = blue;
-}
-
-/** Gets the color ramps on behalf of fbcon */
-void cirrus_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno)
-{
- struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc);
-
- *red = cirrus_crtc->lut_r[regno];
- *green = cirrus_crtc->lut_g[regno];
- *blue = cirrus_crtc->lut_b[regno];
-}
-
static void cirrus_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index c0f336d23f9c..1b755439f591 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -29,7 +29,6 @@
#include <drm/drmP.h>
#include <drm/drm_atomic.h>
#include <drm/drm_mode.h>
-#include <drm/drm_plane_helper.h>
#include <drm/drm_print.h>
#include <linux/sync_file.h>
@@ -188,12 +187,15 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
}
for (i = 0; i < state->num_private_objs; i++) {
- void *obj_state = state->private_objs[i].obj_state;
+ struct drm_private_obj *obj = state->private_objs[i].ptr;
- state->private_objs[i].funcs->destroy_state(obj_state);
- state->private_objs[i].obj = NULL;
- state->private_objs[i].obj_state = NULL;
- state->private_objs[i].funcs = NULL;
+ if (!obj)
+ continue;
+
+ obj->funcs->atomic_destroy_state(obj,
+ state->private_objs[i].state);
+ state->private_objs[i].ptr = NULL;
+ state->private_objs[i].state = NULL;
}
state->num_private_objs = 0;
@@ -409,34 +411,6 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
}
EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc);
-/**
- * drm_atomic_replace_property_blob - replace a blob property
- * @blob: a pointer to the member blob to be replaced
- * @new_blob: the new blob to replace with
- * @replaced: whether the blob has been replaced
- *
- * RETURNS:
- * Zero on success, error code on failure
- */
-static void
-drm_atomic_replace_property_blob(struct drm_property_blob **blob,
- struct drm_property_blob *new_blob,
- bool *replaced)
-{
- struct drm_property_blob *old_blob = *blob;
-
- if (old_blob == new_blob)
- return;
-
- drm_property_blob_put(old_blob);
- if (new_blob)
- drm_property_blob_get(new_blob);
- *blob = new_blob;
- *replaced = true;
-
- return;
-}
-
static int
drm_atomic_replace_property_blob_from_id(struct drm_device *dev,
struct drm_property_blob **blob,
@@ -457,7 +431,7 @@ drm_atomic_replace_property_blob_from_id(struct drm_device *dev,
}
}
- drm_atomic_replace_property_blob(blob, new_blob, replaced);
+ *replaced |= drm_property_replace_blob(blob, new_blob);
drm_property_blob_put(new_blob);
return 0;
@@ -739,7 +713,7 @@ EXPORT_SYMBOL(drm_atomic_get_plane_state);
* RETURNS:
* Zero on success, error code on failure
*/
-int drm_atomic_plane_set_property(struct drm_plane *plane,
+static int drm_atomic_plane_set_property(struct drm_plane *plane,
struct drm_plane_state *state, struct drm_property *property,
uint64_t val)
{
@@ -796,7 +770,6 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
return 0;
}
-EXPORT_SYMBOL(drm_atomic_plane_set_property);
/**
* drm_atomic_plane_get_property - get property value from plane state
@@ -991,11 +964,44 @@ static void drm_atomic_plane_print_state(struct drm_printer *p,
}
/**
+ * drm_atomic_private_obj_init - initialize private object
+ * @obj: private object
+ * @state: initial private object state
+ * @funcs: pointer to the struct of function pointers that identify the object
+ * type
+ *
+ * Initialize the private object, which can be embedded into any
+ * driver private object that needs its own atomic state.
+ */
+void
+drm_atomic_private_obj_init(struct drm_private_obj *obj,
+ struct drm_private_state *state,
+ const struct drm_private_state_funcs *funcs)
+{
+ memset(obj, 0, sizeof(*obj));
+
+ obj->state = state;
+ obj->funcs = funcs;
+}
+EXPORT_SYMBOL(drm_atomic_private_obj_init);
+
+/**
+ * drm_atomic_private_obj_fini - finalize private object
+ * @obj: private object
+ *
+ * Finalize the private object.
+ */
+void
+drm_atomic_private_obj_fini(struct drm_private_obj *obj)
+{
+ obj->funcs->atomic_destroy_state(obj, obj->state);
+}
+EXPORT_SYMBOL(drm_atomic_private_obj_fini);
+
+/**
* drm_atomic_get_private_obj_state - get private object state
* @state: global atomic state
* @obj: private object to get the state for
- * @funcs: pointer to the struct of function pointers that identify the object
- * type
*
* This function returns the private object state for the given private object,
* allocating the state if needed. It does not grab any locks as the caller is
@@ -1005,18 +1011,18 @@ static void drm_atomic_plane_print_state(struct drm_printer *p,
*
* Either the allocated state or the error code encoded into a pointer.
*/
-void *
-drm_atomic_get_private_obj_state(struct drm_atomic_state *state, void *obj,
- const struct drm_private_state_funcs *funcs)
+struct drm_private_state *
+drm_atomic_get_private_obj_state(struct drm_atomic_state *state,
+ struct drm_private_obj *obj)
{
int index, num_objs, i;
size_t size;
struct __drm_private_objs_state *arr;
+ struct drm_private_state *obj_state;
for (i = 0; i < state->num_private_objs; i++)
- if (obj == state->private_objs[i].obj &&
- state->private_objs[i].obj_state)
- return state->private_objs[i].obj_state;
+ if (obj == state->private_objs[i].ptr)
+ return state->private_objs[i].state;
num_objs = state->num_private_objs + 1;
size = sizeof(*state->private_objs) * num_objs;
@@ -1028,18 +1034,21 @@ drm_atomic_get_private_obj_state(struct drm_atomic_state *state, void *obj,
index = state->num_private_objs;
memset(&state->private_objs[index], 0, sizeof(*state->private_objs));
- state->private_objs[index].obj_state = funcs->duplicate_state(state, obj);
- if (!state->private_objs[index].obj_state)
+ obj_state = obj->funcs->atomic_duplicate_state(obj);
+ if (!obj_state)
return ERR_PTR(-ENOMEM);
- state->private_objs[index].obj = obj;
- state->private_objs[index].funcs = funcs;
+ state->private_objs[index].state = obj_state;
+ state->private_objs[index].old_state = obj->state;
+ state->private_objs[index].new_state = obj_state;
+ state->private_objs[index].ptr = obj;
+
state->num_private_objs = num_objs;
- DRM_DEBUG_ATOMIC("Added new private object state %p to %p\n",
- state->private_objs[index].obj_state, state);
+ DRM_DEBUG_ATOMIC("Added new private object %p state %p to %p\n",
+ obj, obj_state, state);
- return state->private_objs[index].obj_state;
+ return obj_state;
}
EXPORT_SYMBOL(drm_atomic_get_private_obj_state);
@@ -1135,7 +1144,7 @@ EXPORT_SYMBOL(drm_atomic_get_connector_state);
* RETURNS:
* Zero on success, error code on failure
*/
-int drm_atomic_connector_set_property(struct drm_connector *connector,
+static int drm_atomic_connector_set_property(struct drm_connector *connector,
struct drm_connector_state *state, struct drm_property *property,
uint64_t val)
{
@@ -1202,7 +1211,6 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
return 0;
}
-EXPORT_SYMBOL(drm_atomic_connector_set_property);
static void drm_atomic_connector_print_state(struct drm_printer *p,
const struct drm_connector_state *state)
@@ -1580,38 +1588,6 @@ drm_atomic_add_affected_planes(struct drm_atomic_state *state,
EXPORT_SYMBOL(drm_atomic_add_affected_planes);
/**
- * drm_atomic_legacy_backoff - locking backoff for legacy ioctls
- * @state: atomic state
- *
- * This function should be used by legacy entry points which don't understand
- * -EDEADLK semantics. For simplicity this one will grab all modeset locks after
- * the slowpath completed.
- */
-void drm_atomic_legacy_backoff(struct drm_atomic_state *state)
-{
- struct drm_device *dev = state->dev;
- int ret;
- bool global = false;
-
- if (WARN_ON(dev->mode_config.acquire_ctx == state->acquire_ctx)) {
- global = true;
-
- dev->mode_config.acquire_ctx = NULL;
- }
-
-retry:
- drm_modeset_backoff(state->acquire_ctx);
-
- ret = drm_modeset_lock_all_ctx(dev, state->acquire_ctx);
- if (ret)
- goto retry;
-
- if (global)
- dev->mode_config.acquire_ctx = state->acquire_ctx;
-}
-EXPORT_SYMBOL(drm_atomic_legacy_backoff);
-
-/**
* drm_atomic_check_only - check whether a given config would work
* @state: atomic configuration to check
*
@@ -1854,9 +1830,60 @@ static struct drm_pending_vblank_event *create_vblank_event(
return e;
}
-static int atomic_set_prop(struct drm_atomic_state *state,
- struct drm_mode_object *obj, struct drm_property *prop,
- uint64_t prop_value)
+int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
+ struct drm_connector *connector,
+ int mode)
+{
+ struct drm_connector *tmp_connector;
+ struct drm_connector_state *new_conn_state;
+ struct drm_crtc *crtc;
+ struct drm_crtc_state *crtc_state;
+ int i, ret, old_mode = connector->dpms;
+ bool active = false;
+
+ ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex,
+ state->acquire_ctx);
+ if (ret)
+ return ret;
+
+ if (mode != DRM_MODE_DPMS_ON)
+ mode = DRM_MODE_DPMS_OFF;
+ connector->dpms = mode;
+
+ crtc = connector->state->crtc;
+ if (!crtc)
+ goto out;
+ ret = drm_atomic_add_affected_connectors(state, crtc);
+ if (ret)
+ goto out;
+
+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
+ if (IS_ERR(crtc_state)) {
+ ret = PTR_ERR(crtc_state);
+ goto out;
+ }
+
+ for_each_new_connector_in_state(state, tmp_connector, new_conn_state, i) {
+ if (new_conn_state->crtc != crtc)
+ continue;
+ if (tmp_connector->dpms == DRM_MODE_DPMS_ON) {
+ active = true;
+ break;
+ }
+ }
+
+ crtc_state->active = active;
+ ret = drm_atomic_commit(state);
+out:
+ if (ret != 0)
+ connector->dpms = old_mode;
+ return ret;
+}
+
+int drm_atomic_set_property(struct drm_atomic_state *state,
+ struct drm_mode_object *obj,
+ struct drm_property *prop,
+ uint64_t prop_value)
{
struct drm_mode_object *ref;
int ret;
@@ -2039,7 +2066,7 @@ static int prepare_crtc_signaling(struct drm_device *dev,
{
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
- int i, ret;
+ int i, c = 0, ret;
if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY)
return 0;
@@ -2100,8 +2127,17 @@ static int prepare_crtc_signaling(struct drm_device *dev,
crtc_state->event->base.fence = fence;
}
+
+ c++;
}
+ /*
+ * Having this flag means user mode pends on event which will never
+ * reach due to lack of at least one CRTC for signaling
+ */
+ if (c == 0 && (arg->flags & DRM_MODE_PAGE_FLIP_EVENT))
+ return -EINVAL;
+
return 0;
}
@@ -2267,7 +2303,8 @@ retry:
goto out;
}
- ret = atomic_set_prop(state, obj, prop, prop_value);
+ ret = drm_atomic_set_property(state, obj, prop,
+ prop_value);
if (ret) {
drm_mode_object_put(obj);
goto out;
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 86d3093c6c9b..4e53aae9a1fb 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -795,6 +795,9 @@ int drm_atomic_helper_check(struct drm_device *dev,
if (ret)
return ret;
+ if (state->legacy_cursor_update)
+ state->async_update = !drm_atomic_helper_async_check(dev, state);
+
return ret;
}
EXPORT_SYMBOL(drm_atomic_helper_check);
@@ -918,16 +921,12 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
crtc = new_conn_state->crtc;
if ((!crtc && old_conn_state->crtc) ||
(crtc && drm_atomic_crtc_needs_modeset(crtc->state))) {
- struct drm_property *dpms_prop =
- dev->mode_config.dpms_property;
int mode = DRM_MODE_DPMS_OFF;
if (crtc && crtc->state->active)
mode = DRM_MODE_DPMS_ON;
connector->dpms = mode;
- drm_object_property_set_value(&connector->base,
- dpms_prop, mode);
}
}
@@ -1069,12 +1068,13 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
struct drm_atomic_state *old_state)
{
struct drm_crtc *crtc;
+ struct drm_crtc_state *old_crtc_state;
struct drm_crtc_state *new_crtc_state;
struct drm_connector *connector;
struct drm_connector_state *new_conn_state;
int i;
- for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
+ for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
const struct drm_crtc_helper_funcs *funcs;
/* Need to filter out CRTCs where only planes change. */
@@ -1090,8 +1090,8 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
DRM_DEBUG_ATOMIC("enabling [CRTC:%d:%s]\n",
crtc->base.id, crtc->name);
- if (funcs->enable)
- funcs->enable(crtc);
+ if (funcs->atomic_enable)
+ funcs->atomic_enable(crtc, old_crtc_state);
else
funcs->commit(crtc);
}
@@ -1191,9 +1191,13 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_fences);
*
* Helper to, after atomic commit, wait for vblanks on all effected
* crtcs (ie. before cleaning up old framebuffers using
- * drm_atomic_helper_cleanup_planes()). It will only wait on crtcs where the
+ * drm_atomic_helper_cleanup_planes()). It will only wait on CRTCs where the
* framebuffers have actually changed to optimize for the legacy cursor and
* plane update use-case.
+ *
+ * Drivers using the nonblocking commit tracking support initialized by calling
+ * drm_atomic_helper_setup_commit() should look at
+ * drm_atomic_helper_wait_for_flip_done() as an alternative.
*/
void
drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
@@ -1241,27 +1245,54 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
/**
+ * drm_atomic_helper_wait_for_flip_done - wait for all page flips to be done
+ * @dev: DRM device
+ * @old_state: atomic state object with old state structures
+ *
+ * Helper to, after atomic commit, wait for page flips on all effected
+ * crtcs (ie. before cleaning up old framebuffers using
+ * drm_atomic_helper_cleanup_planes()). Compared to
+ * drm_atomic_helper_wait_for_vblanks() this waits for the completion of on all
+ * CRTCs, assuming that cursors-only updates are signalling their completion
+ * immediately (or using a different path).
+ *
+ * This requires that drivers use the nonblocking commit tracking support
+ * initialized using drm_atomic_helper_setup_commit().
+ */
+void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev,
+ struct drm_atomic_state *old_state)
+{
+ struct drm_crtc_state *unused;
+ struct drm_crtc *crtc;
+ int i;
+
+ for_each_new_crtc_in_state(old_state, crtc, unused, i) {
+ struct drm_crtc_commit *commit = old_state->crtcs[i].commit;
+ int ret;
+
+ if (!commit)
+ continue;
+
+ ret = wait_for_completion_timeout(&commit->flip_done, 10 * HZ);
+ if (ret == 0)
+ DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
+ crtc->base.id, crtc->name);
+ }
+}
+EXPORT_SYMBOL(drm_atomic_helper_wait_for_flip_done);
+
+/**
* drm_atomic_helper_commit_tail - commit atomic update to hardware
* @old_state: atomic state object with old state structures
*
* This is the default implementation for the
- * &drm_mode_config_helper_funcs.atomic_commit_tail hook.
+ * &drm_mode_config_helper_funcs.atomic_commit_tail hook, for drivers
+ * that do not support runtime_pm or do not need the CRTC to be
+ * enabled to perform a commit. Otherwise, see
+ * drm_atomic_helper_commit_tail_rpm().
*
* Note that the default ordering of how the various stages are called is to
- * match the legacy modeset helper library closest. One peculiarity of that is
- * that it doesn't mesh well with runtime PM at all.
- *
- * For drivers supporting runtime PM the recommended sequence is instead ::
- *
- * drm_atomic_helper_commit_modeset_disables(dev, old_state);
- *
- * drm_atomic_helper_commit_modeset_enables(dev, old_state);
- *
- * drm_atomic_helper_commit_planes(dev, old_state,
- * DRM_PLANE_COMMIT_ACTIVE_ONLY);
- *
- * for committing the atomic update to hardware. See the kerneldoc entries for
- * these three functions for more details.
+ * match the legacy modeset helper library closest.
*/
void drm_atomic_helper_commit_tail(struct drm_atomic_state *old_state)
{
@@ -1281,6 +1312,35 @@ void drm_atomic_helper_commit_tail(struct drm_atomic_state *old_state)
}
EXPORT_SYMBOL(drm_atomic_helper_commit_tail);
+/**
+ * drm_atomic_helper_commit_tail_rpm - commit atomic update to hardware
+ * @old_state: new modeset state to be committed
+ *
+ * This is an alternative implementation for the
+ * &drm_mode_config_helper_funcs.atomic_commit_tail hook, for drivers
+ * that support runtime_pm or need the CRTC to be enabled to perform a
+ * commit. Otherwise, one should use the default implementation
+ * drm_atomic_helper_commit_tail().
+ */
+void drm_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state)
+{
+ struct drm_device *dev = old_state->dev;
+
+ drm_atomic_helper_commit_modeset_disables(dev, old_state);
+
+ drm_atomic_helper_commit_modeset_enables(dev, old_state);
+
+ drm_atomic_helper_commit_planes(dev, old_state,
+ DRM_PLANE_COMMIT_ACTIVE_ONLY);
+
+ drm_atomic_helper_commit_hw_done(old_state);
+
+ drm_atomic_helper_wait_for_vblanks(dev, old_state);
+
+ drm_atomic_helper_cleanup_planes(dev, old_state);
+}
+EXPORT_SYMBOL(drm_atomic_helper_commit_tail_rpm);
+
static void commit_tail(struct drm_atomic_state *old_state)
{
struct drm_device *dev = old_state->dev;
@@ -1311,6 +1371,114 @@ static void commit_work(struct work_struct *work)
}
/**
+ * drm_atomic_helper_async_check - check if state can be commited asynchronously
+ * @dev: DRM device
+ * @state: the driver state object
+ *
+ * This helper will check if it is possible to commit the state asynchronously.
+ * Async commits are not supposed to swap the states like normal sync commits
+ * but just do in-place changes on the current state.
+ *
+ * It will return 0 if the commit can happen in an asynchronous fashion or error
+ * if not. Note that error just mean it can't be commited asynchronously, if it
+ * fails the commit should be treated like a normal synchronous commit.
+ */
+int drm_atomic_helper_async_check(struct drm_device *dev,
+ struct drm_atomic_state *state)
+{
+ struct drm_crtc *crtc;
+ struct drm_crtc_state *crtc_state;
+ struct drm_crtc_commit *commit;
+ struct drm_plane *__plane, *plane = NULL;
+ struct drm_plane_state *__plane_state, *plane_state = NULL;
+ const struct drm_plane_helper_funcs *funcs;
+ int i, j, n_planes = 0;
+
+ for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
+ if (drm_atomic_crtc_needs_modeset(crtc_state))
+ return -EINVAL;
+ }
+
+ for_each_new_plane_in_state(state, __plane, __plane_state, i) {
+ n_planes++;
+ plane = __plane;
+ plane_state = __plane_state;
+ }
+
+ /* FIXME: we support only single plane updates for now */
+ if (!plane || n_planes != 1)
+ return -EINVAL;
+
+ if (!plane_state->crtc)
+ return -EINVAL;
+
+ funcs = plane->helper_private;
+ if (!funcs->atomic_async_update)
+ return -EINVAL;
+
+ if (plane_state->fence)
+ return -EINVAL;
+
+ /*
+ * Don't do an async update if there is an outstanding commit modifying
+ * the plane. This prevents our async update's changes from getting
+ * overridden by a previous synchronous update's state.
+ */
+ for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
+ if (plane->crtc != crtc)
+ continue;
+
+ spin_lock(&crtc->commit_lock);
+ commit = list_first_entry_or_null(&crtc->commit_list,
+ struct drm_crtc_commit,
+ commit_entry);
+ if (!commit) {
+ spin_unlock(&crtc->commit_lock);
+ continue;
+ }
+ spin_unlock(&crtc->commit_lock);
+
+ if (!crtc->state->state)
+ continue;
+
+ for_each_plane_in_state(crtc->state->state, __plane,
+ __plane_state, j) {
+ if (__plane == plane)
+ return -EINVAL;
+ }
+ }
+
+ return funcs->atomic_async_check(plane, plane_state);
+}
+EXPORT_SYMBOL(drm_atomic_helper_async_check);
+
+/**
+ * drm_atomic_helper_async_commit - commit state asynchronously
+ * @dev: DRM device
+ * @state: the driver state object
+ *
+ * This function commits a state asynchronously, i.e., not vblank
+ * synchronized. It should be used on a state only when
+ * drm_atomic_async_check() succeeds. Async commits are not supposed to swap
+ * the states like normal sync commits, but just do in-place changes on the
+ * current state.
+ */
+void drm_atomic_helper_async_commit(struct drm_device *dev,
+ struct drm_atomic_state *state)
+{
+ struct drm_plane *plane;
+ struct drm_plane_state *plane_state;
+ const struct drm_plane_helper_funcs *funcs;
+ int i;
+
+ for_each_new_plane_in_state(state, plane, plane_state, i) {
+ funcs = plane->helper_private;
+ funcs->atomic_async_update(plane, plane_state);
+ }
+}
+EXPORT_SYMBOL(drm_atomic_helper_async_commit);
+
+/**
* drm_atomic_helper_commit - commit validated state object
* @dev: DRM device
* @state: the driver state object
@@ -1334,6 +1502,17 @@ int drm_atomic_helper_commit(struct drm_device *dev,
{
int ret;
+ if (state->async_update) {
+ ret = drm_atomic_helper_prepare_planes(dev, state);
+ if (ret)
+ return ret;
+
+ drm_atomic_helper_async_commit(dev, state);
+ drm_atomic_helper_cleanup_planes(dev, state);
+
+ return 0;
+ }
+
ret = drm_atomic_helper_setup_commit(state, nonblock);
if (ret)
return ret;
@@ -1346,10 +1525,8 @@ int drm_atomic_helper_commit(struct drm_device *dev,
if (!nonblock) {
ret = drm_atomic_helper_wait_for_fences(dev, state, true);
- if (ret) {
- drm_atomic_helper_cleanup_planes(dev, state);
- return ret;
- }
+ if (ret)
+ goto err;
}
/*
@@ -1358,7 +1535,9 @@ int drm_atomic_helper_commit(struct drm_device *dev,
* the software side now.
*/
- drm_atomic_helper_swap_state(state, true);
+ ret = drm_atomic_helper_swap_state(state, true);
+ if (ret)
+ goto err;
/*
* Everything below can be run asynchronously without the need to grab
@@ -1387,6 +1566,10 @@ int drm_atomic_helper_commit(struct drm_device *dev,
commit_tail(state);
return 0;
+
+err:
+ drm_atomic_helper_cleanup_planes(dev, state);
+ return ret;
}
EXPORT_SYMBOL(drm_atomic_helper_commit);
@@ -1680,9 +1863,7 @@ void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *old_state)
/* backend must have consumed any event by now */
WARN_ON(new_crtc_state->event);
- spin_lock(&crtc->commit_lock);
complete_all(&commit->hw_done);
- spin_unlock(&crtc->commit_lock);
}
}
EXPORT_SYMBOL(drm_atomic_helper_commit_hw_done);
@@ -1711,7 +1892,6 @@ void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state)
if (WARN_ON(!commit))
continue;
- spin_lock(&crtc->commit_lock);
complete_all(&commit->cleanup_done);
WARN_ON(!try_wait_for_completion(&commit->hw_done));
@@ -1721,8 +1901,6 @@ void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state)
if (try_wait_for_completion(&commit->flip_done))
goto del_commit;
- spin_unlock(&crtc->commit_lock);
-
/* We must wait for the vblank event to signal our completion
* before releasing our reference, since the vblank work does
* not hold a reference of its own. */
@@ -1732,8 +1910,8 @@ void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state)
DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
crtc->base.id, crtc->name);
- spin_lock(&crtc->commit_lock);
del_commit:
+ spin_lock(&crtc->commit_lock);
list_del(&commit->commit_entry);
spin_unlock(&crtc->commit_lock);
}
@@ -2069,14 +2247,14 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
/**
* drm_atomic_helper_swap_state - store atomic state into current sw state
* @state: atomic state
- * @stall: stall for proceeding commits
+ * @stall: stall for preceeding commits
*
* This function stores the atomic state into the current state pointers in all
* driver objects. It should be called after all failing steps have been done
* and succeeded, but before the actual hardware state is committed.
*
* For cleanup and error recovery the current state for all changed objects will
- * be swaped into @state.
+ * be swapped into @state.
*
* With that sequence it fits perfectly into the plane prepare/cleanup sequence:
*
@@ -2095,12 +2273,16 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
* the &drm_plane.state, &drm_crtc.state or &drm_connector.state pointer. With
* the current atomic helpers this is almost always the case, since the helpers
* don't pass the right state structures to the callbacks.
+ *
+ * Returns:
+ *
+ * Returns 0 on success. Can return -ERESTARTSYS when @stall is true and the
+ * waiting for the previous commits has been interrupted.
*/
-void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
+int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
bool stall)
{
- int i;
- long ret;
+ int i, ret;
struct drm_connector *connector;
struct drm_connector_state *old_conn_state, *new_conn_state;
struct drm_crtc *crtc;
@@ -2108,8 +2290,8 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
struct drm_plane *plane;
struct drm_plane_state *old_plane_state, *new_plane_state;
struct drm_crtc_commit *commit;
- void *obj, *obj_state;
- const struct drm_private_state_funcs *funcs;
+ struct drm_private_obj *obj;
+ struct drm_private_state *old_obj_state, *new_obj_state;
if (stall) {
for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
@@ -2123,12 +2305,11 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
if (!commit)
continue;
- ret = wait_for_completion_timeout(&commit->hw_done,
- 10*HZ);
- if (ret == 0)
- DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n",
- crtc->base.id, crtc->name);
+ ret = wait_for_completion_interruptible(&commit->hw_done);
drm_crtc_commit_put(commit);
+
+ if (ret)
+ return ret;
}
}
@@ -2171,8 +2352,17 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
plane->state = new_plane_state;
}
- __for_each_private_obj(state, obj, obj_state, i, funcs)
- funcs->swap_state(obj, &state->private_objs[i].obj_state);
+ for_each_oldnew_private_obj_in_state(state, obj, old_obj_state, new_obj_state, i) {
+ WARN_ON(obj->state != old_obj_state);
+
+ old_obj_state->state = state;
+ new_obj_state->state = NULL;
+
+ state->private_objs[i].state = old_obj_state;
+ obj->state = new_obj_state;
+ }
+
+ return 0;
}
EXPORT_SYMBOL(drm_atomic_helper_swap_state);
@@ -2526,6 +2716,7 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
struct drm_plane *plane;
struct drm_crtc_state *crtc_state;
struct drm_crtc *crtc;
+ unsigned plane_mask = 0;
int ret, i;
state = drm_atomic_state_alloc(dev);
@@ -2556,22 +2747,26 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
goto free;
}
- for_each_connector_in_state(state, conn, conn_state, i) {
+ for_each_new_connector_in_state(state, conn, conn_state, i) {
ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
if (ret < 0)
goto free;
}
- for_each_plane_in_state(state, plane, plane_state, i) {
+ for_each_new_plane_in_state(state, plane, plane_state, i) {
ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
if (ret < 0)
goto free;
drm_atomic_set_fb_for_plane(plane_state, NULL);
+ plane_mask |= BIT(drm_plane_index(plane));
+ plane->old_fb = plane->fb;
}
ret = drm_atomic_commit(state);
free:
+ if (plane_mask)
+ drm_atomic_clean_old_fb(dev, plane_mask, ret);
drm_atomic_state_put(state);
return ret;
}
@@ -2702,11 +2897,16 @@ int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
struct drm_connector_state *new_conn_state;
struct drm_crtc *crtc;
struct drm_crtc_state *new_crtc_state;
+ unsigned plane_mask = 0;
+ struct drm_device *dev = state->dev;
+ int ret;
state->acquire_ctx = ctx;
- for_each_new_plane_in_state(state, plane, new_plane_state, i)
+ for_each_new_plane_in_state(state, plane, new_plane_state, i) {
+ plane_mask |= BIT(drm_plane_index(plane));
state->planes[i].old_state = plane->state;
+ }
for_each_new_crtc_in_state(state, crtc, new_crtc_state, i)
state->crtcs[i].old_state = crtc->state;
@@ -2714,7 +2914,11 @@ int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
for_each_new_connector_in_state(state, connector, new_conn_state, i)
state->connectors[i].old_state = connector->state;
- return drm_atomic_commit(state);
+ ret = drm_atomic_commit(state);
+ if (plane_mask)
+ drm_atomic_clean_old_fb(dev, plane_mask, ret);
+
+ return ret;
}
EXPORT_SYMBOL(drm_atomic_helper_commit_duplicated_state);
@@ -2763,177 +2967,11 @@ out:
}
EXPORT_SYMBOL(drm_atomic_helper_resume);
-/**
- * drm_atomic_helper_crtc_set_property - helper for crtc properties
- * @crtc: DRM crtc
- * @property: DRM property
- * @val: value of property
- *
- * Provides a default crtc set_property handler using the atomic driver
- * interface.
- *
- * RETURNS:
- * Zero on success, error code on failure
- */
-int
-drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
- struct drm_property *property,
- uint64_t val)
-{
- struct drm_atomic_state *state;
- struct drm_crtc_state *crtc_state;
- int ret = 0;
-
- state = drm_atomic_state_alloc(crtc->dev);
- if (!state)
- return -ENOMEM;
-
- /* ->set_property is always called with all locks held. */
- state->acquire_ctx = crtc->dev->mode_config.acquire_ctx;
-retry:
- crtc_state = drm_atomic_get_crtc_state(state, crtc);
- if (IS_ERR(crtc_state)) {
- ret = PTR_ERR(crtc_state);
- goto fail;
- }
-
- ret = drm_atomic_crtc_set_property(crtc, crtc_state,
- property, val);
- if (ret)
- goto fail;
-
- ret = drm_atomic_commit(state);
-fail:
- if (ret == -EDEADLK)
- goto backoff;
-
- drm_atomic_state_put(state);
- return ret;
-
-backoff:
- drm_atomic_state_clear(state);
- drm_atomic_legacy_backoff(state);
-
- goto retry;
-}
-EXPORT_SYMBOL(drm_atomic_helper_crtc_set_property);
-
-/**
- * drm_atomic_helper_plane_set_property - helper for plane properties
- * @plane: DRM plane
- * @property: DRM property
- * @val: value of property
- *
- * Provides a default plane set_property handler using the atomic driver
- * interface.
- *
- * RETURNS:
- * Zero on success, error code on failure
- */
-int
-drm_atomic_helper_plane_set_property(struct drm_plane *plane,
- struct drm_property *property,
- uint64_t val)
-{
- struct drm_atomic_state *state;
- struct drm_plane_state *plane_state;
- int ret = 0;
-
- state = drm_atomic_state_alloc(plane->dev);
- if (!state)
- return -ENOMEM;
-
- /* ->set_property is always called with all locks held. */
- state->acquire_ctx = plane->dev->mode_config.acquire_ctx;
-retry:
- plane_state = drm_atomic_get_plane_state(state, plane);
- if (IS_ERR(plane_state)) {
- ret = PTR_ERR(plane_state);
- goto fail;
- }
-
- ret = drm_atomic_plane_set_property(plane, plane_state,
- property, val);
- if (ret)
- goto fail;
-
- ret = drm_atomic_commit(state);
-fail:
- if (ret == -EDEADLK)
- goto backoff;
-
- drm_atomic_state_put(state);
- return ret;
-
-backoff:
- drm_atomic_state_clear(state);
- drm_atomic_legacy_backoff(state);
-
- goto retry;
-}
-EXPORT_SYMBOL(drm_atomic_helper_plane_set_property);
-
-/**
- * drm_atomic_helper_connector_set_property - helper for connector properties
- * @connector: DRM connector
- * @property: DRM property
- * @val: value of property
- *
- * Provides a default connector set_property handler using the atomic driver
- * interface.
- *
- * RETURNS:
- * Zero on success, error code on failure
- */
-int
-drm_atomic_helper_connector_set_property(struct drm_connector *connector,
- struct drm_property *property,
- uint64_t val)
-{
- struct drm_atomic_state *state;
- struct drm_connector_state *connector_state;
- int ret = 0;
-
- state = drm_atomic_state_alloc(connector->dev);
- if (!state)
- return -ENOMEM;
-
- /* ->set_property is always called with all locks held. */
- state->acquire_ctx = connector->dev->mode_config.acquire_ctx;
-retry:
- connector_state = drm_atomic_get_connector_state(state, connector);
- if (IS_ERR(connector_state)) {
- ret = PTR_ERR(connector_state);
- goto fail;
- }
-
- ret = drm_atomic_connector_set_property(connector, connector_state,
- property, val);
- if (ret)
- goto fail;
-
- ret = drm_atomic_commit(state);
-fail:
- if (ret == -EDEADLK)
- goto backoff;
-
- drm_atomic_state_put(state);
- return ret;
-
-backoff:
- drm_atomic_state_clear(state);
- drm_atomic_legacy_backoff(state);
-
- goto retry;
-}
-EXPORT_SYMBOL(drm_atomic_helper_connector_set_property);
-
-static int page_flip_common(
- struct drm_atomic_state *state,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_pending_vblank_event *event,
- uint32_t flags)
+static int page_flip_common(struct drm_atomic_state *state,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_pending_vblank_event *event,
+ uint32_t flags)
{
struct drm_plane *plane = crtc->primary;
struct drm_plane_state *plane_state;
@@ -3027,13 +3065,12 @@ EXPORT_SYMBOL(drm_atomic_helper_page_flip);
* Returns:
* Returns 0 on success, negative errno numbers on failure.
*/
-int drm_atomic_helper_page_flip_target(
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_pending_vblank_event *event,
- uint32_t flags,
- uint32_t target,
- struct drm_modeset_acquire_ctx *ctx)
+int drm_atomic_helper_page_flip_target(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_pending_vblank_event *event,
+ uint32_t flags,
+ uint32_t target,
+ struct drm_modeset_acquire_ctx *ctx)
{
struct drm_plane *plane = crtc->primary;
struct drm_atomic_state *state;
@@ -3065,85 +3102,6 @@ fail:
EXPORT_SYMBOL(drm_atomic_helper_page_flip_target);
/**
- * drm_atomic_helper_connector_dpms() - connector dpms helper implementation
- * @connector: affected connector
- * @mode: DPMS mode
- *
- * This is the main helper function provided by the atomic helper framework for
- * implementing the legacy DPMS connector interface. It computes the new desired
- * &drm_crtc_state.active state for the corresponding CRTC (if the connector is
- * enabled) and updates it.
- *
- * Returns:
- * Returns 0 on success, negative errno numbers on failure.
- */
-int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
- int mode)
-{
- struct drm_mode_config *config = &connector->dev->mode_config;
- struct drm_atomic_state *state;
- struct drm_crtc_state *crtc_state;
- struct drm_crtc *crtc;
- struct drm_connector *tmp_connector;
- struct drm_connector_list_iter conn_iter;
- int ret;
- bool active = false;
- int old_mode = connector->dpms;
-
- if (mode != DRM_MODE_DPMS_ON)
- mode = DRM_MODE_DPMS_OFF;
-
- connector->dpms = mode;
- crtc = connector->state->crtc;
-
- if (!crtc)
- return 0;
-
- state = drm_atomic_state_alloc(connector->dev);
- if (!state)
- return -ENOMEM;
-
- state->acquire_ctx = crtc->dev->mode_config.acquire_ctx;
-retry:
- crtc_state = drm_atomic_get_crtc_state(state, crtc);
- if (IS_ERR(crtc_state)) {
- ret = PTR_ERR(crtc_state);
- goto fail;
- }
-
- WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
-
- drm_connector_list_iter_begin(connector->dev, &conn_iter);
- drm_for_each_connector_iter(tmp_connector, &conn_iter) {
- if (tmp_connector->state->crtc != crtc)
- continue;
-
- if (tmp_connector->dpms == DRM_MODE_DPMS_ON) {
- active = true;
- break;
- }
- }
- drm_connector_list_iter_end(&conn_iter);
- crtc_state->active = active;
-
- ret = drm_atomic_commit(state);
-fail:
- if (ret == -EDEADLK)
- goto backoff;
- if (ret != 0)
- connector->dpms = old_mode;
- drm_atomic_state_put(state);
- return ret;
-
-backoff:
- drm_atomic_state_clear(state);
- drm_atomic_legacy_backoff(state);
-
- goto retry;
-}
-EXPORT_SYMBOL(drm_atomic_helper_connector_dpms);
-
-/**
* drm_atomic_helper_best_encoder - Helper for
* &drm_connector_helper_funcs.best_encoder callback
* @connector: Connector control structure
@@ -3612,12 +3570,12 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_device *dev = crtc->dev;
- struct drm_mode_config *config = &dev->mode_config;
struct drm_atomic_state *state;
struct drm_crtc_state *crtc_state;
struct drm_property_blob *blob = NULL;
struct drm_color_lut *blob_data;
int i, ret = 0;
+ bool replaced;
state = drm_atomic_state_alloc(crtc->dev);
if (!state)
@@ -3648,20 +3606,10 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
}
/* Reset DEGAMMA_LUT and CTM properties. */
- ret = drm_atomic_crtc_set_property(crtc, crtc_state,
- config->degamma_lut_property, 0);
- if (ret)
- goto fail;
-
- ret = drm_atomic_crtc_set_property(crtc, crtc_state,
- config->ctm_property, 0);
- if (ret)
- goto fail;
-
- ret = drm_atomic_crtc_set_property(crtc, crtc_state,
- config->gamma_lut_property, blob->base.id);
- if (ret)
- goto fail;
+ replaced = drm_property_replace_blob(&crtc_state->degamma_lut, NULL);
+ replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL);
+ replaced |= drm_property_replace_blob(&crtc_state->gamma_lut, blob);
+ crtc_state->color_mgmt_changed |= replaced;
ret = drm_atomic_commit(state);
@@ -3671,3 +3619,18 @@ fail:
return ret;
}
EXPORT_SYMBOL(drm_atomic_helper_legacy_gamma_set);
+
+/**
+ * __drm_atomic_helper_private_duplicate_state - copy atomic private state
+ * @obj: CRTC object
+ * @state: new private object state
+ *
+ * Copies atomic state from a private objects's current state and resets inferred values.
+ * This is useful for drivers that subclass the private state.
+ */
+void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
+ struct drm_private_state *state)
+{
+ memcpy(state, obj->state, sizeof(*state));
+}
+EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state);
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 3eda500fc005..fe0982708e95 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -128,6 +128,9 @@ EXPORT_SYMBOL(drm_color_lut_extract);
* optional. The gamma and degamma properties are only attached if
* their size is not 0 and ctm_property is only attached if has_ctm is
* true.
+ *
+ * Drivers should use drm_atomic_helper_legacy_gamma_set() to implement the
+ * legacy &drm_crtc_funcs.gamma_set callback.
*/
void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
uint degamma_lut_size,
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 8072e6e4c62c..ba9f36cef68c 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -717,9 +717,9 @@ DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
* drivers, it remaps to controlling the "ACTIVE" property on the CRTC the
* connector is linked to. Drivers should never set this property directly,
* it is handled by the DRM core by calling the &drm_connector_funcs.dpms
- * callback. Atomic drivers should implement this hook using
- * drm_atomic_helper_connector_dpms(). This is the only property standard
- * connector property that userspace can change.
+ * callback. For atomic drivers the remapping to the "ACTIVE" property is
+ * implemented in the DRM core. This is the only standard connector
+ * property that userspace can change.
* PATH:
* Connector path property to identify how this sink is physically
* connected. Used by DP MST. This should be set by calling
@@ -1225,7 +1225,6 @@ int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
} else if (connector->funcs->set_property)
ret = connector->funcs->set_property(connector, property, value);
- /* store the property value if successful */
if (!ret)
drm_object_property_set_value(&connector->base, property, value);
return ret;
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 4afdf7902eda..eab36a460638 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -863,8 +863,7 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
* provided by the driver.
*
* This function is deprecated. New drivers must implement atomic modeset
- * support, for which this function is unsuitable. Instead drivers should use
- * drm_atomic_helper_connector_dpms().
+ * support, where DPMS is handled in the DRM core.
*
* Returns:
* Always returns 0.
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index d077c5490041..a43582076b20 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -178,6 +178,13 @@ struct drm_minor;
int drm_atomic_debugfs_init(struct drm_minor *minor);
#endif
+int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
+ struct drm_connector *connector,
+ int mode);
+int drm_atomic_set_property(struct drm_atomic_state *state,
+ struct drm_mode_object *obj,
+ struct drm_property *prop,
+ uint64_t prop_value);
int drm_atomic_get_property(struct drm_mode_object *obj,
struct drm_property *property, uint64_t *val);
int drm_mode_atomic_ioctl(struct drm_device *dev,
diff --git a/drivers/gpu/drm/drm_debugfs_crc.c b/drivers/gpu/drm/drm_debugfs_crc.c
index 1722d8f21449..f9e26dda56d6 100644
--- a/drivers/gpu/drm/drm_debugfs_crc.c
+++ b/drivers/gpu/drm/drm_debugfs_crc.c
@@ -136,21 +136,51 @@ static int crtc_crc_data_count(struct drm_crtc_crc *crc)
return CIRC_CNT(crc->head, crc->tail, DRM_CRC_ENTRIES_NR);
}
+static void crtc_crc_cleanup(struct drm_crtc_crc *crc)
+{
+ kfree(crc->entries);
+ crc->entries = NULL;
+ crc->head = 0;
+ crc->tail = 0;
+ crc->values_cnt = 0;
+ crc->opened = false;
+}
+
static int crtc_crc_open(struct inode *inode, struct file *filep)
{
struct drm_crtc *crtc = inode->i_private;
struct drm_crtc_crc *crc = &crtc->crc;
struct drm_crtc_crc_entry *entries = NULL;
size_t values_cnt;
- int ret;
+ int ret = 0;
- if (crc->opened)
- return -EBUSY;
+ if (drm_drv_uses_atomic_modeset(crtc->dev)) {
+ ret = drm_modeset_lock_interruptible(&crtc->mutex, NULL);
+ if (ret)
+ return ret;
+
+ if (!crtc->state->active)
+ ret = -EIO;
+ drm_modeset_unlock(&crtc->mutex);
+
+ if (ret)
+ return ret;
+ }
+
+ spin_lock_irq(&crc->lock);
+ if (!crc->opened)
+ crc->opened = true;
+ else
+ ret = -EBUSY;
+ spin_unlock_irq(&crc->lock);
- ret = crtc->funcs->set_crc_source(crtc, crc->source, &values_cnt);
if (ret)
return ret;
+ ret = crtc->funcs->set_crc_source(crtc, crc->source, &values_cnt);
+ if (ret)
+ goto err;
+
if (WARN_ON(values_cnt > DRM_MAX_CRC_NR)) {
ret = -EINVAL;
goto err_disable;
@@ -170,7 +200,6 @@ static int crtc_crc_open(struct inode *inode, struct file *filep)
spin_lock_irq(&crc->lock);
crc->entries = entries;
crc->values_cnt = values_cnt;
- crc->opened = true;
/*
* Only return once we got a first frame, so userspace doesn't have to
@@ -182,12 +211,17 @@ static int crtc_crc_open(struct inode *inode, struct file *filep)
crc->lock);
spin_unlock_irq(&crc->lock);
- WARN_ON(ret);
+ if (ret)
+ goto err_disable;
return 0;
err_disable:
crtc->funcs->set_crc_source(crtc, NULL, &values_cnt);
+err:
+ spin_lock_irq(&crc->lock);
+ crtc_crc_cleanup(crc);
+ spin_unlock_irq(&crc->lock);
return ret;
}
@@ -197,17 +231,12 @@ static int crtc_crc_release(struct inode *inode, struct file *filep)
struct drm_crtc_crc *crc = &crtc->crc;
size_t values_cnt;
+ crtc->funcs->set_crc_source(crtc, NULL, &values_cnt);
+
spin_lock_irq(&crc->lock);
- kfree(crc->entries);
- crc->entries = NULL;
- crc->head = 0;
- crc->tail = 0;
- crc->values_cnt = 0;
- crc->opened = false;
+ crtc_crc_cleanup(crc);
spin_unlock_irq(&crc->lock);
- crtc->funcs->set_crc_source(crtc, NULL, &values_cnt);
-
return 0;
}
@@ -334,7 +363,7 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame,
spin_lock(&crc->lock);
/* Caller may not have noticed yet that userspace has stopped reading */
- if (!crc->opened) {
+ if (!crc->entries) {
spin_unlock(&crc->lock);
return -EINVAL;
}
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 213fb837e1c4..08af8d6b844b 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -544,7 +544,7 @@ void drm_dp_downstream_debug(struct seq_file *m,
DP_DETAILED_CAP_INFO_AVAILABLE;
int clk;
int bpc;
- char id[6];
+ char id[7];
int len;
uint8_t rev[2];
int type = port_cap[0] & DP_DS_PORT_TYPE_MASK;
@@ -583,6 +583,7 @@ void drm_dp_downstream_debug(struct seq_file *m,
seq_puts(m, "\t\tType: N/A\n");
}
+ memset(id, 0, sizeof(id));
drm_dp_downstream_id(aux, id);
seq_printf(m, "\t\tID: %s\n", id);
@@ -591,7 +592,7 @@ void drm_dp_downstream_debug(struct seq_file *m,
seq_printf(m, "\t\tHW: %d.%d\n",
(rev[0] & 0xf0) >> 4, rev[0] & 0xf);
- len = drm_dp_dpcd_read(aux, DP_BRANCH_SW_REV, &rev, 2);
+ len = drm_dp_dpcd_read(aux, DP_BRANCH_SW_REV, rev, 2);
if (len > 0)
seq_printf(m, "\t\tSW: %d.%d\n", rev[0], rev[1]);
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index bfd237c15e76..41b492f99955 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -31,6 +31,8 @@
#include <drm/drmP.h>
#include <drm/drm_fixed.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
/**
* DOC: dp mst helper
@@ -330,6 +332,13 @@ static bool drm_dp_sideband_msg_build(struct drm_dp_sideband_msg_rx *msg,
return false;
}
+ /*
+ * ignore out-of-order messages or messages that are part of a
+ * failed transaction
+ */
+ if (!recv_hdr.somt && !msg->have_somt)
+ return false;
+
/* get length contained in this portion */
msg->curchunk_len = recv_hdr.msg_len;
msg->curchunk_hdrlen = hdrlen;
@@ -1335,15 +1344,17 @@ static void drm_dp_mst_link_probe_work(struct work_struct *work)
static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,
u8 *guid)
{
- static u8 zero_guid[16];
+ u64 salt;
- if (!memcmp(guid, zero_guid, 16)) {
- u64 salt = get_jiffies_64();
- memcpy(&guid[0], &salt, sizeof(u64));
- memcpy(&guid[8], &salt, sizeof(u64));
- return false;
- }
- return true;
+ if (memchr_inv(guid, 0, 16))
+ return true;
+
+ salt = get_jiffies_64();
+
+ memcpy(&guid[0], &salt, sizeof(u64));
+ memcpy(&guid[8], &salt, sizeof(u64));
+
+ return false;
}
#if 0
@@ -2164,7 +2175,7 @@ out_unlock:
}
EXPORT_SYMBOL(drm_dp_mst_topology_mgr_resume);
-static void drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up)
+static bool drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up)
{
int len;
u8 replyblock[32];
@@ -2179,12 +2190,12 @@ static void drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up)
replyblock, len);
if (ret != len) {
DRM_DEBUG_KMS("failed to read DPCD down rep %d %d\n", len, ret);
- return;
+ return false;
}
ret = drm_dp_sideband_msg_build(msg, replyblock, len, true);
if (!ret) {
DRM_DEBUG_KMS("sideband msg build failed %d\n", replyblock[0]);
- return;
+ return false;
}
replylen = msg->curchunk_len + msg->curchunk_hdrlen;
@@ -2196,21 +2207,32 @@ static void drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up)
ret = drm_dp_dpcd_read(mgr->aux, basereg + curreply,
replyblock, len);
if (ret != len) {
- DRM_DEBUG_KMS("failed to read a chunk\n");
+ DRM_DEBUG_KMS("failed to read a chunk (len %d, ret %d)\n",
+ len, ret);
+ return false;
}
+
ret = drm_dp_sideband_msg_build(msg, replyblock, len, false);
- if (ret == false)
+ if (!ret) {
DRM_DEBUG_KMS("failed to build sideband msg\n");
+ return false;
+ }
+
curreply += len;
replylen -= len;
}
+ return true;
}
static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
{
int ret = 0;
- drm_dp_get_one_sb_msg(mgr, false);
+ if (!drm_dp_get_one_sb_msg(mgr, false)) {
+ memset(&mgr->down_rep_recv, 0,
+ sizeof(struct drm_dp_sideband_msg_rx));
+ return 0;
+ }
if (mgr->down_rep_recv.have_eomt) {
struct drm_dp_sideband_msg_tx *txmsg;
@@ -2266,7 +2288,12 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
{
int ret = 0;
- drm_dp_get_one_sb_msg(mgr, true);
+
+ if (!drm_dp_get_one_sb_msg(mgr, true)) {
+ memset(&mgr->up_req_recv, 0,
+ sizeof(struct drm_dp_sideband_msg_rx));
+ return 0;
+ }
if (mgr->up_req_recv.have_eomt) {
struct drm_dp_sideband_msg_req_body msg;
@@ -2318,7 +2345,9 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
DRM_DEBUG_KMS("Got RSN: pn: %d avail_pbn %d\n", msg.u.resource_stat.port_number, msg.u.resource_stat.available_pbn);
}
- drm_dp_put_mst_branch_device(mstb);
+ if (mstb)
+ drm_dp_put_mst_branch_device(mstb);
+
memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
}
return ret;
@@ -2515,8 +2544,8 @@ int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,
int req_slots;
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
- if (topology_state == NULL)
- return -ENOMEM;
+ if (IS_ERR(topology_state))
+ return PTR_ERR(topology_state);
port = drm_dp_get_validated_port_ref(mgr, port);
if (port == NULL)
@@ -2555,8 +2584,8 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
struct drm_dp_mst_topology_state *topology_state;
topology_state = drm_atomic_get_mst_topology_state(state, mgr);
- if (topology_state == NULL)
- return -ENOMEM;
+ if (IS_ERR(topology_state))
+ return PTR_ERR(topology_state);
/* We cannot rely on port->vcpi.num_slots to update
* topology_state->avail_slots as the port may not exist if the parent
@@ -2992,41 +3021,32 @@ static void drm_dp_destroy_connector_work(struct work_struct *work)
(*mgr->cbs->hotplug)(mgr);
}
-void *drm_dp_mst_duplicate_state(struct drm_atomic_state *state, void *obj)
+static struct drm_private_state *
+drm_dp_mst_duplicate_state(struct drm_private_obj *obj)
{
- struct drm_dp_mst_topology_mgr *mgr = obj;
- struct drm_dp_mst_topology_state *new_mst_state;
+ struct drm_dp_mst_topology_state *state;
- if (WARN_ON(!mgr->state))
+ state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
+ if (!state)
return NULL;
- new_mst_state = kmemdup(mgr->state, sizeof(*new_mst_state), GFP_KERNEL);
- if (new_mst_state)
- new_mst_state->state = state;
- return new_mst_state;
-}
-
-void drm_dp_mst_swap_state(void *obj, void **obj_state_ptr)
-{
- struct drm_dp_mst_topology_mgr *mgr = obj;
- struct drm_dp_mst_topology_state **topology_state_ptr;
-
- topology_state_ptr = (struct drm_dp_mst_topology_state **)obj_state_ptr;
+ __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
- mgr->state->state = (*topology_state_ptr)->state;
- swap(*topology_state_ptr, mgr->state);
- mgr->state->state = NULL;
+ return &state->base;
}
-void drm_dp_mst_destroy_state(void *obj_state)
+static void drm_dp_mst_destroy_state(struct drm_private_obj *obj,
+ struct drm_private_state *state)
{
- kfree(obj_state);
+ struct drm_dp_mst_topology_state *mst_state =
+ to_dp_mst_topology_state(state);
+
+ kfree(mst_state);
}
static const struct drm_private_state_funcs mst_state_funcs = {
- .duplicate_state = drm_dp_mst_duplicate_state,
- .swap_state = drm_dp_mst_swap_state,
- .destroy_state = drm_dp_mst_destroy_state,
+ .atomic_duplicate_state = drm_dp_mst_duplicate_state,
+ .atomic_destroy_state = drm_dp_mst_destroy_state,
};
/**
@@ -3050,8 +3070,7 @@ struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_a
struct drm_device *dev = mgr->dev;
WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
- return drm_atomic_get_private_obj_state(state, mgr,
- &mst_state_funcs);
+ return to_dp_mst_topology_state(drm_atomic_get_private_obj_state(state, &mgr->base));
}
EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
@@ -3071,6 +3090,8 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
int max_dpcd_transaction_bytes,
int max_payloads, int conn_base_id)
{
+ struct drm_dp_mst_topology_state *mst_state;
+
mutex_init(&mgr->lock);
mutex_init(&mgr->qlock);
mutex_init(&mgr->payload_lock);
@@ -3099,14 +3120,18 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
if (test_calc_pbn_mode() < 0)
DRM_ERROR("MST PBN self-test failed\n");
- mgr->state = kzalloc(sizeof(*mgr->state), GFP_KERNEL);
- if (mgr->state == NULL)
+ mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL);
+ if (mst_state == NULL)
return -ENOMEM;
- mgr->state->mgr = mgr;
+
+ mst_state->mgr = mgr;
/* max. time slots - one slot for MTP header */
- mgr->state->avail_slots = 63;
- mgr->funcs = &mst_state_funcs;
+ mst_state->avail_slots = 63;
+
+ drm_atomic_private_obj_init(&mgr->base,
+ &mst_state->base,
+ &mst_state_funcs);
return 0;
}
@@ -3128,8 +3153,7 @@ void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr)
mutex_unlock(&mgr->payload_lock);
mgr->dev = NULL;
mgr->aux = NULL;
- kfree(mgr->state);
- mgr->state = NULL;
+ drm_atomic_private_obj_fini(&mgr->base);
mgr->funcs = NULL;
}
EXPORT_SYMBOL(drm_dp_mst_topology_mgr_destroy);
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 37b8ad3e30d8..be38ac7050d4 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -63,6 +63,15 @@ module_param_named(debug, drm_debug, int, 0600);
static DEFINE_SPINLOCK(drm_minor_lock);
static struct idr drm_minors_idr;
+/*
+ * If the drm core fails to init for whatever reason,
+ * we should prevent any drivers from registering with it.
+ * It's best to check this at drm_dev_init(), as some drivers
+ * prefer to embed struct drm_device into their own device
+ * structure and call drm_dev_init() themselves.
+ */
+static bool drm_core_init_complete = false;
+
static struct dentry *drm_debugfs_root;
#define DRM_PRINTK_FMT "[" DRM_NAME ":%s]%s %pV"
@@ -282,7 +291,7 @@ struct drm_minor *drm_minor_acquire(unsigned int minor_id)
if (!minor) {
return ERR_PTR(-ENODEV);
- } else if (drm_device_is_unplugged(minor->dev)) {
+ } else if (drm_dev_is_unplugged(minor->dev)) {
drm_dev_unref(minor->dev);
return ERR_PTR(-ENODEV);
}
@@ -355,26 +364,32 @@ void drm_put_dev(struct drm_device *dev)
}
EXPORT_SYMBOL(drm_put_dev);
-void drm_unplug_dev(struct drm_device *dev)
+static void drm_device_set_unplugged(struct drm_device *dev)
{
- /* for a USB device */
- if (drm_core_check_feature(dev, DRIVER_MODESET))
- drm_modeset_unregister_all(dev);
+ smp_wmb();
+ atomic_set(&dev->unplugged, 1);
+}
- drm_minor_unregister(dev, DRM_MINOR_PRIMARY);
- drm_minor_unregister(dev, DRM_MINOR_RENDER);
- drm_minor_unregister(dev, DRM_MINOR_CONTROL);
+/**
+ * drm_dev_unplug - unplug a DRM device
+ * @dev: DRM device
+ *
+ * This unplugs a hotpluggable DRM device, which makes it inaccessible to
+ * userspace operations. Entry-points can use drm_dev_is_unplugged(). This
+ * essentially unregisters the device like drm_dev_unregister(), but can be
+ * called while there are still open users of @dev.
+ */
+void drm_dev_unplug(struct drm_device *dev)
+{
+ drm_dev_unregister(dev);
mutex_lock(&drm_global_mutex);
-
drm_device_set_unplugged(dev);
-
- if (dev->open_count == 0) {
- drm_put_dev(dev);
- }
+ if (dev->open_count == 0)
+ drm_dev_unref(dev);
mutex_unlock(&drm_global_mutex);
}
-EXPORT_SYMBOL(drm_unplug_dev);
+EXPORT_SYMBOL(drm_dev_unplug);
/*
* DRM internal mount
@@ -484,6 +499,11 @@ int drm_dev_init(struct drm_device *dev,
{
int ret;
+ if (!drm_core_init_complete) {
+ DRM_ERROR("DRM core is not initialized\n");
+ return -ENODEV;
+ }
+
kref_init(&dev->ref);
dev->dev = parent;
dev->driver = driver;
@@ -821,6 +841,9 @@ EXPORT_SYMBOL(drm_dev_register);
* drm_dev_register() but does not deallocate the device. The caller must call
* drm_dev_unref() to drop their final reference.
*
+ * A special form of unregistering for hotpluggable devices is drm_dev_unplug(),
+ * which can be called while there are still open users of @dev.
+ *
* This should be called first in the device teardown code to make sure
* userspace can't access the device instance any more.
*/
@@ -828,7 +851,8 @@ void drm_dev_unregister(struct drm_device *dev)
{
struct drm_map_list *r_list, *list_temp;
- drm_lastclose(dev);
+ if (drm_core_check_feature(dev, DRIVER_LEGACY))
+ drm_lastclose(dev);
dev->registered = false;
@@ -966,6 +990,8 @@ static int __init drm_core_init(void)
if (ret < 0)
goto error;
+ drm_core_init_complete = true;
+
DRM_DEBUG("Initialized\n");
return 0;
diff --git a/drivers/gpu/drm/drm_dumb_buffers.c b/drivers/gpu/drm/drm_dumb_buffers.c
index 10307cc16d75..39ac15ce4702 100644
--- a/drivers/gpu/drm/drm_dumb_buffers.c
+++ b/drivers/gpu/drm/drm_dumb_buffers.c
@@ -24,6 +24,7 @@
*/
#include <drm/drmP.h>
+#include <drm/drm_gem.h>
#include "drm_crtc_internal.h"
@@ -42,9 +43,10 @@
* create dumb buffers suitable for scanout, which can then be used to create
* KMS frame buffers.
*
- * To support dumb objects drivers must implement the &drm_driver.dumb_create,
- * &drm_driver.dumb_destroy and &drm_driver.dumb_map_offset operations. See
- * there for further details.
+ * To support dumb objects drivers must implement the &drm_driver.dumb_create
+ * operation. &drm_driver.dumb_destroy defaults to drm_gem_dumb_destroy() if
+ * not set and &drm_driver.dumb_map_offset defaults to
+ * drm_gem_dumb_map_offset(). See the callbacks for further details.
*
* Note that dumb objects may not be used for gpu acceleration, as has been
* attempted on some ARM embedded platforms. Such drivers really must have
@@ -108,11 +110,16 @@ int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
{
struct drm_mode_map_dumb *args = data;
- /* call driver ioctl to get mmap offset */
- if (!dev->driver->dumb_map_offset)
+ if (!dev->driver->dumb_create)
return -ENOSYS;
- return dev->driver->dumb_map_offset(file_priv, dev, args->handle, &args->offset);
+ if (dev->driver->dumb_map_offset)
+ return dev->driver->dumb_map_offset(file_priv, dev,
+ args->handle,
+ &args->offset);
+ else
+ return drm_gem_dumb_map_offset(file_priv, dev, args->handle,
+ &args->offset);
}
int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
@@ -120,9 +127,12 @@ int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
{
struct drm_mode_destroy_dumb *args = data;
- if (!dev->driver->dumb_destroy)
+ if (!dev->driver->dumb_create)
return -ENOSYS;
- return dev->driver->dumb_destroy(file_priv, dev, args->handle);
+ if (dev->driver->dumb_destroy)
+ return dev->driver->dumb_destroy(file_priv, dev, args->handle);
+ else
+ return drm_gem_dumb_destroy(file_priv, dev, args->handle);
}
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 2e55599816aa..6bb6337be920 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1006,6 +1006,221 @@ static const struct drm_display_mode edid_cea_modes[] = {
2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
.vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+ /* 65 - 1280x720@24Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040,
+ 3080, 3300, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 66 - 1280x720@25Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3700,
+ 3740, 3960, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 67 - 1280x720@30Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040,
+ 3080, 3300, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 68 - 1280x720@50Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
+ 1760, 1980, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 69 - 1280x720@60Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
+ 1430, 1650, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 70 - 1280x720@100Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720,
+ 1760, 1980, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 71 - 1280x720@120Hz */
+ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390,
+ 1430, 1650, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 72 - 1920x1080@24Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558,
+ 2602, 2750, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 73 - 1920x1080@25Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448,
+ 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 74 - 1920x1080@30Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
+ 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 75 - 1920x1080@50Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
+ 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 76 - 1920x1080@60Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
+ 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 77 - 1920x1080@100Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448,
+ 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 78 - 1920x1080@120Hz */
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008,
+ 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 79 - 1680x720@24Hz */
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 59400, 1680, 3040,
+ 3080, 3300, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 80 - 1680x720@25Hz */
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 59400, 1680, 2908,
+ 2948, 3168, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 81 - 1680x720@30Hz */
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 59400, 1680, 2380,
+ 2420, 2640, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 82 - 1680x720@50Hz */
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 82500, 1680, 1940,
+ 1980, 2200, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 83 - 1680x720@60Hz */
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 99000, 1680, 1940,
+ 1980, 2200, 0, 720, 725, 730, 750, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 84 - 1680x720@100Hz */
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 165000, 1680, 1740,
+ 1780, 2000, 0, 720, 725, 730, 825, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 85 - 1680x720@120Hz */
+ { DRM_MODE("1680x720", DRM_MODE_TYPE_DRIVER, 198000, 1680, 1740,
+ 1780, 2000, 0, 720, 725, 730, 825, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 86 - 2560x1080@24Hz */
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 99000, 2560, 3558,
+ 3602, 3750, 0, 1080, 1084, 1089, 1100, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 87 - 2560x1080@25Hz */
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 90000, 2560, 3008,
+ 3052, 3200, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 88 - 2560x1080@30Hz */
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 118800, 2560, 3328,
+ 3372, 3520, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 89 - 2560x1080@50Hz */
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 185625, 2560, 3108,
+ 3152, 3300, 0, 1080, 1084, 1089, 1125, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 90 - 2560x1080@60Hz */
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 198000, 2560, 2808,
+ 2852, 3000, 0, 1080, 1084, 1089, 1100, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 91 - 2560x1080@100Hz */
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 371250, 2560, 2778,
+ 2822, 2970, 0, 1080, 1084, 1089, 1250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 92 - 2560x1080@120Hz */
+ { DRM_MODE("2560x1080", DRM_MODE_TYPE_DRIVER, 495000, 2560, 3108,
+ 3152, 3300, 0, 1080, 1084, 1089, 1250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 120, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 93 - 3840x2160p@24Hz 16:9 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 5116,
+ 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+ /* 94 - 3840x2160p@25Hz 16:9 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4896,
+ 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+ /* 95 - 3840x2160p@30Hz 16:9 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4016,
+ 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+ /* 96 - 3840x2160p@50Hz 16:9 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4896,
+ 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+ /* 97 - 3840x2160p@60Hz 16:9 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016,
+ 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
+ /* 98 - 4096x2160p@24Hz 256:135 */
+ { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 5116,
+ 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
+ /* 99 - 4096x2160p@25Hz 256:135 */
+ { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 5064,
+ 5152, 5280, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
+ /* 100 - 4096x2160p@30Hz 256:135 */
+ { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 297000, 4096, 4184,
+ 4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
+ /* 101 - 4096x2160p@50Hz 256:135 */
+ { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 5064,
+ 5152, 5280, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
+ /* 102 - 4096x2160p@60Hz 256:135 */
+ { DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 4184,
+ 4272, 4400, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135, },
+ /* 103 - 3840x2160p@24Hz 64:27 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 5116,
+ 5204, 5500, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 24, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 104 - 3840x2160p@25Hz 64:27 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4896,
+ 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 25, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 105 - 3840x2160p@30Hz 64:27 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4016,
+ 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 106 - 3840x2160p@50Hz 64:27 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4896,
+ 4984, 5280, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
+ /* 107 - 3840x2160p@60Hz 64:27 */
+ { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016,
+ 4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
+ .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_64_27, },
};
/*
@@ -2566,7 +2781,10 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid,
#define VIDEO_BLOCK 0x02
#define VENDOR_BLOCK 0x03
#define SPEAKER_BLOCK 0x04
-#define VIDEO_CAPABILITY_BLOCK 0x07
+#define USE_EXTENDED_TAG 0x07
+#define EXT_VIDEO_CAPABILITY_BLOCK 0x00
+#define EXT_VIDEO_DATA_BLOCK_420 0x0E
+#define EXT_VIDEO_CAP_BLOCK_Y420CMDB 0x0F
#define EDID_BASIC_AUDIO (1 << 6)
#define EDID_CEA_YCRCB444 (1 << 5)
#define EDID_CEA_YCRCB422 (1 << 4)
@@ -2902,6 +3120,15 @@ add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid)
return modes;
}
+static u8 svd_to_vic(u8 svd)
+{
+ /* 0-6 bit vic, 7th bit native mode indicator */
+ if ((svd >= 1 && svd <= 64) || (svd >= 129 && svd <= 192))
+ return svd & 127;
+
+ return svd;
+}
+
static struct drm_display_mode *
drm_display_mode_from_vic_index(struct drm_connector *connector,
const u8 *video_db, u8 video_len,
@@ -2915,7 +3142,7 @@ drm_display_mode_from_vic_index(struct drm_connector *connector,
return NULL;
/* CEA modes are numbered 1..127 */
- vic = (video_db[video_index] & 127);
+ vic = svd_to_vic(video_db[video_index]);
if (!drm_valid_cea_vic(vic))
return NULL;
@@ -2928,15 +3155,85 @@ drm_display_mode_from_vic_index(struct drm_connector *connector,
return newmode;
}
+/*
+ * do_y420vdb_modes - Parse YCBCR 420 only modes
+ * @connector: connector corresponding to the HDMI sink
+ * @svds: start of the data block of CEA YCBCR 420 VDB
+ * @len: length of the CEA YCBCR 420 VDB
+ *
+ * Parse the CEA-861-F YCBCR 420 Video Data Block (Y420VDB)
+ * which contains modes which can be supported in YCBCR 420
+ * output format only.
+ */
+static int do_y420vdb_modes(struct drm_connector *connector,
+ const u8 *svds, u8 svds_len)
+{
+ int modes = 0, i;
+ struct drm_device *dev = connector->dev;
+ struct drm_display_info *info = &connector->display_info;
+ struct drm_hdmi_info *hdmi = &info->hdmi;
+
+ for (i = 0; i < svds_len; i++) {
+ u8 vic = svd_to_vic(svds[i]);
+ struct drm_display_mode *newmode;
+
+ if (!drm_valid_cea_vic(vic))
+ continue;
+
+ newmode = drm_mode_duplicate(dev, &edid_cea_modes[vic]);
+ if (!newmode)
+ break;
+ bitmap_set(hdmi->y420_vdb_modes, vic, 1);
+ drm_mode_probed_add(connector, newmode);
+ modes++;
+ }
+
+ if (modes > 0)
+ info->color_formats |= DRM_COLOR_FORMAT_YCRCB420;
+ return modes;
+}
+
+/*
+ * drm_add_cmdb_modes - Add a YCBCR 420 mode into bitmap
+ * @connector: connector corresponding to the HDMI sink
+ * @vic: CEA vic for the video mode to be added in the map
+ *
+ * Makes an entry for a videomode in the YCBCR 420 bitmap
+ */
+static void
+drm_add_cmdb_modes(struct drm_connector *connector, u8 svd)
+{
+ u8 vic = svd_to_vic(svd);
+ struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
+
+ if (!drm_valid_cea_vic(vic))
+ return;
+
+ bitmap_set(hdmi->y420_cmdb_modes, vic, 1);
+}
+
static int
do_cea_modes(struct drm_connector *connector, const u8 *db, u8 len)
{
int i, modes = 0;
+ struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
for (i = 0; i < len; i++) {
struct drm_display_mode *mode;
mode = drm_display_mode_from_vic_index(connector, db, len, i);
if (mode) {
+ /*
+ * YCBCR420 capability block contains a bitmap which
+ * gives the index of CEA modes from CEA VDB, which
+ * can support YCBCR 420 sampling output also (apart
+ * from RGB/YCBCR444 etc).
+ * For example, if the bit 0 in bitmap is set,
+ * first mode in VDB can support YCBCR420 output too.
+ * Add YCBCR420 modes only if sink is HDMI 2.0 capable.
+ */
+ if (i < 64 && hdmi->y420_cmdb_map & (1ULL << i))
+ drm_add_cmdb_modes(connector, db[i]);
+
drm_mode_probed_add(connector, mode);
modes++;
}
@@ -3218,6 +3515,12 @@ cea_db_payload_len(const u8 *db)
}
static int
+cea_db_extended_tag(const u8 *db)
+{
+ return db[1];
+}
+
+static int
cea_db_tag(const u8 *db)
{
return db[0] >> 5;
@@ -3272,9 +3575,77 @@ static bool cea_db_is_hdmi_forum_vsdb(const u8 *db)
return oui == HDMI_FORUM_IEEE_OUI;
}
+static bool cea_db_is_y420cmdb(const u8 *db)
+{
+ if (cea_db_tag(db) != USE_EXTENDED_TAG)
+ return false;
+
+ if (!cea_db_payload_len(db))
+ return false;
+
+ if (cea_db_extended_tag(db) != EXT_VIDEO_CAP_BLOCK_Y420CMDB)
+ return false;
+
+ return true;
+}
+
+static bool cea_db_is_y420vdb(const u8 *db)
+{
+ if (cea_db_tag(db) != USE_EXTENDED_TAG)
+ return false;
+
+ if (!cea_db_payload_len(db))
+ return false;
+
+ if (cea_db_extended_tag(db) != EXT_VIDEO_DATA_BLOCK_420)
+ return false;
+
+ return true;
+}
+
#define for_each_cea_db(cea, i, start, end) \
for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1)
+static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector,
+ const u8 *db)
+{
+ struct drm_display_info *info = &connector->display_info;
+ struct drm_hdmi_info *hdmi = &info->hdmi;
+ u8 map_len = cea_db_payload_len(db) - 1;
+ u8 count;
+ u64 map = 0;
+
+ if (map_len == 0) {
+ /* All CEA modes support ycbcr420 sampling also.*/
+ hdmi->y420_cmdb_map = U64_MAX;
+ info->color_formats |= DRM_COLOR_FORMAT_YCRCB420;
+ return;
+ }
+
+ /*
+ * This map indicates which of the existing CEA block modes
+ * from VDB can support YCBCR420 output too. So if bit=0 is
+ * set, first mode from VDB can support YCBCR420 output too.
+ * We will parse and keep this map, before parsing VDB itself
+ * to avoid going through the same block again and again.
+ *
+ * Spec is not clear about max possible size of this block.
+ * Clamping max bitmap block size at 8 bytes. Every byte can
+ * address 8 CEA modes, in this way this map can address
+ * 8*8 = first 64 SVDs.
+ */
+ if (WARN_ON_ONCE(map_len > 8))
+ map_len = 8;
+
+ for (count = 0; count < map_len; count++)
+ map |= (u64)db[2 + count] << (8 * count);
+
+ if (map)
+ info->color_formats |= DRM_COLOR_FORMAT_YCRCB420;
+
+ hdmi->y420_cmdb_map = map;
+}
+
static int
add_cea_modes(struct drm_connector *connector, struct edid *edid)
{
@@ -3297,10 +3668,16 @@ add_cea_modes(struct drm_connector *connector, struct edid *edid)
video = db + 1;
video_len = dbl;
modes += do_cea_modes(connector, video, dbl);
- }
- else if (cea_db_is_hdmi_vsdb(db)) {
+ } else if (cea_db_is_hdmi_vsdb(db)) {
hdmi = db;
hdmi_len = dbl;
+ } else if (cea_db_is_y420vdb(db)) {
+ const u8 *vdb420 = &db[2];
+
+ /* Add 4:2:0(only) modes present in EDID */
+ modes += do_y420vdb_modes(connector,
+ vdb420,
+ dbl - 1);
}
}
}
@@ -3793,8 +4170,10 @@ bool drm_rgb_quant_range_selectable(struct edid *edid)
return false;
for_each_cea_db(edid_ext, i, start, end) {
- if (cea_db_tag(&edid_ext[i]) == VIDEO_CAPABILITY_BLOCK &&
- cea_db_payload_len(&edid_ext[i]) == 2) {
+ if (cea_db_tag(&edid_ext[i]) == USE_EXTENDED_TAG &&
+ cea_db_payload_len(&edid_ext[i]) == 2 &&
+ cea_db_extended_tag(&edid_ext[i]) ==
+ EXT_VIDEO_CAPABILITY_BLOCK) {
DRM_DEBUG_KMS("CEA VCDB 0x%02x\n", edid_ext[i + 2]);
return edid_ext[i + 2] & EDID_CEA_VCDB_QS;
}
@@ -3823,6 +4202,16 @@ drm_default_rgb_quant_range(const struct drm_display_mode *mode)
}
EXPORT_SYMBOL(drm_default_rgb_quant_range);
+static void drm_parse_ycbcr420_deep_color_info(struct drm_connector *connector,
+ const u8 *db)
+{
+ u8 dc_mask;
+ struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
+
+ dc_mask = db[7] & DRM_EDID_YCBCR420_DC_MASK;
+ hdmi->y420_dc_modes |= dc_mask;
+}
+
static void drm_parse_hdmi_forum_vsdb(struct drm_connector *connector,
const u8 *hf_vsdb)
{
@@ -3863,6 +4252,8 @@ static void drm_parse_hdmi_forum_vsdb(struct drm_connector *connector,
scdc->scrambling.low_rates = true;
}
}
+
+ drm_parse_ycbcr420_deep_color_info(connector, hf_vsdb);
}
static void drm_parse_hdmi_deep_color_info(struct drm_connector *connector,
@@ -3981,6 +4372,8 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
drm_parse_hdmi_vsdb_video(connector, db);
if (cea_db_is_hdmi_forum_vsdb(db))
drm_parse_hdmi_forum_vsdb(connector, db);
+ if (cea_db_is_y420cmdb(db))
+ drm_parse_y420cmdb_bitmap(connector, db);
}
}
@@ -4215,6 +4608,13 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
quirks = edid_get_quirks(edid);
/*
+ * CEA-861-F adds ycbcr capability map block, for HDMI 2.0 sinks.
+ * To avoid multiple parsing of same block, lets parse that map
+ * from sink info, before parsing CEA modes.
+ */
+ drm_add_display_info(connector, edid);
+
+ /*
* EDID spec says modes should be preferred in this order:
* - preferred detailed mode
* - other detailed modes from base block
@@ -4241,8 +4641,6 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
edid_fixup_preferred(connector, quirks);
- drm_add_display_info(connector, edid);
-
if (quirks & EDID_QUIRK_FORCE_6BPC)
connector->display_info.bpc = 6;
@@ -4334,12 +4732,14 @@ EXPORT_SYMBOL(drm_set_preferred_mode);
* data from a DRM display mode
* @frame: HDMI AVI infoframe
* @mode: DRM display mode
+ * @is_hdmi2_sink: Sink is HDMI 2.0 compliant
*
* Return: 0 on success or a negative error code on failure.
*/
int
drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
- const struct drm_display_mode *mode)
+ const struct drm_display_mode *mode,
+ bool is_hdmi2_sink)
{
int err;
@@ -4355,6 +4755,28 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
frame->video_code = drm_match_cea_mode(mode);
+ /*
+ * HDMI 1.4 VIC range: 1 <= VIC <= 64 (CEA-861-D) but
+ * HDMI 2.0 VIC range: 1 <= VIC <= 107 (CEA-861-F). So we
+ * have to make sure we dont break HDMI 1.4 sinks.
+ */
+ if (!is_hdmi2_sink && frame->video_code > 64)
+ frame->video_code = 0;
+
+ /*
+ * HDMI spec says if a mode is found in HDMI 1.4b 4K modes
+ * we should send its VIC in vendor infoframes, else send the
+ * VIC in AVI infoframes. Lets check if this mode is present in
+ * HDMI 1.4b 4K modes
+ */
+ if (frame->video_code) {
+ u8 vendor_if_vic = drm_match_hdmi_mode(mode);
+ bool is_s3d = mode->flags & DRM_MODE_FLAG_3D_MASK;
+
+ if (drm_valid_hdmi_vic(vendor_if_vic) && !is_s3d)
+ frame->video_code = 0;
+ }
+
frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
/*
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
index 53f9bdf470d7..f2ee88363015 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -18,27 +18,17 @@
*/
#include <drm/drmP.h>
-#include <drm/drm_atomic.h>
-#include <drm/drm_crtc.h>
#include <drm/drm_fb_helper.h>
-#include <drm/drm_crtc_helper.h>
+#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_fb_cma_helper.h>
-#include <linux/dma-buf.h>
-#include <linux/dma-mapping.h>
#include <linux/module.h>
-#include <linux/reservation.h>
#define DEFAULT_FBDEFIO_DELAY_MS 50
-struct drm_fb_cma {
- struct drm_framebuffer fb;
- struct drm_gem_cma_object *obj[4];
-};
-
struct drm_fbdev_cma {
struct drm_fb_helper fb_helper;
- struct drm_fb_cma *fb;
const struct drm_framebuffer_funcs *fb_funcs;
};
@@ -90,69 +80,19 @@ static inline struct drm_fbdev_cma *to_fbdev_cma(struct drm_fb_helper *helper)
return container_of(helper, struct drm_fbdev_cma, fb_helper);
}
-static inline struct drm_fb_cma *to_fb_cma(struct drm_framebuffer *fb)
-{
- return container_of(fb, struct drm_fb_cma, fb);
-}
-
void drm_fb_cma_destroy(struct drm_framebuffer *fb)
{
- struct drm_fb_cma *fb_cma = to_fb_cma(fb);
- int i;
-
- for (i = 0; i < 4; i++) {
- if (fb_cma->obj[i])
- drm_gem_object_put_unlocked(&fb_cma->obj[i]->base);
- }
-
- drm_framebuffer_cleanup(fb);
- kfree(fb_cma);
+ drm_gem_fb_destroy(fb);
}
EXPORT_SYMBOL(drm_fb_cma_destroy);
int drm_fb_cma_create_handle(struct drm_framebuffer *fb,
struct drm_file *file_priv, unsigned int *handle)
{
- struct drm_fb_cma *fb_cma = to_fb_cma(fb);
-
- return drm_gem_handle_create(file_priv,
- &fb_cma->obj[0]->base, handle);
+ return drm_gem_fb_create_handle(fb, file_priv, handle);
}
EXPORT_SYMBOL(drm_fb_cma_create_handle);
-static struct drm_framebuffer_funcs drm_fb_cma_funcs = {
- .destroy = drm_fb_cma_destroy,
- .create_handle = drm_fb_cma_create_handle,
-};
-
-static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev,
- const struct drm_mode_fb_cmd2 *mode_cmd,
- struct drm_gem_cma_object **obj,
- unsigned int num_planes, const struct drm_framebuffer_funcs *funcs)
-{
- struct drm_fb_cma *fb_cma;
- int ret;
- int i;
-
- fb_cma = kzalloc(sizeof(*fb_cma), GFP_KERNEL);
- if (!fb_cma)
- return ERR_PTR(-ENOMEM);
-
- drm_helper_mode_fill_fb_struct(dev, &fb_cma->fb, mode_cmd);
-
- for (i = 0; i < num_planes; i++)
- fb_cma->obj[i] = obj[i];
-
- ret = drm_framebuffer_init(dev, &fb_cma->fb, funcs);
- if (ret) {
- dev_err(dev->dev, "Failed to initialize framebuffer: %d\n", ret);
- kfree(fb_cma);
- return ERR_PTR(ret);
- }
-
- return fb_cma;
-}
-
/**
* drm_fb_cma_create_with_funcs() - helper function for the
* &drm_mode_config_funcs.fb_create
@@ -170,53 +110,7 @@ struct drm_framebuffer *drm_fb_cma_create_with_funcs(struct drm_device *dev,
struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd,
const struct drm_framebuffer_funcs *funcs)
{
- const struct drm_format_info *info;
- struct drm_fb_cma *fb_cma;
- struct drm_gem_cma_object *objs[4];
- struct drm_gem_object *obj;
- int ret;
- int i;
-
- info = drm_get_format_info(dev, mode_cmd);
- if (!info)
- return ERR_PTR(-EINVAL);
-
- for (i = 0; i < info->num_planes; i++) {
- unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
- unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
- unsigned int min_size;
-
- obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]);
- if (!obj) {
- dev_err(dev->dev, "Failed to lookup GEM object\n");
- ret = -ENOENT;
- goto err_gem_object_put;
- }
-
- min_size = (height - 1) * mode_cmd->pitches[i]
- + width * info->cpp[i]
- + mode_cmd->offsets[i];
-
- if (obj->size < min_size) {
- drm_gem_object_put_unlocked(obj);
- ret = -EINVAL;
- goto err_gem_object_put;
- }
- objs[i] = to_drm_gem_cma_obj(obj);
- }
-
- fb_cma = drm_fb_cma_alloc(dev, mode_cmd, objs, i, funcs);
- if (IS_ERR(fb_cma)) {
- ret = PTR_ERR(fb_cma);
- goto err_gem_object_put;
- }
-
- return &fb_cma->fb;
-
-err_gem_object_put:
- for (i--; i >= 0; i--)
- drm_gem_object_put_unlocked(&objs[i]->base);
- return ERR_PTR(ret);
+ return drm_gem_fb_create_with_funcs(dev, file_priv, mode_cmd, funcs);
}
EXPORT_SYMBOL_GPL(drm_fb_cma_create_with_funcs);
@@ -233,8 +127,7 @@ EXPORT_SYMBOL_GPL(drm_fb_cma_create_with_funcs);
struct drm_framebuffer *drm_fb_cma_create(struct drm_device *dev,
struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd)
{
- return drm_fb_cma_create_with_funcs(dev, file_priv, mode_cmd,
- &drm_fb_cma_funcs);
+ return drm_gem_fb_create(dev, file_priv, mode_cmd);
}
EXPORT_SYMBOL_GPL(drm_fb_cma_create);
@@ -250,12 +143,13 @@ EXPORT_SYMBOL_GPL(drm_fb_cma_create);
struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb,
unsigned int plane)
{
- struct drm_fb_cma *fb_cma = to_fb_cma(fb);
+ struct drm_gem_object *gem;
- if (plane >= 4)
+ gem = drm_gem_fb_get_obj(fb, plane);
+ if (!gem)
return NULL;
- return fb_cma->obj[plane];
+ return to_drm_gem_cma_obj(gem);
}
EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj);
@@ -272,13 +166,14 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb,
struct drm_plane_state *state,
unsigned int plane)
{
- struct drm_fb_cma *fb_cma = to_fb_cma(fb);
+ struct drm_gem_cma_object *obj;
dma_addr_t paddr;
- if (plane >= 4)
+ obj = drm_fb_cma_get_gem_obj(fb, plane);
+ if (!obj)
return 0;
- paddr = fb_cma->obj[plane]->paddr + fb->offsets[plane];
+ paddr = obj->paddr + fb->offsets[plane];
paddr += fb->format->cpp[plane] * (state->src_x >> 16);
paddr += fb->pitches[plane] * (state->src_y >> 16);
@@ -302,26 +197,13 @@ EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_addr);
int drm_fb_cma_prepare_fb(struct drm_plane *plane,
struct drm_plane_state *state)
{
- struct dma_buf *dma_buf;
- struct dma_fence *fence;
-
- if ((plane->state->fb == state->fb) || !state->fb)
- return 0;
-
- dma_buf = drm_fb_cma_get_gem_obj(state->fb, 0)->base.dma_buf;
- if (dma_buf) {
- fence = reservation_object_get_excl_rcu(dma_buf->resv);
- drm_atomic_set_fence_for_plane(state, fence);
- }
-
- return 0;
+ return drm_gem_fb_prepare_fb(plane, state);
}
EXPORT_SYMBOL_GPL(drm_fb_cma_prepare_fb);
#ifdef CONFIG_DEBUG_FS
static void drm_fb_cma_describe(struct drm_framebuffer *fb, struct seq_file *m)
{
- struct drm_fb_cma *fb_cma = to_fb_cma(fb);
int i;
seq_printf(m, "fb: %dx%d@%4.4s\n", fb->width, fb->height,
@@ -330,7 +212,7 @@ static void drm_fb_cma_describe(struct drm_framebuffer *fb, struct seq_file *m)
for (i = 0; i < fb->format->num_planes; i++) {
seq_printf(m, " %d: offset=%d pitch=%d, obj: ",
i, fb->offsets[i], fb->pitches[i]);
- drm_gem_cma_describe(fb_cma->obj[i], m);
+ drm_gem_cma_describe(drm_fb_cma_get_gem_obj(fb, i), m);
}
}
@@ -431,7 +313,6 @@ drm_fbdev_cma_create(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
struct drm_fbdev_cma *fbdev_cma = to_fbdev_cma(helper);
- struct drm_mode_fb_cmd2 mode_cmd = { 0 };
struct drm_device *dev = helper->dev;
struct drm_gem_cma_object *obj;
struct drm_framebuffer *fb;
@@ -446,14 +327,7 @@ drm_fbdev_cma_create(struct drm_fb_helper *helper,
sizes->surface_bpp);
bytes_per_pixel = DIV_ROUND_UP(sizes->surface_bpp, 8);
-
- mode_cmd.width = sizes->surface_width;
- mode_cmd.height = sizes->surface_height;
- mode_cmd.pitches[0] = sizes->surface_width * bytes_per_pixel;
- mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
- sizes->surface_depth);
-
- size = mode_cmd.pitches[0] * mode_cmd.height;
+ size = sizes->surface_width * sizes->surface_height * bytes_per_pixel;
obj = drm_gem_cma_create(dev, size);
if (IS_ERR(obj))
return -ENOMEM;
@@ -464,15 +338,14 @@ drm_fbdev_cma_create(struct drm_fb_helper *helper,
goto err_gem_free_object;
}
- fbdev_cma->fb = drm_fb_cma_alloc(dev, &mode_cmd, &obj, 1,
- fbdev_cma->fb_funcs);
- if (IS_ERR(fbdev_cma->fb)) {
+ fb = drm_gem_fbdev_fb_create(dev, sizes, 0, &obj->base,
+ fbdev_cma->fb_funcs);
+ if (IS_ERR(fb)) {
dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n");
- ret = PTR_ERR(fbdev_cma->fb);
+ ret = PTR_ERR(fb);
goto err_fb_info_destroy;
}
- fb = &fbdev_cma->fb->fb;
helper->fb = fb;
fbi->par = helper;
@@ -500,7 +373,7 @@ drm_fbdev_cma_create(struct drm_fb_helper *helper,
return 0;
err_cma_destroy:
- drm_framebuffer_remove(&fbdev_cma->fb->fb);
+ drm_framebuffer_remove(fb);
err_fb_info_destroy:
drm_fb_helper_fini(helper);
err_gem_free_object:
@@ -570,6 +443,11 @@ err_free:
}
EXPORT_SYMBOL_GPL(drm_fbdev_cma_init_with_funcs);
+static const struct drm_framebuffer_funcs drm_fb_cma_funcs = {
+ .destroy = drm_gem_fb_destroy,
+ .create_handle = drm_gem_fb_create_handle,
+};
+
/**
* drm_fbdev_cma_init() - Allocate and initializes a drm_fbdev_cma struct
* @dev: DRM device
@@ -597,8 +475,8 @@ void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma)
if (fbdev_cma->fb_helper.fbdev)
drm_fbdev_cma_defio_fini(fbdev_cma->fb_helper.fbdev);
- if (fbdev_cma->fb)
- drm_framebuffer_remove(&fbdev_cma->fb->fb);
+ if (fbdev_cma->fb_helper.fb)
+ drm_framebuffer_remove(fbdev_cma->fb_helper.fb);
drm_fb_helper_fini(&fbdev_cma->fb_helper);
kfree(fbdev_cma);
@@ -640,7 +518,7 @@ EXPORT_SYMBOL_GPL(drm_fbdev_cma_hotplug_event);
* Calls drm_fb_helper_set_suspend, which is a wrapper around
* fb_set_suspend implemented by fbdev core.
*/
-void drm_fbdev_cma_set_suspend(struct drm_fbdev_cma *fbdev_cma, int state)
+void drm_fbdev_cma_set_suspend(struct drm_fbdev_cma *fbdev_cma, bool state)
{
if (fbdev_cma)
drm_fb_helper_set_suspend(&fbdev_cma->fb_helper, state);
@@ -657,7 +535,7 @@ EXPORT_SYMBOL(drm_fbdev_cma_set_suspend);
* fb_set_suspend implemented by fbdev core.
*/
void drm_fbdev_cma_set_suspend_unlocked(struct drm_fbdev_cma *fbdev_cma,
- int state)
+ bool state)
{
if (fbdev_cma)
drm_fb_helper_set_suspend_unlocked(&fbdev_cma->fb_helper,
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 574af01d3ce9..1b8f013ffa65 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -106,11 +106,11 @@ static DEFINE_MUTEX(kernel_fb_helper_lock);
*/
#define drm_fb_helper_for_each_connector(fbh, i__) \
- for (({ lockdep_assert_held(&(fbh)->dev->mode_config.mutex); }), \
+ for (({ lockdep_assert_held(&(fbh)->lock); }), \
i__ = 0; i__ < (fbh)->connector_count; i__++)
-int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
- struct drm_connector *connector)
+static int __drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
+ struct drm_connector *connector)
{
struct drm_fb_helper_connector *fb_conn;
struct drm_fb_helper_connector **temp;
@@ -119,7 +119,7 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
if (!drm_fbdev_emulation)
return 0;
- WARN_ON(!mutex_is_locked(&fb_helper->dev->mode_config.mutex));
+ lockdep_assert_held(&fb_helper->lock);
count = fb_helper->connector_count + 1;
@@ -141,8 +141,21 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
drm_connector_get(connector);
fb_conn->connector = connector;
fb_helper->connector_info[fb_helper->connector_count++] = fb_conn;
+
return 0;
}
+
+int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper,
+ struct drm_connector *connector)
+{
+ int err;
+
+ mutex_lock(&fb_helper->lock);
+ err = __drm_fb_helper_add_one_connector(fb_helper, connector);
+ mutex_unlock(&fb_helper->lock);
+
+ return err;
+}
EXPORT_SYMBOL(drm_fb_helper_add_one_connector);
/**
@@ -169,11 +182,10 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
if (!drm_fbdev_emulation)
return 0;
- mutex_lock(&dev->mode_config.mutex);
+ mutex_lock(&fb_helper->lock);
drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(connector, &conn_iter) {
- ret = drm_fb_helper_add_one_connector(fb_helper, connector);
-
+ ret = __drm_fb_helper_add_one_connector(fb_helper, connector);
if (ret)
goto fail;
}
@@ -192,14 +204,14 @@ fail:
fb_helper->connector_count = 0;
out:
drm_connector_list_iter_end(&conn_iter);
- mutex_unlock(&dev->mode_config.mutex);
+ mutex_unlock(&fb_helper->lock);
return ret;
}
EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors);
-int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
- struct drm_connector *connector)
+static int __drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
+ struct drm_connector *connector)
{
struct drm_fb_helper_connector *fb_helper_connector;
int i, j;
@@ -207,9 +219,9 @@ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
if (!drm_fbdev_emulation)
return 0;
- WARN_ON(!mutex_is_locked(&fb_helper->dev->mode_config.mutex));
+ lockdep_assert_held(&fb_helper->lock);
- for (i = 0; i < fb_helper->connector_count; i++) {
+ drm_fb_helper_for_each_connector(fb_helper, i) {
if (fb_helper->connector_info[i]->connector == connector)
break;
}
@@ -227,23 +239,19 @@ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
return 0;
}
-EXPORT_SYMBOL(drm_fb_helper_remove_one_connector);
-static void drm_fb_helper_save_lut_atomic(struct drm_crtc *crtc, struct drm_fb_helper *helper)
+int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
+ struct drm_connector *connector)
{
- uint16_t *r_base, *g_base, *b_base;
- int i;
-
- if (helper->funcs->gamma_get == NULL)
- return;
+ int err;
- r_base = crtc->gamma_store;
- g_base = r_base + crtc->gamma_size;
- b_base = g_base + crtc->gamma_size;
+ mutex_lock(&fb_helper->lock);
+ err = __drm_fb_helper_remove_one_connector(fb_helper, connector);
+ mutex_unlock(&fb_helper->lock);
- for (i = 0; i < crtc->gamma_size; i++)
- helper->funcs->gamma_get(crtc, &r_base[i], &g_base[i], &b_base[i], i);
+ return err;
}
+EXPORT_SYMBOL(drm_fb_helper_remove_one_connector);
static void drm_fb_helper_restore_lut_atomic(struct drm_crtc *crtc)
{
@@ -285,7 +293,6 @@ int drm_fb_helper_debug_enter(struct fb_info *info)
if (drm_drv_uses_atomic_modeset(mode_set->crtc->dev))
continue;
- drm_fb_helper_save_lut_atomic(mode_set->crtc, helper);
funcs->mode_set_base_atomic(mode_set->crtc,
mode_set->fb,
mode_set->x,
@@ -298,20 +305,6 @@ int drm_fb_helper_debug_enter(struct fb_info *info)
}
EXPORT_SYMBOL(drm_fb_helper_debug_enter);
-/* Find the real fb for a given fb helper CRTC */
-static struct drm_framebuffer *drm_mode_config_fb(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_crtc *c;
-
- drm_for_each_crtc(c, dev) {
- if (crtc->base.id == c->base.id)
- return c->primary->fb;
- }
-
- return NULL;
-}
-
/**
* drm_fb_helper_debug_leave - implementation for &fb_ops.fb_debug_leave
* @info: fbdev registered by the helper
@@ -328,8 +321,11 @@ int drm_fb_helper_debug_leave(struct fb_info *info)
struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set;
crtc = mode_set->crtc;
+ if (drm_drv_uses_atomic_modeset(crtc->dev))
+ continue;
+
funcs = crtc->helper_private;
- fb = drm_mode_config_fb(crtc);
+ fb = crtc->primary->fb;
if (!crtc->enabled)
continue;
@@ -342,9 +338,6 @@ int drm_fb_helper_debug_leave(struct fb_info *info)
if (funcs->mode_set_base_atomic == NULL)
continue;
- if (drm_drv_uses_atomic_modeset(crtc->dev))
- continue;
-
drm_fb_helper_restore_lut_atomic(mode_set->crtc);
funcs->mode_set_base_atomic(mode_set->crtc, fb, crtc->x,
crtc->y, LEAVE_ATOMIC_MODE_SET);
@@ -354,19 +347,24 @@ int drm_fb_helper_debug_leave(struct fb_info *info)
}
EXPORT_SYMBOL(drm_fb_helper_debug_leave);
-static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper)
+static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool active)
{
struct drm_device *dev = fb_helper->dev;
struct drm_plane *plane;
struct drm_atomic_state *state;
int i, ret;
unsigned int plane_mask;
+ struct drm_modeset_acquire_ctx ctx;
+
+ drm_modeset_acquire_init(&ctx, 0);
state = drm_atomic_state_alloc(dev);
- if (!state)
- return -ENOMEM;
+ if (!state) {
+ ret = -ENOMEM;
+ goto out_ctx;
+ }
- state->acquire_ctx = dev->mode_config.acquire_ctx;
+ state->acquire_ctx = &ctx;
retry:
plane_mask = 0;
drm_for_each_plane(plane, dev) {
@@ -375,7 +373,7 @@ retry:
plane_state = drm_atomic_get_plane_state(state, plane);
if (IS_ERR(plane_state)) {
ret = PTR_ERR(plane_state);
- goto fail;
+ goto out_state;
}
plane_state->rotation = DRM_MODE_ROTATE_0;
@@ -389,7 +387,7 @@ retry:
ret = __drm_atomic_helper_disable_plane(plane, plane_state);
if (ret != 0)
- goto fail;
+ goto out_state;
}
for (i = 0; i < fb_helper->crtc_count; i++) {
@@ -397,23 +395,38 @@ retry:
ret = __drm_atomic_helper_set_config(mode_set, state);
if (ret != 0)
- goto fail;
+ goto out_state;
+
+ /*
+ * __drm_atomic_helper_set_config() sets active when a
+ * mode is set, unconditionally clear it if we force DPMS off
+ */
+ if (!active) {
+ struct drm_crtc *crtc = mode_set->crtc;
+ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+
+ crtc_state->active = false;
+ }
}
ret = drm_atomic_commit(state);
-fail:
+out_state:
drm_atomic_clean_old_fb(dev, plane_mask, ret);
if (ret == -EDEADLK)
goto backoff;
drm_atomic_state_put(state);
+out_ctx:
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+
return ret;
backoff:
drm_atomic_state_clear(state);
- drm_atomic_legacy_backoff(state);
+ drm_modeset_backoff(&ctx);
goto retry;
}
@@ -422,8 +435,9 @@ static int restore_fbdev_mode_legacy(struct drm_fb_helper *fb_helper)
{
struct drm_device *dev = fb_helper->dev;
struct drm_plane *plane;
- int i;
+ int i, ret = 0;
+ drm_modeset_lock_all(fb_helper->dev);
drm_for_each_plane(plane, dev) {
if (plane->type != DRM_PLANE_TYPE_PRIMARY)
drm_plane_force_disable(plane);
@@ -437,34 +451,33 @@ static int restore_fbdev_mode_legacy(struct drm_fb_helper *fb_helper)
for (i = 0; i < fb_helper->crtc_count; i++) {
struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
struct drm_crtc *crtc = mode_set->crtc;
- int ret;
if (crtc->funcs->cursor_set2) {
ret = crtc->funcs->cursor_set2(crtc, NULL, 0, 0, 0, 0, 0);
if (ret)
- return ret;
+ goto out;
} else if (crtc->funcs->cursor_set) {
ret = crtc->funcs->cursor_set(crtc, NULL, 0, 0, 0);
if (ret)
- return ret;
+ goto out;
}
ret = drm_mode_set_config_internal(mode_set);
if (ret)
- return ret;
+ goto out;
}
+out:
+ drm_modeset_unlock_all(fb_helper->dev);
- return 0;
+ return ret;
}
static int restore_fbdev_mode(struct drm_fb_helper *fb_helper)
{
struct drm_device *dev = fb_helper->dev;
- drm_warn_on_modeset_not_all_locked(dev);
-
if (drm_drv_uses_atomic_modeset(dev))
- return restore_fbdev_mode_atomic(fb_helper);
+ return restore_fbdev_mode_atomic(fb_helper, true);
else
return restore_fbdev_mode_legacy(fb_helper);
}
@@ -482,23 +495,26 @@ static int restore_fbdev_mode(struct drm_fb_helper *fb_helper)
*/
int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
{
- struct drm_device *dev = fb_helper->dev;
bool do_delayed;
int ret;
if (!drm_fbdev_emulation)
return -ENODEV;
- drm_modeset_lock_all(dev);
+ if (READ_ONCE(fb_helper->deferred_setup))
+ return 0;
+
+ mutex_lock(&fb_helper->lock);
ret = restore_fbdev_mode(fb_helper);
do_delayed = fb_helper->delayed_hotplug;
if (do_delayed)
fb_helper->delayed_hotplug = false;
- drm_modeset_unlock_all(dev);
+ mutex_unlock(&fb_helper->lock);
if (do_delayed)
drm_fb_helper_hotplug_event(fb_helper);
+
return ret;
}
EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode_unlocked);
@@ -517,10 +533,12 @@ static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper)
return false;
drm_for_each_crtc(crtc, dev) {
+ drm_modeset_lock(&crtc->mutex, NULL);
if (crtc->primary->fb)
crtcs_bound++;
if (crtc->primary->fb == fb_helper->fb)
bound++;
+ drm_modeset_unlock(&crtc->mutex);
}
if (bound < crtcs_bound)
@@ -548,11 +566,11 @@ static bool drm_fb_helper_force_kernel_mode(void)
if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
continue;
- drm_modeset_lock_all(dev);
+ mutex_lock(&helper->lock);
ret = restore_fbdev_mode(helper);
if (ret)
error = true;
- drm_modeset_unlock_all(dev);
+ mutex_unlock(&helper->lock);
}
return error;
}
@@ -581,23 +599,14 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { };
#endif
-static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
+static void dpms_legacy(struct drm_fb_helper *fb_helper, int dpms_mode)
{
- struct drm_fb_helper *fb_helper = info->par;
struct drm_device *dev = fb_helper->dev;
struct drm_crtc *crtc;
struct drm_connector *connector;
int i, j;
- /*
- * For each CRTC in this fb, turn the connectors on/off.
- */
drm_modeset_lock_all(dev);
- if (!drm_fb_helper_is_bound(fb_helper)) {
- drm_modeset_unlock_all(dev);
- return;
- }
-
for (i = 0; i < fb_helper->crtc_count; i++) {
crtc = fb_helper->crtc_info[i].mode_set.crtc;
@@ -615,6 +624,26 @@ static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
drm_modeset_unlock_all(dev);
}
+static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
+{
+ struct drm_fb_helper *fb_helper = info->par;
+
+ /*
+ * For each CRTC in this fb, turn the connectors on/off.
+ */
+ mutex_lock(&fb_helper->lock);
+ if (!drm_fb_helper_is_bound(fb_helper)) {
+ mutex_unlock(&fb_helper->lock);
+ return;
+ }
+
+ if (drm_drv_uses_atomic_modeset(fb_helper->dev))
+ restore_fbdev_mode_atomic(fb_helper, dpms_mode == DRM_MODE_DPMS_ON);
+ else
+ dpms_legacy(fb_helper, dpms_mode);
+ mutex_unlock(&fb_helper->lock);
+}
+
/**
* drm_fb_helper_blank - implementation for &fb_ops.fb_blank
* @blank: desired blanking state
@@ -734,6 +763,7 @@ void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
INIT_WORK(&helper->resume_work, drm_fb_helper_resume_worker);
INIT_WORK(&helper->dirty_work, drm_fb_helper_dirty_work);
helper->dirty_clip.x1 = helper->dirty_clip.y1 = ~0;
+ mutex_init(&helper->lock);
helper->funcs = funcs;
helper->dev = dev;
}
@@ -899,6 +929,7 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
}
mutex_unlock(&kernel_fb_helper_lock);
+ mutex_destroy(&fb_helper->lock);
drm_fb_helper_crtc_free(fb_helper);
}
@@ -1167,22 +1198,23 @@ void drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper,
}
EXPORT_SYMBOL(drm_fb_helper_set_suspend_unlocked);
-static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, u16 regno, struct fb_info *info)
+static int setcmap_pseudo_palette(struct fb_cmap *cmap, struct fb_info *info)
{
- struct drm_fb_helper *fb_helper = info->par;
- struct drm_framebuffer *fb = fb_helper->fb;
+ u32 *palette = (u32 *)info->pseudo_palette;
+ int i;
- if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
- u32 *palette;
+ if (cmap->start + cmap->len > 16)
+ return -EINVAL;
+
+ for (i = 0; i < cmap->len; ++i) {
+ u16 red = cmap->red[i];
+ u16 green = cmap->green[i];
+ u16 blue = cmap->blue[i];
u32 value;
- /* place color in psuedopalette */
- if (regno > 16)
- return -EINVAL;
- palette = (u32 *)info->pseudo_palette;
- red >>= (16 - info->var.red.length);
- green >>= (16 - info->var.green.length);
- blue >>= (16 - info->var.blue.length);
+
+ red >>= 16 - info->var.red.length;
+ green >>= 16 - info->var.green.length;
+ blue >>= 16 - info->var.blue.length;
value = (red << info->var.red.offset) |
(green << info->var.green.offset) |
(blue << info->var.blue.offset);
@@ -1192,23 +1224,169 @@ static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
mask <<= info->var.transp.offset;
value |= mask;
}
- palette[regno] = value;
- return 0;
+ palette[cmap->start + i] = value;
}
- /*
- * The driver really shouldn't advertise pseudo/directcolor
- * visuals if it can't deal with the palette.
- */
- if (WARN_ON(!fb_helper->funcs->gamma_set ||
- !fb_helper->funcs->gamma_get))
- return -EINVAL;
+ return 0;
+}
+
+static int setcmap_legacy(struct fb_cmap *cmap, struct fb_info *info)
+{
+ struct drm_fb_helper *fb_helper = info->par;
+ struct drm_crtc *crtc;
+ u16 *r, *g, *b;
+ int i, ret = 0;
- WARN_ON(fb->format->cpp[0] != 1);
+ drm_modeset_lock_all(fb_helper->dev);
+ for (i = 0; i < fb_helper->crtc_count; i++) {
+ crtc = fb_helper->crtc_info[i].mode_set.crtc;
+ if (!crtc->funcs->gamma_set || !crtc->gamma_size)
+ return -EINVAL;
- fb_helper->funcs->gamma_set(crtc, red, green, blue, regno);
+ if (cmap->start + cmap->len > crtc->gamma_size)
+ return -EINVAL;
- return 0;
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
+
+ memcpy(r + cmap->start, cmap->red, cmap->len * sizeof(*r));
+ memcpy(g + cmap->start, cmap->green, cmap->len * sizeof(*g));
+ memcpy(b + cmap->start, cmap->blue, cmap->len * sizeof(*b));
+
+ ret = crtc->funcs->gamma_set(crtc, r, g, b,
+ crtc->gamma_size, NULL);
+ if (ret)
+ return ret;
+ }
+ drm_modeset_unlock_all(fb_helper->dev);
+
+ return ret;
+}
+
+static struct drm_property_blob *setcmap_new_gamma_lut(struct drm_crtc *crtc,
+ struct fb_cmap *cmap)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_property_blob *gamma_lut;
+ struct drm_color_lut *lut;
+ int size = crtc->gamma_size;
+ int i;
+
+ if (!size || cmap->start + cmap->len > size)
+ return ERR_PTR(-EINVAL);
+
+ gamma_lut = drm_property_create_blob(dev, sizeof(*lut) * size, NULL);
+ if (IS_ERR(gamma_lut))
+ return gamma_lut;
+
+ lut = (struct drm_color_lut *)gamma_lut->data;
+ if (cmap->start || cmap->len != size) {
+ u16 *r = crtc->gamma_store;
+ u16 *g = r + crtc->gamma_size;
+ u16 *b = g + crtc->gamma_size;
+
+ for (i = 0; i < cmap->start; i++) {
+ lut[i].red = r[i];
+ lut[i].green = g[i];
+ lut[i].blue = b[i];
+ }
+ for (i = cmap->start + cmap->len; i < size; i++) {
+ lut[i].red = r[i];
+ lut[i].green = g[i];
+ lut[i].blue = b[i];
+ }
+ }
+
+ for (i = 0; i < cmap->len; i++) {
+ lut[cmap->start + i].red = cmap->red[i];
+ lut[cmap->start + i].green = cmap->green[i];
+ lut[cmap->start + i].blue = cmap->blue[i];
+ }
+
+ return gamma_lut;
+}
+
+static int setcmap_atomic(struct fb_cmap *cmap, struct fb_info *info)
+{
+ struct drm_fb_helper *fb_helper = info->par;
+ struct drm_device *dev = fb_helper->dev;
+ struct drm_property_blob *gamma_lut = NULL;
+ struct drm_modeset_acquire_ctx ctx;
+ struct drm_crtc_state *crtc_state;
+ struct drm_atomic_state *state;
+ struct drm_crtc *crtc;
+ u16 *r, *g, *b;
+ int i, ret = 0;
+ bool replaced;
+
+ drm_modeset_acquire_init(&ctx, 0);
+
+ state = drm_atomic_state_alloc(dev);
+ if (!state) {
+ ret = -ENOMEM;
+ goto out_ctx;
+ }
+
+ state->acquire_ctx = &ctx;
+retry:
+ for (i = 0; i < fb_helper->crtc_count; i++) {
+ crtc = fb_helper->crtc_info[i].mode_set.crtc;
+
+ if (!gamma_lut)
+ gamma_lut = setcmap_new_gamma_lut(crtc, cmap);
+ if (IS_ERR(gamma_lut)) {
+ ret = PTR_ERR(gamma_lut);
+ gamma_lut = NULL;
+ goto out_state;
+ }
+
+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
+ if (IS_ERR(crtc_state)) {
+ ret = PTR_ERR(crtc_state);
+ goto out_state;
+ }
+
+ replaced = drm_property_replace_blob(&crtc_state->degamma_lut,
+ NULL);
+ replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL);
+ replaced |= drm_property_replace_blob(&crtc_state->gamma_lut,
+ gamma_lut);
+ crtc_state->color_mgmt_changed |= replaced;
+ }
+
+ ret = drm_atomic_commit(state);
+ if (ret)
+ goto out_state;
+
+ for (i = 0; i < fb_helper->crtc_count; i++) {
+ crtc = fb_helper->crtc_info[i].mode_set.crtc;
+
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
+
+ memcpy(r + cmap->start, cmap->red, cmap->len * sizeof(*r));
+ memcpy(g + cmap->start, cmap->green, cmap->len * sizeof(*g));
+ memcpy(b + cmap->start, cmap->blue, cmap->len * sizeof(*b));
+ }
+
+out_state:
+ if (ret == -EDEADLK)
+ goto backoff;
+
+ drm_property_blob_put(gamma_lut);
+ drm_atomic_state_put(state);
+out_ctx:
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+
+ return ret;
+
+backoff:
+ drm_atomic_state_clear(state);
+ drm_modeset_backoff(&ctx);
+ goto retry;
}
/**
@@ -1219,52 +1397,29 @@ static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
{
struct drm_fb_helper *fb_helper = info->par;
- struct drm_device *dev = fb_helper->dev;
- const struct drm_crtc_helper_funcs *crtc_funcs;
- u16 *red, *green, *blue, *transp;
- struct drm_crtc *crtc;
- int i, j, rc = 0;
- int start;
+ int ret;
if (oops_in_progress)
return -EBUSY;
- drm_modeset_lock_all(dev);
+ mutex_lock(&fb_helper->lock);
+
if (!drm_fb_helper_is_bound(fb_helper)) {
- drm_modeset_unlock_all(dev);
- return -EBUSY;
+ ret = -EBUSY;
+ goto out;
}
- for (i = 0; i < fb_helper->crtc_count; i++) {
- crtc = fb_helper->crtc_info[i].mode_set.crtc;
- crtc_funcs = crtc->helper_private;
-
- red = cmap->red;
- green = cmap->green;
- blue = cmap->blue;
- transp = cmap->transp;
- start = cmap->start;
-
- for (j = 0; j < cmap->len; j++) {
- u16 hred, hgreen, hblue, htransp = 0xffff;
-
- hred = *red++;
- hgreen = *green++;
- hblue = *blue++;
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR)
+ ret = setcmap_pseudo_palette(cmap, info);
+ else if (drm_drv_uses_atomic_modeset(fb_helper->dev))
+ ret = setcmap_atomic(cmap, info);
+ else
+ ret = setcmap_legacy(cmap, info);
- if (transp)
- htransp = *transp++;
+out:
+ mutex_unlock(&fb_helper->lock);
- rc = setcolreg(crtc, hred, hgreen, hblue, start++, info);
- if (rc)
- goto out;
- }
- if (crtc_funcs->load_lut)
- crtc_funcs->load_lut(crtc);
- }
- out:
- drm_modeset_unlock_all(dev);
- return rc;
+ return ret;
}
EXPORT_SYMBOL(drm_fb_helper_setcmap);
@@ -1281,12 +1436,11 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
unsigned long arg)
{
struct drm_fb_helper *fb_helper = info->par;
- struct drm_device *dev = fb_helper->dev;
struct drm_mode_set *mode_set;
struct drm_crtc *crtc;
int ret = 0;
- mutex_lock(&dev->mode_config.mutex);
+ mutex_lock(&fb_helper->lock);
if (!drm_fb_helper_is_bound(fb_helper)) {
ret = -EBUSY;
goto unlock;
@@ -1331,7 +1485,7 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
}
unlock:
- mutex_unlock(&dev->mode_config.mutex);
+ mutex_unlock(&fb_helper->lock);
return ret;
}
EXPORT_SYMBOL(drm_fb_helper_ioctl);
@@ -1463,61 +1617,36 @@ int drm_fb_helper_set_par(struct fb_info *info)
}
EXPORT_SYMBOL(drm_fb_helper_set_par);
-static int pan_display_atomic(struct fb_var_screeninfo *var,
- struct fb_info *info)
+static void pan_set(struct drm_fb_helper *fb_helper, int x, int y)
{
- struct drm_fb_helper *fb_helper = info->par;
- struct drm_device *dev = fb_helper->dev;
- struct drm_atomic_state *state;
- struct drm_plane *plane;
- int i, ret;
- unsigned int plane_mask;
-
- state = drm_atomic_state_alloc(dev);
- if (!state)
- return -ENOMEM;
+ int i;
- state->acquire_ctx = dev->mode_config.acquire_ctx;
-retry:
- plane_mask = 0;
for (i = 0; i < fb_helper->crtc_count; i++) {
struct drm_mode_set *mode_set;
mode_set = &fb_helper->crtc_info[i].mode_set;
- mode_set->x = var->xoffset;
- mode_set->y = var->yoffset;
-
- ret = __drm_atomic_helper_set_config(mode_set, state);
- if (ret != 0)
- goto fail;
-
- plane = mode_set->crtc->primary;
- plane_mask |= (1 << drm_plane_index(plane));
- plane->old_fb = plane->fb;
+ mode_set->x = x;
+ mode_set->y = y;
}
+}
- ret = drm_atomic_commit(state);
- if (ret != 0)
- goto fail;
+static int pan_display_atomic(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct drm_fb_helper *fb_helper = info->par;
+ int ret;
- info->var.xoffset = var->xoffset;
- info->var.yoffset = var->yoffset;
+ pan_set(fb_helper, var->xoffset, var->yoffset);
-fail:
- drm_atomic_clean_old_fb(dev, plane_mask, ret);
+ ret = restore_fbdev_mode_atomic(fb_helper, true);
+ if (!ret) {
+ info->var.xoffset = var->xoffset;
+ info->var.yoffset = var->yoffset;
+ } else
+ pan_set(fb_helper, info->var.xoffset, info->var.yoffset);
- if (ret == -EDEADLK)
- goto backoff;
-
- drm_atomic_state_put(state);
return ret;
-
-backoff:
- drm_atomic_state_clear(state);
- drm_atomic_legacy_backoff(state);
-
- goto retry;
}
static int pan_display_legacy(struct fb_var_screeninfo *var,
@@ -1528,6 +1657,7 @@ static int pan_display_legacy(struct fb_var_screeninfo *var,
int ret = 0;
int i;
+ drm_modeset_lock_all(fb_helper->dev);
for (i = 0; i < fb_helper->crtc_count; i++) {
modeset = &fb_helper->crtc_info[i].mode_set;
@@ -1542,6 +1672,7 @@ static int pan_display_legacy(struct fb_var_screeninfo *var,
}
}
}
+ drm_modeset_unlock_all(fb_helper->dev);
return ret;
}
@@ -1561,9 +1692,9 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
if (oops_in_progress)
return -EBUSY;
- drm_modeset_lock_all(dev);
+ mutex_lock(&fb_helper->lock);
if (!drm_fb_helper_is_bound(fb_helper)) {
- drm_modeset_unlock_all(dev);
+ mutex_unlock(&fb_helper->lock);
return -EBUSY;
}
@@ -1571,7 +1702,7 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
ret = pan_display_atomic(var, info);
else
ret = pan_display_legacy(var, info);
- drm_modeset_unlock_all(dev);
+ mutex_unlock(&fb_helper->lock);
return ret;
}
@@ -1579,8 +1710,7 @@ EXPORT_SYMBOL(drm_fb_helper_pan_display);
/*
* Allocates the backing storage and sets up the fbdev info structure through
- * the ->fb_probe callback and then registers the fbdev and sets up the panic
- * notifier.
+ * the ->fb_probe callback.
*/
static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
int preferred_bpp)
@@ -1678,13 +1808,8 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
}
if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) {
- /*
- * hmm everyone went away - assume VGA cable just fell out
- * and will come back later.
- */
- DRM_INFO("Cannot find any crtc or sizes - going 1024x768\n");
- sizes.fb_width = sizes.surface_width = 1024;
- sizes.fb_height = sizes.surface_height = 768;
+ DRM_INFO("Cannot find any crtc or sizes\n");
+ return -EAGAIN;
}
/* Handle our overallocation */
@@ -1696,17 +1821,6 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
if (ret < 0)
return ret;
- /*
- * Set the fb pointer - usually drm_setup_crtcs does this for hotplug
- * events, but at init time drm_setup_crtcs needs to be called before
- * the fb is allocated (since we need to figure out the desired size of
- * the fb before we can allocate it ...). Hence we need to fix things up
- * here again.
- */
- for (i = 0; i < fb_helper->crtc_count; i++)
- if (fb_helper->crtc_info[i].mode_set.num_connectors)
- fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
-
return 0;
}
@@ -1768,8 +1882,6 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe
info->var.xoffset = 0;
info->var.yoffset = 0;
info->var.activate = FB_ACTIVATE_NOW;
- info->var.height = -1;
- info->var.width = -1;
switch (fb->format->depth) {
case 8:
@@ -1831,12 +1943,11 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe
EXPORT_SYMBOL(drm_fb_helper_fill_var);
static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper *fb_helper,
- uint32_t maxX,
- uint32_t maxY)
+ uint32_t maxX,
+ uint32_t maxY)
{
struct drm_connector *connector;
- int count = 0;
- int i;
+ int i, count = 0;
drm_fb_helper_for_each_connector(fb_helper, i) {
connector = fb_helper->connector_info[i]->connector;
@@ -2234,11 +2345,8 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
int i;
DRM_DEBUG_KMS("\n");
- if (drm_fb_helper_probe_connector_modes(fb_helper, width, height) == 0)
- DRM_DEBUG_KMS("No connectors reported connected with modes\n");
-
/* prevent concurrent modification of connector_count by hotplug */
- lockdep_assert_held(&fb_helper->dev->mode_config.mutex);
+ lockdep_assert_held(&fb_helper->lock);
crtcs = kcalloc(fb_helper->connector_count,
sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
@@ -2253,6 +2361,9 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
goto out;
}
+ mutex_lock(&fb_helper->dev->mode_config.mutex);
+ if (drm_fb_helper_probe_connector_modes(fb_helper, width, height) == 0)
+ DRM_DEBUG_KMS("No connectors reported connected with modes\n");
drm_enable_connectors(fb_helper, enabled);
if (!(fb_helper->funcs->initial_config &&
@@ -2274,6 +2385,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
drm_pick_crtcs(fb_helper, crtcs, modes, 0, width, height);
}
+ mutex_unlock(&fb_helper->dev->mode_config.mutex);
/* need to set the modesets up here for use later */
/* fill out the connector<->crtc mappings into the modesets */
@@ -2285,9 +2397,9 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
struct drm_display_mode *mode = modes[i];
struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
struct drm_fb_offset *offset = &offsets[i];
- struct drm_mode_set *modeset = &fb_crtc->mode_set;
if (mode && fb_crtc) {
+ struct drm_mode_set *modeset = &fb_crtc->mode_set;
struct drm_connector *connector =
fb_helper->connector_info[i]->connector;
@@ -2301,7 +2413,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
fb_crtc->desired_mode);
drm_connector_get(connector);
modeset->connectors[modeset->num_connectors++] = connector;
- modeset->fb = fb_helper->fb;
modeset->x = offset->x;
modeset->y = offset->y;
}
@@ -2313,6 +2424,91 @@ out:
kfree(enabled);
}
+/*
+ * This is a continuation of drm_setup_crtcs() that sets up anything related
+ * to the framebuffer. During initialization, drm_setup_crtcs() is called before
+ * the framebuffer has been allocated (fb_helper->fb and fb_helper->fbdev).
+ * So, any setup that touches those fields needs to be done here instead of in
+ * drm_setup_crtcs().
+ */
+static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
+{
+ struct fb_info *info = fb_helper->fbdev;
+ int i;
+
+ for (i = 0; i < fb_helper->crtc_count; i++)
+ if (fb_helper->crtc_info[i].mode_set.num_connectors)
+ fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
+
+ mutex_lock(&fb_helper->dev->mode_config.mutex);
+ drm_fb_helper_for_each_connector(fb_helper, i) {
+ struct drm_connector *connector =
+ fb_helper->connector_info[i]->connector;
+
+ /* use first connected connector for the physical dimensions */
+ if (connector->status == connector_status_connected) {
+ info->var.width = connector->display_info.width_mm;
+ info->var.height = connector->display_info.height_mm;
+ break;
+ }
+ }
+ mutex_unlock(&fb_helper->dev->mode_config.mutex);
+}
+
+/* Note: Drops fb_helper->lock before returning. */
+static int
+__drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper,
+ int bpp_sel)
+{
+ struct drm_device *dev = fb_helper->dev;
+ struct fb_info *info;
+ unsigned int width, height;
+ int ret;
+
+ width = dev->mode_config.max_width;
+ height = dev->mode_config.max_height;
+
+ drm_setup_crtcs(fb_helper, width, height);
+ ret = drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);
+ if (ret < 0) {
+ if (ret == -EAGAIN) {
+ fb_helper->preferred_bpp = bpp_sel;
+ fb_helper->deferred_setup = true;
+ ret = 0;
+ }
+ mutex_unlock(&fb_helper->lock);
+
+ return ret;
+ }
+ drm_setup_crtcs_fb(fb_helper);
+
+ fb_helper->deferred_setup = false;
+
+ info = fb_helper->fbdev;
+ info->var.pixclock = 0;
+
+ /* Need to drop locks to avoid recursive deadlock in
+ * register_framebuffer. This is ok because the only thing left to do is
+ * register the fbdev emulation instance in kernel_fb_helper_list. */
+ mutex_unlock(&fb_helper->lock);
+
+ ret = register_framebuffer(info);
+ if (ret < 0)
+ return ret;
+
+ dev_info(dev->dev, "fb%d: %s frame buffer device\n",
+ info->node, info->fix.id);
+
+ mutex_lock(&kernel_fb_helper_lock);
+ if (list_empty(&kernel_fb_helper_list))
+ register_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
+
+ list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list);
+ mutex_unlock(&kernel_fb_helper_lock);
+
+ return 0;
+}
+
/**
* drm_fb_helper_initial_config - setup a sane initial connector configuration
* @fb_helper: fb_helper device struct
@@ -2357,39 +2553,15 @@ out:
*/
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
{
- struct drm_device *dev = fb_helper->dev;
- struct fb_info *info;
int ret;
if (!drm_fbdev_emulation)
return 0;
- mutex_lock(&dev->mode_config.mutex);
- drm_setup_crtcs(fb_helper,
- dev->mode_config.max_width,
- dev->mode_config.max_height);
- ret = drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);
- mutex_unlock(&dev->mode_config.mutex);
- if (ret)
- return ret;
+ mutex_lock(&fb_helper->lock);
+ ret = __drm_fb_helper_initial_config_and_unlock(fb_helper, bpp_sel);
- info = fb_helper->fbdev;
- info->var.pixclock = 0;
- ret = register_framebuffer(info);
- if (ret < 0)
- return ret;
-
- dev_info(dev->dev, "fb%d: %s frame buffer device\n",
- info->node, info->fix.id);
-
- mutex_lock(&kernel_fb_helper_lock);
- if (list_empty(&kernel_fb_helper_list))
- register_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
-
- list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list);
- mutex_unlock(&kernel_fb_helper_lock);
-
- return 0;
+ return ret;
}
EXPORT_SYMBOL(drm_fb_helper_initial_config);
@@ -2416,22 +2588,29 @@ EXPORT_SYMBOL(drm_fb_helper_initial_config);
*/
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
{
- struct drm_device *dev = fb_helper->dev;
+ int err = 0;
if (!drm_fbdev_emulation)
return 0;
- mutex_lock(&dev->mode_config.mutex);
+ mutex_lock(&fb_helper->lock);
+ if (fb_helper->deferred_setup) {
+ err = __drm_fb_helper_initial_config_and_unlock(fb_helper,
+ fb_helper->preferred_bpp);
+ return err;
+ }
+
if (!fb_helper->fb || !drm_fb_helper_is_bound(fb_helper)) {
fb_helper->delayed_hotplug = true;
- mutex_unlock(&dev->mode_config.mutex);
- return 0;
+ mutex_unlock(&fb_helper->lock);
+ return err;
}
+
DRM_DEBUG_KMS("\n");
drm_setup_crtcs(fb_helper, fb_helper->fb->width, fb_helper->fb->height);
-
- mutex_unlock(&dev->mode_config.mutex);
+ drm_setup_crtcs_fb(fb_helper);
+ mutex_unlock(&fb_helper->lock);
drm_fb_helper_set_par(fb_helper->fbdev);
diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index 84f3a242cc39..b3c6e997ccdb 100644
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -75,7 +75,7 @@ DEFINE_MUTEX(drm_global_mutex);
* for drivers which use the CMA GEM helpers it's drm_gem_cma_mmap().
*
* No other file operations are supported by the DRM userspace API. Overall the
- * following is an example #file_operations structure::
+ * following is an example &file_operations structure::
*
* static const example_drm_fops = {
* .owner = THIS_MODULE,
@@ -92,6 +92,11 @@ DEFINE_MUTEX(drm_global_mutex);
* For plain GEM based drivers there is the DEFINE_DRM_GEM_FOPS() macro, and for
* CMA based drivers there is the DEFINE_DRM_GEM_CMA_FOPS() macro to make this
* simpler.
+ *
+ * The driver's &file_operations must be stored in &drm_driver.fops.
+ *
+ * For driver-private IOCTL handling see the more detailed discussion in
+ * :ref:`IOCTL support in the userland interfaces chapter<drm_driver_ioctl>`.
*/
static int drm_open_helper(struct file *filp, struct drm_minor *minor);
@@ -431,7 +436,7 @@ int drm_release(struct inode *inode, struct file *filp)
if (!--dev->open_count) {
drm_lastclose(dev);
- if (drm_device_is_unplugged(dev))
+ if (drm_dev_is_unplugged(dev))
drm_put_dev(dev);
}
mutex_unlock(&drm_global_mutex);
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index b3ef4f1c2630..af279844d7ce 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -817,7 +817,7 @@ retry:
plane->old_fb = plane->fb;
}
- for_each_connector_in_state(state, conn, conn_state, i) {
+ for_each_new_connector_in_state(state, conn, conn_state, i) {
ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
if (ret)
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 8dc11064253d..ad4e9cfe48a2 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -311,6 +311,41 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle)
EXPORT_SYMBOL(drm_gem_handle_delete);
/**
+ * drm_gem_dumb_map_offset - return the fake mmap offset for a gem object
+ * @file: drm file-private structure containing the gem object
+ * @dev: corresponding drm_device
+ * @handle: gem object handle
+ * @offset: return location for the fake mmap offset
+ *
+ * This implements the &drm_driver.dumb_map_offset kms driver callback for
+ * drivers which use gem to manage their backing storage.
+ *
+ * Returns:
+ * 0 on success or a negative error code on failure.
+ */
+int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
+ u32 handle, u64 *offset)
+{
+ struct drm_gem_object *obj;
+ int ret;
+
+ obj = drm_gem_object_lookup(file, handle);
+ if (!obj)
+ return -ENOENT;
+
+ ret = drm_gem_create_mmap_offset(obj);
+ if (ret)
+ goto out;
+
+ *offset = drm_vma_node_offset_addr(&obj->vma_node);
+out:
+ drm_gem_object_put_unlocked(obj);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(drm_gem_dumb_map_offset);
+
+/**
* drm_gem_dumb_destroy - dumb fb callback helper for gem based drivers
* @file: drm file-private structure to remove the dumb handle from
* @dev: corresponding drm_device
@@ -826,13 +861,15 @@ drm_gem_object_put_unlocked(struct drm_gem_object *obj)
return;
dev = obj->dev;
- might_lock(&dev->struct_mutex);
- if (dev->driver->gem_free_object_unlocked)
+ if (dev->driver->gem_free_object_unlocked) {
kref_put(&obj->refcount, drm_gem_object_free);
- else if (kref_put_mutex(&obj->refcount, drm_gem_object_free,
+ } else {
+ might_lock(&dev->struct_mutex);
+ if (kref_put_mutex(&obj->refcount, drm_gem_object_free,
&dev->struct_mutex))
- mutex_unlock(&dev->struct_mutex);
+ mutex_unlock(&dev->struct_mutex);
+ }
}
EXPORT_SYMBOL(drm_gem_object_put_unlocked);
@@ -964,7 +1001,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
struct drm_vma_offset_node *node;
int ret;
- if (drm_device_is_unplugged(dev))
+ if (drm_dev_is_unplugged(dev))
return -ENODEV;
drm_vma_offset_lock_lookup(dev->vma_offset_manager);
diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c
index bc28e7575254..373e33f22be4 100644
--- a/drivers/gpu/drm/drm_gem_cma_helper.c
+++ b/drivers/gpu/drm/drm_gem_cma_helper.c
@@ -177,7 +177,7 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv,
* This function frees the backing memory of the CMA GEM object, cleans up the
* GEM object state and frees the memory used to store the object itself.
* Drivers using the CMA helpers should set this as their
- * &drm_driver.gem_free_object callback.
+ * &drm_driver.gem_free_object_unlocked callback.
*/
void drm_gem_cma_free_object(struct drm_gem_object *gem_obj)
{
@@ -264,41 +264,6 @@ int drm_gem_cma_dumb_create(struct drm_file *file_priv,
}
EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_create);
-/**
- * drm_gem_cma_dumb_map_offset - return the fake mmap offset for a CMA GEM
- * object
- * @file_priv: DRM file-private structure containing the GEM object
- * @drm: DRM device
- * @handle: GEM object handle
- * @offset: return location for the fake mmap offset
- *
- * This function look up an object by its handle and returns the fake mmap
- * offset associated with it. Drivers using the CMA helpers should set this
- * as their &drm_driver.dumb_map_offset callback.
- *
- * Returns:
- * 0 on success or a negative error code on failure.
- */
-int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv,
- struct drm_device *drm, u32 handle,
- u64 *offset)
-{
- struct drm_gem_object *gem_obj;
-
- gem_obj = drm_gem_object_lookup(file_priv, handle);
- if (!gem_obj) {
- dev_err(drm->dev, "failed to lookup GEM object\n");
- return -EINVAL;
- }
-
- *offset = drm_vma_node_offset_addr(&gem_obj->vma_node);
-
- drm_gem_object_put_unlocked(gem_obj);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_map_offset);
-
const struct vm_operations_struct drm_gem_cma_vm_ops = {
.open = drm_gem_vm_open,
.close = drm_gem_vm_close,
@@ -390,7 +355,7 @@ unsigned long drm_gem_cma_get_unmapped_area(struct file *filp,
struct drm_device *dev = priv->minor->dev;
struct drm_vma_offset_node *node;
- if (drm_device_is_unplugged(dev))
+ if (drm_dev_is_unplugged(dev))
return -ENODEV;
drm_vma_offset_lock_lookup(dev->vma_offset_manager);
diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
new file mode 100644
index 000000000000..d54a083dc5dd
--- /dev/null
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -0,0 +1,283 @@
+/*
+ * drm gem framebuffer helper functions
+ *
+ * Copyright (C) 2017 Noralf Trønnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/dma-buf.h>
+#include <linux/dma-fence.h>
+#include <linux/reservation.h>
+#include <linux/slab.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem.h>
+#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_modeset_helper.h>
+
+/**
+ * DOC: overview
+ *
+ * This library provides helpers for drivers that don't subclass
+ * &drm_framebuffer and and use &drm_gem_object for their backing storage.
+ *
+ * Drivers without additional needs to validate framebuffers can simply use
+ * drm_gem_fb_create() and everything is wired up automatically. But all
+ * parts can be used individually.
+ */
+
+/**
+ * drm_gem_fb_get_obj() - Get GEM object for framebuffer
+ * @fb: The framebuffer
+ * @plane: Which plane
+ *
+ * Returns the GEM object for given framebuffer.
+ */
+struct drm_gem_object *drm_gem_fb_get_obj(struct drm_framebuffer *fb,
+ unsigned int plane)
+{
+ if (plane >= 4)
+ return NULL;
+
+ return fb->obj[plane];
+}
+EXPORT_SYMBOL_GPL(drm_gem_fb_get_obj);
+
+static struct drm_framebuffer *
+drm_gem_fb_alloc(struct drm_device *dev,
+ const struct drm_mode_fb_cmd2 *mode_cmd,
+ struct drm_gem_object **obj, unsigned int num_planes,
+ const struct drm_framebuffer_funcs *funcs)
+{
+ struct drm_framebuffer *fb;
+ int ret, i;
+
+ fb = kzalloc(sizeof(*fb), GFP_KERNEL);
+ if (!fb)
+ return ERR_PTR(-ENOMEM);
+
+ drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
+
+ for (i = 0; i < num_planes; i++)
+ fb->obj[i] = obj[i];
+
+ ret = drm_framebuffer_init(dev, fb, funcs);
+ if (ret) {
+ DRM_DEV_ERROR(dev->dev, "Failed to init framebuffer: %d\n",
+ ret);
+ kfree(fb);
+ return ERR_PTR(ret);
+ }
+
+ return fb;
+}
+
+/**
+ * drm_gem_fb_destroy - Free GEM backed framebuffer
+ * @fb: DRM framebuffer
+ *
+ * Frees a GEM backed framebuffer with its backing buffer(s) and the structure
+ * itself. Drivers can use this as their &drm_framebuffer_funcs->destroy
+ * callback.
+ */
+void drm_gem_fb_destroy(struct drm_framebuffer *fb)
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ drm_gem_object_put_unlocked(fb->obj[i]);
+
+ drm_framebuffer_cleanup(fb);
+ kfree(fb);
+}
+EXPORT_SYMBOL(drm_gem_fb_destroy);
+
+/**
+ * drm_gem_fb_create_handle - Create handle for GEM backed framebuffer
+ * @fb: DRM framebuffer
+ * @file: drm file
+ * @handle: handle created
+ *
+ * Drivers can use this as their &drm_framebuffer_funcs->create_handle
+ * callback.
+ *
+ * Returns:
+ * 0 on success or a negative error code on failure.
+ */
+int drm_gem_fb_create_handle(struct drm_framebuffer *fb, struct drm_file *file,
+ unsigned int *handle)
+{
+ return drm_gem_handle_create(file, fb->obj[0], handle);
+}
+EXPORT_SYMBOL(drm_gem_fb_create_handle);
+
+/**
+ * drm_gem_fb_create_with_funcs() - helper function for the
+ * &drm_mode_config_funcs.fb_create
+ * callback
+ * @dev: DRM device
+ * @file: drm file for the ioctl call
+ * @mode_cmd: metadata from the userspace fb creation request
+ * @funcs: vtable to be used for the new framebuffer object
+ *
+ * This can be used to set &drm_framebuffer_funcs for drivers that need the
+ * &drm_framebuffer_funcs.dirty callback. Use drm_gem_fb_create() if you don't
+ * need to change &drm_framebuffer_funcs.
+ * The function does buffer size validation.
+ */
+struct drm_framebuffer *
+drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
+ const struct drm_mode_fb_cmd2 *mode_cmd,
+ const struct drm_framebuffer_funcs *funcs)
+{
+ const struct drm_format_info *info;
+ struct drm_gem_object *objs[4];
+ struct drm_framebuffer *fb;
+ int ret, i;
+
+ info = drm_get_format_info(dev, mode_cmd);
+ if (!info)
+ return ERR_PTR(-EINVAL);
+
+ for (i = 0; i < info->num_planes; i++) {
+ unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
+ unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
+ unsigned int min_size;
+
+ objs[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]);
+ if (!objs[i]) {
+ DRM_DEV_ERROR(dev->dev, "Failed to lookup GEM\n");
+ ret = -ENOENT;
+ goto err_gem_object_put;
+ }
+
+ min_size = (height - 1) * mode_cmd->pitches[i]
+ + width * info->cpp[i]
+ + mode_cmd->offsets[i];
+
+ if (objs[i]->size < min_size) {
+ drm_gem_object_put_unlocked(objs[i]);
+ ret = -EINVAL;
+ goto err_gem_object_put;
+ }
+ }
+
+ fb = drm_gem_fb_alloc(dev, mode_cmd, objs, i, funcs);
+ if (IS_ERR(fb)) {
+ ret = PTR_ERR(fb);
+ goto err_gem_object_put;
+ }
+
+ return fb;
+
+err_gem_object_put:
+ for (i--; i >= 0; i--)
+ drm_gem_object_put_unlocked(objs[i]);
+
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_funcs);
+
+static const struct drm_framebuffer_funcs drm_gem_fb_funcs = {
+ .destroy = drm_gem_fb_destroy,
+ .create_handle = drm_gem_fb_create_handle,
+};
+
+/**
+ * drm_gem_fb_create() - &drm_mode_config_funcs.fb_create callback function
+ * @dev: DRM device
+ * @file: drm file for the ioctl call
+ * @mode_cmd: metadata from the userspace fb creation request
+ *
+ * If your hardware has special alignment or pitch requirements these should be
+ * checked before calling this function. The function does buffer size
+ * validation. Use drm_gem_fb_create_with_funcs() if you need to set
+ * &drm_framebuffer_funcs.dirty.
+ */
+struct drm_framebuffer *
+drm_gem_fb_create(struct drm_device *dev, struct drm_file *file,
+ const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+ return drm_gem_fb_create_with_funcs(dev, file, mode_cmd,
+ &drm_gem_fb_funcs);
+}
+EXPORT_SYMBOL_GPL(drm_gem_fb_create);
+
+/**
+ * drm_gem_fb_prepare_fb() - Prepare gem framebuffer
+ * @plane: Which plane
+ * @state: Plane state attach fence to
+ *
+ * This can be used as the &drm_plane_helper_funcs.prepare_fb hook.
+ *
+ * This function checks if the plane FB has an dma-buf attached, extracts
+ * the exclusive fence and attaches it to plane state for the atomic helper
+ * to wait on.
+ *
+ * There is no need for &drm_plane_helper_funcs.cleanup_fb hook for simple
+ * gem based framebuffer drivers which have their buffers always pinned in
+ * memory.
+ */
+int drm_gem_fb_prepare_fb(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ struct dma_buf *dma_buf;
+ struct dma_fence *fence;
+
+ if ((plane->state->fb == state->fb) || !state->fb)
+ return 0;
+
+ dma_buf = drm_gem_fb_get_obj(state->fb, 0)->dma_buf;
+ if (dma_buf) {
+ fence = reservation_object_get_excl_rcu(dma_buf->resv);
+ drm_atomic_set_fence_for_plane(state, fence);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(drm_gem_fb_prepare_fb);
+
+/**
+ * drm_gem_fbdev_fb_create - Create a drm_framebuffer for fbdev emulation
+ * @dev: DRM device
+ * @sizes: fbdev size description
+ * @pitch_align: optional pitch alignment
+ * @obj: GEM object backing the framebuffer
+ * @funcs: vtable to be used for the new framebuffer object
+ *
+ * This function creates a framebuffer for use with fbdev emulation.
+ *
+ * Returns:
+ * Pointer to a drm_framebuffer on success or an error pointer on failure.
+ */
+struct drm_framebuffer *
+drm_gem_fbdev_fb_create(struct drm_device *dev,
+ struct drm_fb_helper_surface_size *sizes,
+ unsigned int pitch_align, struct drm_gem_object *obj,
+ const struct drm_framebuffer_funcs *funcs)
+{
+ struct drm_mode_fb_cmd2 mode_cmd = { 0 };
+
+ mode_cmd.width = sizes->surface_width;
+ mode_cmd.height = sizes->surface_height;
+ mode_cmd.pitches[0] = sizes->surface_width *
+ DIV_ROUND_UP(sizes->surface_bpp, 8);
+ if (pitch_align)
+ mode_cmd.pitches[0] = roundup(mode_cmd.pitches[0],
+ pitch_align);
+ mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
+ sizes->surface_depth);
+ if (obj->size < mode_cmd.pitches[0] * mode_cmd.height)
+ return ERR_PTR(-EINVAL);
+
+ return drm_gem_fb_alloc(dev, &mode_cmd, &obj, 1, funcs);
+}
+EXPORT_SYMBOL(drm_gem_fbdev_fb_create);
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 5edc24bd10fa..4e906b82a170 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -32,6 +32,7 @@ void drm_lastclose(struct drm_device *dev);
int drm_irq_by_busid(struct drm_device *dev, void *data,
struct drm_file *file_priv);
void drm_pci_agp_destroy(struct drm_device *dev);
+int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master);
/* drm_prime.c */
int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
@@ -56,14 +57,19 @@ int drm_gem_name_info(struct seq_file *m, void *data);
/* drm_vblank.c */
extern unsigned int drm_timestamp_monotonic;
void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
+void drm_vblank_cleanup(struct drm_device *dev);
+
+/* IOCTLS */
+int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *filp);
+int drm_legacy_modeset_ctl_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+/* drm_irq.c */
/* IOCTLS */
-int drm_wait_vblank(struct drm_device *dev, void *data,
- struct drm_file *filp);
int drm_legacy_irq_control(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-int drm_legacy_modeset_ctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
/* drm_auth.c */
int drm_getmagic(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c
index d1f202852028..f8e96e648acf 100644
--- a/drivers/gpu/drm/drm_ioc32.c
+++ b/drivers/gpu/drm/drm_ioc32.c
@@ -842,7 +842,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
req.request.type = req32.request.type;
req.request.sequence = req32.request.sequence;
req.request.signal = req32.request.signal;
- err = drm_ioctl_kernel(file, drm_wait_vblank, &req, DRM_UNLOCKED);
+ err = drm_ioctl_kernel(file, drm_wait_vblank_ioctl, &req, DRM_UNLOCKED);
if (err)
return err;
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index f1eb326524cf..d920b2118a39 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -143,8 +143,8 @@ static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv)
if (master->unique != NULL)
drm_unset_busid(dev, master);
- if (dev->driver->set_busid) {
- ret = dev->driver->set_busid(dev, master);
+ if (dev->dev && dev_is_pci(dev->dev)) {
+ ret = drm_pci_set_busid(dev, master);
if (ret) {
drm_unset_busid(dev, master);
return ret;
@@ -603,9 +603,9 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_legacy_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_legacy_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank_ioctl, DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_legacy_modeset_ctl, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_legacy_modeset_ctl_ioctl, 0),
DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
@@ -695,7 +695,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
*
* DRM driver private IOCTL must be in the range from DRM_COMMAND_BASE to
* DRM_COMMAND_END. Finally you need an array of &struct drm_ioctl_desc to wire
- * up the handlers and set the access rights:
+ * up the handlers and set the access rights::
*
* static const struct drm_ioctl_desc my_driver_ioctls[] = {
* DRM_IOCTL_DEF_DRV(MY_DRIVER_OPERATION, my_driver_operation,
@@ -704,6 +704,9 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
*
* And then assign this to the &drm_driver.ioctls field in your driver
* structure.
+ *
+ * See the separate chapter on :ref:`file operations<drm_driver_fops>` for how
+ * the driver-specific IOCTLs are wired up.
*/
long drm_ioctl_kernel(struct file *file, drm_ioctl_t *func, void *kdata,
@@ -713,7 +716,7 @@ long drm_ioctl_kernel(struct file *file, drm_ioctl_t *func, void *kdata,
struct drm_device *dev = file_priv->minor->dev;
int retcode;
- if (drm_device_is_unplugged(dev))
+ if (drm_dev_is_unplugged(dev))
return -ENODEV;
retcode = drm_ioctl_permit(flags, file_priv);
@@ -762,7 +765,7 @@ long drm_ioctl(struct file *filp,
dev = file_priv->minor->dev;
- if (drm_device_is_unplugged(dev))
+ if (drm_dev_is_unplugged(dev))
return -ENODEV;
is_driver_ioctl = nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END;
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 1160a579e0dc..4b47226b90d4 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -165,14 +165,14 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node)
u32 reg;
if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
- dev_err(dev, "modalias failure on %s\n", node->full_name);
+ dev_err(dev, "modalias failure on %pOF\n", node);
return ERR_PTR(-EINVAL);
}
ret = of_property_read_u32(node, "reg", &reg);
if (ret) {
- dev_err(dev, "device node %s has no valid reg property: %d\n",
- node->full_name, ret);
+ dev_err(dev, "device node %pOF has no valid reg property: %d\n",
+ node, ret);
return ERR_PTR(-EINVAL);
}
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index d9862259a2a7..74f6ff5df656 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -337,6 +337,13 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
return -ENOMEM;
dev->mode_config.gamma_lut_size_property = prop;
+ prop = drm_property_create(dev,
+ DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB,
+ "IN_FORMATS", 0);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.modifiers_property = prop;
+
return 0;
}
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c
index da9a9adbcc98..1055533792f3 100644
--- a/drivers/gpu/drm/drm_mode_object.c
+++ b/drivers/gpu/drm/drm_mode_object.c
@@ -233,6 +233,9 @@ int drm_object_property_set_value(struct drm_mode_object *obj,
{
int i;
+ WARN_ON(drm_drv_uses_atomic_modeset(property->dev) &&
+ !(property->flags & DRM_MODE_PROP_IMMUTABLE));
+
for (i = 0; i < obj->properties->count; i++) {
if (obj->properties->properties[i] == property) {
obj->properties->values[i] = val;
@@ -244,24 +247,7 @@ int drm_object_property_set_value(struct drm_mode_object *obj,
}
EXPORT_SYMBOL(drm_object_property_set_value);
-/**
- * drm_object_property_get_value - retrieve the value of a property
- * @obj: drm mode object to get property value from
- * @property: property to retrieve
- * @val: storage for the property value
- *
- * This function retrieves the softare state of the given property for the given
- * property. Since there is no driver callback to retrieve the current property
- * value this might be out of sync with the hardware, depending upon the driver
- * and property.
- *
- * Atomic drivers should never call this function directly, the core will read
- * out property values through the various ->atomic_get_property callbacks.
- *
- * Returns:
- * Zero on success, error code on failure.
- */
-int drm_object_property_get_value(struct drm_mode_object *obj,
+int __drm_object_property_get_value(struct drm_mode_object *obj,
struct drm_property *property, uint64_t *val)
{
int i;
@@ -284,6 +270,31 @@ int drm_object_property_get_value(struct drm_mode_object *obj,
return -EINVAL;
}
+
+/**
+ * drm_object_property_get_value - retrieve the value of a property
+ * @obj: drm mode object to get property value from
+ * @property: property to retrieve
+ * @val: storage for the property value
+ *
+ * This function retrieves the softare state of the given property for the given
+ * property. Since there is no driver callback to retrieve the current property
+ * value this might be out of sync with the hardware, depending upon the driver
+ * and property.
+ *
+ * Atomic drivers should never call this function directly, the core will read
+ * out property values through the various ->atomic_get_property callbacks.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_object_property_get_value(struct drm_mode_object *obj,
+ struct drm_property *property, uint64_t *val)
+{
+ WARN_ON(drm_drv_uses_atomic_modeset(property->dev));
+
+ return __drm_object_property_get_value(obj, property, val);
+}
EXPORT_SYMBOL(drm_object_property_get_value);
/* helper for getconnector and getproperties ioctls */
@@ -302,7 +313,7 @@ int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic,
continue;
if (*arg_count_props > count) {
- ret = drm_object_property_get_value(obj, prop, &val);
+ ret = __drm_object_property_get_value(obj, prop, &val);
if (ret)
return ret;
@@ -381,6 +392,83 @@ struct drm_property *drm_mode_obj_find_prop_id(struct drm_mode_object *obj,
return NULL;
}
+static int set_property_legacy(struct drm_mode_object *obj,
+ struct drm_property *prop,
+ uint64_t prop_value)
+{
+ struct drm_device *dev = prop->dev;
+ struct drm_mode_object *ref;
+ int ret = -EINVAL;
+
+ if (!drm_property_change_valid_get(prop, prop_value, &ref))
+ return -EINVAL;
+
+ drm_modeset_lock_all(dev);
+ switch (obj->type) {
+ case DRM_MODE_OBJECT_CONNECTOR:
+ ret = drm_mode_connector_set_obj_prop(obj, prop,
+ prop_value);
+ break;
+ case DRM_MODE_OBJECT_CRTC:
+ ret = drm_mode_crtc_set_obj_prop(obj, prop, prop_value);
+ break;
+ case DRM_MODE_OBJECT_PLANE:
+ ret = drm_mode_plane_set_obj_prop(obj_to_plane(obj),
+ prop, prop_value);
+ break;
+ }
+ drm_property_change_valid_put(prop, ref);
+ drm_modeset_unlock_all(dev);
+
+ return ret;
+}
+
+static int set_property_atomic(struct drm_mode_object *obj,
+ struct drm_property *prop,
+ uint64_t prop_value)
+{
+ struct drm_device *dev = prop->dev;
+ struct drm_atomic_state *state;
+ struct drm_modeset_acquire_ctx ctx;
+ int ret;
+
+ drm_modeset_acquire_init(&ctx, 0);
+
+ state = drm_atomic_state_alloc(dev);
+ if (!state)
+ return -ENOMEM;
+ state->acquire_ctx = &ctx;
+retry:
+ if (prop == state->dev->mode_config.dpms_property) {
+ if (obj->type != DRM_MODE_OBJECT_CONNECTOR) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = drm_atomic_connector_commit_dpms(state,
+ obj_to_connector(obj),
+ prop_value);
+ } else {
+ ret = drm_atomic_set_property(state, obj, prop, prop_value);
+ if (ret)
+ goto out;
+ ret = drm_atomic_commit(state);
+ }
+out:
+ if (ret == -EDEADLK) {
+ drm_atomic_state_clear(state);
+ drm_modeset_backoff(&ctx);
+ goto retry;
+ }
+
+ drm_atomic_state_put(state);
+
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+
+ return ret;
+}
+
int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
@@ -388,18 +476,13 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
struct drm_mode_object *arg_obj;
struct drm_property *property;
int ret = -EINVAL;
- struct drm_mode_object *ref;
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- drm_modeset_lock_all(dev);
-
arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
- if (!arg_obj) {
- ret = -ENOENT;
- goto out;
- }
+ if (!arg_obj)
+ return -ENOENT;
if (!arg_obj->properties)
goto out_unref;
@@ -408,28 +491,12 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
if (!property)
goto out_unref;
- if (!drm_property_change_valid_get(property, arg->value, &ref))
- goto out_unref;
-
- switch (arg_obj->type) {
- case DRM_MODE_OBJECT_CONNECTOR:
- ret = drm_mode_connector_set_obj_prop(arg_obj, property,
- arg->value);
- break;
- case DRM_MODE_OBJECT_CRTC:
- ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value);
- break;
- case DRM_MODE_OBJECT_PLANE:
- ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj),
- property, arg->value);
- break;
- }
-
- drm_property_change_valid_put(property, ref);
+ if (drm_drv_uses_atomic_modeset(property->dev))
+ ret = set_property_atomic(arg_obj, property, arg->value);
+ else
+ ret = set_property_legacy(arg_obj, property, arg->value);
out_unref:
drm_mode_object_put(arg_obj);
-out:
- drm_modeset_unlock_all(dev);
return ret;
}
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index f2493b9b82e6..4a3f68a33844 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -709,8 +709,8 @@ int of_get_drm_display_mode(struct device_node *np,
if (bus_flags)
drm_bus_flags_from_videomode(&vm, bus_flags);
- pr_debug("%s: got %dx%d display mode from %s\n",
- of_node_full_name(np), vm.hactive, vm.vactive, np->name);
+ pr_debug("%pOF: got %dx%d display mode from %s\n",
+ np, vm.hactive, vm.vactive, np->name);
drm_mode_debug_printmodeline(dmode);
return 0;
@@ -1083,6 +1083,34 @@ drm_mode_validate_size(const struct drm_display_mode *mode,
}
EXPORT_SYMBOL(drm_mode_validate_size);
+/**
+ * drm_mode_validate_ycbcr420 - add 'ycbcr420-only' modes only when allowed
+ * @mode: mode to check
+ * @connector: drm connector under action
+ *
+ * This function is a helper which can be used to filter out any YCBCR420
+ * only mode, when the source doesn't support it.
+ *
+ * Returns:
+ * The mode status
+ */
+enum drm_mode_status
+drm_mode_validate_ycbcr420(const struct drm_display_mode *mode,
+ struct drm_connector *connector)
+{
+ u8 vic = drm_match_cea_mode(mode);
+ enum drm_mode_status status = MODE_OK;
+ struct drm_hdmi_info *hdmi = &connector->display_info.hdmi;
+
+ if (test_bit(vic, hdmi->y420_vdb_modes)) {
+ if (!connector->ycbcr_420_allowed)
+ status = MODE_NO_420;
+ }
+
+ return status;
+}
+EXPORT_SYMBOL(drm_mode_validate_ycbcr420);
+
#define MODE_STATUS(status) [MODE_ ## status + 3] = #status
static const char * const drm_mode_status_names[] = {
@@ -1122,6 +1150,7 @@ static const char * const drm_mode_status_names[] = {
MODE_STATUS(ONE_SIZE),
MODE_STATUS(NO_REDUCED),
MODE_STATUS(NO_STEREO),
+ MODE_STATUS(NO_420),
MODE_STATUS(STALE),
MODE_STATUS(BAD),
MODE_STATUS(ERROR),
@@ -1576,3 +1605,61 @@ int drm_mode_convert_umode(struct drm_display_mode *out,
out:
return ret;
}
+
+/**
+ * drm_mode_is_420_only - if a given videomode can be only supported in YCBCR420
+ * output format
+ *
+ * @display: display under action
+ * @mode: video mode to be tested.
+ *
+ * Returns:
+ * true if the mode can be supported in YCBCR420 format
+ * false if not.
+ */
+bool drm_mode_is_420_only(const struct drm_display_info *display,
+ const struct drm_display_mode *mode)
+{
+ u8 vic = drm_match_cea_mode(mode);
+
+ return test_bit(vic, display->hdmi.y420_vdb_modes);
+}
+EXPORT_SYMBOL(drm_mode_is_420_only);
+
+/**
+ * drm_mode_is_420_also - if a given videomode can be supported in YCBCR420
+ * output format also (along with RGB/YCBCR444/422)
+ *
+ * @display: display under action.
+ * @mode: video mode to be tested.
+ *
+ * Returns:
+ * true if the mode can be support YCBCR420 format
+ * false if not.
+ */
+bool drm_mode_is_420_also(const struct drm_display_info *display,
+ const struct drm_display_mode *mode)
+{
+ u8 vic = drm_match_cea_mode(mode);
+
+ return test_bit(vic, display->hdmi.y420_cmdb_modes);
+}
+EXPORT_SYMBOL(drm_mode_is_420_also);
+/**
+ * drm_mode_is_420 - if a given videomode can be supported in YCBCR420
+ * output format
+ *
+ * @display: display under action.
+ * @mode: video mode to be tested.
+ *
+ * Returns:
+ * true if the mode can be supported in YCBCR420 format
+ * false if not.
+ */
+bool drm_mode_is_420(const struct drm_display_info *display,
+ const struct drm_display_mode *mode)
+{
+ return drm_mode_is_420_only(display, mode) ||
+ drm_mode_is_420_also(display, mode);
+}
+EXPORT_SYMBOL(drm_mode_is_420);
diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
index 2b33825f2f93..9cb1eede0b4d 100644
--- a/drivers/gpu/drm/drm_modeset_helper.c
+++ b/drivers/gpu/drm/drm_modeset_helper.c
@@ -124,6 +124,7 @@ static struct drm_plane *create_primary_plane(struct drm_device *dev)
&drm_primary_helper_funcs,
safe_modeset_formats,
ARRAY_SIZE(safe_modeset_formats),
+ NULL,
DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) {
kfree(primary);
diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c
index 64ef09a6cccb..af4e906c630d 100644
--- a/drivers/gpu/drm/drm_modeset_lock.c
+++ b/drivers/gpu/drm/drm_modeset_lock.c
@@ -52,7 +52,12 @@
* drm_modeset_drop_locks(&ctx);
* drm_modeset_acquire_fini(&ctx);
*
- * On top of of these per-object locks using &ww_mutex there's also an overall
+ * If all that is needed is a single modeset lock, then the &struct
+ * drm_modeset_acquire_ctx is not needed and the locking can be simplified
+ * by passing a NULL instead of ctx in the drm_modeset_lock()
+ * call and, when done, by calling drm_modeset_unlock().
+ *
+ * On top of these per-object locks using &ww_mutex there's also an overall
* &drm_mode_config.mutex, for protecting everything else. Mostly this means
* probe state of connectors, and preventing hotplug add/removal of connectors.
*
@@ -313,11 +318,14 @@ EXPORT_SYMBOL(drm_modeset_lock_init);
* @lock: lock to take
* @ctx: acquire ctx
*
- * If ctx is not NULL, then its ww acquire context is used and the
+ * If @ctx is not NULL, then its ww acquire context is used and the
* lock will be tracked by the context and can be released by calling
* drm_modeset_drop_locks(). If -EDEADLK is returned, this means a
* deadlock scenario has been detected and it is an error to attempt
* to take any more locks without first calling drm_modeset_backoff().
+ *
+ * If @ctx is NULL then the function call behaves like a normal,
+ * non-nesting mutex_lock() call.
*/
int drm_modeset_lock(struct drm_modeset_lock *lock,
struct drm_modeset_acquire_ctx *ctx)
diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 2120f33bdf4a..8dafbdfcd2ea 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -160,8 +160,8 @@ int drm_of_component_probe(struct device *dev,
of_node_put(remote);
continue;
} else if (!of_device_is_available(remote->parent)) {
- dev_warn(dev, "parent device of %s is not available\n",
- remote->full_name);
+ dev_warn(dev, "parent device of %pOF is not available\n",
+ remote);
of_node_put(remote);
continue;
}
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c
index 1eb4fc3eee20..1235c9877d6f 100644
--- a/drivers/gpu/drm/drm_pci.c
+++ b/drivers/gpu/drm/drm_pci.c
@@ -149,7 +149,6 @@ int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master)
master->unique_len = strlen(master->unique);
return 0;
}
-EXPORT_SYMBOL(drm_pci_set_busid);
static int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p)
{
@@ -281,20 +280,15 @@ err_free:
EXPORT_SYMBOL(drm_get_pci_dev);
/**
- * drm_pci_init - Register matching PCI devices with the DRM subsystem
+ * drm_legacy_pci_init - shadow-attach a legacy DRM PCI driver
* @driver: DRM device driver
* @pdriver: PCI device driver
*
- * Initializes a drm_device structures, registering the stubs and initializing
- * the AGP device.
- *
- * NOTE: This function is deprecated. Modern modesetting drm drivers should use
- * pci_register_driver() directly, this function only provides shadow-binding
- * support for old legacy drivers on top of that core pci function.
+ * This is only used by legacy dri1 drivers and deprecated.
*
* Return: 0 on success or a negative error code on failure.
*/
-int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
+int drm_legacy_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
{
struct pci_dev *pdev = NULL;
const struct pci_device_id *pid;
@@ -302,8 +296,8 @@ int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
DRM_DEBUG("\n");
- if (!(driver->driver_features & DRIVER_LEGACY))
- return pci_register_driver(pdriver);
+ if (WARN_ON(!(driver->driver_features & DRIVER_LEGACY)))
+ return -EINVAL;
/* If not using KMS, fall back to stealth mode manual scanning. */
INIT_LIST_HEAD(&driver->legacy_dev_list);
@@ -330,6 +324,7 @@ int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
}
return 0;
}
+EXPORT_SYMBOL(drm_legacy_pci_init);
int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *mask)
{
@@ -391,11 +386,6 @@ EXPORT_SYMBOL(drm_pcie_get_max_link_width);
#else
-int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
-{
- return -1;
-}
-
void drm_pci_agp_destroy(struct drm_device *dev) {}
int drm_irq_by_busid(struct drm_device *dev, void *data,
@@ -405,27 +395,21 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
}
#endif
-EXPORT_SYMBOL(drm_pci_init);
-
/**
- * drm_pci_exit - Unregister matching PCI devices from the DRM subsystem
+ * drm_legacy_pci_exit - unregister shadow-attach legacy DRM driver
* @driver: DRM device driver
* @pdriver: PCI device driver
*
- * Unregisters one or more devices matched by a PCI driver from the DRM
- * subsystem.
- *
- * NOTE: This function is deprecated. Modern modesetting drm drivers should use
- * pci_unregister_driver() directly, this function only provides shadow-binding
- * support for old legacy drivers on top of that core pci function.
+ * Unregister a DRM driver shadow-attached through drm_legacy_pci_init(). This
+ * is deprecated and only used by dri1 drivers.
*/
-void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
+void drm_legacy_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
{
struct drm_device *dev, *tmp;
DRM_DEBUG("\n");
if (!(driver->driver_features & DRIVER_LEGACY)) {
- pci_unregister_driver(pdriver);
+ WARN_ON(1);
} else {
list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list,
legacy_dev_list) {
@@ -435,4 +419,4 @@ void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
}
DRM_INFO("Module unloaded\n");
}
-EXPORT_SYMBOL(drm_pci_exit);
+EXPORT_SYMBOL(drm_legacy_pci_exit);
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 5dc8c4350602..85ab1eec73e5 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -62,6 +62,87 @@ static unsigned int drm_num_planes(struct drm_device *dev)
return num;
}
+static inline u32 *
+formats_ptr(struct drm_format_modifier_blob *blob)
+{
+ return (u32 *)(((char *)blob) + blob->formats_offset);
+}
+
+static inline struct drm_format_modifier *
+modifiers_ptr(struct drm_format_modifier_blob *blob)
+{
+ return (struct drm_format_modifier *)(((char *)blob) + blob->modifiers_offset);
+}
+
+static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane)
+{
+ const struct drm_mode_config *config = &dev->mode_config;
+ struct drm_property_blob *blob;
+ struct drm_format_modifier *mod;
+ size_t blob_size, formats_size, modifiers_size;
+ struct drm_format_modifier_blob *blob_data;
+ unsigned int i, j;
+
+ formats_size = sizeof(__u32) * plane->format_count;
+ if (WARN_ON(!formats_size)) {
+ /* 0 formats are never expected */
+ return 0;
+ }
+
+ modifiers_size =
+ sizeof(struct drm_format_modifier) * plane->modifier_count;
+
+ blob_size = sizeof(struct drm_format_modifier_blob);
+ /* Modifiers offset is a pointer to a struct with a 64 bit field so it
+ * should be naturally aligned to 8B.
+ */
+ BUILD_BUG_ON(sizeof(struct drm_format_modifier_blob) % 8);
+ blob_size += ALIGN(formats_size, 8);
+ blob_size += modifiers_size;
+
+ blob = drm_property_create_blob(dev, blob_size, NULL);
+ if (IS_ERR(blob))
+ return -1;
+
+ blob_data = (struct drm_format_modifier_blob *)blob->data;
+ blob_data->version = FORMAT_BLOB_CURRENT;
+ blob_data->count_formats = plane->format_count;
+ blob_data->formats_offset = sizeof(struct drm_format_modifier_blob);
+ blob_data->count_modifiers = plane->modifier_count;
+
+ blob_data->modifiers_offset =
+ ALIGN(blob_data->formats_offset + formats_size, 8);
+
+ memcpy(formats_ptr(blob_data), plane->format_types, formats_size);
+
+ /* If we can't determine support, just bail */
+ if (!plane->funcs->format_mod_supported)
+ goto done;
+
+ mod = modifiers_ptr(blob_data);
+ for (i = 0; i < plane->modifier_count; i++) {
+ for (j = 0; j < plane->format_count; j++) {
+ if (plane->funcs->format_mod_supported(plane,
+ plane->format_types[j],
+ plane->modifiers[i])) {
+
+ mod->formats |= 1ULL << j;
+ }
+ }
+
+ mod->modifier = plane->modifiers[i];
+ mod->offset = 0;
+ mod->pad = 0;
+ mod++;
+ }
+
+done:
+ drm_object_attach_property(&plane->base, config->modifiers_property,
+ blob->base.id);
+
+ return 0;
+}
+
/**
* drm_universal_plane_init - Initialize a new universal plane object
* @dev: DRM device
@@ -70,6 +151,8 @@ static unsigned int drm_num_planes(struct drm_device *dev)
* @funcs: callbacks for the new plane
* @formats: array of supported formats (DRM_FORMAT\_\*)
* @format_count: number of elements in @formats
+ * @format_modifiers: array of struct drm_format modifiers terminated by
+ * DRM_FORMAT_MOD_INVALID
* @type: type of plane (overlay, primary, cursor)
* @name: printf style format string for the plane name, or NULL for default name
*
@@ -82,10 +165,12 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
uint32_t possible_crtcs,
const struct drm_plane_funcs *funcs,
const uint32_t *formats, unsigned int format_count,
+ const uint64_t *format_modifiers,
enum drm_plane_type type,
const char *name, ...)
{
struct drm_mode_config *config = &dev->mode_config;
+ unsigned int format_modifier_count = 0;
int ret;
ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
@@ -105,6 +190,31 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
return -ENOMEM;
}
+ /*
+ * First driver to need more than 64 formats needs to fix this. Each
+ * format is encoded as a bit and the current code only supports a u64.
+ */
+ if (WARN_ON(format_count > 64))
+ return -EINVAL;
+
+ if (format_modifiers) {
+ const uint64_t *temp_modifiers = format_modifiers;
+ while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID)
+ format_modifier_count++;
+ }
+
+ plane->modifier_count = format_modifier_count;
+ plane->modifiers = kmalloc_array(format_modifier_count,
+ sizeof(format_modifiers[0]),
+ GFP_KERNEL);
+
+ if (format_modifier_count && !plane->modifiers) {
+ DRM_DEBUG_KMS("out of memory when allocating plane\n");
+ kfree(plane->format_types);
+ drm_mode_object_unregister(dev, &plane->base);
+ return -ENOMEM;
+ }
+
if (name) {
va_list ap;
@@ -117,12 +227,15 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
}
if (!plane->name) {
kfree(plane->format_types);
+ kfree(plane->modifiers);
drm_mode_object_unregister(dev, &plane->base);
return -ENOMEM;
}
memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
plane->format_count = format_count;
+ memcpy(plane->modifiers, format_modifiers,
+ format_modifier_count * sizeof(format_modifiers[0]));
plane->possible_crtcs = possible_crtcs;
plane->type = type;
@@ -149,6 +262,9 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
drm_object_attach_property(&plane->base, config->prop_src_h, 0);
}
+ if (config->allow_fb_modifiers)
+ create_in_format_blob(dev, plane);
+
return 0;
}
EXPORT_SYMBOL(drm_universal_plane_init);
@@ -205,7 +321,8 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
return drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
- formats, format_count, type, NULL);
+ formats, format_count,
+ NULL, type, NULL);
}
EXPORT_SYMBOL(drm_plane_init);
@@ -224,6 +341,7 @@ void drm_plane_cleanup(struct drm_plane *plane)
drm_modeset_lock_fini(&plane->mutex);
kfree(plane->format_types);
+ kfree(plane->modifiers);
drm_mode_object_unregister(dev, &plane->base);
BUG_ON(list_empty(&plane->head));
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 00e6832a8c1a..904966cde32b 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -528,6 +528,10 @@ retry:
if (mode->status == MODE_OK)
mode->status = drm_mode_validate_pipeline(mode,
connector);
+
+ if (mode->status == MODE_OK)
+ mode->status = drm_mode_validate_ycbcr420(mode,
+ connector);
}
prune:
diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
index 3e88fa24eab3..bc5128203056 100644
--- a/drivers/gpu/drm/drm_property.c
+++ b/drivers/gpu/drm/drm_property.c
@@ -709,6 +709,29 @@ err_created:
}
EXPORT_SYMBOL(drm_property_replace_global_blob);
+/**
+ * drm_property_replace_blob - replace a blob property
+ * @blob: a pointer to the member blob to be replaced
+ * @new_blob: the new blob to replace with
+ *
+ * Return: true if the blob was in fact replaced.
+ */
+bool drm_property_replace_blob(struct drm_property_blob **blob,
+ struct drm_property_blob *new_blob)
+{
+ struct drm_property_blob *old_blob = *blob;
+
+ if (old_blob == new_blob)
+ return false;
+
+ drm_property_blob_put(old_blob);
+ if (new_blob)
+ drm_property_blob_get(new_blob);
+ *blob = new_blob;
+ return true;
+}
+EXPORT_SYMBOL(drm_property_replace_blob);
+
int drm_mode_getblob_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
diff --git a/drivers/gpu/drm/drm_scdc_helper.c b/drivers/gpu/drm/drm_scdc_helper.c
index 3cd96a95736d..7d1b0f011d33 100644
--- a/drivers/gpu/drm/drm_scdc_helper.c
+++ b/drivers/gpu/drm/drm_scdc_helper.c
@@ -194,19 +194,26 @@ EXPORT_SYMBOL(drm_scdc_set_scrambling);
* @adapter: I2C adapter for DDC channel
* @set: ret or reset the high clock ratio
*
- * TMDS clock ratio calculations go like this:
- * TMDS character = 10 bit TMDS encoded value
- * TMDS character rate = The rate at which TMDS characters are transmitted(Mcsc)
- * TMDS bit rate = 10x TMDS character rate
- * As per the spec:
- * TMDS clock rate for pixel clock < 340 MHz = 1x the character rate
- * = 1/10 pixel clock rate
- * TMDS clock rate for pixel clock > 340 MHz = 0.25x the character rate
- * = 1/40 pixel clock rate
- *
- * Writes to the TMDS config register over SCDC channel, and:
- * sets TMDS clock ratio to 1/40 when set = 1
- * sets TMDS clock ratio to 1/10 when set = 0
+ *
+ * TMDS clock ratio calculations go like this:
+ * TMDS character = 10 bit TMDS encoded value
+ *
+ * TMDS character rate = The rate at which TMDS characters are
+ * transmitted (Mcsc)
+ *
+ * TMDS bit rate = 10x TMDS character rate
+ *
+ * As per the spec:
+ * TMDS clock rate for pixel clock < 340 MHz = 1x the character
+ * rate = 1/10 pixel clock rate
+ *
+ * TMDS clock rate for pixel clock > 340 MHz = 0.25x the character
+ * rate = 1/40 pixel clock rate
+ *
+ * Writes to the TMDS config register over SCDC channel, and:
+ * sets TMDS clock ratio to 1/40 when set = 1
+ *
+ * sets TMDS clock ratio to 1/10 when set = 0
*
* Returns:
* True if write is successful, false otherwise.
diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c
index e084f9f8ca66..dc9fd109de14 100644
--- a/drivers/gpu/drm/drm_simple_kms_helper.c
+++ b/drivers/gpu/drm/drm_simple_kms_helper.c
@@ -37,10 +37,18 @@ static const struct drm_encoder_funcs drm_simple_kms_encoder_funcs = {
static int drm_simple_kms_crtc_check(struct drm_crtc *crtc,
struct drm_crtc_state *state)
{
+ bool has_primary = state->plane_mask &
+ BIT(drm_plane_index(crtc->primary));
+
+ /* We always want to have an active plane with an active CRTC */
+ if (has_primary != state->enable)
+ return -EINVAL;
+
return drm_atomic_add_affected_planes(state->state, crtc);
}
-static void drm_simple_kms_crtc_enable(struct drm_crtc *crtc)
+static void drm_simple_kms_crtc_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct drm_simple_display_pipe *pipe;
@@ -51,7 +59,8 @@ static void drm_simple_kms_crtc_enable(struct drm_crtc *crtc)
pipe->funcs->enable(pipe, crtc->state);
}
-static void drm_simple_kms_crtc_disable(struct drm_crtc *crtc)
+static void drm_simple_kms_crtc_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct drm_simple_display_pipe *pipe;
@@ -64,8 +73,8 @@ static void drm_simple_kms_crtc_disable(struct drm_crtc *crtc)
static const struct drm_crtc_helper_funcs drm_simple_kms_crtc_helper_funcs = {
.atomic_check = drm_simple_kms_crtc_check,
- .disable = drm_simple_kms_crtc_disable,
- .enable = drm_simple_kms_crtc_enable,
+ .atomic_enable = drm_simple_kms_crtc_enable,
+ .atomic_disable = drm_simple_kms_crtc_disable,
};
static const struct drm_crtc_funcs drm_simple_kms_crtc_funcs = {
@@ -88,9 +97,6 @@ static int drm_simple_kms_plane_atomic_check(struct drm_plane *plane,
pipe = container_of(plane, struct drm_simple_display_pipe, plane);
crtc_state = drm_atomic_get_new_crtc_state(plane_state->state,
&pipe->crtc);
- if (crtc_state->enable != !!plane_state->crtc)
- return -EINVAL; /* plane must match crtc enable state */
-
if (!crtc_state->enable)
return 0; /* nothing to check when disabling or disabled */
@@ -193,6 +199,7 @@ EXPORT_SYMBOL(drm_simple_display_pipe_attach_bridge);
* @funcs: callbacks for the display pipe (optional)
* @formats: array of supported formats (DRM_FORMAT\_\*)
* @format_count: number of elements in @formats
+ * @format_modifiers: array of formats modifiers
* @connector: connector to attach and register (optional)
*
* Sets up a display pipeline which consist of a really simple
@@ -213,6 +220,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
struct drm_simple_display_pipe *pipe,
const struct drm_simple_display_pipe_funcs *funcs,
const uint32_t *formats, unsigned int format_count,
+ const uint64_t *format_modifiers,
struct drm_connector *connector)
{
struct drm_encoder *encoder = &pipe->encoder;
@@ -227,6 +235,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
ret = drm_universal_plane_init(dev, plane, 0,
&drm_simple_kms_plane_funcs,
formats, format_count,
+ format_modifiers,
DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 789ba0b37f7b..a5b38a80a99a 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -330,7 +330,6 @@ err_put_fd:
}
/**
* drm_syncobj_open - initalizes syncobj file-private structures at devnode open time
- * @dev: drm_device which is being opened by userspace
* @file_private: drm file-private structure to set up
*
* Called at device open time, sets up the structure for handling refcounting
@@ -354,7 +353,6 @@ drm_syncobj_release_handle(int id, void *ptr, void *data)
/**
* drm_syncobj_release - release file-private sync object resources
- * @dev: drm_device which is being closed by userspace
* @file_private: drm file-private structure to clean up
*
* Called at close time when the filp is going away.
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index e9f33cd805dd..70f2b9593edc 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -31,6 +31,41 @@
#include "drm_trace.h"
#include "drm_internal.h"
+/**
+ * DOC: vblank handling
+ *
+ * Vertical blanking plays a major role in graphics rendering. To achieve
+ * tear-free display, users must synchronize page flips and/or rendering to
+ * vertical blanking. The DRM API offers ioctls to perform page flips
+ * synchronized to vertical blanking and wait for vertical blanking.
+ *
+ * The DRM core handles most of the vertical blanking management logic, which
+ * involves filtering out spurious interrupts, keeping race-free blanking
+ * counters, coping with counter wrap-around and resets and keeping use counts.
+ * It relies on the driver to generate vertical blanking interrupts and
+ * optionally provide a hardware vertical blanking counter.
+ *
+ * Drivers must initialize the vertical blanking handling core with a call to
+ * drm_vblank_init(). Minimally, a driver needs to implement
+ * &drm_crtc_funcs.enable_vblank and &drm_crtc_funcs.disable_vblank plus call
+ * drm_crtc_handle_vblank() in it's vblank interrupt handler for working vblank
+ * support.
+ *
+ * Vertical blanking interrupts can be enabled by the DRM core or by drivers
+ * themselves (for instance to handle page flipping operations). The DRM core
+ * maintains a vertical blanking use count to ensure that the interrupts are not
+ * disabled while a user still needs them. To increment the use count, drivers
+ * call drm_crtc_vblank_get() and release the vblank reference again with
+ * drm_crtc_vblank_put(). In between these two calls vblank interrupts are
+ * guaranteed to be enabled.
+ *
+ * On many hardware disabling the vblank interrupt cannot be done in a race-free
+ * manner, see &drm_driver.vblank_disable_immediate and
+ * &drm_driver.max_vblank_count. In that case the vblank core only disables the
+ * vblanks after a timer has expired, which can be configured through the
+ * ``vblankoffdelay`` module parameter.
+ */
+
/* Retry timestamp calculation up to 3 times to satisfy
* drm_timestamp_precision before giving up.
*/
@@ -259,16 +294,17 @@ static u32 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
}
/**
- * drm_accurate_vblank_count - retrieve the master vblank counter
+ * drm_crtc_accurate_vblank_count - retrieve the master vblank counter
* @crtc: which counter to retrieve
*
- * This function is similar to @drm_crtc_vblank_count but this
- * function interpolates to handle a race with vblank irq's.
+ * This function is similar to drm_crtc_vblank_count() but this function
+ * interpolates to handle a race with vblank interrupts using the high precision
+ * timestamping support.
*
- * This is mostly useful for hardware that can obtain the scanout
- * position, but doesn't have a frame counter.
+ * This is mostly useful for hardware that can obtain the scanout position, but
+ * doesn't have a hardware frame counter.
*/
-u32 drm_accurate_vblank_count(struct drm_crtc *crtc)
+u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
unsigned int pipe = drm_crtc_index(crtc);
@@ -287,7 +323,7 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc)
return vblank;
}
-EXPORT_SYMBOL(drm_accurate_vblank_count);
+EXPORT_SYMBOL(drm_crtc_accurate_vblank_count);
static void __disable_vblank(struct drm_device *dev, unsigned int pipe)
{
@@ -358,15 +394,6 @@ static void vblank_disable_fn(unsigned long arg)
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
}
-/**
- * drm_vblank_cleanup - cleanup vblank support
- * @dev: DRM device
- *
- * This function cleans up any resources allocated in drm_vblank_init.
- *
- * Drivers which don't use drm_irq_install() need to set &drm_device.irq_enabled
- * themselves, to signal to the DRM core that vblank interrupts are enabled.
- */
void drm_vblank_cleanup(struct drm_device *dev)
{
unsigned int pipe;
@@ -388,7 +415,6 @@ void drm_vblank_cleanup(struct drm_device *dev)
dev->num_crtcs = 0;
}
-EXPORT_SYMBOL(drm_vblank_cleanup);
/**
* drm_vblank_init - initialize vblank support
@@ -396,6 +422,8 @@ EXPORT_SYMBOL(drm_vblank_cleanup);
* @num_crtcs: number of CRTCs supported by @dev
*
* This function initializes vblank support for @num_crtcs display pipelines.
+ * Cleanup is handled by the DRM core, or through calling drm_dev_fini() for
+ * drivers with a &drm_driver.release callback.
*
* Returns:
* Zero on success or a negative error code on failure.
@@ -468,11 +496,11 @@ EXPORT_SYMBOL(drm_crtc_vblank_waitqueue);
* @crtc: drm_crtc whose timestamp constants should be updated.
* @mode: display mode containing the scanout timings
*
- * Calculate and store various constants which are later
- * needed by vblank and swap-completion timestamping, e.g,
- * by drm_calc_vbltimestamp_from_scanoutpos(). They are
- * derived from CRTC's true scanout timing, so they take
- * things like panel scaling or other adjustments into account.
+ * Calculate and store various constants which are later needed by vblank and
+ * swap-completion timestamping, e.g, by
+ * drm_calc_vbltimestamp_from_scanoutpos(). They are derived from CRTC's true
+ * scanout timing, so they take things like panel scaling or other adjustments
+ * into account.
*/
void drm_calc_timestamping_constants(struct drm_crtc *crtc,
const struct drm_display_mode *mode)
@@ -535,25 +563,14 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants);
* if flag is set.
*
* Implements calculation of exact vblank timestamps from given drm_display_mode
- * timings and current video scanout position of a CRTC. This can be called from
- * within get_vblank_timestamp() implementation of a kms driver to implement the
- * actual timestamping.
- *
- * Should return timestamps conforming to the OML_sync_control OpenML
- * extension specification. The timestamp corresponds to the end of
- * the vblank interval, aka start of scanout of topmost-leftmost display
- * pixel in the following video frame.
+ * timings and current video scanout position of a CRTC. This can be directly
+ * used as the &drm_driver.get_vblank_timestamp implementation of a kms driver
+ * if &drm_driver.get_scanout_position is implemented.
*
- * Requires support for optional dev->driver->get_scanout_position()
- * in kms driver, plus a bit of setup code to provide a drm_display_mode
- * that corresponds to the true scanout timing.
- *
- * The current implementation only handles standard video modes. It
- * returns as no operation if a doublescan or interlaced video mode is
- * active. Higher level code is expected to handle this.
- *
- * This function can be used to implement the &drm_driver.get_vblank_timestamp
- * directly, if the driver implements the &drm_driver.get_scanout_position hook.
+ * The current implementation only handles standard video modes. For double scan
+ * and interlaced modes the driver is supposed to adjust the hardware mode
+ * (taken from &drm_crtc_state.adjusted mode for atomic modeset drivers) to
+ * match the scanout position reported.
*
* Note that atomic drivers must call drm_calc_timestamping_constants() before
* enabling a CRTC. The atomic helpers already take care of that in
@@ -738,7 +755,9 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
*
* Fetches the "cooked" vblank count value that represents the number of
* vblank events since the system was booted, including lost events due to
- * modesetting activity.
+ * modesetting activity. Note that this timer isn't correct against a racing
+ * vblank interrupt (since it only reports the software vblank counter), see
+ * drm_crtc_accurate_vblank_count() for such use-cases.
*
* Returns:
* The software vblank counter.
@@ -749,20 +768,6 @@ u32 drm_crtc_vblank_count(struct drm_crtc *crtc)
}
EXPORT_SYMBOL(drm_crtc_vblank_count);
-/**
- * drm_vblank_count_and_time - retrieve "cooked" vblank counter value and the
- * system timestamp corresponding to that vblank counter value.
- * @dev: DRM device
- * @pipe: index of CRTC whose counter to retrieve
- * @vblanktime: Pointer to struct timeval to receive the vblank timestamp.
- *
- * Fetches the "cooked" vblank count value that represents the number of
- * vblank events since the system was booted, including lost events due to
- * modesetting activity. Returns corresponding system timestamp of the time
- * of the vblank interval that corresponds to the current vblank counter value.
- *
- * This is the legacy version of drm_crtc_vblank_count_and_time().
- */
static u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe,
struct timeval *vblanktime)
{
@@ -831,7 +836,7 @@ static void send_vblank_event(struct drm_device *dev,
* NOTE: Drivers using this to send out the &drm_crtc_state.event as part of an
* atomic commit must ensure that the next vblank happens at exactly the same
* time as the atomic commit is committed to the hardware. This function itself
- * does **not** protect again the next vblank interrupt racing with either this
+ * does **not** protect against the next vblank interrupt racing with either this
* function call or the atomic commit operation. A possible sequence could be:
*
* 1. Driver commits new hardware state into vblank-synchronized registers.
@@ -852,8 +857,8 @@ static void send_vblank_event(struct drm_device *dev,
* handler by calling drm_crtc_send_vblank_event() and make sure that there's no
* possible race with the hardware committing the atomic update.
*
- * Caller must hold event lock. Caller must also hold a vblank reference for
- * the event @e, which will be dropped when the next vblank arrives.
+ * Caller must hold a vblank reference for the event @e, which will be dropped
+ * when the next vblank arrives.
*/
void drm_crtc_arm_vblank_event(struct drm_crtc *crtc,
struct drm_pending_vblank_event *e)
@@ -913,14 +918,6 @@ static int __enable_vblank(struct drm_device *dev, unsigned int pipe)
return dev->driver->enable_vblank(dev, pipe);
}
-/**
- * drm_vblank_enable - enable the vblank interrupt on a CRTC
- * @dev: DRM device
- * @pipe: CRTC index
- *
- * Returns:
- * Zero on success or a negative error code on failure.
- */
static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
{
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
@@ -958,19 +955,6 @@ static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
return ret;
}
-/**
- * drm_vblank_get - get a reference count on vblank events
- * @dev: DRM device
- * @pipe: index of CRTC to own
- *
- * Acquire a reference count on vblank events to avoid having them disabled
- * while in use.
- *
- * This is the legacy version of drm_crtc_vblank_get().
- *
- * Returns:
- * Zero on success or a negative error code on failure.
- */
static int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
{
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
@@ -1014,16 +998,6 @@ int drm_crtc_vblank_get(struct drm_crtc *crtc)
}
EXPORT_SYMBOL(drm_crtc_vblank_get);
-/**
- * drm_vblank_put - release ownership of vblank events
- * @dev: DRM device
- * @pipe: index of CRTC to release
- *
- * Release ownership of a given vblank counter, turning off interrupts
- * if possible. Disable interrupts after drm_vblank_offdelay milliseconds.
- *
- * This is the legacy version of drm_crtc_vblank_put().
- */
static void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
{
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
@@ -1067,6 +1041,8 @@ EXPORT_SYMBOL(drm_crtc_vblank_put);
* This waits for one vblank to pass on @pipe, using the irq driver interfaces.
* It is a failure to call this when the vblank irq for @pipe is disabled, e.g.
* due to lack of driver support or because the crtc is off.
+ *
+ * This is the legacy version of drm_crtc_wait_one_vblank().
*/
void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
{
@@ -1116,7 +1092,7 @@ EXPORT_SYMBOL(drm_crtc_wait_one_vblank);
* stored so that drm_vblank_on can restore it again.
*
* Drivers must use this function when the hardware vblank counter can get
- * reset, e.g. when suspending.
+ * reset, e.g. when suspending or disabling the @crtc in general.
*/
void drm_crtc_vblank_off(struct drm_crtc *crtc)
{
@@ -1184,6 +1160,8 @@ EXPORT_SYMBOL(drm_crtc_vblank_off);
* drm_crtc_vblank_on() functions. The difference compared to
* drm_crtc_vblank_off() is that this function doesn't save the vblank counter
* and hence doesn't need to call any driver hooks.
+ *
+ * This is useful for recovering driver state e.g. on driver load, or on resume.
*/
void drm_crtc_vblank_reset(struct drm_crtc *crtc)
{
@@ -1212,9 +1190,10 @@ EXPORT_SYMBOL(drm_crtc_vblank_reset);
* @crtc: CRTC in question
*
* This functions restores the vblank interrupt state captured with
- * drm_crtc_vblank_off() again. Note that calls to drm_crtc_vblank_on() and
- * drm_crtc_vblank_off() can be unbalanced and so can also be unconditionally called
- * in driver load code to reflect the current hardware state of the crtc.
+ * drm_crtc_vblank_off() again and is generally called when enabling @crtc. Note
+ * that calls to drm_crtc_vblank_on() and drm_crtc_vblank_off() can be
+ * unbalanced and so can also be unconditionally called in driver load code to
+ * reflect the current hardware state of the crtc.
*/
void drm_crtc_vblank_on(struct drm_crtc *crtc)
{
@@ -1299,8 +1278,8 @@ static void drm_legacy_vblank_post_modeset(struct drm_device *dev,
}
}
-int drm_legacy_modeset_ctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
+int drm_legacy_modeset_ctl_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
struct drm_modeset_ctl *modeset = data;
unsigned int pipe;
@@ -1419,22 +1398,8 @@ static bool drm_wait_vblank_is_query(union drm_wait_vblank *vblwait)
_DRM_VBLANK_NEXTONMISS));
}
-/*
- * Wait for VBLANK.
- *
- * \param inode device inode.
- * \param file_priv DRM file private.
- * \param cmd command.
- * \param data user argument, pointing to a drm_wait_vblank structure.
- * \return zero on success or a negative number on failure.
- *
- * This function enables the vblank interrupt on the pipe requested, then
- * sleeps waiting for the requested sequence number to occur, and drops
- * the vblank interrupt refcount afterwards. (vblank IRQ disable follows that
- * after a timeout with no further vblank waits scheduled).
- */
-int drm_wait_vblank(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
+int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
struct drm_vblank_crtc *vblank;
union drm_wait_vblank *vblwait = data;
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c
index 1170b3209a12..13a59ed2afbc 100644
--- a/drivers/gpu/drm/drm_vm.c
+++ b/drivers/gpu/drm/drm_vm.c
@@ -631,7 +631,7 @@ int drm_legacy_mmap(struct file *filp, struct vm_area_struct *vma)
struct drm_device *dev = priv->minor->dev;
int ret;
- if (drm_device_is_unplugged(dev))
+ if (drm_dev_is_unplugged(dev))
return -ENODEV;
mutex_lock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/etnaviv/Kconfig b/drivers/gpu/drm/etnaviv/Kconfig
index 71cee4e9fefb..38b477b5fbf9 100644
--- a/drivers/gpu/drm/etnaviv/Kconfig
+++ b/drivers/gpu/drm/etnaviv/Kconfig
@@ -10,6 +10,8 @@ config DRM_ETNAVIV
select IOMMU_API
select IOMMU_SUPPORT
select WANT_DEV_COREDUMP
+ select CMA if HAVE_DMA_CONTIGUOUS
+ select DMA_CMA if HAVE_DMA_CONTIGUOUS
help
DRM driver for Vivante GPUs.
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 91e17aeee1da..2cb4773823c2 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -316,7 +316,7 @@ static int etnaviv_ioctl_gem_cpu_prep(struct drm_device *dev, void *data,
ret = etnaviv_gem_cpu_prep(obj, args->op, &TS(args->timeout));
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -337,7 +337,7 @@ static int etnaviv_ioctl_gem_cpu_fini(struct drm_device *dev, void *data,
ret = etnaviv_gem_cpu_fini(obj);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -357,7 +357,7 @@ static int etnaviv_ioctl_gem_info(struct drm_device *dev, void *data,
return -ENOENT;
ret = etnaviv_gem_mmap_offset(obj, &args->offset);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -446,7 +446,7 @@ static int etnaviv_ioctl_gem_wait(struct drm_device *dev, void *data,
ret = etnaviv_gem_wait_bo(gpu, obj, timeout);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
index 9a3bea738330..5a634594a6ce 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
@@ -68,7 +68,7 @@ static int etnaviv_gem_shmem_get_pages(struct etnaviv_gem_object *etnaviv_obj)
struct page **p = drm_gem_get_pages(&etnaviv_obj->base);
if (IS_ERR(p)) {
- dev_err(dev->dev, "could not get pages: %ld\n", PTR_ERR(p));
+ dev_dbg(dev->dev, "could not get pages: %ld\n", PTR_ERR(p));
return PTR_ERR(p);
}
@@ -265,7 +265,7 @@ void etnaviv_gem_mapping_reference(struct etnaviv_vram_mapping *mapping)
{
struct etnaviv_gem_object *etnaviv_obj = mapping->object;
- drm_gem_object_reference(&etnaviv_obj->base);
+ drm_gem_object_get(&etnaviv_obj->base);
mutex_lock(&etnaviv_obj->lock);
WARN_ON(mapping->use == 0);
@@ -282,7 +282,7 @@ void etnaviv_gem_mapping_unreference(struct etnaviv_vram_mapping *mapping)
mapping->use -= 1;
mutex_unlock(&etnaviv_obj->lock);
- drm_gem_object_unreference_unlocked(&etnaviv_obj->base);
+ drm_gem_object_put_unlocked(&etnaviv_obj->base);
}
struct etnaviv_vram_mapping *etnaviv_gem_mapping_get(
@@ -358,7 +358,7 @@ out:
return ERR_PTR(ret);
/* Take a reference on the object */
- drm_gem_object_reference(obj);
+ drm_gem_object_get(obj);
return mapping;
}
@@ -413,6 +413,16 @@ int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op,
bool write = !!(op & ETNA_PREP_WRITE);
int ret;
+ if (!etnaviv_obj->sgt) {
+ void *ret;
+
+ mutex_lock(&etnaviv_obj->lock);
+ ret = etnaviv_gem_get_pages(etnaviv_obj);
+ mutex_unlock(&etnaviv_obj->lock);
+ if (IS_ERR(ret))
+ return PTR_ERR(ret);
+ }
+
if (op & ETNA_PREP_NOSYNC) {
if (!reservation_object_test_signaled_rcu(etnaviv_obj->resv,
write))
@@ -427,16 +437,6 @@ int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op,
}
if (etnaviv_obj->flags & ETNA_BO_CACHED) {
- if (!etnaviv_obj->sgt) {
- void *ret;
-
- mutex_lock(&etnaviv_obj->lock);
- ret = etnaviv_gem_get_pages(etnaviv_obj);
- mutex_unlock(&etnaviv_obj->lock);
- if (IS_ERR(ret))
- return PTR_ERR(ret);
- }
-
dma_sync_sg_for_cpu(dev->dev, etnaviv_obj->sgt->sgl,
etnaviv_obj->sgt->nents,
etnaviv_op_to_dma_dir(op));
@@ -662,7 +662,8 @@ static struct drm_gem_object *__etnaviv_gem_new(struct drm_device *dev,
* going to pin these pages.
*/
mapping = obj->filp->f_mapping;
- mapping_set_gfp_mask(mapping, GFP_HIGHUSER);
+ mapping_set_gfp_mask(mapping, GFP_HIGHUSER |
+ __GFP_RETRY_MAYFAIL | __GFP_NOWARN);
}
if (ret)
@@ -671,7 +672,7 @@ static struct drm_gem_object *__etnaviv_gem_new(struct drm_device *dev,
return obj;
fail:
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(ret);
}
@@ -688,14 +689,14 @@ int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file,
ret = etnaviv_gem_obj_add(dev, obj);
if (ret < 0) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
ret = drm_gem_handle_create(file, obj, handle);
/* drop reference from allocate - handle holds it now */
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -712,7 +713,7 @@ struct drm_gem_object *etnaviv_gem_new(struct drm_device *dev,
ret = etnaviv_gem_obj_add(dev, obj);
if (ret < 0) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(ret);
}
@@ -800,7 +801,7 @@ static void __etnaviv_gem_userptr_get_pages(struct work_struct *_work)
}
mutex_unlock(&etnaviv_obj->lock);
- drm_gem_object_unreference_unlocked(&etnaviv_obj->base);
+ drm_gem_object_put_unlocked(&etnaviv_obj->base);
mmput(work->mm);
put_task_struct(work->task);
@@ -858,7 +859,7 @@ static int etnaviv_gem_userptr_get_pages(struct etnaviv_gem_object *etnaviv_obj)
}
get_task_struct(current);
- drm_gem_object_reference(&etnaviv_obj->base);
+ drm_gem_object_get(&etnaviv_obj->base);
work->mm = mm;
work->task = current;
@@ -924,6 +925,6 @@ int etnaviv_gem_new_userptr(struct drm_device *dev, struct drm_file *file,
ret = drm_gem_handle_create(file, &etnaviv_obj->base, handle);
unreference:
/* drop reference from allocate - handle holds it now */
- drm_gem_object_unreference_unlocked(&etnaviv_obj->base);
+ drm_gem_object_put_unlocked(&etnaviv_obj->base);
return ret;
}
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
index e5da4f2300ba..ae884723e9b1 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
@@ -146,7 +146,7 @@ struct drm_gem_object *etnaviv_gem_prime_import_sg_table(struct drm_device *dev,
return &etnaviv_obj->base;
fail:
- drm_gem_object_unreference_unlocked(&etnaviv_obj->base);
+ drm_gem_object_put_unlocked(&etnaviv_obj->base);
return ERR_PTR(ret);
}
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
index 5bd93169dac2..a7ff2e4c00d2 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
@@ -88,7 +88,7 @@ static int submit_lookup_objects(struct etnaviv_gem_submit *submit,
* Take a refcount on the object. The file table lock
* prevents the object_idr's refcount on this being dropped.
*/
- drm_gem_object_reference(obj);
+ drm_gem_object_get(obj);
submit->bos[i].obj = to_etnaviv_bo(obj);
}
@@ -270,8 +270,8 @@ static int submit_reloc(struct etnaviv_gem_submit *submit, void *stream,
if (ret)
return ret;
- if (r->reloc_offset >= bo->obj->base.size - sizeof(*ptr)) {
- DRM_ERROR("relocation %u outside object", i);
+ if (r->reloc_offset > bo->obj->base.size - sizeof(*ptr)) {
+ DRM_ERROR("relocation %u outside object\n", i);
return -EINVAL;
}
@@ -291,7 +291,7 @@ static void submit_cleanup(struct etnaviv_gem_submit *submit)
struct etnaviv_gem_object *etnaviv_obj = submit->bos[i].obj;
submit_unlock_object(submit, i);
- drm_gem_object_unreference_unlocked(&etnaviv_obj->base);
+ drm_gem_object_put_unlocked(&etnaviv_obj->base);
}
ww_acquire_fini(&submit->ticket);
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index ada45fdd0eae..fc9a6a83dfc7 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -1622,10 +1622,12 @@ static int etnaviv_gpu_bind(struct device *dev, struct device *master,
struct etnaviv_gpu *gpu = dev_get_drvdata(dev);
int ret;
- gpu->cooling = thermal_of_cooling_device_register(dev->of_node,
+ if (IS_ENABLED(CONFIG_THERMAL)) {
+ gpu->cooling = thermal_of_cooling_device_register(dev->of_node,
(char *)dev_name(dev), gpu, &cooling_ops);
- if (IS_ERR(gpu->cooling))
- return PTR_ERR(gpu->cooling);
+ if (IS_ERR(gpu->cooling))
+ return PTR_ERR(gpu->cooling);
+ }
#ifdef CONFIG_PM
ret = pm_runtime_get_sync(gpu->dev);
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 1d185347c64c..305dc3d4ff77 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -75,6 +75,7 @@ config DRM_EXYNOS_DP
config DRM_EXYNOS_HDMI
bool "HDMI"
depends on DRM_EXYNOS_MIXER || DRM_EXYNOS5433_DECON
+ select CEC_CORE if CEC_NOTIFIER
help
Choose this option if you want to use Exynos HDMI for DRM.
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index d72777f6411a..c37078fbe0ea 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -21,7 +21,8 @@
#include "exynos_drm_drv.h"
#include "exynos_drm_plane.h"
-static void exynos_drm_crtc_enable(struct drm_crtc *crtc)
+static void exynos_drm_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
@@ -31,7 +32,8 @@ static void exynos_drm_crtc_enable(struct drm_crtc *crtc)
drm_crtc_vblank_on(crtc);
}
-static void exynos_drm_crtc_disable(struct drm_crtc *crtc)
+static void exynos_drm_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
@@ -82,11 +84,11 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
- .enable = exynos_drm_crtc_enable,
- .disable = exynos_drm_crtc_disable,
.atomic_check = exynos_crtc_atomic_check,
.atomic_begin = exynos_crtc_atomic_begin,
.atomic_flush = exynos_crtc_atomic_flush,
+ .atomic_enable = exynos_drm_crtc_atomic_enable,
+ .atomic_disable = exynos_drm_crtc_atomic_disable,
};
void exynos_crtc_handle_event(struct exynos_drm_crtc *exynos_crtc)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
index 63abcd280fa0..76d80e5de521 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
@@ -59,7 +59,6 @@ static void exynos_dpi_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs exynos_dpi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = exynos_dpi_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = exynos_dpi_connector_destroy,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 35a8dfc93836..b1f7299600f0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -145,8 +145,6 @@ static struct drm_driver exynos_drm_driver = {
.gem_free_object_unlocked = exynos_drm_gem_free_object,
.gem_vm_ops = &exynos_drm_gem_vm_ops,
.dumb_create = exynos_drm_gem_dumb_create,
- .dumb_map_offset = exynos_drm_gem_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_export = drm_gem_prime_export,
@@ -395,8 +393,9 @@ static int exynos_drm_bind(struct device *dev)
/* init kms poll for handling hpd */
drm_kms_helper_poll_init(drm);
- /* force connectors detection */
- drm_helper_hpd_irq_event(drm);
+ ret = exynos_drm_fbdev_init(drm);
+ if (ret)
+ goto err_cleanup_poll;
/* register the DRM device */
ret = drm_dev_register(drm, 0);
@@ -407,6 +406,7 @@ static int exynos_drm_bind(struct device *dev)
err_cleanup_fbdev:
exynos_drm_fbdev_fini(drm);
+err_cleanup_poll:
drm_kms_helper_poll_fini(drm);
exynos_drm_device_subdrv_remove(drm);
err_unbind_all:
@@ -453,7 +453,6 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)
struct component_match *match;
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
- exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
match = exynos_drm_match_add(&pdev->dev);
if (IS_ERR(match))
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index a11b79596e2f..c399dc9b325f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1537,7 +1537,6 @@ static void exynos_dsi_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs exynos_dsi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = exynos_dsi_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = exynos_dsi_connector_destroy,
@@ -1618,8 +1617,7 @@ static int exynos_dsi_of_read_u32(const struct device_node *np,
int ret = of_property_read_u32(np, propname, out_value);
if (ret < 0)
- pr_err("%s: failed to get '%s' property\n", np->full_name,
- propname);
+ pr_err("%pOF: failed to get '%s' property\n", np, propname);
return ret;
}
@@ -1651,8 +1649,6 @@ static int exynos_dsi_parse_dt(struct exynos_dsi *dsi)
return ret;
dsi->bridge_node = of_graph_get_remote_node(node, DSI_PORT_IN, 0);
- if (!dsi->bridge_node)
- return -EINVAL;
return 0;
}
@@ -1687,9 +1683,11 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
return ret;
}
- bridge = of_drm_find_bridge(dsi->bridge_node);
- if (bridge)
- drm_bridge_attach(encoder, bridge, NULL);
+ if (dsi->bridge_node) {
+ bridge = of_drm_find_bridge(dsi->bridge_node);
+ if (bridge)
+ drm_bridge_attach(encoder, bridge, NULL);
+ }
return mipi_dsi_host_register(&dsi->dsi_host);
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index d48fd7c918f8..6592f50d460a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -145,13 +145,19 @@ static struct drm_framebuffer *
exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
const struct drm_mode_fb_cmd2 *mode_cmd)
{
+ const struct drm_format_info *info = drm_get_format_info(dev, mode_cmd);
struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER];
struct drm_gem_object *obj;
struct drm_framebuffer *fb;
int i;
int ret;
- for (i = 0; i < drm_format_num_planes(mode_cmd->pixel_format); i++) {
+ for (i = 0; i < info->num_planes; i++) {
+ unsigned int height = (i == 0) ? mode_cmd->height :
+ DIV_ROUND_UP(mode_cmd->height, info->vsub);
+ unsigned long size = height * mode_cmd->pitches[i] +
+ mode_cmd->offsets[i];
+
obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]);
if (!obj) {
DRM_ERROR("failed to lookup gem object\n");
@@ -160,6 +166,12 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
}
exynos_gem[i] = to_exynos_gem(obj);
+
+ if (size > exynos_gem[i]->size) {
+ i++;
+ ret = -EINVAL;
+ goto err;
+ }
}
fb = exynos_drm_framebuffer_init(dev, mode_cmd, exynos_gem, i);
@@ -187,33 +199,8 @@ dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index)
return exynos_fb->dma_addr[index];
}
-static void exynos_drm_atomic_commit_tail(struct drm_atomic_state *state)
-{
- struct drm_device *dev = state->dev;
-
- drm_atomic_helper_commit_modeset_disables(dev, state);
-
- drm_atomic_helper_commit_modeset_enables(dev, state);
-
- /*
- * Exynos can't update planes with CRTCs and encoders disabled,
- * its updates routines, specially for FIMD, requires the clocks
- * to be enabled. So it is necessary to handle the modeset operations
- * *before* the commit_planes() step, this way it will always
- * have the relevant clocks enabled to perform the update.
- */
- drm_atomic_helper_commit_planes(dev, state,
- DRM_PLANE_COMMIT_ACTIVE_ONLY);
-
- drm_atomic_helper_commit_hw_done(state);
-
- drm_atomic_helper_wait_for_vblanks(dev, state);
-
- drm_atomic_helper_cleanup_planes(dev, state);
-}
-
static struct drm_mode_config_helper_funcs exynos_drm_mode_config_helpers = {
- .atomic_commit_tail = exynos_drm_atomic_commit_tail,
+ .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
};
static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 641531243e04..c3a068409b48 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -183,24 +183,6 @@ static const struct drm_fb_helper_funcs exynos_drm_fb_helper_funcs = {
.fb_probe = exynos_drm_fbdev_create,
};
-static bool exynos_drm_fbdev_is_anything_connected(struct drm_device *dev)
-{
- struct drm_connector *connector;
- bool ret = false;
-
- mutex_lock(&dev->mode_config.mutex);
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- if (connector->status != connector_status_connected)
- continue;
-
- ret = true;
- break;
- }
- mutex_unlock(&dev->mode_config.mutex);
-
- return ret;
-}
-
int exynos_drm_fbdev_init(struct drm_device *dev)
{
struct exynos_drm_fbdev *fbdev;
@@ -211,9 +193,6 @@ int exynos_drm_fbdev_init(struct drm_device *dev)
if (!dev->mode_config.num_crtc || !dev->mode_config.num_connector)
return 0;
- if (!exynos_drm_fbdev_is_anything_connected(dev))
- return 0;
-
fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
if (!fbdev)
return -ENOMEM;
@@ -304,8 +283,5 @@ void exynos_drm_output_poll_changed(struct drm_device *dev)
struct exynos_drm_private *private = dev->dev_private;
struct drm_fb_helper *fb_helper = private->fb_helper;
- if (fb_helper)
- drm_fb_helper_hotplug_event(fb_helper);
- else
- exynos_drm_fbdev_init(dev);
+ drm_fb_helper_hotplug_event(fb_helper);
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index c23479be4850..077de014d610 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -286,8 +286,8 @@ int exynos_drm_gem_map_ioctl(struct drm_device *dev, void *data,
{
struct drm_exynos_gem_map *args = data;
- return exynos_drm_gem_dumb_map_offset(file_priv, dev, args->handle,
- &args->offset);
+ return drm_gem_dumb_map_offset(file_priv, dev, args->handle,
+ &args->offset);
}
dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
@@ -422,32 +422,6 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
return 0;
}
-int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv,
- struct drm_device *dev, uint32_t handle,
- uint64_t *offset)
-{
- struct drm_gem_object *obj;
- int ret = 0;
-
- /*
- * get offset of memory allocated for drm framebuffer.
- * - this callback would be called by user application
- * with DRM_IOCTL_MODE_MAP_DUMB command.
- */
-
- obj = drm_gem_object_lookup(file_priv, handle);
- if (!obj) {
- DRM_ERROR("failed to lookup gem object.\n");
- return -EINVAL;
- }
-
- *offset = drm_vma_node_offset_addr(&obj->vma_node);
- DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset);
-
- drm_gem_object_unreference_unlocked(obj);
- return ret;
-}
-
int exynos_drm_gem_fault(struct vm_fault *vmf)
{
struct vm_area_struct *vma = vmf->vma;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 85457255fcd1..e86d1a9518c3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -110,11 +110,6 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
-/* map memory region for drm framebuffer to user space. */
-int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv,
- struct drm_device *dev, uint32_t handle,
- uint64_t *offset);
-
/* page fault handler and mmap fault address(virtual) to physical memory. */
int exynos_drm_gem_fault(struct vm_fault *vmf);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c
index e45720543a45..16bbee897e0d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_mic.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c
@@ -340,16 +340,10 @@ static int exynos_mic_bind(struct device *dev, struct device *master,
void *data)
{
struct exynos_mic *mic = dev_get_drvdata(dev);
- int ret;
- mic->bridge.funcs = &mic_bridge_funcs;
- mic->bridge.of_node = dev->of_node;
mic->bridge.driver_private = mic;
- ret = drm_bridge_add(&mic->bridge);
- if (ret)
- DRM_ERROR("mic: Failed to add MIC to the global bridge list\n");
- return ret;
+ return 0;
}
static void exynos_mic_unbind(struct device *dev, struct device *master,
@@ -365,8 +359,6 @@ static void exynos_mic_unbind(struct device *dev, struct device *master,
already_disabled:
mutex_unlock(&mic_mutex);
-
- drm_bridge_remove(&mic->bridge);
}
static const struct component_ops exynos_mic_component_ops = {
@@ -461,6 +453,15 @@ static int exynos_mic_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, mic);
+ mic->bridge.funcs = &mic_bridge_funcs;
+ mic->bridge.of_node = dev->of_node;
+
+ ret = drm_bridge_add(&mic->bridge);
+ if (ret) {
+ DRM_ERROR("mic: Failed to add MIC to the global bridge list\n");
+ return ret;
+ }
+
pm_runtime_enable(dev);
ret = component_add(dev, &exynos_mic_component_ops);
@@ -479,8 +480,13 @@ err:
static int exynos_mic_remove(struct platform_device *pdev)
{
+ struct exynos_mic *mic = platform_get_drvdata(pdev);
+
component_del(&pdev->dev, &exynos_mic_component_ops);
pm_runtime_disable(&pdev->dev);
+
+ drm_bridge_remove(&mic->bridge);
+
return 0;
}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index 611b6fd65433..8de74009dee4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -173,7 +173,6 @@ static struct drm_plane_funcs exynos_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = drm_plane_cleanup,
- .set_property = drm_atomic_helper_plane_set_property,
.reset = exynos_drm_plane_reset,
.atomic_duplicate_state = exynos_drm_plane_duplicate_state,
.atomic_destroy_state = exynos_drm_plane_destroy_state,
@@ -283,7 +282,7 @@ int exynos_plane_init(struct drm_device *dev,
&exynos_plane_funcs,
config->pixel_formats,
config->num_pixel_formats,
- config->type, NULL);
+ NULL, config->type, NULL);
if (err) {
DRM_ERROR("failed to initialize plane\n");
return err;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index cb8a72842537..9186a654c3b5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -289,7 +289,6 @@ static void vidi_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs vidi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = vidi_detect,
.destroy = vidi_connector_destroy,
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 06bfbe400cf1..d70eeb8c5f75 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -784,7 +784,7 @@ static void hdmi_reg_infoframes(struct hdmi_context *hdata)
}
ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi,
- &hdata->current_mode);
+ &hdata->current_mode, false);
if (!ret)
ret = hdmi_avi_infoframe_pack(&frm.avi, buf, sizeof(buf));
if (ret > 0) {
@@ -835,7 +835,6 @@ static void hdmi_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = hdmi_detect,
.destroy = hdmi_connector_destroy,
@@ -1501,8 +1500,6 @@ static void hdmi_disable(struct drm_encoder *encoder)
*/
cancel_delayed_work(&hdata->hotplug_work);
cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
-
- hdmiphy_disable(hdata);
}
static const struct drm_encoder_helper_funcs exynos_hdmi_encoder_helper_funcs = {
@@ -1676,7 +1673,7 @@ static int hdmi_resources_init(struct hdmi_context *hdata)
return hdmi_bridge_init(hdata);
}
-static struct of_device_id hdmi_match_types[] = {
+static const struct of_device_id hdmi_match_types[] = {
{
.compatible = "samsung,exynos4210-hdmi",
.data = &exynos4210_hdmi_driver_data,
@@ -1934,8 +1931,7 @@ static int hdmi_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
-static int exynos_hdmi_suspend(struct device *dev)
+static int __maybe_unused exynos_hdmi_suspend(struct device *dev)
{
struct hdmi_context *hdata = dev_get_drvdata(dev);
@@ -1944,7 +1940,7 @@ static int exynos_hdmi_suspend(struct device *dev)
return 0;
}
-static int exynos_hdmi_resume(struct device *dev)
+static int __maybe_unused exynos_hdmi_resume(struct device *dev)
{
struct hdmi_context *hdata = dev_get_drvdata(dev);
int ret;
@@ -1955,7 +1951,6 @@ static int exynos_hdmi_resume(struct device *dev)
return 0;
}
-#endif
static const struct dev_pm_ops exynos_hdmi_pm_ops = {
SET_RUNTIME_PM_OPS(exynos_hdmi_suspend, exynos_hdmi_resume, NULL)
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 6bed4f3ffcd6..a998a8dd783c 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -1094,28 +1094,28 @@ static const struct exynos_drm_crtc_ops mixer_crtc_ops = {
.atomic_check = mixer_atomic_check,
};
-static struct mixer_drv_data exynos5420_mxr_drv_data = {
+static const struct mixer_drv_data exynos5420_mxr_drv_data = {
.version = MXR_VER_128_0_0_184,
.is_vp_enabled = 0,
};
-static struct mixer_drv_data exynos5250_mxr_drv_data = {
+static const struct mixer_drv_data exynos5250_mxr_drv_data = {
.version = MXR_VER_16_0_33_0,
.is_vp_enabled = 0,
};
-static struct mixer_drv_data exynos4212_mxr_drv_data = {
+static const struct mixer_drv_data exynos4212_mxr_drv_data = {
.version = MXR_VER_0_0_0_16,
.is_vp_enabled = 1,
};
-static struct mixer_drv_data exynos4210_mxr_drv_data = {
+static const struct mixer_drv_data exynos4210_mxr_drv_data = {
.version = MXR_VER_0_0_0_16,
.is_vp_enabled = 1,
.has_sclk = 1,
};
-static struct of_device_id mixer_match_types[] = {
+static const struct of_device_id mixer_match_types[] = {
{
.compatible = "samsung,exynos4210-mixer",
.data = &exynos4210_mxr_drv_data,
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
index cc4e944a1d3c..0e3752437e44 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
@@ -63,7 +63,8 @@ static void fsl_dcu_drm_crtc_atomic_disable(struct drm_crtc *crtc,
clk_disable_unprepare(fsl_dev->pix_clk);
}
-static void fsl_dcu_drm_crtc_enable(struct drm_crtc *crtc)
+static void fsl_dcu_drm_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct drm_device *dev = crtc->dev;
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
@@ -133,7 +134,7 @@ static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
static const struct drm_crtc_helper_funcs fsl_dcu_drm_crtc_helper_funcs = {
.atomic_disable = fsl_dcu_drm_crtc_atomic_disable,
.atomic_flush = fsl_dcu_drm_crtc_atomic_flush,
- .enable = fsl_dcu_drm_crtc_enable,
+ .atomic_enable = fsl_dcu_drm_crtc_atomic_enable,
.mode_set_nofb = fsl_dcu_drm_crtc_mode_set_nofb,
};
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index 5cbde196895a..58e9e0601a61 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -176,8 +176,6 @@ static struct drm_driver fsl_dcu_drm_driver = {
.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
.gem_prime_mmap = drm_gem_cma_prime_mmap,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.fops = &fsl_dcu_drm_fops,
.name = "fsl-dcu-drm",
.desc = "Freescale DCU DRM",
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
index 0a20723aa6e1..9554b245746e 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
@@ -224,7 +224,7 @@ struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev)
&fsl_dcu_drm_plane_funcs,
fsl_dcu_drm_plane_formats,
ARRAY_SIZE(fsl_dcu_drm_plane_formats),
- DRM_PLANE_TYPE_PRIMARY, NULL);
+ NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) {
kfree(primary);
primary = NULL;
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
index dcbf3c06e1d8..edd7d8127d19 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
@@ -63,7 +63,6 @@ static const struct drm_connector_funcs fsl_dcu_drm_connector_funcs = {
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.destroy = fsl_dcu_drm_connector_destroy,
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.reset = drm_atomic_helper_connector_reset,
};
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 7da70b6c83f0..2570c7f647a6 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -479,26 +479,6 @@ static struct drm_framebuffer *psb_user_framebuffer_create
return psb_framebuffer_create(dev, cmd, r);
}
-static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
- struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
-
- gma_crtc->lut_r[regno] = red >> 8;
- gma_crtc->lut_g[regno] = green >> 8;
- gma_crtc->lut_b[regno] = blue >> 8;
-}
-
-static void psbfb_gamma_get(struct drm_crtc *crtc, u16 *red,
- u16 *green, u16 *blue, int regno)
-{
- struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
-
- *red = gma_crtc->lut_r[regno] << 8;
- *green = gma_crtc->lut_g[regno] << 8;
- *blue = gma_crtc->lut_b[regno] << 8;
-}
-
static int psbfb_probe(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
@@ -525,8 +505,6 @@ static int psbfb_probe(struct drm_fb_helper *helper,
}
static const struct drm_fb_helper_funcs psb_fb_helper_funcs = {
- .gamma_set = psbfb_gamma_set,
- .gamma_get = psbfb_gamma_get,
.fb_probe = psbfb_probe,
};
diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c
index 7da061aab729..131239759a75 100644
--- a/drivers/gpu/drm/gma500/gem.c
+++ b/drivers/gpu/drm/gma500/gem.c
@@ -48,36 +48,6 @@ int psb_gem_get_aperture(struct drm_device *dev, void *data,
}
/**
- * psb_gem_dumb_map_gtt - buffer mapping for dumb interface
- * @file: our drm client file
- * @dev: drm device
- * @handle: GEM handle to the object (from dumb_create)
- *
- * Do the necessary setup to allow the mapping of the frame buffer
- * into user memory. We don't have to do much here at the moment.
- */
-int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
- uint32_t handle, uint64_t *offset)
-{
- int ret = 0;
- struct drm_gem_object *obj;
-
- /* GEM does all our handle to object mapping */
- obj = drm_gem_object_lookup(file, handle);
- if (obj == NULL)
- return -ENOENT;
-
- /* Make it mmapable */
- ret = drm_gem_create_mmap_offset(obj);
- if (ret)
- goto out;
- *offset = drm_vma_node_offset_addr(&obj->vma_node);
-out:
- drm_gem_object_unreference_unlocked(obj);
- return ret;
-}
-
-/**
* psb_gem_create - create a mappable object
* @file: the DRM file of the client
* @dev: our device
diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c
index e7fd356acf2e..f3c48a2be71b 100644
--- a/drivers/gpu/drm/gma500/gma_display.c
+++ b/drivers/gpu/drm/gma500/gma_display.c
@@ -144,33 +144,32 @@ void gma_crtc_load_lut(struct drm_crtc *crtc)
struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
const struct psb_offset *map = &dev_priv->regmap[gma_crtc->pipe];
int palreg = map->palette;
+ u16 *r, *g, *b;
int i;
/* The clocks have to be on to load the palette. */
if (!crtc->enabled)
return;
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
+
if (gma_power_begin(dev, false)) {
for (i = 0; i < 256; i++) {
REG_WRITE(palreg + 4 * i,
- ((gma_crtc->lut_r[i] +
- gma_crtc->lut_adj[i]) << 16) |
- ((gma_crtc->lut_g[i] +
- gma_crtc->lut_adj[i]) << 8) |
- (gma_crtc->lut_b[i] +
- gma_crtc->lut_adj[i]));
+ (((*r++ >> 8) + gma_crtc->lut_adj[i]) << 16) |
+ (((*g++ >> 8) + gma_crtc->lut_adj[i]) << 8) |
+ ((*b++ >> 8) + gma_crtc->lut_adj[i]));
}
gma_power_end(dev);
} else {
for (i = 0; i < 256; i++) {
/* FIXME: Why pipe[0] and not pipe[..._crtc->pipe]? */
dev_priv->regs.pipe[0].palette[i] =
- ((gma_crtc->lut_r[i] +
- gma_crtc->lut_adj[i]) << 16) |
- ((gma_crtc->lut_g[i] +
- gma_crtc->lut_adj[i]) << 8) |
- (gma_crtc->lut_b[i] +
- gma_crtc->lut_adj[i]);
+ (((*r++ >> 8) + gma_crtc->lut_adj[i]) << 16) |
+ (((*g++ >> 8) + gma_crtc->lut_adj[i]) << 8) |
+ ((*b++ >> 8) + gma_crtc->lut_adj[i]);
}
}
@@ -180,15 +179,6 @@ int gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue,
u32 size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
- int i;
-
- for (i = 0; i < size; i++) {
- gma_crtc->lut_r[i] = red[i] >> 8;
- gma_crtc->lut_g[i] = green[i] >> 8;
- gma_crtc->lut_b[i] = blue[i] >> 8;
- }
-
gma_crtc_load_lut(crtc);
return 0;
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c b/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c
index 1616af209bfc..c50534c923df 100644
--- a/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c
+++ b/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c
@@ -520,7 +520,7 @@ static int __read_panel_data(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
u8 *data, u16 len, u32 *data_out, u16 len_out, bool hs)
{
unsigned long flags;
- struct drm_device *dev = sender->dev;
+ struct drm_device *dev;
int i;
u32 gen_data_reg;
int retry = MDFLD_DSI_READ_MAX_COUNT;
@@ -530,6 +530,8 @@ static int __read_panel_data(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
return -EINVAL;
}
+ dev = sender->dev;
+
/**
* do reading.
* 0) send out generic read request
diff --git a/drivers/gpu/drm/gma500/mdfld_intel_display.c b/drivers/gpu/drm/gma500/mdfld_intel_display.c
index 63c6e08600ae..531e4450c000 100644
--- a/drivers/gpu/drm/gma500/mdfld_intel_display.c
+++ b/drivers/gpu/drm/gma500/mdfld_intel_display.c
@@ -737,11 +737,7 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc,
sizeof(struct drm_display_mode));
list_for_each_entry(connector, &mode_config->connector_list, head) {
- if (!connector)
- continue;
-
encoder = connector->encoder;
-
if (!encoder)
continue;
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 1f9b35afefee..37a3be71acd9 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -480,7 +480,6 @@ static struct drm_driver driver = {
.load = psb_driver_load,
.unload = psb_driver_unload,
.lastclose = psb_driver_lastclose,
- .set_busid = drm_pci_set_busid,
.num_ioctls = ARRAY_SIZE(psb_ioctls),
.irq_preinstall = psb_irq_preinstall,
@@ -495,8 +494,6 @@ static struct drm_driver driver = {
.gem_vm_ops = &psb_gem_vm_ops,
.dumb_create = psb_gem_dumb_create,
- .dumb_map_offset = psb_gem_dumb_map_gtt,
- .dumb_destroy = drm_gem_dumb_destroy,
.ioctls = psb_ioctls,
.fops = &psb_gem_fops,
.name = DRIVER_NAME,
@@ -517,12 +514,12 @@ static struct pci_driver psb_pci_driver = {
static int __init psb_init(void)
{
- return drm_pci_init(&driver, &psb_pci_driver);
+ return pci_register_driver(&psb_pci_driver);
}
static void __exit psb_exit(void)
{
- drm_pci_exit(&driver, &psb_pci_driver);
+ pci_unregister_driver(&psb_pci_driver);
}
late_initcall(psb_init);
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index 83667087d6e5..821497dbd3fc 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -750,8 +750,6 @@ extern int psb_gem_get_aperture(struct drm_device *dev, void *data,
struct drm_file *file);
extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
struct drm_mode_create_dumb *args);
-extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
- uint32_t handle, uint64_t *offset);
extern int psb_gem_fault(struct vm_fault *vmf);
/* psb_device.c */
diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c
index 7b6c84925098..8762efaef283 100644
--- a/drivers/gpu/drm/gma500/psb_intel_display.c
+++ b/drivers/gpu/drm/gma500/psb_intel_display.c
@@ -518,13 +518,8 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe,
gma_crtc->pipe = pipe;
gma_crtc->plane = pipe;
- for (i = 0; i < 256; i++) {
- gma_crtc->lut_r[i] = i;
- gma_crtc->lut_g[i] = i;
- gma_crtc->lut_b[i] = i;
-
+ for (i = 0; i < 256; i++)
gma_crtc->lut_adj[i] = 0;
- }
gma_crtc->mode_dev = mode_dev;
gma_crtc->cursor_addr = 0;
diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h
index 6a10215fc42d..e8e4ea14b12b 100644
--- a/drivers/gpu/drm/gma500/psb_intel_drv.h
+++ b/drivers/gpu/drm/gma500/psb_intel_drv.h
@@ -172,7 +172,6 @@ struct gma_crtc {
int plane;
uint32_t cursor_addr;
struct gtt_range *cursor_gt;
- u8 lut_r[256], lut_g[256], lut_b[256];
u8 lut_adj[256];
struct psb_intel_framebuffer *fbdev_fb;
/* a mode_set for fbdev users on this crtc */
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
index 59542bddc980..a956545774a3 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
@@ -150,7 +150,6 @@ static const u32 channel_formats1[] = {
static struct drm_plane_funcs hibmc_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
- .set_property = drm_atomic_helper_plane_set_property,
.destroy = drm_plane_cleanup,
.reset = drm_atomic_helper_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
@@ -181,6 +180,7 @@ static struct drm_plane *hibmc_plane_init(struct hibmc_drm_private *priv)
ret = drm_universal_plane_init(dev, plane, 1, &hibmc_plane_funcs,
channel_formats1,
ARRAY_SIZE(channel_formats1),
+ NULL,
DRM_PLANE_TYPE_PRIMARY,
NULL);
if (ret) {
@@ -192,7 +192,8 @@ static struct drm_plane *hibmc_plane_init(struct hibmc_drm_private *priv)
return plane;
}
-static void hibmc_crtc_enable(struct drm_crtc *crtc)
+static void hibmc_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
unsigned int reg;
struct hibmc_drm_private *priv = crtc->dev->dev_private;
@@ -209,7 +210,8 @@ static void hibmc_crtc_enable(struct drm_crtc *crtc)
drm_crtc_vblank_on(crtc);
}
-static void hibmc_crtc_disable(struct drm_crtc *crtc)
+static void hibmc_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
unsigned int reg;
struct hibmc_drm_private *priv = crtc->dev->dev_private;
@@ -453,11 +455,11 @@ static const struct drm_crtc_funcs hibmc_crtc_funcs = {
};
static const struct drm_crtc_helper_funcs hibmc_crtc_helper_funcs = {
- .enable = hibmc_crtc_enable,
- .disable = hibmc_crtc_disable,
.mode_set_nofb = hibmc_crtc_mode_set_nofb,
.atomic_begin = hibmc_crtc_atomic_begin,
.atomic_flush = hibmc_crtc_atomic_flush,
+ .atomic_enable = hibmc_crtc_atomic_enable,
+ .atomic_disable = hibmc_crtc_atomic_disable,
};
int hibmc_de_init(struct hibmc_drm_private *priv)
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
index 2ffdbf9801bd..d4f6f1f9df5b 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
@@ -67,7 +67,6 @@ static struct drm_driver hibmc_driver = {
.gem_free_object_unlocked = hibmc_gem_free_object,
.dumb_create = hibmc_dumb_create,
.dumb_map_offset = hibmc_dumb_mmap_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.irq_handler = hibmc_drm_interrupt,
};
@@ -276,11 +275,12 @@ static int hibmc_unload(struct drm_device *dev)
hibmc_fbdev_fini(priv);
+ drm_atomic_helper_shutdown(dev);
+
if (dev->irq_enabled)
drm_irq_uninstall(dev);
if (priv->msi_enabled)
pci_disable_msi(dev->pdev);
- drm_vblank_cleanup(dev);
hibmc_kms_fini(priv);
hibmc_mm_fini(priv);
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c
index f5ac80daeef2..b92595c477ef 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c
@@ -131,7 +131,6 @@ static int hibmc_drm_fb_create(struct drm_fb_helper *helper,
strcpy(info->fix.id, "hibmcdrmfb");
- info->flags = FBINFO_DEFAULT;
info->fbops = &hibmc_drm_fb_ops;
drm_fb_helper_fill_fix(info, hi_fbdev->fb->fb.pitches[0],
@@ -158,7 +157,7 @@ out_unpin_bo:
out_unreserve_ttm_bo:
ttm_bo_unreserve(&bo->bo);
out_unref_gem:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return ret;
}
@@ -173,7 +172,7 @@ static void hibmc_fbdev_destroy(struct hibmc_fbdev *fbdev)
drm_fb_helper_fini(fbh);
if (gfb)
- drm_framebuffer_unreference(&gfb->fb);
+ drm_framebuffer_put(&gfb->fb);
}
static const struct drm_fb_helper_funcs hibmc_fbdev_helper_funcs = {
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
index 12a18557c5fd..ec4dd9df9150 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
@@ -47,7 +47,6 @@ static const struct drm_connector_helper_funcs
};
static const struct drm_connector_funcs hibmc_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
index ac457c779caa..3518167a7dc4 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c
@@ -444,7 +444,7 @@ int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev,
}
ret = drm_gem_handle_create(file, gobj, &handle);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (ret) {
DRM_ERROR("failed to unreference GEM object: %d\n", ret);
return ret;
@@ -479,7 +479,7 @@ int hibmc_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev,
bo = gem_to_hibmc_bo(obj);
*offset = hibmc_bo_mmap_offset(bo);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return 0;
}
@@ -487,7 +487,7 @@ static void hibmc_user_framebuffer_destroy(struct drm_framebuffer *fb)
{
struct hibmc_framebuffer *hibmc_fb = to_hibmc_framebuffer(fb);
- drm_gem_object_unreference_unlocked(hibmc_fb->obj);
+ drm_gem_object_put_unlocked(hibmc_fb->obj);
drm_framebuffer_cleanup(fb);
kfree(hibmc_fb);
}
@@ -543,7 +543,7 @@ hibmc_user_framebuffer_create(struct drm_device *dev,
hibmc_fb = hibmc_framebuffer_init(dev, mode_cmd, obj);
if (IS_ERR(hibmc_fb)) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR((long)hibmc_fb);
}
return &hibmc_fb->fb;
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
index c96c228a9898..39f7d15673ed 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
@@ -467,7 +467,8 @@ static void ade_dump_regs(void __iomem *base)
static void ade_dump_regs(void __iomem *base) { }
#endif
-static void ade_crtc_enable(struct drm_crtc *crtc)
+static void ade_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct ade_crtc *acrtc = to_ade_crtc(crtc);
struct ade_hw_ctx *ctx = acrtc->ctx;
@@ -489,7 +490,8 @@ static void ade_crtc_enable(struct drm_crtc *crtc)
acrtc->enable = true;
}
-static void ade_crtc_disable(struct drm_crtc *crtc)
+static void ade_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct ade_crtc *acrtc = to_ade_crtc(crtc);
struct ade_hw_ctx *ctx = acrtc->ctx;
@@ -553,11 +555,11 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs ade_crtc_helper_funcs = {
- .enable = ade_crtc_enable,
- .disable = ade_crtc_disable,
.mode_set_nofb = ade_crtc_mode_set_nofb,
.atomic_begin = ade_crtc_atomic_begin,
.atomic_flush = ade_crtc_atomic_flush,
+ .atomic_enable = ade_crtc_atomic_enable,
+ .atomic_disable = ade_crtc_atomic_disable,
};
static const struct drm_crtc_funcs ade_crtc_funcs = {
@@ -565,7 +567,6 @@ static const struct drm_crtc_funcs ade_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
.reset = drm_atomic_helper_crtc_reset,
- .set_property = drm_atomic_helper_crtc_set_property,
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
.enable_vblank = ade_crtc_enable_vblank,
@@ -583,8 +584,7 @@ static int ade_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
*/
port = of_get_child_by_name(dev->dev->of_node, "port");
if (!port) {
- DRM_ERROR("no port node found in %s\n",
- dev->dev->of_node->full_name);
+ DRM_ERROR("no port node found in %pOF\n", dev->dev->of_node);
return -EINVAL;
}
of_node_put(port);
@@ -889,7 +889,6 @@ static const struct drm_plane_helper_funcs ade_plane_helper_funcs = {
static struct drm_plane_funcs ade_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
- .set_property = drm_atomic_helper_plane_set_property,
.destroy = drm_plane_cleanup,
.reset = drm_atomic_helper_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
@@ -909,7 +908,7 @@ static int ade_plane_init(struct drm_device *dev, struct ade_plane *aplane,
return ret;
ret = drm_universal_plane_init(dev, &aplane->base, 1, &ade_plane_funcs,
- fmts, fmts_cnt, type, NULL);
+ fmts, fmts_cnt, NULL, type, NULL);
if (ret) {
DRM_ERROR("fail to init plane, ch=%d\n", aplane->ch);
return ret;
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
index 9c903672f582..e27352ca26c4 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
@@ -34,14 +34,12 @@ static int kirin_drm_kms_cleanup(struct drm_device *dev)
{
struct kirin_drm_private *priv = dev->dev_private;
-#ifdef CONFIG_DRM_FBDEV_EMULATION
if (priv->fbdev) {
drm_fbdev_cma_fini(priv->fbdev);
priv->fbdev = NULL;
}
-#endif
+
drm_kms_helper_poll_fini(dev);
- drm_vblank_cleanup(dev);
dc_ops->cleanup(to_platform_device(dev->dev));
drm_mode_config_cleanup(dev);
devm_kfree(dev->dev, priv);
@@ -50,27 +48,16 @@ static int kirin_drm_kms_cleanup(struct drm_device *dev)
return 0;
}
-#ifdef CONFIG_DRM_FBDEV_EMULATION
static void kirin_fbdev_output_poll_changed(struct drm_device *dev)
{
struct kirin_drm_private *priv = dev->dev_private;
- if (priv->fbdev) {
- drm_fbdev_cma_hotplug_event(priv->fbdev);
- } else {
- priv->fbdev = drm_fbdev_cma_init(dev, 32,
- dev->mode_config.num_connector);
- if (IS_ERR(priv->fbdev))
- priv->fbdev = NULL;
- }
+ drm_fbdev_cma_hotplug_event(priv->fbdev);
}
-#endif
static const struct drm_mode_config_funcs kirin_drm_mode_config_funcs = {
.fb_create = drm_fb_cma_create,
-#ifdef CONFIG_DRM_FBDEV_EMULATION
.output_poll_changed = kirin_fbdev_output_poll_changed,
-#endif
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
};
@@ -129,11 +116,18 @@ static int kirin_drm_kms_init(struct drm_device *dev)
/* init kms poll for handling hpd */
drm_kms_helper_poll_init(dev);
- /* force detection after connectors init */
- (void)drm_helper_hpd_irq_event(dev);
+ priv->fbdev = drm_fbdev_cma_init(dev, 32,
+ dev->mode_config.num_connector);
+ if (IS_ERR(priv->fbdev)) {
+ DRM_ERROR("failed to initialize fbdev.\n");
+ ret = PTR_ERR(priv->fbdev);
+ goto err_cleanup_poll;
+ }
return 0;
+err_cleanup_poll:
+ drm_kms_helper_poll_fini(dev);
err_unbind_all:
component_unbind_all(dev->dev, dev);
err_dc_cleanup:
@@ -163,8 +157,6 @@ static struct drm_driver kirin_drm_driver = {
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = kirin_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h
index 7f60c64915d9..56cb62df065c 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.h
@@ -20,9 +20,7 @@ struct kirin_dc_ops {
};
struct kirin_drm_private {
-#ifdef CONFIG_DRM_FBDEV_EMULATION
struct drm_fbdev_cma *fbdev;
-#endif
};
extern const struct kirin_dc_ops ade_dc_ops;
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 86f47e190309..54e3255dde13 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -712,7 +712,7 @@ tda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode)
{
union hdmi_infoframe frame;
- drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode);
+ drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false);
frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_FULL;
tda998x_write_if(priv, DIP_IF_FLAGS_IF2, REG_IF2_HB0, &frame);
@@ -969,14 +969,6 @@ static int tda998x_audio_codec_init(struct tda998x_priv *priv,
/* DRM connector functions */
-static int tda998x_connector_dpms(struct drm_connector *connector, int mode)
-{
- if (drm_core_check_feature(connector->dev, DRIVER_ATOMIC))
- return drm_atomic_helper_connector_dpms(connector, mode);
- else
- return drm_helper_connector_dpms(connector, mode);
-}
-
static int tda998x_connector_fill_modes(struct drm_connector *connector,
uint32_t maxX, uint32_t maxY)
{
@@ -1014,7 +1006,7 @@ static void tda998x_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs tda998x_connector_funcs = {
- .dpms = tda998x_connector_dpms,
+ .dpms = drm_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.fill_modes = tda998x_connector_fill_modes,
.detect = tda998x_connector_detect,
diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c
index 37fd0906f807..c69d5c487f51 100644
--- a/drivers/gpu/drm/i810/i810_drv.c
+++ b/drivers/gpu/drm/i810/i810_drv.c
@@ -59,7 +59,6 @@ static struct drm_driver driver = {
.load = i810_driver_load,
.lastclose = i810_driver_lastclose,
.preclose = i810_driver_preclose,
- .set_busid = drm_pci_set_busid,
.dma_quiescent = i810_driver_dma_quiescent,
.ioctls = i810_ioctls,
.fops = &i810_driver_fops,
@@ -83,12 +82,12 @@ static int __init i810_init(void)
return -EINVAL;
}
driver.num_ioctls = i810_max_ioctl;
- return drm_pci_init(&driver, &i810_pci_driver);
+ return drm_legacy_pci_init(&driver, &i810_pci_driver);
}
static void __exit i810_exit(void)
{
- drm_pci_exit(&driver, &i810_pci_driver);
+ drm_legacy_pci_exit(&driver, &i810_pci_driver);
}
module_init(i810_init);
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index a5cd5dacf055..e9e64e8e9765 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -21,6 +21,7 @@ config DRM_I915
select ACPI_BUTTON if ACPI
select SYNC_FILE
select IOSF_MBI
+ select CRC32
help
Choose this option if you have a system that has "Intel Graphics
Media Accelerator" or "HD Graphics" integrated graphics,
diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug
index 78c5c049a347..aed7d207ea84 100644
--- a/drivers/gpu/drm/i915/Kconfig.debug
+++ b/drivers/gpu/drm/i915/Kconfig.debug
@@ -25,6 +25,7 @@ config DRM_I915_DEBUG
select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks)
select DRM_DEBUG_MM if DRM=y
select DRM_DEBUG_MM_SELFTEST
+ select SW_SYNC # signaling validation framework (igt/syncobj*)
select DRM_I915_SW_FENCE_DEBUG_OBJECTS
select DRM_I915_SELFTEST
default n
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index f8227318dcaf..892f52b53060 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -39,6 +39,7 @@ i915-y += i915_cmd_parser.o \
i915_gem_gtt.o \
i915_gem_internal.o \
i915_gem.o \
+ i915_gem_object.o \
i915_gem_render_state.o \
i915_gem_request.o \
i915_gem_shrinker.o \
diff --git a/drivers/gpu/drm/i915/gvt/aperture_gm.c b/drivers/gpu/drm/i915/gvt/aperture_gm.c
index 325618d969fe..ca3d1925beda 100644
--- a/drivers/gpu/drm/i915/gvt/aperture_gm.c
+++ b/drivers/gpu/drm/i915/gvt/aperture_gm.c
@@ -285,8 +285,8 @@ static int alloc_resource(struct intel_vgpu *vgpu,
return 0;
no_enough_resource:
- gvt_vgpu_err("fail to allocate resource %s\n", item);
- gvt_vgpu_err("request %luMB avail %luMB max %luMB taken %luMB\n",
+ gvt_err("fail to allocate resource %s\n", item);
+ gvt_err("request %luMB avail %luMB max %luMB taken %luMB\n",
BYTES_TO_MB(request), BYTES_TO_MB(avail),
BYTES_TO_MB(max), BYTES_TO_MB(taken));
return -ENOSPC;
diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index 713848c36349..72b97ce525e8 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -1382,13 +1382,13 @@ static inline int cmd_address_audit(struct parser_exec_state *s,
ret = -EINVAL;
goto err;
}
- } else if ((!vgpu_gmadr_is_valid(s->vgpu, guest_gma)) ||
- (!vgpu_gmadr_is_valid(s->vgpu,
- guest_gma + op_size - 1))) {
+ } else if (!intel_gvt_ggtt_validate_range(vgpu, guest_gma, op_size)) {
ret = -EINVAL;
goto err;
}
+
return 0;
+
err:
gvt_vgpu_err("cmd_parser: Malicious %s detected, addr=0x%lx, len=%d!\n",
s->info->name, guest_gma, op_size);
@@ -2647,7 +2647,7 @@ static int shadow_workload_ring_buffer(struct intel_vgpu_workload *workload)
return 0;
}
-int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload)
+int intel_gvt_scan_and_shadow_ringbuffer(struct intel_vgpu_workload *workload)
{
int ret;
struct intel_vgpu *vgpu = workload->vgpu;
diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.h b/drivers/gpu/drm/i915/gvt/cmd_parser.h
index bed33514103c..286703643002 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.h
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.h
@@ -42,7 +42,7 @@ void intel_gvt_clean_cmd_parser(struct intel_gvt *gvt);
int intel_gvt_init_cmd_parser(struct intel_gvt *gvt);
-int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload);
+int intel_gvt_scan_and_shadow_ringbuffer(struct intel_vgpu_workload *workload);
int intel_gvt_scan_and_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx);
diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c
index 2deb05f618fb..3c318439a659 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -178,9 +178,9 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
SDE_PORTE_HOTPLUG_SPT);
vgpu_vreg(vgpu, SKL_FUSE_STATUS) |=
SKL_FUSE_DOWNLOAD_STATUS |
- SKL_FUSE_PG0_DIST_STATUS |
- SKL_FUSE_PG1_DIST_STATUS |
- SKL_FUSE_PG2_DIST_STATUS;
+ SKL_FUSE_PG_DIST_STATUS(SKL_PG0) |
+ SKL_FUSE_PG_DIST_STATUS(SKL_PG1) |
+ SKL_FUSE_PG_DIST_STATUS(SKL_PG2);
vgpu_vreg(vgpu, LCPLL1_CTL) |=
LCPLL_PLL_ENABLE |
LCPLL_PLL_LOCK;
@@ -323,27 +323,27 @@ void intel_gvt_check_vblank_emulation(struct intel_gvt *gvt)
{
struct intel_gvt_irq *irq = &gvt->irq;
struct intel_vgpu *vgpu;
- bool have_enabled_pipe = false;
int pipe, id;
if (WARN_ON(!mutex_is_locked(&gvt->lock)))
return;
- hrtimer_cancel(&irq->vblank_timer.timer);
-
for_each_active_vgpu(gvt, vgpu, id) {
for (pipe = 0; pipe < I915_MAX_PIPES; pipe++) {
- have_enabled_pipe =
- pipe_is_enabled(vgpu, pipe);
- if (have_enabled_pipe)
- break;
+ if (pipe_is_enabled(vgpu, pipe))
+ goto out;
}
}
- if (have_enabled_pipe)
- hrtimer_start(&irq->vblank_timer.timer,
- ktime_add_ns(ktime_get(), irq->vblank_timer.period),
- HRTIMER_MODE_ABS);
+ /* all the pipes are disabled */
+ hrtimer_cancel(&irq->vblank_timer.timer);
+ return;
+
+out:
+ hrtimer_start(&irq->vblank_timer.timer,
+ ktime_add_ns(ktime_get(), irq->vblank_timer.period),
+ HRTIMER_MODE_ABS);
+
}
static void emulate_vblank_on_pipe(struct intel_vgpu *vgpu, int pipe)
diff --git a/drivers/gpu/drm/i915/gvt/execlist.c b/drivers/gpu/drm/i915/gvt/execlist.c
index 700050556242..91b4300f3b39 100644
--- a/drivers/gpu/drm/i915/gvt/execlist.c
+++ b/drivers/gpu/drm/i915/gvt/execlist.c
@@ -46,6 +46,8 @@
#define same_context(a, b) (((a)->context_id == (b)->context_id) && \
((a)->lrca == (b)->lrca))
+static void clean_workloads(struct intel_vgpu *vgpu, unsigned long engine_mask);
+
static int context_switch_events[] = {
[RCS] = RCS_AS_CONTEXT_SWITCH,
[BCS] = BCS_AS_CONTEXT_SWITCH,
@@ -499,10 +501,10 @@ static void release_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
static int complete_execlist_workload(struct intel_vgpu_workload *workload)
{
struct intel_vgpu *vgpu = workload->vgpu;
- struct intel_vgpu_execlist *execlist =
- &vgpu->execlist[workload->ring_id];
+ int ring_id = workload->ring_id;
+ struct intel_vgpu_execlist *execlist = &vgpu->execlist[ring_id];
struct intel_vgpu_workload *next_workload;
- struct list_head *next = workload_q_head(vgpu, workload->ring_id)->next;
+ struct list_head *next = workload_q_head(vgpu, ring_id)->next;
bool lite_restore = false;
int ret;
@@ -512,10 +514,25 @@ static int complete_execlist_workload(struct intel_vgpu_workload *workload)
release_shadow_batch_buffer(workload);
release_shadow_wa_ctx(&workload->wa_ctx);
- if (workload->status || vgpu->resetting)
+ if (workload->status || (vgpu->resetting_eng & ENGINE_MASK(ring_id))) {
+ /* if workload->status is not successful means HW GPU
+ * has occurred GPU hang or something wrong with i915/GVT,
+ * and GVT won't inject context switch interrupt to guest.
+ * So this error is a vGPU hang actually to the guest.
+ * According to this we should emunlate a vGPU hang. If
+ * there are pending workloads which are already submitted
+ * from guest, we should clean them up like HW GPU does.
+ *
+ * if it is in middle of engine resetting, the pending
+ * workloads won't be submitted to HW GPU and will be
+ * cleaned up during the resetting process later, so doing
+ * the workload clean up here doesn't have any impact.
+ **/
+ clean_workloads(vgpu, ENGINE_MASK(ring_id));
goto out;
+ }
- if (!list_empty(workload_q_head(vgpu, workload->ring_id))) {
+ if (!list_empty(workload_q_head(vgpu, ring_id))) {
struct execlist_ctx_descriptor_format *this_desc, *next_desc;
next_workload = container_of(next,
@@ -605,6 +622,7 @@ static int submit_context(struct intel_vgpu *vgpu, int ring_id,
struct list_head *q = workload_q_head(vgpu, ring_id);
struct intel_vgpu_workload *last_workload = get_last_workload(q);
struct intel_vgpu_workload *workload = NULL;
+ struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
u64 ring_context_gpa;
u32 head, tail, start, ctl, ctx_ctl, per_ctx, indirect_ctx;
int ret;
@@ -668,6 +686,7 @@ static int submit_context(struct intel_vgpu *vgpu, int ring_id,
workload->complete = complete_execlist_workload;
workload->status = -EINPROGRESS;
workload->emulate_schedule_in = emulate_schedule_in;
+ workload->shadowed = false;
if (ring_id == RCS) {
intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
@@ -701,6 +720,17 @@ static int submit_context(struct intel_vgpu *vgpu, int ring_id,
return ret;
}
+ /* Only scan and shadow the first workload in the queue
+ * as there is only one pre-allocated buf-obj for shadow.
+ */
+ if (list_empty(workload_q_head(vgpu, ring_id))) {
+ intel_runtime_pm_get(dev_priv);
+ mutex_lock(&dev_priv->drm.struct_mutex);
+ intel_gvt_scan_and_shadow_workload(workload);
+ mutex_unlock(&dev_priv->drm.struct_mutex);
+ intel_runtime_pm_put(dev_priv);
+ }
+
queue_workload(workload);
return 0;
}
@@ -783,6 +813,8 @@ static void clean_workloads(struct intel_vgpu *vgpu, unsigned long engine_mask)
list_del_init(&pos->list);
free_workload(pos);
}
+
+ clear_bit(engine->id, vgpu->shadow_ctx_desc_updated);
}
}
diff --git a/drivers/gpu/drm/i915/gvt/firmware.c b/drivers/gpu/drm/i915/gvt/firmware.c
index 5dad9298b2d5..a26c1705430e 100644
--- a/drivers/gpu/drm/i915/gvt/firmware.c
+++ b/drivers/gpu/drm/i915/gvt/firmware.c
@@ -72,11 +72,13 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
struct intel_gvt_device_info *info = &gvt->device_info;
struct pci_dev *pdev = gvt->dev_priv->drm.pdev;
struct intel_gvt_mmio_info *e;
+ struct gvt_mmio_block *block = gvt->mmio.mmio_block;
+ int num = gvt->mmio.num_mmio_block;
struct gvt_firmware_header *h;
void *firmware;
void *p;
unsigned long size, crc32_start;
- int i;
+ int i, j;
int ret;
size = sizeof(*h) + info->mmio_size + info->cfg_space_size;
@@ -105,6 +107,13 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
hash_for_each(gvt->mmio.mmio_info_table, i, e, node)
*(u32 *)(p + e->offset) = I915_READ_NOTRACE(_MMIO(e->offset));
+ for (i = 0; i < num; i++, block++) {
+ for (j = 0; j < block->size; j += 4)
+ *(u32 *)(p + INTEL_GVT_MMIO_OFFSET(block->offset) + j) =
+ I915_READ_NOTRACE(_MMIO(INTEL_GVT_MMIO_OFFSET(
+ block->offset) + j));
+ }
+
memcpy(gvt->firmware.mmio, p, info->mmio_size);
crc32_start = offsetof(struct gvt_firmware_header, crc32) + 4;
diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index 6166e34d892b..e6dfc3331f4b 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -259,7 +259,7 @@ static void write_pte64(struct drm_i915_private *dev_priv,
writeq(pte, addr);
}
-static inline struct intel_gvt_gtt_entry *gtt_get_entry64(void *pt,
+static inline int gtt_get_entry64(void *pt,
struct intel_gvt_gtt_entry *e,
unsigned long index, bool hypervisor_access, unsigned long gpa,
struct intel_vgpu *vgpu)
@@ -268,22 +268,23 @@ static inline struct intel_gvt_gtt_entry *gtt_get_entry64(void *pt,
int ret;
if (WARN_ON(info->gtt_entry_size != 8))
- return e;
+ return -EINVAL;
if (hypervisor_access) {
ret = intel_gvt_hypervisor_read_gpa(vgpu, gpa +
(index << info->gtt_entry_size_shift),
&e->val64, 8);
- WARN_ON(ret);
+ if (WARN_ON(ret))
+ return ret;
} else if (!pt) {
e->val64 = read_pte64(vgpu->gvt->dev_priv, index);
} else {
e->val64 = *((u64 *)pt + index);
}
- return e;
+ return 0;
}
-static inline struct intel_gvt_gtt_entry *gtt_set_entry64(void *pt,
+static inline int gtt_set_entry64(void *pt,
struct intel_gvt_gtt_entry *e,
unsigned long index, bool hypervisor_access, unsigned long gpa,
struct intel_vgpu *vgpu)
@@ -292,19 +293,20 @@ static inline struct intel_gvt_gtt_entry *gtt_set_entry64(void *pt,
int ret;
if (WARN_ON(info->gtt_entry_size != 8))
- return e;
+ return -EINVAL;
if (hypervisor_access) {
ret = intel_gvt_hypervisor_write_gpa(vgpu, gpa +
(index << info->gtt_entry_size_shift),
&e->val64, 8);
- WARN_ON(ret);
+ if (WARN_ON(ret))
+ return ret;
} else if (!pt) {
write_pte64(vgpu->gvt->dev_priv, index, e->val64);
} else {
*((u64 *)pt + index) = e->val64;
}
- return e;
+ return 0;
}
#define GTT_HAW 46
@@ -445,21 +447,25 @@ static int gtt_entry_p2m(struct intel_vgpu *vgpu, struct intel_gvt_gtt_entry *p,
/*
* MM helpers.
*/
-struct intel_gvt_gtt_entry *intel_vgpu_mm_get_entry(struct intel_vgpu_mm *mm,
+int intel_vgpu_mm_get_entry(struct intel_vgpu_mm *mm,
void *page_table, struct intel_gvt_gtt_entry *e,
unsigned long index)
{
struct intel_gvt *gvt = mm->vgpu->gvt;
struct intel_gvt_gtt_pte_ops *ops = gvt->gtt.pte_ops;
+ int ret;
e->type = mm->page_table_entry_type;
- ops->get_entry(page_table, e, index, false, 0, mm->vgpu);
+ ret = ops->get_entry(page_table, e, index, false, 0, mm->vgpu);
+ if (ret)
+ return ret;
+
ops->test_pse(e);
- return e;
+ return 0;
}
-struct intel_gvt_gtt_entry *intel_vgpu_mm_set_entry(struct intel_vgpu_mm *mm,
+int intel_vgpu_mm_set_entry(struct intel_vgpu_mm *mm,
void *page_table, struct intel_gvt_gtt_entry *e,
unsigned long index)
{
@@ -472,7 +478,7 @@ struct intel_gvt_gtt_entry *intel_vgpu_mm_set_entry(struct intel_vgpu_mm *mm,
/*
* PPGTT shadow page table helpers.
*/
-static inline struct intel_gvt_gtt_entry *ppgtt_spt_get_entry(
+static inline int ppgtt_spt_get_entry(
struct intel_vgpu_ppgtt_spt *spt,
void *page_table, int type,
struct intel_gvt_gtt_entry *e, unsigned long index,
@@ -480,20 +486,24 @@ static inline struct intel_gvt_gtt_entry *ppgtt_spt_get_entry(
{
struct intel_gvt *gvt = spt->vgpu->gvt;
struct intel_gvt_gtt_pte_ops *ops = gvt->gtt.pte_ops;
+ int ret;
e->type = get_entry_type(type);
if (WARN(!gtt_type_is_entry(e->type), "invalid entry type\n"))
- return e;
+ return -EINVAL;
- ops->get_entry(page_table, e, index, guest,
+ ret = ops->get_entry(page_table, e, index, guest,
spt->guest_page.gfn << GTT_PAGE_SHIFT,
spt->vgpu);
+ if (ret)
+ return ret;
+
ops->test_pse(e);
- return e;
+ return 0;
}
-static inline struct intel_gvt_gtt_entry *ppgtt_spt_set_entry(
+static inline int ppgtt_spt_set_entry(
struct intel_vgpu_ppgtt_spt *spt,
void *page_table, int type,
struct intel_gvt_gtt_entry *e, unsigned long index,
@@ -503,7 +513,7 @@ static inline struct intel_gvt_gtt_entry *ppgtt_spt_set_entry(
struct intel_gvt_gtt_pte_ops *ops = gvt->gtt.pte_ops;
if (WARN(!gtt_type_is_entry(e->type), "invalid entry type\n"))
- return e;
+ return -EINVAL;
return ops->set_entry(page_table, e, index, guest,
spt->guest_page.gfn << GTT_PAGE_SHIFT,
@@ -792,13 +802,13 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_find_shadow_page(
#define for_each_present_guest_entry(spt, e, i) \
for (i = 0; i < pt_entries(spt); i++) \
- if (spt->vgpu->gvt->gtt.pte_ops->test_present( \
- ppgtt_get_guest_entry(spt, e, i)))
+ if (!ppgtt_get_guest_entry(spt, e, i) && \
+ spt->vgpu->gvt->gtt.pte_ops->test_present(e))
#define for_each_present_shadow_entry(spt, e, i) \
for (i = 0; i < pt_entries(spt); i++) \
- if (spt->vgpu->gvt->gtt.pte_ops->test_present( \
- ppgtt_get_shadow_entry(spt, e, i)))
+ if (!ppgtt_get_shadow_entry(spt, e, i) && \
+ spt->vgpu->gvt->gtt.pte_ops->test_present(e))
static void ppgtt_get_shadow_page(struct intel_vgpu_ppgtt_spt *spt)
{
@@ -979,29 +989,26 @@ fail:
}
static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_guest_page *gpt,
- unsigned long index)
+ struct intel_gvt_gtt_entry *se, unsigned long index)
{
struct intel_vgpu_ppgtt_spt *spt = guest_page_to_ppgtt_spt(gpt);
struct intel_vgpu_shadow_page *sp = &spt->shadow_page;
struct intel_vgpu *vgpu = spt->vgpu;
struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
- struct intel_gvt_gtt_entry e;
int ret;
- ppgtt_get_shadow_entry(spt, &e, index);
-
- trace_gpt_change(spt->vgpu->id, "remove", spt, sp->type, e.val64,
+ trace_gpt_change(spt->vgpu->id, "remove", spt, sp->type, se->val64,
index);
- if (!ops->test_present(&e))
+ if (!ops->test_present(se))
return 0;
- if (ops->get_pfn(&e) == vgpu->gtt.scratch_pt[sp->type].page_mfn)
+ if (ops->get_pfn(se) == vgpu->gtt.scratch_pt[sp->type].page_mfn)
return 0;
- if (gtt_type_is_pt(get_next_pt_type(e.type))) {
+ if (gtt_type_is_pt(get_next_pt_type(se->type))) {
struct intel_vgpu_ppgtt_spt *s =
- ppgtt_find_shadow_page(vgpu, ops->get_pfn(&e));
+ ppgtt_find_shadow_page(vgpu, ops->get_pfn(se));
if (!s) {
gvt_vgpu_err("fail to find guest page\n");
ret = -ENXIO;
@@ -1011,12 +1018,10 @@ static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_guest_page *gpt,
if (ret)
goto fail;
}
- ops->set_pfn(&e, vgpu->gtt.scratch_pt[sp->type].page_mfn);
- ppgtt_set_shadow_entry(spt, &e, index);
return 0;
fail:
gvt_vgpu_err("fail: shadow page %p guest entry 0x%llx type %d\n",
- spt, e.val64, e.type);
+ spt, se->val64, se->type);
return ret;
}
@@ -1236,22 +1241,37 @@ static int ppgtt_handle_guest_write_page_table(
{
struct intel_vgpu_ppgtt_spt *spt = guest_page_to_ppgtt_spt(gpt);
struct intel_vgpu *vgpu = spt->vgpu;
+ int type = spt->shadow_page.type;
struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
+ struct intel_gvt_gtt_entry se;
int ret;
int new_present;
new_present = ops->test_present(we);
- ret = ppgtt_handle_guest_entry_removal(gpt, index);
- if (ret)
- goto fail;
+ /*
+ * Adding the new entry first and then removing the old one, that can
+ * guarantee the ppgtt table is validated during the window between
+ * adding and removal.
+ */
+ ppgtt_get_shadow_entry(spt, &se, index);
if (new_present) {
ret = ppgtt_handle_guest_entry_add(gpt, we, index);
if (ret)
goto fail;
}
+
+ ret = ppgtt_handle_guest_entry_removal(gpt, &se, index);
+ if (ret)
+ goto fail;
+
+ if (!new_present) {
+ ops->set_pfn(&se, vgpu->gtt.scratch_pt[type].page_mfn);
+ ppgtt_set_shadow_entry(spt, &se, index);
+ }
+
return 0;
fail:
gvt_vgpu_err("fail: shadow page %p guest entry 0x%llx type %d.\n",
@@ -1323,7 +1343,7 @@ static int ppgtt_handle_guest_write_page_table_bytes(void *gp,
struct intel_vgpu *vgpu = spt->vgpu;
struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
const struct intel_gvt_device_info *info = &vgpu->gvt->device_info;
- struct intel_gvt_gtt_entry we;
+ struct intel_gvt_gtt_entry we, se;
unsigned long index;
int ret;
@@ -1339,7 +1359,8 @@ static int ppgtt_handle_guest_write_page_table_bytes(void *gp,
return ret;
} else {
if (!test_bit(index, spt->post_shadow_bitmap)) {
- ret = ppgtt_handle_guest_entry_removal(gpt, index);
+ ppgtt_get_shadow_entry(spt, &se, index);
+ ret = ppgtt_handle_guest_entry_removal(gpt, &se, index);
if (ret)
return ret;
}
@@ -1713,8 +1734,10 @@ unsigned long intel_vgpu_gma_to_gpa(struct intel_vgpu_mm *mm, unsigned long gma)
if (!vgpu_gmadr_is_valid(vgpu, gma))
goto err;
- ggtt_get_guest_entry(mm, &e,
- gma_ops->gma_to_ggtt_pte_index(gma));
+ ret = ggtt_get_guest_entry(mm, &e,
+ gma_ops->gma_to_ggtt_pte_index(gma));
+ if (ret)
+ goto err;
gpa = (pte_ops->get_pfn(&e) << GTT_PAGE_SHIFT)
+ (gma & ~GTT_PAGE_MASK);
@@ -1724,7 +1747,9 @@ unsigned long intel_vgpu_gma_to_gpa(struct intel_vgpu_mm *mm, unsigned long gma)
switch (mm->page_table_level) {
case 4:
- ppgtt_get_shadow_root_entry(mm, &e, 0);
+ ret = ppgtt_get_shadow_root_entry(mm, &e, 0);
+ if (ret)
+ goto err;
gma_index[0] = gma_ops->gma_to_pml4_index(gma);
gma_index[1] = gma_ops->gma_to_l4_pdp_index(gma);
gma_index[2] = gma_ops->gma_to_pde_index(gma);
@@ -1732,15 +1757,19 @@ unsigned long intel_vgpu_gma_to_gpa(struct intel_vgpu_mm *mm, unsigned long gma)
index = 4;
break;
case 3:
- ppgtt_get_shadow_root_entry(mm, &e,
+ ret = ppgtt_get_shadow_root_entry(mm, &e,
gma_ops->gma_to_l3_pdp_index(gma));
+ if (ret)
+ goto err;
gma_index[0] = gma_ops->gma_to_pde_index(gma);
gma_index[1] = gma_ops->gma_to_pte_index(gma);
index = 2;
break;
case 2:
- ppgtt_get_shadow_root_entry(mm, &e,
+ ret = ppgtt_get_shadow_root_entry(mm, &e,
gma_ops->gma_to_pde_index(gma));
+ if (ret)
+ goto err;
gma_index[0] = gma_ops->gma_to_pte_index(gma);
index = 1;
break;
@@ -1755,6 +1784,11 @@ unsigned long intel_vgpu_gma_to_gpa(struct intel_vgpu_mm *mm, unsigned long gma)
(i == index - 1));
if (ret)
goto err;
+
+ if (!pte_ops->test_present(&e)) {
+ gvt_dbg_core("GMA 0x%lx is not present\n", gma);
+ goto err;
+ }
}
gpa = (pte_ops->get_pfn(&e) << GTT_PAGE_SHIFT)
@@ -2329,13 +2363,12 @@ void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu)
/**
* intel_vgpu_reset_gtt - reset the all GTT related status
* @vgpu: a vGPU
- * @dmlr: true for vGPU Device Model Level Reset, false for GT Reset
*
* This function is called from vfio core to reset reset all
* GTT related status, including GGTT, PPGTT, scratch page.
*
*/
-void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu, bool dmlr)
+void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu)
{
int i;
@@ -2347,9 +2380,6 @@ void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu, bool dmlr)
*/
intel_vgpu_free_mm(vgpu, INTEL_GVT_MM_PPGTT);
- if (!dmlr)
- return;
-
intel_vgpu_reset_ggtt(vgpu);
/* clear scratch page for security */
diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h
index f88eb5e89bea..30a4c8d16026 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.h
+++ b/drivers/gpu/drm/i915/gvt/gtt.h
@@ -49,14 +49,18 @@ struct intel_gvt_gtt_entry {
};
struct intel_gvt_gtt_pte_ops {
- struct intel_gvt_gtt_entry *(*get_entry)(void *pt,
- struct intel_gvt_gtt_entry *e,
- unsigned long index, bool hypervisor_access, unsigned long gpa,
- struct intel_vgpu *vgpu);
- struct intel_gvt_gtt_entry *(*set_entry)(void *pt,
- struct intel_gvt_gtt_entry *e,
- unsigned long index, bool hypervisor_access, unsigned long gpa,
- struct intel_vgpu *vgpu);
+ int (*get_entry)(void *pt,
+ struct intel_gvt_gtt_entry *e,
+ unsigned long index,
+ bool hypervisor_access,
+ unsigned long gpa,
+ struct intel_vgpu *vgpu);
+ int (*set_entry)(void *pt,
+ struct intel_gvt_gtt_entry *e,
+ unsigned long index,
+ bool hypervisor_access,
+ unsigned long gpa,
+ struct intel_vgpu *vgpu);
bool (*test_present)(struct intel_gvt_gtt_entry *e);
void (*clear_present)(struct intel_gvt_gtt_entry *e);
bool (*test_pse)(struct intel_gvt_gtt_entry *e);
@@ -143,12 +147,12 @@ struct intel_vgpu_mm {
struct intel_vgpu *vgpu;
};
-extern struct intel_gvt_gtt_entry *intel_vgpu_mm_get_entry(
+extern int intel_vgpu_mm_get_entry(
struct intel_vgpu_mm *mm,
void *page_table, struct intel_gvt_gtt_entry *e,
unsigned long index);
-extern struct intel_gvt_gtt_entry *intel_vgpu_mm_set_entry(
+extern int intel_vgpu_mm_set_entry(
struct intel_vgpu_mm *mm,
void *page_table, struct intel_gvt_gtt_entry *e,
unsigned long index);
@@ -208,7 +212,7 @@ extern void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu);
void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu);
extern int intel_gvt_init_gtt(struct intel_gvt *gvt);
-extern void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu, bool dmlr);
+void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu);
extern void intel_gvt_clean_gtt(struct intel_gvt *gvt);
extern struct intel_vgpu_mm *intel_gvt_find_ppgtt_mm(struct intel_vgpu *vgpu,
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 3a74e79eac2f..44b719eda8c4 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -149,7 +149,7 @@ struct intel_vgpu {
bool active;
bool pv_notified;
bool failsafe;
- bool resetting;
+ unsigned int resetting_eng;
void *sched_data;
struct vgpu_sched_ctl sched_ctl;
@@ -167,6 +167,7 @@ struct intel_vgpu {
atomic_t running_workload_num;
DECLARE_BITMAP(tlb_handle_pending, I915_NUM_ENGINES);
struct i915_gem_context *shadow_ctx;
+ DECLARE_BITMAP(shadow_ctx_desc_updated, I915_NUM_ENGINES);
#if IS_ENABLED(CONFIG_DRM_I915_GVT_KVMGT)
struct {
@@ -195,6 +196,15 @@ struct intel_gvt_fence {
unsigned long vgpu_allocated_fence_num;
};
+/* Special MMIO blocks. */
+struct gvt_mmio_block {
+ unsigned int device;
+ i915_reg_t offset;
+ unsigned int size;
+ gvt_mmio_func read;
+ gvt_mmio_func write;
+};
+
#define INTEL_GVT_MMIO_HASH_BITS 11
struct intel_gvt_mmio {
@@ -214,6 +224,9 @@ struct intel_gvt_mmio {
/* This reg could be accessed by unaligned address */
#define F_UNALIGN (1 << 6)
+ struct gvt_mmio_block *mmio_block;
+ unsigned int num_mmio_block;
+
DECLARE_HASHTABLE(mmio_info_table, INTEL_GVT_MMIO_HASH_BITS);
unsigned int num_tracked_mmio;
};
@@ -470,6 +483,8 @@ int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa);
int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci);
void populate_pvinfo_page(struct intel_vgpu *vgpu);
+int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload);
+
struct intel_gvt_ops {
int (*emulate_cfg_read)(struct intel_vgpu *, unsigned int, void *,
unsigned int);
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c
index 17febe830ff6..3502a59166ff 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -113,9 +113,17 @@ static int new_mmio_info(struct intel_gvt *gvt,
info->offset = i;
p = find_mmio_info(gvt, info->offset);
- if (p)
- gvt_err("dup mmio definition offset %x\n",
+ if (p) {
+ WARN(1, "dup mmio definition offset %x\n",
info->offset);
+ kfree(info);
+
+ /* We return -EEXIST here to make GVT-g load fail.
+ * So duplicated MMIO can be found as soon as
+ * possible.
+ */
+ return -EEXIST;
+ }
info->ro_mask = ro_mask;
info->device = device;
@@ -1222,10 +1230,12 @@ static int power_well_ctl_mmio_write(struct intel_vgpu *vgpu,
{
write_vreg(vgpu, offset, p_data, bytes);
- if (vgpu_vreg(vgpu, offset) & HSW_PWR_WELL_ENABLE_REQUEST)
- vgpu_vreg(vgpu, offset) |= HSW_PWR_WELL_STATE_ENABLED;
+ if (vgpu_vreg(vgpu, offset) & HSW_PWR_WELL_CTL_REQ(HSW_DISP_PW_GLOBAL))
+ vgpu_vreg(vgpu, offset) |=
+ HSW_PWR_WELL_CTL_STATE(HSW_DISP_PW_GLOBAL);
else
- vgpu_vreg(vgpu, offset) &= ~HSW_PWR_WELL_STATE_ENABLED;
+ vgpu_vreg(vgpu, offset) &=
+ ~HSW_PWR_WELL_CTL_STATE(HSW_DISP_PW_GLOBAL);
return 0;
}
@@ -2242,10 +2252,17 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
MMIO_D(GEN6_RC6p_THRESHOLD, D_ALL);
MMIO_D(GEN6_RC6pp_THRESHOLD, D_ALL);
MMIO_D(GEN6_PMINTRMSK, D_ALL);
- MMIO_DH(HSW_PWR_WELL_BIOS, D_BDW, NULL, power_well_ctl_mmio_write);
- MMIO_DH(HSW_PWR_WELL_DRIVER, D_BDW, NULL, power_well_ctl_mmio_write);
- MMIO_DH(HSW_PWR_WELL_KVMR, D_BDW, NULL, power_well_ctl_mmio_write);
- MMIO_DH(HSW_PWR_WELL_DEBUG, D_BDW, NULL, power_well_ctl_mmio_write);
+ /*
+ * Use an arbitrary power well controlled by the PWR_WELL_CTL
+ * register.
+ */
+ MMIO_DH(HSW_PWR_WELL_CTL_BIOS(HSW_DISP_PW_GLOBAL), D_BDW, NULL,
+ power_well_ctl_mmio_write);
+ MMIO_DH(HSW_PWR_WELL_CTL_DRIVER(HSW_DISP_PW_GLOBAL), D_BDW, NULL,
+ power_well_ctl_mmio_write);
+ MMIO_DH(HSW_PWR_WELL_CTL_KVMR, D_BDW, NULL, power_well_ctl_mmio_write);
+ MMIO_DH(HSW_PWR_WELL_CTL_DEBUG(HSW_DISP_PW_GLOBAL), D_BDW, NULL,
+ power_well_ctl_mmio_write);
MMIO_DH(HSW_PWR_WELL_CTL5, D_BDW, NULL, power_well_ctl_mmio_write);
MMIO_DH(HSW_PWR_WELL_CTL6, D_BDW, NULL, power_well_ctl_mmio_write);
@@ -2581,7 +2598,6 @@ static int init_broadwell_mmio_info(struct intel_gvt *gvt)
MMIO_F(0x24d0, 48, F_CMD_ACCESS, 0, 0, D_BDW_PLUS,
NULL, force_nonpriv_write);
- MMIO_D(0x22040, D_BDW_PLUS);
MMIO_D(0x44484, D_BDW_PLUS);
MMIO_D(0x4448c, D_BDW_PLUS);
@@ -2636,9 +2652,13 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
MMIO_F(_DPD_AUX_CH_CTL, 6 * 4, 0, 0, 0, D_SKL_PLUS, NULL,
dp_aux_ch_ctl_mmio_write);
- MMIO_D(HSW_PWR_WELL_BIOS, D_SKL_PLUS);
- MMIO_DH(HSW_PWR_WELL_DRIVER, D_SKL_PLUS, NULL,
- skl_power_well_ctl_write);
+ /*
+ * Use an arbitrary power well controlled by the PWR_WELL_CTL
+ * register.
+ */
+ MMIO_D(HSW_PWR_WELL_CTL_BIOS(SKL_DISP_PW_MISC_IO), D_SKL_PLUS);
+ MMIO_DH(HSW_PWR_WELL_CTL_DRIVER(SKL_DISP_PW_MISC_IO), D_SKL_PLUS, NULL,
+ skl_power_well_ctl_write);
MMIO_DH(GEN6_PCODE_MAILBOX, D_SKL_PLUS, NULL, mailbox_write);
MMIO_D(0xa210, D_SKL_PLUS);
@@ -2831,7 +2851,6 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
MMIO_D(0x320f0, D_SKL | D_KBL);
MMIO_DFH(_REG_VCS2_EXCC, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
- MMIO_DFH(_REG_VECS_EXCC, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
MMIO_D(0x70034, D_SKL_PLUS);
MMIO_D(0x71034, D_SKL_PLUS);
MMIO_D(0x72034, D_SKL_PLUS);
@@ -2849,39 +2868,20 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
NULL, NULL);
MMIO_D(0x4ab8, D_KBL);
- MMIO_D(0x940c, D_SKL_PLUS);
MMIO_D(0x2248, D_SKL_PLUS | D_KBL);
- MMIO_D(0x4ab0, D_SKL | D_KBL);
- MMIO_D(0x20d4, D_SKL | D_KBL);
return 0;
}
-/* Special MMIO blocks. */
-static struct gvt_mmio_block {
- unsigned int device;
- i915_reg_t offset;
- unsigned int size;
- gvt_mmio_func read;
- gvt_mmio_func write;
-} gvt_mmio_blocks[] = {
- {D_SKL_PLUS, _MMIO(CSR_MMIO_START_RANGE), 0x3000, NULL, NULL},
- {D_ALL, _MMIO(MCHBAR_MIRROR_BASE_SNB), 0x40000, NULL, NULL},
- {D_ALL, _MMIO(VGT_PVINFO_PAGE), VGT_PVINFO_SIZE,
- pvinfo_mmio_read, pvinfo_mmio_write},
- {D_ALL, LGC_PALETTE(PIPE_A, 0), 1024, NULL, NULL},
- {D_ALL, LGC_PALETTE(PIPE_B, 0), 1024, NULL, NULL},
- {D_ALL, LGC_PALETTE(PIPE_C, 0), 1024, NULL, NULL},
-};
-
static struct gvt_mmio_block *find_mmio_block(struct intel_gvt *gvt,
unsigned int offset)
{
unsigned long device = intel_gvt_get_device_type(gvt);
- struct gvt_mmio_block *block = gvt_mmio_blocks;
+ struct gvt_mmio_block *block = gvt->mmio.mmio_block;
+ int num = gvt->mmio.num_mmio_block;
int i;
- for (i = 0; i < ARRAY_SIZE(gvt_mmio_blocks); i++, block++) {
+ for (i = 0; i < num; i++, block++) {
if (!(device & block->device))
continue;
if (offset >= INTEL_GVT_MMIO_OFFSET(block->offset) &&
@@ -2912,6 +2912,17 @@ void intel_gvt_clean_mmio_info(struct intel_gvt *gvt)
gvt->mmio.mmio_attribute = NULL;
}
+/* Special MMIO blocks. */
+static struct gvt_mmio_block mmio_blocks[] = {
+ {D_SKL_PLUS, _MMIO(CSR_MMIO_START_RANGE), 0x3000, NULL, NULL},
+ {D_ALL, _MMIO(MCHBAR_MIRROR_BASE_SNB), 0x40000, NULL, NULL},
+ {D_ALL, _MMIO(VGT_PVINFO_PAGE), VGT_PVINFO_SIZE,
+ pvinfo_mmio_read, pvinfo_mmio_write},
+ {D_ALL, LGC_PALETTE(PIPE_A, 0), 1024, NULL, NULL},
+ {D_ALL, LGC_PALETTE(PIPE_B, 0), 1024, NULL, NULL},
+ {D_ALL, LGC_PALETTE(PIPE_C, 0), 1024, NULL, NULL},
+};
+
/**
* intel_gvt_setup_mmio_info - setup MMIO information table for GVT device
* @gvt: GVT device
@@ -2951,6 +2962,9 @@ int intel_gvt_setup_mmio_info(struct intel_gvt *gvt)
goto err;
}
+ gvt->mmio.mmio_block = mmio_blocks;
+ gvt->mmio.num_mmio_block = ARRAY_SIZE(mmio_blocks);
+
gvt_dbg_mmio("traced %u virtual mmio registers\n",
gvt->mmio.num_tracked_mmio);
return 0;
@@ -3030,7 +3044,7 @@ int intel_vgpu_mmio_reg_rw(struct intel_vgpu *vgpu, unsigned int offset,
gvt_mmio_func func;
int ret;
- if (WARN_ON(bytes > 4))
+ if (WARN_ON(bytes > 8))
return -EINVAL;
/*
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index fd0c85f9ef3c..83e88c70272a 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1170,10 +1170,27 @@ vgpu_id_show(struct device *dev, struct device_attribute *attr,
return sprintf(buf, "\n");
}
+static ssize_t
+hw_id_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct mdev_device *mdev = mdev_from_dev(dev);
+
+ if (mdev) {
+ struct intel_vgpu *vgpu = (struct intel_vgpu *)
+ mdev_get_drvdata(mdev);
+ return sprintf(buf, "%u\n",
+ vgpu->shadow_ctx->hw_id);
+ }
+ return sprintf(buf, "\n");
+}
+
static DEVICE_ATTR_RO(vgpu_id);
+static DEVICE_ATTR_RO(hw_id);
static struct attribute *intel_vgpu_attrs[] = {
&dev_attr_vgpu_id.attr,
+ &dev_attr_hw_id.attr,
NULL
};
diff --git a/drivers/gpu/drm/i915/gvt/render.c b/drivers/gpu/drm/i915/gvt/render.c
index 504e57c3bc23..2ea542257f03 100644
--- a/drivers/gpu/drm/i915/gvt/render.c
+++ b/drivers/gpu/drm/i915/gvt/render.c
@@ -207,18 +207,16 @@ static void load_mocs(struct intel_vgpu *vgpu, int ring_id)
offset.reg = regs[ring_id];
for (i = 0; i < 64; i++) {
- gen9_render_mocs[ring_id][i] = I915_READ(offset);
+ gen9_render_mocs[ring_id][i] = I915_READ_FW(offset);
I915_WRITE(offset, vgpu_vreg(vgpu, offset));
- POSTING_READ(offset);
offset.reg += 4;
}
if (ring_id == RCS) {
l3_offset.reg = 0xb020;
for (i = 0; i < 32; i++) {
- gen9_render_mocs_L3[i] = I915_READ(l3_offset);
- I915_WRITE(l3_offset, vgpu_vreg(vgpu, l3_offset));
- POSTING_READ(l3_offset);
+ gen9_render_mocs_L3[i] = I915_READ_FW(l3_offset);
+ I915_WRITE_FW(l3_offset, vgpu_vreg(vgpu, l3_offset));
l3_offset.reg += 4;
}
}
@@ -242,18 +240,16 @@ static void restore_mocs(struct intel_vgpu *vgpu, int ring_id)
offset.reg = regs[ring_id];
for (i = 0; i < 64; i++) {
- vgpu_vreg(vgpu, offset) = I915_READ(offset);
- I915_WRITE(offset, gen9_render_mocs[ring_id][i]);
- POSTING_READ(offset);
+ vgpu_vreg(vgpu, offset) = I915_READ_FW(offset);
+ I915_WRITE_FW(offset, gen9_render_mocs[ring_id][i]);
offset.reg += 4;
}
if (ring_id == RCS) {
l3_offset.reg = 0xb020;
for (i = 0; i < 32; i++) {
- vgpu_vreg(vgpu, l3_offset) = I915_READ(l3_offset);
- I915_WRITE(l3_offset, gen9_render_mocs_L3[i]);
- POSTING_READ(l3_offset);
+ vgpu_vreg(vgpu, l3_offset) = I915_READ_FW(l3_offset);
+ I915_WRITE_FW(l3_offset, gen9_render_mocs_L3[i]);
l3_offset.reg += 4;
}
}
@@ -272,6 +268,7 @@ static void switch_mmio_to_vgpu(struct intel_vgpu *vgpu, int ring_id)
u32 ctx_ctrl = reg_state[CTX_CONTEXT_CONTROL_VAL];
u32 inhibit_mask =
_MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT);
+ i915_reg_t last_reg = _MMIO(0);
if (IS_SKYLAKE(vgpu->gvt->dev_priv)
|| IS_KABYLAKE(vgpu->gvt->dev_priv)) {
@@ -287,7 +284,7 @@ static void switch_mmio_to_vgpu(struct intel_vgpu *vgpu, int ring_id)
if (mmio->ring_id != ring_id)
continue;
- mmio->value = I915_READ(mmio->reg);
+ mmio->value = I915_READ_FW(mmio->reg);
/*
* if it is an inhibit context, load in_context mmio
@@ -304,13 +301,18 @@ static void switch_mmio_to_vgpu(struct intel_vgpu *vgpu, int ring_id)
else
v = vgpu_vreg(vgpu, mmio->reg);
- I915_WRITE(mmio->reg, v);
- POSTING_READ(mmio->reg);
+ I915_WRITE_FW(mmio->reg, v);
+ last_reg = mmio->reg;
trace_render_mmio(vgpu->id, "load",
i915_mmio_reg_offset(mmio->reg),
mmio->value, v);
}
+
+ /* Make sure the swiched MMIOs has taken effect. */
+ if (likely(INTEL_GVT_MMIO_OFFSET(last_reg)))
+ I915_READ_FW(last_reg);
+
handle_tlb_pending_event(vgpu, ring_id);
}
@@ -319,6 +321,7 @@ static void switch_mmio_to_host(struct intel_vgpu *vgpu, int ring_id)
{
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
struct render_mmio *mmio;
+ i915_reg_t last_reg = _MMIO(0);
u32 v;
int i, array_size;
@@ -335,7 +338,7 @@ static void switch_mmio_to_host(struct intel_vgpu *vgpu, int ring_id)
if (mmio->ring_id != ring_id)
continue;
- vgpu_vreg(vgpu, mmio->reg) = I915_READ(mmio->reg);
+ vgpu_vreg(vgpu, mmio->reg) = I915_READ_FW(mmio->reg);
if (mmio->mask) {
vgpu_vreg(vgpu, mmio->reg) &= ~(mmio->mask << 16);
@@ -346,13 +349,17 @@ static void switch_mmio_to_host(struct intel_vgpu *vgpu, int ring_id)
if (mmio->in_context)
continue;
- I915_WRITE(mmio->reg, v);
- POSTING_READ(mmio->reg);
+ I915_WRITE_FW(mmio->reg, v);
+ last_reg = mmio->reg;
trace_render_mmio(vgpu->id, "restore",
i915_mmio_reg_offset(mmio->reg),
mmio->value, v);
}
+
+ /* Make sure the swiched MMIOs has taken effect. */
+ if (likely(INTEL_GVT_MMIO_OFFSET(last_reg)))
+ I915_READ_FW(last_reg);
}
/**
@@ -367,12 +374,23 @@ static void switch_mmio_to_host(struct intel_vgpu *vgpu, int ring_id)
void intel_gvt_switch_mmio(struct intel_vgpu *pre,
struct intel_vgpu *next, int ring_id)
{
+ struct drm_i915_private *dev_priv;
+
if (WARN_ON(!pre && !next))
return;
gvt_dbg_render("switch ring %d from %s to %s\n", ring_id,
pre ? "vGPU" : "host", next ? "vGPU" : "HOST");
+ dev_priv = pre ? pre->gvt->dev_priv : next->gvt->dev_priv;
+
+ /**
+ * We are using raw mmio access wrapper to improve the
+ * performace for batch mmio read/write, so we need
+ * handle forcewake mannually.
+ */
+ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
/**
* TODO: Optimize for vGPU to vGPU switch by merging
* switch_mmio_to_host() and switch_mmio_to_vgpu().
@@ -382,4 +400,6 @@ void intel_gvt_switch_mmio(struct intel_vgpu *pre,
if (next)
switch_mmio_to_vgpu(next, ring_id);
+
+ intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
}
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
index 4f7057d62d88..391800d2067b 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -184,41 +184,52 @@ static int shadow_context_status_change(struct notifier_block *nb,
return NOTIFY_OK;
}
-static int dispatch_workload(struct intel_vgpu_workload *workload)
+static void shadow_context_descriptor_update(struct i915_gem_context *ctx,
+ struct intel_engine_cs *engine)
+{
+ struct intel_context *ce = &ctx->engine[engine->id];
+ u64 desc = 0;
+
+ desc = ce->lrc_desc;
+
+ /* Update bits 0-11 of the context descriptor which includes flags
+ * like GEN8_CTX_* cached in desc_template
+ */
+ desc &= U64_MAX << 12;
+ desc |= ctx->desc_template & ((1ULL << 12) - 1);
+
+ ce->lrc_desc = desc;
+}
+
+/**
+ * intel_gvt_scan_and_shadow_workload - audit the workload by scanning and
+ * shadow it as well, include ringbuffer,wa_ctx and ctx.
+ * @workload: an abstract entity for each execlist submission.
+ *
+ * This function is called before the workload submitting to i915, to make
+ * sure the content of the workload is valid.
+ */
+int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload)
{
int ring_id = workload->ring_id;
struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx;
struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv;
- struct intel_engine_cs *engine = dev_priv->engine[ring_id];
struct drm_i915_gem_request *rq;
struct intel_vgpu *vgpu = workload->vgpu;
- struct intel_ring *ring;
int ret;
- gvt_dbg_sched("ring id %d prepare to dispatch workload %p\n",
- ring_id, workload);
+ lockdep_assert_held(&dev_priv->drm.struct_mutex);
+
+ if (workload->shadowed)
+ return 0;
shadow_ctx->desc_template &= ~(0x3 << GEN8_CTX_ADDRESSING_MODE_SHIFT);
shadow_ctx->desc_template |= workload->ctx_desc.addressing_mode <<
GEN8_CTX_ADDRESSING_MODE_SHIFT;
- mutex_lock(&dev_priv->drm.struct_mutex);
-
- /* pin shadow context by gvt even the shadow context will be pinned
- * when i915 alloc request. That is because gvt will update the guest
- * context from shadow context when workload is completed, and at that
- * moment, i915 may already unpined the shadow context to make the
- * shadow_ctx pages invalid. So gvt need to pin itself. After update
- * the guest context, gvt can unpin the shadow_ctx safely.
- */
- ring = engine->context_pin(engine, shadow_ctx);
- if (IS_ERR(ring)) {
- ret = PTR_ERR(ring);
- gvt_vgpu_err("fail to pin shadow context\n");
- workload->status = ret;
- mutex_unlock(&dev_priv->drm.struct_mutex);
- return ret;
- }
+ if (!test_and_set_bit(ring_id, vgpu->shadow_ctx_desc_updated))
+ shadow_context_descriptor_update(shadow_ctx,
+ dev_priv->engine[ring_id]);
rq = i915_gem_request_alloc(dev_priv->engine[ring_id], shadow_ctx);
if (IS_ERR(rq)) {
@@ -231,7 +242,7 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
workload->req = i915_gem_request_get(rq);
- ret = intel_gvt_scan_and_shadow_workload(workload);
+ ret = intel_gvt_scan_and_shadow_ringbuffer(workload);
if (ret)
goto out;
@@ -246,25 +257,61 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
if (ret)
goto out;
+ workload->shadowed = true;
+
+out:
+ return ret;
+}
+
+static int dispatch_workload(struct intel_vgpu_workload *workload)
+{
+ int ring_id = workload->ring_id;
+ struct i915_gem_context *shadow_ctx = workload->vgpu->shadow_ctx;
+ struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv;
+ struct intel_engine_cs *engine = dev_priv->engine[ring_id];
+ struct intel_vgpu *vgpu = workload->vgpu;
+ struct intel_ring *ring;
+ int ret = 0;
+
+ gvt_dbg_sched("ring id %d prepare to dispatch workload %p\n",
+ ring_id, workload);
+
+ mutex_lock(&dev_priv->drm.struct_mutex);
+
+ ret = intel_gvt_scan_and_shadow_workload(workload);
+ if (ret)
+ goto out;
+
if (workload->prepare) {
ret = workload->prepare(workload);
if (ret)
goto out;
}
- gvt_dbg_sched("ring id %d submit workload to i915 %p\n",
- ring_id, workload->req);
+ /* pin shadow context by gvt even the shadow context will be pinned
+ * when i915 alloc request. That is because gvt will update the guest
+ * context from shadow context when workload is completed, and at that
+ * moment, i915 may already unpined the shadow context to make the
+ * shadow_ctx pages invalid. So gvt need to pin itself. After update
+ * the guest context, gvt can unpin the shadow_ctx safely.
+ */
+ ring = engine->context_pin(engine, shadow_ctx);
+ if (IS_ERR(ring)) {
+ ret = PTR_ERR(ring);
+ gvt_vgpu_err("fail to pin shadow context\n");
+ goto out;
+ }
- ret = 0;
- workload->dispatched = true;
out:
if (ret)
workload->status = ret;
- if (!IS_ERR_OR_NULL(rq))
- i915_add_request(rq);
- else
- engine->context_unpin(engine, shadow_ctx);
+ if (!IS_ERR_OR_NULL(workload->req)) {
+ gvt_dbg_sched("ring id %d submit workload to i915 %p\n",
+ ring_id, workload->req);
+ i915_add_request(workload->req);
+ workload->dispatched = true;
+ }
mutex_unlock(&dev_priv->drm.struct_mutex);
return ret;
@@ -432,7 +479,8 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id)
i915_gem_request_put(fetch_and_zero(&workload->req));
- if (!workload->status && !vgpu->resetting) {
+ if (!workload->status && !(vgpu->resetting_eng &
+ ENGINE_MASK(ring_id))) {
update_guest_context(workload);
for_each_set_bit(event, workload->pending_events,
@@ -616,7 +664,7 @@ err:
void intel_vgpu_clean_gvt_context(struct intel_vgpu *vgpu)
{
- i915_gem_context_put_unlocked(vgpu->shadow_ctx);
+ i915_gem_context_put(vgpu->shadow_ctx);
}
int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu)
@@ -630,5 +678,7 @@ int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu)
vgpu->shadow_ctx->engine[RCS].initialised = true;
+ bitmap_zero(vgpu->shadow_ctx_desc_updated, I915_NUM_ENGINES);
+
return 0;
}
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.h b/drivers/gpu/drm/i915/gvt/scheduler.h
index 9b6bf51e9b9b..0d431a968a32 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.h
+++ b/drivers/gpu/drm/i915/gvt/scheduler.h
@@ -82,6 +82,7 @@ struct intel_vgpu_workload {
struct drm_i915_gem_request *req;
/* if this workload has been dispatched to i915? */
bool dispatched;
+ bool shadowed;
int status;
struct intel_vgpu_mm *shadow_mm;
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index 90c14e6e3ea0..02c61a1ad56a 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -43,6 +43,7 @@ void populate_pvinfo_page(struct intel_vgpu *vgpu)
vgpu_vreg(vgpu, vgtif_reg(version_minor)) = 0;
vgpu_vreg(vgpu, vgtif_reg(display_ready)) = 0;
vgpu_vreg(vgpu, vgtif_reg(vgt_id)) = vgpu->id;
+ vgpu_vreg(vgpu, vgtif_reg(vgt_caps)) = VGT_CAPS_FULL_48BIT_PPGTT;
vgpu_vreg(vgpu, vgtif_reg(avail_rs.mappable_gmadr.base)) =
vgpu_aperture_gmadr_base(vgpu);
vgpu_vreg(vgpu, vgtif_reg(avail_rs.mappable_gmadr.size)) =
@@ -480,11 +481,13 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr,
{
struct intel_gvt *gvt = vgpu->gvt;
struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
+ unsigned int resetting_eng = dmlr ? ALL_ENGINES : engine_mask;
gvt_dbg_core("------------------------------------------\n");
gvt_dbg_core("resseting vgpu%d, dmlr %d, engine_mask %08x\n",
vgpu->id, dmlr, engine_mask);
- vgpu->resetting = true;
+
+ vgpu->resetting_eng = resetting_eng;
intel_vgpu_stop_schedule(vgpu);
/*
@@ -497,16 +500,16 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr,
mutex_lock(&gvt->lock);
}
- intel_vgpu_reset_execlist(vgpu, dmlr ? ALL_ENGINES : engine_mask);
+ intel_vgpu_reset_execlist(vgpu, resetting_eng);
/* full GPU reset or device model level reset */
if (engine_mask == ALL_ENGINES || dmlr) {
- intel_vgpu_reset_gtt(vgpu, dmlr);
-
/*fence will not be reset during virtual reset */
- if (dmlr)
+ if (dmlr) {
+ intel_vgpu_reset_gtt(vgpu);
intel_vgpu_reset_resource(vgpu);
+ }
intel_vgpu_reset_mmio(vgpu, dmlr);
populate_pvinfo_page(vgpu);
@@ -520,7 +523,7 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr,
}
}
- vgpu->resetting = false;
+ vgpu->resetting_eng = 0;
gvt_dbg_core("reset vgpu%d done\n", vgpu->id);
gvt_dbg_core("------------------------------------------\n");
}
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 00d8967c8512..48572b157222 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -543,75 +543,6 @@ static int i915_gem_gtt_info(struct seq_file *m, void *data)
return 0;
}
-static int i915_gem_pageflip_info(struct seq_file *m, void *data)
-{
- struct drm_i915_private *dev_priv = node_to_i915(m->private);
- struct drm_device *dev = &dev_priv->drm;
- struct intel_crtc *crtc;
- int ret;
-
- ret = mutex_lock_interruptible(&dev->struct_mutex);
- if (ret)
- return ret;
-
- for_each_intel_crtc(dev, crtc) {
- const char pipe = pipe_name(crtc->pipe);
- const char plane = plane_name(crtc->plane);
- struct intel_flip_work *work;
-
- spin_lock_irq(&dev->event_lock);
- work = crtc->flip_work;
- if (work == NULL) {
- seq_printf(m, "No flip due on pipe %c (plane %c)\n",
- pipe, plane);
- } else {
- u32 pending;
- u32 addr;
-
- pending = atomic_read(&work->pending);
- if (pending) {
- seq_printf(m, "Flip ioctl preparing on pipe %c (plane %c)\n",
- pipe, plane);
- } else {
- seq_printf(m, "Flip pending (waiting for vsync) on pipe %c (plane %c)\n",
- pipe, plane);
- }
- if (work->flip_queued_req) {
- struct intel_engine_cs *engine = work->flip_queued_req->engine;
-
- seq_printf(m, "Flip queued on %s at seqno %x, last submitted seqno %x [current breadcrumb %x], completed? %d\n",
- engine->name,
- work->flip_queued_req->global_seqno,
- intel_engine_last_submit(engine),
- intel_engine_get_seqno(engine),
- i915_gem_request_completed(work->flip_queued_req));
- } else
- seq_printf(m, "Flip not associated with any ring\n");
- seq_printf(m, "Flip queued on frame %d, (was ready on frame %d), now %d\n",
- work->flip_queued_vblank,
- work->flip_ready_vblank,
- intel_crtc_get_vblank_counter(crtc));
- seq_printf(m, "%d prepares\n", atomic_read(&work->pending));
-
- if (INTEL_GEN(dev_priv) >= 4)
- addr = I915_HI_DISPBASE(I915_READ(DSPSURF(crtc->plane)));
- else
- addr = I915_READ(DSPADDR(crtc->plane));
- seq_printf(m, "Current scanout address 0x%08x\n", addr);
-
- if (work->pending_flip_obj) {
- seq_printf(m, "New framebuffer address 0x%08lx\n", (long)work->gtt_offset);
- seq_printf(m, "MMIO update completed? %d\n", addr == work->gtt_offset);
- }
- }
- spin_unlock_irq(&dev->event_lock);
- }
-
- mutex_unlock(&dev->struct_mutex);
-
- return 0;
-}
-
static int i915_gem_batch_pool_info(struct seq_file *m, void *data)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -1159,7 +1090,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
reqf = I915_READ(GEN6_RPNSWREQ);
- if (IS_GEN9(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 9)
reqf >>= 23;
else {
reqf &= ~GEN6_TURBO_DISABLE;
@@ -1181,7 +1112,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
rpdownei = I915_READ(GEN6_RP_CUR_DOWN_EI) & GEN6_CURIAVG_MASK;
rpcurdown = I915_READ(GEN6_RP_CUR_DOWN) & GEN6_CURBSYTAVG_MASK;
rpprevdown = I915_READ(GEN6_RP_PREV_DOWN) & GEN6_CURBSYTAVG_MASK;
- if (IS_GEN9(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 9)
cagf = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT;
else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
cagf = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
@@ -1210,7 +1141,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
dev_priv->rps.pm_intrmsk_mbz);
seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status);
seq_printf(m, "Render p-state ratio: %d\n",
- (gt_perf_status & (IS_GEN9(dev_priv) ? 0x1ff00 : 0xff00)) >> 8);
+ (gt_perf_status & (INTEL_GEN(dev_priv) >= 9 ? 0x1ff00 : 0xff00)) >> 8);
seq_printf(m, "Render p-state VID: %d\n",
gt_perf_status & 0xff);
seq_printf(m, "Render p-state limit: %d\n",
@@ -1241,18 +1172,21 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
max_freq = (IS_GEN9_LP(dev_priv) ? rp_state_cap >> 0 :
rp_state_cap >> 16) & 0xff;
- max_freq *= (IS_GEN9_BC(dev_priv) ? GEN9_FREQ_SCALER : 1);
+ max_freq *= (IS_GEN9_BC(dev_priv) ||
+ IS_CANNONLAKE(dev_priv) ? GEN9_FREQ_SCALER : 1);
seq_printf(m, "Lowest (RPN) frequency: %dMHz\n",
intel_gpu_freq(dev_priv, max_freq));
max_freq = (rp_state_cap & 0xff00) >> 8;
- max_freq *= (IS_GEN9_BC(dev_priv) ? GEN9_FREQ_SCALER : 1);
+ max_freq *= (IS_GEN9_BC(dev_priv) ||
+ IS_CANNONLAKE(dev_priv) ? GEN9_FREQ_SCALER : 1);
seq_printf(m, "Nominal (RP1) frequency: %dMHz\n",
intel_gpu_freq(dev_priv, max_freq));
max_freq = (IS_GEN9_LP(dev_priv) ? rp_state_cap >> 16 :
rp_state_cap >> 0) & 0xff;
- max_freq *= (IS_GEN9_BC(dev_priv) ? GEN9_FREQ_SCALER : 1);
+ max_freq *= (IS_GEN9_BC(dev_priv) ||
+ IS_CANNONLAKE(dev_priv) ? GEN9_FREQ_SCALER : 1);
seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n",
intel_gpu_freq(dev_priv, max_freq));
seq_printf(m, "Max overclocked frequency: %dMHz\n",
@@ -1407,6 +1341,23 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused)
return 0;
}
+static int i915_reset_info(struct seq_file *m, void *unused)
+{
+ struct drm_i915_private *dev_priv = node_to_i915(m->private);
+ struct i915_gpu_error *error = &dev_priv->gpu_error;
+ struct intel_engine_cs *engine;
+ enum intel_engine_id id;
+
+ seq_printf(m, "full gpu reset = %u\n", i915_reset_count(error));
+
+ for_each_engine(engine, dev_priv, id) {
+ seq_printf(m, "%s = %u\n", engine->name,
+ i915_reset_engine_count(error, engine));
+ }
+
+ return 0;
+}
+
static int ironlake_drpc_info(struct seq_file *m)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -1838,7 +1789,7 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
if (ret)
goto out;
- if (IS_GEN9_BC(dev_priv)) {
+ if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
/* Convert GT frequency to 50 HZ units */
min_gpu_freq =
dev_priv->rps.min_freq_softlimit / GEN9_FREQ_SCALER;
@@ -1858,7 +1809,8 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
&ia_freq);
seq_printf(m, "%d\t\t%d\t\t\t\t%d\n",
intel_gpu_freq(dev_priv, (gpu_freq *
- (IS_GEN9_BC(dev_priv) ?
+ (IS_GEN9_BC(dev_priv) ||
+ IS_CANNONLAKE(dev_priv) ?
GEN9_FREQ_SCALER : 1))),
((ia_freq >> 0) & 0xff) * 100,
((ia_freq >> 8) & 0xff) * 100);
@@ -1914,7 +1866,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
return ret;
#ifdef CONFIG_DRM_FBDEV_EMULATION
- if (dev_priv->fbdev) {
+ if (dev_priv->fbdev && dev_priv->fbdev->helper.fb) {
fbdev_fb = to_intel_framebuffer(dev_priv->fbdev->helper.fb);
seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ",
@@ -1970,7 +1922,7 @@ static int i915_context_status(struct seq_file *m, void *unused)
if (ret)
return ret;
- list_for_each_entry(ctx, &dev_priv->context_list, link) {
+ list_for_each_entry(ctx, &dev_priv->contexts.list, link) {
seq_printf(m, "HW context %u ", ctx->hw_id);
if (ctx->pid) {
struct task_struct *task;
@@ -2002,12 +1954,6 @@ static int i915_context_status(struct seq_file *m, void *unused)
seq_putc(m, '\n');
}
- seq_printf(m,
- "\tvma hashtable size=%u (actual %lu), count=%u\n",
- ctx->vma_lut.ht_size,
- BIT(ctx->vma_lut.ht_bits),
- ctx->vma_lut.ht_count);
-
seq_putc(m, '\n');
}
@@ -2076,7 +2022,7 @@ static int i915_dump_lrc(struct seq_file *m, void *unused)
if (ret)
return ret;
- list_for_each_entry(ctx, &dev_priv->context_list, link)
+ list_for_each_entry(ctx, &dev_priv->contexts.list, link)
for_each_engine(engine, dev_priv, id)
i915_dump_lrc_obj(m, ctx, engine);
@@ -2310,6 +2256,8 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
seq_printf(m, "GPU busy? %s [%d requests]\n",
yesno(dev_priv->gt.awake), dev_priv->gt.active_requests);
seq_printf(m, "CPU waiting? %d\n", count_irq_waiters(dev_priv));
+ seq_printf(m, "Boosts outstanding? %d\n",
+ atomic_read(&dev_priv->rps.num_waiters));
seq_printf(m, "Frequency requested %d\n",
intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq));
seq_printf(m, " min hard:%d, soft:%d; max soft:%d, hard:%d\n",
@@ -2323,22 +2271,20 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
intel_gpu_freq(dev_priv, dev_priv->rps.boost_freq));
mutex_lock(&dev->filelist_mutex);
- spin_lock(&dev_priv->rps.client_lock);
list_for_each_entry_reverse(file, &dev->filelist, lhead) {
struct drm_i915_file_private *file_priv = file->driver_priv;
struct task_struct *task;
rcu_read_lock();
task = pid_task(file->pid, PIDTYPE_PID);
- seq_printf(m, "%s [%d]: %d boosts%s\n",
+ seq_printf(m, "%s [%d]: %d boosts\n",
task ? task->comm : "<unknown>",
task ? task->pid : -1,
- file_priv->rps.boosts,
- list_empty(&file_priv->rps.link) ? "" : ", active");
+ atomic_read(&file_priv->rps.boosts));
rcu_read_unlock();
}
- seq_printf(m, "Kernel (anonymous) boosts: %d\n", dev_priv->rps.boosts);
- spin_unlock(&dev_priv->rps.client_lock);
+ seq_printf(m, "Kernel (anonymous) boosts: %d\n",
+ atomic_read(&dev_priv->rps.boosts));
mutex_unlock(&dev->filelist_mutex);
if (INTEL_GEN(dev_priv) >= 6 &&
@@ -2831,7 +2777,7 @@ out:
static int i915_energy_uJ(struct seq_file *m, void *data)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
- u64 power;
+ unsigned long long power;
u32 units;
if (INTEL_GEN(dev_priv) < 6)
@@ -2839,15 +2785,18 @@ static int i915_energy_uJ(struct seq_file *m, void *data)
intel_runtime_pm_get(dev_priv);
- rdmsrl(MSR_RAPL_POWER_UNIT, power);
- power = (power & 0x1f00) >> 8;
- units = 1000000 / (1 << power); /* convert to uJ */
+ if (rdmsrl_safe(MSR_RAPL_POWER_UNIT, &power)) {
+ intel_runtime_pm_put(dev_priv);
+ return -ENODEV;
+ }
+
+ units = (power & 0x1f00) >> 8;
power = I915_READ(MCH_SECP_NRG_STTS);
- power *= units;
+ power = (1000000 * power) >> units; /* convert to uJ */
intel_runtime_pm_put(dev_priv);
- seq_printf(m, "%llu", (long long unsigned)power);
+ seq_printf(m, "%llu", power);
return 0;
}
@@ -3289,6 +3238,7 @@ static int i915_display_info(struct seq_file *m, void *unused)
static int i915_engine_info(struct seq_file *m, void *unused)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
+ struct i915_gpu_error *error = &dev_priv->gpu_error;
struct intel_engine_cs *engine;
enum intel_engine_id id;
@@ -3312,6 +3262,8 @@ static int i915_engine_info(struct seq_file *m, void *unused)
engine->hangcheck.seqno,
jiffies_to_msecs(jiffies - engine->hangcheck.action_timestamp),
engine->timeline->inflight_seqnos);
+ seq_printf(m, "\tReset count: %d\n",
+ i915_reset_engine_count(error, engine));
rcu_read_lock();
@@ -3370,8 +3322,10 @@ static int i915_engine_info(struct seq_file *m, void *unused)
ptr = I915_READ(RING_CONTEXT_STATUS_PTR(engine));
read = GEN8_CSB_READ_PTR(ptr);
write = GEN8_CSB_WRITE_PTR(ptr);
- seq_printf(m, "\tExeclist CSB read %d, write %d\n",
- read, write);
+ seq_printf(m, "\tExeclist CSB read %d, write %d, interrupt posted? %s\n",
+ read, write,
+ yesno(test_bit(ENGINE_IRQ_EXECLIST,
+ &engine->irq_posted)));
if (read >= GEN8_CSB_ENTRIES)
read = 0;
if (write >= GEN8_CSB_ENTRIES)
@@ -3758,13 +3712,18 @@ static ssize_t i915_displayport_test_active_write(struct file *file,
drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(connector, &conn_iter) {
+ struct intel_encoder *encoder;
+
if (connector->connector_type !=
DRM_MODE_CONNECTOR_DisplayPort)
continue;
- if (connector->status == connector_status_connected &&
- connector->encoder != NULL) {
- intel_dp = enc_to_intel_dp(connector->encoder);
+ encoder = to_intel_encoder(connector->encoder);
+ if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
+ continue;
+
+ if (encoder && connector->status == connector_status_connected) {
+ intel_dp = enc_to_intel_dp(&encoder->base);
status = kstrtoint(input_buffer, 10, &val);
if (status < 0)
break;
@@ -3796,13 +3755,18 @@ static int i915_displayport_test_active_show(struct seq_file *m, void *data)
drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(connector, &conn_iter) {
+ struct intel_encoder *encoder;
+
if (connector->connector_type !=
DRM_MODE_CONNECTOR_DisplayPort)
continue;
- if (connector->status == connector_status_connected &&
- connector->encoder != NULL) {
- intel_dp = enc_to_intel_dp(connector->encoder);
+ encoder = to_intel_encoder(connector->encoder);
+ if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
+ continue;
+
+ if (encoder && connector->status == connector_status_connected) {
+ intel_dp = enc_to_intel_dp(&encoder->base);
if (intel_dp->compliance.test_active)
seq_puts(m, "1");
else
@@ -3842,13 +3806,18 @@ static int i915_displayport_test_data_show(struct seq_file *m, void *data)
drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(connector, &conn_iter) {
+ struct intel_encoder *encoder;
+
if (connector->connector_type !=
DRM_MODE_CONNECTOR_DisplayPort)
continue;
- if (connector->status == connector_status_connected &&
- connector->encoder != NULL) {
- intel_dp = enc_to_intel_dp(connector->encoder);
+ encoder = to_intel_encoder(connector->encoder);
+ if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
+ continue;
+
+ if (encoder && connector->status == connector_status_connected) {
+ intel_dp = enc_to_intel_dp(&encoder->base);
if (intel_dp->compliance.test_type ==
DP_TEST_LINK_EDID_READ)
seq_printf(m, "%lx",
@@ -3895,13 +3864,18 @@ static int i915_displayport_test_type_show(struct seq_file *m, void *data)
drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(connector, &conn_iter) {
+ struct intel_encoder *encoder;
+
if (connector->connector_type !=
DRM_MODE_CONNECTOR_DisplayPort)
continue;
- if (connector->status == connector_status_connected &&
- connector->encoder != NULL) {
- intel_dp = enc_to_intel_dp(connector->encoder);
+ encoder = to_intel_encoder(connector->encoder);
+ if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
+ continue;
+
+ if (encoder && connector->status == connector_status_connected) {
+ intel_dp = enc_to_intel_dp(&encoder->base);
seq_printf(m, "%02lx", intel_dp->compliance.test_type);
} else
seq_puts(m, "0");
@@ -4580,7 +4554,7 @@ static void gen9_sseu_device_status(struct drm_i915_private *dev_priv,
sseu->slice_mask |= BIT(s);
- if (IS_GEN9_BC(dev_priv))
+ if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv))
sseu->subslice_mask =
INTEL_INFO(dev_priv)->sseu.subslice_mask;
@@ -4810,7 +4784,6 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_gem_gtt", i915_gem_gtt_info, 0},
{"i915_gem_pin_display", i915_gem_gtt_info, 0, (void *)1},
{"i915_gem_stolen", i915_gem_stolen_list_info },
- {"i915_gem_pageflip", i915_gem_pageflip_info, 0},
{"i915_gem_request", i915_gem_request_info, 0},
{"i915_gem_seqno", i915_gem_seqno_info, 0},
{"i915_gem_fence_regs", i915_gem_fence_regs_info, 0},
@@ -4824,6 +4797,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_huc_load_status", i915_huc_load_status_info, 0},
{"i915_frequency_info", i915_frequency_info, 0},
{"i915_hangcheck_info", i915_hangcheck_info, 0},
+ {"i915_reset_info", i915_reset_info, 0},
{"i915_drpc_info", i915_drpc_info, 0},
{"i915_emon_status", i915_emon_status, 0},
{"i915_ring_freq_table", i915_ring_freq_table, 0},
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index fc307e03943c..43100229613c 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -132,9 +132,13 @@ static enum intel_pch intel_virt_detect_pch(struct drm_i915_private *dev_priv)
DRM_DEBUG_KMS("Assuming Ibex Peak PCH\n");
} else if (IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv)) {
ret = PCH_CPT;
- DRM_DEBUG_KMS("Assuming CouarPoint PCH\n");
+ DRM_DEBUG_KMS("Assuming CougarPoint PCH\n");
} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
ret = PCH_LPT;
+ if (IS_HSW_ULT(dev_priv) || IS_BDW_ULT(dev_priv))
+ dev_priv->pch_id = INTEL_PCH_LPT_LP_DEVICE_ID_TYPE;
+ else
+ dev_priv->pch_id = INTEL_PCH_LPT_DEVICE_ID_TYPE;
DRM_DEBUG_KMS("Assuming LynxPoint PCH\n");
} else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
ret = PCH_SPT;
@@ -173,29 +177,25 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv)
while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) {
if (pch->vendor == PCI_VENDOR_ID_INTEL) {
unsigned short id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
- unsigned short id_ext = pch->device &
- INTEL_PCH_DEVICE_ID_MASK_EXT;
+
+ dev_priv->pch_id = id;
if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id;
dev_priv->pch_type = PCH_IBX;
DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
WARN_ON(!IS_GEN5(dev_priv));
} else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id;
dev_priv->pch_type = PCH_CPT;
DRM_DEBUG_KMS("Found CougarPoint PCH\n");
- WARN_ON(!(IS_GEN6(dev_priv) ||
- IS_IVYBRIDGE(dev_priv)));
+ WARN_ON(!IS_GEN6(dev_priv) &&
+ !IS_IVYBRIDGE(dev_priv));
} else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
/* PantherPoint is CPT compatible */
- dev_priv->pch_id = id;
dev_priv->pch_type = PCH_CPT;
DRM_DEBUG_KMS("Found PantherPoint PCH\n");
- WARN_ON(!(IS_GEN6(dev_priv) ||
- IS_IVYBRIDGE(dev_priv)));
+ WARN_ON(!IS_GEN6(dev_priv) &&
+ !IS_IVYBRIDGE(dev_priv));
} else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id;
dev_priv->pch_type = PCH_LPT;
DRM_DEBUG_KMS("Found LynxPoint PCH\n");
WARN_ON(!IS_HASWELL(dev_priv) &&
@@ -203,51 +203,60 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv)
WARN_ON(IS_HSW_ULT(dev_priv) ||
IS_BDW_ULT(dev_priv));
} else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id;
dev_priv->pch_type = PCH_LPT;
DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
WARN_ON(!IS_HASWELL(dev_priv) &&
!IS_BROADWELL(dev_priv));
WARN_ON(!IS_HSW_ULT(dev_priv) &&
!IS_BDW_ULT(dev_priv));
+ } else if (id == INTEL_PCH_WPT_DEVICE_ID_TYPE) {
+ /* WildcatPoint is LPT compatible */
+ dev_priv->pch_type = PCH_LPT;
+ DRM_DEBUG_KMS("Found WildcatPoint PCH\n");
+ WARN_ON(!IS_HASWELL(dev_priv) &&
+ !IS_BROADWELL(dev_priv));
+ WARN_ON(IS_HSW_ULT(dev_priv) ||
+ IS_BDW_ULT(dev_priv));
+ } else if (id == INTEL_PCH_WPT_LP_DEVICE_ID_TYPE) {
+ /* WildcatPoint is LPT compatible */
+ dev_priv->pch_type = PCH_LPT;
+ DRM_DEBUG_KMS("Found WildcatPoint LP PCH\n");
+ WARN_ON(!IS_HASWELL(dev_priv) &&
+ !IS_BROADWELL(dev_priv));
+ WARN_ON(!IS_HSW_ULT(dev_priv) &&
+ !IS_BDW_ULT(dev_priv));
} else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id;
dev_priv->pch_type = PCH_SPT;
DRM_DEBUG_KMS("Found SunrisePoint PCH\n");
WARN_ON(!IS_SKYLAKE(dev_priv) &&
!IS_KABYLAKE(dev_priv));
- } else if (id_ext == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id_ext;
+ } else if (id == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) {
dev_priv->pch_type = PCH_SPT;
DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n");
WARN_ON(!IS_SKYLAKE(dev_priv) &&
!IS_KABYLAKE(dev_priv));
} else if (id == INTEL_PCH_KBP_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id;
dev_priv->pch_type = PCH_KBP;
- DRM_DEBUG_KMS("Found KabyPoint PCH\n");
+ DRM_DEBUG_KMS("Found Kaby Lake PCH (KBP)\n");
WARN_ON(!IS_SKYLAKE(dev_priv) &&
!IS_KABYLAKE(dev_priv));
} else if (id == INTEL_PCH_CNP_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id;
dev_priv->pch_type = PCH_CNP;
- DRM_DEBUG_KMS("Found CannonPoint PCH\n");
+ DRM_DEBUG_KMS("Found Cannon Lake PCH (CNP)\n");
WARN_ON(!IS_CANNONLAKE(dev_priv) &&
!IS_COFFEELAKE(dev_priv));
- } else if (id_ext == INTEL_PCH_CNP_LP_DEVICE_ID_TYPE) {
- dev_priv->pch_id = id_ext;
+ } else if (id == INTEL_PCH_CNP_LP_DEVICE_ID_TYPE) {
dev_priv->pch_type = PCH_CNP;
- DRM_DEBUG_KMS("Found CannonPoint LP PCH\n");
+ DRM_DEBUG_KMS("Found Cannon Lake LP PCH (CNP-LP)\n");
WARN_ON(!IS_CANNONLAKE(dev_priv) &&
!IS_COFFEELAKE(dev_priv));
- } else if ((id == INTEL_PCH_P2X_DEVICE_ID_TYPE) ||
- (id == INTEL_PCH_P3X_DEVICE_ID_TYPE) ||
- ((id == INTEL_PCH_QEMU_DEVICE_ID_TYPE) &&
+ } else if (id == INTEL_PCH_P2X_DEVICE_ID_TYPE ||
+ id == INTEL_PCH_P3X_DEVICE_ID_TYPE ||
+ (id == INTEL_PCH_QEMU_DEVICE_ID_TYPE &&
pch->subsystem_vendor ==
PCI_SUBVENDOR_ID_REDHAT_QUMRANET &&
pch->subsystem_device ==
PCI_SUBDEVICE_ID_QEMU)) {
- dev_priv->pch_id = id;
dev_priv->pch_type =
intel_virt_detect_pch(dev_priv);
} else
@@ -331,6 +340,8 @@ static int i915_getparam(struct drm_device *dev, void *data,
break;
case I915_PARAM_HAS_GPU_RESET:
value = i915.enable_hangcheck && intel_has_gpu_reset(dev_priv);
+ if (value && intel_has_reset_engine(dev_priv))
+ value = 2;
break;
case I915_PARAM_HAS_RESOURCE_STREAMER:
value = HAS_RESOURCE_STREAMER(dev_priv);
@@ -377,6 +388,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_HAS_EXEC_FENCE:
case I915_PARAM_HAS_EXEC_CAPTURE:
case I915_PARAM_HAS_EXEC_BATCH_FIRST:
+ case I915_PARAM_HAS_EXEC_FENCE_ARRAY:
/* For the time being all of these are always true;
* if some supported hardware does not have one of these
* features this value needs to be provided from
@@ -585,16 +597,19 @@ static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
static void i915_gem_fini(struct drm_i915_private *dev_priv)
{
+ /* Flush any outstanding unpin_work. */
+ i915_gem_drain_workqueue(dev_priv);
+
mutex_lock(&dev_priv->drm.struct_mutex);
intel_uc_fini_hw(dev_priv);
i915_gem_cleanup_engines(dev_priv);
- i915_gem_context_fini(dev_priv);
+ i915_gem_contexts_fini(dev_priv);
i915_gem_cleanup_userptr(dev_priv);
mutex_unlock(&dev_priv->drm.struct_mutex);
i915_gem_drain_freed_objects(dev_priv);
- WARN_ON(!list_empty(&dev_priv->context_list));
+ WARN_ON(!list_empty(&dev_priv->contexts.list));
}
static int i915_load_modeset_init(struct drm_device *dev)
@@ -862,7 +877,6 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,
spin_lock_init(&dev_priv->uncore.lock);
spin_lock_init(&dev_priv->mm.object_stat_lock);
- spin_lock_init(&dev_priv->mmio_flip_lock);
mutex_init(&dev_priv->sb_lock);
mutex_init(&dev_priv->modeset_restore_lock);
mutex_init(&dev_priv->av_mutex);
@@ -1227,6 +1241,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
*/
static void i915_driver_unregister(struct drm_i915_private *dev_priv)
{
+ intel_fbdev_unregister(dev_priv);
intel_audio_deinit(dev_priv);
intel_gpu_ips_teardown();
@@ -1319,7 +1334,7 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent)
ret = i915_load_modeset_init(&dev_priv->drm);
if (ret < 0)
- goto out_cleanup_vblank;
+ goto out_cleanup_hw;
i915_driver_register(dev_priv);
@@ -1336,8 +1351,6 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0;
-out_cleanup_vblank:
- drm_vblank_cleanup(&dev_priv->drm);
out_cleanup_hw:
i915_driver_cleanup_hw(dev_priv);
out_cleanup_mmio:
@@ -1360,7 +1373,7 @@ void i915_driver_unload(struct drm_device *dev)
struct drm_i915_private *dev_priv = to_i915(dev);
struct pci_dev *pdev = dev_priv->drm.pdev;
- intel_fbdev_fini(dev);
+ i915_driver_unregister(dev_priv);
if (i915_gem_suspend(dev_priv))
DRM_ERROR("failed to idle hardware; continuing to unload!\n");
@@ -1371,10 +1384,6 @@ void i915_driver_unload(struct drm_device *dev)
intel_gvt_cleanup(dev_priv);
- i915_driver_unregister(dev_priv);
-
- drm_vblank_cleanup(dev);
-
intel_modeset_cleanup(dev);
/*
@@ -1400,9 +1409,6 @@ void i915_driver_unload(struct drm_device *dev)
cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work);
i915_reset_error_state(dev_priv);
- /* Flush any outstanding unpin_work. */
- drain_workqueue(dev_priv->wq);
-
i915_gem_fini(dev_priv);
intel_uc_fini_fw(dev_priv);
intel_fbc_cleanup_cfb(dev_priv);
@@ -1427,9 +1433,10 @@ static void i915_driver_release(struct drm_device *dev)
static int i915_driver_open(struct drm_device *dev, struct drm_file *file)
{
+ struct drm_i915_private *i915 = to_i915(dev);
int ret;
- ret = i915_gem_open(dev, file);
+ ret = i915_gem_open(i915, file);
if (ret)
return ret;
@@ -1459,7 +1466,7 @@ static void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
struct drm_i915_file_private *file_priv = file->driver_priv;
mutex_lock(&dev->struct_mutex);
- i915_gem_context_close(dev, file);
+ i915_gem_context_close(file);
i915_gem_release(dev, file);
mutex_unlock(&dev->struct_mutex);
@@ -1825,7 +1832,8 @@ static int i915_resume_switcheroo(struct drm_device *dev)
/**
* i915_reset - reset chip after a hang
- * @dev_priv: device private to reset
+ * @i915: #drm_i915_private to reset
+ * @flags: Instructions
*
* Reset the chip. Useful if a hang is detected. Marks the device as wedged
* on failure.
@@ -1840,33 +1848,34 @@ static int i915_resume_switcheroo(struct drm_device *dev)
* - re-init interrupt state
* - re-init display
*/
-void i915_reset(struct drm_i915_private *dev_priv)
+void i915_reset(struct drm_i915_private *i915, unsigned int flags)
{
- struct i915_gpu_error *error = &dev_priv->gpu_error;
+ struct i915_gpu_error *error = &i915->gpu_error;
int ret;
- lockdep_assert_held(&dev_priv->drm.struct_mutex);
+ lockdep_assert_held(&i915->drm.struct_mutex);
GEM_BUG_ON(!test_bit(I915_RESET_BACKOFF, &error->flags));
if (!test_bit(I915_RESET_HANDOFF, &error->flags))
return;
/* Clear any previous failed attempts at recovery. Time to try again. */
- if (!i915_gem_unset_wedged(dev_priv))
+ if (!i915_gem_unset_wedged(i915))
goto wakeup;
+ if (!(flags & I915_RESET_QUIET))
+ dev_notice(i915->drm.dev, "Resetting chip after gpu hang\n");
error->reset_count++;
- pr_notice("drm/i915: Resetting chip after gpu hang\n");
- disable_irq(dev_priv->drm.irq);
- ret = i915_gem_reset_prepare(dev_priv);
+ disable_irq(i915->drm.irq);
+ ret = i915_gem_reset_prepare(i915);
if (ret) {
DRM_ERROR("GPU recovery failed\n");
- intel_gpu_reset(dev_priv, ALL_ENGINES);
+ intel_gpu_reset(i915, ALL_ENGINES);
goto error;
}
- ret = intel_gpu_reset(dev_priv, ALL_ENGINES);
+ ret = intel_gpu_reset(i915, ALL_ENGINES);
if (ret) {
if (ret != -ENODEV)
DRM_ERROR("Failed to reset chip: %i\n", ret);
@@ -1875,8 +1884,8 @@ void i915_reset(struct drm_i915_private *dev_priv)
goto error;
}
- i915_gem_reset(dev_priv);
- intel_overlay_reset(dev_priv);
+ i915_gem_reset(i915);
+ intel_overlay_reset(i915);
/* Ok, now get things going again... */
@@ -1892,17 +1901,17 @@ void i915_reset(struct drm_i915_private *dev_priv)
* was running at the time of the reset (i.e. we weren't VT
* switched away).
*/
- ret = i915_gem_init_hw(dev_priv);
+ ret = i915_gem_init_hw(i915);
if (ret) {
DRM_ERROR("Failed hw init on reset %d\n", ret);
goto error;
}
- i915_queue_hangcheck(dev_priv);
+ i915_queue_hangcheck(i915);
finish:
- i915_gem_reset_finish(dev_priv);
- enable_irq(dev_priv->drm.irq);
+ i915_gem_reset_finish(i915);
+ enable_irq(i915->drm.irq);
wakeup:
clear_bit(I915_RESET_HANDOFF, &error->flags);
@@ -1910,10 +1919,74 @@ wakeup:
return;
error:
- i915_gem_set_wedged(dev_priv);
+ i915_gem_set_wedged(i915);
+ i915_gem_retire_requests(i915);
goto finish;
}
+/**
+ * i915_reset_engine - reset GPU engine to recover from a hang
+ * @engine: engine to reset
+ * @flags: options
+ *
+ * Reset a specific GPU engine. Useful if a hang is detected.
+ * Returns zero on successful reset or otherwise an error code.
+ *
+ * Procedure is:
+ * - identifies the request that caused the hang and it is dropped
+ * - reset engine (which will force the engine to idle)
+ * - re-init/configure engine
+ */
+int i915_reset_engine(struct intel_engine_cs *engine, unsigned int flags)
+{
+ struct i915_gpu_error *error = &engine->i915->gpu_error;
+ struct drm_i915_gem_request *active_request;
+ int ret;
+
+ GEM_BUG_ON(!test_bit(I915_RESET_ENGINE + engine->id, &error->flags));
+
+ if (!(flags & I915_RESET_QUIET)) {
+ dev_notice(engine->i915->drm.dev,
+ "Resetting %s after gpu hang\n", engine->name);
+ }
+ error->reset_engine_count[engine->id]++;
+
+ active_request = i915_gem_reset_prepare_engine(engine);
+ if (IS_ERR(active_request)) {
+ DRM_DEBUG_DRIVER("Previous reset failed, promote to full reset\n");
+ ret = PTR_ERR(active_request);
+ goto out;
+ }
+
+ ret = intel_gpu_reset(engine->i915, intel_engine_flag(engine));
+ if (ret) {
+ /* If we fail here, we expect to fallback to a global reset */
+ DRM_DEBUG_DRIVER("Failed to reset %s, ret=%d\n",
+ engine->name, ret);
+ goto out;
+ }
+
+ /*
+ * The request that caused the hang is stuck on elsp, we know the
+ * active request and can drop it, adjust head to skip the offending
+ * request to resume executing remaining requests in the queue.
+ */
+ i915_gem_reset_engine(engine, active_request);
+
+ /*
+ * The engine and its registers (and workarounds in case of render)
+ * have been reset to their default values. Follow the init_ring
+ * process to program RING_MODE, HWSP and re-enable submission.
+ */
+ ret = engine->init_hw(engine);
+ if (ret)
+ goto out;
+
+out:
+ i915_gem_reset_finish_engine(engine);
+ return ret;
+}
+
static int i915_pm_suspend(struct device *kdev)
{
struct pci_dev *pdev = to_pci_dev(kdev);
@@ -2657,6 +2730,8 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(I915_PERF_OPEN, i915_perf_open_ioctl, DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(I915_PERF_ADD_CONFIG, i915_perf_add_config_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(I915_PERF_REMOVE_CONFIG, i915_perf_remove_config_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
};
static struct drm_driver driver = {
@@ -2665,12 +2740,11 @@ static struct drm_driver driver = {
*/
.driver_features =
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME |
- DRIVER_RENDER | DRIVER_MODESET | DRIVER_ATOMIC,
+ DRIVER_RENDER | DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_SYNCOBJ,
.release = i915_driver_release,
.open = i915_driver_open,
.lastclose = i915_driver_lastclose,
.postclose = i915_driver_postclose,
- .set_busid = drm_pci_set_busid,
.gem_close_object = i915_gem_close_object,
.gem_free_object_unlocked = i915_gem_free_object,
@@ -2683,7 +2757,6 @@ static struct drm_driver driver = {
.dumb_create = i915_gem_dumb_create,
.dumb_map_offset = i915_gem_mmap_gtt,
- .dumb_destroy = drm_gem_dumb_destroy,
.ioctls = i915_ioctls,
.num_ioctls = ARRAY_SIZE(i915_ioctls),
.fops = &i915_driver_fops,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e1f7c97a338a..60267e375e88 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -80,8 +80,8 @@
#define DRIVER_NAME "i915"
#define DRIVER_DESC "Intel Graphics"
-#define DRIVER_DATE "20170619"
-#define DRIVER_TIMESTAMP 1497857498
+#define DRIVER_DATE "20170818"
+#define DRIVER_TIMESTAMP 1503088845
/* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and
* WARN_ON()) for hw state sanity checks to check for unexpected conditions
@@ -122,7 +122,7 @@ static inline bool is_fixed16_zero(uint_fixed_16_16_t val)
return false;
}
-static inline uint_fixed_16_16_t u32_to_fixed_16_16(uint32_t val)
+static inline uint_fixed_16_16_t u32_to_fixed16(uint32_t val)
{
uint_fixed_16_16_t fp;
@@ -132,17 +132,17 @@ static inline uint_fixed_16_16_t u32_to_fixed_16_16(uint32_t val)
return fp;
}
-static inline uint32_t fixed_16_16_to_u32_round_up(uint_fixed_16_16_t fp)
+static inline uint32_t fixed16_to_u32_round_up(uint_fixed_16_16_t fp)
{
return DIV_ROUND_UP(fp.val, 1 << 16);
}
-static inline uint32_t fixed_16_16_to_u32(uint_fixed_16_16_t fp)
+static inline uint32_t fixed16_to_u32(uint_fixed_16_16_t fp)
{
return fp.val >> 16;
}
-static inline uint_fixed_16_16_t min_fixed_16_16(uint_fixed_16_16_t min1,
+static inline uint_fixed_16_16_t min_fixed16(uint_fixed_16_16_t min1,
uint_fixed_16_16_t min2)
{
uint_fixed_16_16_t min;
@@ -151,7 +151,7 @@ static inline uint_fixed_16_16_t min_fixed_16_16(uint_fixed_16_16_t min1,
return min;
}
-static inline uint_fixed_16_16_t max_fixed_16_16(uint_fixed_16_16_t max1,
+static inline uint_fixed_16_16_t max_fixed16(uint_fixed_16_16_t max1,
uint_fixed_16_16_t max2)
{
uint_fixed_16_16_t max;
@@ -160,6 +160,14 @@ static inline uint_fixed_16_16_t max_fixed_16_16(uint_fixed_16_16_t max1,
return max;
}
+static inline uint_fixed_16_16_t clamp_u64_to_fixed16(uint64_t val)
+{
+ uint_fixed_16_16_t fp;
+ WARN_ON(val >> 32);
+ fp.val = clamp_t(uint32_t, val, 0, ~0);
+ return fp;
+}
+
static inline uint32_t div_round_up_fixed16(uint_fixed_16_16_t val,
uint_fixed_16_16_t d)
{
@@ -170,48 +178,30 @@ static inline uint32_t mul_round_up_u32_fixed16(uint32_t val,
uint_fixed_16_16_t mul)
{
uint64_t intermediate_val;
- uint32_t result;
intermediate_val = (uint64_t) val * mul.val;
intermediate_val = DIV_ROUND_UP_ULL(intermediate_val, 1 << 16);
WARN_ON(intermediate_val >> 32);
- result = clamp_t(uint32_t, intermediate_val, 0, ~0);
- return result;
+ return clamp_t(uint32_t, intermediate_val, 0, ~0);
}
static inline uint_fixed_16_16_t mul_fixed16(uint_fixed_16_16_t val,
uint_fixed_16_16_t mul)
{
uint64_t intermediate_val;
- uint_fixed_16_16_t fp;
intermediate_val = (uint64_t) val.val * mul.val;
intermediate_val = intermediate_val >> 16;
- WARN_ON(intermediate_val >> 32);
- fp.val = clamp_t(uint32_t, intermediate_val, 0, ~0);
- return fp;
+ return clamp_u64_to_fixed16(intermediate_val);
}
-static inline uint_fixed_16_16_t fixed_16_16_div(uint32_t val, uint32_t d)
+static inline uint_fixed_16_16_t div_fixed16(uint32_t val, uint32_t d)
{
- uint_fixed_16_16_t fp, res;
-
- fp = u32_to_fixed_16_16(val);
- res.val = DIV_ROUND_UP(fp.val, d);
- return res;
-}
-
-static inline uint_fixed_16_16_t fixed_16_16_div_u64(uint32_t val, uint32_t d)
-{
- uint_fixed_16_16_t res;
uint64_t interm_val;
interm_val = (uint64_t)val << 16;
interm_val = DIV_ROUND_UP_ULL(interm_val, d);
- WARN_ON(interm_val >> 32);
- res.val = (uint32_t) interm_val;
-
- return res;
+ return clamp_u64_to_fixed16(interm_val);
}
static inline uint32_t div_round_up_u32_fixed16(uint32_t val,
@@ -225,16 +215,32 @@ static inline uint32_t div_round_up_u32_fixed16(uint32_t val,
return clamp_t(uint32_t, interm_val, 0, ~0);
}
-static inline uint_fixed_16_16_t mul_u32_fixed_16_16(uint32_t val,
+static inline uint_fixed_16_16_t mul_u32_fixed16(uint32_t val,
uint_fixed_16_16_t mul)
{
uint64_t intermediate_val;
- uint_fixed_16_16_t fp;
intermediate_val = (uint64_t) val * mul.val;
- WARN_ON(intermediate_val >> 32);
- fp.val = (uint32_t) intermediate_val;
- return fp;
+ return clamp_u64_to_fixed16(intermediate_val);
+}
+
+static inline uint_fixed_16_16_t add_fixed16(uint_fixed_16_16_t add1,
+ uint_fixed_16_16_t add2)
+{
+ uint64_t interm_sum;
+
+ interm_sum = (uint64_t) add1.val + add2.val;
+ return clamp_u64_to_fixed16(interm_sum);
+}
+
+static inline uint_fixed_16_16_t add_fixed16_u32(uint_fixed_16_16_t add1,
+ uint32_t add2)
+{
+ uint64_t interm_sum;
+ uint_fixed_16_16_t interm_add2 = u32_to_fixed16(add2);
+
+ interm_sum = (uint64_t) add1.val + interm_add2.val;
+ return clamp_u64_to_fixed16(interm_sum);
}
static inline const char *yesno(bool v)
@@ -584,8 +590,7 @@ struct drm_i915_file_private {
struct idr context_idr;
struct intel_rps_client {
- struct list_head link;
- unsigned boosts;
+ atomic_t boosts;
} rps;
unsigned int bsd_engine;
@@ -597,7 +602,7 @@ struct drm_i915_file_private {
* to limit the badly behaving clients access to gpu.
*/
#define I915_MAX_CLIENT_CONTEXT_BANS 3
- int context_bans;
+ atomic_t context_bans;
};
/* Used by dp and fdi links */
@@ -641,6 +646,7 @@ struct intel_opregion {
u32 swsci_sbcb_sub_functions;
struct opregion_asle *asle;
void *rvda;
+ void *vbt_firmware;
const void *vbt;
u32 vbt_size;
u32 *lid_state;
@@ -710,11 +716,6 @@ struct drm_i915_display_funcs {
void (*fdi_link_train)(struct intel_crtc *crtc,
const struct intel_crtc_state *crtc_state);
void (*init_clock_gating)(struct drm_i915_private *dev_priv);
- int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags);
void (*hpd_irq_setup)(struct drm_i915_private *dev_priv);
/* clock updates for mode set */
/* cursor updates */
@@ -753,6 +754,7 @@ struct intel_csr {
func(has_csr); \
func(has_ddi); \
func(has_dp_mst); \
+ func(has_reset_engine); \
func(has_fbc); \
func(has_fpga_dbg); \
func(has_full_ppgtt); \
@@ -917,6 +919,7 @@ struct i915_gpu_state {
enum intel_engine_hangcheck_action hangcheck_action;
struct i915_address_space *vm;
int num_requests;
+ u32 reset_count;
/* position of active request inside the ring */
u32 rq_head, rq_post, rq_tail;
@@ -1056,6 +1059,11 @@ struct intel_fbc {
bool underrun_detected;
struct work_struct underrun_work;
+ /*
+ * Due to the atomic rules we can't access some structures without the
+ * appropriate locking, so we cache information here in order to avoid
+ * these problems.
+ */
struct intel_fbc_state_cache {
struct i915_vma *vma;
@@ -1077,6 +1085,13 @@ struct intel_fbc {
} fb;
} state_cache;
+ /*
+ * This structure contains everything that's relevant to program the
+ * hardware registers. When we want to figure out if we need to disable
+ * and re-enable FBC for a new configuration we just check if there's
+ * something different in the struct. The genx_fbc_activate functions
+ * are supposed to read from it in order to program the registers.
+ */
struct intel_fbc_reg_params {
struct i915_vma *vma;
@@ -1149,11 +1164,11 @@ struct i915_psr {
enum intel_pch {
PCH_NONE = 0, /* No PCH present */
PCH_IBX, /* Ibexpeak PCH */
- PCH_CPT, /* Cougarpoint PCH */
- PCH_LPT, /* Lynxpoint PCH */
+ PCH_CPT, /* Cougarpoint/Pantherpoint PCH */
+ PCH_LPT, /* Lynxpoint/Wildcatpoint PCH */
PCH_SPT, /* Sunrisepoint PCH */
- PCH_KBP, /* Kabypoint PCH */
- PCH_CNP, /* Cannonpoint PCH */
+ PCH_KBP, /* Kaby Lake PCH */
+ PCH_CNP, /* Cannon Lake PCH */
PCH_NOP,
};
@@ -1166,6 +1181,7 @@ enum intel_sbi_destination {
#define QUIRK_INVERT_BRIGHTNESS (1<<2)
#define QUIRK_BACKLIGHT_PRESENT (1<<3)
#define QUIRK_PIN_SWIZZLED_PAGES (1<<5)
+#define QUIRK_INCREASE_T12_DELAY (1<<6)
struct intel_fbdev;
struct intel_fbc_work;
@@ -1301,13 +1317,10 @@ struct intel_gen6_power_mgmt {
int last_adj;
enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
- spinlock_t client_lock;
- struct list_head clients;
- bool client_boost;
-
bool enabled;
struct delayed_work autoenable_work;
- unsigned boosts;
+ atomic_t num_waiters;
+ atomic_t boosts;
/* manual wa residency calculations */
struct intel_rps_ei ei;
@@ -1383,12 +1396,23 @@ struct i915_power_well {
bool hw_enabled;
u64 domains;
/* unique identifier for this power well */
- unsigned long id;
+ enum i915_power_well_id id;
/*
* Arbitraty data associated with this power well. Platform and power
* well specific.
*/
- unsigned long data;
+ union {
+ struct {
+ enum dpio_phy phy;
+ } bxt;
+ struct {
+ /* Mask of pipes whose IRQ logic is backed by the pw */
+ u8 irq_pipe_mask;
+ /* The pw is backing the VGA functionality */
+ bool has_vga:1;
+ bool has_fuses:1;
+ } hsw;
+ };
const struct i915_power_well_ops *ops;
};
@@ -1505,6 +1529,8 @@ struct i915_gpu_error {
/* Protected by the above dev->gpu_error.lock. */
struct i915_gpu_state *first_error;
+ atomic_t pending_fb_pin;
+
unsigned long missed_irq_rings;
/**
@@ -1550,6 +1576,12 @@ struct i915_gpu_error {
* inspect the bit and do the reset directly, otherwise the worker
* waits for the struct_mutex.
*
+ * #I915_RESET_ENGINE[num_engines] - Since the driver doesn't need to
+ * acquire the struct_mutex to reset an engine, we need an explicit
+ * flag to prevent two concurrent reset attempts in the same engine.
+ * As the number of engines continues to grow, allocate the flags from
+ * the most significant bits.
+ *
* #I915_WEDGED - If reset fails and we can no longer use the GPU,
* we set the #I915_WEDGED bit. Prior to command submission, e.g.
* i915_gem_request_alloc(), this bit is checked and the sequence
@@ -1558,7 +1590,12 @@ struct i915_gpu_error {
unsigned long flags;
#define I915_RESET_BACKOFF 0
#define I915_RESET_HANDOFF 1
+#define I915_RESET_MODESET 2
#define I915_WEDGED (BITS_PER_LONG - 1)
+#define I915_RESET_ENGINE (I915_WEDGED - I915_NUM_ENGINES)
+
+ /** Number of times an engine has been reset */
+ u32 reset_engine_count[I915_NUM_ENGINES];
/**
* Waitqueue to signal when a hang is detected. Used to for waiters
@@ -1869,6 +1906,7 @@ struct i915_workarounds {
struct i915_virtual_gpu {
bool active;
+ u32 caps;
};
/* used in computing the new watermarks state */
@@ -1888,6 +1926,24 @@ struct i915_oa_reg {
u32 value;
};
+struct i915_oa_config {
+ char uuid[UUID_STRING_LEN + 1];
+ int id;
+
+ const struct i915_oa_reg *mux_regs;
+ u32 mux_regs_len;
+ const struct i915_oa_reg *b_counter_regs;
+ u32 b_counter_regs_len;
+ const struct i915_oa_reg *flex_regs;
+ u32 flex_regs_len;
+
+ struct attribute_group sysfs_metric;
+ struct attribute *attrs[2];
+ struct device_attribute sysfs_metric_id;
+
+ atomic_t ref_count;
+};
+
struct i915_perf_stream;
/**
@@ -2000,6 +2056,11 @@ struct i915_perf_stream {
* type of configured stream.
*/
const struct i915_perf_stream_ops *ops;
+
+ /**
+ * @oa_config: The OA configuration used by the stream.
+ */
+ struct i915_oa_config *oa_config;
};
/**
@@ -2007,6 +2068,25 @@ struct i915_perf_stream {
*/
struct i915_oa_ops {
/**
+ * @is_valid_b_counter_reg: Validates register's address for
+ * programming boolean counters for a particular platform.
+ */
+ bool (*is_valid_b_counter_reg)(struct drm_i915_private *dev_priv,
+ u32 addr);
+
+ /**
+ * @is_valid_mux_reg: Validates register's address for programming mux
+ * for a particular platform.
+ */
+ bool (*is_valid_mux_reg)(struct drm_i915_private *dev_priv, u32 addr);
+
+ /**
+ * @is_valid_flex_reg: Validates register's address for programming
+ * flex EU filtering for a particular platform.
+ */
+ bool (*is_valid_flex_reg)(struct drm_i915_private *dev_priv, u32 addr);
+
+ /**
* @init_oa_buffer: Resets the head and tail pointers of the
* circular buffer for periodic OA reports.
*
@@ -2024,20 +2104,13 @@ struct i915_oa_ops {
void (*init_oa_buffer)(struct drm_i915_private *dev_priv);
/**
- * @select_metric_set: The auto generated code that checks whether a
- * requested OA config is applicable to the system and if so sets up
- * the mux, oa and flex eu register config pointers according to the
- * current dev_priv->perf.oa.metrics_set.
- */
- int (*select_metric_set)(struct drm_i915_private *dev_priv);
-
- /**
* @enable_metric_set: Selects and applies any MUX configuration to set
* up the Boolean and Custom (B/C) counters that are part of the
* counter reports being sampled. May apply system constraints such as
* disabling EU clock gating as required.
*/
- int (*enable_metric_set)(struct drm_i915_private *dev_priv);
+ int (*enable_metric_set)(struct drm_i915_private *dev_priv,
+ const struct i915_oa_config *oa_config);
/**
* @disable_metric_set: Remove system constraints associated with using
@@ -2083,6 +2156,7 @@ struct drm_i915_private {
struct kmem_cache *objects;
struct kmem_cache *vmas;
+ struct kmem_cache *luts;
struct kmem_cache *requests;
struct kmem_cache *dependencies;
struct kmem_cache *priorities;
@@ -2133,9 +2207,6 @@ struct drm_i915_private {
/* protects the irq masks */
spinlock_t irq_lock;
- /* protects the mmio flip data */
- spinlock_t mmio_flip_lock;
-
bool display_irqs_enabled;
/* To control wakeup latency, e.g. for irq-driven dp aux transfers. */
@@ -2236,18 +2307,10 @@ struct drm_i915_private {
DECLARE_HASHTABLE(mm_structs, 7);
struct mutex mm_lock;
- /* The hw wants to have a stable context identifier for the lifetime
- * of the context (for OA, PASID, faults, etc). This is limited
- * in execlists to 21 bits.
- */
- struct ida context_hw_ida;
-#define MAX_CONTEXT_HW_ID (1<<21) /* exclusive */
-
/* Kernel Modesetting */
struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES];
struct intel_crtc *pipe_to_crtc_mapping[I915_MAX_PIPES];
- wait_queue_head_t pending_flip_queue;
#ifdef CONFIG_DEBUG_FS
struct intel_pipe_crc pipe_crc[I915_MAX_PIPES];
@@ -2303,11 +2366,9 @@ struct drm_i915_private {
struct drm_i915_gem_object *vlv_pctx;
-#ifdef CONFIG_DRM_FBDEV_EMULATION
/* list of fbdev register on this device */
struct intel_fbdev *fbdev;
struct work_struct fbdev_suspend_work;
-#endif
struct drm_property *broadcast_rgb_property;
struct drm_property *force_audio_property;
@@ -2321,7 +2382,18 @@ struct drm_i915_private {
*/
struct mutex av_mutex;
- struct list_head context_list;
+ struct {
+ struct list_head list;
+ struct llist_head free_list;
+ struct work_struct free_work;
+
+ /* The hw wants to have a stable context identifier for the
+ * lifetime of the context (for OA, PASID, faults, etc).
+ * This is limited in execlists to 21 bits.
+ */
+ struct ida hw_ida;
+#define MAX_CONTEXT_HW_ID (1<<21) /* exclusive */
+ } contexts;
u32 fdi_rx_config;
@@ -2399,10 +2471,32 @@ struct drm_i915_private {
struct kobject *metrics_kobj;
struct ctl_table_header *sysctl_header;
+ /*
+ * Lock associated with adding/modifying/removing OA configs
+ * in dev_priv->perf.metrics_idr.
+ */
+ struct mutex metrics_lock;
+
+ /*
+ * List of dynamic configurations, you need to hold
+ * dev_priv->perf.metrics_lock to access it.
+ */
+ struct idr metrics_idr;
+
+ /*
+ * Lock associated with anything below within this structure
+ * except exclusive_stream.
+ */
struct mutex lock;
struct list_head streams;
struct {
+ /*
+ * The stream currently using the OA unit. If accessed
+ * outside a syscall associated to its file
+ * descriptor, you need to hold
+ * dev_priv->drm.struct_mutex.
+ */
struct i915_perf_stream *exclusive_stream;
u32 specific_ctx_id;
@@ -2421,16 +2515,7 @@ struct drm_i915_private {
int period_exponent;
int timestamp_frequency;
- int metrics_set;
-
- const struct i915_oa_reg *mux_regs[6];
- int mux_regs_lens[6];
- int n_mux_configs;
-
- const struct i915_oa_reg *b_counter_regs;
- int b_counter_regs_len;
- const struct i915_oa_reg *flex_regs;
- int flex_regs_len;
+ struct i915_oa_config test_config;
struct {
struct i915_vma *vma;
@@ -2517,7 +2602,6 @@ struct drm_i915_private {
struct i915_oa_ops ops;
const struct i915_oa_format *oa_formats;
- int n_builtin_sets;
} oa;
} perf;
@@ -2996,16 +3080,17 @@ intel_info(const struct drm_i915_private *dev_priv)
#define HAS_POOLED_EU(dev_priv) ((dev_priv)->info.has_pooled_eu)
-#define INTEL_PCH_DEVICE_ID_MASK 0xff00
-#define INTEL_PCH_DEVICE_ID_MASK_EXT 0xff80
+#define INTEL_PCH_DEVICE_ID_MASK 0xff80
#define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00
#define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00
#define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00
#define INTEL_PCH_LPT_DEVICE_ID_TYPE 0x8c00
#define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE 0x9c00
+#define INTEL_PCH_WPT_DEVICE_ID_TYPE 0x8c80
+#define INTEL_PCH_WPT_LP_DEVICE_ID_TYPE 0x9c80
#define INTEL_PCH_SPT_DEVICE_ID_TYPE 0xA100
#define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE 0x9D00
-#define INTEL_PCH_KBP_DEVICE_ID_TYPE 0xA200
+#define INTEL_PCH_KBP_DEVICE_ID_TYPE 0xA280
#define INTEL_PCH_CNP_DEVICE_ID_TYPE 0xA300
#define INTEL_PCH_CNP_LP_DEVICE_ID_TYPE 0x9D80
#define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100
@@ -3020,9 +3105,11 @@ intel_info(const struct drm_i915_private *dev_priv)
#define HAS_PCH_SPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_SPT)
#define HAS_PCH_LPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_LPT)
#define HAS_PCH_LPT_LP(dev_priv) \
- ((dev_priv)->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE)
+ ((dev_priv)->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE || \
+ (dev_priv)->pch_id == INTEL_PCH_WPT_LP_DEVICE_ID_TYPE)
#define HAS_PCH_LPT_H(dev_priv) \
- ((dev_priv)->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE)
+ ((dev_priv)->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE || \
+ (dev_priv)->pch_id == INTEL_PCH_WPT_DEVICE_ID_TYPE)
#define HAS_PCH_CPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_CPT)
#define HAS_PCH_IBX(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_IBX)
#define HAS_PCH_NOP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_NOP)
@@ -3088,7 +3175,13 @@ extern int i915_driver_load(struct pci_dev *pdev,
extern void i915_driver_unload(struct drm_device *dev);
extern int intel_gpu_reset(struct drm_i915_private *dev_priv, u32 engine_mask);
extern bool intel_has_gpu_reset(struct drm_i915_private *dev_priv);
-extern void i915_reset(struct drm_i915_private *dev_priv);
+
+#define I915_RESET_QUIET BIT(0)
+extern void i915_reset(struct drm_i915_private *i915, unsigned int flags);
+extern int i915_reset_engine(struct intel_engine_cs *engine,
+ unsigned int flags);
+
+extern bool intel_has_reset_engine(struct drm_i915_private *dev_priv);
extern int intel_guc_reset(struct drm_i915_private *dev_priv);
extern void intel_engine_init_hangcheck(struct intel_engine_cs *engine);
extern void intel_hangcheck_init(struct drm_i915_private *dev_priv);
@@ -3107,7 +3200,8 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
void intel_hpd_init(struct drm_i915_private *dev_priv);
void intel_hpd_init_work(struct drm_i915_private *dev_priv);
void intel_hpd_cancel_work(struct drm_i915_private *dev_priv);
-bool intel_hpd_pin_to_port(enum hpd_pin pin, enum port *port);
+enum port intel_hpd_pin_to_port(enum hpd_pin pin);
+enum hpd_pin intel_hpd_pin(enum port port);
bool intel_hpd_disable(struct drm_i915_private *dev_priv, enum hpd_pin pin);
void intel_hpd_enable(struct drm_i915_private *dev_priv, enum hpd_pin pin);
@@ -3276,6 +3370,26 @@ static inline void i915_gem_drain_freed_objects(struct drm_i915_private *i915)
} while (flush_work(&i915->mm.free_work));
}
+static inline void i915_gem_drain_workqueue(struct drm_i915_private *i915)
+{
+ /*
+ * Similar to objects above (see i915_gem_drain_freed-objects), in
+ * general we have workers that are armed by RCU and then rearm
+ * themselves in their callbacks. To be paranoid, we need to
+ * drain the workqueue a second time after waiting for the RCU
+ * grace period so that we catch work queued via RCU from the first
+ * pass. As neither drain_workqueue() nor flush_workqueue() report
+ * a result, we make an assumption that we only don't require more
+ * than 2 passes to catch all recursive RCU delayed work.
+ *
+ */
+ int pass = 2;
+ do {
+ rcu_barrier();
+ drain_workqueue(i915->wq);
+ } while (--pass);
+}
+
struct i915_vma * __must_check
i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
const struct i915_ggtt_view *view,
@@ -3461,11 +3575,22 @@ static inline u32 i915_reset_count(struct i915_gpu_error *error)
return READ_ONCE(error->reset_count);
}
+static inline u32 i915_reset_engine_count(struct i915_gpu_error *error,
+ struct intel_engine_cs *engine)
+{
+ return READ_ONCE(error->reset_engine_count[engine->id]);
+}
+
+struct drm_i915_gem_request *
+i915_gem_reset_prepare_engine(struct intel_engine_cs *engine);
int i915_gem_reset_prepare(struct drm_i915_private *dev_priv);
void i915_gem_reset(struct drm_i915_private *dev_priv);
+void i915_gem_reset_finish_engine(struct intel_engine_cs *engine);
void i915_gem_reset_finish(struct drm_i915_private *dev_priv);
void i915_gem_set_wedged(struct drm_i915_private *dev_priv);
bool i915_gem_unset_wedged(struct drm_i915_private *dev_priv);
+void i915_gem_reset_engine(struct intel_engine_cs *engine,
+ struct drm_i915_gem_request *request);
void i915_gem_init_mmio(struct drm_i915_private *i915);
int __must_check i915_gem_init(struct drm_i915_private *dev_priv);
@@ -3499,7 +3624,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
void i915_gem_object_unpin_from_display_plane(struct i915_vma *vma);
int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
int align);
-int i915_gem_open(struct drm_device *dev, struct drm_file *file);
+int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file);
void i915_gem_release(struct drm_device *dev, struct drm_file *file);
int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
@@ -3531,38 +3656,23 @@ void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
struct sg_table *pages);
static inline struct i915_gem_context *
-i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id)
+__i915_gem_context_lookup_rcu(struct drm_i915_file_private *file_priv, u32 id)
{
- struct i915_gem_context *ctx;
-
- lockdep_assert_held(&file_priv->dev_priv->drm.struct_mutex);
-
- ctx = idr_find(&file_priv->context_idr, id);
- if (!ctx)
- return ERR_PTR(-ENOENT);
-
- return ctx;
+ return idr_find(&file_priv->context_idr, id);
}
static inline struct i915_gem_context *
-i915_gem_context_get(struct i915_gem_context *ctx)
-{
- kref_get(&ctx->ref);
- return ctx;
-}
-
-static inline void i915_gem_context_put(struct i915_gem_context *ctx)
+i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id)
{
- lockdep_assert_held(&ctx->i915->drm.struct_mutex);
- kref_put(&ctx->ref, i915_gem_context_free);
-}
+ struct i915_gem_context *ctx;
-static inline void i915_gem_context_put_unlocked(struct i915_gem_context *ctx)
-{
- struct mutex *lock = &ctx->i915->drm.struct_mutex;
+ rcu_read_lock();
+ ctx = __i915_gem_context_lookup_rcu(file_priv, id);
+ if (ctx && !kref_get_unless_zero(&ctx->ref))
+ ctx = NULL;
+ rcu_read_unlock();
- if (kref_put_mutex(&ctx->ref, i915_gem_context_free, lock))
- mutex_unlock(lock);
+ return ctx;
}
static inline struct intel_timeline *
@@ -3577,6 +3687,10 @@ i915_gem_context_lookup_timeline(struct i915_gem_context *ctx,
int i915_perf_open_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
+int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file);
+int i915_perf_remove_config_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file);
void i915_oa_init_reg_state(struct intel_engine_cs *engine,
struct i915_gem_context *ctx,
uint32_t *reg_state);
@@ -4064,6 +4178,11 @@ static inline unsigned long msecs_to_jiffies_timeout(const unsigned int m)
static inline unsigned long nsecs_to_jiffies_timeout(const u64 n)
{
+ /* nsecs_to_jiffies64() does not guard against overflow */
+ if (NSEC_PER_SEC % HZ &&
+ div_u64(n, NSEC_PER_SEC) >= MAX_JIFFY_OFFSET / HZ)
+ return MAX_JIFFY_OFFSET;
+
return min_t(u64, MAX_JIFFY_OFFSET, nsecs_to_jiffies64(n) + 1);
}
@@ -4210,10 +4329,11 @@ int remap_io_mapping(struct vm_area_struct *vma,
unsigned long addr, unsigned long pfn, unsigned long size,
struct io_mapping *iomap);
-static inline bool i915_gem_object_is_coherent(struct drm_i915_gem_object *obj)
+static inline bool
+intel_engine_can_store_dword(struct intel_engine_cs *engine)
{
- return (obj->cache_level != I915_CACHE_NONE ||
- HAS_LLC(to_i915(obj->base.dev)));
+ return __intel_engine_can_store_dword(INTEL_GEN(engine->i915),
+ engine->class);
}
#endif
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 969bac8404f1..b9e8e0d6e97b 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -52,7 +52,7 @@ static bool cpu_write_needs_clflush(struct drm_i915_gem_object *obj)
if (obj->cache_dirty)
return false;
- if (!obj->cache_coherent)
+ if (!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE))
return true;
return obj->pin_display;
@@ -253,7 +253,7 @@ __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj,
if (needs_clflush &&
(obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0 &&
- !obj->cache_coherent)
+ !(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ))
drm_clflush_sg(pages);
__start_cpu_write(obj);
@@ -388,7 +388,7 @@ i915_gem_object_wait_fence(struct dma_fence *fence,
*/
if (rps) {
if (INTEL_GEN(rq->i915) >= 6)
- gen6_rps_boost(rq->i915, rps, rq->emitted_jiffies);
+ gen6_rps_boost(rq, rps);
else
rps = NULL;
}
@@ -399,22 +399,6 @@ out:
if (flags & I915_WAIT_LOCKED && i915_gem_request_completed(rq))
i915_gem_request_retire_upto(rq);
- if (rps && i915_gem_request_global_seqno(rq) == intel_engine_last_submit(rq->engine)) {
- /* The GPU is now idle and this client has stalled.
- * Since no other client has submitted a request in the
- * meantime, assume that this client is the only one
- * supplying work to the GPU but is unable to keep that
- * work supplied because it is waiting. Since the GPU is
- * then never kept fully busy, RPS autoclocking will
- * keep the clocks relatively low, causing further delays.
- * Compensate by giving the synchronous client credit for
- * a waitboost next time.
- */
- spin_lock(&rq->i915->rps.client_lock);
- list_del_init(&rps->link);
- spin_unlock(&rq->i915->rps.client_lock);
- }
-
return timeout;
}
@@ -577,46 +561,6 @@ static struct intel_rps_client *to_rps_client(struct drm_file *file)
return &fpriv->rps;
}
-int
-i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
- int align)
-{
- int ret;
-
- if (align > obj->base.size)
- return -EINVAL;
-
- if (obj->ops == &i915_gem_phys_ops)
- return 0;
-
- if (obj->mm.madv != I915_MADV_WILLNEED)
- return -EFAULT;
-
- if (obj->base.filp == NULL)
- return -EINVAL;
-
- ret = i915_gem_object_unbind(obj);
- if (ret)
- return ret;
-
- __i915_gem_object_put_pages(obj, I915_MM_NORMAL);
- if (obj->mm.pages)
- return -EBUSY;
-
- GEM_BUG_ON(obj->ops != &i915_gem_object_ops);
- obj->ops = &i915_gem_phys_ops;
-
- ret = i915_gem_object_pin_pages(obj);
- if (ret)
- goto err_xfer;
-
- return 0;
-
-err_xfer:
- obj->ops = &i915_gem_object_ops;
- return ret;
-}
-
static int
i915_gem_phys_pwrite(struct drm_i915_gem_object *obj,
struct drm_i915_gem_pwrite *args,
@@ -856,7 +800,8 @@ int i915_gem_obj_prepare_shmem_read(struct drm_i915_gem_object *obj,
if (ret)
return ret;
- if (obj->cache_coherent || !static_cpu_has(X86_FEATURE_CLFLUSH)) {
+ if (obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ ||
+ !static_cpu_has(X86_FEATURE_CLFLUSH)) {
ret = i915_gem_object_set_to_cpu_domain(obj, false);
if (ret)
goto err_unpin;
@@ -908,7 +853,8 @@ int i915_gem_obj_prepare_shmem_write(struct drm_i915_gem_object *obj,
if (ret)
return ret;
- if (obj->cache_coherent || !static_cpu_has(X86_FEATURE_CLFLUSH)) {
+ if (obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE ||
+ !static_cpu_has(X86_FEATURE_CLFLUSH)) {
ret = i915_gem_object_set_to_cpu_domain(obj, true);
if (ret)
goto err_unpin;
@@ -2756,34 +2702,38 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj,
return 0;
}
-static bool ban_context(const struct i915_gem_context *ctx)
+static bool ban_context(const struct i915_gem_context *ctx,
+ unsigned int score)
{
return (i915_gem_context_is_bannable(ctx) &&
- ctx->ban_score >= CONTEXT_SCORE_BAN_THRESHOLD);
+ score >= CONTEXT_SCORE_BAN_THRESHOLD);
}
static void i915_gem_context_mark_guilty(struct i915_gem_context *ctx)
{
- ctx->guilty_count++;
- ctx->ban_score += CONTEXT_SCORE_GUILTY;
- if (ban_context(ctx))
- i915_gem_context_set_banned(ctx);
+ unsigned int score;
+ bool banned;
- DRM_DEBUG_DRIVER("context %s marked guilty (score %d) banned? %s\n",
- ctx->name, ctx->ban_score,
- yesno(i915_gem_context_is_banned(ctx)));
+ atomic_inc(&ctx->guilty_count);
- if (!i915_gem_context_is_banned(ctx) || IS_ERR_OR_NULL(ctx->file_priv))
+ score = atomic_add_return(CONTEXT_SCORE_GUILTY, &ctx->ban_score);
+ banned = ban_context(ctx, score);
+ DRM_DEBUG_DRIVER("context %s marked guilty (score %d) banned? %s\n",
+ ctx->name, score, yesno(banned));
+ if (!banned)
return;
- ctx->file_priv->context_bans++;
- DRM_DEBUG_DRIVER("client %s has had %d context banned\n",
- ctx->name, ctx->file_priv->context_bans);
+ i915_gem_context_set_banned(ctx);
+ if (!IS_ERR_OR_NULL(ctx->file_priv)) {
+ atomic_inc(&ctx->file_priv->context_bans);
+ DRM_DEBUG_DRIVER("client %s has had %d context banned\n",
+ ctx->name, atomic_read(&ctx->file_priv->context_bans));
+ }
}
static void i915_gem_context_mark_innocent(struct i915_gem_context *ctx)
{
- ctx->active_count++;
+ atomic_inc(&ctx->active_count);
}
struct drm_i915_gem_request *
@@ -2832,46 +2782,62 @@ static bool engine_stalled(struct intel_engine_cs *engine)
return true;
}
+/*
+ * Ensure irq handler finishes, and not run again.
+ * Also return the active request so that we only search for it once.
+ */
+struct drm_i915_gem_request *
+i915_gem_reset_prepare_engine(struct intel_engine_cs *engine)
+{
+ struct drm_i915_gem_request *request = NULL;
+
+ /* Prevent the signaler thread from updating the request
+ * state (by calling dma_fence_signal) as we are processing
+ * the reset. The write from the GPU of the seqno is
+ * asynchronous and the signaler thread may see a different
+ * value to us and declare the request complete, even though
+ * the reset routine have picked that request as the active
+ * (incomplete) request. This conflict is not handled
+ * gracefully!
+ */
+ kthread_park(engine->breadcrumbs.signaler);
+
+ /* Prevent request submission to the hardware until we have
+ * completed the reset in i915_gem_reset_finish(). If a request
+ * is completed by one engine, it may then queue a request
+ * to a second via its engine->irq_tasklet *just* as we are
+ * calling engine->init_hw() and also writing the ELSP.
+ * Turning off the engine->irq_tasklet until the reset is over
+ * prevents the race.
+ */
+ tasklet_kill(&engine->irq_tasklet);
+ tasklet_disable(&engine->irq_tasklet);
+
+ if (engine->irq_seqno_barrier)
+ engine->irq_seqno_barrier(engine);
+
+ request = i915_gem_find_active_request(engine);
+ if (request && request->fence.error == -EIO)
+ request = ERR_PTR(-EIO); /* Previous reset failed! */
+
+ return request;
+}
+
int i915_gem_reset_prepare(struct drm_i915_private *dev_priv)
{
struct intel_engine_cs *engine;
+ struct drm_i915_gem_request *request;
enum intel_engine_id id;
int err = 0;
- /* Ensure irq handler finishes, and not run again. */
for_each_engine(engine, dev_priv, id) {
- struct drm_i915_gem_request *request;
-
- /* Prevent the signaler thread from updating the request
- * state (by calling dma_fence_signal) as we are processing
- * the reset. The write from the GPU of the seqno is
- * asynchronous and the signaler thread may see a different
- * value to us and declare the request complete, even though
- * the reset routine have picked that request as the active
- * (incomplete) request. This conflict is not handled
- * gracefully!
- */
- kthread_park(engine->breadcrumbs.signaler);
-
- /* Prevent request submission to the hardware until we have
- * completed the reset in i915_gem_reset_finish(). If a request
- * is completed by one engine, it may then queue a request
- * to a second via its engine->irq_tasklet *just* as we are
- * calling engine->init_hw() and also writing the ELSP.
- * Turning off the engine->irq_tasklet until the reset is over
- * prevents the race.
- */
- tasklet_kill(&engine->irq_tasklet);
- tasklet_disable(&engine->irq_tasklet);
-
- if (engine->irq_seqno_barrier)
- engine->irq_seqno_barrier(engine);
-
- if (engine_stalled(engine)) {
- request = i915_gem_find_active_request(engine);
- if (request && request->fence.error == -EIO)
- err = -EIO; /* Previous reset failed! */
+ request = i915_gem_reset_prepare_engine(engine);
+ if (IS_ERR(request)) {
+ err = PTR_ERR(request);
+ continue;
}
+
+ engine->hangcheck.active_request = request;
}
i915_gem_revoke_fences(dev_priv);
@@ -2921,12 +2887,11 @@ static void engine_skip_context(struct drm_i915_gem_request *request)
spin_unlock_irqrestore(&engine->timeline->lock, flags);
}
-/* Returns true if the request was guilty of hang */
-static bool i915_gem_reset_request(struct drm_i915_gem_request *request)
+/* Returns the request if it was guilty of the hang */
+static struct drm_i915_gem_request *
+i915_gem_reset_request(struct intel_engine_cs *engine,
+ struct drm_i915_gem_request *request)
{
- /* Read once and return the resolution */
- const bool guilty = engine_stalled(request->engine);
-
/* The guilty request will get skipped on a hung engine.
*
* Users of client default contexts do not rely on logical
@@ -2948,29 +2913,47 @@ static bool i915_gem_reset_request(struct drm_i915_gem_request *request)
* subsequent hangs.
*/
- if (guilty) {
+ if (engine_stalled(engine)) {
i915_gem_context_mark_guilty(request->ctx);
skip_request(request);
+
+ /* If this context is now banned, skip all pending requests. */
+ if (i915_gem_context_is_banned(request->ctx))
+ engine_skip_context(request);
} else {
- i915_gem_context_mark_innocent(request->ctx);
- dma_fence_set_error(&request->fence, -EAGAIN);
+ /*
+ * Since this is not the hung engine, it may have advanced
+ * since the hang declaration. Double check by refinding
+ * the active request at the time of the reset.
+ */
+ request = i915_gem_find_active_request(engine);
+ if (request) {
+ i915_gem_context_mark_innocent(request->ctx);
+ dma_fence_set_error(&request->fence, -EAGAIN);
+
+ /* Rewind the engine to replay the incomplete rq */
+ spin_lock_irq(&engine->timeline->lock);
+ request = list_prev_entry(request, link);
+ if (&request->link == &engine->timeline->requests)
+ request = NULL;
+ spin_unlock_irq(&engine->timeline->lock);
+ }
}
- return guilty;
+ return request;
}
-static void i915_gem_reset_engine(struct intel_engine_cs *engine)
+void i915_gem_reset_engine(struct intel_engine_cs *engine,
+ struct drm_i915_gem_request *request)
{
- struct drm_i915_gem_request *request;
+ engine->irq_posted = 0;
- request = i915_gem_find_active_request(engine);
- if (request && i915_gem_reset_request(request)) {
+ if (request)
+ request = i915_gem_reset_request(engine, request);
+
+ if (request) {
DRM_DEBUG_DRIVER("resetting %s to restart from tail of request 0x%x\n",
engine->name, request->global_seqno);
-
- /* If this context is now banned, skip all pending requests. */
- if (i915_gem_context_is_banned(request->ctx))
- engine_skip_context(request);
}
/* Setup the CS to resume from the breadcrumb of the hung request */
@@ -2989,7 +2972,7 @@ void i915_gem_reset(struct drm_i915_private *dev_priv)
for_each_engine(engine, dev_priv, id) {
struct i915_gem_context *ctx;
- i915_gem_reset_engine(engine);
+ i915_gem_reset_engine(engine, engine->hangcheck.active_request);
ctx = fetch_and_zero(&engine->last_retired_context);
if (ctx)
engine->context_unpin(engine, ctx);
@@ -3005,6 +2988,12 @@ void i915_gem_reset(struct drm_i915_private *dev_priv)
}
}
+void i915_gem_reset_finish_engine(struct intel_engine_cs *engine)
+{
+ tasklet_enable(&engine->irq_tasklet);
+ kthread_unpark(engine->breadcrumbs.signaler);
+}
+
void i915_gem_reset_finish(struct drm_i915_private *dev_priv)
{
struct intel_engine_cs *engine;
@@ -3013,13 +3002,14 @@ void i915_gem_reset_finish(struct drm_i915_private *dev_priv)
lockdep_assert_held(&dev_priv->drm.struct_mutex);
for_each_engine(engine, dev_priv, id) {
- tasklet_enable(&engine->irq_tasklet);
- kthread_unpark(engine->breadcrumbs.signaler);
+ engine->hangcheck.active_request = NULL;
+ i915_gem_reset_finish_engine(engine);
}
}
static void nop_submit_request(struct drm_i915_gem_request *request)
{
+ GEM_BUG_ON(!i915_terminally_wedged(&request->i915->gpu_error));
dma_fence_set_error(&request->fence, -EIO);
i915_gem_request_submit(request);
intel_engine_init_global_seqno(request->engine, request->global_seqno);
@@ -3041,16 +3031,10 @@ static void engine_set_wedged(struct intel_engine_cs *engine)
/* Mark all executing requests as skipped */
spin_lock_irqsave(&engine->timeline->lock, flags);
list_for_each_entry(request, &engine->timeline->requests, link)
- dma_fence_set_error(&request->fence, -EIO);
+ if (!i915_gem_request_completed(request))
+ dma_fence_set_error(&request->fence, -EIO);
spin_unlock_irqrestore(&engine->timeline->lock, flags);
- /* Mark all pending requests as complete so that any concurrent
- * (lockless) lookup doesn't try and wait upon the request as we
- * reset it.
- */
- intel_engine_init_global_seqno(engine,
- intel_engine_last_submit(engine));
-
/*
* Clear the execlists queue up before freeing the requests, as those
* are the ones that keep the context and ringbuffer backing objects
@@ -3071,7 +3055,21 @@ static void engine_set_wedged(struct intel_engine_cs *engine)
engine->execlist_first = NULL;
spin_unlock_irqrestore(&engine->timeline->lock, flags);
+
+ /* The port is checked prior to scheduling a tasklet, but
+ * just in case we have suspended the tasklet to do the
+ * wedging make sure that when it wakes, it decides there
+ * is no work to do by clearing the irq_posted bit.
+ */
+ clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
}
+
+ /* Mark all pending requests as complete so that any concurrent
+ * (lockless) lookup doesn't try and wait upon the request as we
+ * reset it.
+ */
+ intel_engine_init_global_seqno(engine,
+ intel_engine_last_submit(engine));
}
static int __i915_gem_set_wedged_BKL(void *data)
@@ -3083,25 +3081,15 @@ static int __i915_gem_set_wedged_BKL(void *data)
for_each_engine(engine, i915, id)
engine_set_wedged(engine);
+ set_bit(I915_WEDGED, &i915->gpu_error.flags);
+ wake_up_all(&i915->gpu_error.reset_queue);
+
return 0;
}
void i915_gem_set_wedged(struct drm_i915_private *dev_priv)
{
- lockdep_assert_held(&dev_priv->drm.struct_mutex);
- set_bit(I915_WEDGED, &dev_priv->gpu_error.flags);
-
- /* Retire completed requests first so the list of inflight/incomplete
- * requests is accurate and we don't try and mark successful requests
- * as in error during __i915_gem_set_wedged_BKL().
- */
- i915_gem_retire_requests(dev_priv);
-
stop_machine(__i915_gem_set_wedged_BKL, dev_priv, NULL);
-
- i915_gem_context_lost(dev_priv);
-
- mod_delayed_work(dev_priv->wq, &dev_priv->gt.idle_work, 0);
}
bool i915_gem_unset_wedged(struct drm_i915_private *i915)
@@ -3156,6 +3144,7 @@ bool i915_gem_unset_wedged(struct drm_i915_private *i915)
* context and do not require stop_machine().
*/
intel_engines_reset_default_submission(i915);
+ i915_gem_contexts_lost(i915);
smp_mb__before_atomic(); /* complete takeover before enabling execbuf */
clear_bit(I915_WEDGED, &i915->gpu_error.flags);
@@ -3253,25 +3242,33 @@ out_rearm:
void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file)
{
+ struct drm_i915_private *i915 = to_i915(gem->dev);
struct drm_i915_gem_object *obj = to_intel_bo(gem);
struct drm_i915_file_private *fpriv = file->driver_priv;
- struct i915_vma *vma, *vn;
+ struct i915_lut_handle *lut, *ln;
- mutex_lock(&obj->base.dev->struct_mutex);
- list_for_each_entry_safe(vma, vn, &obj->vma_list, obj_link)
- if (vma->vm->file == fpriv)
+ mutex_lock(&i915->drm.struct_mutex);
+
+ list_for_each_entry_safe(lut, ln, &obj->lut_list, obj_link) {
+ struct i915_gem_context *ctx = lut->ctx;
+ struct i915_vma *vma;
+
+ if (ctx->file_priv != fpriv)
+ continue;
+
+ vma = radix_tree_delete(&ctx->handles_vma, lut->handle);
+
+ if (!i915_vma_is_ggtt(vma))
i915_vma_close(vma);
- vma = obj->vma_hashed;
- if (vma && vma->ctx->file_priv == fpriv)
- i915_vma_unlink_ctx(vma);
+ list_del(&lut->obj_link);
+ list_del(&lut->ctx_link);
- if (i915_gem_object_is_active(obj) &&
- !i915_gem_object_has_active_reference(obj)) {
- i915_gem_object_set_active_reference(obj);
- i915_gem_object_get(obj);
+ kmem_cache_free(i915->luts, lut);
+ __i915_gem_object_release_unless_active(obj);
}
- mutex_unlock(&obj->base.dev->struct_mutex);
+
+ mutex_unlock(&i915->drm.struct_mutex);
}
static unsigned long to_wait_timeout(s64 timeout_ns)
@@ -3297,7 +3294,7 @@ static unsigned long to_wait_timeout(s64 timeout_ns)
* -ERESTARTSYS: signal interrupted the wait
* -ENONENT: object doesn't exist
* Also possible, but rare:
- * -EAGAIN: GPU wedged
+ * -EAGAIN: incomplete, restart syscall
* -ENOMEM: damn
* -ENODEV: Internal IRQ fail
* -E?: The add request failed
@@ -3345,6 +3342,10 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
*/
if (ret == -ETIME && !nsecs_to_jiffies(args->timeout_ns))
args->timeout_ns = 0;
+
+ /* Asked to wait beyond the jiffie/scheduler precision? */
+ if (ret == -ETIME && args->timeout_ns)
+ ret = -EAGAIN;
}
i915_gem_object_put(obj);
@@ -3686,8 +3687,7 @@ restart:
list_for_each_entry(vma, &obj->vma_list, obj_link)
vma->node.color = cache_level;
- obj->cache_level = cache_level;
- obj->cache_coherent = i915_gem_object_is_coherent(obj);
+ i915_gem_object_set_cache_coherency(obj, cache_level);
obj->cache_dirty = true; /* Always invalidate stale cachelines */
return 0;
@@ -4260,6 +4260,7 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
INIT_LIST_HEAD(&obj->global_link);
INIT_LIST_HEAD(&obj->userfault_link);
INIT_LIST_HEAD(&obj->vma_list);
+ INIT_LIST_HEAD(&obj->lut_list);
INIT_LIST_HEAD(&obj->batch_pool_link);
obj->ops = ops;
@@ -4292,6 +4293,7 @@ i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size)
{
struct drm_i915_gem_object *obj;
struct address_space *mapping;
+ unsigned int cache_level;
gfp_t mask;
int ret;
@@ -4330,7 +4332,7 @@ i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size)
obj->base.write_domain = I915_GEM_DOMAIN_CPU;
obj->base.read_domains = I915_GEM_DOMAIN_CPU;
- if (HAS_LLC(dev_priv)) {
+ if (HAS_LLC(dev_priv))
/* On some devices, we can have the GPU use the LLC (the CPU
* cache) for about a 10% performance improvement
* compared to uncached. Graphics requests other than
@@ -4343,12 +4345,11 @@ i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size)
* However, we maintain the display planes as UC, and so
* need to rebind when first used as such.
*/
- obj->cache_level = I915_CACHE_LLC;
- } else
- obj->cache_level = I915_CACHE_NONE;
+ cache_level = I915_CACHE_LLC;
+ else
+ cache_level = I915_CACHE_NONE;
- obj->cache_coherent = i915_gem_object_is_coherent(obj);
- obj->cache_dirty = !obj->cache_coherent;
+ i915_gem_object_set_cache_coherency(obj, cache_level);
trace_i915_gem_object_create(obj);
@@ -4503,8 +4504,8 @@ void __i915_gem_object_release_unless_active(struct drm_i915_gem_object *obj)
{
lockdep_assert_held(&obj->base.dev->struct_mutex);
- GEM_BUG_ON(i915_gem_object_has_active_reference(obj));
- if (i915_gem_object_is_active(obj))
+ if (!i915_gem_object_has_active_reference(obj) &&
+ i915_gem_object_is_active(obj))
i915_gem_object_set_active_reference(obj);
else
i915_gem_object_put(obj);
@@ -4565,7 +4566,7 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv)
goto err_unlock;
assert_kernel_context_is_current(dev_priv);
- i915_gem_context_lost(dev_priv);
+ i915_gem_contexts_lost(dev_priv);
mutex_unlock(&dev->struct_mutex);
intel_guc_suspend(dev_priv);
@@ -4579,8 +4580,6 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv)
while (flush_delayed_work(&dev_priv->gt.idle_work))
;
- i915_gem_drain_freed_objects(dev_priv);
-
/* Assert that we sucessfully flushed all the work and
* reset the GPU back to its idle, low power state.
*/
@@ -4812,7 +4811,7 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
if (ret)
goto out_unlock;
- ret = i915_gem_context_init(dev_priv);
+ ret = i915_gem_contexts_init(dev_priv);
if (ret)
goto out_unlock;
@@ -4898,12 +4897,16 @@ i915_gem_load_init(struct drm_i915_private *dev_priv)
if (!dev_priv->vmas)
goto err_objects;
+ dev_priv->luts = KMEM_CACHE(i915_lut_handle, 0);
+ if (!dev_priv->luts)
+ goto err_vmas;
+
dev_priv->requests = KMEM_CACHE(drm_i915_gem_request,
SLAB_HWCACHE_ALIGN |
SLAB_RECLAIM_ACCOUNT |
SLAB_TYPESAFE_BY_RCU);
if (!dev_priv->requests)
- goto err_vmas;
+ goto err_luts;
dev_priv->dependencies = KMEM_CACHE(i915_dependency,
SLAB_HWCACHE_ALIGN |
@@ -4922,7 +4925,6 @@ i915_gem_load_init(struct drm_i915_private *dev_priv)
if (err)
goto err_priorities;
- INIT_LIST_HEAD(&dev_priv->context_list);
INIT_WORK(&dev_priv->mm.free_work, __i915_gem_free_work);
init_llist_head(&dev_priv->mm.free_list);
INIT_LIST_HEAD(&dev_priv->mm.unbound_list);
@@ -4936,8 +4938,6 @@ i915_gem_load_init(struct drm_i915_private *dev_priv)
init_waitqueue_head(&dev_priv->gpu_error.wait_queue);
init_waitqueue_head(&dev_priv->gpu_error.reset_queue);
- init_waitqueue_head(&dev_priv->pending_flip_queue);
-
atomic_set(&dev_priv->mm.bsd_engine_dispatch_index, 0);
spin_lock_init(&dev_priv->fb_tracking.lock);
@@ -4950,6 +4950,8 @@ err_dependencies:
kmem_cache_destroy(dev_priv->dependencies);
err_requests:
kmem_cache_destroy(dev_priv->requests);
+err_luts:
+ kmem_cache_destroy(dev_priv->luts);
err_vmas:
kmem_cache_destroy(dev_priv->vmas);
err_objects:
@@ -4972,6 +4974,7 @@ void i915_gem_load_cleanup(struct drm_i915_private *dev_priv)
kmem_cache_destroy(dev_priv->priorities);
kmem_cache_destroy(dev_priv->dependencies);
kmem_cache_destroy(dev_priv->requests);
+ kmem_cache_destroy(dev_priv->luts);
kmem_cache_destroy(dev_priv->vmas);
kmem_cache_destroy(dev_priv->objects);
@@ -5038,15 +5041,9 @@ void i915_gem_release(struct drm_device *dev, struct drm_file *file)
list_for_each_entry(request, &file_priv->mm.request_list, client_link)
request->file_priv = NULL;
spin_unlock(&file_priv->mm.lock);
-
- if (!list_empty(&file_priv->rps.link)) {
- spin_lock(&to_i915(dev)->rps.client_lock);
- list_del(&file_priv->rps.link);
- spin_unlock(&to_i915(dev)->rps.client_lock);
- }
}
-int i915_gem_open(struct drm_device *dev, struct drm_file *file)
+int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file)
{
struct drm_i915_file_private *file_priv;
int ret;
@@ -5058,16 +5055,15 @@ int i915_gem_open(struct drm_device *dev, struct drm_file *file)
return -ENOMEM;
file->driver_priv = file_priv;
- file_priv->dev_priv = to_i915(dev);
+ file_priv->dev_priv = i915;
file_priv->file = file;
- INIT_LIST_HEAD(&file_priv->rps.link);
spin_lock_init(&file_priv->mm.lock);
INIT_LIST_HEAD(&file_priv->mm.request_list);
file_priv->bsd_engine = -1;
- ret = i915_gem_context_open(dev, file);
+ ret = i915_gem_context_open(i915, file);
if (ret)
kfree(file_priv);
@@ -5311,6 +5307,64 @@ i915_gem_object_get_dma_address(struct drm_i915_gem_object *obj,
return sg_dma_address(sg) + (offset << PAGE_SHIFT);
}
+int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align)
+{
+ struct sg_table *pages;
+ int err;
+
+ if (align > obj->base.size)
+ return -EINVAL;
+
+ if (obj->ops == &i915_gem_phys_ops)
+ return 0;
+
+ if (obj->ops != &i915_gem_object_ops)
+ return -EINVAL;
+
+ err = i915_gem_object_unbind(obj);
+ if (err)
+ return err;
+
+ mutex_lock(&obj->mm.lock);
+
+ if (obj->mm.madv != I915_MADV_WILLNEED) {
+ err = -EFAULT;
+ goto err_unlock;
+ }
+
+ if (obj->mm.quirked) {
+ err = -EFAULT;
+ goto err_unlock;
+ }
+
+ if (obj->mm.mapping) {
+ err = -EBUSY;
+ goto err_unlock;
+ }
+
+ pages = obj->mm.pages;
+ obj->ops = &i915_gem_phys_ops;
+
+ err = ____i915_gem_object_get_pages(obj);
+ if (err)
+ goto err_xfer;
+
+ /* Perma-pin (until release) the physical set of pages */
+ __i915_gem_object_pin_pages(obj);
+
+ if (!IS_ERR_OR_NULL(pages))
+ i915_gem_object_ops.put_pages(obj, pages);
+ mutex_unlock(&obj->mm.lock);
+ return 0;
+
+err_xfer:
+ obj->ops = &i915_gem_object_ops;
+ obj->mm.pages = pages;
+err_unlock:
+ mutex_unlock(&obj->mm.lock);
+ return err;
+}
+
#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
#include "selftests/scatterlist.c"
#include "selftests/mock_gem_device.c"
diff --git a/drivers/gpu/drm/i915/i915_gem_clflush.c b/drivers/gpu/drm/i915/i915_gem_clflush.c
index 152f16c11878..8a04d33055be 100644
--- a/drivers/gpu/drm/i915/i915_gem_clflush.c
+++ b/drivers/gpu/drm/i915/i915_gem_clflush.c
@@ -114,7 +114,7 @@ i915_clflush_notify(struct i915_sw_fence *fence,
return NOTIFY_DONE;
}
-void i915_gem_clflush_object(struct drm_i915_gem_object *obj,
+bool i915_gem_clflush_object(struct drm_i915_gem_object *obj,
unsigned int flags)
{
struct clflush *clflush;
@@ -128,7 +128,7 @@ void i915_gem_clflush_object(struct drm_i915_gem_object *obj,
*/
if (!i915_gem_object_has_struct_page(obj)) {
obj->cache_dirty = false;
- return;
+ return false;
}
/* If the GPU is snooping the contents of the CPU cache,
@@ -139,8 +139,9 @@ void i915_gem_clflush_object(struct drm_i915_gem_object *obj,
* snooping behaviour occurs naturally as the result of our domain
* tracking.
*/
- if (!(flags & I915_CLFLUSH_FORCE) && obj->cache_coherent)
- return;
+ if (!(flags & I915_CLFLUSH_FORCE) &&
+ obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)
+ return false;
trace_i915_gem_object_clflush(obj);
@@ -179,4 +180,5 @@ void i915_gem_clflush_object(struct drm_i915_gem_object *obj,
}
obj->cache_dirty = false;
+ return true;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_clflush.h b/drivers/gpu/drm/i915/i915_gem_clflush.h
index 2455a7820937..f390247561b3 100644
--- a/drivers/gpu/drm/i915/i915_gem_clflush.h
+++ b/drivers/gpu/drm/i915/i915_gem_clflush.h
@@ -28,7 +28,7 @@
struct drm_i915_private;
struct drm_i915_gem_object;
-void i915_gem_clflush_object(struct drm_i915_gem_object *obj,
+bool i915_gem_clflush_object(struct drm_i915_gem_object *obj,
unsigned int flags);
#define I915_CLFLUSH_FORCE BIT(0)
#define I915_CLFLUSH_SYNC BIT(1)
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 39ed58a21fc1..58a2a44f88bd 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -93,81 +93,37 @@
#define ALL_L3_SLICES(dev) (1 << NUM_L3_SLICES(dev)) - 1
-/* Initial size (as log2) to preallocate the handle->object hashtable */
-#define VMA_HT_BITS 2u /* 4 x 2 pointers, 64 bytes minimum */
-
-static void resize_vma_ht(struct work_struct *work)
+static void lut_close(struct i915_gem_context *ctx)
{
- struct i915_gem_context_vma_lut *lut =
- container_of(work, typeof(*lut), resize);
- unsigned int bits, new_bits, size, i;
- struct hlist_head *new_ht;
-
- GEM_BUG_ON(!(lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS));
-
- bits = 1 + ilog2(4*lut->ht_count/3 + 1);
- new_bits = min_t(unsigned int,
- max(bits, VMA_HT_BITS),
- sizeof(unsigned int) * BITS_PER_BYTE - 1);
- if (new_bits == lut->ht_bits)
- goto out;
-
- new_ht = kzalloc(sizeof(*new_ht)<<new_bits, GFP_KERNEL | __GFP_NOWARN);
- if (!new_ht)
- new_ht = vzalloc(sizeof(*new_ht)<<new_bits);
- if (!new_ht)
- /* Pretend resize succeeded and stop calling us for a bit! */
- goto out;
+ struct i915_lut_handle *lut, *ln;
+ struct radix_tree_iter iter;
+ void __rcu **slot;
- size = BIT(lut->ht_bits);
- for (i = 0; i < size; i++) {
- struct i915_vma *vma;
- struct hlist_node *tmp;
-
- hlist_for_each_entry_safe(vma, tmp, &lut->ht[i], ctx_node)
- hlist_add_head(&vma->ctx_node,
- &new_ht[hash_32(vma->ctx_handle,
- new_bits)]);
+ list_for_each_entry_safe(lut, ln, &ctx->handles_list, ctx_link) {
+ list_del(&lut->obj_link);
+ kmem_cache_free(ctx->i915->luts, lut);
}
- kvfree(lut->ht);
- lut->ht = new_ht;
- lut->ht_bits = new_bits;
-out:
- smp_store_release(&lut->ht_size, BIT(bits));
- GEM_BUG_ON(lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS);
-}
-static void vma_lut_free(struct i915_gem_context *ctx)
-{
- struct i915_gem_context_vma_lut *lut = &ctx->vma_lut;
- unsigned int i, size;
+ radix_tree_for_each_slot(slot, &ctx->handles_vma, &iter, 0) {
+ struct i915_vma *vma = rcu_dereference_raw(*slot);
+ struct drm_i915_gem_object *obj = vma->obj;
- if (lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS)
- cancel_work_sync(&lut->resize);
+ radix_tree_iter_delete(&ctx->handles_vma, &iter, slot);
- size = BIT(lut->ht_bits);
- for (i = 0; i < size; i++) {
- struct i915_vma *vma;
+ if (!i915_vma_is_ggtt(vma))
+ i915_vma_close(vma);
- hlist_for_each_entry(vma, &lut->ht[i], ctx_node) {
- vma->obj->vma_hashed = NULL;
- vma->ctx = NULL;
- i915_vma_put(vma);
- }
+ __i915_gem_object_release_unless_active(obj);
}
- kvfree(lut->ht);
}
-void i915_gem_context_free(struct kref *ctx_ref)
+static void i915_gem_context_free(struct i915_gem_context *ctx)
{
- struct i915_gem_context *ctx = container_of(ctx_ref, typeof(*ctx), ref);
int i;
lockdep_assert_held(&ctx->i915->drm.struct_mutex);
- trace_i915_context_free(ctx);
GEM_BUG_ON(!i915_gem_context_is_closed(ctx));
- vma_lut_free(ctx);
i915_ppgtt_put(ctx->ppgtt);
for (i = 0; i < I915_NUM_ENGINES; i++) {
@@ -188,15 +144,64 @@ void i915_gem_context_free(struct kref *ctx_ref)
list_del(&ctx->link);
- ida_simple_remove(&ctx->i915->context_hw_ida, ctx->hw_id);
- kfree(ctx);
+ ida_simple_remove(&ctx->i915->contexts.hw_ida, ctx->hw_id);
+ kfree_rcu(ctx, rcu);
+}
+
+static void contexts_free(struct drm_i915_private *i915)
+{
+ struct llist_node *freed = llist_del_all(&i915->contexts.free_list);
+ struct i915_gem_context *ctx, *cn;
+
+ lockdep_assert_held(&i915->drm.struct_mutex);
+
+ llist_for_each_entry_safe(ctx, cn, freed, free_link)
+ i915_gem_context_free(ctx);
+}
+
+static void contexts_free_first(struct drm_i915_private *i915)
+{
+ struct i915_gem_context *ctx;
+ struct llist_node *freed;
+
+ lockdep_assert_held(&i915->drm.struct_mutex);
+
+ freed = llist_del_first(&i915->contexts.free_list);
+ if (!freed)
+ return;
+
+ ctx = container_of(freed, typeof(*ctx), free_link);
+ i915_gem_context_free(ctx);
+}
+
+static void contexts_free_worker(struct work_struct *work)
+{
+ struct drm_i915_private *i915 =
+ container_of(work, typeof(*i915), contexts.free_work);
+
+ mutex_lock(&i915->drm.struct_mutex);
+ contexts_free(i915);
+ mutex_unlock(&i915->drm.struct_mutex);
+}
+
+void i915_gem_context_release(struct kref *ref)
+{
+ struct i915_gem_context *ctx = container_of(ref, typeof(*ctx), ref);
+ struct drm_i915_private *i915 = ctx->i915;
+
+ trace_i915_context_free(ctx);
+ if (llist_add(&ctx->free_link, &i915->contexts.free_list))
+ queue_work(i915->wq, &i915->contexts.free_work);
}
static void context_close(struct i915_gem_context *ctx)
{
i915_gem_context_set_closed(ctx);
+
+ lut_close(ctx);
if (ctx->ppgtt)
i915_ppgtt_close(&ctx->ppgtt->base);
+
ctx->file_priv = ERR_PTR(-EBADF);
i915_gem_context_put(ctx);
}
@@ -205,7 +210,7 @@ static int assign_hw_id(struct drm_i915_private *dev_priv, unsigned *out)
{
int ret;
- ret = ida_simple_get(&dev_priv->context_hw_ida,
+ ret = ida_simple_get(&dev_priv->contexts.hw_ida,
0, MAX_CONTEXT_HW_ID, GFP_KERNEL);
if (ret < 0) {
/* Contexts are only released when no longer active.
@@ -213,7 +218,7 @@ static int assign_hw_id(struct drm_i915_private *dev_priv, unsigned *out)
* stale contexts and try again.
*/
i915_gem_retire_requests(dev_priv);
- ret = ida_simple_get(&dev_priv->context_hw_ida,
+ ret = ida_simple_get(&dev_priv->contexts.hw_ida,
0, MAX_CONTEXT_HW_ID, GFP_KERNEL);
if (ret < 0)
return ret;
@@ -265,20 +270,12 @@ __create_hw_context(struct drm_i915_private *dev_priv,
}
kref_init(&ctx->ref);
- list_add_tail(&ctx->link, &dev_priv->context_list);
+ list_add_tail(&ctx->link, &dev_priv->contexts.list);
ctx->i915 = dev_priv;
ctx->priority = I915_PRIORITY_NORMAL;
- ctx->vma_lut.ht_bits = VMA_HT_BITS;
- ctx->vma_lut.ht_size = BIT(VMA_HT_BITS);
- BUILD_BUG_ON(BIT(VMA_HT_BITS) == I915_CTX_RESIZE_IN_PROGRESS);
- ctx->vma_lut.ht = kcalloc(ctx->vma_lut.ht_size,
- sizeof(*ctx->vma_lut.ht),
- GFP_KERNEL);
- if (!ctx->vma_lut.ht)
- goto err_out;
-
- INIT_WORK(&ctx->vma_lut.resize, resize_vma_ht);
+ INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
+ INIT_LIST_HEAD(&ctx->handles_list);
/* Default context will never have a file_priv */
ret = DEFAULT_CONTEXT_HANDLE;
@@ -328,8 +325,6 @@ err_pid:
put_pid(ctx->pid);
idr_remove(&file_priv->context_idr, ctx->user_handle);
err_lut:
- kvfree(ctx->vma_lut.ht);
-err_out:
context_close(ctx);
return ERR_PTR(ret);
}
@@ -354,6 +349,9 @@ i915_gem_create_context(struct drm_i915_private *dev_priv,
lockdep_assert_held(&dev_priv->drm.struct_mutex);
+ /* Reap the most stale context */
+ contexts_free_first(dev_priv);
+
ctx = __create_hw_context(dev_priv, file_priv);
if (IS_ERR(ctx))
return ctx;
@@ -418,7 +416,7 @@ out:
return ctx;
}
-int i915_gem_context_init(struct drm_i915_private *dev_priv)
+int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
{
struct i915_gem_context *ctx;
@@ -427,6 +425,10 @@ int i915_gem_context_init(struct drm_i915_private *dev_priv)
if (WARN_ON(dev_priv->kernel_context))
return 0;
+ INIT_LIST_HEAD(&dev_priv->contexts.list);
+ INIT_WORK(&dev_priv->contexts.free_work, contexts_free_worker);
+ init_llist_head(&dev_priv->contexts.free_list);
+
if (intel_vgpu_active(dev_priv) &&
HAS_LOGICAL_RING_CONTEXTS(dev_priv)) {
if (!i915.enable_execlists) {
@@ -437,7 +439,7 @@ int i915_gem_context_init(struct drm_i915_private *dev_priv)
/* Using the simple ida interface, the max is limited by sizeof(int) */
BUILD_BUG_ON(MAX_CONTEXT_HW_ID > INT_MAX);
- ida_init(&dev_priv->context_hw_ida);
+ ida_init(&dev_priv->contexts.hw_ida);
ctx = i915_gem_create_context(dev_priv, NULL);
if (IS_ERR(ctx)) {
@@ -463,7 +465,7 @@ int i915_gem_context_init(struct drm_i915_private *dev_priv)
return 0;
}
-void i915_gem_context_lost(struct drm_i915_private *dev_priv)
+void i915_gem_contexts_lost(struct drm_i915_private *dev_priv)
{
struct intel_engine_cs *engine;
enum intel_engine_id id;
@@ -484,7 +486,7 @@ void i915_gem_context_lost(struct drm_i915_private *dev_priv)
if (!i915.enable_execlists) {
struct i915_gem_context *ctx;
- list_for_each_entry(ctx, &dev_priv->context_list, link) {
+ list_for_each_entry(ctx, &dev_priv->contexts.list, link) {
if (!i915_gem_context_is_default(ctx))
continue;
@@ -503,18 +505,20 @@ void i915_gem_context_lost(struct drm_i915_private *dev_priv)
}
}
-void i915_gem_context_fini(struct drm_i915_private *dev_priv)
+void i915_gem_contexts_fini(struct drm_i915_private *i915)
{
- struct i915_gem_context *dctx = dev_priv->kernel_context;
-
- lockdep_assert_held(&dev_priv->drm.struct_mutex);
+ struct i915_gem_context *ctx;
- GEM_BUG_ON(!i915_gem_context_is_kernel(dctx));
+ lockdep_assert_held(&i915->drm.struct_mutex);
- context_close(dctx);
- dev_priv->kernel_context = NULL;
+ /* Keep the context so that we can free it immediately ourselves */
+ ctx = i915_gem_context_get(fetch_and_zero(&i915->kernel_context));
+ GEM_BUG_ON(!i915_gem_context_is_kernel(ctx));
+ context_close(ctx);
+ i915_gem_context_free(ctx);
- ida_destroy(&dev_priv->context_hw_ida);
+ /* Must free all deferred contexts (via flush_workqueue) first */
+ ida_destroy(&i915->contexts.hw_ida);
}
static int context_idr_cleanup(int id, void *p, void *data)
@@ -525,32 +529,32 @@ static int context_idr_cleanup(int id, void *p, void *data)
return 0;
}
-int i915_gem_context_open(struct drm_device *dev, struct drm_file *file)
+int i915_gem_context_open(struct drm_i915_private *i915,
+ struct drm_file *file)
{
struct drm_i915_file_private *file_priv = file->driver_priv;
struct i915_gem_context *ctx;
idr_init(&file_priv->context_idr);
- mutex_lock(&dev->struct_mutex);
- ctx = i915_gem_create_context(to_i915(dev), file_priv);
- mutex_unlock(&dev->struct_mutex);
-
- GEM_BUG_ON(i915_gem_context_is_kernel(ctx));
-
+ mutex_lock(&i915->drm.struct_mutex);
+ ctx = i915_gem_create_context(i915, file_priv);
+ mutex_unlock(&i915->drm.struct_mutex);
if (IS_ERR(ctx)) {
idr_destroy(&file_priv->context_idr);
return PTR_ERR(ctx);
}
+ GEM_BUG_ON(i915_gem_context_is_kernel(ctx));
+
return 0;
}
-void i915_gem_context_close(struct drm_device *dev, struct drm_file *file)
+void i915_gem_context_close(struct drm_file *file)
{
struct drm_i915_file_private *file_priv = file->driver_priv;
- lockdep_assert_held(&dev->struct_mutex);
+ lockdep_assert_held(&file_priv->dev_priv->drm.struct_mutex);
idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL);
idr_destroy(&file_priv->context_idr);
@@ -688,19 +692,19 @@ static inline bool skip_rcs_switch(struct i915_hw_ppgtt *ppgtt,
}
static bool
-needs_pd_load_pre(struct i915_hw_ppgtt *ppgtt,
- struct intel_engine_cs *engine,
- struct i915_gem_context *to)
+needs_pd_load_pre(struct i915_hw_ppgtt *ppgtt, struct intel_engine_cs *engine)
{
+ struct i915_gem_context *from = engine->legacy_active_context;
+
if (!ppgtt)
return false;
/* Always load the ppgtt on first use */
- if (!engine->legacy_active_context)
+ if (!from)
return true;
/* Same context without new entries, skip */
- if (engine->legacy_active_context == to &&
+ if ((!from->ppgtt || from->ppgtt == ppgtt) &&
!(intel_engine_flag(engine) & ppgtt->pd_dirty_rings))
return false;
@@ -744,7 +748,7 @@ static int do_rcs_switch(struct drm_i915_gem_request *req)
if (skip_rcs_switch(ppgtt, engine, to))
return 0;
- if (needs_pd_load_pre(ppgtt, engine, to)) {
+ if (needs_pd_load_pre(ppgtt, engine)) {
/* Older GENs and non render rings still want the load first,
* "PP_DCLV followed by PP_DIR_BASE register through Load
* Register Immediate commands in Ring Buffer before submitting
@@ -841,7 +845,7 @@ int i915_switch_context(struct drm_i915_gem_request *req)
struct i915_hw_ppgtt *ppgtt =
to->ppgtt ?: req->i915->mm.aliasing_ppgtt;
- if (needs_pd_load_pre(ppgtt, engine, to)) {
+ if (needs_pd_load_pre(ppgtt, engine)) {
int ret;
trace_switch_mm(engine, to);
@@ -852,6 +856,7 @@ int i915_switch_context(struct drm_i915_gem_request *req)
ppgtt->pd_dirty_rings &= ~intel_engine_flag(engine);
}
+ engine->legacy_active_context = to;
return 0;
}
@@ -924,7 +929,7 @@ int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv)
static bool client_is_banned(struct drm_i915_file_private *file_priv)
{
- return file_priv->context_bans > I915_MAX_CLIENT_CONTEXT_BANS;
+ return atomic_read(&file_priv->context_bans) > I915_MAX_CLIENT_CONTEXT_BANS;
}
int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
@@ -981,20 +986,19 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
if (args->ctx_id == DEFAULT_CONTEXT_HANDLE)
return -ENOENT;
- ret = i915_mutex_lock_interruptible(dev);
- if (ret)
- return ret;
-
ctx = i915_gem_context_lookup(file_priv, args->ctx_id);
- if (IS_ERR(ctx)) {
- mutex_unlock(&dev->struct_mutex);
- return PTR_ERR(ctx);
- }
+ if (!ctx)
+ return -ENOENT;
+
+ ret = mutex_lock_interruptible(&dev->struct_mutex);
+ if (ret)
+ goto out;
__destroy_hw_context(ctx, file_priv);
mutex_unlock(&dev->struct_mutex);
- DRM_DEBUG("HW context %d destroyed\n", args->ctx_id);
+out:
+ i915_gem_context_put(ctx);
return 0;
}
@@ -1004,17 +1008,11 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
struct drm_i915_file_private *file_priv = file->driver_priv;
struct drm_i915_gem_context_param *args = data;
struct i915_gem_context *ctx;
- int ret;
-
- ret = i915_mutex_lock_interruptible(dev);
- if (ret)
- return ret;
+ int ret = 0;
ctx = i915_gem_context_lookup(file_priv, args->ctx_id);
- if (IS_ERR(ctx)) {
- mutex_unlock(&dev->struct_mutex);
- return PTR_ERR(ctx);
- }
+ if (!ctx)
+ return -ENOENT;
args->size = 0;
switch (args->param) {
@@ -1042,8 +1040,8 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
ret = -EINVAL;
break;
}
- mutex_unlock(&dev->struct_mutex);
+ i915_gem_context_put(ctx);
return ret;
}
@@ -1055,15 +1053,13 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
struct i915_gem_context *ctx;
int ret;
+ ctx = i915_gem_context_lookup(file_priv, args->ctx_id);
+ if (!ctx)
+ return -ENOENT;
+
ret = i915_mutex_lock_interruptible(dev);
if (ret)
- return ret;
-
- ctx = i915_gem_context_lookup(file_priv, args->ctx_id);
- if (IS_ERR(ctx)) {
- mutex_unlock(&dev->struct_mutex);
- return PTR_ERR(ctx);
- }
+ goto out;
switch (args->param) {
case I915_CONTEXT_PARAM_BAN_PERIOD:
@@ -1101,6 +1097,8 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
}
mutex_unlock(&dev->struct_mutex);
+out:
+ i915_gem_context_put(ctx);
return ret;
}
@@ -1115,27 +1113,31 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
if (args->flags || args->pad)
return -EINVAL;
- ret = i915_mutex_lock_interruptible(dev);
- if (ret)
- return ret;
+ ret = -ENOENT;
+ rcu_read_lock();
+ ctx = __i915_gem_context_lookup_rcu(file->driver_priv, args->ctx_id);
+ if (!ctx)
+ goto out;
- ctx = i915_gem_context_lookup(file->driver_priv, args->ctx_id);
- if (IS_ERR(ctx)) {
- mutex_unlock(&dev->struct_mutex);
- return PTR_ERR(ctx);
- }
+ /*
+ * We opt for unserialised reads here. This may result in tearing
+ * in the extremely unlikely event of a GPU hang on this context
+ * as we are querying them. If we need that extra layer of protection,
+ * we should wrap the hangstats with a seqlock.
+ */
if (capable(CAP_SYS_ADMIN))
args->reset_count = i915_reset_count(&dev_priv->gpu_error);
else
args->reset_count = 0;
- args->batch_active = ctx->guilty_count;
- args->batch_pending = ctx->active_count;
-
- mutex_unlock(&dev->struct_mutex);
+ args->batch_active = atomic_read(&ctx->guilty_count);
+ args->batch_pending = atomic_read(&ctx->active_count);
- return 0;
+ ret = 0;
+out:
+ rcu_read_unlock();
+ return ret;
}
#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h
index 82c99ba92ad3..44688e22a5c2 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/i915_gem_context.h
@@ -27,6 +27,7 @@
#include <linux/bitops.h>
#include <linux/list.h>
+#include <linux/radix-tree.h>
struct pid;
@@ -86,6 +87,7 @@ struct i915_gem_context {
/** link: place with &drm_i915_private.context_list */
struct list_head link;
+ struct llist_node free_link;
/**
* @ref: reference count
@@ -99,6 +101,11 @@ struct i915_gem_context {
struct kref ref;
/**
+ * @rcu: rcu_head for deferred freeing.
+ */
+ struct rcu_head rcu;
+
+ /**
* @flags: small set of booleans
*/
unsigned long flags;
@@ -143,32 +150,6 @@ struct i915_gem_context {
/** ggtt_offset_bias: placement restriction for context objects */
u32 ggtt_offset_bias;
- struct i915_gem_context_vma_lut {
- /** ht_size: last request size to allocate the hashtable for. */
- unsigned int ht_size;
-#define I915_CTX_RESIZE_IN_PROGRESS BIT(0)
- /** ht_bits: real log2(size) of hashtable. */
- unsigned int ht_bits;
- /** ht_count: current number of entries inside the hashtable */
- unsigned int ht_count;
-
- /** ht: the array of buckets comprising the simple hashtable */
- struct hlist_head *ht;
-
- /**
- * resize: After an execbuf completes, we check the load factor
- * of the hashtable. If the hashtable is too full, or too empty,
- * we schedule a task to resize the hashtable. During the
- * resize, the entries are moved between different buckets and
- * so we cannot simultaneously read the hashtable as it is
- * being resized (unlike rhashtable). Therefore we treat the
- * active work as a strong barrier, pausing a subsequent
- * execbuf to wait for the resize worker to complete, if
- * required.
- */
- struct work_struct resize;
- } vma_lut;
-
/** engine: per-engine logical HW state */
struct intel_context {
struct i915_vma *state;
@@ -185,20 +166,32 @@ struct i915_gem_context {
u32 desc_template;
/** guilty_count: How many times this context has caused a GPU hang. */
- unsigned int guilty_count;
+ atomic_t guilty_count;
/**
* @active_count: How many times this context was active during a GPU
* hang, but did not cause it.
*/
- unsigned int active_count;
+ atomic_t active_count;
#define CONTEXT_SCORE_GUILTY 10
#define CONTEXT_SCORE_BAN_THRESHOLD 40
/** ban_score: Accumulated score of all hangs caused by this context. */
- int ban_score;
+ atomic_t ban_score;
/** remap_slice: Bitmask of cache lines that need remapping */
u8 remap_slice;
+
+ /** handles_vma: rbtree to look up our context specific obj/vma for
+ * the user handle. (user handles are per fd, but the binding is
+ * per vm, which may be one per context or shared with the global GTT)
+ */
+ struct radix_tree_root handles_vma;
+
+ /** handles_list: reverse list of all the rbtree entries in use for
+ * this context, which allows us to free all the allocations on
+ * context close.
+ */
+ struct list_head handles_list;
};
static inline bool i915_gem_context_is_closed(const struct i915_gem_context *ctx)
@@ -273,14 +266,18 @@ static inline bool i915_gem_context_is_kernel(struct i915_gem_context *ctx)
}
/* i915_gem_context.c */
-int __must_check i915_gem_context_init(struct drm_i915_private *dev_priv);
-void i915_gem_context_lost(struct drm_i915_private *dev_priv);
-void i915_gem_context_fini(struct drm_i915_private *dev_priv);
-int i915_gem_context_open(struct drm_device *dev, struct drm_file *file);
-void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);
+int __must_check i915_gem_contexts_init(struct drm_i915_private *dev_priv);
+void i915_gem_contexts_lost(struct drm_i915_private *dev_priv);
+void i915_gem_contexts_fini(struct drm_i915_private *dev_priv);
+
+int i915_gem_context_open(struct drm_i915_private *i915,
+ struct drm_file *file);
+void i915_gem_context_close(struct drm_file *file);
+
int i915_switch_context(struct drm_i915_gem_request *req);
int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv);
-void i915_gem_context_free(struct kref *ctx_ref);
+
+void i915_gem_context_release(struct kref *ctx_ref);
struct i915_gem_context *
i915_gem_context_create_gvt(struct drm_device *dev);
@@ -295,4 +292,16 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
+static inline struct i915_gem_context *
+i915_gem_context_get(struct i915_gem_context *ctx)
+{
+ kref_get(&ctx->ref);
+ return ctx;
+}
+
+static inline void i915_gem_context_put(struct i915_gem_context *ctx)
+{
+ kref_put(&ctx->ref, i915_gem_context_release);
+}
+
#endif /* !__I915_GEM_CONTEXT_H__ */
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index a193f1b36c67..4df039ef2ce3 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -318,8 +318,8 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
/* Overlap of objects in the same batch? */
if (i915_vma_is_pinned(vma)) {
ret = -ENOSPC;
- if (vma->exec_entry &&
- vma->exec_entry->flags & EXEC_OBJECT_PINNED)
+ if (vma->exec_flags &&
+ *vma->exec_flags & EXEC_OBJECT_PINNED)
ret = -EINVAL;
break;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 054b2e54cdaf..3d74f3a27c13 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -32,6 +32,7 @@
#include <linux/uaccess.h>
#include <drm/drmP.h>
+#include <drm/drm_syncobj.h>
#include <drm/i915_drm.h>
#include "i915_drv.h"
@@ -191,6 +192,8 @@ struct i915_execbuffer {
struct drm_file *file; /** per-file lookup tables and limits */
struct drm_i915_gem_execbuffer2 *args; /** ioctl parameters */
struct drm_i915_gem_exec_object2 *exec; /** ioctl execobj[] */
+ struct i915_vma **vma;
+ unsigned int *flags;
struct intel_engine_cs *engine; /** engine to queue the request to */
struct i915_gem_context *ctx; /** context for building the request */
@@ -244,13 +247,7 @@ struct i915_execbuffer {
struct hlist_head *buckets; /** ht for relocation handles */
};
-/*
- * As an alternative to creating a hashtable of handle-to-vma for a batch,
- * we used the last available reserved field in the execobject[] and stash
- * a link from the execobj to its vma.
- */
-#define __exec_to_vma(ee) (ee)->rsvd2
-#define exec_to_vma(ee) u64_to_ptr(struct i915_vma, __exec_to_vma(ee))
+#define exec_entry(EB, VMA) (&(EB)->exec[(VMA)->exec_flags - (EB)->flags])
/*
* Used to convert any address to canonical form.
@@ -319,85 +316,82 @@ static int eb_create(struct i915_execbuffer *eb)
static bool
eb_vma_misplaced(const struct drm_i915_gem_exec_object2 *entry,
- const struct i915_vma *vma)
+ const struct i915_vma *vma,
+ unsigned int flags)
{
- if (!(entry->flags & __EXEC_OBJECT_HAS_PIN))
- return true;
-
if (vma->node.size < entry->pad_to_size)
return true;
if (entry->alignment && !IS_ALIGNED(vma->node.start, entry->alignment))
return true;
- if (entry->flags & EXEC_OBJECT_PINNED &&
+ if (flags & EXEC_OBJECT_PINNED &&
vma->node.start != entry->offset)
return true;
- if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS &&
+ if (flags & __EXEC_OBJECT_NEEDS_BIAS &&
vma->node.start < BATCH_OFFSET_BIAS)
return true;
- if (!(entry->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS) &&
+ if (!(flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS) &&
(vma->node.start + vma->node.size - 1) >> 32)
return true;
return false;
}
-static inline void
+static inline bool
eb_pin_vma(struct i915_execbuffer *eb,
- struct drm_i915_gem_exec_object2 *entry,
+ const struct drm_i915_gem_exec_object2 *entry,
struct i915_vma *vma)
{
- u64 flags;
+ unsigned int exec_flags = *vma->exec_flags;
+ u64 pin_flags;
if (vma->node.size)
- flags = vma->node.start;
+ pin_flags = vma->node.start;
else
- flags = entry->offset & PIN_OFFSET_MASK;
+ pin_flags = entry->offset & PIN_OFFSET_MASK;
- flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED;
- if (unlikely(entry->flags & EXEC_OBJECT_NEEDS_GTT))
- flags |= PIN_GLOBAL;
+ pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED;
+ if (unlikely(exec_flags & EXEC_OBJECT_NEEDS_GTT))
+ pin_flags |= PIN_GLOBAL;
- if (unlikely(i915_vma_pin(vma, 0, 0, flags)))
- return;
+ if (unlikely(i915_vma_pin(vma, 0, 0, pin_flags)))
+ return false;
- if (unlikely(entry->flags & EXEC_OBJECT_NEEDS_FENCE)) {
+ if (unlikely(exec_flags & EXEC_OBJECT_NEEDS_FENCE)) {
if (unlikely(i915_vma_get_fence(vma))) {
i915_vma_unpin(vma);
- return;
+ return false;
}
if (i915_vma_pin_fence(vma))
- entry->flags |= __EXEC_OBJECT_HAS_FENCE;
+ exec_flags |= __EXEC_OBJECT_HAS_FENCE;
}
- entry->flags |= __EXEC_OBJECT_HAS_PIN;
+ *vma->exec_flags = exec_flags | __EXEC_OBJECT_HAS_PIN;
+ return !eb_vma_misplaced(entry, vma, exec_flags);
}
-static inline void
-__eb_unreserve_vma(struct i915_vma *vma,
- const struct drm_i915_gem_exec_object2 *entry)
+static inline void __eb_unreserve_vma(struct i915_vma *vma, unsigned int flags)
{
- GEM_BUG_ON(!(entry->flags & __EXEC_OBJECT_HAS_PIN));
+ GEM_BUG_ON(!(flags & __EXEC_OBJECT_HAS_PIN));
- if (unlikely(entry->flags & __EXEC_OBJECT_HAS_FENCE))
+ if (unlikely(flags & __EXEC_OBJECT_HAS_FENCE))
i915_vma_unpin_fence(vma);
__i915_vma_unpin(vma);
}
static inline void
-eb_unreserve_vma(struct i915_vma *vma,
- struct drm_i915_gem_exec_object2 *entry)
+eb_unreserve_vma(struct i915_vma *vma, unsigned int *flags)
{
- if (!(entry->flags & __EXEC_OBJECT_HAS_PIN))
+ if (!(*flags & __EXEC_OBJECT_HAS_PIN))
return;
- __eb_unreserve_vma(vma, entry);
- entry->flags &= ~__EXEC_OBJECT_RESERVED;
+ __eb_unreserve_vma(vma, *flags);
+ *flags &= ~__EXEC_OBJECT_RESERVED;
}
static int
@@ -427,7 +421,7 @@ eb_validate_vma(struct i915_execbuffer *eb,
entry->pad_to_size = 0;
}
- if (unlikely(vma->exec_entry)) {
+ if (unlikely(vma->exec_flags)) {
DRM_DEBUG("Object [handle %d, index %d] appears more than once in object list\n",
entry->handle, (int)(entry - eb->exec));
return -EINVAL;
@@ -440,14 +434,25 @@ eb_validate_vma(struct i915_execbuffer *eb,
*/
entry->offset = gen8_noncanonical_addr(entry->offset);
+ if (!eb->reloc_cache.has_fence) {
+ entry->flags &= ~EXEC_OBJECT_NEEDS_FENCE;
+ } else {
+ if ((entry->flags & EXEC_OBJECT_NEEDS_FENCE ||
+ eb->reloc_cache.needs_unfenced) &&
+ i915_gem_object_is_tiled(vma->obj))
+ entry->flags |= EXEC_OBJECT_NEEDS_GTT | __EXEC_OBJECT_NEEDS_MAP;
+ }
+
+ if (!(entry->flags & EXEC_OBJECT_PINNED))
+ entry->flags |= eb->context_flags;
+
return 0;
}
static int
-eb_add_vma(struct i915_execbuffer *eb,
- struct drm_i915_gem_exec_object2 *entry,
- struct i915_vma *vma)
+eb_add_vma(struct i915_execbuffer *eb, unsigned int i, struct i915_vma *vma)
{
+ struct drm_i915_gem_exec_object2 *entry = &eb->exec[i];
int err;
GEM_BUG_ON(i915_vma_is_closed(vma));
@@ -468,40 +473,28 @@ eb_add_vma(struct i915_execbuffer *eb,
if (entry->relocation_count)
list_add_tail(&vma->reloc_link, &eb->relocs);
- if (!eb->reloc_cache.has_fence) {
- entry->flags &= ~EXEC_OBJECT_NEEDS_FENCE;
- } else {
- if ((entry->flags & EXEC_OBJECT_NEEDS_FENCE ||
- eb->reloc_cache.needs_unfenced) &&
- i915_gem_object_is_tiled(vma->obj))
- entry->flags |= EXEC_OBJECT_NEEDS_GTT | __EXEC_OBJECT_NEEDS_MAP;
- }
-
- if (!(entry->flags & EXEC_OBJECT_PINNED))
- entry->flags |= eb->context_flags;
-
/*
* Stash a pointer from the vma to execobj, so we can query its flags,
* size, alignment etc as provided by the user. Also we stash a pointer
* to the vma inside the execobj so that we can use a direct lookup
* to find the right target VMA when doing relocations.
*/
- vma->exec_entry = entry;
- __exec_to_vma(entry) = (uintptr_t)vma;
+ eb->vma[i] = vma;
+ eb->flags[i] = entry->flags;
+ vma->exec_flags = &eb->flags[i];
err = 0;
- eb_pin_vma(eb, entry, vma);
- if (eb_vma_misplaced(entry, vma)) {
- eb_unreserve_vma(vma, entry);
-
- list_add_tail(&vma->exec_link, &eb->unbound);
- if (drm_mm_node_allocated(&vma->node))
- err = i915_vma_unbind(vma);
- } else {
+ if (eb_pin_vma(eb, entry, vma)) {
if (entry->offset != vma->node.start) {
entry->offset = vma->node.start | UPDATE;
eb->args->flags |= __EXEC_HAS_RELOC;
}
+ } else {
+ eb_unreserve_vma(vma, vma->exec_flags);
+
+ list_add_tail(&vma->exec_link, &eb->unbound);
+ if (drm_mm_node_allocated(&vma->node))
+ err = i915_vma_unbind(vma);
}
return err;
}
@@ -526,32 +519,35 @@ static inline int use_cpu_reloc(const struct reloc_cache *cache,
static int eb_reserve_vma(const struct i915_execbuffer *eb,
struct i915_vma *vma)
{
- struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
- u64 flags;
+ struct drm_i915_gem_exec_object2 *entry = exec_entry(eb, vma);
+ unsigned int exec_flags = *vma->exec_flags;
+ u64 pin_flags;
int err;
- flags = PIN_USER | PIN_NONBLOCK;
- if (entry->flags & EXEC_OBJECT_NEEDS_GTT)
- flags |= PIN_GLOBAL;
+ pin_flags = PIN_USER | PIN_NONBLOCK;
+ if (exec_flags & EXEC_OBJECT_NEEDS_GTT)
+ pin_flags |= PIN_GLOBAL;
/*
* Wa32bitGeneralStateOffset & Wa32bitInstructionBaseOffset,
* limit address to the first 4GBs for unflagged objects.
*/
- if (!(entry->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
- flags |= PIN_ZONE_4G;
+ if (!(exec_flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
+ pin_flags |= PIN_ZONE_4G;
- if (entry->flags & __EXEC_OBJECT_NEEDS_MAP)
- flags |= PIN_MAPPABLE;
+ if (exec_flags & __EXEC_OBJECT_NEEDS_MAP)
+ pin_flags |= PIN_MAPPABLE;
- if (entry->flags & EXEC_OBJECT_PINNED) {
- flags |= entry->offset | PIN_OFFSET_FIXED;
- flags &= ~PIN_NONBLOCK; /* force overlapping PINNED checks */
- } else if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) {
- flags |= BATCH_OFFSET_BIAS | PIN_OFFSET_BIAS;
+ if (exec_flags & EXEC_OBJECT_PINNED) {
+ pin_flags |= entry->offset | PIN_OFFSET_FIXED;
+ pin_flags &= ~PIN_NONBLOCK; /* force overlapping checks */
+ } else if (exec_flags & __EXEC_OBJECT_NEEDS_BIAS) {
+ pin_flags |= BATCH_OFFSET_BIAS | PIN_OFFSET_BIAS;
}
- err = i915_vma_pin(vma, entry->pad_to_size, entry->alignment, flags);
+ err = i915_vma_pin(vma,
+ entry->pad_to_size, entry->alignment,
+ pin_flags);
if (err)
return err;
@@ -560,10 +556,7 @@ static int eb_reserve_vma(const struct i915_execbuffer *eb,
eb->args->flags |= __EXEC_HAS_RELOC;
}
- entry->flags |= __EXEC_OBJECT_HAS_PIN;
- GEM_BUG_ON(eb_vma_misplaced(entry, vma));
-
- if (unlikely(entry->flags & EXEC_OBJECT_NEEDS_FENCE)) {
+ if (unlikely(exec_flags & EXEC_OBJECT_NEEDS_FENCE)) {
err = i915_vma_get_fence(vma);
if (unlikely(err)) {
i915_vma_unpin(vma);
@@ -571,9 +564,12 @@ static int eb_reserve_vma(const struct i915_execbuffer *eb,
}
if (i915_vma_pin_fence(vma))
- entry->flags |= __EXEC_OBJECT_HAS_FENCE;
+ exec_flags |= __EXEC_OBJECT_HAS_FENCE;
}
+ *vma->exec_flags = exec_flags | __EXEC_OBJECT_HAS_PIN;
+ GEM_BUG_ON(eb_vma_misplaced(entry, vma, exec_flags));
+
return 0;
}
@@ -614,18 +610,18 @@ static int eb_reserve(struct i915_execbuffer *eb)
INIT_LIST_HEAD(&eb->unbound);
INIT_LIST_HEAD(&last);
for (i = 0; i < count; i++) {
- struct drm_i915_gem_exec_object2 *entry = &eb->exec[i];
+ unsigned int flags = eb->flags[i];
+ struct i915_vma *vma = eb->vma[i];
- if (entry->flags & EXEC_OBJECT_PINNED &&
- entry->flags & __EXEC_OBJECT_HAS_PIN)
+ if (flags & EXEC_OBJECT_PINNED &&
+ flags & __EXEC_OBJECT_HAS_PIN)
continue;
- vma = exec_to_vma(entry);
- eb_unreserve_vma(vma, entry);
+ eb_unreserve_vma(vma, &eb->flags[i]);
- if (entry->flags & EXEC_OBJECT_PINNED)
+ if (flags & EXEC_OBJECT_PINNED)
list_add(&vma->exec_link, &eb->unbound);
- else if (entry->flags & __EXEC_OBJECT_NEEDS_MAP)
+ else if (flags & __EXEC_OBJECT_NEEDS_MAP)
list_add_tail(&vma->exec_link, &eb->unbound);
else
list_add_tail(&vma->exec_link, &last);
@@ -649,19 +645,6 @@ static int eb_reserve(struct i915_execbuffer *eb)
} while (1);
}
-static inline struct hlist_head *
-ht_head(const struct i915_gem_context_vma_lut *lut, u32 handle)
-{
- return &lut->ht[hash_32(handle, lut->ht_bits)];
-}
-
-static inline bool
-ht_needs_resize(const struct i915_gem_context_vma_lut *lut)
-{
- return (4*lut->ht_count > 3*lut->ht_size ||
- 4*lut->ht_count + 1 < lut->ht_size);
-}
-
static unsigned int eb_batch_index(const struct i915_execbuffer *eb)
{
if (eb->args->flags & I915_EXEC_BATCH_FIRST)
@@ -675,16 +658,10 @@ static int eb_select_context(struct i915_execbuffer *eb)
struct i915_gem_context *ctx;
ctx = i915_gem_context_lookup(eb->file->driver_priv, eb->args->rsvd1);
- if (unlikely(IS_ERR(ctx)))
- return PTR_ERR(ctx);
-
- if (unlikely(i915_gem_context_is_banned(ctx))) {
- DRM_DEBUG("Context %u tried to submit while banned\n",
- ctx->user_handle);
- return -EIO;
- }
+ if (unlikely(!ctx))
+ return -ENOENT;
- eb->ctx = i915_gem_context_get(ctx);
+ eb->ctx = ctx;
eb->vm = ctx->ppgtt ? &ctx->ppgtt->base : &eb->i915->ggtt.base;
eb->context_flags = 0;
@@ -696,132 +673,74 @@ static int eb_select_context(struct i915_execbuffer *eb)
static int eb_lookup_vmas(struct i915_execbuffer *eb)
{
-#define INTERMEDIATE BIT(0)
- const unsigned int count = eb->buffer_count;
- struct i915_gem_context_vma_lut *lut = &eb->ctx->vma_lut;
- struct i915_vma *vma;
- struct idr *idr;
+ struct radix_tree_root *handles_vma = &eb->ctx->handles_vma;
+ struct drm_i915_gem_object *uninitialized_var(obj);
unsigned int i;
- int slow_pass = -1;
int err;
- INIT_LIST_HEAD(&eb->relocs);
- INIT_LIST_HEAD(&eb->unbound);
-
- if (unlikely(lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS))
- flush_work(&lut->resize);
- GEM_BUG_ON(lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS);
-
- for (i = 0; i < count; i++) {
- __exec_to_vma(&eb->exec[i]) = 0;
-
- hlist_for_each_entry(vma,
- ht_head(lut, eb->exec[i].handle),
- ctx_node) {
- if (vma->ctx_handle != eb->exec[i].handle)
- continue;
-
- err = eb_add_vma(eb, &eb->exec[i], vma);
- if (unlikely(err))
- return err;
-
- goto next_vma;
- }
+ if (unlikely(i915_gem_context_is_closed(eb->ctx)))
+ return -ENOENT;
- if (slow_pass < 0)
- slow_pass = i;
-next_vma: ;
- }
+ if (unlikely(i915_gem_context_is_banned(eb->ctx)))
+ return -EIO;
- if (slow_pass < 0)
- goto out;
+ INIT_LIST_HEAD(&eb->relocs);
+ INIT_LIST_HEAD(&eb->unbound);
- spin_lock(&eb->file->table_lock);
- /*
- * Grab a reference to the object and release the lock so we can lookup
- * or create the VMA without using GFP_ATOMIC
- */
- idr = &eb->file->object_idr;
- for (i = slow_pass; i < count; i++) {
- struct drm_i915_gem_object *obj;
+ for (i = 0; i < eb->buffer_count; i++) {
+ u32 handle = eb->exec[i].handle;
+ struct i915_lut_handle *lut;
+ struct i915_vma *vma;
- if (__exec_to_vma(&eb->exec[i]))
- continue;
+ vma = radix_tree_lookup(handles_vma, handle);
+ if (likely(vma))
+ goto add_vma;
- obj = to_intel_bo(idr_find(idr, eb->exec[i].handle));
+ obj = i915_gem_object_lookup(eb->file, handle);
if (unlikely(!obj)) {
- spin_unlock(&eb->file->table_lock);
- DRM_DEBUG("Invalid object handle %d at index %d\n",
- eb->exec[i].handle, i);
err = -ENOENT;
- goto err;
+ goto err_vma;
}
- __exec_to_vma(&eb->exec[i]) = INTERMEDIATE | (uintptr_t)obj;
- }
- spin_unlock(&eb->file->table_lock);
-
- for (i = slow_pass; i < count; i++) {
- struct drm_i915_gem_object *obj;
-
- if (!(__exec_to_vma(&eb->exec[i]) & INTERMEDIATE))
- continue;
-
- /*
- * NOTE: We can leak any vmas created here when something fails
- * later on. But that's no issue since vma_unbind can deal with
- * vmas which are not actually bound. And since only
- * lookup_or_create exists as an interface to get at the vma
- * from the (obj, vm) we don't run the risk of creating
- * duplicated vmas for the same vm.
- */
- obj = u64_to_ptr(typeof(*obj),
- __exec_to_vma(&eb->exec[i]) & ~INTERMEDIATE);
vma = i915_vma_instance(obj, eb->vm, NULL);
if (unlikely(IS_ERR(vma))) {
- DRM_DEBUG("Failed to lookup VMA\n");
err = PTR_ERR(vma);
- goto err;
+ goto err_obj;
}
- /* First come, first served */
- if (!vma->ctx) {
- vma->ctx = eb->ctx;
- vma->ctx_handle = eb->exec[i].handle;
- hlist_add_head(&vma->ctx_node,
- ht_head(lut, eb->exec[i].handle));
- lut->ht_count++;
- lut->ht_size |= I915_CTX_RESIZE_IN_PROGRESS;
- if (i915_vma_is_ggtt(vma)) {
- GEM_BUG_ON(obj->vma_hashed);
- obj->vma_hashed = vma;
- }
+ lut = kmem_cache_alloc(eb->i915->luts, GFP_KERNEL);
+ if (unlikely(!lut)) {
+ err = -ENOMEM;
+ goto err_obj;
+ }
- i915_vma_get(vma);
+ err = radix_tree_insert(handles_vma, handle, vma);
+ if (unlikely(err)) {
+ kfree(lut);
+ goto err_obj;
}
- err = eb_add_vma(eb, &eb->exec[i], vma);
- if (unlikely(err))
- goto err;
+ list_add(&lut->obj_link, &obj->lut_list);
+ list_add(&lut->ctx_link, &eb->ctx->handles_list);
+ lut->ctx = eb->ctx;
+ lut->handle = handle;
- /* Only after we validated the user didn't use our bits */
- if (vma->ctx != eb->ctx) {
- i915_vma_get(vma);
- eb->exec[i].flags |= __EXEC_OBJECT_HAS_REF;
- }
- }
+ /* transfer ref to ctx */
+ obj = NULL;
- if (lut->ht_size & I915_CTX_RESIZE_IN_PROGRESS) {
- if (ht_needs_resize(lut))
- queue_work(system_highpri_wq, &lut->resize);
- else
- lut->ht_size &= ~I915_CTX_RESIZE_IN_PROGRESS;
+add_vma:
+ err = eb_add_vma(eb, i, vma);
+ if (unlikely(err))
+ goto err_obj;
+
+ GEM_BUG_ON(vma != eb->vma[i]);
+ GEM_BUG_ON(vma->exec_flags != &eb->flags[i]);
}
-out:
/* take note of the batch buffer before we might reorder the lists */
i = eb_batch_index(eb);
- eb->batch = exec_to_vma(&eb->exec[i]);
+ eb->batch = eb->vma[i];
+ GEM_BUG_ON(eb->batch->exec_flags != &eb->flags[i]);
/*
* SNA is doing fancy tricks with compressing batch buffers, which leads
@@ -832,22 +751,20 @@ out:
* Note that actual hangs have only been observed on gen7, but for
* paranoia do it everywhere.
*/
- if (!(eb->exec[i].flags & EXEC_OBJECT_PINNED))
- eb->exec[i].flags |= __EXEC_OBJECT_NEEDS_BIAS;
+ if (!(eb->flags[i] & EXEC_OBJECT_PINNED))
+ eb->flags[i] |= __EXEC_OBJECT_NEEDS_BIAS;
if (eb->reloc_cache.has_fence)
- eb->exec[i].flags |= EXEC_OBJECT_NEEDS_FENCE;
+ eb->flags[i] |= EXEC_OBJECT_NEEDS_FENCE;
eb->args->flags |= __EXEC_VALIDATED;
return eb_reserve(eb);
-err:
- for (i = slow_pass; i < count; i++) {
- if (__exec_to_vma(&eb->exec[i]) & INTERMEDIATE)
- __exec_to_vma(&eb->exec[i]) = 0;
- }
- lut->ht_size &= ~I915_CTX_RESIZE_IN_PROGRESS;
+err_obj:
+ if (obj)
+ i915_gem_object_put(obj);
+err_vma:
+ eb->vma[i] = NULL;
return err;
-#undef INTERMEDIATE
}
static struct i915_vma *
@@ -856,7 +773,7 @@ eb_get_vma(const struct i915_execbuffer *eb, unsigned long handle)
if (eb->lut_size < 0) {
if (handle >= -eb->lut_size)
return NULL;
- return exec_to_vma(&eb->exec[handle]);
+ return eb->vma[handle];
} else {
struct hlist_head *head;
struct i915_vma *vma;
@@ -876,24 +793,21 @@ static void eb_release_vmas(const struct i915_execbuffer *eb)
unsigned int i;
for (i = 0; i < count; i++) {
- struct drm_i915_gem_exec_object2 *entry = &eb->exec[i];
- struct i915_vma *vma = exec_to_vma(entry);
+ struct i915_vma *vma = eb->vma[i];
+ unsigned int flags = eb->flags[i];
if (!vma)
- continue;
+ break;
- GEM_BUG_ON(vma->exec_entry != entry);
- vma->exec_entry = NULL;
- __exec_to_vma(entry) = 0;
+ GEM_BUG_ON(vma->exec_flags != &eb->flags[i]);
+ vma->exec_flags = NULL;
+ eb->vma[i] = NULL;
- if (entry->flags & __EXEC_OBJECT_HAS_PIN)
- __eb_unreserve_vma(vma, entry);
+ if (flags & __EXEC_OBJECT_HAS_PIN)
+ __eb_unreserve_vma(vma, flags);
- if (entry->flags & __EXEC_OBJECT_HAS_REF)
+ if (flags & __EXEC_OBJECT_HAS_REF)
i915_vma_put(vma);
-
- entry->flags &=
- ~(__EXEC_OBJECT_RESERVED | __EXEC_OBJECT_HAS_REF);
}
}
@@ -1266,7 +1180,9 @@ relocate_entry(struct i915_vma *vma,
if (!eb->reloc_cache.vaddr &&
(DBG_FORCE_RELOC == FORCE_GPU_RELOC ||
- !reservation_object_test_signaled_rcu(vma->resv, true))) {
+ !reservation_object_test_signaled_rcu(vma->resv, true)) &&
+ __intel_engine_can_store_dword(eb->reloc_cache.gen,
+ eb->engine->class)) {
const unsigned int gen = eb->reloc_cache.gen;
unsigned int len;
u32 *batch;
@@ -1276,10 +1192,8 @@ relocate_entry(struct i915_vma *vma,
len = offset & 7 ? 8 : 5;
else if (gen >= 4)
len = 4;
- else if (gen >= 3)
+ else
len = 3;
- else /* On gen2 MI_STORE_DWORD_IMM uses a physical address */
- goto repeat;
batch = reloc_gpu(eb, vma, len);
if (IS_ERR(batch))
@@ -1382,7 +1296,7 @@ eb_relocate_entry(struct i915_execbuffer *eb,
}
if (reloc->write_domain) {
- target->exec_entry->flags |= EXEC_OBJECT_WRITE;
+ *target->exec_flags |= EXEC_OBJECT_WRITE;
/*
* Sandybridge PPGTT errata: We need a global gtt mapping
@@ -1432,9 +1346,9 @@ eb_relocate_entry(struct i915_execbuffer *eb,
* patching using the GPU (though that should be serialised by the
* timeline). To be completely sure, and since we are required to
* do relocations we are already stalling, disable the user's opt
- * of our synchronisation.
+ * out of our synchronisation.
*/
- vma->exec_entry->flags &= ~EXEC_OBJECT_ASYNC;
+ *vma->exec_flags &= ~EXEC_OBJECT_ASYNC;
/* and update the user's relocation entry */
return relocate_entry(vma, reloc, eb, target);
@@ -1445,7 +1359,7 @@ static int eb_relocate_vma(struct i915_execbuffer *eb, struct i915_vma *vma)
#define N_RELOC(x) ((x) / sizeof(struct drm_i915_gem_relocation_entry))
struct drm_i915_gem_relocation_entry stack[N_RELOC(512)];
struct drm_i915_gem_relocation_entry __user *urelocs;
- const struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
+ const struct drm_i915_gem_exec_object2 *entry = exec_entry(eb, vma);
unsigned int remain;
urelocs = u64_to_user_ptr(entry->relocs_ptr);
@@ -1458,7 +1372,7 @@ static int eb_relocate_vma(struct i915_execbuffer *eb, struct i915_vma *vma)
* to read. However, if the array is not writable the user loses
* the updated relocation values.
*/
- if (unlikely(!access_ok(VERIFY_READ, urelocs, remain*sizeof(urelocs))))
+ if (unlikely(!access_ok(VERIFY_READ, urelocs, remain*sizeof(*urelocs))))
return -EFAULT;
do {
@@ -1528,7 +1442,7 @@ out:
static int
eb_relocate_vma_slow(struct i915_execbuffer *eb, struct i915_vma *vma)
{
- const struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
+ const struct drm_i915_gem_exec_object2 *entry = exec_entry(eb, vma);
struct drm_i915_gem_relocation_entry *relocs =
u64_to_ptr(typeof(*relocs), entry->relocs_ptr);
unsigned int i;
@@ -1732,6 +1646,8 @@ repeat:
if (err)
goto err;
+ GEM_BUG_ON(!eb->batch);
+
list_for_each_entry(vma, &eb->relocs, reloc_link) {
if (!have_copy) {
pagefault_disable();
@@ -1775,7 +1691,7 @@ out:
}
}
- return err ?: have_copy;
+ return err;
}
static int eb_relocate(struct i915_execbuffer *eb)
@@ -1825,11 +1741,11 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb)
int err;
for (i = 0; i < count; i++) {
- const struct drm_i915_gem_exec_object2 *entry = &eb->exec[i];
- struct i915_vma *vma = exec_to_vma(entry);
+ unsigned int flags = eb->flags[i];
+ struct i915_vma *vma = eb->vma[i];
struct drm_i915_gem_object *obj = vma->obj;
- if (entry->flags & EXEC_OBJECT_CAPTURE) {
+ if (flags & EXEC_OBJECT_CAPTURE) {
struct i915_gem_capture_list *capture;
capture = kmalloc(sizeof(*capture), GFP_KERNEL);
@@ -1837,33 +1753,47 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb)
return -ENOMEM;
capture->next = eb->request->capture_list;
- capture->vma = vma;
+ capture->vma = eb->vma[i];
eb->request->capture_list = capture;
}
- if (entry->flags & EXEC_OBJECT_ASYNC)
- goto skip_flushes;
+ /*
+ * If the GPU is not _reading_ through the CPU cache, we need
+ * to make sure that any writes (both previous GPU writes from
+ * before a change in snooping levels and normal CPU writes)
+ * caught in that cache are flushed to main memory.
+ *
+ * We want to say
+ * obj->cache_dirty &&
+ * !(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)
+ * but gcc's optimiser doesn't handle that as well and emits
+ * two jumps instead of one. Maybe one day...
+ */
+ if (unlikely(obj->cache_dirty & ~obj->cache_coherent)) {
+ if (i915_gem_clflush_object(obj, 0))
+ flags &= ~EXEC_OBJECT_ASYNC;
+ }
- if (unlikely(obj->cache_dirty && !obj->cache_coherent))
- i915_gem_clflush_object(obj, 0);
+ if (flags & EXEC_OBJECT_ASYNC)
+ continue;
err = i915_gem_request_await_object
- (eb->request, obj, entry->flags & EXEC_OBJECT_WRITE);
+ (eb->request, obj, flags & EXEC_OBJECT_WRITE);
if (err)
return err;
-
-skip_flushes:
- i915_vma_move_to_active(vma, eb->request, entry->flags);
- __eb_unreserve_vma(vma, entry);
- vma->exec_entry = NULL;
}
for (i = 0; i < count; i++) {
- const struct drm_i915_gem_exec_object2 *entry = &eb->exec[i];
- struct i915_vma *vma = exec_to_vma(entry);
+ unsigned int flags = eb->flags[i];
+ struct i915_vma *vma = eb->vma[i];
+
+ i915_vma_move_to_active(vma, eb->request, flags);
+ eb_export_fence(vma, eb->request, flags);
- eb_export_fence(vma, eb->request, entry->flags);
- if (unlikely(entry->flags & __EXEC_OBJECT_HAS_REF))
+ __eb_unreserve_vma(vma, flags);
+ vma->exec_flags = NULL;
+
+ if (unlikely(flags & __EXEC_OBJECT_HAS_REF))
i915_vma_put(vma);
}
eb->exec = NULL;
@@ -1881,8 +1811,10 @@ static bool i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec)
return false;
/* Kernel clipping was a DRI1 misfeature */
- if (exec->num_cliprects || exec->cliprects_ptr)
- return false;
+ if (!(exec->flags & I915_EXEC_FENCE_ARRAY)) {
+ if (exec->num_cliprects || exec->cliprects_ptr)
+ return false;
+ }
if (exec->DR4 == 0xffffffff) {
DRM_DEBUG("UXA submitting garbage DR4, fixing up\n");
@@ -1990,11 +1922,11 @@ static struct i915_vma *eb_parse(struct i915_execbuffer *eb, bool is_master)
if (IS_ERR(vma))
goto out;
- vma->exec_entry =
- memset(&eb->exec[eb->buffer_count++],
- 0, sizeof(*vma->exec_entry));
- vma->exec_entry->flags = __EXEC_OBJECT_HAS_PIN | __EXEC_OBJECT_HAS_REF;
- __exec_to_vma(vma->exec_entry) = (uintptr_t)i915_vma_get(vma);
+ eb->vma[eb->buffer_count] = i915_vma_get(vma);
+ eb->flags[eb->buffer_count] =
+ __EXEC_OBJECT_HAS_PIN | __EXEC_OBJECT_HAS_REF;
+ vma->exec_flags = &eb->flags[eb->buffer_count];
+ eb->buffer_count++;
out:
i915_gem_object_unpin_pages(shadow_batch_obj);
@@ -2113,11 +2045,131 @@ eb_select_engine(struct drm_i915_private *dev_priv,
return engine;
}
+static void
+__free_fence_array(struct drm_syncobj **fences, unsigned int n)
+{
+ while (n--)
+ drm_syncobj_put(ptr_mask_bits(fences[n], 2));
+ kvfree(fences);
+}
+
+static struct drm_syncobj **
+get_fence_array(struct drm_i915_gem_execbuffer2 *args,
+ struct drm_file *file)
+{
+ const unsigned int nfences = args->num_cliprects;
+ struct drm_i915_gem_exec_fence __user *user;
+ struct drm_syncobj **fences;
+ unsigned int n;
+ int err;
+
+ if (!(args->flags & I915_EXEC_FENCE_ARRAY))
+ return NULL;
+
+ if (nfences > SIZE_MAX / sizeof(*fences))
+ return ERR_PTR(-EINVAL);
+
+ user = u64_to_user_ptr(args->cliprects_ptr);
+ if (!access_ok(VERIFY_READ, user, nfences * 2 * sizeof(u32)))
+ return ERR_PTR(-EFAULT);
+
+ fences = kvmalloc_array(args->num_cliprects, sizeof(*fences),
+ __GFP_NOWARN | GFP_TEMPORARY);
+ if (!fences)
+ return ERR_PTR(-ENOMEM);
+
+ for (n = 0; n < nfences; n++) {
+ struct drm_i915_gem_exec_fence fence;
+ struct drm_syncobj *syncobj;
+
+ if (__copy_from_user(&fence, user++, sizeof(fence))) {
+ err = -EFAULT;
+ goto err;
+ }
+
+ syncobj = drm_syncobj_find(file, fence.handle);
+ if (!syncobj) {
+ DRM_DEBUG("Invalid syncobj handle provided\n");
+ err = -ENOENT;
+ goto err;
+ }
+
+ fences[n] = ptr_pack_bits(syncobj, fence.flags, 2);
+ }
+
+ return fences;
+
+err:
+ __free_fence_array(fences, n);
+ return ERR_PTR(err);
+}
+
+static void
+put_fence_array(struct drm_i915_gem_execbuffer2 *args,
+ struct drm_syncobj **fences)
+{
+ if (fences)
+ __free_fence_array(fences, args->num_cliprects);
+}
+
+static int
+await_fence_array(struct i915_execbuffer *eb,
+ struct drm_syncobj **fences)
+{
+ const unsigned int nfences = eb->args->num_cliprects;
+ unsigned int n;
+ int err;
+
+ for (n = 0; n < nfences; n++) {
+ struct drm_syncobj *syncobj;
+ struct dma_fence *fence;
+ unsigned int flags;
+
+ syncobj = ptr_unpack_bits(fences[n], &flags, 2);
+ if (!(flags & I915_EXEC_FENCE_WAIT))
+ continue;
+
+ rcu_read_lock();
+ fence = dma_fence_get_rcu_safe(&syncobj->fence);
+ rcu_read_unlock();
+ if (!fence)
+ return -EINVAL;
+
+ err = i915_gem_request_await_dma_fence(eb->request, fence);
+ dma_fence_put(fence);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+static void
+signal_fence_array(struct i915_execbuffer *eb,
+ struct drm_syncobj **fences)
+{
+ const unsigned int nfences = eb->args->num_cliprects;
+ struct dma_fence * const fence = &eb->request->fence;
+ unsigned int n;
+
+ for (n = 0; n < nfences; n++) {
+ struct drm_syncobj *syncobj;
+ unsigned int flags;
+
+ syncobj = ptr_unpack_bits(fences[n], &flags, 2);
+ if (!(flags & I915_EXEC_FENCE_SIGNAL))
+ continue;
+
+ drm_syncobj_replace_fence(syncobj, fence);
+ }
+}
+
static int
i915_gem_do_execbuffer(struct drm_device *dev,
struct drm_file *file,
struct drm_i915_gem_execbuffer2 *args,
- struct drm_i915_gem_exec_object2 *exec)
+ struct drm_i915_gem_exec_object2 *exec,
+ struct drm_syncobj **fences)
{
struct i915_execbuffer eb;
struct dma_fence *in_fence = NULL;
@@ -2133,8 +2185,12 @@ i915_gem_do_execbuffer(struct drm_device *dev,
eb.args = args;
if (DBG_FORCE_RELOC || !(args->flags & I915_EXEC_NO_RELOC))
args->flags |= __EXEC_HAS_RELOC;
+
eb.exec = exec;
- eb.ctx = NULL;
+ eb.vma = (struct i915_vma **)(exec + args->buffer_count + 1);
+ eb.vma[0] = NULL;
+ eb.flags = (unsigned int *)(eb.vma + args->buffer_count + 1);
+
eb.invalid_flags = __EXEC_OBJECT_UNKNOWN_FLAGS;
if (USES_FULL_PPGTT(eb.i915))
eb.invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
@@ -2192,6 +2248,10 @@ i915_gem_do_execbuffer(struct drm_device *dev,
GEM_BUG_ON(!eb.lut_size);
+ err = eb_select_context(&eb);
+ if (unlikely(err))
+ goto err_destroy;
+
/*
* Take a local wakeref for preparing to dispatch the execbuf as
* we expect to access the hardware fairly frequently in the
@@ -2200,16 +2260,13 @@ i915_gem_do_execbuffer(struct drm_device *dev,
* 100ms.
*/
intel_runtime_pm_get(eb.i915);
+
err = i915_mutex_lock_interruptible(dev);
if (err)
goto err_rpm;
- err = eb_select_context(&eb);
- if (unlikely(err))
- goto err_unlock;
-
err = eb_relocate(&eb);
- if (err)
+ if (err) {
/*
* If the user expects the execobject.offset and
* reloc.presumed_offset to be an exact match,
@@ -2218,10 +2275,10 @@ i915_gem_do_execbuffer(struct drm_device *dev,
* relocation.
*/
args->flags &= ~__EXEC_HAS_RELOC;
- if (err < 0)
goto err_vma;
+ }
- if (unlikely(eb.batch->exec_entry->flags & EXEC_OBJECT_WRITE)) {
+ if (unlikely(*eb.batch->exec_flags & EXEC_OBJECT_WRITE)) {
DRM_DEBUG("Attempting to use self-modifying batch buffer\n");
err = -EINVAL;
goto err_vma;
@@ -2303,6 +2360,12 @@ i915_gem_do_execbuffer(struct drm_device *dev,
goto err_request;
}
+ if (fences) {
+ err = await_fence_array(&eb, fences);
+ if (err)
+ goto err_request;
+ }
+
if (out_fence_fd != -1) {
out_fence = sync_file_create(&eb.request->fence);
if (!out_fence) {
@@ -2326,6 +2389,9 @@ err_request:
__i915_add_request(eb.request, err == 0);
add_to_client(eb.request, file);
+ if (fences)
+ signal_fence_array(&eb, fences);
+
if (out_fence) {
if (err == 0) {
fd_install(out_fence_fd, out_fence->file);
@@ -2343,11 +2409,11 @@ err_batch_unpin:
err_vma:
if (eb.exec)
eb_release_vmas(&eb);
- i915_gem_context_put(eb.ctx);
-err_unlock:
mutex_unlock(&dev->struct_mutex);
err_rpm:
intel_runtime_pm_put(eb.i915);
+ i915_gem_context_put(eb.ctx);
+err_destroy:
eb_destroy(&eb);
err_out_fence:
if (out_fence_fd != -1)
@@ -2365,7 +2431,9 @@ int
i915_gem_execbuffer(struct drm_device *dev, void *data,
struct drm_file *file)
{
- const size_t sz = sizeof(struct drm_i915_gem_exec_object2);
+ const size_t sz = (sizeof(struct drm_i915_gem_exec_object2) +
+ sizeof(struct i915_vma *) +
+ sizeof(unsigned int));
struct drm_i915_gem_execbuffer *args = data;
struct drm_i915_gem_execbuffer2 exec2;
struct drm_i915_gem_exec_object *exec_list = NULL;
@@ -2427,7 +2495,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
exec2_list[i].flags = 0;
}
- err = i915_gem_do_execbuffer(dev, file, &exec2, exec2_list);
+ err = i915_gem_do_execbuffer(dev, file, &exec2, exec2_list, NULL);
if (exec2.flags & __EXEC_HAS_RELOC) {
struct drm_i915_gem_exec_object __user *user_exec_list =
u64_to_user_ptr(args->buffers_ptr);
@@ -2456,9 +2524,12 @@ int
i915_gem_execbuffer2(struct drm_device *dev, void *data,
struct drm_file *file)
{
- const size_t sz = sizeof(struct drm_i915_gem_exec_object2);
+ const size_t sz = (sizeof(struct drm_i915_gem_exec_object2) +
+ sizeof(struct i915_vma *) +
+ sizeof(unsigned int));
struct drm_i915_gem_execbuffer2 *args = data;
struct drm_i915_gem_exec_object2 *exec2_list;
+ struct drm_syncobj **fences = NULL;
int err;
if (args->buffer_count < 1 || args->buffer_count > SIZE_MAX / sz - 1) {
@@ -2485,7 +2556,15 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data,
return -EFAULT;
}
- err = i915_gem_do_execbuffer(dev, file, args, exec2_list);
+ if (args->flags & I915_EXEC_FENCE_ARRAY) {
+ fences = get_fence_array(args, file);
+ if (IS_ERR(fences)) {
+ kvfree(exec2_list);
+ return PTR_ERR(fences);
+ }
+ }
+
+ err = i915_gem_do_execbuffer(dev, file, args, exec2_list, fences);
/*
* Now that we have begun execution of the batchbuffer, we ignore
@@ -2515,6 +2594,7 @@ end_user:
}
args->flags &= ~__I915_EXEC_UNKNOWN_FLAGS;
+ put_fence_array(args, fences);
kvfree(exec2_list);
return err;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 61fc7e90a7da..d60f38adc4c4 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -144,9 +144,9 @@ int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv,
has_full_48bit_ppgtt = dev_priv->info.has_full_48bit_ppgtt;
if (intel_vgpu_active(dev_priv)) {
- /* emulation is too hard */
+ /* GVT-g has no support for 32bit ppgtt */
has_full_ppgtt = false;
- has_full_48bit_ppgtt = false;
+ has_full_48bit_ppgtt = intel_vgpu_has_full_48bit_ppgtt(dev_priv);
}
if (!has_aliasing_ppgtt)
@@ -180,10 +180,15 @@ int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv,
return 0;
}
- if (INTEL_GEN(dev_priv) >= 8 && i915.enable_execlists && has_full_ppgtt)
- return has_full_48bit_ppgtt ? 3 : 2;
- else
- return has_aliasing_ppgtt ? 1 : 0;
+ if (INTEL_GEN(dev_priv) >= 8 && i915.enable_execlists) {
+ if (has_full_48bit_ppgtt)
+ return 3;
+
+ if (has_full_ppgtt)
+ return 2;
+ }
+
+ return has_aliasing_ppgtt ? 1 : 0;
}
static int ppgtt_bind_vma(struct i915_vma *vma,
@@ -207,8 +212,7 @@ static int ppgtt_bind_vma(struct i915_vma *vma,
if (vma->obj->gt_ro)
pte_flags |= PTE_READ_ONLY;
- vma->vm->insert_entries(vma->vm, vma->pages, vma->node.start,
- cache_level, pte_flags);
+ vma->vm->insert_entries(vma->vm, vma, cache_level, pte_flags);
return 0;
}
@@ -907,37 +911,35 @@ gen8_ppgtt_insert_pte_entries(struct i915_hw_ppgtt *ppgtt,
}
static void gen8_ppgtt_insert_3lvl(struct i915_address_space *vm,
- struct sg_table *pages,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level cache_level,
u32 unused)
{
struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
struct sgt_dma iter = {
- .sg = pages->sgl,
+ .sg = vma->pages->sgl,
.dma = sg_dma_address(iter.sg),
.max = iter.dma + iter.sg->length,
};
- struct gen8_insert_pte idx = gen8_insert_pte(start);
+ struct gen8_insert_pte idx = gen8_insert_pte(vma->node.start);
gen8_ppgtt_insert_pte_entries(ppgtt, &ppgtt->pdp, &iter, &idx,
cache_level);
}
static void gen8_ppgtt_insert_4lvl(struct i915_address_space *vm,
- struct sg_table *pages,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level cache_level,
u32 unused)
{
struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
struct sgt_dma iter = {
- .sg = pages->sgl,
+ .sg = vma->pages->sgl,
.dma = sg_dma_address(iter.sg),
.max = iter.dma + iter.sg->length,
};
struct i915_page_directory_pointer **pdps = ppgtt->pml4.pdps;
- struct gen8_insert_pte idx = gen8_insert_pte(start);
+ struct gen8_insert_pte idx = gen8_insert_pte(vma->node.start);
while (gen8_ppgtt_insert_pte_entries(ppgtt, pdps[idx.pml4e++], &iter,
&idx, cache_level))
@@ -1621,13 +1623,12 @@ static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
}
static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
- struct sg_table *pages,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level cache_level,
u32 flags)
{
struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
- unsigned first_entry = start >> PAGE_SHIFT;
+ unsigned first_entry = vma->node.start >> PAGE_SHIFT;
unsigned act_pt = first_entry / GEN6_PTES;
unsigned act_pte = first_entry % GEN6_PTES;
const u32 pte_encode = vm->pte_encode(0, cache_level, flags);
@@ -1635,7 +1636,7 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
gen6_pte_t *vaddr;
vaddr = kmap_atomic_px(ppgtt->pd.page_table[act_pt]);
- iter.sg = pages->sgl;
+ iter.sg = vma->pages->sgl;
iter.dma = sg_dma_address(iter.sg);
iter.max = iter.dma + iter.sg->length;
do {
@@ -2090,8 +2091,7 @@ static void gen8_ggtt_insert_page(struct i915_address_space *vm,
}
static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
- struct sg_table *st,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level level,
u32 unused)
{
@@ -2102,8 +2102,8 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
dma_addr_t addr;
gtt_entries = (gen8_pte_t __iomem *)ggtt->gsm;
- gtt_entries += start >> PAGE_SHIFT;
- for_each_sgt_dma(addr, sgt_iter, st)
+ gtt_entries += vma->node.start >> PAGE_SHIFT;
+ for_each_sgt_dma(addr, sgt_iter, vma->pages)
gen8_set_pte(gtt_entries++, pte_encode | addr);
wmb();
@@ -2137,17 +2137,16 @@ static void gen6_ggtt_insert_page(struct i915_address_space *vm,
* mapped BAR (dev_priv->mm.gtt->gtt).
*/
static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
- struct sg_table *st,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level level,
u32 flags)
{
struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
gen6_pte_t __iomem *entries = (gen6_pte_t __iomem *)ggtt->gsm;
- unsigned int i = start >> PAGE_SHIFT;
+ unsigned int i = vma->node.start >> PAGE_SHIFT;
struct sgt_iter iter;
dma_addr_t addr;
- for_each_sgt_dma(addr, iter, st)
+ for_each_sgt_dma(addr, iter, vma->pages)
iowrite32(vm->pte_encode(addr, level, flags), &entries[i++]);
wmb();
@@ -2229,8 +2228,7 @@ static void bxt_vtd_ggtt_insert_page__BKL(struct i915_address_space *vm,
struct insert_entries {
struct i915_address_space *vm;
- struct sg_table *st;
- u64 start;
+ struct i915_vma *vma;
enum i915_cache_level level;
};
@@ -2238,19 +2236,18 @@ static int bxt_vtd_ggtt_insert_entries__cb(void *_arg)
{
struct insert_entries *arg = _arg;
- gen8_ggtt_insert_entries(arg->vm, arg->st, arg->start, arg->level, 0);
+ gen8_ggtt_insert_entries(arg->vm, arg->vma, arg->level, 0);
bxt_vtd_ggtt_wa(arg->vm);
return 0;
}
static void bxt_vtd_ggtt_insert_entries__BKL(struct i915_address_space *vm,
- struct sg_table *st,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level level,
u32 unused)
{
- struct insert_entries arg = { vm, st, start, level };
+ struct insert_entries arg = { vm, vma, level };
stop_machine(bxt_vtd_ggtt_insert_entries__cb, &arg, NULL);
}
@@ -2316,15 +2313,15 @@ static void i915_ggtt_insert_page(struct i915_address_space *vm,
}
static void i915_ggtt_insert_entries(struct i915_address_space *vm,
- struct sg_table *pages,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level cache_level,
u32 unused)
{
unsigned int flags = (cache_level == I915_CACHE_NONE) ?
AGP_USER_MEMORY : AGP_USER_CACHED_MEMORY;
- intel_gtt_insert_sg_entries(pages, start >> PAGE_SHIFT, flags);
+ intel_gtt_insert_sg_entries(vma->pages, vma->node.start >> PAGE_SHIFT,
+ flags);
}
static void i915_ggtt_clear_range(struct i915_address_space *vm,
@@ -2353,8 +2350,7 @@ static int ggtt_bind_vma(struct i915_vma *vma,
pte_flags |= PTE_READ_ONLY;
intel_runtime_pm_get(i915);
- vma->vm->insert_entries(vma->vm, vma->pages, vma->node.start,
- cache_level, pte_flags);
+ vma->vm->insert_entries(vma->vm, vma, cache_level, pte_flags);
intel_runtime_pm_put(i915);
/*
@@ -2407,16 +2403,13 @@ static int aliasing_gtt_bind_vma(struct i915_vma *vma,
goto err_pages;
}
- appgtt->base.insert_entries(&appgtt->base,
- vma->pages, vma->node.start,
- cache_level, pte_flags);
+ appgtt->base.insert_entries(&appgtt->base, vma, cache_level,
+ pte_flags);
}
if (flags & I915_VMA_GLOBAL_BIND) {
intel_runtime_pm_get(i915);
- vma->vm->insert_entries(vma->vm,
- vma->pages, vma->node.start,
- cache_level, pte_flags);
+ vma->vm->insert_entries(vma->vm, vma, cache_level, pte_flags);
intel_runtime_pm_put(i915);
}
@@ -2749,6 +2742,24 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
return 0;
}
+static void cnl_setup_private_ppat(struct drm_i915_private *dev_priv)
+{
+ /* XXX: spec is unclear if this is still needed for CNL+ */
+ if (!USES_PPGTT(dev_priv)) {
+ I915_WRITE(GEN10_PAT_INDEX(0), GEN8_PPAT_UC);
+ return;
+ }
+
+ I915_WRITE(GEN10_PAT_INDEX(0), GEN8_PPAT_WB | GEN8_PPAT_LLC);
+ I915_WRITE(GEN10_PAT_INDEX(1), GEN8_PPAT_WC | GEN8_PPAT_LLCELLC);
+ I915_WRITE(GEN10_PAT_INDEX(2), GEN8_PPAT_WT | GEN8_PPAT_LLCELLC);
+ I915_WRITE(GEN10_PAT_INDEX(3), GEN8_PPAT_UC);
+ I915_WRITE(GEN10_PAT_INDEX(4), GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0));
+ I915_WRITE(GEN10_PAT_INDEX(5), GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(1));
+ I915_WRITE(GEN10_PAT_INDEX(6), GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(2));
+ I915_WRITE(GEN10_PAT_INDEX(7), GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3));
+}
+
/* The GGTT and PPGTT need a private PPAT setup in order to handle cacheability
* bits. When using advanced contexts each context stores its own PAT, but
* writing this data shouldn't be harmful even in those cases. */
@@ -2863,7 +2874,9 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
ggtt->base.total = (size / sizeof(gen8_pte_t)) << PAGE_SHIFT;
- if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 10)
+ cnl_setup_private_ppat(dev_priv);
+ else if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv))
chv_setup_private_ppat(dev_priv);
else
bdw_setup_private_ppat(dev_priv);
@@ -3145,7 +3158,9 @@ void i915_gem_restore_gtt_mappings(struct drm_i915_private *dev_priv)
ggtt->base.closed = false;
if (INTEL_GEN(dev_priv) >= 8) {
- if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 10)
+ cnl_setup_private_ppat(dev_priv);
+ else if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv))
chv_setup_private_ppat(dev_priv);
else
bdw_setup_private_ppat(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 1b2a56c3e5d3..b4e3aa7c0ce1 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -313,8 +313,7 @@ struct i915_address_space {
enum i915_cache_level cache_level,
u32 flags);
void (*insert_entries)(struct i915_address_space *vm,
- struct sg_table *st,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level cache_level,
u32 flags);
void (*cleanup)(struct i915_address_space *vm);
diff --git a/drivers/gpu/drm/i915/i915_gem_internal.c b/drivers/gpu/drm/i915/i915_gem_internal.c
index 568bf83af1f5..c1f64ddaf8aa 100644
--- a/drivers/gpu/drm/i915/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/i915_gem_internal.c
@@ -174,6 +174,7 @@ i915_gem_object_create_internal(struct drm_i915_private *i915,
phys_addr_t size)
{
struct drm_i915_gem_object *obj;
+ unsigned int cache_level;
GEM_BUG_ON(!size);
GEM_BUG_ON(!IS_ALIGNED(size, PAGE_SIZE));
@@ -190,9 +191,9 @@ i915_gem_object_create_internal(struct drm_i915_private *i915,
obj->base.read_domains = I915_GEM_DOMAIN_CPU;
obj->base.write_domain = I915_GEM_DOMAIN_CPU;
- obj->cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
- obj->cache_coherent = i915_gem_object_is_coherent(obj);
- obj->cache_dirty = !obj->cache_coherent;
+
+ cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
+ i915_gem_object_set_cache_coherency(obj, cache_level);
return obj;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_object.c b/drivers/gpu/drm/i915/i915_gem_object.c
new file mode 100644
index 000000000000..aab8cdd80e6d
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gem_object.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ */
+
+#include "i915_drv.h"
+#include "i915_gem_object.h"
+
+/**
+ * Mark up the object's coherency levels for a given cache_level
+ * @obj: #drm_i915_gem_object
+ * @cache_level: cache level
+ */
+void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj,
+ unsigned int cache_level)
+{
+ obj->cache_level = cache_level;
+
+ if (cache_level != I915_CACHE_NONE)
+ obj->cache_coherent = (I915_BO_CACHE_COHERENT_FOR_READ |
+ I915_BO_CACHE_COHERENT_FOR_WRITE);
+ else if (HAS_LLC(to_i915(obj->base.dev)))
+ obj->cache_coherent = I915_BO_CACHE_COHERENT_FOR_READ;
+ else
+ obj->cache_coherent = 0;
+
+ obj->cache_dirty =
+ !(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE);
+}
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index 5b19a4916a4d..c30d8f808185 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -33,8 +33,24 @@
#include <drm/i915_drm.h>
+#include "i915_gem_request.h"
#include "i915_selftest.h"
+struct drm_i915_gem_object;
+
+/*
+ * struct i915_lut_handle tracks the fast lookups from handle to vma used
+ * for execbuf. Although we use a radixtree for that mapping, in order to
+ * remove them as the object or context is closed, we need a secondary list
+ * and a translation entry (i915_lut_handle).
+ */
+struct i915_lut_handle {
+ struct list_head obj_link;
+ struct list_head ctx_link;
+ struct i915_gem_context *ctx;
+ u32 handle;
+};
+
struct drm_i915_gem_object_ops {
unsigned int flags;
#define I915_GEM_OBJECT_HAS_STRUCT_PAGE BIT(0)
@@ -86,7 +102,15 @@ struct drm_i915_gem_object {
* They are also added to @vma_list for easy iteration.
*/
struct rb_root vma_tree;
- struct i915_vma *vma_hashed;
+
+ /**
+ * @lut_list: List of vma lookup entries in use for this object.
+ *
+ * If this object is closed, we need to remove all of its VMA from
+ * the fast lookup index in associated contexts; @lut_list provides
+ * this translation from object to context->handles_vma.
+ */
+ struct list_head lut_list;
/** Stolen memory for this object, instead of being backed by shmem. */
struct drm_mm_node *stolen;
@@ -118,8 +142,10 @@ struct drm_i915_gem_object {
*/
unsigned long gt_ro:1;
unsigned int cache_level:3;
+ unsigned int cache_coherent:2;
+#define I915_BO_CACHE_COHERENT_FOR_READ BIT(0)
+#define I915_BO_CACHE_COHERENT_FOR_WRITE BIT(1)
unsigned int cache_dirty:1;
- unsigned int cache_coherent:1;
atomic_t frontbuffer_bits;
unsigned int frontbuffer_ggtt_origin; /* write once */
@@ -391,6 +417,8 @@ i915_gem_object_last_write_engine(struct drm_i915_gem_object *obj)
return engine;
}
+void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj,
+ unsigned int cache_level);
void i915_gem_object_flush_if_display(struct drm_i915_gem_object *obj);
#endif
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c
index 7032c542a9b1..4dd4c2159a92 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.c
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
@@ -242,6 +242,10 @@ int i915_gem_render_state_emit(struct drm_i915_gem_request *req)
goto err_unpin;
}
+ ret = req->engine->emit_flush(req, EMIT_INVALIDATE);
+ if (ret)
+ goto err_unpin;
+
ret = req->engine->emit_bb_start(req,
so->batch_offset, so->batch_size,
I915_DISPATCH_SECURE);
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 8c59c79cbd8b..813a3b546d6e 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -213,6 +213,10 @@ static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno)
cond_resched();
}
+ /* Check we are idle before we fiddle with hw state! */
+ GEM_BUG_ON(!intel_engine_is_idle(engine));
+ GEM_BUG_ON(i915_gem_active_isset(&engine->timeline->last_request));
+
/* Finally reset hw state */
intel_engine_init_global_seqno(engine, seqno);
tl->seqno = seqno;
@@ -240,27 +244,60 @@ int i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno)
return reset_all_global_seqno(dev_priv, seqno - 1);
}
-static int reserve_seqno(struct intel_engine_cs *engine)
+static void mark_busy(struct drm_i915_private *i915)
{
+ if (i915->gt.awake)
+ return;
+
+ GEM_BUG_ON(!i915->gt.active_requests);
+
+ intel_runtime_pm_get_noresume(i915);
+ i915->gt.awake = true;
+
+ intel_enable_gt_powersave(i915);
+ i915_update_gfx_val(i915);
+ if (INTEL_GEN(i915) >= 6)
+ gen6_rps_busy(i915);
+
+ queue_delayed_work(i915->wq,
+ &i915->gt.retire_work,
+ round_jiffies_up_relative(HZ));
+}
+
+static int reserve_engine(struct intel_engine_cs *engine)
+{
+ struct drm_i915_private *i915 = engine->i915;
u32 active = ++engine->timeline->inflight_seqnos;
u32 seqno = engine->timeline->seqno;
int ret;
/* Reservation is fine until we need to wrap around */
- if (likely(!add_overflows(seqno, active)))
- return 0;
-
- ret = reset_all_global_seqno(engine->i915, 0);
- if (ret) {
- engine->timeline->inflight_seqnos--;
- return ret;
+ if (unlikely(add_overflows(seqno, active))) {
+ ret = reset_all_global_seqno(i915, 0);
+ if (ret) {
+ engine->timeline->inflight_seqnos--;
+ return ret;
+ }
}
+ if (!i915->gt.active_requests++)
+ mark_busy(i915);
+
return 0;
}
-static void unreserve_seqno(struct intel_engine_cs *engine)
+static void unreserve_engine(struct intel_engine_cs *engine)
{
+ struct drm_i915_private *i915 = engine->i915;
+
+ if (!--i915->gt.active_requests) {
+ /* Cancel the mark_busy() from our reserve_engine() */
+ GEM_BUG_ON(!i915->gt.awake);
+ mod_delayed_work(i915->wq,
+ &i915->gt.idle_work,
+ msecs_to_jiffies(100));
+ }
+
GEM_BUG_ON(!engine->timeline->inflight_seqnos);
engine->timeline->inflight_seqnos--;
}
@@ -329,13 +366,7 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
list_del_init(&request->link);
spin_unlock_irq(&engine->timeline->lock);
- if (!--request->i915->gt.active_requests) {
- GEM_BUG_ON(!request->i915->gt.awake);
- mod_delayed_work(request->i915->wq,
- &request->i915->gt.idle_work,
- msecs_to_jiffies(100));
- }
- unreserve_seqno(request->engine);
+ unreserve_engine(request->engine);
advance_ring(request);
free_capture_list(request);
@@ -370,8 +401,7 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
i915_gem_request_remove_from_client(request);
/* Retirement decays the ban score as it is a sign of ctx progress */
- if (request->ctx->ban_score > 0)
- request->ctx->ban_score--;
+ atomic_dec_if_positive(&request->ctx->ban_score);
/* The backing object for the context is done after switching to the
* *next* context. Therefore we cannot retire the previous context until
@@ -384,7 +414,11 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
engine->context_unpin(engine, engine->last_retired_context);
engine->last_retired_context = request->ctx;
- dma_fence_signal(&request->fence);
+ spin_lock_irq(&request->lock);
+ if (request->waitboost)
+ atomic_dec(&request->i915->rps.num_waiters);
+ dma_fence_signal_locked(&request->fence);
+ spin_unlock_irq(&request->lock);
i915_priotree_fini(request->i915, &request->priotree);
i915_gem_request_put(request);
@@ -568,7 +602,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
return ERR_CAST(ring);
GEM_BUG_ON(!ring);
- ret = reserve_seqno(engine);
+ ret = reserve_engine(engine);
if (ret)
goto err_unpin;
@@ -639,6 +673,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
req->file_priv = NULL;
req->batch = NULL;
req->capture_list = NULL;
+ req->waitboost = false;
/*
* Reserve space in the ring buffer for all the commands required to
@@ -673,7 +708,7 @@ err_ctx:
kmem_cache_free(dev_priv->requests, req);
err_unreserve:
- unreserve_seqno(engine);
+ unreserve_engine(engine);
err_unpin:
engine->context_unpin(engine, ctx);
return ERR_PTR(ret);
@@ -855,28 +890,6 @@ i915_gem_request_await_object(struct drm_i915_gem_request *to,
return ret;
}
-static void i915_gem_mark_busy(const struct intel_engine_cs *engine)
-{
- struct drm_i915_private *dev_priv = engine->i915;
-
- if (dev_priv->gt.awake)
- return;
-
- GEM_BUG_ON(!dev_priv->gt.active_requests);
-
- intel_runtime_pm_get_noresume(dev_priv);
- dev_priv->gt.awake = true;
-
- intel_enable_gt_powersave(dev_priv);
- i915_update_gfx_val(dev_priv);
- if (INTEL_GEN(dev_priv) >= 6)
- gen6_rps_busy(dev_priv);
-
- queue_delayed_work(dev_priv->wq,
- &dev_priv->gt.retire_work,
- round_jiffies_up_relative(HZ));
-}
-
/*
* NB: This function is not allowed to fail. Doing so would mean the the
* request is not being tracked for completion but the work itself is
@@ -958,9 +971,6 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
list_add_tail(&request->ring_link, &ring->request_list);
request->emitted_jiffies = jiffies;
- if (!request->i915->gt.active_requests++)
- i915_gem_mark_busy(engine);
-
/* Let the backend know a new request has arrived that may need
* to adjust the existing execution schedule due to a high priority
* request - i.e. we may want to preempt the current request in order
@@ -1063,7 +1073,7 @@ static bool __i915_wait_request_check_and_reset(struct drm_i915_gem_request *req
return false;
__set_current_state(TASK_RUNNING);
- i915_reset(request->i915);
+ i915_reset(request->i915, 0);
return true;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h
index 7579b9702c22..49a4c8994ff0 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.h
+++ b/drivers/gpu/drm/i915/i915_gem_request.h
@@ -184,6 +184,8 @@ struct drm_i915_gem_request {
/** Time at which this request was emitted, in jiffies. */
unsigned long emitted_jiffies;
+ bool waitboost;
+
/** engine->request_list entry for this request */
struct list_head link;
diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c
index 1032f98add11..77fb39808131 100644
--- a/drivers/gpu/drm/i915/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c
@@ -43,16 +43,21 @@ static bool shrinker_lock(struct drm_i915_private *dev_priv, bool *unlock)
return true;
case MUTEX_TRYLOCK_FAILED:
+ *unlock = false;
+ preempt_disable();
do {
cpu_relax();
if (mutex_trylock(&dev_priv->drm.struct_mutex)) {
- case MUTEX_TRYLOCK_SUCCESS:
*unlock = true;
- return true;
+ break;
}
} while (!need_resched());
+ preempt_enable();
+ return *unlock;
- return false;
+ case MUTEX_TRYLOCK_SUCCESS:
+ *unlock = true;
+ return true;
}
BUG();
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index a817b3e0b17e..507c9f0d8df1 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -254,9 +254,10 @@ static dma_addr_t i915_stolen_to_dma(struct drm_i915_private *dev_priv)
* This is a BIOS w/a: Some BIOS wrap stolen in the root
* PCI bus, but have an off-by-one error. Hence retry the
* reservation starting from 1 instead of 0.
+ * There's also BIOS with off-by-one on the other end.
*/
r = devm_request_mem_region(dev_priv->drm.dev, base + 1,
- ggtt->stolen_size - 1,
+ ggtt->stolen_size - 2,
"Graphics Stolen Memory");
/*
* GEN3 firmware likes to smash pci bridges into the stolen
@@ -579,6 +580,7 @@ _i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
struct drm_mm_node *stolen)
{
struct drm_i915_gem_object *obj;
+ unsigned int cache_level;
obj = i915_gem_object_alloc(dev_priv);
if (obj == NULL)
@@ -589,8 +591,8 @@ _i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
obj->stolen = stolen;
obj->base.read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
- obj->cache_level = HAS_LLC(dev_priv) ? I915_CACHE_LLC : I915_CACHE_NONE;
- obj->cache_coherent = true; /* assumptions! more like cache_oblivious */
+ cache_level = HAS_LLC(dev_priv) ? I915_CACHE_LLC : I915_CACHE_NONE;
+ i915_gem_object_set_cache_coherency(obj, cache_level);
if (i915_gem_object_pin_pages(obj))
goto cleanup;
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
index ccd09e8419f5..f152a38d7079 100644
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -804,9 +804,7 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file
i915_gem_object_init(obj, &i915_gem_userptr_ops);
obj->base.read_domains = I915_GEM_DOMAIN_CPU;
obj->base.write_domain = I915_GEM_DOMAIN_CPU;
- obj->cache_level = I915_CACHE_LLC;
- obj->cache_coherent = i915_gem_object_is_coherent(obj);
- obj->cache_dirty = !obj->cache_coherent;
+ i915_gem_object_set_cache_coherency(obj, I915_CACHE_LLC);
obj->userptr.ptr = args->user_ptr;
obj->userptr.read_only = !!(args->flags & I915_USERPTR_READ_ONLY);
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index e18f350bc364..ed5a1eb839ad 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -463,6 +463,7 @@ static void error_print_engine(struct drm_i915_error_state_buf *m,
err_printf(m, " hangcheck action timestamp: %lu, %u ms ago\n",
ee->hangcheck_timestamp,
jiffies_to_msecs(jiffies - ee->hangcheck_timestamp));
+ err_printf(m, " engine reset count: %u\n", ee->reset_count);
error_print_request(m, " ELSP[0]: ", &ee->execlist[0]);
error_print_request(m, " ELSP[1]: ", &ee->execlist[1]);
@@ -1236,6 +1237,8 @@ static void error_record_engine_registers(struct i915_gpu_state *error,
ee->hangcheck_timestamp = engine->hangcheck.action_timestamp;
ee->hangcheck_action = engine->hangcheck.action;
ee->hangcheck_stalled = engine->hangcheck.stalled;
+ ee->reset_count = i915_reset_engine_count(&dev_priv->gpu_error,
+ engine);
if (USES_PPGTT(dev_priv)) {
int i;
@@ -1263,7 +1266,7 @@ static void record_request(struct drm_i915_gem_request *request,
struct drm_i915_error_request *erq)
{
erq->context = request->ctx->hw_id;
- erq->ban_score = request->ctx->ban_score;
+ erq->ban_score = atomic_read(&request->ctx->ban_score);
erq->seqno = request->global_seqno;
erq->jiffies = request->emitted_jiffies;
erq->head = request->head;
@@ -1354,9 +1357,9 @@ static void record_context(struct drm_i915_error_context *e,
e->handle = ctx->user_handle;
e->hw_id = ctx->hw_id;
- e->ban_score = ctx->ban_score;
- e->guilty = ctx->guilty_count;
- e->active = ctx->active_count;
+ e->ban_score = atomic_read(&ctx->ban_score);
+ e->guilty = atomic_read(&ctx->guilty_count);
+ e->active = atomic_read(&ctx->active_count);
}
static void request_record_user_bo(struct drm_i915_gem_request *request,
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 4cd9ee1ba332..e21ce9c18b6e 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -275,17 +275,17 @@ void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask)
static i915_reg_t gen6_pm_iir(struct drm_i915_private *dev_priv)
{
- return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR;
+ return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR;
}
static i915_reg_t gen6_pm_imr(struct drm_i915_private *dev_priv)
{
- return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IMR(2) : GEN6_PMIMR;
+ return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IMR(2) : GEN6_PMIMR;
}
static i915_reg_t gen6_pm_ier(struct drm_i915_private *dev_priv)
{
- return INTEL_INFO(dev_priv)->gen >= 8 ? GEN8_GT_IER(2) : GEN6_PMIER;
+ return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IER(2) : GEN6_PMIER;
}
/**
@@ -1091,18 +1091,6 @@ static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir)
return events;
}
-static bool any_waiters(struct drm_i915_private *dev_priv)
-{
- struct intel_engine_cs *engine;
- enum intel_engine_id id;
-
- for_each_engine(engine, dev_priv, id)
- if (intel_engine_has_waiter(engine))
- return true;
-
- return false;
-}
-
static void gen6_pm_rps_work(struct work_struct *work)
{
struct drm_i915_private *dev_priv =
@@ -1114,7 +1102,7 @@ static void gen6_pm_rps_work(struct work_struct *work)
spin_lock_irq(&dev_priv->irq_lock);
if (dev_priv->rps.interrupts_enabled) {
pm_iir = fetch_and_zero(&dev_priv->rps.pm_iir);
- client_boost = fetch_and_zero(&dev_priv->rps.client_boost);
+ client_boost = atomic_read(&dev_priv->rps.num_waiters);
}
spin_unlock_irq(&dev_priv->irq_lock);
@@ -1131,7 +1119,7 @@ static void gen6_pm_rps_work(struct work_struct *work)
new_delay = dev_priv->rps.cur_freq;
min = dev_priv->rps.min_freq_softlimit;
max = dev_priv->rps.max_freq_softlimit;
- if (client_boost || any_waiters(dev_priv))
+ if (client_boost)
max = dev_priv->rps.max_freq;
if (client_boost && new_delay < dev_priv->rps.boost_freq) {
new_delay = dev_priv->rps.boost_freq;
@@ -1144,7 +1132,7 @@ static void gen6_pm_rps_work(struct work_struct *work)
if (new_delay >= dev_priv->rps.max_freq_softlimit)
adj = 0;
- } else if (client_boost || any_waiters(dev_priv)) {
+ } else if (client_boost) {
adj = 0;
} else if (pm_iir & GEN6_PM_RP_DOWN_TIMEOUT) {
if (dev_priv->rps.cur_freq > dev_priv->rps.efficient_freq)
@@ -1513,7 +1501,8 @@ static void intel_get_hpd_pins(u32 *pin_mask, u32 *long_mask,
*pin_mask |= BIT(i);
- if (!intel_hpd_pin_to_port(i, &port))
+ port = intel_hpd_pin_to_port(i);
+ if (port == PORT_NONE)
continue;
if (long_pulse_detect(port, dig_hotplug_reg))
@@ -1603,7 +1592,7 @@ static void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv,
crcs[3] = crc3;
crcs[4] = crc4;
drm_crtc_add_crc_entry(&crtc->base, true,
- drm_accurate_vblank_count(&crtc->base),
+ drm_crtc_accurate_vblank_count(&crtc->base),
crcs);
}
}
@@ -1673,7 +1662,7 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
spin_unlock(&dev_priv->irq_lock);
}
- if (INTEL_INFO(dev_priv)->gen >= 8)
+ if (INTEL_GEN(dev_priv) >= 8)
return;
if (HAS_VEBOX(dev_priv)) {
@@ -1720,18 +1709,6 @@ static void gen9_guc_irq_handler(struct drm_i915_private *dev_priv, u32 gt_iir)
}
}
-static bool intel_pipe_handle_vblank(struct drm_i915_private *dev_priv,
- enum pipe pipe)
-{
- bool ret;
-
- ret = drm_handle_vblank(&dev_priv->drm, pipe);
- if (ret)
- intel_finish_page_flip_mmio(dev_priv, pipe);
-
- return ret;
-}
-
static void valleyview_pipestat_irq_ack(struct drm_i915_private *dev_priv,
u32 iir, u32 pipe_stats[I915_MAX_PIPES])
{
@@ -1796,12 +1773,8 @@ static void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv,
enum pipe pipe;
for_each_pipe(dev_priv, pipe) {
- if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS &&
- intel_pipe_handle_vblank(dev_priv, pipe))
- intel_check_page_flip(dev_priv, pipe);
-
- if (pipe_stats[pipe] & PLANE_FLIP_DONE_INT_STATUS_VLV)
- intel_finish_page_flip_cs(dev_priv, pipe);
+ if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS)
+ drm_handle_vblank(&dev_priv->drm, pipe);
if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
i9xx_pipe_crc_irq_handler(dev_priv, pipe);
@@ -2098,10 +2071,10 @@ static void ibx_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
DRM_DEBUG_DRIVER("PCH transcoder CRC error interrupt\n");
if (pch_iir & SDE_TRANSA_FIFO_UNDER)
- intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_A);
+ intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_A);
if (pch_iir & SDE_TRANSB_FIFO_UNDER)
- intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_B);
+ intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_B);
}
static void ivb_err_int_handler(struct drm_i915_private *dev_priv)
@@ -2135,13 +2108,13 @@ static void cpt_serr_int_handler(struct drm_i915_private *dev_priv)
DRM_ERROR("PCH poison interrupt\n");
if (serr_int & SERR_INT_TRANS_A_FIFO_UNDERRUN)
- intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_A);
+ intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_A);
if (serr_int & SERR_INT_TRANS_B_FIFO_UNDERRUN)
- intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_B);
+ intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_B);
if (serr_int & SERR_INT_TRANS_C_FIFO_UNDERRUN)
- intel_pch_fifo_underrun_irq_handler(dev_priv, TRANSCODER_C);
+ intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_C);
I915_WRITE(SERR_INT, serr_int);
}
@@ -2253,19 +2226,14 @@ static void ilk_display_irq_handler(struct drm_i915_private *dev_priv,
DRM_ERROR("Poison interrupt\n");
for_each_pipe(dev_priv, pipe) {
- if (de_iir & DE_PIPE_VBLANK(pipe) &&
- intel_pipe_handle_vblank(dev_priv, pipe))
- intel_check_page_flip(dev_priv, pipe);
+ if (de_iir & DE_PIPE_VBLANK(pipe))
+ drm_handle_vblank(&dev_priv->drm, pipe);
if (de_iir & DE_PIPE_FIFO_UNDERRUN(pipe))
intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
if (de_iir & DE_PIPE_CRC_DONE(pipe))
i9xx_pipe_crc_irq_handler(dev_priv, pipe);
-
- /* plane/pipes map 1:1 on ilk+ */
- if (de_iir & DE_PLANE_FLIP_DONE(pipe))
- intel_finish_page_flip_cs(dev_priv, pipe);
}
/* check event from PCH */
@@ -2304,13 +2272,8 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
intel_opregion_asle_intr(dev_priv);
for_each_pipe(dev_priv, pipe) {
- if (de_iir & (DE_PIPE_VBLANK_IVB(pipe)) &&
- intel_pipe_handle_vblank(dev_priv, pipe))
- intel_check_page_flip(dev_priv, pipe);
-
- /* plane/pipes map 1:1 on ilk+ */
- if (de_iir & DE_PLANE_FLIP_DONE_IVB(pipe))
- intel_finish_page_flip_cs(dev_priv, pipe);
+ if (de_iir & (DE_PIPE_VBLANK_IVB(pipe)))
+ drm_handle_vblank(&dev_priv->drm, pipe);
}
/* check event from PCH */
@@ -2452,7 +2415,7 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
ret = IRQ_HANDLED;
tmp_mask = GEN8_AUX_CHANNEL_A;
- if (INTEL_INFO(dev_priv)->gen >= 9)
+ if (INTEL_GEN(dev_priv) >= 9)
tmp_mask |= GEN9_AUX_CHANNEL_B |
GEN9_AUX_CHANNEL_C |
GEN9_AUX_CHANNEL_D;
@@ -2491,7 +2454,7 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
}
for_each_pipe(dev_priv, pipe) {
- u32 flip_done, fault_errors;
+ u32 fault_errors;
if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe)))
continue;
@@ -2505,18 +2468,8 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
ret = IRQ_HANDLED;
I915_WRITE(GEN8_DE_PIPE_IIR(pipe), iir);
- if (iir & GEN8_PIPE_VBLANK &&
- intel_pipe_handle_vblank(dev_priv, pipe))
- intel_check_page_flip(dev_priv, pipe);
-
- flip_done = iir;
- if (INTEL_INFO(dev_priv)->gen >= 9)
- flip_done &= GEN9_PIPE_PLANE1_FLIP_DONE;
- else
- flip_done &= GEN8_PIPE_PRIMARY_FLIP_DONE;
-
- if (flip_done)
- intel_finish_page_flip_cs(dev_priv, pipe);
+ if (iir & GEN8_PIPE_VBLANK)
+ drm_handle_vblank(&dev_priv->drm, pipe);
if (iir & GEN8_PIPE_CDCLK_CRC_DONE)
hsw_pipe_crc_irq_handler(dev_priv, pipe);
@@ -2525,7 +2478,7 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
fault_errors = iir;
- if (INTEL_INFO(dev_priv)->gen >= 9)
+ if (INTEL_GEN(dev_priv) >= 9)
fault_errors &= GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
else
fault_errors &= GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
@@ -2599,86 +2552,93 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
return ret;
}
+struct wedge_me {
+ struct delayed_work work;
+ struct drm_i915_private *i915;
+ const char *name;
+};
+
+static void wedge_me(struct work_struct *work)
+{
+ struct wedge_me *w = container_of(work, typeof(*w), work.work);
+
+ dev_err(w->i915->drm.dev,
+ "%s timed out, cancelling all in-flight rendering.\n",
+ w->name);
+ i915_gem_set_wedged(w->i915);
+}
+
+static void __init_wedge(struct wedge_me *w,
+ struct drm_i915_private *i915,
+ long timeout,
+ const char *name)
+{
+ w->i915 = i915;
+ w->name = name;
+
+ INIT_DELAYED_WORK_ONSTACK(&w->work, wedge_me);
+ schedule_delayed_work(&w->work, timeout);
+}
+
+static void __fini_wedge(struct wedge_me *w)
+{
+ cancel_delayed_work_sync(&w->work);
+ destroy_delayed_work_on_stack(&w->work);
+ w->i915 = NULL;
+}
+
+#define i915_wedge_on_timeout(W, DEV, TIMEOUT) \
+ for (__init_wedge((W), (DEV), (TIMEOUT), __func__); \
+ (W)->i915; \
+ __fini_wedge((W)))
+
/**
- * i915_reset_and_wakeup - do process context error handling work
+ * i915_reset_device - do process context error handling work
* @dev_priv: i915 device private
*
* Fire an error uevent so userspace can see that a hang or error
* was detected.
*/
-static void i915_reset_and_wakeup(struct drm_i915_private *dev_priv)
+static void i915_reset_device(struct drm_i915_private *dev_priv)
{
struct kobject *kobj = &dev_priv->drm.primary->kdev->kobj;
char *error_event[] = { I915_ERROR_UEVENT "=1", NULL };
char *reset_event[] = { I915_RESET_UEVENT "=1", NULL };
char *reset_done_event[] = { I915_ERROR_UEVENT "=0", NULL };
+ struct wedge_me w;
kobject_uevent_env(kobj, KOBJ_CHANGE, error_event);
DRM_DEBUG_DRIVER("resetting chip\n");
kobject_uevent_env(kobj, KOBJ_CHANGE, reset_event);
- intel_prepare_reset(dev_priv);
+ /* Use a watchdog to ensure that our reset completes */
+ i915_wedge_on_timeout(&w, dev_priv, 5*HZ) {
+ intel_prepare_reset(dev_priv);
- set_bit(I915_RESET_HANDOFF, &dev_priv->gpu_error.flags);
- wake_up_all(&dev_priv->gpu_error.wait_queue);
+ /* Signal that locked waiters should reset the GPU */
+ set_bit(I915_RESET_HANDOFF, &dev_priv->gpu_error.flags);
+ wake_up_all(&dev_priv->gpu_error.wait_queue);
- do {
- /*
- * All state reset _must_ be completed before we update the
- * reset counter, for otherwise waiters might miss the reset
- * pending state and not properly drop locks, resulting in
- * deadlocks with the reset work.
+ /* Wait for anyone holding the lock to wakeup, without
+ * blocking indefinitely on struct_mutex.
*/
- if (mutex_trylock(&dev_priv->drm.struct_mutex)) {
- i915_reset(dev_priv);
- mutex_unlock(&dev_priv->drm.struct_mutex);
- }
-
- /* We need to wait for anyone holding the lock to wakeup */
- } while (wait_on_bit_timeout(&dev_priv->gpu_error.flags,
- I915_RESET_HANDOFF,
- TASK_UNINTERRUPTIBLE,
- HZ));
+ do {
+ if (mutex_trylock(&dev_priv->drm.struct_mutex)) {
+ i915_reset(dev_priv, 0);
+ mutex_unlock(&dev_priv->drm.struct_mutex);
+ }
+ } while (wait_on_bit_timeout(&dev_priv->gpu_error.flags,
+ I915_RESET_HANDOFF,
+ TASK_UNINTERRUPTIBLE,
+ 1));
- intel_finish_reset(dev_priv);
+ intel_finish_reset(dev_priv);
+ }
if (!test_bit(I915_WEDGED, &dev_priv->gpu_error.flags))
kobject_uevent_env(kobj,
KOBJ_CHANGE, reset_done_event);
-
- /*
- * Note: The wake_up also serves as a memory barrier so that
- * waiters see the updated value of the dev_priv->gpu_error.
- */
- clear_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags);
- wake_up_all(&dev_priv->gpu_error.reset_queue);
-}
-
-static inline void
-i915_err_print_instdone(struct drm_i915_private *dev_priv,
- struct intel_instdone *instdone)
-{
- int slice;
- int subslice;
-
- pr_err(" INSTDONE: 0x%08x\n", instdone->instdone);
-
- if (INTEL_GEN(dev_priv) <= 3)
- return;
-
- pr_err(" SC_INSTDONE: 0x%08x\n", instdone->slice_common);
-
- if (INTEL_GEN(dev_priv) <= 6)
- return;
-
- for_each_instdone_slice_subslice(dev_priv, slice, subslice)
- pr_err(" SAMPLER_INSTDONE[%d][%d]: 0x%08x\n",
- slice, subslice, instdone->sampler[slice][subslice]);
-
- for_each_instdone_slice_subslice(dev_priv, slice, subslice)
- pr_err(" ROW_INSTDONE[%d][%d]: 0x%08x\n",
- slice, subslice, instdone->row[slice][subslice]);
}
static void i915_clear_error_registers(struct drm_i915_private *dev_priv)
@@ -2722,6 +2682,8 @@ void i915_handle_error(struct drm_i915_private *dev_priv,
u32 engine_mask,
const char *fmt, ...)
{
+ struct intel_engine_cs *engine;
+ unsigned int tmp;
va_list args;
char error_msg[80];
@@ -2741,14 +2703,56 @@ void i915_handle_error(struct drm_i915_private *dev_priv,
i915_capture_error_state(dev_priv, engine_mask, error_msg);
i915_clear_error_registers(dev_priv);
+ /*
+ * Try engine reset when available. We fall back to full reset if
+ * single reset fails.
+ */
+ if (intel_has_reset_engine(dev_priv)) {
+ for_each_engine_masked(engine, dev_priv, engine_mask, tmp) {
+ BUILD_BUG_ON(I915_RESET_MODESET >= I915_RESET_ENGINE);
+ if (test_and_set_bit(I915_RESET_ENGINE + engine->id,
+ &dev_priv->gpu_error.flags))
+ continue;
+
+ if (i915_reset_engine(engine, 0) == 0)
+ engine_mask &= ~intel_engine_flag(engine);
+
+ clear_bit(I915_RESET_ENGINE + engine->id,
+ &dev_priv->gpu_error.flags);
+ wake_up_bit(&dev_priv->gpu_error.flags,
+ I915_RESET_ENGINE + engine->id);
+ }
+ }
+
if (!engine_mask)
goto out;
- if (test_and_set_bit(I915_RESET_BACKOFF,
- &dev_priv->gpu_error.flags))
+ /* Full reset needs the mutex, stop any other user trying to do so. */
+ if (test_and_set_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags)) {
+ wait_event(dev_priv->gpu_error.reset_queue,
+ !test_bit(I915_RESET_BACKOFF,
+ &dev_priv->gpu_error.flags));
goto out;
+ }
+
+ /* Prevent any other reset-engine attempt. */
+ for_each_engine(engine, dev_priv, tmp) {
+ while (test_and_set_bit(I915_RESET_ENGINE + engine->id,
+ &dev_priv->gpu_error.flags))
+ wait_on_bit(&dev_priv->gpu_error.flags,
+ I915_RESET_ENGINE + engine->id,
+ TASK_UNINTERRUPTIBLE);
+ }
+
+ i915_reset_device(dev_priv);
- i915_reset_and_wakeup(dev_priv);
+ for_each_engine(engine, dev_priv, tmp) {
+ clear_bit(I915_RESET_ENGINE + engine->id,
+ &dev_priv->gpu_error.flags);
+ }
+
+ clear_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags);
+ wake_up_all(&dev_priv->gpu_error.reset_queue);
out:
intel_runtime_pm_put(dev_priv);
@@ -3009,7 +3013,7 @@ static void gen8_irq_reset(struct drm_device *dev)
}
void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
- unsigned int pipe_mask)
+ u8 pipe_mask)
{
uint32_t extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN;
enum pipe pipe;
@@ -3023,7 +3027,7 @@ void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
}
void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv,
- unsigned int pipe_mask)
+ u8 pipe_mask)
{
enum pipe pipe;
@@ -3427,7 +3431,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
u32 de_misc_masked = GEN8_DE_MISC_GSE;
enum pipe pipe;
- if (INTEL_INFO(dev_priv)->gen >= 9) {
+ if (INTEL_GEN(dev_priv) >= 9) {
de_pipe_masked |= GEN9_PIPE_PLANE1_FLIP_DONE |
GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
de_port_masked |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
@@ -3610,34 +3614,6 @@ static int i8xx_irq_postinstall(struct drm_device *dev)
/*
* Returns true when a page flip has completed.
*/
-static bool i8xx_handle_vblank(struct drm_i915_private *dev_priv,
- int plane, int pipe, u32 iir)
-{
- u16 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane);
-
- if (!intel_pipe_handle_vblank(dev_priv, pipe))
- return false;
-
- if ((iir & flip_pending) == 0)
- goto check_page_flip;
-
- /* We detect FlipDone by looking for the change in PendingFlip from '1'
- * to '0' on the following vblank, i.e. IIR has the Pendingflip
- * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
- * the flip is completed (no longer pending). Since this doesn't raise
- * an interrupt per se, we watch for the change at vblank.
- */
- if (I915_READ16(ISR) & flip_pending)
- goto check_page_flip;
-
- intel_finish_page_flip_cs(dev_priv, pipe);
- return true;
-
-check_page_flip:
- intel_check_page_flip(dev_priv, pipe);
- return false;
-}
-
static irqreturn_t i8xx_irq_handler(int irq, void *arg)
{
struct drm_device *dev = arg;
@@ -3645,9 +3621,6 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
u16 iir, new_iir;
u32 pipe_stats[2];
int pipe;
- u16 flip_mask =
- I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
- I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
irqreturn_t ret;
if (!intel_irqs_enabled(dev_priv))
@@ -3661,7 +3634,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
if (iir == 0)
goto out;
- while (iir & ~flip_mask) {
+ while (iir) {
/* Can't rely on pipestat interrupt bit in iir as it might
* have been cleared after the pipestat interrupt was received.
* It doesn't set the bit in iir again, but it still produces
@@ -3683,7 +3656,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
}
spin_unlock(&dev_priv->irq_lock);
- I915_WRITE16(IIR, iir & ~flip_mask);
+ I915_WRITE16(IIR, iir);
new_iir = I915_READ16(IIR); /* Flush posted writes */
if (iir & I915_USER_INTERRUPT)
@@ -3694,9 +3667,8 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
if (HAS_FBC(dev_priv))
plane = !plane;
- if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS &&
- i8xx_handle_vblank(dev_priv, plane, pipe, iir))
- flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(plane);
+ if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
+ drm_handle_vblank(&dev_priv->drm, pipe);
if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
i9xx_pipe_crc_irq_handler(dev_priv, pipe);
@@ -3796,45 +3768,11 @@ static int i915_irq_postinstall(struct drm_device *dev)
return 0;
}
-/*
- * Returns true when a page flip has completed.
- */
-static bool i915_handle_vblank(struct drm_i915_private *dev_priv,
- int plane, int pipe, u32 iir)
-{
- u32 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane);
-
- if (!intel_pipe_handle_vblank(dev_priv, pipe))
- return false;
-
- if ((iir & flip_pending) == 0)
- goto check_page_flip;
-
- /* We detect FlipDone by looking for the change in PendingFlip from '1'
- * to '0' on the following vblank, i.e. IIR has the Pendingflip
- * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
- * the flip is completed (no longer pending). Since this doesn't raise
- * an interrupt per se, we watch for the change at vblank.
- */
- if (I915_READ(ISR) & flip_pending)
- goto check_page_flip;
-
- intel_finish_page_flip_cs(dev_priv, pipe);
- return true;
-
-check_page_flip:
- intel_check_page_flip(dev_priv, pipe);
- return false;
-}
-
static irqreturn_t i915_irq_handler(int irq, void *arg)
{
struct drm_device *dev = arg;
struct drm_i915_private *dev_priv = to_i915(dev);
u32 iir, new_iir, pipe_stats[I915_MAX_PIPES];
- u32 flip_mask =
- I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
- I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
int pipe, ret = IRQ_NONE;
if (!intel_irqs_enabled(dev_priv))
@@ -3845,7 +3783,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
iir = I915_READ(IIR);
do {
- bool irq_received = (iir & ~flip_mask) != 0;
+ bool irq_received = (iir) != 0;
bool blc_event = false;
/* Can't rely on pipestat interrupt bit in iir as it might
@@ -3880,7 +3818,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
i9xx_hpd_irq_handler(dev_priv, hotplug_status);
}
- I915_WRITE(IIR, iir & ~flip_mask);
+ I915_WRITE(IIR, iir);
new_iir = I915_READ(IIR); /* Flush posted writes */
if (iir & I915_USER_INTERRUPT)
@@ -3891,9 +3829,8 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
if (HAS_FBC(dev_priv))
plane = !plane;
- if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS &&
- i915_handle_vblank(dev_priv, plane, pipe, iir))
- flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(plane);
+ if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
+ drm_handle_vblank(&dev_priv->drm, pipe);
if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
blc_event = true;
@@ -3926,7 +3863,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
*/
ret = IRQ_HANDLED;
iir = new_iir;
- } while (iir & ~flip_mask);
+ } while (iir);
enable_rpm_wakeref_asserts(dev_priv);
@@ -4061,9 +3998,6 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
u32 iir, new_iir;
u32 pipe_stats[I915_MAX_PIPES];
int ret = IRQ_NONE, pipe;
- u32 flip_mask =
- I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
- I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
if (!intel_irqs_enabled(dev_priv))
return IRQ_NONE;
@@ -4074,7 +4008,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
iir = I915_READ(IIR);
for (;;) {
- bool irq_received = (iir & ~flip_mask) != 0;
+ bool irq_received = (iir) != 0;
bool blc_event = false;
/* Can't rely on pipestat interrupt bit in iir as it might
@@ -4112,7 +4046,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
i9xx_hpd_irq_handler(dev_priv, hotplug_status);
}
- I915_WRITE(IIR, iir & ~flip_mask);
+ I915_WRITE(IIR, iir);
new_iir = I915_READ(IIR); /* Flush posted writes */
if (iir & I915_USER_INTERRUPT)
@@ -4121,9 +4055,8 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
notify_ring(dev_priv->engine[VCS]);
for_each_pipe(dev_priv, pipe) {
- if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS &&
- i915_handle_vblank(dev_priv, pipe, pipe, iir))
- flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(pipe);
+ if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS)
+ drm_handle_vblank(&dev_priv->drm, pipe);
if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
blc_event = true;
@@ -4225,16 +4158,16 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
*
* TODO: verify if this can be reproduced on VLV,CHV.
*/
- if (INTEL_INFO(dev_priv)->gen <= 7)
+ if (INTEL_GEN(dev_priv) <= 7)
dev_priv->rps.pm_intrmsk_mbz |= GEN6_PM_RP_UP_EI_EXPIRED;
- if (INTEL_INFO(dev_priv)->gen >= 8)
+ if (INTEL_GEN(dev_priv) >= 8)
dev_priv->rps.pm_intrmsk_mbz |= GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC;
if (IS_GEN2(dev_priv)) {
/* Gen2 doesn't have a hardware frame counter */
dev->max_vblank_count = 0;
- } else if (IS_G4X(dev_priv) || INTEL_INFO(dev_priv)->gen >= 5) {
+ } else if (IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5) {
dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
dev->driver->get_vblank_counter = g4x_get_vblank_counter;
} else {
@@ -4281,7 +4214,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
dev->driver->enable_vblank = i965_enable_vblank;
dev->driver->disable_vblank = i965_disable_vblank;
dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
- } else if (INTEL_INFO(dev_priv)->gen >= 8) {
+ } else if (INTEL_GEN(dev_priv) >= 8) {
dev->driver->irq_handler = gen8_irq_handler;
dev->driver->irq_preinstall = gen8_irq_reset;
dev->driver->irq_postinstall = gen8_irq_postinstall;
diff --git a/drivers/gpu/drm/i915/i915_oa_bdw.c b/drivers/gpu/drm/i915/i915_oa_bdw.c
index d4462c2aaaee..abdf4d0abcce 100644
--- a/drivers/gpu/drm/i915/i915_oa_bdw.c
+++ b/drivers/gpu/drm/i915/i915_oa_bdw.c
@@ -31,3981 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_bdw.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_COMPUTE_L3_CACHE,
- METRIC_SET_ID_DATA_PORT_READS_COALESCING,
- METRIC_SET_ID_DATA_PORT_WRITES_COALESCING,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_L3_2,
- METRIC_SET_ID_L3_3,
- METRIC_SET_ID_L3_4,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER_1,
- METRIC_SET_ID_SAMPLER_2,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_COMPUTE_EXTRA,
- METRIC_SET_ID_VME_PIPE,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_bdw = 22;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic_0_slices_0x01[] = {
- { _MMIO(0x9888), 0x143f000f },
- { _MMIO(0x9888), 0x14110014 },
- { _MMIO(0x9888), 0x14310014 },
- { _MMIO(0x9888), 0x14bf000f },
- { _MMIO(0x9888), 0x118a0317 },
- { _MMIO(0x9888), 0x13837be0 },
- { _MMIO(0x9888), 0x3b800060 },
- { _MMIO(0x9888), 0x3d800005 },
- { _MMIO(0x9888), 0x005c4000 },
- { _MMIO(0x9888), 0x065c8000 },
- { _MMIO(0x9888), 0x085cc000 },
- { _MMIO(0x9888), 0x003d8000 },
- { _MMIO(0x9888), 0x183d0800 },
- { _MMIO(0x9888), 0x0a3f0023 },
- { _MMIO(0x9888), 0x103f0000 },
- { _MMIO(0x9888), 0x00584000 },
- { _MMIO(0x9888), 0x08584000 },
- { _MMIO(0x9888), 0x0a5a4000 },
- { _MMIO(0x9888), 0x005b4000 },
- { _MMIO(0x9888), 0x0e5b8000 },
- { _MMIO(0x9888), 0x185b2400 },
- { _MMIO(0x9888), 0x0a1d4000 },
- { _MMIO(0x9888), 0x0c1f0800 },
- { _MMIO(0x9888), 0x0e1faa00 },
- { _MMIO(0x9888), 0x00384000 },
- { _MMIO(0x9888), 0x0e384000 },
- { _MMIO(0x9888), 0x16384000 },
- { _MMIO(0x9888), 0x18380001 },
- { _MMIO(0x9888), 0x00392000 },
- { _MMIO(0x9888), 0x06398000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a391000 },
- { _MMIO(0x9888), 0x00104000 },
- { _MMIO(0x9888), 0x08104000 },
- { _MMIO(0x9888), 0x00110030 },
- { _MMIO(0x9888), 0x08110031 },
- { _MMIO(0x9888), 0x10110000 },
- { _MMIO(0x9888), 0x00134000 },
- { _MMIO(0x9888), 0x16130020 },
- { _MMIO(0x9888), 0x06308000 },
- { _MMIO(0x9888), 0x08308000 },
- { _MMIO(0x9888), 0x06311800 },
- { _MMIO(0x9888), 0x08311880 },
- { _MMIO(0x9888), 0x10310000 },
- { _MMIO(0x9888), 0x0e334000 },
- { _MMIO(0x9888), 0x16330080 },
- { _MMIO(0x9888), 0x0abf1180 },
- { _MMIO(0x9888), 0x10bf0000 },
- { _MMIO(0x9888), 0x0ada8000 },
- { _MMIO(0x9888), 0x0a9d8000 },
- { _MMIO(0x9888), 0x109f0002 },
- { _MMIO(0x9888), 0x0ab94000 },
- { _MMIO(0x9888), 0x0d888000 },
- { _MMIO(0x9888), 0x038a0380 },
- { _MMIO(0x9888), 0x058a000e },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8a00a0 },
- { _MMIO(0x9888), 0x078a0000 },
- { _MMIO(0x9888), 0x098a0000 },
- { _MMIO(0x9888), 0x238b2820 },
- { _MMIO(0x9888), 0x258b2550 },
- { _MMIO(0x9888), 0x198c1000 },
- { _MMIO(0x9888), 0x0b8d8000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa0 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x0d831021 },
- { _MMIO(0x9888), 0x0f83572f },
- { _MMIO(0x9888), 0x01835680 },
- { _MMIO(0x9888), 0x0383002c },
- { _MMIO(0x9888), 0x11830000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830001 },
- { _MMIO(0x9888), 0x05830000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x05844000 },
- { _MMIO(0x9888), 0x1b80c137 },
- { _MMIO(0x9888), 0x1d80c147 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x15804000 },
- { _MMIO(0x9888), 0x4d801110 },
- { _MMIO(0x9888), 0x4f800331 },
- { _MMIO(0x9888), 0x43800802 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45801465 },
- { _MMIO(0x9888), 0x53801111 },
- { _MMIO(0x9888), 0x478014a5 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800ca5 },
- { _MMIO(0x9888), 0x41800003 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic_1_slices_0x02[] = {
- { _MMIO(0x9888), 0x143f000f },
- { _MMIO(0x9888), 0x14bf000f },
- { _MMIO(0x9888), 0x14910014 },
- { _MMIO(0x9888), 0x14b10014 },
- { _MMIO(0x9888), 0x118a0317 },
- { _MMIO(0x9888), 0x13837be0 },
- { _MMIO(0x9888), 0x3b800060 },
- { _MMIO(0x9888), 0x3d800005 },
- { _MMIO(0x9888), 0x0a3f0023 },
- { _MMIO(0x9888), 0x103f0000 },
- { _MMIO(0x9888), 0x0a5a4000 },
- { _MMIO(0x9888), 0x0a1d4000 },
- { _MMIO(0x9888), 0x0e1f8000 },
- { _MMIO(0x9888), 0x0a391000 },
- { _MMIO(0x9888), 0x00dc4000 },
- { _MMIO(0x9888), 0x06dc8000 },
- { _MMIO(0x9888), 0x08dcc000 },
- { _MMIO(0x9888), 0x00bd8000 },
- { _MMIO(0x9888), 0x18bd0800 },
- { _MMIO(0x9888), 0x0abf1180 },
- { _MMIO(0x9888), 0x10bf0000 },
- { _MMIO(0x9888), 0x00d84000 },
- { _MMIO(0x9888), 0x08d84000 },
- { _MMIO(0x9888), 0x0ada8000 },
- { _MMIO(0x9888), 0x00db4000 },
- { _MMIO(0x9888), 0x0edb8000 },
- { _MMIO(0x9888), 0x18db2400 },
- { _MMIO(0x9888), 0x0a9d8000 },
- { _MMIO(0x9888), 0x0c9f0800 },
- { _MMIO(0x9888), 0x0e9f2a00 },
- { _MMIO(0x9888), 0x109f0002 },
- { _MMIO(0x9888), 0x00b84000 },
- { _MMIO(0x9888), 0x0eb84000 },
- { _MMIO(0x9888), 0x16b84000 },
- { _MMIO(0x9888), 0x18b80001 },
- { _MMIO(0x9888), 0x00b92000 },
- { _MMIO(0x9888), 0x06b98000 },
- { _MMIO(0x9888), 0x08b9a000 },
- { _MMIO(0x9888), 0x0ab94000 },
- { _MMIO(0x9888), 0x00904000 },
- { _MMIO(0x9888), 0x08904000 },
- { _MMIO(0x9888), 0x00910030 },
- { _MMIO(0x9888), 0x08910031 },
- { _MMIO(0x9888), 0x10910000 },
- { _MMIO(0x9888), 0x00934000 },
- { _MMIO(0x9888), 0x16930020 },
- { _MMIO(0x9888), 0x06b08000 },
- { _MMIO(0x9888), 0x08b08000 },
- { _MMIO(0x9888), 0x06b11800 },
- { _MMIO(0x9888), 0x08b11880 },
- { _MMIO(0x9888), 0x10b10000 },
- { _MMIO(0x9888), 0x0eb34000 },
- { _MMIO(0x9888), 0x16b30080 },
- { _MMIO(0x9888), 0x01888000 },
- { _MMIO(0x9888), 0x0d88b800 },
- { _MMIO(0x9888), 0x038a0380 },
- { _MMIO(0x9888), 0x058a000e },
- { _MMIO(0x9888), 0x1b8a0080 },
- { _MMIO(0x9888), 0x078a0000 },
- { _MMIO(0x9888), 0x098a0000 },
- { _MMIO(0x9888), 0x238b2840 },
- { _MMIO(0x9888), 0x258b26a0 },
- { _MMIO(0x9888), 0x018c4000 },
- { _MMIO(0x9888), 0x0f8c4000 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c1100 },
- { _MMIO(0x9888), 0x018d2000 },
- { _MMIO(0x9888), 0x078d8000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8d8000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa0 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x0d831021 },
- { _MMIO(0x9888), 0x0f83572f },
- { _MMIO(0x9888), 0x01835680 },
- { _MMIO(0x9888), 0x0383002c },
- { _MMIO(0x9888), 0x11830000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830001 },
- { _MMIO(0x9888), 0x05830000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x05844000 },
- { _MMIO(0x9888), 0x1b80c137 },
- { _MMIO(0x9888), 0x1d80c147 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x15804000 },
- { _MMIO(0x9888), 0x4d801550 },
- { _MMIO(0x9888), 0x4f800331 },
- { _MMIO(0x9888), 0x43800802 },
- { _MMIO(0x9888), 0x51800400 },
- { _MMIO(0x9888), 0x458004a1 },
- { _MMIO(0x9888), 0x53805555 },
- { _MMIO(0x9888), 0x47800421 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f801421 },
- { _MMIO(0x9888), 0x41800845 },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 2);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 2);
-
- if (INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) {
- regs[n] = mux_config_render_basic_0_slices_0x01;
- lens[n] = ARRAY_SIZE(mux_config_render_basic_0_slices_0x01);
- n++;
- }
- if (INTEL_INFO(dev_priv)->sseu.slice_mask & 0x02) {
- regs[n] = mux_config_render_basic_1_slices_0x02;
- lens[n] = ARRAY_SIZE(mux_config_render_basic_1_slices_0x02);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic_0_slices_0x01[] = {
- { _MMIO(0x9888), 0x105c00e0 },
- { _MMIO(0x9888), 0x105800e0 },
- { _MMIO(0x9888), 0x103800e0 },
- { _MMIO(0x9888), 0x3580001a },
- { _MMIO(0x9888), 0x3b800060 },
- { _MMIO(0x9888), 0x3d800005 },
- { _MMIO(0x9888), 0x065c2100 },
- { _MMIO(0x9888), 0x0a5c0041 },
- { _MMIO(0x9888), 0x0c5c6600 },
- { _MMIO(0x9888), 0x005c6580 },
- { _MMIO(0x9888), 0x085c8000 },
- { _MMIO(0x9888), 0x0e5c8000 },
- { _MMIO(0x9888), 0x00580042 },
- { _MMIO(0x9888), 0x08582080 },
- { _MMIO(0x9888), 0x0c58004c },
- { _MMIO(0x9888), 0x0e582580 },
- { _MMIO(0x9888), 0x005b4000 },
- { _MMIO(0x9888), 0x185b1000 },
- { _MMIO(0x9888), 0x1a5b0104 },
- { _MMIO(0x9888), 0x0c1fa800 },
- { _MMIO(0x9888), 0x0e1faa00 },
- { _MMIO(0x9888), 0x101f02aa },
- { _MMIO(0x9888), 0x08380042 },
- { _MMIO(0x9888), 0x0a382080 },
- { _MMIO(0x9888), 0x0e38404c },
- { _MMIO(0x9888), 0x0238404b },
- { _MMIO(0x9888), 0x00384000 },
- { _MMIO(0x9888), 0x16380000 },
- { _MMIO(0x9888), 0x18381145 },
- { _MMIO(0x9888), 0x04380000 },
- { _MMIO(0x9888), 0x0039a000 },
- { _MMIO(0x9888), 0x06398000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0c39a000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x02392000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8aaaa0 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x238b02a0 },
- { _MMIO(0x9888), 0x258b5550 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x1f850a80 },
- { _MMIO(0x9888), 0x2185aaa0 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x03844000 },
- { _MMIO(0x9888), 0x17808137 },
- { _MMIO(0x9888), 0x1980c147 },
- { _MMIO(0x9888), 0x1b80c0e5 },
- { _MMIO(0x9888), 0x1d80c0e3 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x13804000 },
- { _MMIO(0x9888), 0x15800000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d801000 },
- { _MMIO(0x9888), 0x4f800111 },
- { _MMIO(0x9888), 0x43800062 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800062 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800062 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f801062 },
- { _MMIO(0x9888), 0x41801084 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic_2_slices_0x02[] = {
- { _MMIO(0x9888), 0x10dc00e0 },
- { _MMIO(0x9888), 0x10d800e0 },
- { _MMIO(0x9888), 0x10b800e0 },
- { _MMIO(0x9888), 0x3580001a },
- { _MMIO(0x9888), 0x3b800060 },
- { _MMIO(0x9888), 0x3d800005 },
- { _MMIO(0x9888), 0x06dc2100 },
- { _MMIO(0x9888), 0x0adc0041 },
- { _MMIO(0x9888), 0x0cdc6600 },
- { _MMIO(0x9888), 0x00dc6580 },
- { _MMIO(0x9888), 0x08dc8000 },
- { _MMIO(0x9888), 0x0edc8000 },
- { _MMIO(0x9888), 0x00d80042 },
- { _MMIO(0x9888), 0x08d82080 },
- { _MMIO(0x9888), 0x0cd8004c },
- { _MMIO(0x9888), 0x0ed82580 },
- { _MMIO(0x9888), 0x00db4000 },
- { _MMIO(0x9888), 0x18db1000 },
- { _MMIO(0x9888), 0x1adb0104 },
- { _MMIO(0x9888), 0x0c9fa800 },
- { _MMIO(0x9888), 0x0e9faa00 },
- { _MMIO(0x9888), 0x109f02aa },
- { _MMIO(0x9888), 0x08b80042 },
- { _MMIO(0x9888), 0x0ab82080 },
- { _MMIO(0x9888), 0x0eb8404c },
- { _MMIO(0x9888), 0x02b8404b },
- { _MMIO(0x9888), 0x00b84000 },
- { _MMIO(0x9888), 0x16b80000 },
- { _MMIO(0x9888), 0x18b81145 },
- { _MMIO(0x9888), 0x04b80000 },
- { _MMIO(0x9888), 0x00b9a000 },
- { _MMIO(0x9888), 0x06b98000 },
- { _MMIO(0x9888), 0x08b9a000 },
- { _MMIO(0x9888), 0x0ab9a000 },
- { _MMIO(0x9888), 0x0cb9a000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x02b92000 },
- { _MMIO(0x9888), 0x01888000 },
- { _MMIO(0x9888), 0x0d88f800 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x238b0540 },
- { _MMIO(0x9888), 0x258baaa0 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x018c4000 },
- { _MMIO(0x9888), 0x0f8c4000 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c5500 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x018da000 },
- { _MMIO(0x9888), 0x078d8000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x038d2000 },
- { _MMIO(0x9888), 0x1f850a80 },
- { _MMIO(0x9888), 0x2185aaa0 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x03844000 },
- { _MMIO(0x9888), 0x17808137 },
- { _MMIO(0x9888), 0x1980c147 },
- { _MMIO(0x9888), 0x1b80c0e5 },
- { _MMIO(0x9888), 0x1d80c0e3 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x13804000 },
- { _MMIO(0x9888), 0x15800000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d805000 },
- { _MMIO(0x9888), 0x4f800555 },
- { _MMIO(0x9888), 0x43800062 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800062 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800062 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800062 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 2);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 2);
-
- if (INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) {
- regs[n] = mux_config_compute_basic_0_slices_0x01;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic_0_slices_0x01);
- n++;
- }
- if (INTEL_INFO(dev_priv)->sseu.slice_mask & 0x02) {
- regs[n] = mux_config_compute_basic_2_slices_0x02;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic_2_slices_0x02);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile[] = {
- { _MMIO(0x9888), 0x0a1e0000 },
- { _MMIO(0x9888), 0x0c1f000f },
- { _MMIO(0x9888), 0x10176800 },
- { _MMIO(0x9888), 0x1191001f },
- { _MMIO(0x9888), 0x0b880320 },
- { _MMIO(0x9888), 0x01890c40 },
- { _MMIO(0x9888), 0x118a1c00 },
- { _MMIO(0x9888), 0x118d7c00 },
- { _MMIO(0x9888), 0x118e0020 },
- { _MMIO(0x9888), 0x118f4c00 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x13900001 },
- { _MMIO(0x9888), 0x065c4000 },
- { _MMIO(0x9888), 0x0c3d8000 },
- { _MMIO(0x9888), 0x06584000 },
- { _MMIO(0x9888), 0x0c5b4000 },
- { _MMIO(0x9888), 0x081e0040 },
- { _MMIO(0x9888), 0x0e1e0000 },
- { _MMIO(0x9888), 0x021f5400 },
- { _MMIO(0x9888), 0x001f0000 },
- { _MMIO(0x9888), 0x101f0010 },
- { _MMIO(0x9888), 0x0e1f0080 },
- { _MMIO(0x9888), 0x0c384000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x0c13c000 },
- { _MMIO(0x9888), 0x06164000 },
- { _MMIO(0x9888), 0x06170012 },
- { _MMIO(0x9888), 0x00170000 },
- { _MMIO(0x9888), 0x01910005 },
- { _MMIO(0x9888), 0x07880002 },
- { _MMIO(0x9888), 0x01880c00 },
- { _MMIO(0x9888), 0x0f880000 },
- { _MMIO(0x9888), 0x0d880000 },
- { _MMIO(0x9888), 0x05880000 },
- { _MMIO(0x9888), 0x09890032 },
- { _MMIO(0x9888), 0x078a0800 },
- { _MMIO(0x9888), 0x0f8a0a00 },
- { _MMIO(0x9888), 0x198a4000 },
- { _MMIO(0x9888), 0x1b8a2000 },
- { _MMIO(0x9888), 0x1d8a0000 },
- { _MMIO(0x9888), 0x038a4000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x238b54c0 },
- { _MMIO(0x9888), 0x258baa55 },
- { _MMIO(0x9888), 0x278b0019 },
- { _MMIO(0x9888), 0x198c0100 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x0f8d0015 },
- { _MMIO(0x9888), 0x018d1000 },
- { _MMIO(0x9888), 0x098d8000 },
- { _MMIO(0x9888), 0x0b8df000 },
- { _MMIO(0x9888), 0x0d8d3000 },
- { _MMIO(0x9888), 0x038de000 },
- { _MMIO(0x9888), 0x058d3000 },
- { _MMIO(0x9888), 0x0d8e0004 },
- { _MMIO(0x9888), 0x058e000c },
- { _MMIO(0x9888), 0x098e0000 },
- { _MMIO(0x9888), 0x078e0000 },
- { _MMIO(0x9888), 0x038e0000 },
- { _MMIO(0x9888), 0x0b8f0020 },
- { _MMIO(0x9888), 0x198f0c00 },
- { _MMIO(0x9888), 0x078f8000 },
- { _MMIO(0x9888), 0x098f4000 },
- { _MMIO(0x9888), 0x0b900980 },
- { _MMIO(0x9888), 0x03900d80 },
- { _MMIO(0x9888), 0x01900000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d801111 },
- { _MMIO(0x9888), 0x3d800800 },
- { _MMIO(0x9888), 0x4f801011 },
- { _MMIO(0x9888), 0x43800443 },
- { _MMIO(0x9888), 0x51801111 },
- { _MMIO(0x9888), 0x45800422 },
- { _MMIO(0x9888), 0x53801111 },
- { _MMIO(0x9888), 0x47800c60 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800422 },
- { _MMIO(0x9888), 0x41800021 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_pipe_profile;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads[] = {
- { _MMIO(0x9888), 0x198b0343 },
- { _MMIO(0x9888), 0x13845800 },
- { _MMIO(0x9888), 0x15840018 },
- { _MMIO(0x9888), 0x3580001a },
- { _MMIO(0x9888), 0x038b6300 },
- { _MMIO(0x9888), 0x058b6b62 },
- { _MMIO(0x9888), 0x078b006a },
- { _MMIO(0x9888), 0x118b0000 },
- { _MMIO(0x9888), 0x238b0000 },
- { _MMIO(0x9888), 0x258b0000 },
- { _MMIO(0x9888), 0x1f85a080 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385000a },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x01840018 },
- { _MMIO(0x9888), 0x07844c80 },
- { _MMIO(0x9888), 0x09840d9a },
- { _MMIO(0x9888), 0x0b840e9c },
- { _MMIO(0x9888), 0x0d840f9e },
- { _MMIO(0x9888), 0x0f840010 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x03848000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x2f8000e5 },
- { _MMIO(0x9888), 0x138080e3 },
- { _MMIO(0x9888), 0x1580c0e1 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x11804000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f804000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3d800800 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800842 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800842 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47801042 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800084 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_reads;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes[] = {
- { _MMIO(0x9888), 0x198b0343 },
- { _MMIO(0x9888), 0x13845400 },
- { _MMIO(0x9888), 0x3580001a },
- { _MMIO(0x9888), 0x3d800805 },
- { _MMIO(0x9888), 0x038b6300 },
- { _MMIO(0x9888), 0x058b6b62 },
- { _MMIO(0x9888), 0x078b006a },
- { _MMIO(0x9888), 0x118b0000 },
- { _MMIO(0x9888), 0x238b0000 },
- { _MMIO(0x9888), 0x258b0000 },
- { _MMIO(0x9888), 0x1f85a080 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x23850002 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x01840010 },
- { _MMIO(0x9888), 0x07844880 },
- { _MMIO(0x9888), 0x09840992 },
- { _MMIO(0x9888), 0x0b840a94 },
- { _MMIO(0x9888), 0x0d840b96 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x03848000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x2d800147 },
- { _MMIO(0x9888), 0x2f8000e5 },
- { _MMIO(0x9888), 0x138080e3 },
- { _MMIO(0x9888), 0x1580c0e1 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x11804000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f800000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800842 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800842 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47801082 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800084 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_writes;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fc2a },
- { _MMIO(0x2774), 0x0000bf00 },
- { _MMIO(0x2778), 0x0007fc6a },
- { _MMIO(0x277c), 0x0000bf00 },
- { _MMIO(0x2780), 0x0007fc92 },
- { _MMIO(0x2784), 0x0000bf00 },
- { _MMIO(0x2788), 0x0007fca2 },
- { _MMIO(0x278c), 0x0000bf00 },
- { _MMIO(0x2790), 0x0007fc32 },
- { _MMIO(0x2794), 0x0000bf00 },
- { _MMIO(0x2798), 0x0007fc9a },
- { _MMIO(0x279c), 0x0000bf00 },
- { _MMIO(0x27a0), 0x0007fe6a },
- { _MMIO(0x27a4), 0x0000bf00 },
- { _MMIO(0x27a8), 0x0007fe7a },
- { _MMIO(0x27ac), 0x0000bf00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended_0_subslices_0x01[] = {
- { _MMIO(0x9888), 0x143d0160 },
- { _MMIO(0x9888), 0x163d2800 },
- { _MMIO(0x9888), 0x183d0120 },
- { _MMIO(0x9888), 0x105800e0 },
- { _MMIO(0x9888), 0x005cc000 },
- { _MMIO(0x9888), 0x065c8000 },
- { _MMIO(0x9888), 0x085cc000 },
- { _MMIO(0x9888), 0x0a5cc000 },
- { _MMIO(0x9888), 0x0c5cc000 },
- { _MMIO(0x9888), 0x0e5cc000 },
- { _MMIO(0x9888), 0x025cc000 },
- { _MMIO(0x9888), 0x045cc000 },
- { _MMIO(0x9888), 0x003d0011 },
- { _MMIO(0x9888), 0x063d0900 },
- { _MMIO(0x9888), 0x083d0a13 },
- { _MMIO(0x9888), 0x0a3d0b15 },
- { _MMIO(0x9888), 0x0c3d2317 },
- { _MMIO(0x9888), 0x043d21b7 },
- { _MMIO(0x9888), 0x103d0000 },
- { _MMIO(0x9888), 0x0e3d0000 },
- { _MMIO(0x9888), 0x1a3d0000 },
- { _MMIO(0x9888), 0x0e5825c1 },
- { _MMIO(0x9888), 0x00586100 },
- { _MMIO(0x9888), 0x0258204c },
- { _MMIO(0x9888), 0x06588000 },
- { _MMIO(0x9888), 0x0858c000 },
- { _MMIO(0x9888), 0x0a58c000 },
- { _MMIO(0x9888), 0x0c58c000 },
- { _MMIO(0x9888), 0x0458c000 },
- { _MMIO(0x9888), 0x005b4000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x185b5400 },
- { _MMIO(0x9888), 0x1a5b0155 },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x045b4000 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5b4000 },
- { _MMIO(0x9888), 0x0c1fa800 },
- { _MMIO(0x9888), 0x0e1faa2a },
- { _MMIO(0x9888), 0x101f02aa },
- { _MMIO(0x9888), 0x00384000 },
- { _MMIO(0x9888), 0x0e384000 },
- { _MMIO(0x9888), 0x16384000 },
- { _MMIO(0x9888), 0x18381555 },
- { _MMIO(0x9888), 0x02384000 },
- { _MMIO(0x9888), 0x04384000 },
- { _MMIO(0x9888), 0x06384000 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0039a000 },
- { _MMIO(0x9888), 0x06398000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0c39a000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8aaaa0 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x238b2aa0 },
- { _MMIO(0x9888), 0x258b5551 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa2 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800420 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800421 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended_2_subslices_0x02[] = {
- { _MMIO(0x9888), 0x105c00e0 },
- { _MMIO(0x9888), 0x145b0160 },
- { _MMIO(0x9888), 0x165b2800 },
- { _MMIO(0x9888), 0x185b0120 },
- { _MMIO(0x9888), 0x0e5c25c1 },
- { _MMIO(0x9888), 0x005c6100 },
- { _MMIO(0x9888), 0x025c204c },
- { _MMIO(0x9888), 0x065c8000 },
- { _MMIO(0x9888), 0x085cc000 },
- { _MMIO(0x9888), 0x0a5cc000 },
- { _MMIO(0x9888), 0x0c5cc000 },
- { _MMIO(0x9888), 0x045cc000 },
- { _MMIO(0x9888), 0x005b0011 },
- { _MMIO(0x9888), 0x065b0900 },
- { _MMIO(0x9888), 0x085b0a13 },
- { _MMIO(0x9888), 0x0a5b0b15 },
- { _MMIO(0x9888), 0x0c5b2317 },
- { _MMIO(0x9888), 0x045b21b7 },
- { _MMIO(0x9888), 0x105b0000 },
- { _MMIO(0x9888), 0x0e5b0000 },
- { _MMIO(0x9888), 0x1a5b0000 },
- { _MMIO(0x9888), 0x0c1fa800 },
- { _MMIO(0x9888), 0x0e1faa2a },
- { _MMIO(0x9888), 0x101f02aa },
- { _MMIO(0x9888), 0x00384000 },
- { _MMIO(0x9888), 0x0e384000 },
- { _MMIO(0x9888), 0x16384000 },
- { _MMIO(0x9888), 0x18381555 },
- { _MMIO(0x9888), 0x02384000 },
- { _MMIO(0x9888), 0x04384000 },
- { _MMIO(0x9888), 0x06384000 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0039a000 },
- { _MMIO(0x9888), 0x06398000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0c39a000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8aaaa0 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x238b2aa0 },
- { _MMIO(0x9888), 0x258b5551 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa2 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800420 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800421 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended_4_subslices_0x04[] = {
- { _MMIO(0x9888), 0x103800e0 },
- { _MMIO(0x9888), 0x143a0160 },
- { _MMIO(0x9888), 0x163a2800 },
- { _MMIO(0x9888), 0x183a0120 },
- { _MMIO(0x9888), 0x0c1fa800 },
- { _MMIO(0x9888), 0x0e1faa2a },
- { _MMIO(0x9888), 0x101f02aa },
- { _MMIO(0x9888), 0x0e38a5c1 },
- { _MMIO(0x9888), 0x0038a100 },
- { _MMIO(0x9888), 0x0238204c },
- { _MMIO(0x9888), 0x16388000 },
- { _MMIO(0x9888), 0x183802aa },
- { _MMIO(0x9888), 0x04380000 },
- { _MMIO(0x9888), 0x06380000 },
- { _MMIO(0x9888), 0x08388000 },
- { _MMIO(0x9888), 0x0a388000 },
- { _MMIO(0x9888), 0x0039a000 },
- { _MMIO(0x9888), 0x06398000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0c39a000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x003a0011 },
- { _MMIO(0x9888), 0x063a0900 },
- { _MMIO(0x9888), 0x083a0a13 },
- { _MMIO(0x9888), 0x0a3a0b15 },
- { _MMIO(0x9888), 0x0c3a2317 },
- { _MMIO(0x9888), 0x043a21b7 },
- { _MMIO(0x9888), 0x103a0000 },
- { _MMIO(0x9888), 0x0e3a0000 },
- { _MMIO(0x9888), 0x1a3a0000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8aaaa0 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x238b2aa0 },
- { _MMIO(0x9888), 0x258b5551 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa2 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800420 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800421 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended_1_subslices_0x08[] = {
- { _MMIO(0x9888), 0x14bd0160 },
- { _MMIO(0x9888), 0x16bd2800 },
- { _MMIO(0x9888), 0x18bd0120 },
- { _MMIO(0x9888), 0x10d800e0 },
- { _MMIO(0x9888), 0x00dcc000 },
- { _MMIO(0x9888), 0x06dc8000 },
- { _MMIO(0x9888), 0x08dcc000 },
- { _MMIO(0x9888), 0x0adcc000 },
- { _MMIO(0x9888), 0x0cdcc000 },
- { _MMIO(0x9888), 0x0edcc000 },
- { _MMIO(0x9888), 0x02dcc000 },
- { _MMIO(0x9888), 0x04dcc000 },
- { _MMIO(0x9888), 0x00bd0011 },
- { _MMIO(0x9888), 0x06bd0900 },
- { _MMIO(0x9888), 0x08bd0a13 },
- { _MMIO(0x9888), 0x0abd0b15 },
- { _MMIO(0x9888), 0x0cbd2317 },
- { _MMIO(0x9888), 0x04bd21b7 },
- { _MMIO(0x9888), 0x10bd0000 },
- { _MMIO(0x9888), 0x0ebd0000 },
- { _MMIO(0x9888), 0x1abd0000 },
- { _MMIO(0x9888), 0x0ed825c1 },
- { _MMIO(0x9888), 0x00d86100 },
- { _MMIO(0x9888), 0x02d8204c },
- { _MMIO(0x9888), 0x06d88000 },
- { _MMIO(0x9888), 0x08d8c000 },
- { _MMIO(0x9888), 0x0ad8c000 },
- { _MMIO(0x9888), 0x0cd8c000 },
- { _MMIO(0x9888), 0x04d8c000 },
- { _MMIO(0x9888), 0x00db4000 },
- { _MMIO(0x9888), 0x0edb4000 },
- { _MMIO(0x9888), 0x18db5400 },
- { _MMIO(0x9888), 0x1adb0155 },
- { _MMIO(0x9888), 0x02db4000 },
- { _MMIO(0x9888), 0x04db4000 },
- { _MMIO(0x9888), 0x06db4000 },
- { _MMIO(0x9888), 0x08db4000 },
- { _MMIO(0x9888), 0x0adb4000 },
- { _MMIO(0x9888), 0x0c9fa800 },
- { _MMIO(0x9888), 0x0e9faa2a },
- { _MMIO(0x9888), 0x109f02aa },
- { _MMIO(0x9888), 0x00b84000 },
- { _MMIO(0x9888), 0x0eb84000 },
- { _MMIO(0x9888), 0x16b84000 },
- { _MMIO(0x9888), 0x18b81555 },
- { _MMIO(0x9888), 0x02b84000 },
- { _MMIO(0x9888), 0x04b84000 },
- { _MMIO(0x9888), 0x06b84000 },
- { _MMIO(0x9888), 0x08b84000 },
- { _MMIO(0x9888), 0x0ab84000 },
- { _MMIO(0x9888), 0x00b9a000 },
- { _MMIO(0x9888), 0x06b98000 },
- { _MMIO(0x9888), 0x08b9a000 },
- { _MMIO(0x9888), 0x0ab9a000 },
- { _MMIO(0x9888), 0x0cb9a000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x02b9a000 },
- { _MMIO(0x9888), 0x04b9a000 },
- { _MMIO(0x9888), 0x01888000 },
- { _MMIO(0x9888), 0x0d88f800 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x238b5540 },
- { _MMIO(0x9888), 0x258baaa2 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x018c4000 },
- { _MMIO(0x9888), 0x0f8c4000 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c5500 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x018da000 },
- { _MMIO(0x9888), 0x078d8000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa2 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800420 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800421 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended_3_subslices_0x10[] = {
- { _MMIO(0x9888), 0x10dc00e0 },
- { _MMIO(0x9888), 0x14db0160 },
- { _MMIO(0x9888), 0x16db2800 },
- { _MMIO(0x9888), 0x18db0120 },
- { _MMIO(0x9888), 0x0edc25c1 },
- { _MMIO(0x9888), 0x00dc6100 },
- { _MMIO(0x9888), 0x02dc204c },
- { _MMIO(0x9888), 0x06dc8000 },
- { _MMIO(0x9888), 0x08dcc000 },
- { _MMIO(0x9888), 0x0adcc000 },
- { _MMIO(0x9888), 0x0cdcc000 },
- { _MMIO(0x9888), 0x04dcc000 },
- { _MMIO(0x9888), 0x00db0011 },
- { _MMIO(0x9888), 0x06db0900 },
- { _MMIO(0x9888), 0x08db0a13 },
- { _MMIO(0x9888), 0x0adb0b15 },
- { _MMIO(0x9888), 0x0cdb2317 },
- { _MMIO(0x9888), 0x04db21b7 },
- { _MMIO(0x9888), 0x10db0000 },
- { _MMIO(0x9888), 0x0edb0000 },
- { _MMIO(0x9888), 0x1adb0000 },
- { _MMIO(0x9888), 0x0c9fa800 },
- { _MMIO(0x9888), 0x0e9faa2a },
- { _MMIO(0x9888), 0x109f02aa },
- { _MMIO(0x9888), 0x00b84000 },
- { _MMIO(0x9888), 0x0eb84000 },
- { _MMIO(0x9888), 0x16b84000 },
- { _MMIO(0x9888), 0x18b81555 },
- { _MMIO(0x9888), 0x02b84000 },
- { _MMIO(0x9888), 0x04b84000 },
- { _MMIO(0x9888), 0x06b84000 },
- { _MMIO(0x9888), 0x08b84000 },
- { _MMIO(0x9888), 0x0ab84000 },
- { _MMIO(0x9888), 0x00b9a000 },
- { _MMIO(0x9888), 0x06b98000 },
- { _MMIO(0x9888), 0x08b9a000 },
- { _MMIO(0x9888), 0x0ab9a000 },
- { _MMIO(0x9888), 0x0cb9a000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x02b9a000 },
- { _MMIO(0x9888), 0x04b9a000 },
- { _MMIO(0x9888), 0x01888000 },
- { _MMIO(0x9888), 0x0d88f800 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x238b5540 },
- { _MMIO(0x9888), 0x258baaa2 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x018c4000 },
- { _MMIO(0x9888), 0x0f8c4000 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c5500 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x018da000 },
- { _MMIO(0x9888), 0x078d8000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa2 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800420 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800421 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended_5_subslices_0x20[] = {
- { _MMIO(0x9888), 0x10b800e0 },
- { _MMIO(0x9888), 0x14ba0160 },
- { _MMIO(0x9888), 0x16ba2800 },
- { _MMIO(0x9888), 0x18ba0120 },
- { _MMIO(0x9888), 0x0c9fa800 },
- { _MMIO(0x9888), 0x0e9faa2a },
- { _MMIO(0x9888), 0x109f02aa },
- { _MMIO(0x9888), 0x0eb8a5c1 },
- { _MMIO(0x9888), 0x00b8a100 },
- { _MMIO(0x9888), 0x02b8204c },
- { _MMIO(0x9888), 0x16b88000 },
- { _MMIO(0x9888), 0x18b802aa },
- { _MMIO(0x9888), 0x04b80000 },
- { _MMIO(0x9888), 0x06b80000 },
- { _MMIO(0x9888), 0x08b88000 },
- { _MMIO(0x9888), 0x0ab88000 },
- { _MMIO(0x9888), 0x00b9a000 },
- { _MMIO(0x9888), 0x06b98000 },
- { _MMIO(0x9888), 0x08b9a000 },
- { _MMIO(0x9888), 0x0ab9a000 },
- { _MMIO(0x9888), 0x0cb9a000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x02b9a000 },
- { _MMIO(0x9888), 0x04b9a000 },
- { _MMIO(0x9888), 0x00ba0011 },
- { _MMIO(0x9888), 0x06ba0900 },
- { _MMIO(0x9888), 0x08ba0a13 },
- { _MMIO(0x9888), 0x0aba0b15 },
- { _MMIO(0x9888), 0x0cba2317 },
- { _MMIO(0x9888), 0x04ba21b7 },
- { _MMIO(0x9888), 0x10ba0000 },
- { _MMIO(0x9888), 0x0eba0000 },
- { _MMIO(0x9888), 0x1aba0000 },
- { _MMIO(0x9888), 0x01888000 },
- { _MMIO(0x9888), 0x0d88f800 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x238b5540 },
- { _MMIO(0x9888), 0x258baaa2 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x018c4000 },
- { _MMIO(0x9888), 0x0f8c4000 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c5500 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x018da000 },
- { _MMIO(0x9888), 0x078d8000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa2 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800420 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800421 },
- { _MMIO(0x9888), 0x41800000 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 6);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 6);
-
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x01) {
- regs[n] = mux_config_compute_extended_0_subslices_0x01;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended_0_subslices_0x01);
- n++;
- }
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x08) {
- regs[n] = mux_config_compute_extended_1_subslices_0x08;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended_1_subslices_0x08);
- n++;
- }
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x02) {
- regs[n] = mux_config_compute_extended_2_subslices_0x02;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended_2_subslices_0x02);
- n++;
- }
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x10) {
- regs[n] = mux_config_compute_extended_3_subslices_0x10;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended_3_subslices_0x10);
- n++;
- }
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x04) {
- regs[n] = mux_config_compute_extended_4_subslices_0x04;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended_4_subslices_0x04);
- n++;
- }
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x20) {
- regs[n] = mux_config_compute_extended_5_subslices_0x20;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended_5_subslices_0x20);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fffa },
- { _MMIO(0x2774), 0x0000fefe },
- { _MMIO(0x2778), 0x0007fffa },
- { _MMIO(0x277c), 0x0000fefd },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000fbef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000fbdf },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00101100 },
- { _MMIO(0xe45c), 0x00201200 },
- { _MMIO(0xe55c), 0x00301300 },
- { _MMIO(0xe65c), 0x00401400 },
-};
-
-static const struct i915_oa_reg mux_config_compute_l3_cache[] = {
- { _MMIO(0x9888), 0x143f00b3 },
- { _MMIO(0x9888), 0x14bf00b3 },
- { _MMIO(0x9888), 0x138303c0 },
- { _MMIO(0x9888), 0x3b800060 },
- { _MMIO(0x9888), 0x3d800805 },
- { _MMIO(0x9888), 0x003f0029 },
- { _MMIO(0x9888), 0x063f1400 },
- { _MMIO(0x9888), 0x083f1225 },
- { _MMIO(0x9888), 0x0e3f1327 },
- { _MMIO(0x9888), 0x103f0000 },
- { _MMIO(0x9888), 0x005a4000 },
- { _MMIO(0x9888), 0x065a8000 },
- { _MMIO(0x9888), 0x085ac000 },
- { _MMIO(0x9888), 0x0e5ac000 },
- { _MMIO(0x9888), 0x001d4000 },
- { _MMIO(0x9888), 0x061d8000 },
- { _MMIO(0x9888), 0x081dc000 },
- { _MMIO(0x9888), 0x0e1dc000 },
- { _MMIO(0x9888), 0x0c1f0800 },
- { _MMIO(0x9888), 0x0e1f2a00 },
- { _MMIO(0x9888), 0x101f0280 },
- { _MMIO(0x9888), 0x00391000 },
- { _MMIO(0x9888), 0x06394000 },
- { _MMIO(0x9888), 0x08395000 },
- { _MMIO(0x9888), 0x0e395000 },
- { _MMIO(0x9888), 0x0abf1429 },
- { _MMIO(0x9888), 0x0cbf1225 },
- { _MMIO(0x9888), 0x00bf1380 },
- { _MMIO(0x9888), 0x02bf0026 },
- { _MMIO(0x9888), 0x10bf0000 },
- { _MMIO(0x9888), 0x0adac000 },
- { _MMIO(0x9888), 0x0cdac000 },
- { _MMIO(0x9888), 0x00da8000 },
- { _MMIO(0x9888), 0x02da4000 },
- { _MMIO(0x9888), 0x0a9dc000 },
- { _MMIO(0x9888), 0x0c9dc000 },
- { _MMIO(0x9888), 0x009d8000 },
- { _MMIO(0x9888), 0x029d4000 },
- { _MMIO(0x9888), 0x0e9f8000 },
- { _MMIO(0x9888), 0x109f002a },
- { _MMIO(0x9888), 0x0c9fa000 },
- { _MMIO(0x9888), 0x0ab95000 },
- { _MMIO(0x9888), 0x0cb95000 },
- { _MMIO(0x9888), 0x00b94000 },
- { _MMIO(0x9888), 0x02b91000 },
- { _MMIO(0x9888), 0x0d88c000 },
- { _MMIO(0x9888), 0x0f880003 },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8a8020 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x238b0520 },
- { _MMIO(0x9888), 0x258ba950 },
- { _MMIO(0x9888), 0x278b0016 },
- { _MMIO(0x9888), 0x198c5400 },
- { _MMIO(0x9888), 0x1b8c0001 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x018d8000 },
- { _MMIO(0x9888), 0x038d2000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaa0 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x03835180 },
- { _MMIO(0x9888), 0x05834022 },
- { _MMIO(0x9888), 0x11830000 },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x07830000 },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x05844000 },
- { _MMIO(0x9888), 0x1b80c137 },
- { _MMIO(0x9888), 0x1d80c147 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x15804000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d801000 },
- { _MMIO(0x9888), 0x4f800111 },
- { _MMIO(0x9888), 0x43800842 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800840 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800800 },
- { _MMIO(0x9888), 0x418014a2 },
-};
-
-static int
-get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_l3_cache;
- lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_data_port_reads_coalescing[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0xba98ba98 },
- { _MMIO(0x2748), 0xba98ba98 },
- { _MMIO(0x2744), 0x00003377 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fff2 },
- { _MMIO(0x2774), 0x00007ff0 },
- { _MMIO(0x2778), 0x0007ffe2 },
- { _MMIO(0x277c), 0x00007ff0 },
- { _MMIO(0x2780), 0x0007ffc2 },
- { _MMIO(0x2784), 0x00007ff0 },
- { _MMIO(0x2788), 0x0007ff82 },
- { _MMIO(0x278c), 0x00007ff0 },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000bfef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000bfdf },
- { _MMIO(0x27a0), 0x0007fffa },
- { _MMIO(0x27a4), 0x0000bfbf },
- { _MMIO(0x27a8), 0x0007fffa },
- { _MMIO(0x27ac), 0x0000bf7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_data_port_reads_coalescing[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_data_port_reads_coalescing_0_subslices_0x01[] = {
- { _MMIO(0x9888), 0x103d0005 },
- { _MMIO(0x9888), 0x163d240b },
- { _MMIO(0x9888), 0x1058022f },
- { _MMIO(0x9888), 0x185b5520 },
- { _MMIO(0x9888), 0x198b0003 },
- { _MMIO(0x9888), 0x005cc000 },
- { _MMIO(0x9888), 0x065cc000 },
- { _MMIO(0x9888), 0x085cc000 },
- { _MMIO(0x9888), 0x0a5cc000 },
- { _MMIO(0x9888), 0x0c5cc000 },
- { _MMIO(0x9888), 0x0e5cc000 },
- { _MMIO(0x9888), 0x025c4000 },
- { _MMIO(0x9888), 0x045c8000 },
- { _MMIO(0x9888), 0x003d0000 },
- { _MMIO(0x9888), 0x063d00b0 },
- { _MMIO(0x9888), 0x083d0182 },
- { _MMIO(0x9888), 0x0a3d10a0 },
- { _MMIO(0x9888), 0x0c3d11a2 },
- { _MMIO(0x9888), 0x0e3d0000 },
- { _MMIO(0x9888), 0x183d0000 },
- { _MMIO(0x9888), 0x1a3d0000 },
- { _MMIO(0x9888), 0x0e582242 },
- { _MMIO(0x9888), 0x00586700 },
- { _MMIO(0x9888), 0x0258004f },
- { _MMIO(0x9888), 0x0658c000 },
- { _MMIO(0x9888), 0x0858c000 },
- { _MMIO(0x9888), 0x0a58c000 },
- { _MMIO(0x9888), 0x0c58c000 },
- { _MMIO(0x9888), 0x045b6300 },
- { _MMIO(0x9888), 0x105b0000 },
- { _MMIO(0x9888), 0x005b4000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x1a5b0155 },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x0a5b0000 },
- { _MMIO(0x9888), 0x0c5b4000 },
- { _MMIO(0x9888), 0x0c1fa800 },
- { _MMIO(0x9888), 0x0e1faaa0 },
- { _MMIO(0x9888), 0x101f02aa },
- { _MMIO(0x9888), 0x00384000 },
- { _MMIO(0x9888), 0x0e384000 },
- { _MMIO(0x9888), 0x16384000 },
- { _MMIO(0x9888), 0x18381555 },
- { _MMIO(0x9888), 0x02384000 },
- { _MMIO(0x9888), 0x04384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0c384000 },
- { _MMIO(0x9888), 0x0039a000 },
- { _MMIO(0x9888), 0x0639a000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0c39a000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x02392000 },
- { _MMIO(0x9888), 0x04398000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8aaaa0 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x038b6300 },
- { _MMIO(0x9888), 0x058b0062 },
- { _MMIO(0x9888), 0x118b0000 },
- { _MMIO(0x9888), 0x238b02a0 },
- { _MMIO(0x9888), 0x258b5555 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d801000 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f800001 },
- { _MMIO(0x9888), 0x43800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800420 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800421 },
- { _MMIO(0x9888), 0x41800041 },
-};
-
-static int
-get_data_port_reads_coalescing_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x01) {
- regs[n] = mux_config_data_port_reads_coalescing_0_subslices_0x01;
- lens[n] = ARRAY_SIZE(mux_config_data_port_reads_coalescing_0_subslices_0x01);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_data_port_writes_coalescing[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0xba98ba98 },
- { _MMIO(0x2748), 0xba98ba98 },
- { _MMIO(0x2744), 0x00003377 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ff72 },
- { _MMIO(0x2774), 0x0000bfd0 },
- { _MMIO(0x2778), 0x0007ff62 },
- { _MMIO(0x277c), 0x0000bfd0 },
- { _MMIO(0x2780), 0x0007ff42 },
- { _MMIO(0x2784), 0x0000bfd0 },
- { _MMIO(0x2788), 0x0007ff02 },
- { _MMIO(0x278c), 0x0000bfd0 },
- { _MMIO(0x2790), 0x0005fff2 },
- { _MMIO(0x2794), 0x0000bfd0 },
- { _MMIO(0x2798), 0x0005ffe2 },
- { _MMIO(0x279c), 0x0000bfd0 },
- { _MMIO(0x27a0), 0x0005ffc2 },
- { _MMIO(0x27a4), 0x0000bfd0 },
- { _MMIO(0x27a8), 0x0005ff82 },
- { _MMIO(0x27ac), 0x0000bfd0 },
-};
-
-static const struct i915_oa_reg flex_eu_config_data_port_writes_coalescing[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_data_port_writes_coalescing_0_subslices_0x01[] = {
- { _MMIO(0x9888), 0x103d0005 },
- { _MMIO(0x9888), 0x143d0120 },
- { _MMIO(0x9888), 0x163d2400 },
- { _MMIO(0x9888), 0x1058022f },
- { _MMIO(0x9888), 0x105b0000 },
- { _MMIO(0x9888), 0x198b0003 },
- { _MMIO(0x9888), 0x005cc000 },
- { _MMIO(0x9888), 0x065cc000 },
- { _MMIO(0x9888), 0x085cc000 },
- { _MMIO(0x9888), 0x0a5cc000 },
- { _MMIO(0x9888), 0x0e5cc000 },
- { _MMIO(0x9888), 0x025c4000 },
- { _MMIO(0x9888), 0x045c8000 },
- { _MMIO(0x9888), 0x003d0000 },
- { _MMIO(0x9888), 0x063d0094 },
- { _MMIO(0x9888), 0x083d0182 },
- { _MMIO(0x9888), 0x0a3d1814 },
- { _MMIO(0x9888), 0x0e3d0000 },
- { _MMIO(0x9888), 0x183d0000 },
- { _MMIO(0x9888), 0x1a3d0000 },
- { _MMIO(0x9888), 0x0c3d0000 },
- { _MMIO(0x9888), 0x0e582242 },
- { _MMIO(0x9888), 0x00586700 },
- { _MMIO(0x9888), 0x0258004f },
- { _MMIO(0x9888), 0x0658c000 },
- { _MMIO(0x9888), 0x0858c000 },
- { _MMIO(0x9888), 0x0a58c000 },
- { _MMIO(0x9888), 0x045b6a80 },
- { _MMIO(0x9888), 0x005b4000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x185b5400 },
- { _MMIO(0x9888), 0x1a5b0141 },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x0a5b0000 },
- { _MMIO(0x9888), 0x0c5b4000 },
- { _MMIO(0x9888), 0x0c1fa800 },
- { _MMIO(0x9888), 0x0e1faaa0 },
- { _MMIO(0x9888), 0x101f0282 },
- { _MMIO(0x9888), 0x00384000 },
- { _MMIO(0x9888), 0x0e384000 },
- { _MMIO(0x9888), 0x16384000 },
- { _MMIO(0x9888), 0x18381415 },
- { _MMIO(0x9888), 0x02384000 },
- { _MMIO(0x9888), 0x04384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0c384000 },
- { _MMIO(0x9888), 0x0039a000 },
- { _MMIO(0x9888), 0x0639a000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x02392000 },
- { _MMIO(0x9888), 0x04398000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8a82a0 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x038b6300 },
- { _MMIO(0x9888), 0x058b0062 },
- { _MMIO(0x9888), 0x118b0000 },
- { _MMIO(0x9888), 0x238b02a0 },
- { _MMIO(0x9888), 0x258b1555 },
- { _MMIO(0x9888), 0x278b0014 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x21852aaa },
- { _MMIO(0x9888), 0x23850028 },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830141 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0xd24), 0x00000000 },
- { _MMIO(0x9888), 0x4d801000 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f800001 },
- { _MMIO(0x9888), 0x43800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800420 },
- { _MMIO(0x9888), 0x3f800421 },
- { _MMIO(0x9888), 0x41800041 },
-};
-
-static int
-get_data_port_writes_coalescing_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x01) {
- regs[n] = mux_config_data_port_writes_coalescing_0_subslices_0x01;
- lens[n] = ARRAY_SIZE(mux_config_data_port_writes_coalescing_0_subslices_0x01);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fff7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x105c0232 },
- { _MMIO(0x9888), 0x10580232 },
- { _MMIO(0x9888), 0x10380232 },
- { _MMIO(0x9888), 0x10dc0232 },
- { _MMIO(0x9888), 0x10d80232 },
- { _MMIO(0x9888), 0x10b80232 },
- { _MMIO(0x9888), 0x118e4400 },
- { _MMIO(0x9888), 0x025c6080 },
- { _MMIO(0x9888), 0x045c004b },
- { _MMIO(0x9888), 0x005c8000 },
- { _MMIO(0x9888), 0x00582080 },
- { _MMIO(0x9888), 0x0258004b },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x045b4000 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f00aa },
- { _MMIO(0x9888), 0x04386080 },
- { _MMIO(0x9888), 0x0638404b },
- { _MMIO(0x9888), 0x02384000 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a380000 },
- { _MMIO(0x9888), 0x0c380000 },
- { _MMIO(0x9888), 0x00398000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x0cdc25c1 },
- { _MMIO(0x9888), 0x0adcc000 },
- { _MMIO(0x9888), 0x0ad825c1 },
- { _MMIO(0x9888), 0x18db4000 },
- { _MMIO(0x9888), 0x1adb0001 },
- { _MMIO(0x9888), 0x0e9f8000 },
- { _MMIO(0x9888), 0x109f02aa },
- { _MMIO(0x9888), 0x0eb825c1 },
- { _MMIO(0x9888), 0x18b80154 },
- { _MMIO(0x9888), 0x0ab9a000 },
- { _MMIO(0x9888), 0x0cb9a000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x0d88c000 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x258baa05 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x198c5400 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x098dc000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x098e05c0 },
- { _MMIO(0x9888), 0x058e0000 },
- { _MMIO(0x9888), 0x198f0020 },
- { _MMIO(0x9888), 0x2185aa0a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x19835000 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x09848000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x19808000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x51800040 },
- { _MMIO(0x9888), 0x43800400 },
- { _MMIO(0x9888), 0x45800800 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800c62 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f801042 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x418014a4 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1[] = {
- { _MMIO(0x9888), 0x10bf03da },
- { _MMIO(0x9888), 0x14bf0001 },
- { _MMIO(0x9888), 0x12980340 },
- { _MMIO(0x9888), 0x12990340 },
- { _MMIO(0x9888), 0x0cbf1187 },
- { _MMIO(0x9888), 0x0ebf1205 },
- { _MMIO(0x9888), 0x00bf0500 },
- { _MMIO(0x9888), 0x02bf042b },
- { _MMIO(0x9888), 0x04bf002c },
- { _MMIO(0x9888), 0x0cdac000 },
- { _MMIO(0x9888), 0x0edac000 },
- { _MMIO(0x9888), 0x00da8000 },
- { _MMIO(0x9888), 0x02dac000 },
- { _MMIO(0x9888), 0x04da4000 },
- { _MMIO(0x9888), 0x04983400 },
- { _MMIO(0x9888), 0x10980000 },
- { _MMIO(0x9888), 0x06990034 },
- { _MMIO(0x9888), 0x10990000 },
- { _MMIO(0x9888), 0x0c9dc000 },
- { _MMIO(0x9888), 0x0e9dc000 },
- { _MMIO(0x9888), 0x009d8000 },
- { _MMIO(0x9888), 0x029dc000 },
- { _MMIO(0x9888), 0x049d4000 },
- { _MMIO(0x9888), 0x109f02a8 },
- { _MMIO(0x9888), 0x0c9fa000 },
- { _MMIO(0x9888), 0x0e9f00ba },
- { _MMIO(0x9888), 0x0cb88000 },
- { _MMIO(0x9888), 0x0cb95000 },
- { _MMIO(0x9888), 0x0eb95000 },
- { _MMIO(0x9888), 0x00b94000 },
- { _MMIO(0x9888), 0x02b95000 },
- { _MMIO(0x9888), 0x04b91000 },
- { _MMIO(0x9888), 0x06b92000 },
- { _MMIO(0x9888), 0x0cba4000 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x258b800a },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b5500 },
- { _MMIO(0x9888), 0x198c4000 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x018d8000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2185800a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x1b830154 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x47800000 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800060 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_1;
- lens[n] = ARRAY_SIZE(mux_config_l3_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_2[] = {
- { _MMIO(0x9888), 0x103f03da },
- { _MMIO(0x9888), 0x143f0001 },
- { _MMIO(0x9888), 0x12180340 },
- { _MMIO(0x9888), 0x12190340 },
- { _MMIO(0x9888), 0x0c3f1187 },
- { _MMIO(0x9888), 0x0e3f1205 },
- { _MMIO(0x9888), 0x003f0500 },
- { _MMIO(0x9888), 0x023f042b },
- { _MMIO(0x9888), 0x043f002c },
- { _MMIO(0x9888), 0x0c5ac000 },
- { _MMIO(0x9888), 0x0e5ac000 },
- { _MMIO(0x9888), 0x005a8000 },
- { _MMIO(0x9888), 0x025ac000 },
- { _MMIO(0x9888), 0x045a4000 },
- { _MMIO(0x9888), 0x04183400 },
- { _MMIO(0x9888), 0x10180000 },
- { _MMIO(0x9888), 0x06190034 },
- { _MMIO(0x9888), 0x10190000 },
- { _MMIO(0x9888), 0x0c1dc000 },
- { _MMIO(0x9888), 0x0e1dc000 },
- { _MMIO(0x9888), 0x001d8000 },
- { _MMIO(0x9888), 0x021dc000 },
- { _MMIO(0x9888), 0x041d4000 },
- { _MMIO(0x9888), 0x101f02a8 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f00ba },
- { _MMIO(0x9888), 0x0c388000 },
- { _MMIO(0x9888), 0x0c395000 },
- { _MMIO(0x9888), 0x0e395000 },
- { _MMIO(0x9888), 0x00394000 },
- { _MMIO(0x9888), 0x02395000 },
- { _MMIO(0x9888), 0x04391000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x0c3a4000 },
- { _MMIO(0x9888), 0x1b8aa800 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x258b4005 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x2185800a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x1b830154 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x47800000 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800060 },
-};
-
-static int
-get_l3_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_2;
- lens[n] = ARRAY_SIZE(mux_config_l3_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_3[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_3[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_3[] = {
- { _MMIO(0x9888), 0x121b0340 },
- { _MMIO(0x9888), 0x103f0274 },
- { _MMIO(0x9888), 0x123f0000 },
- { _MMIO(0x9888), 0x129b0340 },
- { _MMIO(0x9888), 0x10bf0274 },
- { _MMIO(0x9888), 0x12bf0000 },
- { _MMIO(0x9888), 0x041b3400 },
- { _MMIO(0x9888), 0x101b0000 },
- { _MMIO(0x9888), 0x045c8000 },
- { _MMIO(0x9888), 0x0a3d4000 },
- { _MMIO(0x9888), 0x003f0080 },
- { _MMIO(0x9888), 0x023f0793 },
- { _MMIO(0x9888), 0x043f0014 },
- { _MMIO(0x9888), 0x04588000 },
- { _MMIO(0x9888), 0x005a8000 },
- { _MMIO(0x9888), 0x025ac000 },
- { _MMIO(0x9888), 0x045a4000 },
- { _MMIO(0x9888), 0x0a5b4000 },
- { _MMIO(0x9888), 0x001d8000 },
- { _MMIO(0x9888), 0x021dc000 },
- { _MMIO(0x9888), 0x041d4000 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f002a },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x00394000 },
- { _MMIO(0x9888), 0x02395000 },
- { _MMIO(0x9888), 0x04399000 },
- { _MMIO(0x9888), 0x069b0034 },
- { _MMIO(0x9888), 0x109b0000 },
- { _MMIO(0x9888), 0x06dc4000 },
- { _MMIO(0x9888), 0x0cbd4000 },
- { _MMIO(0x9888), 0x0cbf0981 },
- { _MMIO(0x9888), 0x0ebf0a0f },
- { _MMIO(0x9888), 0x06d84000 },
- { _MMIO(0x9888), 0x0cdac000 },
- { _MMIO(0x9888), 0x0edac000 },
- { _MMIO(0x9888), 0x0cdb4000 },
- { _MMIO(0x9888), 0x0c9dc000 },
- { _MMIO(0x9888), 0x0e9dc000 },
- { _MMIO(0x9888), 0x109f02a8 },
- { _MMIO(0x9888), 0x0e9f0080 },
- { _MMIO(0x9888), 0x0cb84000 },
- { _MMIO(0x9888), 0x0cb95000 },
- { _MMIO(0x9888), 0x0eb95000 },
- { _MMIO(0x9888), 0x06b92000 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x258b8009 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x198c4000 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2185800a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x1b830154 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x45800c00 },
- { _MMIO(0x9888), 0x47800c63 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f8014a5 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800045 },
-};
-
-static int
-get_l3_3_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_3;
- lens[n] = ARRAY_SIZE(mux_config_l3_3);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_4[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_4[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_4[] = {
- { _MMIO(0x9888), 0x121a0340 },
- { _MMIO(0x9888), 0x103f0017 },
- { _MMIO(0x9888), 0x123f0020 },
- { _MMIO(0x9888), 0x129a0340 },
- { _MMIO(0x9888), 0x10bf0017 },
- { _MMIO(0x9888), 0x12bf0020 },
- { _MMIO(0x9888), 0x041a3400 },
- { _MMIO(0x9888), 0x101a0000 },
- { _MMIO(0x9888), 0x043b8000 },
- { _MMIO(0x9888), 0x0a3e0010 },
- { _MMIO(0x9888), 0x003f0200 },
- { _MMIO(0x9888), 0x023f0113 },
- { _MMIO(0x9888), 0x043f0014 },
- { _MMIO(0x9888), 0x02592000 },
- { _MMIO(0x9888), 0x005a8000 },
- { _MMIO(0x9888), 0x025ac000 },
- { _MMIO(0x9888), 0x045a4000 },
- { _MMIO(0x9888), 0x0a1c8000 },
- { _MMIO(0x9888), 0x001d8000 },
- { _MMIO(0x9888), 0x021dc000 },
- { _MMIO(0x9888), 0x041d4000 },
- { _MMIO(0x9888), 0x0a1e8000 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f001a },
- { _MMIO(0x9888), 0x00394000 },
- { _MMIO(0x9888), 0x02395000 },
- { _MMIO(0x9888), 0x04391000 },
- { _MMIO(0x9888), 0x069a0034 },
- { _MMIO(0x9888), 0x109a0000 },
- { _MMIO(0x9888), 0x06bb4000 },
- { _MMIO(0x9888), 0x0abe0040 },
- { _MMIO(0x9888), 0x0cbf0984 },
- { _MMIO(0x9888), 0x0ebf0a02 },
- { _MMIO(0x9888), 0x02d94000 },
- { _MMIO(0x9888), 0x0cdac000 },
- { _MMIO(0x9888), 0x0edac000 },
- { _MMIO(0x9888), 0x0c9c0400 },
- { _MMIO(0x9888), 0x0c9dc000 },
- { _MMIO(0x9888), 0x0e9dc000 },
- { _MMIO(0x9888), 0x0c9e0400 },
- { _MMIO(0x9888), 0x109f02a8 },
- { _MMIO(0x9888), 0x0e9f0040 },
- { _MMIO(0x9888), 0x0cb95000 },
- { _MMIO(0x9888), 0x0eb95000 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x258b8009 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x198c4000 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2185800a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x1b830154 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x45800800 },
- { _MMIO(0x9888), 0x47800842 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f801084 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800044 },
-};
-
-static int
-get_l3_4_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_4;
- lens[n] = ARRAY_SIZE(mux_config_l3_4);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00006000 },
- { _MMIO(0x2774), 0x0000f3ff },
- { _MMIO(0x2778), 0x00001800 },
- { _MMIO(0x277c), 0x0000fcff },
- { _MMIO(0x2780), 0x00000600 },
- { _MMIO(0x2784), 0x0000ff3f },
- { _MMIO(0x2788), 0x00000180 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000060 },
- { _MMIO(0x2794), 0x0000fff3 },
- { _MMIO(0x2798), 0x00000018 },
- { _MMIO(0x279c), 0x0000fffc },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x143b000e },
- { _MMIO(0x9888), 0x043c55c0 },
- { _MMIO(0x9888), 0x0a1e0280 },
- { _MMIO(0x9888), 0x0c1e0408 },
- { _MMIO(0x9888), 0x10390000 },
- { _MMIO(0x9888), 0x12397a1f },
- { _MMIO(0x9888), 0x14bb000e },
- { _MMIO(0x9888), 0x04bc5000 },
- { _MMIO(0x9888), 0x0a9e0296 },
- { _MMIO(0x9888), 0x0c9e0008 },
- { _MMIO(0x9888), 0x10b90000 },
- { _MMIO(0x9888), 0x12b97a1f },
- { _MMIO(0x9888), 0x063b0042 },
- { _MMIO(0x9888), 0x103b0000 },
- { _MMIO(0x9888), 0x083c0000 },
- { _MMIO(0x9888), 0x0a3e0040 },
- { _MMIO(0x9888), 0x043f8000 },
- { _MMIO(0x9888), 0x02594000 },
- { _MMIO(0x9888), 0x045a8000 },
- { _MMIO(0x9888), 0x0c1c0400 },
- { _MMIO(0x9888), 0x041d8000 },
- { _MMIO(0x9888), 0x081e02c0 },
- { _MMIO(0x9888), 0x0e1e0000 },
- { _MMIO(0x9888), 0x0c1fa800 },
- { _MMIO(0x9888), 0x0e1f0260 },
- { _MMIO(0x9888), 0x101f0014 },
- { _MMIO(0x9888), 0x003905e0 },
- { _MMIO(0x9888), 0x06390bc0 },
- { _MMIO(0x9888), 0x02390018 },
- { _MMIO(0x9888), 0x04394000 },
- { _MMIO(0x9888), 0x04bb0042 },
- { _MMIO(0x9888), 0x10bb0000 },
- { _MMIO(0x9888), 0x02bc05c0 },
- { _MMIO(0x9888), 0x08bc0000 },
- { _MMIO(0x9888), 0x0abe0004 },
- { _MMIO(0x9888), 0x02bf8000 },
- { _MMIO(0x9888), 0x02d91000 },
- { _MMIO(0x9888), 0x02da8000 },
- { _MMIO(0x9888), 0x089c8000 },
- { _MMIO(0x9888), 0x029d8000 },
- { _MMIO(0x9888), 0x089e8000 },
- { _MMIO(0x9888), 0x0e9e0000 },
- { _MMIO(0x9888), 0x0e9fa806 },
- { _MMIO(0x9888), 0x109f0142 },
- { _MMIO(0x9888), 0x08b90617 },
- { _MMIO(0x9888), 0x0ab90be0 },
- { _MMIO(0x9888), 0x02b94000 },
- { _MMIO(0x9888), 0x0d88f000 },
- { _MMIO(0x9888), 0x0f88000c },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x1b8a2800 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x238b52a0 },
- { _MMIO(0x9888), 0x258b6a95 },
- { _MMIO(0x9888), 0x278b0029 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c1500 },
- { _MMIO(0x9888), 0x1b8c0014 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x038d8000 },
- { _MMIO(0x9888), 0x058d2000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x4d800444 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f804000 },
- { _MMIO(0x9888), 0x43801080 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800084 },
- { _MMIO(0x9888), 0x53800044 },
- { _MMIO(0x9888), 0x47801080 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800000 },
- { _MMIO(0x9888), 0x41800840 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler_1[] = {
- { _MMIO(0x9888), 0x18921400 },
- { _MMIO(0x9888), 0x149500ab },
- { _MMIO(0x9888), 0x18b21400 },
- { _MMIO(0x9888), 0x14b500ab },
- { _MMIO(0x9888), 0x18d21400 },
- { _MMIO(0x9888), 0x14d500ab },
- { _MMIO(0x9888), 0x0cdc8000 },
- { _MMIO(0x9888), 0x0edc4000 },
- { _MMIO(0x9888), 0x02dcc000 },
- { _MMIO(0x9888), 0x04dcc000 },
- { _MMIO(0x9888), 0x1abd00a0 },
- { _MMIO(0x9888), 0x0abd8000 },
- { _MMIO(0x9888), 0x0cd88000 },
- { _MMIO(0x9888), 0x0ed84000 },
- { _MMIO(0x9888), 0x04d88000 },
- { _MMIO(0x9888), 0x1adb0050 },
- { _MMIO(0x9888), 0x04db8000 },
- { _MMIO(0x9888), 0x06db8000 },
- { _MMIO(0x9888), 0x08db8000 },
- { _MMIO(0x9888), 0x0adb4000 },
- { _MMIO(0x9888), 0x109f02a0 },
- { _MMIO(0x9888), 0x0c9fa000 },
- { _MMIO(0x9888), 0x0e9f00aa },
- { _MMIO(0x9888), 0x18b82500 },
- { _MMIO(0x9888), 0x02b88000 },
- { _MMIO(0x9888), 0x04b84000 },
- { _MMIO(0x9888), 0x06b84000 },
- { _MMIO(0x9888), 0x08b84000 },
- { _MMIO(0x9888), 0x0ab84000 },
- { _MMIO(0x9888), 0x0cb88000 },
- { _MMIO(0x9888), 0x0cb98000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x00b98000 },
- { _MMIO(0x9888), 0x02b9a000 },
- { _MMIO(0x9888), 0x04b9a000 },
- { _MMIO(0x9888), 0x06b92000 },
- { _MMIO(0x9888), 0x1aba0200 },
- { _MMIO(0x9888), 0x02ba8000 },
- { _MMIO(0x9888), 0x0cba8000 },
- { _MMIO(0x9888), 0x04908000 },
- { _MMIO(0x9888), 0x04918000 },
- { _MMIO(0x9888), 0x04927300 },
- { _MMIO(0x9888), 0x10920000 },
- { _MMIO(0x9888), 0x1893000a },
- { _MMIO(0x9888), 0x0a934000 },
- { _MMIO(0x9888), 0x0a946000 },
- { _MMIO(0x9888), 0x0c959000 },
- { _MMIO(0x9888), 0x0e950098 },
- { _MMIO(0x9888), 0x10950000 },
- { _MMIO(0x9888), 0x04b04000 },
- { _MMIO(0x9888), 0x04b14000 },
- { _MMIO(0x9888), 0x04b20073 },
- { _MMIO(0x9888), 0x10b20000 },
- { _MMIO(0x9888), 0x04b38000 },
- { _MMIO(0x9888), 0x06b38000 },
- { _MMIO(0x9888), 0x08b34000 },
- { _MMIO(0x9888), 0x04b4c000 },
- { _MMIO(0x9888), 0x02b59890 },
- { _MMIO(0x9888), 0x10b50000 },
- { _MMIO(0x9888), 0x06d04000 },
- { _MMIO(0x9888), 0x06d14000 },
- { _MMIO(0x9888), 0x06d20073 },
- { _MMIO(0x9888), 0x10d20000 },
- { _MMIO(0x9888), 0x18d30020 },
- { _MMIO(0x9888), 0x02d38000 },
- { _MMIO(0x9888), 0x0cd34000 },
- { _MMIO(0x9888), 0x0ad48000 },
- { _MMIO(0x9888), 0x04d42000 },
- { _MMIO(0x9888), 0x0ed59000 },
- { _MMIO(0x9888), 0x00d59800 },
- { _MMIO(0x9888), 0x10d50000 },
- { _MMIO(0x9888), 0x0f88000e },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b5500 },
- { _MMIO(0x9888), 0x258b000a },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x0d8d8000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x018d8000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x2185000a },
- { _MMIO(0x9888), 0x1b830150 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d848000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d808000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47801021 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800c64 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800c02 },
-};
-
-static int
-get_sampler_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler_1;
- lens[n] = ARRAY_SIZE(mux_config_sampler_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler_2[] = {
- { _MMIO(0x9888), 0x18121400 },
- { _MMIO(0x9888), 0x141500ab },
- { _MMIO(0x9888), 0x18321400 },
- { _MMIO(0x9888), 0x143500ab },
- { _MMIO(0x9888), 0x18521400 },
- { _MMIO(0x9888), 0x145500ab },
- { _MMIO(0x9888), 0x0c5c8000 },
- { _MMIO(0x9888), 0x0e5c4000 },
- { _MMIO(0x9888), 0x025cc000 },
- { _MMIO(0x9888), 0x045cc000 },
- { _MMIO(0x9888), 0x1a3d00a0 },
- { _MMIO(0x9888), 0x0a3d8000 },
- { _MMIO(0x9888), 0x0c588000 },
- { _MMIO(0x9888), 0x0e584000 },
- { _MMIO(0x9888), 0x04588000 },
- { _MMIO(0x9888), 0x1a5b0050 },
- { _MMIO(0x9888), 0x045b8000 },
- { _MMIO(0x9888), 0x065b8000 },
- { _MMIO(0x9888), 0x085b8000 },
- { _MMIO(0x9888), 0x0a5b4000 },
- { _MMIO(0x9888), 0x101f02a0 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f00aa },
- { _MMIO(0x9888), 0x18382500 },
- { _MMIO(0x9888), 0x02388000 },
- { _MMIO(0x9888), 0x04384000 },
- { _MMIO(0x9888), 0x06384000 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0c388000 },
- { _MMIO(0x9888), 0x0c398000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x00398000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x1a3a0200 },
- { _MMIO(0x9888), 0x023a8000 },
- { _MMIO(0x9888), 0x0c3a8000 },
- { _MMIO(0x9888), 0x04108000 },
- { _MMIO(0x9888), 0x04118000 },
- { _MMIO(0x9888), 0x04127300 },
- { _MMIO(0x9888), 0x10120000 },
- { _MMIO(0x9888), 0x1813000a },
- { _MMIO(0x9888), 0x0a134000 },
- { _MMIO(0x9888), 0x0a146000 },
- { _MMIO(0x9888), 0x0c159000 },
- { _MMIO(0x9888), 0x0e150098 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x04304000 },
- { _MMIO(0x9888), 0x04314000 },
- { _MMIO(0x9888), 0x04320073 },
- { _MMIO(0x9888), 0x10320000 },
- { _MMIO(0x9888), 0x04338000 },
- { _MMIO(0x9888), 0x06338000 },
- { _MMIO(0x9888), 0x08334000 },
- { _MMIO(0x9888), 0x0434c000 },
- { _MMIO(0x9888), 0x02359890 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x06504000 },
- { _MMIO(0x9888), 0x06514000 },
- { _MMIO(0x9888), 0x06520073 },
- { _MMIO(0x9888), 0x10520000 },
- { _MMIO(0x9888), 0x18530020 },
- { _MMIO(0x9888), 0x02538000 },
- { _MMIO(0x9888), 0x0c534000 },
- { _MMIO(0x9888), 0x0a548000 },
- { _MMIO(0x9888), 0x04542000 },
- { _MMIO(0x9888), 0x0e559000 },
- { _MMIO(0x9888), 0x00559800 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x1b8aa000 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x258b0005 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x2185000a },
- { _MMIO(0x9888), 0x1b830150 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d848000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d808000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47801021 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800c64 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800c02 },
-};
-
-static int
-get_sampler_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler_2;
- lens[n] = ARRAY_SIZE(mux_config_sampler_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x0000fe7f },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000ffbf },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fff7 },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fff9 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x16154d60 },
- { _MMIO(0x9888), 0x16352e60 },
- { _MMIO(0x9888), 0x16554d60 },
- { _MMIO(0x9888), 0x16950000 },
- { _MMIO(0x9888), 0x16b50000 },
- { _MMIO(0x9888), 0x16d50000 },
- { _MMIO(0x9888), 0x005c8000 },
- { _MMIO(0x9888), 0x045cc000 },
- { _MMIO(0x9888), 0x065c4000 },
- { _MMIO(0x9888), 0x083d8000 },
- { _MMIO(0x9888), 0x0a3d8000 },
- { _MMIO(0x9888), 0x0458c000 },
- { _MMIO(0x9888), 0x025b8000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5b4000 },
- { _MMIO(0x9888), 0x0c5b8000 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f00aa },
- { _MMIO(0x9888), 0x02384000 },
- { _MMIO(0x9888), 0x04388000 },
- { _MMIO(0x9888), 0x06388000 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0c384000 },
- { _MMIO(0x9888), 0x00398000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x043a8000 },
- { _MMIO(0x9888), 0x063a8000 },
- { _MMIO(0x9888), 0x08138000 },
- { _MMIO(0x9888), 0x0a138000 },
- { _MMIO(0x9888), 0x06143000 },
- { _MMIO(0x9888), 0x0415cfc7 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x02338000 },
- { _MMIO(0x9888), 0x0c338000 },
- { _MMIO(0x9888), 0x04342000 },
- { _MMIO(0x9888), 0x06344000 },
- { _MMIO(0x9888), 0x0035c700 },
- { _MMIO(0x9888), 0x063500cf },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x04538000 },
- { _MMIO(0x9888), 0x06538000 },
- { _MMIO(0x9888), 0x0454c000 },
- { _MMIO(0x9888), 0x0255cfc7 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x06dc8000 },
- { _MMIO(0x9888), 0x08dc4000 },
- { _MMIO(0x9888), 0x0cdcc000 },
- { _MMIO(0x9888), 0x0edcc000 },
- { _MMIO(0x9888), 0x1abd00a8 },
- { _MMIO(0x9888), 0x0cd8c000 },
- { _MMIO(0x9888), 0x0ed84000 },
- { _MMIO(0x9888), 0x0edb8000 },
- { _MMIO(0x9888), 0x18db0800 },
- { _MMIO(0x9888), 0x1adb0254 },
- { _MMIO(0x9888), 0x0e9faa00 },
- { _MMIO(0x9888), 0x109f02aa },
- { _MMIO(0x9888), 0x0eb84000 },
- { _MMIO(0x9888), 0x16b84000 },
- { _MMIO(0x9888), 0x18b8156a },
- { _MMIO(0x9888), 0x06b98000 },
- { _MMIO(0x9888), 0x08b9a000 },
- { _MMIO(0x9888), 0x0ab9a000 },
- { _MMIO(0x9888), 0x0cb9a000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x18baa000 },
- { _MMIO(0x9888), 0x1aba0002 },
- { _MMIO(0x9888), 0x16934000 },
- { _MMIO(0x9888), 0x1893000a },
- { _MMIO(0x9888), 0x0a947000 },
- { _MMIO(0x9888), 0x0c95c5c1 },
- { _MMIO(0x9888), 0x0e9500c3 },
- { _MMIO(0x9888), 0x10950000 },
- { _MMIO(0x9888), 0x0eb38000 },
- { _MMIO(0x9888), 0x16b30040 },
- { _MMIO(0x9888), 0x18b30020 },
- { _MMIO(0x9888), 0x06b48000 },
- { _MMIO(0x9888), 0x08b41000 },
- { _MMIO(0x9888), 0x0ab48000 },
- { _MMIO(0x9888), 0x06b5c500 },
- { _MMIO(0x9888), 0x08b500c3 },
- { _MMIO(0x9888), 0x0eb5c100 },
- { _MMIO(0x9888), 0x10b50000 },
- { _MMIO(0x9888), 0x16d31500 },
- { _MMIO(0x9888), 0x08d4e000 },
- { _MMIO(0x9888), 0x08d5c100 },
- { _MMIO(0x9888), 0x0ad5c3c5 },
- { _MMIO(0x9888), 0x10d50000 },
- { _MMIO(0x9888), 0x0d88f800 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x258baaa5 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x0f8c4000 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c5500 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x078d8000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800c42 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800063 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800800 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f8014a4 },
- { _MMIO(0x9888), 0x41801042 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x0000fe7f },
- { _MMIO(0x2780), 0x00000000 },
- { _MMIO(0x2784), 0x0000ff9f },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000ffe7 },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fffb },
- { _MMIO(0x2798), 0x00000002 },
- { _MMIO(0x279c), 0x0000fffd },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x16150000 },
- { _MMIO(0x9888), 0x16350000 },
- { _MMIO(0x9888), 0x16550000 },
- { _MMIO(0x9888), 0x16952e60 },
- { _MMIO(0x9888), 0x16b54d60 },
- { _MMIO(0x9888), 0x16d52e60 },
- { _MMIO(0x9888), 0x065c8000 },
- { _MMIO(0x9888), 0x085cc000 },
- { _MMIO(0x9888), 0x0a5cc000 },
- { _MMIO(0x9888), 0x0c5c4000 },
- { _MMIO(0x9888), 0x0e3d8000 },
- { _MMIO(0x9888), 0x183da000 },
- { _MMIO(0x9888), 0x06588000 },
- { _MMIO(0x9888), 0x08588000 },
- { _MMIO(0x9888), 0x0a584000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x185b5800 },
- { _MMIO(0x9888), 0x1a5b000a },
- { _MMIO(0x9888), 0x0e1faa00 },
- { _MMIO(0x9888), 0x101f02aa },
- { _MMIO(0x9888), 0x0e384000 },
- { _MMIO(0x9888), 0x16384000 },
- { _MMIO(0x9888), 0x18382a55 },
- { _MMIO(0x9888), 0x06398000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0c39a000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x1a3a02a0 },
- { _MMIO(0x9888), 0x0e138000 },
- { _MMIO(0x9888), 0x16130500 },
- { _MMIO(0x9888), 0x06148000 },
- { _MMIO(0x9888), 0x08146000 },
- { _MMIO(0x9888), 0x0615c100 },
- { _MMIO(0x9888), 0x0815c500 },
- { _MMIO(0x9888), 0x0a1500c3 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x16335040 },
- { _MMIO(0x9888), 0x08349000 },
- { _MMIO(0x9888), 0x0a341000 },
- { _MMIO(0x9888), 0x083500c1 },
- { _MMIO(0x9888), 0x0a35c500 },
- { _MMIO(0x9888), 0x0c3500c3 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x1853002a },
- { _MMIO(0x9888), 0x0a54e000 },
- { _MMIO(0x9888), 0x0c55c500 },
- { _MMIO(0x9888), 0x0e55c1c3 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x00dc8000 },
- { _MMIO(0x9888), 0x02dcc000 },
- { _MMIO(0x9888), 0x04dc4000 },
- { _MMIO(0x9888), 0x04bd8000 },
- { _MMIO(0x9888), 0x06bd8000 },
- { _MMIO(0x9888), 0x02d8c000 },
- { _MMIO(0x9888), 0x02db8000 },
- { _MMIO(0x9888), 0x04db4000 },
- { _MMIO(0x9888), 0x06db4000 },
- { _MMIO(0x9888), 0x08db8000 },
- { _MMIO(0x9888), 0x0c9fa000 },
- { _MMIO(0x9888), 0x0e9f00aa },
- { _MMIO(0x9888), 0x02b84000 },
- { _MMIO(0x9888), 0x04b84000 },
- { _MMIO(0x9888), 0x06b84000 },
- { _MMIO(0x9888), 0x08b84000 },
- { _MMIO(0x9888), 0x0ab88000 },
- { _MMIO(0x9888), 0x0cb88000 },
- { _MMIO(0x9888), 0x00b98000 },
- { _MMIO(0x9888), 0x02b9a000 },
- { _MMIO(0x9888), 0x04b9a000 },
- { _MMIO(0x9888), 0x06b92000 },
- { _MMIO(0x9888), 0x0aba8000 },
- { _MMIO(0x9888), 0x0cba8000 },
- { _MMIO(0x9888), 0x04938000 },
- { _MMIO(0x9888), 0x06938000 },
- { _MMIO(0x9888), 0x0494c000 },
- { _MMIO(0x9888), 0x0295cfc7 },
- { _MMIO(0x9888), 0x10950000 },
- { _MMIO(0x9888), 0x02b38000 },
- { _MMIO(0x9888), 0x08b38000 },
- { _MMIO(0x9888), 0x04b42000 },
- { _MMIO(0x9888), 0x06b41000 },
- { _MMIO(0x9888), 0x00b5c700 },
- { _MMIO(0x9888), 0x04b500cf },
- { _MMIO(0x9888), 0x10b50000 },
- { _MMIO(0x9888), 0x0ad38000 },
- { _MMIO(0x9888), 0x0cd38000 },
- { _MMIO(0x9888), 0x06d46000 },
- { _MMIO(0x9888), 0x04d5c700 },
- { _MMIO(0x9888), 0x06d500cf },
- { _MMIO(0x9888), 0x10d50000 },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8aaaa0 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x258b555a },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x238b5500 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x018d8000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800882 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45801082 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x478014a5 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800002 },
- { _MMIO(0x9888), 0x41800c62 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extra[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extra[] = {
- { _MMIO(0xe458), 0x00001000 },
- { _MMIO(0xe558), 0x00003002 },
- { _MMIO(0xe658), 0x00005004 },
- { _MMIO(0xe758), 0x00011010 },
- { _MMIO(0xe45c), 0x00050012 },
- { _MMIO(0xe55c), 0x00052051 },
- { _MMIO(0xe65c), 0x00000008 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extra[] = {
- { _MMIO(0x9888), 0x161503e0 },
- { _MMIO(0x9888), 0x163503e0 },
- { _MMIO(0x9888), 0x165503e0 },
- { _MMIO(0x9888), 0x169503e0 },
- { _MMIO(0x9888), 0x16b503e0 },
- { _MMIO(0x9888), 0x16d503e0 },
- { _MMIO(0x9888), 0x045cc000 },
- { _MMIO(0x9888), 0x083d8000 },
- { _MMIO(0x9888), 0x04584000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5b8000 },
- { _MMIO(0x9888), 0x0e1f00a8 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0c388000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x0c3a8000 },
- { _MMIO(0x9888), 0x08138000 },
- { _MMIO(0x9888), 0x06141000 },
- { _MMIO(0x9888), 0x041500c3 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x0a338000 },
- { _MMIO(0x9888), 0x06342000 },
- { _MMIO(0x9888), 0x0435c300 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x0c538000 },
- { _MMIO(0x9888), 0x06544000 },
- { _MMIO(0x9888), 0x065500c3 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x00dc8000 },
- { _MMIO(0x9888), 0x02dc4000 },
- { _MMIO(0x9888), 0x02bd8000 },
- { _MMIO(0x9888), 0x00d88000 },
- { _MMIO(0x9888), 0x02db4000 },
- { _MMIO(0x9888), 0x04db8000 },
- { _MMIO(0x9888), 0x0c9fa000 },
- { _MMIO(0x9888), 0x0e9f0002 },
- { _MMIO(0x9888), 0x02b84000 },
- { _MMIO(0x9888), 0x04b84000 },
- { _MMIO(0x9888), 0x06b88000 },
- { _MMIO(0x9888), 0x00b98000 },
- { _MMIO(0x9888), 0x02b9a000 },
- { _MMIO(0x9888), 0x06ba8000 },
- { _MMIO(0x9888), 0x02938000 },
- { _MMIO(0x9888), 0x04942000 },
- { _MMIO(0x9888), 0x0095c300 },
- { _MMIO(0x9888), 0x10950000 },
- { _MMIO(0x9888), 0x04b38000 },
- { _MMIO(0x9888), 0x04b44000 },
- { _MMIO(0x9888), 0x02b500c3 },
- { _MMIO(0x9888), 0x10b50000 },
- { _MMIO(0x9888), 0x06d38000 },
- { _MMIO(0x9888), 0x04d48000 },
- { _MMIO(0x9888), 0x02d5c300 },
- { _MMIO(0x9888), 0x10d50000 },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x238b3500 },
- { _MMIO(0x9888), 0x258b0005 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x018d8000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x2185000a },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800c40 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41801482 },
- { _MMIO(0x9888), 0x31800000 },
-};
-
-static int
-get_compute_extra_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extra;
- lens[n] = ARRAY_SIZE(mux_config_compute_extra);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_vme_pipe[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00100030 },
- { _MMIO(0x2774), 0x0000fff9 },
- { _MMIO(0x2778), 0x00000002 },
- { _MMIO(0x277c), 0x0000fffc },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000fff3 },
- { _MMIO(0x2788), 0x00100180 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000ffcf },
- { _MMIO(0x2798), 0x00000002 },
- { _MMIO(0x279c), 0x0000ff3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_vme_pipe[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00008003 },
-};
-
-static const struct i915_oa_reg mux_config_vme_pipe[] = {
- { _MMIO(0x9888), 0x14100812 },
- { _MMIO(0x9888), 0x14125800 },
- { _MMIO(0x9888), 0x161200c0 },
- { _MMIO(0x9888), 0x14300812 },
- { _MMIO(0x9888), 0x14325800 },
- { _MMIO(0x9888), 0x163200c0 },
- { _MMIO(0x9888), 0x005c4000 },
- { _MMIO(0x9888), 0x065c8000 },
- { _MMIO(0x9888), 0x085cc000 },
- { _MMIO(0x9888), 0x0a5cc000 },
- { _MMIO(0x9888), 0x0c5cc000 },
- { _MMIO(0x9888), 0x003d8000 },
- { _MMIO(0x9888), 0x0e3d8000 },
- { _MMIO(0x9888), 0x183d2800 },
- { _MMIO(0x9888), 0x00584000 },
- { _MMIO(0x9888), 0x06588000 },
- { _MMIO(0x9888), 0x0858c000 },
- { _MMIO(0x9888), 0x005b4000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x185b9400 },
- { _MMIO(0x9888), 0x1a5b002a },
- { _MMIO(0x9888), 0x0c1f0800 },
- { _MMIO(0x9888), 0x0e1faa00 },
- { _MMIO(0x9888), 0x101f002a },
- { _MMIO(0x9888), 0x00384000 },
- { _MMIO(0x9888), 0x0e384000 },
- { _MMIO(0x9888), 0x16384000 },
- { _MMIO(0x9888), 0x18380155 },
- { _MMIO(0x9888), 0x00392000 },
- { _MMIO(0x9888), 0x06398000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0c39a000 },
- { _MMIO(0x9888), 0x00100047 },
- { _MMIO(0x9888), 0x06101a80 },
- { _MMIO(0x9888), 0x10100000 },
- { _MMIO(0x9888), 0x0810c000 },
- { _MMIO(0x9888), 0x0811c000 },
- { _MMIO(0x9888), 0x08126151 },
- { _MMIO(0x9888), 0x10120000 },
- { _MMIO(0x9888), 0x00134000 },
- { _MMIO(0x9888), 0x0e134000 },
- { _MMIO(0x9888), 0x161300a0 },
- { _MMIO(0x9888), 0x0a301ac7 },
- { _MMIO(0x9888), 0x10300000 },
- { _MMIO(0x9888), 0x0c30c000 },
- { _MMIO(0x9888), 0x0c31c000 },
- { _MMIO(0x9888), 0x0c326151 },
- { _MMIO(0x9888), 0x10320000 },
- { _MMIO(0x9888), 0x16332a00 },
- { _MMIO(0x9888), 0x18330001 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8a2aa0 },
- { _MMIO(0x9888), 0x238b0020 },
- { _MMIO(0x9888), 0x258b5550 },
- { _MMIO(0x9888), 0x278b0001 },
- { _MMIO(0x9888), 0x1f850080 },
- { _MMIO(0x9888), 0x2185aaa0 },
- { _MMIO(0x9888), 0x23850002 },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830015 },
- { _MMIO(0x9888), 0x01844000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x11804000 },
- { _MMIO(0x9888), 0x17808000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3d800800 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800002 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800884 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800002 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
-};
-
-static int
-get_vme_pipe_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_vme_pipe;
- lens[n] = ARRAY_SIZE(mux_config_vme_pipe);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2744), 0x00800000 },
@@ -4035,6 +60,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x000000a0 },
{ _MMIO(0x9888), 0x198b0000 },
{ _MMIO(0x9888), 0x078b0066 },
{ _MMIO(0x9888), 0x118b0000 },
@@ -4047,1330 +73,38 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x4f800000 },
{ _MMIO(0x9888), 0x41800000 },
{ _MMIO(0x9888), 0x31800000 },
-};
-
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_bdw(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_L3_CACHE:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_l3_cache_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_l3_cache;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_l3_cache);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_l3_cache;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_l3_cache);
-
- return 0;
- case METRIC_SET_ID_DATA_PORT_READS_COALESCING:
- dev_priv->perf.oa.n_mux_configs =
- get_data_port_reads_coalescing_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"DATA_PORT_READS_COALESCING\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_data_port_reads_coalescing;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_data_port_reads_coalescing);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_data_port_reads_coalescing;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_data_port_reads_coalescing);
-
- return 0;
- case METRIC_SET_ID_DATA_PORT_WRITES_COALESCING:
- dev_priv->perf.oa.n_mux_configs =
- get_data_port_writes_coalescing_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"DATA_PORT_WRITES_COALESCING\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_data_port_writes_coalescing;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_data_port_writes_coalescing);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_data_port_writes_coalescing;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_data_port_writes_coalescing);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_L3_2:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_2);
-
- return 0;
- case METRIC_SET_ID_L3_3:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_3_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_3;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_3);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_3;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_3);
-
- return 0;
- case METRIC_SET_ID_L3_4:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_4_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_4\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_4;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_4);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_4;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_4);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER_1:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler_1);
-
- return 0;
- case METRIC_SET_ID_SAMPLER_2:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler_2);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTRA:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extra_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extra;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extra);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extra;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extra);
-
- return 0;
- case METRIC_SET_ID_VME_PIPE:
- dev_priv->perf.oa.n_mux_configs =
- get_vme_pipe_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_vme_pipe;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_vme_pipe);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_vme_pipe;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_vme_pipe);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "b541bd57-0e0f-4154-b4c0-5858010a2bf7",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "35fbc9b2-a891-40a6-a38d-022bb7057552",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "233d0544-fff7-4281-8291-e02f222aff72",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "2b255d48-2117-4fef-a8f7-f151e1d25a2c",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "f7fd3220-b466-4a4d-9f98-b0caf3f2394c",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
-}
-
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "e99ccaca-821c-4df9-97a7-96bdb7204e43",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE);
-}
-
-static struct device_attribute dev_attr_compute_l3_cache_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_l3_cache_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_l3_cache[] = {
- &dev_attr_compute_l3_cache_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_l3_cache = {
- .name = "27a364dc-8225-4ecb-b607-d6f1925598d9",
- .attrs = attrs_compute_l3_cache,
-};
-
-static ssize_t
-show_data_port_reads_coalescing_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_DATA_PORT_READS_COALESCING);
-}
-
-static struct device_attribute dev_attr_data_port_reads_coalescing_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_data_port_reads_coalescing_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_data_port_reads_coalescing[] = {
- &dev_attr_data_port_reads_coalescing_id.attr,
- NULL,
-};
-
-static struct attribute_group group_data_port_reads_coalescing = {
- .name = "857fc630-2f09-4804-85f1-084adfadd5ab",
- .attrs = attrs_data_port_reads_coalescing,
-};
-
-static ssize_t
-show_data_port_writes_coalescing_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_DATA_PORT_WRITES_COALESCING);
-}
-
-static struct device_attribute dev_attr_data_port_writes_coalescing_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_data_port_writes_coalescing_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_data_port_writes_coalescing[] = {
- &dev_attr_data_port_writes_coalescing_id.attr,
- NULL,
-};
-
-static struct attribute_group group_data_port_writes_coalescing = {
- .name = "343ebc99-4a55-414c-8c17-d8e259cf5e20",
- .attrs = attrs_data_port_writes_coalescing,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "7bdafd88-a4fa-4ed5-bc09-1a977aa5be3e",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "9385ebb2-f34f-4aa5-aec5-7e9cbbea0f0b",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2);
-}
-
-static struct device_attribute dev_attr_l3_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_2[] = {
- &dev_attr_l3_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_2 = {
- .name = "446ae59b-ff2e-41c9-b49e-0184a54bf00a",
- .attrs = attrs_l3_2,
-};
-
-static ssize_t
-show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3);
-}
-
-static struct device_attribute dev_attr_l3_3_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_3_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_3[] = {
- &dev_attr_l3_3_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_3 = {
- .name = "84a7956f-1ea4-4d0d-837f-e39a0376e38c",
- .attrs = attrs_l3_3,
-};
-
-static ssize_t
-show_l3_4_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_4);
-}
-
-static struct device_attribute dev_attr_l3_4_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_4_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_4[] = {
- &dev_attr_l3_4_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_4 = {
- .name = "92b493d9-df18-4bed-be06-5cac6f2a6f5f",
- .attrs = attrs_l3_4,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "14345c35-cc46-40d0-bb04-6ed1fbb43679",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER_1);
-}
-
-static struct device_attribute dev_attr_sampler_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler_1[] = {
- &dev_attr_sampler_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler_1 = {
- .name = "f0c6ba37-d3d3-4211-91b5-226730312a54",
- .attrs = attrs_sampler_1,
-};
-
-static ssize_t
-show_sampler_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER_2);
-}
-
-static struct device_attribute dev_attr_sampler_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler_2[] = {
- &dev_attr_sampler_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler_2 = {
- .name = "30bf3702-48cf-4bca-b412-7cf50bb2f564",
- .attrs = attrs_sampler_2,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "238bec85-df05-44f3-b905-d166712f2451",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "24bf02cd-8693-4583-981c-c4165b33da01",
- .attrs = attrs_tdl_2,
-};
-
-static ssize_t
-show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA);
-}
-
-static struct device_attribute dev_attr_compute_extra_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extra_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extra[] = {
- &dev_attr_compute_extra_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extra = {
- .name = "8fb61ba2-2fbb-454c-a136-2dec5a8a595e",
- .attrs = attrs_compute_extra,
-};
-
-static ssize_t
-show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE);
-}
-
-static struct device_attribute dev_attr_vme_pipe_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_vme_pipe_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_vme_pipe[] = {
- &dev_attr_vme_pipe_id.attr,
- NULL,
-};
-
-static struct attribute_group group_vme_pipe = {
- .name = "e1743ca0-7fc8-410b-a066-de7bbb9280b7",
- .attrs = attrs_vme_pipe,
+ { _MMIO(0x9840), 0x00000080 },
};
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "d6de6f55-e526-4f79-a6a6-d7315c09044e",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_bdw(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_bdw(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "d6de6f55-e526-4f79-a6a6-d7315c09044e",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (ret)
- goto error_compute_l3_cache;
- }
- if (get_data_port_reads_coalescing_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_data_port_reads_coalescing);
- if (ret)
- goto error_data_port_reads_coalescing;
- }
- if (get_data_port_writes_coalescing_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_data_port_writes_coalescing);
- if (ret)
- goto error_data_port_writes_coalescing;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (ret)
- goto error_l3_2;
- }
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (ret)
- goto error_l3_3;
- }
- if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_4);
- if (ret)
- goto error_l3_4;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler_1);
- if (ret)
- goto error_sampler_1;
- }
- if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler_2);
- if (ret)
- goto error_sampler_2;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (ret)
- goto error_compute_extra;
- }
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (ret)
- goto error_vme_pipe;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
-error_vme_pipe:
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
-error_compute_extra:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_2);
-error_sampler_2:
- if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_1);
-error_sampler_1:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_4);
-error_l3_4:
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
-error_l3_3:
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
-error_l3_2:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_data_port_writes_coalescing_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_data_port_writes_coalescing);
-error_data_port_writes_coalescing:
- if (get_data_port_reads_coalescing_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_data_port_reads_coalescing);
-error_data_port_reads_coalescing:
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
-error_compute_l3_cache:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_bdw(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "d6de6f55-e526-4f79-a6a6-d7315c09044e";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (get_data_port_reads_coalescing_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_data_port_reads_coalescing);
- if (get_data_port_writes_coalescing_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_data_port_writes_coalescing);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_4);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_1);
- if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_2);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_bdw.h b/drivers/gpu/drm/i915/i915_oa_bdw.h
index 6363ff9f64c0..b812d16162ac 100644
--- a/drivers/gpu/drm/i915/i915_oa_bdw.h
+++ b/drivers/gpu/drm/i915/i915_oa_bdw.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_BDW_H__
#define __I915_OA_BDW_H__
-extern int i915_oa_n_builtin_metric_sets_bdw;
-
-extern int i915_oa_select_metric_set_bdw(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_bdw(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_bdw(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_bdw(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_bxt.c b/drivers/gpu/drm/i915/i915_oa_bxt.c
index 93864d8f32dd..b69b900de0fe 100644
--- a/drivers/gpu/drm/i915/i915_oa_bxt.c
+++ b/drivers/gpu/drm/i915/i915_oa_bxt.c
@@ -31,1702 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_bxt.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_COMPUTE_L3_CACHE,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_COMPUTE_EXTRA,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_bxt = 15;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic_0_sku_gte_0x03[] = {
- { _MMIO(0x9888), 0x166c00f0 },
- { _MMIO(0x9888), 0x12120280 },
- { _MMIO(0x9888), 0x12320280 },
- { _MMIO(0x9888), 0x11930317 },
- { _MMIO(0x9888), 0x159303df },
- { _MMIO(0x9888), 0x3f900c00 },
- { _MMIO(0x9888), 0x419000a0 },
- { _MMIO(0x9888), 0x002d1000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x082d5000 },
- { _MMIO(0x9888), 0x0a2d1000 },
- { _MMIO(0x9888), 0x0c2e0800 },
- { _MMIO(0x9888), 0x0e2e5900 },
- { _MMIO(0x9888), 0x0a4c8000 },
- { _MMIO(0x9888), 0x0c4c8000 },
- { _MMIO(0x9888), 0x0e4c4000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e2000 },
- { _MMIO(0x9888), 0x1c4f0010 },
- { _MMIO(0x9888), 0x0a6c0053 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1a0fcc00 },
- { _MMIO(0x9888), 0x1c0f0002 },
- { _MMIO(0x9888), 0x1c2c0040 },
- { _MMIO(0x9888), 0x00101000 },
- { _MMIO(0x9888), 0x04101000 },
- { _MMIO(0x9888), 0x00114000 },
- { _MMIO(0x9888), 0x08114000 },
- { _MMIO(0x9888), 0x00120020 },
- { _MMIO(0x9888), 0x08120021 },
- { _MMIO(0x9888), 0x00141000 },
- { _MMIO(0x9888), 0x08141000 },
- { _MMIO(0x9888), 0x02308000 },
- { _MMIO(0x9888), 0x04302000 },
- { _MMIO(0x9888), 0x06318000 },
- { _MMIO(0x9888), 0x08318000 },
- { _MMIO(0x9888), 0x06320800 },
- { _MMIO(0x9888), 0x08320840 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x06344000 },
- { _MMIO(0x9888), 0x08344000 },
- { _MMIO(0x9888), 0x0d931831 },
- { _MMIO(0x9888), 0x0f939f3f },
- { _MMIO(0x9888), 0x01939e80 },
- { _MMIO(0x9888), 0x039303bc },
- { _MMIO(0x9888), 0x0593000e },
- { _MMIO(0x9888), 0x1993002a },
- { _MMIO(0x9888), 0x07930000 },
- { _MMIO(0x9888), 0x09930000 },
- { _MMIO(0x9888), 0x1d900177 },
- { _MMIO(0x9888), 0x1f900187 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25904000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x53901110 },
- { _MMIO(0x9888), 0x43900423 },
- { _MMIO(0x9888), 0x55900111 },
- { _MMIO(0x9888), 0x47900c02 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900020 },
- { _MMIO(0x9888), 0x59901111 },
- { _MMIO(0x9888), 0x4b900421 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x45900821 },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- if (dev_priv->drm.pdev->revision >= 0x03) {
- regs[n] = mux_config_render_basic_0_sku_gte_0x03;
- lens[n] = ARRAY_SIZE(mux_config_render_basic_0_sku_gte_0x03);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x124f1c00 },
- { _MMIO(0x9888), 0x39900340 },
- { _MMIO(0x9888), 0x3f900c00 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x002d5000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x082d4000 },
- { _MMIO(0x9888), 0x0a2d1000 },
- { _MMIO(0x9888), 0x0c2d5000 },
- { _MMIO(0x9888), 0x0e2d4000 },
- { _MMIO(0x9888), 0x0c2e1400 },
- { _MMIO(0x9888), 0x0e2e5100 },
- { _MMIO(0x9888), 0x102e0114 },
- { _MMIO(0x9888), 0x044cc000 },
- { _MMIO(0x9888), 0x0a4c8000 },
- { _MMIO(0x9888), 0x0c4c8000 },
- { _MMIO(0x9888), 0x0e4c4000 },
- { _MMIO(0x9888), 0x104c8000 },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x004ea000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e2000 },
- { _MMIO(0x9888), 0x0c4ea000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x004f6b42 },
- { _MMIO(0x9888), 0x064f6200 },
- { _MMIO(0x9888), 0x084f4100 },
- { _MMIO(0x9888), 0x0a4f0061 },
- { _MMIO(0x9888), 0x0c4f6c4c },
- { _MMIO(0x9888), 0x0e4f4b00 },
- { _MMIO(0x9888), 0x1a4f0000 },
- { _MMIO(0x9888), 0x1c4f0000 },
- { _MMIO(0x9888), 0x180f5000 },
- { _MMIO(0x9888), 0x1a0f8800 },
- { _MMIO(0x9888), 0x1c0f08a2 },
- { _MMIO(0x9888), 0x182c4000 },
- { _MMIO(0x9888), 0x1c2c1451 },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x1a2c0010 },
- { _MMIO(0x9888), 0x01938000 },
- { _MMIO(0x9888), 0x0f938000 },
- { _MMIO(0x9888), 0x19938a28 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x19900177 },
- { _MMIO(0x9888), 0x1b900178 },
- { _MMIO(0x9888), 0x1d900125 },
- { _MMIO(0x9888), 0x1f900123 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x25904000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x53901000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x55900111 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900000 },
- { _MMIO(0x9888), 0x45900000 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_basic;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile[] = {
- { _MMIO(0x9888), 0x0c2e001f },
- { _MMIO(0x9888), 0x0a2f0000 },
- { _MMIO(0x9888), 0x10186800 },
- { _MMIO(0x9888), 0x11810019 },
- { _MMIO(0x9888), 0x15810013 },
- { _MMIO(0x9888), 0x13820020 },
- { _MMIO(0x9888), 0x11830020 },
- { _MMIO(0x9888), 0x17840000 },
- { _MMIO(0x9888), 0x11860007 },
- { _MMIO(0x9888), 0x21860000 },
- { _MMIO(0x9888), 0x178703e0 },
- { _MMIO(0x9888), 0x0c2d8000 },
- { _MMIO(0x9888), 0x042d4000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x022e5400 },
- { _MMIO(0x9888), 0x002e0000 },
- { _MMIO(0x9888), 0x0e2e0080 },
- { _MMIO(0x9888), 0x082f0040 },
- { _MMIO(0x9888), 0x002f0000 },
- { _MMIO(0x9888), 0x06143000 },
- { _MMIO(0x9888), 0x06174000 },
- { _MMIO(0x9888), 0x06180012 },
- { _MMIO(0x9888), 0x00180000 },
- { _MMIO(0x9888), 0x0d804000 },
- { _MMIO(0x9888), 0x0f804000 },
- { _MMIO(0x9888), 0x05804000 },
- { _MMIO(0x9888), 0x09810200 },
- { _MMIO(0x9888), 0x0b810030 },
- { _MMIO(0x9888), 0x03810003 },
- { _MMIO(0x9888), 0x21819140 },
- { _MMIO(0x9888), 0x23819050 },
- { _MMIO(0x9888), 0x25810018 },
- { _MMIO(0x9888), 0x0b820980 },
- { _MMIO(0x9888), 0x03820d80 },
- { _MMIO(0x9888), 0x11820000 },
- { _MMIO(0x9888), 0x0182c000 },
- { _MMIO(0x9888), 0x07828000 },
- { _MMIO(0x9888), 0x09824000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x0d830004 },
- { _MMIO(0x9888), 0x0583000c },
- { _MMIO(0x9888), 0x0f831000 },
- { _MMIO(0x9888), 0x01848072 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x09844000 },
- { _MMIO(0x9888), 0x0f848000 },
- { _MMIO(0x9888), 0x07860000 },
- { _MMIO(0x9888), 0x09860092 },
- { _MMIO(0x9888), 0x0f860400 },
- { _MMIO(0x9888), 0x01869100 },
- { _MMIO(0x9888), 0x0f870065 },
- { _MMIO(0x9888), 0x01870000 },
- { _MMIO(0x9888), 0x19930800 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x1b952000 },
- { _MMIO(0x9888), 0x1d955055 },
- { _MMIO(0x9888), 0x1f951455 },
- { _MMIO(0x9888), 0x0992a000 },
- { _MMIO(0x9888), 0x0f928000 },
- { _MMIO(0x9888), 0x1192a800 },
- { _MMIO(0x9888), 0x1392028a },
- { _MMIO(0x9888), 0x0b92a000 },
- { _MMIO(0x9888), 0x0d922000 },
- { _MMIO(0x9888), 0x13908000 },
- { _MMIO(0x9888), 0x21908000 },
- { _MMIO(0x9888), 0x23908000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27908000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f908000 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x15908000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900c01 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900863 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900061 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900000 },
- { _MMIO(0x9888), 0x45900c22 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_pipe_profile;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads[] = {
- { _MMIO(0x9888), 0x19800343 },
- { _MMIO(0x9888), 0x39900340 },
- { _MMIO(0x9888), 0x3f901000 },
- { _MMIO(0x9888), 0x41900003 },
- { _MMIO(0x9888), 0x03803180 },
- { _MMIO(0x9888), 0x058035e2 },
- { _MMIO(0x9888), 0x0780006a },
- { _MMIO(0x9888), 0x11800000 },
- { _MMIO(0x9888), 0x2181a000 },
- { _MMIO(0x9888), 0x2381000a },
- { _MMIO(0x9888), 0x1d950550 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d92a000 },
- { _MMIO(0x9888), 0x0f922000 },
- { _MMIO(0x9888), 0x13900170 },
- { _MMIO(0x9888), 0x21900171 },
- { _MMIO(0x9888), 0x23900172 },
- { _MMIO(0x9888), 0x25900173 },
- { _MMIO(0x9888), 0x27900174 },
- { _MMIO(0x9888), 0x29900175 },
- { _MMIO(0x9888), 0x2b900176 },
- { _MMIO(0x9888), 0x2d900177 },
- { _MMIO(0x9888), 0x2f90017f },
- { _MMIO(0x9888), 0x31900125 },
- { _MMIO(0x9888), 0x15900123 },
- { _MMIO(0x9888), 0x17900121 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43901084 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47901080 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49901084 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b901084 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900004 },
- { _MMIO(0x9888), 0x45900000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_reads;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes[] = {
- { _MMIO(0x9888), 0x19800343 },
- { _MMIO(0x9888), 0x39900340 },
- { _MMIO(0x9888), 0x3f900000 },
- { _MMIO(0x9888), 0x41900080 },
- { _MMIO(0x9888), 0x03803180 },
- { _MMIO(0x9888), 0x058035e2 },
- { _MMIO(0x9888), 0x0780006a },
- { _MMIO(0x9888), 0x11800000 },
- { _MMIO(0x9888), 0x2181a000 },
- { _MMIO(0x9888), 0x2381000a },
- { _MMIO(0x9888), 0x1d950550 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d92a000 },
- { _MMIO(0x9888), 0x0f922000 },
- { _MMIO(0x9888), 0x13900180 },
- { _MMIO(0x9888), 0x21900181 },
- { _MMIO(0x9888), 0x23900182 },
- { _MMIO(0x9888), 0x25900183 },
- { _MMIO(0x9888), 0x27900184 },
- { _MMIO(0x9888), 0x29900185 },
- { _MMIO(0x9888), 0x2b900186 },
- { _MMIO(0x9888), 0x2d900187 },
- { _MMIO(0x9888), 0x2f900170 },
- { _MMIO(0x9888), 0x31900125 },
- { _MMIO(0x9888), 0x15900123 },
- { _MMIO(0x9888), 0x17900121 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43901084 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47901080 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49901084 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b901084 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900004 },
- { _MMIO(0x9888), 0x45900000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_writes;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fc2a },
- { _MMIO(0x2774), 0x0000bf00 },
- { _MMIO(0x2778), 0x0007fc6a },
- { _MMIO(0x277c), 0x0000bf00 },
- { _MMIO(0x2780), 0x0007fc92 },
- { _MMIO(0x2784), 0x0000bf00 },
- { _MMIO(0x2788), 0x0007fca2 },
- { _MMIO(0x278c), 0x0000bf00 },
- { _MMIO(0x2790), 0x0007fc32 },
- { _MMIO(0x2794), 0x0000bf00 },
- { _MMIO(0x2798), 0x0007fc9a },
- { _MMIO(0x279c), 0x0000bf00 },
- { _MMIO(0x27a0), 0x0007fe6a },
- { _MMIO(0x27a4), 0x0000bf00 },
- { _MMIO(0x27a8), 0x0007fe7a },
- { _MMIO(0x27ac), 0x0000bf00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x141c0160 },
- { _MMIO(0x9888), 0x161c0015 },
- { _MMIO(0x9888), 0x181c0120 },
- { _MMIO(0x9888), 0x002d5000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x082d5000 },
- { _MMIO(0x9888), 0x0a2d5000 },
- { _MMIO(0x9888), 0x0c2d5000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x0c2e5400 },
- { _MMIO(0x9888), 0x0e2e5515 },
- { _MMIO(0x9888), 0x102e0155 },
- { _MMIO(0x9888), 0x044cc000 },
- { _MMIO(0x9888), 0x0a4c8000 },
- { _MMIO(0x9888), 0x0c4cc000 },
- { _MMIO(0x9888), 0x0e4cc000 },
- { _MMIO(0x9888), 0x104c8000 },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x004ea000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084ea000 },
- { _MMIO(0x9888), 0x0a4ea000 },
- { _MMIO(0x9888), 0x0c4ea000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x0e4f4b41 },
- { _MMIO(0x9888), 0x004f4200 },
- { _MMIO(0x9888), 0x024f404c },
- { _MMIO(0x9888), 0x1c4f0000 },
- { _MMIO(0x9888), 0x1a4f0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x061b8000 },
- { _MMIO(0x9888), 0x081bc000 },
- { _MMIO(0x9888), 0x0a1bc000 },
- { _MMIO(0x9888), 0x0c1bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x001c0031 },
- { _MMIO(0x9888), 0x061c1900 },
- { _MMIO(0x9888), 0x081c1a33 },
- { _MMIO(0x9888), 0x0a1c1b35 },
- { _MMIO(0x9888), 0x0c1c3337 },
- { _MMIO(0x9888), 0x041c31c7 },
- { _MMIO(0x9888), 0x180f5000 },
- { _MMIO(0x9888), 0x1a0fa8aa },
- { _MMIO(0x9888), 0x1c0f0aaa },
- { _MMIO(0x9888), 0x182c8000 },
- { _MMIO(0x9888), 0x1c2c6aaa },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x1a2c2950 },
- { _MMIO(0x9888), 0x01938000 },
- { _MMIO(0x9888), 0x0f938000 },
- { _MMIO(0x9888), 0x1993aaaa },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25904000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x29904000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900420 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900400 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x45900001 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extended;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fffa },
- { _MMIO(0x2774), 0x0000fefe },
- { _MMIO(0x2778), 0x0007fffa },
- { _MMIO(0x277c), 0x0000fefd },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000fbef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000fbdf },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00101100 },
- { _MMIO(0xe45c), 0x00201200 },
- { _MMIO(0xe55c), 0x00301300 },
- { _MMIO(0xe65c), 0x00401400 },
-};
-
-static const struct i915_oa_reg mux_config_compute_l3_cache[] = {
- { _MMIO(0x9888), 0x166c03b0 },
- { _MMIO(0x9888), 0x1593001e },
- { _MMIO(0x9888), 0x3f900c00 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x002d1000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x082d5000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x0c2e0400 },
- { _MMIO(0x9888), 0x0e2e1500 },
- { _MMIO(0x9888), 0x102e0140 },
- { _MMIO(0x9888), 0x044c4000 },
- { _MMIO(0x9888), 0x0a4c8000 },
- { _MMIO(0x9888), 0x0c4cc000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x004e2000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084ea000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x1a4f4001 },
- { _MMIO(0x9888), 0x1c4f5005 },
- { _MMIO(0x9888), 0x006c0051 },
- { _MMIO(0x9888), 0x066c5000 },
- { _MMIO(0x9888), 0x086c5c5d },
- { _MMIO(0x9888), 0x0e6c5e5f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x146c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x180f1000 },
- { _MMIO(0x9888), 0x1a0fa800 },
- { _MMIO(0x9888), 0x1c0f0a00 },
- { _MMIO(0x9888), 0x182c4000 },
- { _MMIO(0x9888), 0x1c2c4015 },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x03931980 },
- { _MMIO(0x9888), 0x05930032 },
- { _MMIO(0x9888), 0x11930000 },
- { _MMIO(0x9888), 0x01938000 },
- { _MMIO(0x9888), 0x0f938000 },
- { _MMIO(0x9888), 0x1993a00a },
- { _MMIO(0x9888), 0x07930000 },
- { _MMIO(0x9888), 0x09930000 },
- { _MMIO(0x9888), 0x1d900177 },
- { _MMIO(0x9888), 0x1f900178 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x53901000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x55900111 },
- { _MMIO(0x9888), 0x47900001 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x4d900000 },
- { _MMIO(0x9888), 0x45900400 },
-};
-
-static int
-get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_l3_cache;
- lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x104f0232 },
- { _MMIO(0x9888), 0x124f4640 },
- { _MMIO(0x9888), 0x11834400 },
- { _MMIO(0x9888), 0x022d4000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x0e2e0055 },
- { _MMIO(0x9888), 0x064c8000 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x024f6100 },
- { _MMIO(0x9888), 0x044f416b },
- { _MMIO(0x9888), 0x064f004b },
- { _MMIO(0x9888), 0x1a4f0000 },
- { _MMIO(0x9888), 0x1a0f02a8 },
- { _MMIO(0x9888), 0x1a2c5500 },
- { _MMIO(0x9888), 0x0f808000 },
- { _MMIO(0x9888), 0x25810020 },
- { _MMIO(0x9888), 0x0f8305c0 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x1f951000 },
- { _MMIO(0x9888), 0x13920200 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4d900003 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1_0_sku_gte_0x03[] = {
- { _MMIO(0x9888), 0x12643400 },
- { _MMIO(0x9888), 0x12653400 },
- { _MMIO(0x9888), 0x106c6800 },
- { _MMIO(0x9888), 0x126c001e },
- { _MMIO(0x9888), 0x166c0010 },
- { _MMIO(0x9888), 0x0c2d5000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x102e0154 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e0055 },
- { _MMIO(0x9888), 0x104c8000 },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x0c4ea000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x1c4f5500 },
- { _MMIO(0x9888), 0x1a4f1554 },
- { _MMIO(0x9888), 0x0a640024 },
- { _MMIO(0x9888), 0x10640000 },
- { _MMIO(0x9888), 0x04640000 },
- { _MMIO(0x9888), 0x0c650024 },
- { _MMIO(0x9888), 0x10650000 },
- { _MMIO(0x9888), 0x06650000 },
- { _MMIO(0x9888), 0x0c6c5327 },
- { _MMIO(0x9888), 0x0e6c5425 },
- { _MMIO(0x9888), 0x006c2a00 },
- { _MMIO(0x9888), 0x026c285b },
- { _MMIO(0x9888), 0x046c005c },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1a6c0900 },
- { _MMIO(0x9888), 0x1c0f0aa0 },
- { _MMIO(0x9888), 0x180f4000 },
- { _MMIO(0x9888), 0x1a0f02aa },
- { _MMIO(0x9888), 0x1c2c5400 },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x1a2c5550 },
- { _MMIO(0x9888), 0x1993aa00 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900421 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900420 },
- { _MMIO(0x9888), 0x45900021 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1_0_sku_lt_0x03[] = {
- { _MMIO(0x9888), 0x14640340 },
- { _MMIO(0x9888), 0x14650340 },
- { _MMIO(0x9888), 0x106c6800 },
- { _MMIO(0x9888), 0x126c001e },
- { _MMIO(0x9888), 0x166c0010 },
- { _MMIO(0x9888), 0x0c2d5000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x102e0154 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e0055 },
- { _MMIO(0x9888), 0x104c8000 },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x0c4ea000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x1c4f5500 },
- { _MMIO(0x9888), 0x1a4f1554 },
- { _MMIO(0x9888), 0x04642400 },
- { _MMIO(0x9888), 0x22640000 },
- { _MMIO(0x9888), 0x1a640000 },
- { _MMIO(0x9888), 0x06650024 },
- { _MMIO(0x9888), 0x22650000 },
- { _MMIO(0x9888), 0x1c650000 },
- { _MMIO(0x9888), 0x0c6c5327 },
- { _MMIO(0x9888), 0x0e6c5425 },
- { _MMIO(0x9888), 0x006c2a00 },
- { _MMIO(0x9888), 0x026c285b },
- { _MMIO(0x9888), 0x046c005c },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1a6c0900 },
- { _MMIO(0x9888), 0x1c0f0aa0 },
- { _MMIO(0x9888), 0x180f4000 },
- { _MMIO(0x9888), 0x1a0f02aa },
- { _MMIO(0x9888), 0x1c2c5400 },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x1a2c5550 },
- { _MMIO(0x9888), 0x1993aa00 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900421 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900420 },
- { _MMIO(0x9888), 0x45900021 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 2);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 2);
-
- if (dev_priv->drm.pdev->revision >= 0x03) {
- regs[n] = mux_config_l3_1_0_sku_gte_0x03;
- lens[n] = ARRAY_SIZE(mux_config_l3_1_0_sku_gte_0x03);
- n++;
- }
- if (dev_priv->drm.pdev->revision < 0x03) {
- regs[n] = mux_config_l3_1_0_sku_lt_0x03;
- lens[n] = ARRAY_SIZE(mux_config_l3_1_0_sku_lt_0x03);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000efff },
- { _MMIO(0x2778), 0x00006000 },
- { _MMIO(0x277c), 0x0000f3ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x102d7800 },
- { _MMIO(0x9888), 0x122d79e0 },
- { _MMIO(0x9888), 0x0c2f0004 },
- { _MMIO(0x9888), 0x100e3800 },
- { _MMIO(0x9888), 0x180f0005 },
- { _MMIO(0x9888), 0x002d0940 },
- { _MMIO(0x9888), 0x022d802f },
- { _MMIO(0x9888), 0x042d4013 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x0e2e0050 },
- { _MMIO(0x9888), 0x022f0010 },
- { _MMIO(0x9888), 0x002f0000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x040e0480 },
- { _MMIO(0x9888), 0x000e0000 },
- { _MMIO(0x9888), 0x060f0027 },
- { _MMIO(0x9888), 0x100f0000 },
- { _MMIO(0x9888), 0x1a0f0040 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x439014a0 },
- { _MMIO(0x9888), 0x459000a4 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler[] = {
- { _MMIO(0x9888), 0x121300a0 },
- { _MMIO(0x9888), 0x141600ab },
- { _MMIO(0x9888), 0x123300a0 },
- { _MMIO(0x9888), 0x143600ab },
- { _MMIO(0x9888), 0x125300a0 },
- { _MMIO(0x9888), 0x145600ab },
- { _MMIO(0x9888), 0x0c2d4000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x102e01a0 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e0065 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x084c4000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x044e2000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x1c0f0800 },
- { _MMIO(0x9888), 0x180f4000 },
- { _MMIO(0x9888), 0x1a0f023f },
- { _MMIO(0x9888), 0x1e2c0003 },
- { _MMIO(0x9888), 0x1a2cc030 },
- { _MMIO(0x9888), 0x04132180 },
- { _MMIO(0x9888), 0x02130000 },
- { _MMIO(0x9888), 0x0c148000 },
- { _MMIO(0x9888), 0x0e142000 },
- { _MMIO(0x9888), 0x04148000 },
- { _MMIO(0x9888), 0x1e150140 },
- { _MMIO(0x9888), 0x1c150040 },
- { _MMIO(0x9888), 0x0c163000 },
- { _MMIO(0x9888), 0x0e160068 },
- { _MMIO(0x9888), 0x10160000 },
- { _MMIO(0x9888), 0x18160000 },
- { _MMIO(0x9888), 0x0a164000 },
- { _MMIO(0x9888), 0x04330043 },
- { _MMIO(0x9888), 0x02330000 },
- { _MMIO(0x9888), 0x0234a000 },
- { _MMIO(0x9888), 0x04342000 },
- { _MMIO(0x9888), 0x1c350015 },
- { _MMIO(0x9888), 0x02363460 },
- { _MMIO(0x9888), 0x10360000 },
- { _MMIO(0x9888), 0x04360000 },
- { _MMIO(0x9888), 0x06360000 },
- { _MMIO(0x9888), 0x08364000 },
- { _MMIO(0x9888), 0x06530043 },
- { _MMIO(0x9888), 0x02530000 },
- { _MMIO(0x9888), 0x0e548000 },
- { _MMIO(0x9888), 0x00548000 },
- { _MMIO(0x9888), 0x06542000 },
- { _MMIO(0x9888), 0x1e550400 },
- { _MMIO(0x9888), 0x1a552000 },
- { _MMIO(0x9888), 0x1c550100 },
- { _MMIO(0x9888), 0x0e563000 },
- { _MMIO(0x9888), 0x00563400 },
- { _MMIO(0x9888), 0x10560000 },
- { _MMIO(0x9888), 0x18560000 },
- { _MMIO(0x9888), 0x02560000 },
- { _MMIO(0x9888), 0x0c564000 },
- { _MMIO(0x9888), 0x1993a800 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b9014a0 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900820 },
- { _MMIO(0x9888), 0x45901022 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
-};
-
-static int
-get_sampler_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler;
- lens[n] = ARRAY_SIZE(mux_config_sampler);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x00007fff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x00009fff },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000efff },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000f3ff },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fdff },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x141a0000 },
- { _MMIO(0x9888), 0x143a0000 },
- { _MMIO(0x9888), 0x145a0000 },
- { _MMIO(0x9888), 0x0c2d4000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x102e0150 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e006a },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064c4000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024e2000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x1c0f0bc0 },
- { _MMIO(0x9888), 0x180f4000 },
- { _MMIO(0x9888), 0x1a0f0302 },
- { _MMIO(0x9888), 0x1e2c0003 },
- { _MMIO(0x9888), 0x1a2c00f0 },
- { _MMIO(0x9888), 0x021a3080 },
- { _MMIO(0x9888), 0x041a31e5 },
- { _MMIO(0x9888), 0x02148000 },
- { _MMIO(0x9888), 0x0414a000 },
- { _MMIO(0x9888), 0x1c150054 },
- { _MMIO(0x9888), 0x06168000 },
- { _MMIO(0x9888), 0x08168000 },
- { _MMIO(0x9888), 0x0a168000 },
- { _MMIO(0x9888), 0x0c3a3280 },
- { _MMIO(0x9888), 0x0e3a0063 },
- { _MMIO(0x9888), 0x063a0061 },
- { _MMIO(0x9888), 0x023a0000 },
- { _MMIO(0x9888), 0x0c348000 },
- { _MMIO(0x9888), 0x0e342000 },
- { _MMIO(0x9888), 0x06342000 },
- { _MMIO(0x9888), 0x1e350140 },
- { _MMIO(0x9888), 0x1c350100 },
- { _MMIO(0x9888), 0x18360028 },
- { _MMIO(0x9888), 0x0c368000 },
- { _MMIO(0x9888), 0x0e5a3080 },
- { _MMIO(0x9888), 0x005a3280 },
- { _MMIO(0x9888), 0x025a0063 },
- { _MMIO(0x9888), 0x0e548000 },
- { _MMIO(0x9888), 0x00548000 },
- { _MMIO(0x9888), 0x02542000 },
- { _MMIO(0x9888), 0x1e550400 },
- { _MMIO(0x9888), 0x1a552000 },
- { _MMIO(0x9888), 0x1c550001 },
- { _MMIO(0x9888), 0x18560080 },
- { _MMIO(0x9888), 0x02568000 },
- { _MMIO(0x9888), 0x04568000 },
- { _MMIO(0x9888), 0x1993a800 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900420 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x45901084 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900001 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x141a026b },
- { _MMIO(0x9888), 0x143a0173 },
- { _MMIO(0x9888), 0x145a026b },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e0069 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x180f6000 },
- { _MMIO(0x9888), 0x1a0f030a },
- { _MMIO(0x9888), 0x1a2c03c0 },
- { _MMIO(0x9888), 0x041a37e7 },
- { _MMIO(0x9888), 0x021a0000 },
- { _MMIO(0x9888), 0x0414a000 },
- { _MMIO(0x9888), 0x1c150050 },
- { _MMIO(0x9888), 0x08168000 },
- { _MMIO(0x9888), 0x0a168000 },
- { _MMIO(0x9888), 0x003a3380 },
- { _MMIO(0x9888), 0x063a006f },
- { _MMIO(0x9888), 0x023a0000 },
- { _MMIO(0x9888), 0x00348000 },
- { _MMIO(0x9888), 0x06342000 },
- { _MMIO(0x9888), 0x1a352000 },
- { _MMIO(0x9888), 0x1c350100 },
- { _MMIO(0x9888), 0x02368000 },
- { _MMIO(0x9888), 0x0c368000 },
- { _MMIO(0x9888), 0x025a37e7 },
- { _MMIO(0x9888), 0x0254a000 },
- { _MMIO(0x9888), 0x1c550005 },
- { _MMIO(0x9888), 0x04568000 },
- { _MMIO(0x9888), 0x06568000 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900020 },
- { _MMIO(0x9888), 0x45901080 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extra[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extra[] = {
- { _MMIO(0xe458), 0x00001000 },
- { _MMIO(0xe558), 0x00003002 },
- { _MMIO(0xe658), 0x00005004 },
- { _MMIO(0xe758), 0x00011010 },
- { _MMIO(0xe45c), 0x00050012 },
- { _MMIO(0xe55c), 0x00052051 },
- { _MMIO(0xe65c), 0x00000008 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extra[] = {
- { _MMIO(0x9888), 0x141a001f },
- { _MMIO(0x9888), 0x143a001f },
- { _MMIO(0x9888), 0x145a001f },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x0e2e0094 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x1a0f00e0 },
- { _MMIO(0x9888), 0x1a2c0c00 },
- { _MMIO(0x9888), 0x061a0063 },
- { _MMIO(0x9888), 0x021a0000 },
- { _MMIO(0x9888), 0x06142000 },
- { _MMIO(0x9888), 0x1c150100 },
- { _MMIO(0x9888), 0x0c168000 },
- { _MMIO(0x9888), 0x043a3180 },
- { _MMIO(0x9888), 0x023a0000 },
- { _MMIO(0x9888), 0x04348000 },
- { _MMIO(0x9888), 0x1c350040 },
- { _MMIO(0x9888), 0x0a368000 },
- { _MMIO(0x9888), 0x045a0063 },
- { _MMIO(0x9888), 0x025a0000 },
- { _MMIO(0x9888), 0x04542000 },
- { _MMIO(0x9888), 0x1c550010 },
- { _MMIO(0x9888), 0x08568000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900400 },
- { _MMIO(0x9888), 0x47900004 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_compute_extra_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extra;
- lens[n] = ARRAY_SIZE(mux_config_compute_extra);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2744), 0x00800000 },
@@ -1756,6 +60,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x00000080 },
{ _MMIO(0x9888), 0x19800000 },
{ _MMIO(0x9888), 0x07800063 },
{ _MMIO(0x9888), 0x11800000 },
@@ -1769,922 +74,35 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x33900000 },
};
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_bxt(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_L3_CACHE:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_l3_cache_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_l3_cache;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_l3_cache);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_l3_cache;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_l3_cache);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTRA:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extra_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extra;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extra);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extra;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extra);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "22b9519a-e9ba-4c41-8b54-f4f8ca14fa0a",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "012d72cf-82a9-4d25-8ddf-74076fd30797",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "ce416533-e49e-4211-80af-ec513590a914",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "398e2452-18d7-42d0-b241-e4d0a9148ada",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "d324a0d6-7269-4847-a5c2-6f71ddc7fed5",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
-}
-
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "caf3596a-7bb1-4dec-b3b3-2a080d283b49",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE);
-}
-
-static struct device_attribute dev_attr_compute_l3_cache_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_l3_cache_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_l3_cache[] = {
- &dev_attr_compute_l3_cache_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_l3_cache = {
- .name = "49b956e2-d5b9-47e0-9d8a-cee5e8cec527",
- .attrs = attrs_compute_l3_cache,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "f64ef50a-bdba-4b35-8f09-203c13d8ee5a",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "00ad5a41-7eab-4f7a-9103-49d411c67219",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "46dc44ca-491c-4cc1-a951-e7b3e62bf02b",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER);
-}
-
-static struct device_attribute dev_attr_sampler_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler[] = {
- &dev_attr_sampler_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler = {
- .name = "8364e2a8-af63-40af-b0d5-42969a255654",
- .attrs = attrs_sampler,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "175c8092-cb25-4d1e-8dc7-b4fdd39e2d92",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "d260f03f-b34d-4b49-a44e-436819117332",
- .attrs = attrs_tdl_2,
-};
-
-static ssize_t
-show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA);
-}
-
-static struct device_attribute dev_attr_compute_extra_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extra_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extra[] = {
- &dev_attr_compute_extra_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extra = {
- .name = "fa6ecf21-2cb8-4d0b-9308-6e4a7b4ca87a",
- .attrs = attrs_compute_extra,
-};
-
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "5ee72f5c-092f-421e-8b70-225f7c3e9612",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_bxt(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_bxt(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "5ee72f5c-092f-421e-8b70-225f7c3e9612",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (ret)
- goto error_compute_l3_cache;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (ret)
- goto error_sampler;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (ret)
- goto error_compute_extra;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
-error_compute_extra:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
-error_sampler:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
-error_compute_l3_cache:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_bxt(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "5ee72f5c-092f-421e-8b70-225f7c3e9612";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_bxt.h b/drivers/gpu/drm/i915/i915_oa_bxt.h
index 6cf7ba746e7e..690b963a2383 100644
--- a/drivers/gpu/drm/i915/i915_oa_bxt.h
+++ b/drivers/gpu/drm/i915/i915_oa_bxt.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_BXT_H__
#define __I915_OA_BXT_H__
-extern int i915_oa_n_builtin_metric_sets_bxt;
-
-extern int i915_oa_select_metric_set_bxt(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_bxt(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_bxt(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_bxt(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_chv.c b/drivers/gpu/drm/i915/i915_oa_chv.c
index aa6bece7e75f..322a3f94cd16 100644
--- a/drivers/gpu/drm/i915/i915_oa_chv.c
+++ b/drivers/gpu/drm/i915/i915_oa_chv.c
@@ -31,1943 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_chv.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_L3_2,
- METRIC_SET_ID_L3_3,
- METRIC_SET_ID_L3_4,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER_1,
- METRIC_SET_ID_SAMPLER_2,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_chv = 14;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic[] = {
- { _MMIO(0x9888), 0x59800000 },
- { _MMIO(0x9888), 0x59800001 },
- { _MMIO(0x9888), 0x285a0006 },
- { _MMIO(0x9888), 0x2c110014 },
- { _MMIO(0x9888), 0x2e110000 },
- { _MMIO(0x9888), 0x2c310014 },
- { _MMIO(0x9888), 0x2e310000 },
- { _MMIO(0x9888), 0x2b8303df },
- { _MMIO(0x9888), 0x3580024f },
- { _MMIO(0x9888), 0x00580888 },
- { _MMIO(0x9888), 0x1e5a0015 },
- { _MMIO(0x9888), 0x205a0014 },
- { _MMIO(0x9888), 0x045a0000 },
- { _MMIO(0x9888), 0x025a0000 },
- { _MMIO(0x9888), 0x02180500 },
- { _MMIO(0x9888), 0x00190555 },
- { _MMIO(0x9888), 0x021d0500 },
- { _MMIO(0x9888), 0x021f0a00 },
- { _MMIO(0x9888), 0x00380444 },
- { _MMIO(0x9888), 0x02390500 },
- { _MMIO(0x9888), 0x003a0666 },
- { _MMIO(0x9888), 0x00100111 },
- { _MMIO(0x9888), 0x06110030 },
- { _MMIO(0x9888), 0x0a110031 },
- { _MMIO(0x9888), 0x0e110046 },
- { _MMIO(0x9888), 0x04110000 },
- { _MMIO(0x9888), 0x00110000 },
- { _MMIO(0x9888), 0x00130111 },
- { _MMIO(0x9888), 0x00300444 },
- { _MMIO(0x9888), 0x08310030 },
- { _MMIO(0x9888), 0x0c310031 },
- { _MMIO(0x9888), 0x10310046 },
- { _MMIO(0x9888), 0x04310000 },
- { _MMIO(0x9888), 0x00310000 },
- { _MMIO(0x9888), 0x00330444 },
- { _MMIO(0x9888), 0x038a0a00 },
- { _MMIO(0x9888), 0x018b0fff },
- { _MMIO(0x9888), 0x038b0a00 },
- { _MMIO(0x9888), 0x01855000 },
- { _MMIO(0x9888), 0x03850055 },
- { _MMIO(0x9888), 0x13830021 },
- { _MMIO(0x9888), 0x15830020 },
- { _MMIO(0x9888), 0x1783002f },
- { _MMIO(0x9888), 0x1983002e },
- { _MMIO(0x9888), 0x1b83002d },
- { _MMIO(0x9888), 0x1d83002c },
- { _MMIO(0x9888), 0x05830000 },
- { _MMIO(0x9888), 0x01840555 },
- { _MMIO(0x9888), 0x03840500 },
- { _MMIO(0x9888), 0x23800074 },
- { _MMIO(0x9888), 0x2580007d },
- { _MMIO(0x9888), 0x05800000 },
- { _MMIO(0x9888), 0x01805000 },
- { _MMIO(0x9888), 0x03800055 },
- { _MMIO(0x9888), 0x01865000 },
- { _MMIO(0x9888), 0x03860055 },
- { _MMIO(0x9888), 0x01875000 },
- { _MMIO(0x9888), 0x03870055 },
- { _MMIO(0x9888), 0x418000aa },
- { _MMIO(0x9888), 0x4380000a },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x4780000a },
- { _MMIO(0x9888), 0x49800000 },
- { _MMIO(0x9888), 0x4b800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x55800000 },
- { _MMIO(0x9888), 0x57800000 },
- { _MMIO(0x9888), 0x59800000 },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_basic;
- lens[n] = ARRAY_SIZE(mux_config_render_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic[] = {
- { _MMIO(0x9888), 0x59800000 },
- { _MMIO(0x9888), 0x59800001 },
- { _MMIO(0x9888), 0x2e5800e0 },
- { _MMIO(0x9888), 0x2e3800e0 },
- { _MMIO(0x9888), 0x3580024f },
- { _MMIO(0x9888), 0x3d800140 },
- { _MMIO(0x9888), 0x08580042 },
- { _MMIO(0x9888), 0x0c580040 },
- { _MMIO(0x9888), 0x1058004c },
- { _MMIO(0x9888), 0x1458004b },
- { _MMIO(0x9888), 0x04580000 },
- { _MMIO(0x9888), 0x00580000 },
- { _MMIO(0x9888), 0x00195555 },
- { _MMIO(0x9888), 0x06380042 },
- { _MMIO(0x9888), 0x0a380040 },
- { _MMIO(0x9888), 0x0e38004c },
- { _MMIO(0x9888), 0x1238004b },
- { _MMIO(0x9888), 0x04380000 },
- { _MMIO(0x9888), 0x00384444 },
- { _MMIO(0x9888), 0x003a5555 },
- { _MMIO(0x9888), 0x018bffff },
- { _MMIO(0x9888), 0x01845555 },
- { _MMIO(0x9888), 0x17800074 },
- { _MMIO(0x9888), 0x1980007d },
- { _MMIO(0x9888), 0x1b80007c },
- { _MMIO(0x9888), 0x1d8000b6 },
- { _MMIO(0x9888), 0x1f8000b7 },
- { _MMIO(0x9888), 0x05800000 },
- { _MMIO(0x9888), 0x03800000 },
- { _MMIO(0x9888), 0x418000aa },
- { _MMIO(0x9888), 0x438000aa },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x47800000 },
- { _MMIO(0x9888), 0x4980012a },
- { _MMIO(0x9888), 0x4b80012a },
- { _MMIO(0x9888), 0x4d80012a },
- { _MMIO(0x9888), 0x4f80012a },
- { _MMIO(0x9888), 0x518001ce },
- { _MMIO(0x9888), 0x538001ce },
- { _MMIO(0x9888), 0x5580000e },
- { _MMIO(0x9888), 0x59800000 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_basic;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile[] = {
- { _MMIO(0x9888), 0x59800000 },
- { _MMIO(0x9888), 0x59800001 },
- { _MMIO(0x9888), 0x261e0000 },
- { _MMIO(0x9888), 0x281f000f },
- { _MMIO(0x9888), 0x2817001a },
- { _MMIO(0x9888), 0x2791001f },
- { _MMIO(0x9888), 0x27880019 },
- { _MMIO(0x9888), 0x2d890000 },
- { _MMIO(0x9888), 0x278a0007 },
- { _MMIO(0x9888), 0x298d001f },
- { _MMIO(0x9888), 0x278e0020 },
- { _MMIO(0x9888), 0x2b8f0012 },
- { _MMIO(0x9888), 0x29900000 },
- { _MMIO(0x9888), 0x00184000 },
- { _MMIO(0x9888), 0x02181000 },
- { _MMIO(0x9888), 0x02194000 },
- { _MMIO(0x9888), 0x141e0002 },
- { _MMIO(0x9888), 0x041e0000 },
- { _MMIO(0x9888), 0x001e0000 },
- { _MMIO(0x9888), 0x221f0015 },
- { _MMIO(0x9888), 0x041f0000 },
- { _MMIO(0x9888), 0x001f4000 },
- { _MMIO(0x9888), 0x021f0000 },
- { _MMIO(0x9888), 0x023a8000 },
- { _MMIO(0x9888), 0x0213c000 },
- { _MMIO(0x9888), 0x02164000 },
- { _MMIO(0x9888), 0x24170012 },
- { _MMIO(0x9888), 0x04170000 },
- { _MMIO(0x9888), 0x07910005 },
- { _MMIO(0x9888), 0x05910000 },
- { _MMIO(0x9888), 0x01911500 },
- { _MMIO(0x9888), 0x03910501 },
- { _MMIO(0x9888), 0x0d880002 },
- { _MMIO(0x9888), 0x1d880003 },
- { _MMIO(0x9888), 0x05880000 },
- { _MMIO(0x9888), 0x0b890032 },
- { _MMIO(0x9888), 0x1b890031 },
- { _MMIO(0x9888), 0x05890000 },
- { _MMIO(0x9888), 0x01890040 },
- { _MMIO(0x9888), 0x03890040 },
- { _MMIO(0x9888), 0x098a0000 },
- { _MMIO(0x9888), 0x198a0004 },
- { _MMIO(0x9888), 0x058a0000 },
- { _MMIO(0x9888), 0x018a8050 },
- { _MMIO(0x9888), 0x038a2050 },
- { _MMIO(0x9888), 0x018b95a9 },
- { _MMIO(0x9888), 0x038be5a9 },
- { _MMIO(0x9888), 0x018c1500 },
- { _MMIO(0x9888), 0x038c0501 },
- { _MMIO(0x9888), 0x178d0015 },
- { _MMIO(0x9888), 0x058d0000 },
- { _MMIO(0x9888), 0x138e0004 },
- { _MMIO(0x9888), 0x218e000c },
- { _MMIO(0x9888), 0x058e0000 },
- { _MMIO(0x9888), 0x018e0500 },
- { _MMIO(0x9888), 0x038e0101 },
- { _MMIO(0x9888), 0x0f8f0027 },
- { _MMIO(0x9888), 0x058f0000 },
- { _MMIO(0x9888), 0x018f0000 },
- { _MMIO(0x9888), 0x038f0001 },
- { _MMIO(0x9888), 0x11900013 },
- { _MMIO(0x9888), 0x1f900017 },
- { _MMIO(0x9888), 0x05900000 },
- { _MMIO(0x9888), 0x01900100 },
- { _MMIO(0x9888), 0x03900001 },
- { _MMIO(0x9888), 0x01845555 },
- { _MMIO(0x9888), 0x03845555 },
- { _MMIO(0x9888), 0x418000aa },
- { _MMIO(0x9888), 0x438000aa },
- { _MMIO(0x9888), 0x458000aa },
- { _MMIO(0x9888), 0x478000aa },
- { _MMIO(0x9888), 0x4980018c },
- { _MMIO(0x9888), 0x4b80014b },
- { _MMIO(0x9888), 0x4d800128 },
- { _MMIO(0x9888), 0x4f80012a },
- { _MMIO(0x9888), 0x51800187 },
- { _MMIO(0x9888), 0x5380014b },
- { _MMIO(0x9888), 0x55800149 },
- { _MMIO(0x9888), 0x5780010a },
- { _MMIO(0x9888), 0x59800000 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_pipe_profile;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fff7 },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x105c0232 },
- { _MMIO(0x9888), 0x10580232 },
- { _MMIO(0x9888), 0x10380232 },
- { _MMIO(0x9888), 0x10dc0232 },
- { _MMIO(0x9888), 0x10d80232 },
- { _MMIO(0x9888), 0x10b80232 },
- { _MMIO(0x9888), 0x118e4400 },
- { _MMIO(0x9888), 0x025c6080 },
- { _MMIO(0x9888), 0x045c004b },
- { _MMIO(0x9888), 0x005c8000 },
- { _MMIO(0x9888), 0x00582080 },
- { _MMIO(0x9888), 0x0258004b },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x045b4000 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f00aa },
- { _MMIO(0x9888), 0x04386080 },
- { _MMIO(0x9888), 0x0638404b },
- { _MMIO(0x9888), 0x02384000 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a380000 },
- { _MMIO(0x9888), 0x0c380000 },
- { _MMIO(0x9888), 0x00398000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x0cdc25c1 },
- { _MMIO(0x9888), 0x0adcc000 },
- { _MMIO(0x9888), 0x0ad825c1 },
- { _MMIO(0x9888), 0x18db4000 },
- { _MMIO(0x9888), 0x1adb0001 },
- { _MMIO(0x9888), 0x0e9f8000 },
- { _MMIO(0x9888), 0x109f02aa },
- { _MMIO(0x9888), 0x0eb825c1 },
- { _MMIO(0x9888), 0x18b80154 },
- { _MMIO(0x9888), 0x0ab9a000 },
- { _MMIO(0x9888), 0x0cb9a000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x0d88c000 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x258baa05 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x198c5400 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x098dc000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x098e05c0 },
- { _MMIO(0x9888), 0x058e0000 },
- { _MMIO(0x9888), 0x198f0020 },
- { _MMIO(0x9888), 0x2185aa0a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x19835000 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x09848000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x19808000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x51800040 },
- { _MMIO(0x9888), 0x43800400 },
- { _MMIO(0x9888), 0x45800800 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800c62 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f801042 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x418014a4 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1[] = {
- { _MMIO(0x9888), 0x10bf03da },
- { _MMIO(0x9888), 0x14bf0001 },
- { _MMIO(0x9888), 0x12980340 },
- { _MMIO(0x9888), 0x12990340 },
- { _MMIO(0x9888), 0x0cbf1187 },
- { _MMIO(0x9888), 0x0ebf1205 },
- { _MMIO(0x9888), 0x00bf0500 },
- { _MMIO(0x9888), 0x02bf042b },
- { _MMIO(0x9888), 0x04bf002c },
- { _MMIO(0x9888), 0x0cdac000 },
- { _MMIO(0x9888), 0x0edac000 },
- { _MMIO(0x9888), 0x00da8000 },
- { _MMIO(0x9888), 0x02dac000 },
- { _MMIO(0x9888), 0x04da4000 },
- { _MMIO(0x9888), 0x04983400 },
- { _MMIO(0x9888), 0x10980000 },
- { _MMIO(0x9888), 0x06990034 },
- { _MMIO(0x9888), 0x10990000 },
- { _MMIO(0x9888), 0x0c9dc000 },
- { _MMIO(0x9888), 0x0e9dc000 },
- { _MMIO(0x9888), 0x009d8000 },
- { _MMIO(0x9888), 0x029dc000 },
- { _MMIO(0x9888), 0x049d4000 },
- { _MMIO(0x9888), 0x109f02a8 },
- { _MMIO(0x9888), 0x0c9fa000 },
- { _MMIO(0x9888), 0x0e9f00ba },
- { _MMIO(0x9888), 0x0cb88000 },
- { _MMIO(0x9888), 0x0cb95000 },
- { _MMIO(0x9888), 0x0eb95000 },
- { _MMIO(0x9888), 0x00b94000 },
- { _MMIO(0x9888), 0x02b95000 },
- { _MMIO(0x9888), 0x04b91000 },
- { _MMIO(0x9888), 0x06b92000 },
- { _MMIO(0x9888), 0x0cba4000 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x258b800a },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b5500 },
- { _MMIO(0x9888), 0x198c4000 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x018d8000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2185800a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x1b830154 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x47800000 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800060 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_1;
- lens[n] = ARRAY_SIZE(mux_config_l3_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_2[] = {
- { _MMIO(0x9888), 0x103f03da },
- { _MMIO(0x9888), 0x143f0001 },
- { _MMIO(0x9888), 0x12180340 },
- { _MMIO(0x9888), 0x12190340 },
- { _MMIO(0x9888), 0x0c3f1187 },
- { _MMIO(0x9888), 0x0e3f1205 },
- { _MMIO(0x9888), 0x003f0500 },
- { _MMIO(0x9888), 0x023f042b },
- { _MMIO(0x9888), 0x043f002c },
- { _MMIO(0x9888), 0x0c5ac000 },
- { _MMIO(0x9888), 0x0e5ac000 },
- { _MMIO(0x9888), 0x005a8000 },
- { _MMIO(0x9888), 0x025ac000 },
- { _MMIO(0x9888), 0x045a4000 },
- { _MMIO(0x9888), 0x04183400 },
- { _MMIO(0x9888), 0x10180000 },
- { _MMIO(0x9888), 0x06190034 },
- { _MMIO(0x9888), 0x10190000 },
- { _MMIO(0x9888), 0x0c1dc000 },
- { _MMIO(0x9888), 0x0e1dc000 },
- { _MMIO(0x9888), 0x001d8000 },
- { _MMIO(0x9888), 0x021dc000 },
- { _MMIO(0x9888), 0x041d4000 },
- { _MMIO(0x9888), 0x101f02a8 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f00ba },
- { _MMIO(0x9888), 0x0c388000 },
- { _MMIO(0x9888), 0x0c395000 },
- { _MMIO(0x9888), 0x0e395000 },
- { _MMIO(0x9888), 0x00394000 },
- { _MMIO(0x9888), 0x02395000 },
- { _MMIO(0x9888), 0x04391000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x0c3a4000 },
- { _MMIO(0x9888), 0x1b8aa800 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x258b4005 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x2185800a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x1b830154 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x45800000 },
- { _MMIO(0x9888), 0x47800000 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800060 },
-};
-
-static int
-get_l3_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_2;
- lens[n] = ARRAY_SIZE(mux_config_l3_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_3[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_3[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_3[] = {
- { _MMIO(0x9888), 0x121b0340 },
- { _MMIO(0x9888), 0x103f0274 },
- { _MMIO(0x9888), 0x123f0000 },
- { _MMIO(0x9888), 0x129b0340 },
- { _MMIO(0x9888), 0x10bf0274 },
- { _MMIO(0x9888), 0x12bf0000 },
- { _MMIO(0x9888), 0x041b3400 },
- { _MMIO(0x9888), 0x101b0000 },
- { _MMIO(0x9888), 0x045c8000 },
- { _MMIO(0x9888), 0x0a3d4000 },
- { _MMIO(0x9888), 0x003f0080 },
- { _MMIO(0x9888), 0x023f0793 },
- { _MMIO(0x9888), 0x043f0014 },
- { _MMIO(0x9888), 0x04588000 },
- { _MMIO(0x9888), 0x005a8000 },
- { _MMIO(0x9888), 0x025ac000 },
- { _MMIO(0x9888), 0x045a4000 },
- { _MMIO(0x9888), 0x0a5b4000 },
- { _MMIO(0x9888), 0x001d8000 },
- { _MMIO(0x9888), 0x021dc000 },
- { _MMIO(0x9888), 0x041d4000 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f002a },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x00394000 },
- { _MMIO(0x9888), 0x02395000 },
- { _MMIO(0x9888), 0x04399000 },
- { _MMIO(0x9888), 0x069b0034 },
- { _MMIO(0x9888), 0x109b0000 },
- { _MMIO(0x9888), 0x06dc4000 },
- { _MMIO(0x9888), 0x0cbd4000 },
- { _MMIO(0x9888), 0x0cbf0981 },
- { _MMIO(0x9888), 0x0ebf0a0f },
- { _MMIO(0x9888), 0x06d84000 },
- { _MMIO(0x9888), 0x0cdac000 },
- { _MMIO(0x9888), 0x0edac000 },
- { _MMIO(0x9888), 0x0cdb4000 },
- { _MMIO(0x9888), 0x0c9dc000 },
- { _MMIO(0x9888), 0x0e9dc000 },
- { _MMIO(0x9888), 0x109f02a8 },
- { _MMIO(0x9888), 0x0e9f0080 },
- { _MMIO(0x9888), 0x0cb84000 },
- { _MMIO(0x9888), 0x0cb95000 },
- { _MMIO(0x9888), 0x0eb95000 },
- { _MMIO(0x9888), 0x06b92000 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x258b8009 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x198c4000 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2185800a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x1b830154 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x45800c00 },
- { _MMIO(0x9888), 0x47800c63 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f8014a5 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800045 },
-};
-
-static int
-get_l3_3_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_3;
- lens[n] = ARRAY_SIZE(mux_config_l3_3);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_4[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_4[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_4[] = {
- { _MMIO(0x9888), 0x121a0340 },
- { _MMIO(0x9888), 0x103f0017 },
- { _MMIO(0x9888), 0x123f0020 },
- { _MMIO(0x9888), 0x129a0340 },
- { _MMIO(0x9888), 0x10bf0017 },
- { _MMIO(0x9888), 0x12bf0020 },
- { _MMIO(0x9888), 0x041a3400 },
- { _MMIO(0x9888), 0x101a0000 },
- { _MMIO(0x9888), 0x043b8000 },
- { _MMIO(0x9888), 0x0a3e0010 },
- { _MMIO(0x9888), 0x003f0200 },
- { _MMIO(0x9888), 0x023f0113 },
- { _MMIO(0x9888), 0x043f0014 },
- { _MMIO(0x9888), 0x02592000 },
- { _MMIO(0x9888), 0x005a8000 },
- { _MMIO(0x9888), 0x025ac000 },
- { _MMIO(0x9888), 0x045a4000 },
- { _MMIO(0x9888), 0x0a1c8000 },
- { _MMIO(0x9888), 0x001d8000 },
- { _MMIO(0x9888), 0x021dc000 },
- { _MMIO(0x9888), 0x041d4000 },
- { _MMIO(0x9888), 0x0a1e8000 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f001a },
- { _MMIO(0x9888), 0x00394000 },
- { _MMIO(0x9888), 0x02395000 },
- { _MMIO(0x9888), 0x04391000 },
- { _MMIO(0x9888), 0x069a0034 },
- { _MMIO(0x9888), 0x109a0000 },
- { _MMIO(0x9888), 0x06bb4000 },
- { _MMIO(0x9888), 0x0abe0040 },
- { _MMIO(0x9888), 0x0cbf0984 },
- { _MMIO(0x9888), 0x0ebf0a02 },
- { _MMIO(0x9888), 0x02d94000 },
- { _MMIO(0x9888), 0x0cdac000 },
- { _MMIO(0x9888), 0x0edac000 },
- { _MMIO(0x9888), 0x0c9c0400 },
- { _MMIO(0x9888), 0x0c9dc000 },
- { _MMIO(0x9888), 0x0e9dc000 },
- { _MMIO(0x9888), 0x0c9e0400 },
- { _MMIO(0x9888), 0x109f02a8 },
- { _MMIO(0x9888), 0x0e9f0040 },
- { _MMIO(0x9888), 0x0cb95000 },
- { _MMIO(0x9888), 0x0eb95000 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x258b8009 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x198c4000 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2185800a },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x1b830154 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x45800800 },
- { _MMIO(0x9888), 0x47800842 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f801084 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800044 },
-};
-
-static int
-get_l3_4_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_4;
- lens[n] = ARRAY_SIZE(mux_config_l3_4);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00006000 },
- { _MMIO(0x2774), 0x0000f3ff },
- { _MMIO(0x2778), 0x00001800 },
- { _MMIO(0x277c), 0x0000fcff },
- { _MMIO(0x2780), 0x00000600 },
- { _MMIO(0x2784), 0x0000ff3f },
- { _MMIO(0x2788), 0x00000180 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000060 },
- { _MMIO(0x2794), 0x0000fff3 },
- { _MMIO(0x2798), 0x00000018 },
- { _MMIO(0x279c), 0x0000fffc },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x143b000e },
- { _MMIO(0x9888), 0x043c55c0 },
- { _MMIO(0x9888), 0x0a1e0280 },
- { _MMIO(0x9888), 0x0c1e0408 },
- { _MMIO(0x9888), 0x10390000 },
- { _MMIO(0x9888), 0x12397a1f },
- { _MMIO(0x9888), 0x14bb000e },
- { _MMIO(0x9888), 0x04bc5000 },
- { _MMIO(0x9888), 0x0a9e0296 },
- { _MMIO(0x9888), 0x0c9e0008 },
- { _MMIO(0x9888), 0x10b90000 },
- { _MMIO(0x9888), 0x12b97a1f },
- { _MMIO(0x9888), 0x063b0042 },
- { _MMIO(0x9888), 0x103b0000 },
- { _MMIO(0x9888), 0x083c0000 },
- { _MMIO(0x9888), 0x0a3e0040 },
- { _MMIO(0x9888), 0x043f8000 },
- { _MMIO(0x9888), 0x02594000 },
- { _MMIO(0x9888), 0x045a8000 },
- { _MMIO(0x9888), 0x0c1c0400 },
- { _MMIO(0x9888), 0x041d8000 },
- { _MMIO(0x9888), 0x081e02c0 },
- { _MMIO(0x9888), 0x0e1e0000 },
- { _MMIO(0x9888), 0x0c1fa800 },
- { _MMIO(0x9888), 0x0e1f0260 },
- { _MMIO(0x9888), 0x101f0014 },
- { _MMIO(0x9888), 0x003905e0 },
- { _MMIO(0x9888), 0x06390bc0 },
- { _MMIO(0x9888), 0x02390018 },
- { _MMIO(0x9888), 0x04394000 },
- { _MMIO(0x9888), 0x04bb0042 },
- { _MMIO(0x9888), 0x10bb0000 },
- { _MMIO(0x9888), 0x02bc05c0 },
- { _MMIO(0x9888), 0x08bc0000 },
- { _MMIO(0x9888), 0x0abe0004 },
- { _MMIO(0x9888), 0x02bf8000 },
- { _MMIO(0x9888), 0x02d91000 },
- { _MMIO(0x9888), 0x02da8000 },
- { _MMIO(0x9888), 0x089c8000 },
- { _MMIO(0x9888), 0x029d8000 },
- { _MMIO(0x9888), 0x089e8000 },
- { _MMIO(0x9888), 0x0e9e0000 },
- { _MMIO(0x9888), 0x0e9fa806 },
- { _MMIO(0x9888), 0x109f0142 },
- { _MMIO(0x9888), 0x08b90617 },
- { _MMIO(0x9888), 0x0ab90be0 },
- { _MMIO(0x9888), 0x02b94000 },
- { _MMIO(0x9888), 0x0d88f000 },
- { _MMIO(0x9888), 0x0f88000c },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x018a8000 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x1b8a2800 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x238b52a0 },
- { _MMIO(0x9888), 0x258b6a95 },
- { _MMIO(0x9888), 0x278b0029 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c1500 },
- { _MMIO(0x9888), 0x1b8c0014 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x038d8000 },
- { _MMIO(0x9888), 0x058d2000 },
- { _MMIO(0x9888), 0x1f85aa80 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x01834000 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0184c000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1180c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x4d800444 },
- { _MMIO(0x9888), 0x3d800000 },
- { _MMIO(0x9888), 0x4f804000 },
- { _MMIO(0x9888), 0x43801080 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800084 },
- { _MMIO(0x9888), 0x53800044 },
- { _MMIO(0x9888), 0x47801080 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x3f800000 },
- { _MMIO(0x9888), 0x41800840 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler_1[] = {
- { _MMIO(0x9888), 0x18921400 },
- { _MMIO(0x9888), 0x149500ab },
- { _MMIO(0x9888), 0x18b21400 },
- { _MMIO(0x9888), 0x14b500ab },
- { _MMIO(0x9888), 0x18d21400 },
- { _MMIO(0x9888), 0x14d500ab },
- { _MMIO(0x9888), 0x0cdc8000 },
- { _MMIO(0x9888), 0x0edc4000 },
- { _MMIO(0x9888), 0x02dcc000 },
- { _MMIO(0x9888), 0x04dcc000 },
- { _MMIO(0x9888), 0x1abd00a0 },
- { _MMIO(0x9888), 0x0abd8000 },
- { _MMIO(0x9888), 0x0cd88000 },
- { _MMIO(0x9888), 0x0ed84000 },
- { _MMIO(0x9888), 0x04d88000 },
- { _MMIO(0x9888), 0x1adb0050 },
- { _MMIO(0x9888), 0x04db8000 },
- { _MMIO(0x9888), 0x06db8000 },
- { _MMIO(0x9888), 0x08db8000 },
- { _MMIO(0x9888), 0x0adb4000 },
- { _MMIO(0x9888), 0x109f02a0 },
- { _MMIO(0x9888), 0x0c9fa000 },
- { _MMIO(0x9888), 0x0e9f00aa },
- { _MMIO(0x9888), 0x18b82500 },
- { _MMIO(0x9888), 0x02b88000 },
- { _MMIO(0x9888), 0x04b84000 },
- { _MMIO(0x9888), 0x06b84000 },
- { _MMIO(0x9888), 0x08b84000 },
- { _MMIO(0x9888), 0x0ab84000 },
- { _MMIO(0x9888), 0x0cb88000 },
- { _MMIO(0x9888), 0x0cb98000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x00b98000 },
- { _MMIO(0x9888), 0x02b9a000 },
- { _MMIO(0x9888), 0x04b9a000 },
- { _MMIO(0x9888), 0x06b92000 },
- { _MMIO(0x9888), 0x1aba0200 },
- { _MMIO(0x9888), 0x02ba8000 },
- { _MMIO(0x9888), 0x0cba8000 },
- { _MMIO(0x9888), 0x04908000 },
- { _MMIO(0x9888), 0x04918000 },
- { _MMIO(0x9888), 0x04927300 },
- { _MMIO(0x9888), 0x10920000 },
- { _MMIO(0x9888), 0x1893000a },
- { _MMIO(0x9888), 0x0a934000 },
- { _MMIO(0x9888), 0x0a946000 },
- { _MMIO(0x9888), 0x0c959000 },
- { _MMIO(0x9888), 0x0e950098 },
- { _MMIO(0x9888), 0x10950000 },
- { _MMIO(0x9888), 0x04b04000 },
- { _MMIO(0x9888), 0x04b14000 },
- { _MMIO(0x9888), 0x04b20073 },
- { _MMIO(0x9888), 0x10b20000 },
- { _MMIO(0x9888), 0x04b38000 },
- { _MMIO(0x9888), 0x06b38000 },
- { _MMIO(0x9888), 0x08b34000 },
- { _MMIO(0x9888), 0x04b4c000 },
- { _MMIO(0x9888), 0x02b59890 },
- { _MMIO(0x9888), 0x10b50000 },
- { _MMIO(0x9888), 0x06d04000 },
- { _MMIO(0x9888), 0x06d14000 },
- { _MMIO(0x9888), 0x06d20073 },
- { _MMIO(0x9888), 0x10d20000 },
- { _MMIO(0x9888), 0x18d30020 },
- { _MMIO(0x9888), 0x02d38000 },
- { _MMIO(0x9888), 0x0cd34000 },
- { _MMIO(0x9888), 0x0ad48000 },
- { _MMIO(0x9888), 0x04d42000 },
- { _MMIO(0x9888), 0x0ed59000 },
- { _MMIO(0x9888), 0x00d59800 },
- { _MMIO(0x9888), 0x10d50000 },
- { _MMIO(0x9888), 0x0f88000e },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b5500 },
- { _MMIO(0x9888), 0x258b000a },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x0d8d8000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x018d8000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x2185000a },
- { _MMIO(0x9888), 0x1b830150 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d848000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d808000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47801021 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800c64 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800c02 },
-};
-
-static int
-get_sampler_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler_1;
- lens[n] = ARRAY_SIZE(mux_config_sampler_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler_2[] = {
- { _MMIO(0x9888), 0x18121400 },
- { _MMIO(0x9888), 0x141500ab },
- { _MMIO(0x9888), 0x18321400 },
- { _MMIO(0x9888), 0x143500ab },
- { _MMIO(0x9888), 0x18521400 },
- { _MMIO(0x9888), 0x145500ab },
- { _MMIO(0x9888), 0x0c5c8000 },
- { _MMIO(0x9888), 0x0e5c4000 },
- { _MMIO(0x9888), 0x025cc000 },
- { _MMIO(0x9888), 0x045cc000 },
- { _MMIO(0x9888), 0x1a3d00a0 },
- { _MMIO(0x9888), 0x0a3d8000 },
- { _MMIO(0x9888), 0x0c588000 },
- { _MMIO(0x9888), 0x0e584000 },
- { _MMIO(0x9888), 0x04588000 },
- { _MMIO(0x9888), 0x1a5b0050 },
- { _MMIO(0x9888), 0x045b8000 },
- { _MMIO(0x9888), 0x065b8000 },
- { _MMIO(0x9888), 0x085b8000 },
- { _MMIO(0x9888), 0x0a5b4000 },
- { _MMIO(0x9888), 0x101f02a0 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f00aa },
- { _MMIO(0x9888), 0x18382500 },
- { _MMIO(0x9888), 0x02388000 },
- { _MMIO(0x9888), 0x04384000 },
- { _MMIO(0x9888), 0x06384000 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0c388000 },
- { _MMIO(0x9888), 0x0c398000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x00398000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x1a3a0200 },
- { _MMIO(0x9888), 0x023a8000 },
- { _MMIO(0x9888), 0x0c3a8000 },
- { _MMIO(0x9888), 0x04108000 },
- { _MMIO(0x9888), 0x04118000 },
- { _MMIO(0x9888), 0x04127300 },
- { _MMIO(0x9888), 0x10120000 },
- { _MMIO(0x9888), 0x1813000a },
- { _MMIO(0x9888), 0x0a134000 },
- { _MMIO(0x9888), 0x0a146000 },
- { _MMIO(0x9888), 0x0c159000 },
- { _MMIO(0x9888), 0x0e150098 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x04304000 },
- { _MMIO(0x9888), 0x04314000 },
- { _MMIO(0x9888), 0x04320073 },
- { _MMIO(0x9888), 0x10320000 },
- { _MMIO(0x9888), 0x04338000 },
- { _MMIO(0x9888), 0x06338000 },
- { _MMIO(0x9888), 0x08334000 },
- { _MMIO(0x9888), 0x0434c000 },
- { _MMIO(0x9888), 0x02359890 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x06504000 },
- { _MMIO(0x9888), 0x06514000 },
- { _MMIO(0x9888), 0x06520073 },
- { _MMIO(0x9888), 0x10520000 },
- { _MMIO(0x9888), 0x18530020 },
- { _MMIO(0x9888), 0x02538000 },
- { _MMIO(0x9888), 0x0c534000 },
- { _MMIO(0x9888), 0x0a548000 },
- { _MMIO(0x9888), 0x04542000 },
- { _MMIO(0x9888), 0x0e559000 },
- { _MMIO(0x9888), 0x00559800 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x1b8aa000 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x258b0005 },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x2185000a },
- { _MMIO(0x9888), 0x1b830150 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0d848000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x07844000 },
- { _MMIO(0x9888), 0x1d808000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x17804000 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47801021 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800c64 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x41800c02 },
-};
-
-static int
-get_sampler_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler_2;
- lens[n] = ARRAY_SIZE(mux_config_sampler_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x0000fe7f },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000ffbf },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fff7 },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fff9 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x16154d60 },
- { _MMIO(0x9888), 0x16352e60 },
- { _MMIO(0x9888), 0x16554d60 },
- { _MMIO(0x9888), 0x16950000 },
- { _MMIO(0x9888), 0x16b50000 },
- { _MMIO(0x9888), 0x16d50000 },
- { _MMIO(0x9888), 0x005c8000 },
- { _MMIO(0x9888), 0x045cc000 },
- { _MMIO(0x9888), 0x065c4000 },
- { _MMIO(0x9888), 0x083d8000 },
- { _MMIO(0x9888), 0x0a3d8000 },
- { _MMIO(0x9888), 0x0458c000 },
- { _MMIO(0x9888), 0x025b8000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5b4000 },
- { _MMIO(0x9888), 0x0c5b8000 },
- { _MMIO(0x9888), 0x0c1fa000 },
- { _MMIO(0x9888), 0x0e1f00aa },
- { _MMIO(0x9888), 0x02384000 },
- { _MMIO(0x9888), 0x04388000 },
- { _MMIO(0x9888), 0x06388000 },
- { _MMIO(0x9888), 0x08384000 },
- { _MMIO(0x9888), 0x0a384000 },
- { _MMIO(0x9888), 0x0c384000 },
- { _MMIO(0x9888), 0x00398000 },
- { _MMIO(0x9888), 0x0239a000 },
- { _MMIO(0x9888), 0x0439a000 },
- { _MMIO(0x9888), 0x06392000 },
- { _MMIO(0x9888), 0x043a8000 },
- { _MMIO(0x9888), 0x063a8000 },
- { _MMIO(0x9888), 0x08138000 },
- { _MMIO(0x9888), 0x0a138000 },
- { _MMIO(0x9888), 0x06143000 },
- { _MMIO(0x9888), 0x0415cfc7 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x02338000 },
- { _MMIO(0x9888), 0x0c338000 },
- { _MMIO(0x9888), 0x04342000 },
- { _MMIO(0x9888), 0x06344000 },
- { _MMIO(0x9888), 0x0035c700 },
- { _MMIO(0x9888), 0x063500cf },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x04538000 },
- { _MMIO(0x9888), 0x06538000 },
- { _MMIO(0x9888), 0x0454c000 },
- { _MMIO(0x9888), 0x0255cfc7 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x06dc8000 },
- { _MMIO(0x9888), 0x08dc4000 },
- { _MMIO(0x9888), 0x0cdcc000 },
- { _MMIO(0x9888), 0x0edcc000 },
- { _MMIO(0x9888), 0x1abd00a8 },
- { _MMIO(0x9888), 0x0cd8c000 },
- { _MMIO(0x9888), 0x0ed84000 },
- { _MMIO(0x9888), 0x0edb8000 },
- { _MMIO(0x9888), 0x18db0800 },
- { _MMIO(0x9888), 0x1adb0254 },
- { _MMIO(0x9888), 0x0e9faa00 },
- { _MMIO(0x9888), 0x109f02aa },
- { _MMIO(0x9888), 0x0eb84000 },
- { _MMIO(0x9888), 0x16b84000 },
- { _MMIO(0x9888), 0x18b8156a },
- { _MMIO(0x9888), 0x06b98000 },
- { _MMIO(0x9888), 0x08b9a000 },
- { _MMIO(0x9888), 0x0ab9a000 },
- { _MMIO(0x9888), 0x0cb9a000 },
- { _MMIO(0x9888), 0x0eb9a000 },
- { _MMIO(0x9888), 0x18baa000 },
- { _MMIO(0x9888), 0x1aba0002 },
- { _MMIO(0x9888), 0x16934000 },
- { _MMIO(0x9888), 0x1893000a },
- { _MMIO(0x9888), 0x0a947000 },
- { _MMIO(0x9888), 0x0c95c5c1 },
- { _MMIO(0x9888), 0x0e9500c3 },
- { _MMIO(0x9888), 0x10950000 },
- { _MMIO(0x9888), 0x0eb38000 },
- { _MMIO(0x9888), 0x16b30040 },
- { _MMIO(0x9888), 0x18b30020 },
- { _MMIO(0x9888), 0x06b48000 },
- { _MMIO(0x9888), 0x08b41000 },
- { _MMIO(0x9888), 0x0ab48000 },
- { _MMIO(0x9888), 0x06b5c500 },
- { _MMIO(0x9888), 0x08b500c3 },
- { _MMIO(0x9888), 0x0eb5c100 },
- { _MMIO(0x9888), 0x10b50000 },
- { _MMIO(0x9888), 0x16d31500 },
- { _MMIO(0x9888), 0x08d4e000 },
- { _MMIO(0x9888), 0x08d5c100 },
- { _MMIO(0x9888), 0x0ad5c3c5 },
- { _MMIO(0x9888), 0x10d50000 },
- { _MMIO(0x9888), 0x0d88f800 },
- { _MMIO(0x9888), 0x0f88000f },
- { _MMIO(0x9888), 0x038a8000 },
- { _MMIO(0x9888), 0x058a8000 },
- { _MMIO(0x9888), 0x078a8000 },
- { _MMIO(0x9888), 0x098a8000 },
- { _MMIO(0x9888), 0x0b8a8000 },
- { _MMIO(0x9888), 0x0d8a8000 },
- { _MMIO(0x9888), 0x258baaa5 },
- { _MMIO(0x9888), 0x278b002a },
- { _MMIO(0x9888), 0x238b2a80 },
- { _MMIO(0x9888), 0x0f8c4000 },
- { _MMIO(0x9888), 0x178c2000 },
- { _MMIO(0x9888), 0x198c5500 },
- { _MMIO(0x9888), 0x1b8c0015 },
- { _MMIO(0x9888), 0x078d8000 },
- { _MMIO(0x9888), 0x098da000 },
- { _MMIO(0x9888), 0x0b8da000 },
- { _MMIO(0x9888), 0x0d8da000 },
- { _MMIO(0x9888), 0x0f8da000 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800c42 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45800063 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x47800800 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f8014a4 },
- { _MMIO(0x9888), 0x41801042 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x0000fe7f },
- { _MMIO(0x2780), 0x00000000 },
- { _MMIO(0x2784), 0x0000ff9f },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000ffe7 },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fffb },
- { _MMIO(0x2798), 0x00000002 },
- { _MMIO(0x279c), 0x0000fffd },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x16150000 },
- { _MMIO(0x9888), 0x16350000 },
- { _MMIO(0x9888), 0x16550000 },
- { _MMIO(0x9888), 0x16952e60 },
- { _MMIO(0x9888), 0x16b54d60 },
- { _MMIO(0x9888), 0x16d52e60 },
- { _MMIO(0x9888), 0x065c8000 },
- { _MMIO(0x9888), 0x085cc000 },
- { _MMIO(0x9888), 0x0a5cc000 },
- { _MMIO(0x9888), 0x0c5c4000 },
- { _MMIO(0x9888), 0x0e3d8000 },
- { _MMIO(0x9888), 0x183da000 },
- { _MMIO(0x9888), 0x06588000 },
- { _MMIO(0x9888), 0x08588000 },
- { _MMIO(0x9888), 0x0a584000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x185b5800 },
- { _MMIO(0x9888), 0x1a5b000a },
- { _MMIO(0x9888), 0x0e1faa00 },
- { _MMIO(0x9888), 0x101f02aa },
- { _MMIO(0x9888), 0x0e384000 },
- { _MMIO(0x9888), 0x16384000 },
- { _MMIO(0x9888), 0x18382a55 },
- { _MMIO(0x9888), 0x06398000 },
- { _MMIO(0x9888), 0x0839a000 },
- { _MMIO(0x9888), 0x0a39a000 },
- { _MMIO(0x9888), 0x0c39a000 },
- { _MMIO(0x9888), 0x0e39a000 },
- { _MMIO(0x9888), 0x1a3a02a0 },
- { _MMIO(0x9888), 0x0e138000 },
- { _MMIO(0x9888), 0x16130500 },
- { _MMIO(0x9888), 0x06148000 },
- { _MMIO(0x9888), 0x08146000 },
- { _MMIO(0x9888), 0x0615c100 },
- { _MMIO(0x9888), 0x0815c500 },
- { _MMIO(0x9888), 0x0a1500c3 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x16335040 },
- { _MMIO(0x9888), 0x08349000 },
- { _MMIO(0x9888), 0x0a341000 },
- { _MMIO(0x9888), 0x083500c1 },
- { _MMIO(0x9888), 0x0a35c500 },
- { _MMIO(0x9888), 0x0c3500c3 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x1853002a },
- { _MMIO(0x9888), 0x0a54e000 },
- { _MMIO(0x9888), 0x0c55c500 },
- { _MMIO(0x9888), 0x0e55c1c3 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x00dc8000 },
- { _MMIO(0x9888), 0x02dcc000 },
- { _MMIO(0x9888), 0x04dc4000 },
- { _MMIO(0x9888), 0x04bd8000 },
- { _MMIO(0x9888), 0x06bd8000 },
- { _MMIO(0x9888), 0x02d8c000 },
- { _MMIO(0x9888), 0x02db8000 },
- { _MMIO(0x9888), 0x04db4000 },
- { _MMIO(0x9888), 0x06db4000 },
- { _MMIO(0x9888), 0x08db8000 },
- { _MMIO(0x9888), 0x0c9fa000 },
- { _MMIO(0x9888), 0x0e9f00aa },
- { _MMIO(0x9888), 0x02b84000 },
- { _MMIO(0x9888), 0x04b84000 },
- { _MMIO(0x9888), 0x06b84000 },
- { _MMIO(0x9888), 0x08b84000 },
- { _MMIO(0x9888), 0x0ab88000 },
- { _MMIO(0x9888), 0x0cb88000 },
- { _MMIO(0x9888), 0x00b98000 },
- { _MMIO(0x9888), 0x02b9a000 },
- { _MMIO(0x9888), 0x04b9a000 },
- { _MMIO(0x9888), 0x06b92000 },
- { _MMIO(0x9888), 0x0aba8000 },
- { _MMIO(0x9888), 0x0cba8000 },
- { _MMIO(0x9888), 0x04938000 },
- { _MMIO(0x9888), 0x06938000 },
- { _MMIO(0x9888), 0x0494c000 },
- { _MMIO(0x9888), 0x0295cfc7 },
- { _MMIO(0x9888), 0x10950000 },
- { _MMIO(0x9888), 0x02b38000 },
- { _MMIO(0x9888), 0x08b38000 },
- { _MMIO(0x9888), 0x04b42000 },
- { _MMIO(0x9888), 0x06b41000 },
- { _MMIO(0x9888), 0x00b5c700 },
- { _MMIO(0x9888), 0x04b500cf },
- { _MMIO(0x9888), 0x10b50000 },
- { _MMIO(0x9888), 0x0ad38000 },
- { _MMIO(0x9888), 0x0cd38000 },
- { _MMIO(0x9888), 0x06d46000 },
- { _MMIO(0x9888), 0x04d5c700 },
- { _MMIO(0x9888), 0x06d500cf },
- { _MMIO(0x9888), 0x10d50000 },
- { _MMIO(0x9888), 0x03888000 },
- { _MMIO(0x9888), 0x05888000 },
- { _MMIO(0x9888), 0x07888000 },
- { _MMIO(0x9888), 0x09888000 },
- { _MMIO(0x9888), 0x0b888000 },
- { _MMIO(0x9888), 0x0d880400 },
- { _MMIO(0x9888), 0x0f8a8000 },
- { _MMIO(0x9888), 0x198a8000 },
- { _MMIO(0x9888), 0x1b8aaaa0 },
- { _MMIO(0x9888), 0x1d8a0002 },
- { _MMIO(0x9888), 0x258b555a },
- { _MMIO(0x9888), 0x278b0015 },
- { _MMIO(0x9888), 0x238b5500 },
- { _MMIO(0x9888), 0x038c4000 },
- { _MMIO(0x9888), 0x058c4000 },
- { _MMIO(0x9888), 0x078c4000 },
- { _MMIO(0x9888), 0x098c4000 },
- { _MMIO(0x9888), 0x0b8c4000 },
- { _MMIO(0x9888), 0x0d8c4000 },
- { _MMIO(0x9888), 0x018d8000 },
- { _MMIO(0x9888), 0x038da000 },
- { _MMIO(0x9888), 0x058da000 },
- { _MMIO(0x9888), 0x078d2000 },
- { _MMIO(0x9888), 0x2185aaaa },
- { _MMIO(0x9888), 0x2385002a },
- { _MMIO(0x9888), 0x1f85aa00 },
- { _MMIO(0x9888), 0x0f834000 },
- { _MMIO(0x9888), 0x19835400 },
- { _MMIO(0x9888), 0x1b830155 },
- { _MMIO(0x9888), 0x03834000 },
- { _MMIO(0x9888), 0x05834000 },
- { _MMIO(0x9888), 0x07834000 },
- { _MMIO(0x9888), 0x09834000 },
- { _MMIO(0x9888), 0x0b834000 },
- { _MMIO(0x9888), 0x0d834000 },
- { _MMIO(0x9888), 0x0784c000 },
- { _MMIO(0x9888), 0x0984c000 },
- { _MMIO(0x9888), 0x0b84c000 },
- { _MMIO(0x9888), 0x0d84c000 },
- { _MMIO(0x9888), 0x0f84c000 },
- { _MMIO(0x9888), 0x01848000 },
- { _MMIO(0x9888), 0x0384c000 },
- { _MMIO(0x9888), 0x0584c000 },
- { _MMIO(0x9888), 0x1780c000 },
- { _MMIO(0x9888), 0x1980c000 },
- { _MMIO(0x9888), 0x1b80c000 },
- { _MMIO(0x9888), 0x1d80c000 },
- { _MMIO(0x9888), 0x1f80c000 },
- { _MMIO(0x9888), 0x11808000 },
- { _MMIO(0x9888), 0x1380c000 },
- { _MMIO(0x9888), 0x1580c000 },
- { _MMIO(0x9888), 0x4f800000 },
- { _MMIO(0x9888), 0x43800882 },
- { _MMIO(0x9888), 0x51800000 },
- { _MMIO(0x9888), 0x45801082 },
- { _MMIO(0x9888), 0x53800000 },
- { _MMIO(0x9888), 0x478014a5 },
- { _MMIO(0x9888), 0x21800000 },
- { _MMIO(0x9888), 0x31800000 },
- { _MMIO(0x9888), 0x4d800000 },
- { _MMIO(0x9888), 0x3f800002 },
- { _MMIO(0x9888), 0x41800c62 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2744), 0x00800000 },
@@ -1997,6 +60,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x000000a0 },
{ _MMIO(0x9888), 0x59800000 },
{ _MMIO(0x9888), 0x59800001 },
{ _MMIO(0x9888), 0x338b0000 },
@@ -2008,866 +72,38 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x57800000 },
{ _MMIO(0x1823a4), 0x00000000 },
{ _MMIO(0x9888), 0x59800000 },
-};
-
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_chv(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_L3_2:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_2);
-
- return 0;
- case METRIC_SET_ID_L3_3:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_3_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_3;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_3);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_3;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_3);
-
- return 0;
- case METRIC_SET_ID_L3_4:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_4_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_4\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_4;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_4);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_4;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_4);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER_1:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler_1);
-
- return 0;
- case METRIC_SET_ID_SAMPLER_2:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler_2);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "9d8a3af5-c02c-4a4a-b947-f1672469e0fb",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "f522a89c-ecd1-4522-8331-3383c54af5f5",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "a9ccc03d-a943-4e6b-9cd6-13e063075927",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "2cf0c064-68df-4fac-9b3f-57f51ca8a069",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "78a87ff9-543a-49ce-95ea-26d86071ea93",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2);
-}
-
-static struct device_attribute dev_attr_l3_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_2[] = {
- &dev_attr_l3_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_2 = {
- .name = "9f2cece5-7bfe-4320-ad66-8c7cc526bec5",
- .attrs = attrs_l3_2,
-};
-
-static ssize_t
-show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3);
-}
-
-static struct device_attribute dev_attr_l3_3_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_3_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_3[] = {
- &dev_attr_l3_3_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_3 = {
- .name = "d890ef38-d309-47e4-b8b5-aa779bb19ab0",
- .attrs = attrs_l3_3,
-};
-
-static ssize_t
-show_l3_4_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_4);
-}
-
-static struct device_attribute dev_attr_l3_4_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_4_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_4[] = {
- &dev_attr_l3_4_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_4 = {
- .name = "5fdff4a6-9dc8-45e1-bfda-ef54869fbdd4",
- .attrs = attrs_l3_4,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "2c0e45e1-7e2c-4a14-ae00-0b7ec868b8aa",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER_1);
-}
-
-static struct device_attribute dev_attr_sampler_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler_1[] = {
- &dev_attr_sampler_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler_1 = {
- .name = "71148d78-baf5-474f-878a-e23158d0265d",
- .attrs = attrs_sampler_1,
-};
-
-static ssize_t
-show_sampler_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER_2);
-}
-
-static struct device_attribute dev_attr_sampler_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler_2[] = {
- &dev_attr_sampler_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler_2 = {
- .name = "b996a2b7-c59c-492d-877a-8cd54fd6df84",
- .attrs = attrs_sampler_2,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "eb2fecba-b431-42e7-8261-fe9429a6e67a",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "60749470-a648-4a4b-9f10-dbfe1e36e44d",
- .attrs = attrs_tdl_2,
+ { _MMIO(0x9840), 0x00000080 },
};
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "4a534b07-cba3-414d-8d60-874830e883aa",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_chv(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_chv(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "4a534b07-cba3-414d-8d60-874830e883aa",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (ret)
- goto error_l3_2;
- }
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (ret)
- goto error_l3_3;
- }
- if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_4);
- if (ret)
- goto error_l3_4;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler_1);
- if (ret)
- goto error_sampler_1;
- }
- if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler_2);
- if (ret)
- goto error_sampler_2;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_2);
-error_sampler_2:
- if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_1);
-error_sampler_1:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_4);
-error_l3_4:
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
-error_l3_3:
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
-error_l3_2:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_chv(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "4a534b07-cba3-414d-8d60-874830e883aa";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (get_l3_4_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_4);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_1);
- if (get_sampler_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_2);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_chv.h b/drivers/gpu/drm/i915/i915_oa_chv.h
index 8b8bdc26d726..b9622496979e 100644
--- a/drivers/gpu/drm/i915/i915_oa_chv.h
+++ b/drivers/gpu/drm/i915/i915_oa_chv.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_CHV_H__
#define __I915_OA_CHV_H__
-extern int i915_oa_n_builtin_metric_sets_chv;
-
-extern int i915_oa_select_metric_set_chv(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_chv(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_chv(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_chv(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_glk.c b/drivers/gpu/drm/i915/i915_oa_glk.c
index 2f356d51bff8..4ee527e4c926 100644
--- a/drivers/gpu/drm/i915/i915_oa_glk.c
+++ b/drivers/gpu/drm/i915/i915_oa_glk.c
@@ -31,1614 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_glk.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_COMPUTE_L3_CACHE,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_COMPUTE_EXTRA,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_glk = 15;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic[] = {
- { _MMIO(0x9888), 0x166c00f0 },
- { _MMIO(0x9888), 0x12120280 },
- { _MMIO(0x9888), 0x12320280 },
- { _MMIO(0x9888), 0x11930317 },
- { _MMIO(0x9888), 0x159303df },
- { _MMIO(0x9888), 0x3f900c00 },
- { _MMIO(0x9888), 0x419000a0 },
- { _MMIO(0x9888), 0x002d1000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x082d5000 },
- { _MMIO(0x9888), 0x0a2d1000 },
- { _MMIO(0x9888), 0x0c2e0800 },
- { _MMIO(0x9888), 0x0e2e5900 },
- { _MMIO(0x9888), 0x0a4c8000 },
- { _MMIO(0x9888), 0x0c4c8000 },
- { _MMIO(0x9888), 0x0e4c4000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e2000 },
- { _MMIO(0x9888), 0x1c4f0010 },
- { _MMIO(0x9888), 0x0a6c0053 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1a0fcc00 },
- { _MMIO(0x9888), 0x1c0f0002 },
- { _MMIO(0x9888), 0x1c2c0040 },
- { _MMIO(0x9888), 0x00101000 },
- { _MMIO(0x9888), 0x04101000 },
- { _MMIO(0x9888), 0x00114000 },
- { _MMIO(0x9888), 0x08114000 },
- { _MMIO(0x9888), 0x00120020 },
- { _MMIO(0x9888), 0x08120021 },
- { _MMIO(0x9888), 0x00141000 },
- { _MMIO(0x9888), 0x08141000 },
- { _MMIO(0x9888), 0x02308000 },
- { _MMIO(0x9888), 0x04302000 },
- { _MMIO(0x9888), 0x06318000 },
- { _MMIO(0x9888), 0x08318000 },
- { _MMIO(0x9888), 0x06320800 },
- { _MMIO(0x9888), 0x08320840 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x06344000 },
- { _MMIO(0x9888), 0x08344000 },
- { _MMIO(0x9888), 0x0d931831 },
- { _MMIO(0x9888), 0x0f939f3f },
- { _MMIO(0x9888), 0x01939e80 },
- { _MMIO(0x9888), 0x039303bc },
- { _MMIO(0x9888), 0x0593000e },
- { _MMIO(0x9888), 0x1993002a },
- { _MMIO(0x9888), 0x07930000 },
- { _MMIO(0x9888), 0x09930000 },
- { _MMIO(0x9888), 0x1d900177 },
- { _MMIO(0x9888), 0x1f900187 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25904000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x53901110 },
- { _MMIO(0x9888), 0x43900423 },
- { _MMIO(0x9888), 0x55900111 },
- { _MMIO(0x9888), 0x47900c02 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900020 },
- { _MMIO(0x9888), 0x59901111 },
- { _MMIO(0x9888), 0x4b900421 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x45900821 },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_basic;
- lens[n] = ARRAY_SIZE(mux_config_render_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x124f1c00 },
- { _MMIO(0x9888), 0x39900340 },
- { _MMIO(0x9888), 0x3f900c00 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x002d5000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x082d4000 },
- { _MMIO(0x9888), 0x0a2d1000 },
- { _MMIO(0x9888), 0x0c2d5000 },
- { _MMIO(0x9888), 0x0e2d4000 },
- { _MMIO(0x9888), 0x0c2e1400 },
- { _MMIO(0x9888), 0x0e2e5100 },
- { _MMIO(0x9888), 0x102e0114 },
- { _MMIO(0x9888), 0x044cc000 },
- { _MMIO(0x9888), 0x0a4c8000 },
- { _MMIO(0x9888), 0x0c4c8000 },
- { _MMIO(0x9888), 0x0e4c4000 },
- { _MMIO(0x9888), 0x104c8000 },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x004ea000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e2000 },
- { _MMIO(0x9888), 0x0c4ea000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x004f6b42 },
- { _MMIO(0x9888), 0x064f6200 },
- { _MMIO(0x9888), 0x084f4100 },
- { _MMIO(0x9888), 0x0a4f0061 },
- { _MMIO(0x9888), 0x0c4f6c4c },
- { _MMIO(0x9888), 0x0e4f4b00 },
- { _MMIO(0x9888), 0x1a4f0000 },
- { _MMIO(0x9888), 0x1c4f0000 },
- { _MMIO(0x9888), 0x180f5000 },
- { _MMIO(0x9888), 0x1a0f8800 },
- { _MMIO(0x9888), 0x1c0f08a2 },
- { _MMIO(0x9888), 0x182c4000 },
- { _MMIO(0x9888), 0x1c2c1451 },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x1a2c0010 },
- { _MMIO(0x9888), 0x01938000 },
- { _MMIO(0x9888), 0x0f938000 },
- { _MMIO(0x9888), 0x19938a28 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x19900177 },
- { _MMIO(0x9888), 0x1b900178 },
- { _MMIO(0x9888), 0x1d900125 },
- { _MMIO(0x9888), 0x1f900123 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x25904000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x53901000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x55900111 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900000 },
- { _MMIO(0x9888), 0x45900000 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_basic;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile[] = {
- { _MMIO(0x9888), 0x0c2e001f },
- { _MMIO(0x9888), 0x0a2f0000 },
- { _MMIO(0x9888), 0x10186800 },
- { _MMIO(0x9888), 0x11810019 },
- { _MMIO(0x9888), 0x15810013 },
- { _MMIO(0x9888), 0x13820020 },
- { _MMIO(0x9888), 0x11830020 },
- { _MMIO(0x9888), 0x17840000 },
- { _MMIO(0x9888), 0x11860007 },
- { _MMIO(0x9888), 0x21860000 },
- { _MMIO(0x9888), 0x178703e0 },
- { _MMIO(0x9888), 0x0c2d8000 },
- { _MMIO(0x9888), 0x042d4000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x022e5400 },
- { _MMIO(0x9888), 0x002e0000 },
- { _MMIO(0x9888), 0x0e2e0080 },
- { _MMIO(0x9888), 0x082f0040 },
- { _MMIO(0x9888), 0x002f0000 },
- { _MMIO(0x9888), 0x06143000 },
- { _MMIO(0x9888), 0x06174000 },
- { _MMIO(0x9888), 0x06180012 },
- { _MMIO(0x9888), 0x00180000 },
- { _MMIO(0x9888), 0x0d804000 },
- { _MMIO(0x9888), 0x0f804000 },
- { _MMIO(0x9888), 0x05804000 },
- { _MMIO(0x9888), 0x09810200 },
- { _MMIO(0x9888), 0x0b810030 },
- { _MMIO(0x9888), 0x03810003 },
- { _MMIO(0x9888), 0x21819140 },
- { _MMIO(0x9888), 0x23819050 },
- { _MMIO(0x9888), 0x25810018 },
- { _MMIO(0x9888), 0x0b820980 },
- { _MMIO(0x9888), 0x03820d80 },
- { _MMIO(0x9888), 0x11820000 },
- { _MMIO(0x9888), 0x0182c000 },
- { _MMIO(0x9888), 0x07828000 },
- { _MMIO(0x9888), 0x09824000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x0d830004 },
- { _MMIO(0x9888), 0x0583000c },
- { _MMIO(0x9888), 0x0f831000 },
- { _MMIO(0x9888), 0x01848072 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x07848000 },
- { _MMIO(0x9888), 0x09844000 },
- { _MMIO(0x9888), 0x0f848000 },
- { _MMIO(0x9888), 0x07860000 },
- { _MMIO(0x9888), 0x09860092 },
- { _MMIO(0x9888), 0x0f860400 },
- { _MMIO(0x9888), 0x01869100 },
- { _MMIO(0x9888), 0x0f870065 },
- { _MMIO(0x9888), 0x01870000 },
- { _MMIO(0x9888), 0x19930800 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x1b952000 },
- { _MMIO(0x9888), 0x1d955055 },
- { _MMIO(0x9888), 0x1f951455 },
- { _MMIO(0x9888), 0x0992a000 },
- { _MMIO(0x9888), 0x0f928000 },
- { _MMIO(0x9888), 0x1192a800 },
- { _MMIO(0x9888), 0x1392028a },
- { _MMIO(0x9888), 0x0b92a000 },
- { _MMIO(0x9888), 0x0d922000 },
- { _MMIO(0x9888), 0x13908000 },
- { _MMIO(0x9888), 0x21908000 },
- { _MMIO(0x9888), 0x23908000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27908000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f908000 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x15908000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900c01 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900863 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900061 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900000 },
- { _MMIO(0x9888), 0x45900c22 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_pipe_profile;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads[] = {
- { _MMIO(0x9888), 0x19800343 },
- { _MMIO(0x9888), 0x39900340 },
- { _MMIO(0x9888), 0x3f901000 },
- { _MMIO(0x9888), 0x41900003 },
- { _MMIO(0x9888), 0x03803180 },
- { _MMIO(0x9888), 0x058035e2 },
- { _MMIO(0x9888), 0x0780006a },
- { _MMIO(0x9888), 0x11800000 },
- { _MMIO(0x9888), 0x2181a000 },
- { _MMIO(0x9888), 0x2381000a },
- { _MMIO(0x9888), 0x1d950550 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d92a000 },
- { _MMIO(0x9888), 0x0f922000 },
- { _MMIO(0x9888), 0x13900170 },
- { _MMIO(0x9888), 0x21900171 },
- { _MMIO(0x9888), 0x23900172 },
- { _MMIO(0x9888), 0x25900173 },
- { _MMIO(0x9888), 0x27900174 },
- { _MMIO(0x9888), 0x29900175 },
- { _MMIO(0x9888), 0x2b900176 },
- { _MMIO(0x9888), 0x2d900177 },
- { _MMIO(0x9888), 0x2f90017f },
- { _MMIO(0x9888), 0x31900125 },
- { _MMIO(0x9888), 0x15900123 },
- { _MMIO(0x9888), 0x17900121 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43901084 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47901080 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49901084 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b901084 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900004 },
- { _MMIO(0x9888), 0x45900000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_reads;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes[] = {
- { _MMIO(0x9888), 0x19800343 },
- { _MMIO(0x9888), 0x39900340 },
- { _MMIO(0x9888), 0x3f900000 },
- { _MMIO(0x9888), 0x41900080 },
- { _MMIO(0x9888), 0x03803180 },
- { _MMIO(0x9888), 0x058035e2 },
- { _MMIO(0x9888), 0x0780006a },
- { _MMIO(0x9888), 0x11800000 },
- { _MMIO(0x9888), 0x2181a000 },
- { _MMIO(0x9888), 0x2381000a },
- { _MMIO(0x9888), 0x1d950550 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d92a000 },
- { _MMIO(0x9888), 0x0f922000 },
- { _MMIO(0x9888), 0x13900180 },
- { _MMIO(0x9888), 0x21900181 },
- { _MMIO(0x9888), 0x23900182 },
- { _MMIO(0x9888), 0x25900183 },
- { _MMIO(0x9888), 0x27900184 },
- { _MMIO(0x9888), 0x29900185 },
- { _MMIO(0x9888), 0x2b900186 },
- { _MMIO(0x9888), 0x2d900187 },
- { _MMIO(0x9888), 0x2f900170 },
- { _MMIO(0x9888), 0x31900125 },
- { _MMIO(0x9888), 0x15900123 },
- { _MMIO(0x9888), 0x17900121 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43901084 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47901080 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49901084 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b901084 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900004 },
- { _MMIO(0x9888), 0x45900000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_writes;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fc2a },
- { _MMIO(0x2774), 0x0000bf00 },
- { _MMIO(0x2778), 0x0007fc6a },
- { _MMIO(0x277c), 0x0000bf00 },
- { _MMIO(0x2780), 0x0007fc92 },
- { _MMIO(0x2784), 0x0000bf00 },
- { _MMIO(0x2788), 0x0007fca2 },
- { _MMIO(0x278c), 0x0000bf00 },
- { _MMIO(0x2790), 0x0007fc32 },
- { _MMIO(0x2794), 0x0000bf00 },
- { _MMIO(0x2798), 0x0007fc9a },
- { _MMIO(0x279c), 0x0000bf00 },
- { _MMIO(0x27a0), 0x0007fe6a },
- { _MMIO(0x27a4), 0x0000bf00 },
- { _MMIO(0x27a8), 0x0007fe7a },
- { _MMIO(0x27ac), 0x0000bf00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x141c0160 },
- { _MMIO(0x9888), 0x161c0015 },
- { _MMIO(0x9888), 0x181c0120 },
- { _MMIO(0x9888), 0x002d5000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x082d5000 },
- { _MMIO(0x9888), 0x0a2d5000 },
- { _MMIO(0x9888), 0x0c2d5000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x0c2e5400 },
- { _MMIO(0x9888), 0x0e2e5515 },
- { _MMIO(0x9888), 0x102e0155 },
- { _MMIO(0x9888), 0x044cc000 },
- { _MMIO(0x9888), 0x0a4c8000 },
- { _MMIO(0x9888), 0x0c4cc000 },
- { _MMIO(0x9888), 0x0e4cc000 },
- { _MMIO(0x9888), 0x104c8000 },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x004ea000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084ea000 },
- { _MMIO(0x9888), 0x0a4ea000 },
- { _MMIO(0x9888), 0x0c4ea000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x0e4f4b41 },
- { _MMIO(0x9888), 0x004f4200 },
- { _MMIO(0x9888), 0x024f404c },
- { _MMIO(0x9888), 0x1c4f0000 },
- { _MMIO(0x9888), 0x1a4f0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x061b8000 },
- { _MMIO(0x9888), 0x081bc000 },
- { _MMIO(0x9888), 0x0a1bc000 },
- { _MMIO(0x9888), 0x0c1bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x001c0031 },
- { _MMIO(0x9888), 0x061c1900 },
- { _MMIO(0x9888), 0x081c1a33 },
- { _MMIO(0x9888), 0x0a1c1b35 },
- { _MMIO(0x9888), 0x0c1c3337 },
- { _MMIO(0x9888), 0x041c31c7 },
- { _MMIO(0x9888), 0x180f5000 },
- { _MMIO(0x9888), 0x1a0fa8aa },
- { _MMIO(0x9888), 0x1c0f0aaa },
- { _MMIO(0x9888), 0x182c8000 },
- { _MMIO(0x9888), 0x1c2c6aaa },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x1a2c2950 },
- { _MMIO(0x9888), 0x01938000 },
- { _MMIO(0x9888), 0x0f938000 },
- { _MMIO(0x9888), 0x1993aaaa },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25904000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x29904000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900420 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900400 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x45900001 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extended;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fffa },
- { _MMIO(0x2774), 0x0000fefe },
- { _MMIO(0x2778), 0x0007fffa },
- { _MMIO(0x277c), 0x0000fefd },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000fbef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000fbdf },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00101100 },
- { _MMIO(0xe45c), 0x00201200 },
- { _MMIO(0xe55c), 0x00301300 },
- { _MMIO(0xe65c), 0x00401400 },
-};
-
-static const struct i915_oa_reg mux_config_compute_l3_cache[] = {
- { _MMIO(0x9888), 0x166c03b0 },
- { _MMIO(0x9888), 0x1593001e },
- { _MMIO(0x9888), 0x3f900c00 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x002d1000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x082d5000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x0c2e0400 },
- { _MMIO(0x9888), 0x0e2e1500 },
- { _MMIO(0x9888), 0x102e0140 },
- { _MMIO(0x9888), 0x044c4000 },
- { _MMIO(0x9888), 0x0a4c8000 },
- { _MMIO(0x9888), 0x0c4cc000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x004e2000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084ea000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x1a4f4001 },
- { _MMIO(0x9888), 0x1c4f5005 },
- { _MMIO(0x9888), 0x006c0051 },
- { _MMIO(0x9888), 0x066c5000 },
- { _MMIO(0x9888), 0x086c5c5d },
- { _MMIO(0x9888), 0x0e6c5e5f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x146c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x180f1000 },
- { _MMIO(0x9888), 0x1a0fa800 },
- { _MMIO(0x9888), 0x1c0f0a00 },
- { _MMIO(0x9888), 0x182c4000 },
- { _MMIO(0x9888), 0x1c2c4015 },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x03931980 },
- { _MMIO(0x9888), 0x05930032 },
- { _MMIO(0x9888), 0x11930000 },
- { _MMIO(0x9888), 0x01938000 },
- { _MMIO(0x9888), 0x0f938000 },
- { _MMIO(0x9888), 0x1993a00a },
- { _MMIO(0x9888), 0x07930000 },
- { _MMIO(0x9888), 0x09930000 },
- { _MMIO(0x9888), 0x1d900177 },
- { _MMIO(0x9888), 0x1f900178 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x53901000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x55900111 },
- { _MMIO(0x9888), 0x47900001 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x4d900000 },
- { _MMIO(0x9888), 0x45900400 },
-};
-
-static int
-get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_l3_cache;
- lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x104f0232 },
- { _MMIO(0x9888), 0x124f4640 },
- { _MMIO(0x9888), 0x11834400 },
- { _MMIO(0x9888), 0x022d4000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x0e2e0055 },
- { _MMIO(0x9888), 0x064c8000 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x024f6100 },
- { _MMIO(0x9888), 0x044f416b },
- { _MMIO(0x9888), 0x064f004b },
- { _MMIO(0x9888), 0x1a4f0000 },
- { _MMIO(0x9888), 0x1a0f02a8 },
- { _MMIO(0x9888), 0x1a2c5500 },
- { _MMIO(0x9888), 0x0f808000 },
- { _MMIO(0x9888), 0x25810020 },
- { _MMIO(0x9888), 0x0f8305c0 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x1f951000 },
- { _MMIO(0x9888), 0x13920200 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4d900003 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1[] = {
- { _MMIO(0x9888), 0x12643400 },
- { _MMIO(0x9888), 0x12653400 },
- { _MMIO(0x9888), 0x106c6800 },
- { _MMIO(0x9888), 0x126c001e },
- { _MMIO(0x9888), 0x166c0010 },
- { _MMIO(0x9888), 0x0c2d5000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x102e0154 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e0055 },
- { _MMIO(0x9888), 0x104c8000 },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x0c4ea000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x1c4f5500 },
- { _MMIO(0x9888), 0x1a4f1554 },
- { _MMIO(0x9888), 0x0a640024 },
- { _MMIO(0x9888), 0x10640000 },
- { _MMIO(0x9888), 0x04640000 },
- { _MMIO(0x9888), 0x0c650024 },
- { _MMIO(0x9888), 0x10650000 },
- { _MMIO(0x9888), 0x06650000 },
- { _MMIO(0x9888), 0x0c6c5327 },
- { _MMIO(0x9888), 0x0e6c5425 },
- { _MMIO(0x9888), 0x006c2a00 },
- { _MMIO(0x9888), 0x026c285b },
- { _MMIO(0x9888), 0x046c005c },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1a6c0900 },
- { _MMIO(0x9888), 0x1c0f0aa0 },
- { _MMIO(0x9888), 0x180f4000 },
- { _MMIO(0x9888), 0x1a0f02aa },
- { _MMIO(0x9888), 0x1c2c5400 },
- { _MMIO(0x9888), 0x1e2c0001 },
- { _MMIO(0x9888), 0x1a2c5550 },
- { _MMIO(0x9888), 0x1993aa00 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900421 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900420 },
- { _MMIO(0x9888), 0x45900021 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_1;
- lens[n] = ARRAY_SIZE(mux_config_l3_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000efff },
- { _MMIO(0x2778), 0x00006000 },
- { _MMIO(0x277c), 0x0000f3ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x102d7800 },
- { _MMIO(0x9888), 0x122d79e0 },
- { _MMIO(0x9888), 0x0c2f0004 },
- { _MMIO(0x9888), 0x100e3800 },
- { _MMIO(0x9888), 0x180f0005 },
- { _MMIO(0x9888), 0x002d0940 },
- { _MMIO(0x9888), 0x022d802f },
- { _MMIO(0x9888), 0x042d4013 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x0e2e0050 },
- { _MMIO(0x9888), 0x022f0010 },
- { _MMIO(0x9888), 0x002f0000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x040e0480 },
- { _MMIO(0x9888), 0x000e0000 },
- { _MMIO(0x9888), 0x060f0027 },
- { _MMIO(0x9888), 0x100f0000 },
- { _MMIO(0x9888), 0x1a0f0040 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x439014a0 },
- { _MMIO(0x9888), 0x459000a4 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler[] = {
- { _MMIO(0x9888), 0x121300a0 },
- { _MMIO(0x9888), 0x141600ab },
- { _MMIO(0x9888), 0x123300a0 },
- { _MMIO(0x9888), 0x143600ab },
- { _MMIO(0x9888), 0x125300a0 },
- { _MMIO(0x9888), 0x145600ab },
- { _MMIO(0x9888), 0x0c2d4000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x102e01a0 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e0065 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x084c4000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x044e2000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x1c0f0800 },
- { _MMIO(0x9888), 0x180f4000 },
- { _MMIO(0x9888), 0x1a0f023f },
- { _MMIO(0x9888), 0x1e2c0003 },
- { _MMIO(0x9888), 0x1a2cc030 },
- { _MMIO(0x9888), 0x04132180 },
- { _MMIO(0x9888), 0x02130000 },
- { _MMIO(0x9888), 0x0c148000 },
- { _MMIO(0x9888), 0x0e142000 },
- { _MMIO(0x9888), 0x04148000 },
- { _MMIO(0x9888), 0x1e150140 },
- { _MMIO(0x9888), 0x1c150040 },
- { _MMIO(0x9888), 0x0c163000 },
- { _MMIO(0x9888), 0x0e160068 },
- { _MMIO(0x9888), 0x10160000 },
- { _MMIO(0x9888), 0x18160000 },
- { _MMIO(0x9888), 0x0a164000 },
- { _MMIO(0x9888), 0x04330043 },
- { _MMIO(0x9888), 0x02330000 },
- { _MMIO(0x9888), 0x0234a000 },
- { _MMIO(0x9888), 0x04342000 },
- { _MMIO(0x9888), 0x1c350015 },
- { _MMIO(0x9888), 0x02363460 },
- { _MMIO(0x9888), 0x10360000 },
- { _MMIO(0x9888), 0x04360000 },
- { _MMIO(0x9888), 0x06360000 },
- { _MMIO(0x9888), 0x08364000 },
- { _MMIO(0x9888), 0x06530043 },
- { _MMIO(0x9888), 0x02530000 },
- { _MMIO(0x9888), 0x0e548000 },
- { _MMIO(0x9888), 0x00548000 },
- { _MMIO(0x9888), 0x06542000 },
- { _MMIO(0x9888), 0x1e550400 },
- { _MMIO(0x9888), 0x1a552000 },
- { _MMIO(0x9888), 0x1c550100 },
- { _MMIO(0x9888), 0x0e563000 },
- { _MMIO(0x9888), 0x00563400 },
- { _MMIO(0x9888), 0x10560000 },
- { _MMIO(0x9888), 0x18560000 },
- { _MMIO(0x9888), 0x02560000 },
- { _MMIO(0x9888), 0x0c564000 },
- { _MMIO(0x9888), 0x1993a800 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b9014a0 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900001 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900820 },
- { _MMIO(0x9888), 0x45901022 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900000 },
-};
-
-static int
-get_sampler_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler;
- lens[n] = ARRAY_SIZE(mux_config_sampler);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x00007fff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x00009fff },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000efff },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000f3ff },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fdff },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x141a0000 },
- { _MMIO(0x9888), 0x143a0000 },
- { _MMIO(0x9888), 0x145a0000 },
- { _MMIO(0x9888), 0x0c2d4000 },
- { _MMIO(0x9888), 0x0e2d5000 },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x102e0150 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e006a },
- { _MMIO(0x9888), 0x124c8000 },
- { _MMIO(0x9888), 0x144c8000 },
- { _MMIO(0x9888), 0x164c2000 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064c4000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x0e4ea000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024e2000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x1c0f0bc0 },
- { _MMIO(0x9888), 0x180f4000 },
- { _MMIO(0x9888), 0x1a0f0302 },
- { _MMIO(0x9888), 0x1e2c0003 },
- { _MMIO(0x9888), 0x1a2c00f0 },
- { _MMIO(0x9888), 0x021a3080 },
- { _MMIO(0x9888), 0x041a31e5 },
- { _MMIO(0x9888), 0x02148000 },
- { _MMIO(0x9888), 0x0414a000 },
- { _MMIO(0x9888), 0x1c150054 },
- { _MMIO(0x9888), 0x06168000 },
- { _MMIO(0x9888), 0x08168000 },
- { _MMIO(0x9888), 0x0a168000 },
- { _MMIO(0x9888), 0x0c3a3280 },
- { _MMIO(0x9888), 0x0e3a0063 },
- { _MMIO(0x9888), 0x063a0061 },
- { _MMIO(0x9888), 0x023a0000 },
- { _MMIO(0x9888), 0x0c348000 },
- { _MMIO(0x9888), 0x0e342000 },
- { _MMIO(0x9888), 0x06342000 },
- { _MMIO(0x9888), 0x1e350140 },
- { _MMIO(0x9888), 0x1c350100 },
- { _MMIO(0x9888), 0x18360028 },
- { _MMIO(0x9888), 0x0c368000 },
- { _MMIO(0x9888), 0x0e5a3080 },
- { _MMIO(0x9888), 0x005a3280 },
- { _MMIO(0x9888), 0x025a0063 },
- { _MMIO(0x9888), 0x0e548000 },
- { _MMIO(0x9888), 0x00548000 },
- { _MMIO(0x9888), 0x02542000 },
- { _MMIO(0x9888), 0x1e550400 },
- { _MMIO(0x9888), 0x1a552000 },
- { _MMIO(0x9888), 0x1c550001 },
- { _MMIO(0x9888), 0x18560080 },
- { _MMIO(0x9888), 0x02568000 },
- { _MMIO(0x9888), 0x04568000 },
- { _MMIO(0x9888), 0x1993a800 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x2d904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900420 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4d900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x45901084 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900001 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x141a026b },
- { _MMIO(0x9888), 0x143a0173 },
- { _MMIO(0x9888), 0x145a026b },
- { _MMIO(0x9888), 0x002d4000 },
- { _MMIO(0x9888), 0x022d5000 },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x0c2e5000 },
- { _MMIO(0x9888), 0x0e2e0069 },
- { _MMIO(0x9888), 0x044c8000 },
- { _MMIO(0x9888), 0x064cc000 },
- { _MMIO(0x9888), 0x0a4c4000 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x024ea000 },
- { _MMIO(0x9888), 0x064e2000 },
- { _MMIO(0x9888), 0x180f6000 },
- { _MMIO(0x9888), 0x1a0f030a },
- { _MMIO(0x9888), 0x1a2c03c0 },
- { _MMIO(0x9888), 0x041a37e7 },
- { _MMIO(0x9888), 0x021a0000 },
- { _MMIO(0x9888), 0x0414a000 },
- { _MMIO(0x9888), 0x1c150050 },
- { _MMIO(0x9888), 0x08168000 },
- { _MMIO(0x9888), 0x0a168000 },
- { _MMIO(0x9888), 0x003a3380 },
- { _MMIO(0x9888), 0x063a006f },
- { _MMIO(0x9888), 0x023a0000 },
- { _MMIO(0x9888), 0x00348000 },
- { _MMIO(0x9888), 0x06342000 },
- { _MMIO(0x9888), 0x1a352000 },
- { _MMIO(0x9888), 0x1c350100 },
- { _MMIO(0x9888), 0x02368000 },
- { _MMIO(0x9888), 0x0c368000 },
- { _MMIO(0x9888), 0x025a37e7 },
- { _MMIO(0x9888), 0x0254a000 },
- { _MMIO(0x9888), 0x1c550005 },
- { _MMIO(0x9888), 0x04568000 },
- { _MMIO(0x9888), 0x06568000 },
- { _MMIO(0x9888), 0x03938000 },
- { _MMIO(0x9888), 0x05938000 },
- { _MMIO(0x9888), 0x07938000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17904000 },
- { _MMIO(0x9888), 0x19904000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900020 },
- { _MMIO(0x9888), 0x45901080 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x47900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extra[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extra[] = {
- { _MMIO(0xe458), 0x00001000 },
- { _MMIO(0xe558), 0x00003002 },
- { _MMIO(0xe658), 0x00005004 },
- { _MMIO(0xe758), 0x00011010 },
- { _MMIO(0xe45c), 0x00050012 },
- { _MMIO(0xe55c), 0x00052051 },
- { _MMIO(0xe65c), 0x00000008 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extra[] = {
- { _MMIO(0x9888), 0x141a001f },
- { _MMIO(0x9888), 0x143a001f },
- { _MMIO(0x9888), 0x145a001f },
- { _MMIO(0x9888), 0x042d5000 },
- { _MMIO(0x9888), 0x062d1000 },
- { _MMIO(0x9888), 0x0e2e0094 },
- { _MMIO(0x9888), 0x084cc000 },
- { _MMIO(0x9888), 0x044ea000 },
- { _MMIO(0x9888), 0x1a0f00e0 },
- { _MMIO(0x9888), 0x1a2c0c00 },
- { _MMIO(0x9888), 0x061a0063 },
- { _MMIO(0x9888), 0x021a0000 },
- { _MMIO(0x9888), 0x06142000 },
- { _MMIO(0x9888), 0x1c150100 },
- { _MMIO(0x9888), 0x0c168000 },
- { _MMIO(0x9888), 0x043a3180 },
- { _MMIO(0x9888), 0x023a0000 },
- { _MMIO(0x9888), 0x04348000 },
- { _MMIO(0x9888), 0x1c350040 },
- { _MMIO(0x9888), 0x0a368000 },
- { _MMIO(0x9888), 0x045a0063 },
- { _MMIO(0x9888), 0x025a0000 },
- { _MMIO(0x9888), 0x04542000 },
- { _MMIO(0x9888), 0x1c550010 },
- { _MMIO(0x9888), 0x08568000 },
- { _MMIO(0x9888), 0x09938000 },
- { _MMIO(0x9888), 0x0b938000 },
- { _MMIO(0x9888), 0x0d938000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1d904000 },
- { _MMIO(0x9888), 0x1f904000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900400 },
- { _MMIO(0x9888), 0x47900004 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_compute_extra_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extra;
- lens[n] = ARRAY_SIZE(mux_config_compute_extra);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2744), 0x00800000 },
@@ -1668,6 +60,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x00000080 },
{ _MMIO(0x9888), 0x19800000 },
{ _MMIO(0x9888), 0x07800063 },
{ _MMIO(0x9888), 0x11800000 },
@@ -1681,922 +74,35 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x33900000 },
};
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_glk(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_L3_CACHE:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_l3_cache_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_l3_cache;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_l3_cache);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_l3_cache;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_l3_cache);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTRA:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extra_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extra;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extra);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extra;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extra);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "d72df5c7-5b4a-4274-a43f-00b0fd51fc68",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "814285f6-354d-41d2-ba49-e24e622714a0",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "07d397a6-b3e6-49f6-9433-a4f293d55978",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "1a356946-5428-450b-a2f0-89f8783a302d",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "5299be9d-7a61-4c99-9f81-f87e6c5aaca9",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
-}
-
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "bc9bcff2-459a-4cbc-986d-a84b077153f3",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE);
-}
-
-static struct device_attribute dev_attr_compute_l3_cache_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_l3_cache_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_l3_cache[] = {
- &dev_attr_compute_l3_cache_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_l3_cache = {
- .name = "88ec931f-5b4a-453a-9db6-a61232b6143d",
- .attrs = attrs_compute_l3_cache,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "530d176d-2a18-4014-adf8-1500c6c60835",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "fdee5a5a-f23c-43d1-aa73-f6257c71671d",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "6617623e-ca73-4791-b2b7-ddedd0846a0c",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER);
-}
-
-static struct device_attribute dev_attr_sampler_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler[] = {
- &dev_attr_sampler_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler = {
- .name = "f3b2ea63-e82e-4234-b418-44dd20dd34d0",
- .attrs = attrs_sampler,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "14411d35-cbf6-4f5e-b68b-190faf9a1a83",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "ffa3f263-0478-4724-8c9f-c911c5ec0f1d",
- .attrs = attrs_tdl_2,
-};
-
-static ssize_t
-show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA);
-}
-
-static struct device_attribute dev_attr_compute_extra_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extra_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extra[] = {
- &dev_attr_compute_extra_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extra = {
- .name = "15274c82-27d2-4819-876a-7cb1a2c59ba4",
- .attrs = attrs_compute_extra,
-};
-
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "dd3fd789-e783-4204-8cd0-b671bbccb0cf",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_glk(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_glk(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "dd3fd789-e783-4204-8cd0-b671bbccb0cf",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (ret)
- goto error_compute_l3_cache;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (ret)
- goto error_sampler;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (ret)
- goto error_compute_extra;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
-error_compute_extra:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
-error_sampler:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
-error_compute_l3_cache:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_glk(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "dd3fd789-e783-4204-8cd0-b671bbccb0cf";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_glk.h b/drivers/gpu/drm/i915/i915_oa_glk.h
index 5511bb1cecf7..63bd113f4bc9 100644
--- a/drivers/gpu/drm/i915/i915_oa_glk.h
+++ b/drivers/gpu/drm/i915/i915_oa_glk.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_GLK_H__
#define __I915_OA_GLK_H__
-extern int i915_oa_n_builtin_metric_sets_glk;
-
-extern int i915_oa_select_metric_set_glk(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_glk(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_glk(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_glk(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_hsw.c b/drivers/gpu/drm/i915/i915_oa_hsw.c
index 10f169f683b7..56b03773bb9d 100644
--- a/drivers/gpu/drm/i915/i915_oa_hsw.c
+++ b/drivers/gpu/drm/i915/i915_oa_hsw.c
@@ -31,17 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_hsw.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_SAMPLER_BALANCE,
-};
-
-int i915_oa_n_builtin_metric_sets_hsw = 6;
-
static const struct i915_oa_reg b_counter_config_render_basic[] = {
{ _MMIO(0x2724), 0x00800000 },
{ _MMIO(0x2720), 0x00000000 },
@@ -53,6 +42,7 @@ static const struct i915_oa_reg flex_eu_config_render_basic[] = {
};
static const struct i915_oa_reg mux_config_render_basic[] = {
+ { _MMIO(0x9840), 0x00000080 },
{ _MMIO(0x253a4), 0x01600000 },
{ _MMIO(0x25440), 0x00100000 },
{ _MMIO(0x25128), 0x00000000 },
@@ -114,750 +104,35 @@ static const struct i915_oa_reg mux_config_render_basic[] = {
{ _MMIO(0x25428), 0x00042049 },
};
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_basic;
- lens[n] = ARRAY_SIZE(mux_config_render_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2718), 0xaaaaaaaa },
- { _MMIO(0x271c), 0xaaaaaaaa },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2728), 0xaaaaaaaa },
- { _MMIO(0x272c), 0xaaaaaaaa },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00000000 },
- { _MMIO(0x2748), 0x00000000 },
- { _MMIO(0x274c), 0x00000000 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2754), 0x00000000 },
- { _MMIO(0x2758), 0x00000000 },
- { _MMIO(0x275c), 0x00000000 },
- { _MMIO(0x236c), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
-};
-
-static const struct i915_oa_reg mux_config_compute_basic[] = {
- { _MMIO(0x253a4), 0x00000000 },
- { _MMIO(0x2681c), 0x01f00800 },
- { _MMIO(0x26820), 0x00001000 },
- { _MMIO(0x2781c), 0x01f00800 },
- { _MMIO(0x26520), 0x00000007 },
- { _MMIO(0x265a0), 0x00000007 },
- { _MMIO(0x25380), 0x00000010 },
- { _MMIO(0x2538c), 0x00300000 },
- { _MMIO(0x25384), 0xaa8aaaaa },
- { _MMIO(0x25404), 0xffffffff },
- { _MMIO(0x26800), 0x00004202 },
- { _MMIO(0x26808), 0x00605817 },
- { _MMIO(0x2680c), 0x10001005 },
- { _MMIO(0x26804), 0x00000000 },
- { _MMIO(0x27800), 0x00000102 },
- { _MMIO(0x27808), 0x0c0701e0 },
- { _MMIO(0x2780c), 0x000200a0 },
- { _MMIO(0x27804), 0x00000000 },
- { _MMIO(0x26484), 0x44000000 },
- { _MMIO(0x26704), 0x44000000 },
- { _MMIO(0x26500), 0x00000006 },
- { _MMIO(0x26510), 0x00000001 },
- { _MMIO(0x26504), 0x88000000 },
- { _MMIO(0x26580), 0x00000006 },
- { _MMIO(0x26590), 0x00000020 },
- { _MMIO(0x26584), 0x00000000 },
- { _MMIO(0x26104), 0x55822222 },
- { _MMIO(0x26184), 0xaa866666 },
- { _MMIO(0x25420), 0x08320c83 },
- { _MMIO(0x25424), 0x06820c83 },
- { _MMIO(0x2541c), 0x00000000 },
- { _MMIO(0x25428), 0x00000c03 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_basic;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2770), 0x0007fe2a },
- { _MMIO(0x2774), 0x0000ff00 },
- { _MMIO(0x2778), 0x0007fe6a },
- { _MMIO(0x277c), 0x0000ff00 },
- { _MMIO(0x2780), 0x0007fe92 },
- { _MMIO(0x2784), 0x0000ff00 },
- { _MMIO(0x2788), 0x0007fea2 },
- { _MMIO(0x278c), 0x0000ff00 },
- { _MMIO(0x2790), 0x0007fe32 },
- { _MMIO(0x2794), 0x0000ff00 },
- { _MMIO(0x2798), 0x0007fe9a },
- { _MMIO(0x279c), 0x0000ff00 },
- { _MMIO(0x27a0), 0x0007ff23 },
- { _MMIO(0x27a4), 0x0000ff00 },
- { _MMIO(0x27a8), 0x0007fff3 },
- { _MMIO(0x27ac), 0x0000fffe },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
-};
-
-static const struct i915_oa_reg mux_config_compute_extended[] = {
- { _MMIO(0x2681c), 0x3eb00800 },
- { _MMIO(0x26820), 0x00900000 },
- { _MMIO(0x25384), 0x02aaaaaa },
- { _MMIO(0x25404), 0x03ffffff },
- { _MMIO(0x26800), 0x00142284 },
- { _MMIO(0x26808), 0x0e629062 },
- { _MMIO(0x2680c), 0x3f6f55cb },
- { _MMIO(0x26810), 0x00000014 },
- { _MMIO(0x26804), 0x00000000 },
- { _MMIO(0x26104), 0x02aaaaaa },
- { _MMIO(0x26184), 0x02aaaaaa },
- { _MMIO(0x25420), 0x00000000 },
- { _MMIO(0x25424), 0x00000000 },
- { _MMIO(0x2541c), 0x00000000 },
- { _MMIO(0x25428), 0x00000000 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extended;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x76543298 },
- { _MMIO(0x2748), 0x98989898 },
- { _MMIO(0x2744), 0x000000e4 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x98a98a98 },
- { _MMIO(0x2758), 0x88888888 },
- { _MMIO(0x2754), 0x000c5500 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fc00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fc00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fc00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fc00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fc00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fc00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fc00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fc00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
-};
-
-static const struct i915_oa_reg mux_config_memory_reads[] = {
- { _MMIO(0x253a4), 0x34300000 },
- { _MMIO(0x25440), 0x2d800000 },
- { _MMIO(0x25444), 0x00000008 },
- { _MMIO(0x25128), 0x0e600000 },
- { _MMIO(0x25380), 0x00000450 },
- { _MMIO(0x25390), 0x00052c43 },
- { _MMIO(0x25384), 0x00000000 },
- { _MMIO(0x25400), 0x00006144 },
- { _MMIO(0x25408), 0x0a418820 },
- { _MMIO(0x2540c), 0x000820e6 },
- { _MMIO(0x25404), 0xff500000 },
- { _MMIO(0x25100), 0x000005d6 },
- { _MMIO(0x2510c), 0x0ef00000 },
- { _MMIO(0x25104), 0x00000000 },
- { _MMIO(0x25420), 0x02108421 },
- { _MMIO(0x25424), 0x00008421 },
- { _MMIO(0x2541c), 0x00000000 },
- { _MMIO(0x25428), 0x00000000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_reads;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x76543298 },
- { _MMIO(0x2748), 0x98989898 },
- { _MMIO(0x2744), 0x000000e4 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0xbabababa },
- { _MMIO(0x2758), 0x88888888 },
- { _MMIO(0x2754), 0x000c5500 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fc00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fc00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fc00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fc00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fc00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fc00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fc00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fc00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
-};
-
-static const struct i915_oa_reg mux_config_memory_writes[] = {
- { _MMIO(0x253a4), 0x34300000 },
- { _MMIO(0x25440), 0x01500000 },
- { _MMIO(0x25444), 0x00000120 },
- { _MMIO(0x25128), 0x0c200000 },
- { _MMIO(0x25380), 0x00000450 },
- { _MMIO(0x25390), 0x00052c43 },
- { _MMIO(0x25384), 0x00000000 },
- { _MMIO(0x25400), 0x00007184 },
- { _MMIO(0x25408), 0x0a418820 },
- { _MMIO(0x2540c), 0x000820e6 },
- { _MMIO(0x25404), 0xff500000 },
- { _MMIO(0x25100), 0x000005d6 },
- { _MMIO(0x2510c), 0x1e700000 },
- { _MMIO(0x25104), 0x00000000 },
- { _MMIO(0x25420), 0x02108421 },
- { _MMIO(0x25424), 0x00008421 },
- { _MMIO(0x2541c), 0x00000000 },
- { _MMIO(0x25428), 0x00000000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_writes;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler_balance[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler_balance[] = {
-};
-
-static const struct i915_oa_reg mux_config_sampler_balance[] = {
- { _MMIO(0x2eb9c), 0x01906400 },
- { _MMIO(0x2fb9c), 0x01906400 },
- { _MMIO(0x253a4), 0x00000000 },
- { _MMIO(0x26b9c), 0x01906400 },
- { _MMIO(0x27b9c), 0x01906400 },
- { _MMIO(0x27104), 0x00a00000 },
- { _MMIO(0x27184), 0x00a50000 },
- { _MMIO(0x2e804), 0x00500000 },
- { _MMIO(0x2e984), 0x00500000 },
- { _MMIO(0x2eb04), 0x00500000 },
- { _MMIO(0x2eb80), 0x00000084 },
- { _MMIO(0x2eb8c), 0x14200000 },
- { _MMIO(0x2eb84), 0x00000000 },
- { _MMIO(0x2f804), 0x00050000 },
- { _MMIO(0x2f984), 0x00050000 },
- { _MMIO(0x2fb04), 0x00050000 },
- { _MMIO(0x2fb80), 0x00000084 },
- { _MMIO(0x2fb8c), 0x00050800 },
- { _MMIO(0x2fb84), 0x00000000 },
- { _MMIO(0x25380), 0x00000010 },
- { _MMIO(0x2538c), 0x000000c0 },
- { _MMIO(0x25384), 0xaa550000 },
- { _MMIO(0x25404), 0xffffc000 },
- { _MMIO(0x26804), 0x50000000 },
- { _MMIO(0x26984), 0x50000000 },
- { _MMIO(0x26b04), 0x50000000 },
- { _MMIO(0x26b80), 0x00000084 },
- { _MMIO(0x26b90), 0x00050800 },
- { _MMIO(0x26b84), 0x00000000 },
- { _MMIO(0x27804), 0x05000000 },
- { _MMIO(0x27984), 0x05000000 },
- { _MMIO(0x27b04), 0x05000000 },
- { _MMIO(0x27b80), 0x00000084 },
- { _MMIO(0x27b90), 0x00000142 },
- { _MMIO(0x27b84), 0x00000000 },
- { _MMIO(0x26104), 0xa0000000 },
- { _MMIO(0x26184), 0xa5000000 },
- { _MMIO(0x25424), 0x00008620 },
- { _MMIO(0x2541c), 0x00000000 },
- { _MMIO(0x25428), 0x0004a54a },
-};
-
-static int
-get_sampler_balance_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler_balance;
- lens[n] = ARRAY_SIZE(mux_config_sampler_balance);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_hsw(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_SAMPLER_BALANCE:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_balance_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER_BALANCE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler_balance;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler_balance);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler_balance;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler_balance);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
static ssize_t
show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "403d8832-1a27-4aa6-a64e-f5389ce7b212",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "39ad14bc-2380-45c4-91eb-fbcb3aa7ae7b",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "3865be28-6982-49fe-9494-e4d1b4795413",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "bb5ed49b-2497-4095-94f6-26ba294db88a",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "3358d639-9b5f-45ab-976d-9b08cbfc6240",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_sampler_balance_id(struct device *kdev, struct device_attribute *attr, char *buf)
+void
+i915_perf_load_test_config_hsw(struct drm_i915_private *dev_priv)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER_BALANCE);
-}
-
-static struct device_attribute dev_attr_sampler_balance_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_balance_id,
- .store = NULL,
-};
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "403d8832-1a27-4aa6-a64e-f5389ce7b212",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
-static struct attribute *attrs_sampler_balance[] = {
- &dev_attr_sampler_balance_id.attr,
- NULL,
-};
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_render_basic;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_render_basic);
-static struct attribute_group group_sampler_balance = {
- .name = "bc274488-b4b6-40c7-90da-b77d7ad16189",
- .attrs = attrs_sampler_balance,
-};
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_render_basic;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_render_basic);
-int
-i915_perf_register_sysfs_hsw(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_render_basic;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_render_basic);
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_sampler_balance_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler_balance);
- if (ret)
- goto error_sampler_balance;
- }
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "403d8832-1a27-4aa6-a64e-f5389ce7b212";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
- return 0;
-
-error_sampler_balance:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
-
-void
-i915_perf_unregister_sysfs_hsw(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_sampler_balance_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler_balance);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_render_basic_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_hsw.h b/drivers/gpu/drm/i915/i915_oa_hsw.h
index 6fe7e0690ef3..74d03439c157 100644
--- a/drivers/gpu/drm/i915/i915_oa_hsw.h
+++ b/drivers/gpu/drm/i915/i915_oa_hsw.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_HSW_H__
#define __I915_OA_HSW_H__
-extern int i915_oa_n_builtin_metric_sets_hsw;
-
-extern int i915_oa_select_metric_set_hsw(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_hsw(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_hsw(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_hsw(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt2.c b/drivers/gpu/drm/i915/i915_oa_kblgt2.c
index 87dbd0a0b076..b6e7cc774136 100644
--- a/drivers/gpu/drm/i915/i915_oa_kblgt2.c
+++ b/drivers/gpu/drm/i915/i915_oa_kblgt2.c
@@ -31,1828 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_kblgt2.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_COMPUTE_L3_CACHE,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_L3_2,
- METRIC_SET_ID_L3_3,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_COMPUTE_EXTRA,
- METRIC_SET_ID_VME_PIPE,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_kblgt2 = 18;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic[] = {
- { _MMIO(0x9888), 0x166c01e0 },
- { _MMIO(0x9888), 0x12170280 },
- { _MMIO(0x9888), 0x12370280 },
- { _MMIO(0x9888), 0x11930317 },
- { _MMIO(0x9888), 0x159303df },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x1a4e0080 },
- { _MMIO(0x9888), 0x0a6c0053 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x0a1b4000 },
- { _MMIO(0x9888), 0x1c1c0001 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x042f1000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c8400 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0d2000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f6600 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x162c2200 },
- { _MMIO(0x9888), 0x062d8000 },
- { _MMIO(0x9888), 0x082d8000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x08133000 },
- { _MMIO(0x9888), 0x00170020 },
- { _MMIO(0x9888), 0x08170021 },
- { _MMIO(0x9888), 0x10170000 },
- { _MMIO(0x9888), 0x0633c000 },
- { _MMIO(0x9888), 0x0833c000 },
- { _MMIO(0x9888), 0x06370800 },
- { _MMIO(0x9888), 0x08370840 },
- { _MMIO(0x9888), 0x10370000 },
- { _MMIO(0x9888), 0x0d933031 },
- { _MMIO(0x9888), 0x0f933e3f },
- { _MMIO(0x9888), 0x01933d00 },
- { _MMIO(0x9888), 0x0393073c },
- { _MMIO(0x9888), 0x0593000e },
- { _MMIO(0x9888), 0x1d930000 },
- { _MMIO(0x9888), 0x19930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x2f908000 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x15908000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190001f },
- { _MMIO(0x9888), 0x51904400 },
- { _MMIO(0x9888), 0x41900020 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c21 },
- { _MMIO(0x9888), 0x47900061 },
- { _MMIO(0x9888), 0x57904440 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900004 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x53904444 },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_basic;
- lens[n] = ARRAY_SIZE(mux_config_render_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x124f1c00 },
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x1a4e0820 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x064f0900 },
- { _MMIO(0x9888), 0x084f0032 },
- { _MMIO(0x9888), 0x0a4f1891 },
- { _MMIO(0x9888), 0x0c4f0e00 },
- { _MMIO(0x9888), 0x0e4f003c },
- { _MMIO(0x9888), 0x004f0d80 },
- { _MMIO(0x9888), 0x024f003b },
- { _MMIO(0x9888), 0x006c0002 },
- { _MMIO(0x9888), 0x086c0100 },
- { _MMIO(0x9888), 0x0c6c000c },
- { _MMIO(0x9888), 0x0e6c0b00 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x081b8000 },
- { _MMIO(0x9888), 0x0c1b4000 },
- { _MMIO(0x9888), 0x0e1b8000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1c8000 },
- { _MMIO(0x9888), 0x1c1c0024 },
- { _MMIO(0x9888), 0x065b8000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5bc000 },
- { _MMIO(0x9888), 0x0c5b8000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x1a5c6000 },
- { _MMIO(0x9888), 0x1c5c001b },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2000 },
- { _MMIO(0x9888), 0x0c4c0208 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020d2000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2cc000 },
- { _MMIO(0x9888), 0x162cfb00 },
- { _MMIO(0x9888), 0x182c00be },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x19900157 },
- { _MMIO(0x9888), 0x1b900158 },
- { _MMIO(0x9888), 0x1d900105 },
- { _MMIO(0x9888), 0x1f900103 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x11900fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900821 },
- { _MMIO(0x9888), 0x47900802 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900802 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900002 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900422 },
- { _MMIO(0x9888), 0x53904444 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_basic;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile[] = {
- { _MMIO(0x9888), 0x0c0e001f },
- { _MMIO(0x9888), 0x0a0f0000 },
- { _MMIO(0x9888), 0x10116800 },
- { _MMIO(0x9888), 0x178a03e0 },
- { _MMIO(0x9888), 0x11824c00 },
- { _MMIO(0x9888), 0x11830020 },
- { _MMIO(0x9888), 0x13840020 },
- { _MMIO(0x9888), 0x11850019 },
- { _MMIO(0x9888), 0x11860007 },
- { _MMIO(0x9888), 0x01870c40 },
- { _MMIO(0x9888), 0x17880000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0a4c0040 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x040d4000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020e5400 },
- { _MMIO(0x9888), 0x000e0000 },
- { _MMIO(0x9888), 0x080f0040 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x100f0000 },
- { _MMIO(0x9888), 0x0e0f0040 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06110012 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x01898000 },
- { _MMIO(0x9888), 0x0d890100 },
- { _MMIO(0x9888), 0x03898000 },
- { _MMIO(0x9888), 0x09808000 },
- { _MMIO(0x9888), 0x0b808000 },
- { _MMIO(0x9888), 0x0380c000 },
- { _MMIO(0x9888), 0x0f8a0075 },
- { _MMIO(0x9888), 0x1d8a0000 },
- { _MMIO(0x9888), 0x118a8000 },
- { _MMIO(0x9888), 0x1b8a4000 },
- { _MMIO(0x9888), 0x138a8000 },
- { _MMIO(0x9888), 0x1d81a000 },
- { _MMIO(0x9888), 0x15818000 },
- { _MMIO(0x9888), 0x17818000 },
- { _MMIO(0x9888), 0x0b820030 },
- { _MMIO(0x9888), 0x07828000 },
- { _MMIO(0x9888), 0x0d824000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x05824000 },
- { _MMIO(0x9888), 0x0d830003 },
- { _MMIO(0x9888), 0x0583000c },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x03838000 },
- { _MMIO(0x9888), 0x07838000 },
- { _MMIO(0x9888), 0x0b840980 },
- { _MMIO(0x9888), 0x03844d80 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x09848000 },
- { _MMIO(0x9888), 0x09850080 },
- { _MMIO(0x9888), 0x03850003 },
- { _MMIO(0x9888), 0x01850000 },
- { _MMIO(0x9888), 0x07860000 },
- { _MMIO(0x9888), 0x0f860400 },
- { _MMIO(0x9888), 0x09870032 },
- { _MMIO(0x9888), 0x01888052 },
- { _MMIO(0x9888), 0x11880000 },
- { _MMIO(0x9888), 0x09884000 },
- { _MMIO(0x9888), 0x1b931001 },
- { _MMIO(0x9888), 0x1d930001 },
- { _MMIO(0x9888), 0x19934000 },
- { _MMIO(0x9888), 0x1b958000 },
- { _MMIO(0x9888), 0x1d950094 },
- { _MMIO(0x9888), 0x19958000 },
- { _MMIO(0x9888), 0x09e58000 },
- { _MMIO(0x9888), 0x0be58000 },
- { _MMIO(0x9888), 0x03e5c000 },
- { _MMIO(0x9888), 0x0592c000 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d924000 },
- { _MMIO(0x9888), 0x0f924000 },
- { _MMIO(0x9888), 0x11928000 },
- { _MMIO(0x9888), 0x1392c000 },
- { _MMIO(0x9888), 0x09924000 },
- { _MMIO(0x9888), 0x01985000 },
- { _MMIO(0x9888), 0x07988000 },
- { _MMIO(0x9888), 0x09981000 },
- { _MMIO(0x9888), 0x0b982000 },
- { _MMIO(0x9888), 0x0d982000 },
- { _MMIO(0x9888), 0x0f989000 },
- { _MMIO(0x9888), 0x05982000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1190c080 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900440 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900400 },
- { _MMIO(0x9888), 0x47900c21 },
- { _MMIO(0x9888), 0x57900400 },
- { _MMIO(0x9888), 0x49900042 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900024 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900841 },
- { _MMIO(0x9888), 0x53900400 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_pipe_profile;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900064 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900150 },
- { _MMIO(0x9888), 0x21900151 },
- { _MMIO(0x9888), 0x23900152 },
- { _MMIO(0x9888), 0x25900153 },
- { _MMIO(0x9888), 0x27900154 },
- { _MMIO(0x9888), 0x29900155 },
- { _MMIO(0x9888), 0x2b900156 },
- { _MMIO(0x9888), 0x2d900157 },
- { _MMIO(0x9888), 0x2f90015f },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_reads;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901000 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900160 },
- { _MMIO(0x9888), 0x21900161 },
- { _MMIO(0x9888), 0x23900162 },
- { _MMIO(0x9888), 0x25900163 },
- { _MMIO(0x9888), 0x27900164 },
- { _MMIO(0x9888), 0x29900165 },
- { _MMIO(0x9888), 0x2b900166 },
- { _MMIO(0x9888), 0x2d900167 },
- { _MMIO(0x9888), 0x2f900150 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_writes;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fc2a },
- { _MMIO(0x2774), 0x0000bf00 },
- { _MMIO(0x2778), 0x0007fc6a },
- { _MMIO(0x277c), 0x0000bf00 },
- { _MMIO(0x2780), 0x0007fc92 },
- { _MMIO(0x2784), 0x0000bf00 },
- { _MMIO(0x2788), 0x0007fca2 },
- { _MMIO(0x278c), 0x0000bf00 },
- { _MMIO(0x2790), 0x0007fc32 },
- { _MMIO(0x2794), 0x0000bf00 },
- { _MMIO(0x2798), 0x0007fc9a },
- { _MMIO(0x279c), 0x0000bf00 },
- { _MMIO(0x27a0), 0x0007fe6a },
- { _MMIO(0x27a4), 0x0000bf00 },
- { _MMIO(0x27a8), 0x0007fe7a },
- { _MMIO(0x27ac), 0x0000bf00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended[] = {
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x141c8160 },
- { _MMIO(0x9888), 0x161c8015 },
- { _MMIO(0x9888), 0x181c0120 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4eaaa0 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0e6c0b01 },
- { _MMIO(0x9888), 0x006c0200 },
- { _MMIO(0x9888), 0x026c000c },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x001c0041 },
- { _MMIO(0x9888), 0x061c4200 },
- { _MMIO(0x9888), 0x081c4443 },
- { _MMIO(0x9888), 0x0a1c4645 },
- { _MMIO(0x9888), 0x0c1c7647 },
- { _MMIO(0x9888), 0x041c7357 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x101c0000 },
- { _MMIO(0x9888), 0x1a1c0000 },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4caa2a },
- { _MMIO(0x9888), 0x0c4c02aa },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5515 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x11907fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900040 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900802 },
- { _MMIO(0x9888), 0x47900842 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900842 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900800 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extended;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fffa },
- { _MMIO(0x2774), 0x0000fefe },
- { _MMIO(0x2778), 0x0007fffa },
- { _MMIO(0x277c), 0x0000fefd },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000fbef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000fbdf },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00101100 },
- { _MMIO(0xe45c), 0x00201200 },
- { _MMIO(0xe55c), 0x00301300 },
- { _MMIO(0xe65c), 0x00401400 },
-};
-
-static const struct i915_oa_reg mux_config_compute_l3_cache[] = {
- { _MMIO(0x9888), 0x166c0760 },
- { _MMIO(0x9888), 0x1593001e },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4e8020 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x006c0051 },
- { _MMIO(0x9888), 0x066c5000 },
- { _MMIO(0x9888), 0x086c5c5d },
- { _MMIO(0x9888), 0x0e6c5e5f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x061b8000 },
- { _MMIO(0x9888), 0x081bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1ce000 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2a00 },
- { _MMIO(0x9888), 0x0c4c0280 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f1500 },
- { _MMIO(0x9888), 0x100f0140 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162c0a00 },
- { _MMIO(0x9888), 0x182c00a0 },
- { _MMIO(0x9888), 0x03933300 },
- { _MMIO(0x9888), 0x05930032 },
- { _MMIO(0x9888), 0x11930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190030f },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900021 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x53904444 },
- { _MMIO(0x9888), 0x43900000 },
-};
-
-static int
-get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_l3_cache;
- lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x104f0232 },
- { _MMIO(0x9888), 0x124f4640 },
- { _MMIO(0x9888), 0x106c0232 },
- { _MMIO(0x9888), 0x11834400 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x004f1880 },
- { _MMIO(0x9888), 0x024f08bb },
- { _MMIO(0x9888), 0x044f001b },
- { _MMIO(0x9888), 0x046c0100 },
- { _MMIO(0x9888), 0x066c000b },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x041b8000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025bc000 },
- { _MMIO(0x9888), 0x045b4000 },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x165c8000 },
- { _MMIO(0x9888), 0x185c8000 },
- { _MMIO(0x9888), 0x0a4c00a0 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x062cc000 },
- { _MMIO(0x9888), 0x082cc000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x0f8305c0 },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x07830000 },
- { _MMIO(0x9888), 0x1d950080 },
- { _MMIO(0x9888), 0x13928000 },
- { _MMIO(0x9888), 0x0f988000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900040 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1[] = {
- { _MMIO(0x9888), 0x126c7b40 },
- { _MMIO(0x9888), 0x166c0020 },
- { _MMIO(0x9888), 0x0a603444 },
- { _MMIO(0x9888), 0x0a613400 },
- { _MMIO(0x9888), 0x1a4ea800 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x0c6c5327 },
- { _MMIO(0x9888), 0x0e6c5425 },
- { _MMIO(0x9888), 0x006c2a00 },
- { _MMIO(0x9888), 0x026c285b },
- { _MMIO(0x9888), 0x046c005c },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0800 },
- { _MMIO(0x9888), 0x0c1bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x1c1c003c },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x10600000 },
- { _MMIO(0x9888), 0x04600000 },
- { _MMIO(0x9888), 0x0c610044 },
- { _MMIO(0x9888), 0x10610000 },
- { _MMIO(0x9888), 0x06610000 },
- { _MMIO(0x9888), 0x0c4c02a8 },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0154 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190ffc0 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900420 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900021 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900400 },
- { _MMIO(0x9888), 0x43900421 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_1;
- lens[n] = ARRAY_SIZE(mux_config_l3_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_2[] = {
- { _MMIO(0x9888), 0x126c02e0 },
- { _MMIO(0x9888), 0x146c0001 },
- { _MMIO(0x9888), 0x0a623400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x026c3324 },
- { _MMIO(0x9888), 0x046c3422 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x06614000 },
- { _MMIO(0x9888), 0x0c620044 },
- { _MMIO(0x9888), 0x10620000 },
- { _MMIO(0x9888), 0x06620000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_2;
- lens[n] = ARRAY_SIZE(mux_config_l3_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_3[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_3[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_3[] = {
- { _MMIO(0x9888), 0x126c4e80 },
- { _MMIO(0x9888), 0x146c0000 },
- { _MMIO(0x9888), 0x0a633400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x026c3321 },
- { _MMIO(0x9888), 0x046c342f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c2000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x06604000 },
- { _MMIO(0x9888), 0x0c630044 },
- { _MMIO(0x9888), 0x10630000 },
- { _MMIO(0x9888), 0x06630000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c00aa },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900002 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_3_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_3;
- lens[n] = ARRAY_SIZE(mux_config_l3_3);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000efff },
- { _MMIO(0x2778), 0x00006000 },
- { _MMIO(0x277c), 0x0000f3ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x102f3800 },
- { _MMIO(0x9888), 0x144d0500 },
- { _MMIO(0x9888), 0x120d03c0 },
- { _MMIO(0x9888), 0x140d03cf },
- { _MMIO(0x9888), 0x0c0f0004 },
- { _MMIO(0x9888), 0x0c4e4000 },
- { _MMIO(0x9888), 0x042f0480 },
- { _MMIO(0x9888), 0x082f0000 },
- { _MMIO(0x9888), 0x022f0000 },
- { _MMIO(0x9888), 0x0a4c0090 },
- { _MMIO(0x9888), 0x064d0027 },
- { _MMIO(0x9888), 0x004d0000 },
- { _MMIO(0x9888), 0x000d0d40 },
- { _MMIO(0x9888), 0x020d803f },
- { _MMIO(0x9888), 0x040d8023 },
- { _MMIO(0x9888), 0x100d0000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020f0010 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x0e0f0050 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41901400 },
- { _MMIO(0x9888), 0x43901485 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler[] = {
- { _MMIO(0x9888), 0x14152c00 },
- { _MMIO(0x9888), 0x16150005 },
- { _MMIO(0x9888), 0x121600a0 },
- { _MMIO(0x9888), 0x14352c00 },
- { _MMIO(0x9888), 0x16350005 },
- { _MMIO(0x9888), 0x123600a0 },
- { _MMIO(0x9888), 0x14552c00 },
- { _MMIO(0x9888), 0x16550005 },
- { _MMIO(0x9888), 0x125600a0 },
- { _MMIO(0x9888), 0x062f6000 },
- { _MMIO(0x9888), 0x022f2000 },
- { _MMIO(0x9888), 0x0c4c0050 },
- { _MMIO(0x9888), 0x0a4c0010 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0350 },
- { _MMIO(0x9888), 0x0c0fb000 },
- { _MMIO(0x9888), 0x0e0f00da },
- { _MMIO(0x9888), 0x182c0028 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x022dc000 },
- { _MMIO(0x9888), 0x042d4000 },
- { _MMIO(0x9888), 0x0c138000 },
- { _MMIO(0x9888), 0x0e132000 },
- { _MMIO(0x9888), 0x0413c000 },
- { _MMIO(0x9888), 0x1c140018 },
- { _MMIO(0x9888), 0x0c157000 },
- { _MMIO(0x9888), 0x0e150078 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x04162180 },
- { _MMIO(0x9888), 0x02160000 },
- { _MMIO(0x9888), 0x04174000 },
- { _MMIO(0x9888), 0x0233a000 },
- { _MMIO(0x9888), 0x04333000 },
- { _MMIO(0x9888), 0x14348000 },
- { _MMIO(0x9888), 0x16348000 },
- { _MMIO(0x9888), 0x02357870 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x04360043 },
- { _MMIO(0x9888), 0x02360000 },
- { _MMIO(0x9888), 0x04371000 },
- { _MMIO(0x9888), 0x0e538000 },
- { _MMIO(0x9888), 0x00538000 },
- { _MMIO(0x9888), 0x06533000 },
- { _MMIO(0x9888), 0x1c540020 },
- { _MMIO(0x9888), 0x12548000 },
- { _MMIO(0x9888), 0x0e557000 },
- { _MMIO(0x9888), 0x00557800 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x06560043 },
- { _MMIO(0x9888), 0x02560000 },
- { _MMIO(0x9888), 0x06571000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900060 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900060 },
-};
-
-static int
-get_sampler_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler;
- lens[n] = ARRAY_SIZE(mux_config_sampler);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x00007fff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x00009fff },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000efff },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000f3ff },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fdff },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x12120000 },
- { _MMIO(0x9888), 0x12320000 },
- { _MMIO(0x9888), 0x12520000 },
- { _MMIO(0x9888), 0x002f8000 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0015 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f03a0 },
- { _MMIO(0x9888), 0x0c0ff000 },
- { _MMIO(0x9888), 0x0e0f0095 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2d8000 },
- { _MMIO(0x9888), 0x0e2d4000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x02108000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x02118000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x02121880 },
- { _MMIO(0x9888), 0x041219b5 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x02134000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x0c308000 },
- { _MMIO(0x9888), 0x0e304000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x0c318000 },
- { _MMIO(0x9888), 0x0e314000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x0c321a80 },
- { _MMIO(0x9888), 0x0e320033 },
- { _MMIO(0x9888), 0x06320031 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x0c334000 },
- { _MMIO(0x9888), 0x0e331000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0e508000 },
- { _MMIO(0x9888), 0x00508000 },
- { _MMIO(0x9888), 0x02504000 },
- { _MMIO(0x9888), 0x0e518000 },
- { _MMIO(0x9888), 0x00518000 },
- { _MMIO(0x9888), 0x02514000 },
- { _MMIO(0x9888), 0x0e521880 },
- { _MMIO(0x9888), 0x00521a80 },
- { _MMIO(0x9888), 0x02520033 },
- { _MMIO(0x9888), 0x0e534000 },
- { _MMIO(0x9888), 0x00534000 },
- { _MMIO(0x9888), 0x02531000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900062 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x12124d60 },
- { _MMIO(0x9888), 0x12322e60 },
- { _MMIO(0x9888), 0x12524d60 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0014 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0fe000 },
- { _MMIO(0x9888), 0x0e0f0097 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x002d8000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x04121fb7 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x00308000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x00318000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x00321b80 },
- { _MMIO(0x9888), 0x0632003f },
- { _MMIO(0x9888), 0x00334000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0250c000 },
- { _MMIO(0x9888), 0x0251c000 },
- { _MMIO(0x9888), 0x02521fb7 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x02535000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900063 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extra[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extra[] = {
- { _MMIO(0xe458), 0x00001000 },
- { _MMIO(0xe558), 0x00003002 },
- { _MMIO(0xe658), 0x00005004 },
- { _MMIO(0xe758), 0x00011010 },
- { _MMIO(0xe45c), 0x00050012 },
- { _MMIO(0xe55c), 0x00052051 },
- { _MMIO(0xe65c), 0x00000008 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extra[] = {
- { _MMIO(0x9888), 0x121203e0 },
- { _MMIO(0x9888), 0x123203e0 },
- { _MMIO(0x9888), 0x125203e0 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0a4c0040 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0e0f006c },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x042d8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06114000 },
- { _MMIO(0x9888), 0x06120033 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x04308000 },
- { _MMIO(0x9888), 0x04318000 },
- { _MMIO(0x9888), 0x04321980 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x04334000 },
- { _MMIO(0x9888), 0x04504000 },
- { _MMIO(0x9888), 0x04514000 },
- { _MMIO(0x9888), 0x04520033 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x04531000 },
- { _MMIO(0x9888), 0x1190e000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900c00 },
- { _MMIO(0x9888), 0x45900002 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_compute_extra_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extra;
- lens[n] = ARRAY_SIZE(mux_config_compute_extra);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_vme_pipe[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00100030 },
- { _MMIO(0x2774), 0x0000fff9 },
- { _MMIO(0x2778), 0x00000002 },
- { _MMIO(0x277c), 0x0000fffc },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000fff3 },
- { _MMIO(0x2788), 0x00100180 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000ffcf },
- { _MMIO(0x2798), 0x00000002 },
- { _MMIO(0x279c), 0x0000ff3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_vme_pipe[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00008003 },
-};
-
-static const struct i915_oa_reg mux_config_vme_pipe[] = {
- { _MMIO(0x9888), 0x141a5800 },
- { _MMIO(0x9888), 0x161a00c0 },
- { _MMIO(0x9888), 0x12180240 },
- { _MMIO(0x9888), 0x14180002 },
- { _MMIO(0x9888), 0x143a5800 },
- { _MMIO(0x9888), 0x163a00c0 },
- { _MMIO(0x9888), 0x12380240 },
- { _MMIO(0x9888), 0x14380002 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x022f8000 },
- { _MMIO(0x9888), 0x042f3000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c1500 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f9500 },
- { _MMIO(0x9888), 0x100f002a },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162c0a00 },
- { _MMIO(0x9888), 0x0a2dc000 },
- { _MMIO(0x9888), 0x0c2dc000 },
- { _MMIO(0x9888), 0x04193000 },
- { _MMIO(0x9888), 0x081a28c1 },
- { _MMIO(0x9888), 0x001a0000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x0613c000 },
- { _MMIO(0x9888), 0x0813f000 },
- { _MMIO(0x9888), 0x00172000 },
- { _MMIO(0x9888), 0x06178000 },
- { _MMIO(0x9888), 0x0817a000 },
- { _MMIO(0x9888), 0x00180037 },
- { _MMIO(0x9888), 0x06180940 },
- { _MMIO(0x9888), 0x08180000 },
- { _MMIO(0x9888), 0x02180000 },
- { _MMIO(0x9888), 0x04183000 },
- { _MMIO(0x9888), 0x06393000 },
- { _MMIO(0x9888), 0x0c3a28c1 },
- { _MMIO(0x9888), 0x003a0000 },
- { _MMIO(0x9888), 0x0a33f000 },
- { _MMIO(0x9888), 0x0c33f000 },
- { _MMIO(0x9888), 0x0a37a000 },
- { _MMIO(0x9888), 0x0c37a000 },
- { _MMIO(0x9888), 0x0a380977 },
- { _MMIO(0x9888), 0x08380000 },
- { _MMIO(0x9888), 0x04380000 },
- { _MMIO(0x9888), 0x06383000 },
- { _MMIO(0x9888), 0x119000ff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900040 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900800 },
- { _MMIO(0x9888), 0x47901000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900844 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_vme_pipe_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_vme_pipe;
- lens[n] = ARRAY_SIZE(mux_config_vme_pipe);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2744), 0x00800000 },
@@ -1882,6 +60,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x00000080 },
{ _MMIO(0x9888), 0x11810000 },
{ _MMIO(0x9888), 0x07810013 },
{ _MMIO(0x9888), 0x1f810000 },
@@ -1896,1096 +75,35 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x33900000 },
};
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_kblgt2(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_L3_CACHE:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_l3_cache_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_l3_cache;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_l3_cache);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_l3_cache;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_l3_cache);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_L3_2:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_2);
-
- return 0;
- case METRIC_SET_ID_L3_3:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_3_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_3;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_3);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_3;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_3);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTRA:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extra_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extra;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extra);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extra;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extra);
-
- return 0;
- case METRIC_SET_ID_VME_PIPE:
- dev_priv->perf.oa.n_mux_configs =
- get_vme_pipe_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_vme_pipe;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_vme_pipe);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_vme_pipe;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_vme_pipe);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "f8d677e9-ff6f-4df1-9310-0334c6efacce",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "e17fc42a-e614-41b6-90c4-1074841a6c77",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "d7a17a3a-ca71-40d2-a919-ace80d50633f",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "57b59202-172b-477a-87de-33f85572c589",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "3addf8ef-8e9b-40f5-a448-3dbb5d5128b0",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
-}
-
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "4af0400a-81c3-47db-a6b6-deddbd75680e",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE);
-}
-
-static struct device_attribute dev_attr_compute_l3_cache_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_l3_cache_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_l3_cache[] = {
- &dev_attr_compute_l3_cache_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_l3_cache = {
- .name = "0e22f995-79ca-4f67-83ab-e9d9772488d8",
- .attrs = attrs_compute_l3_cache,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "bc2a00f7-cb8a-4ff2-8ad0-e241dad16937",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "d2bbe790-f058-42d9-81c6-cdedcf655bc2",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2);
-}
-
-static struct device_attribute dev_attr_l3_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_2[] = {
- &dev_attr_l3_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_2 = {
- .name = "2f8e32e4-5956-46e2-af31-c8ea95887332",
- .attrs = attrs_l3_2,
-};
-
-static ssize_t
-show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3);
-}
-
-static struct device_attribute dev_attr_l3_3_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_3_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_3[] = {
- &dev_attr_l3_3_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_3 = {
- .name = "ca046aad-b5fb-4101-adce-6473ee6e5b14",
- .attrs = attrs_l3_3,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "605f388f-24bb-455c-88e3-8d57ae0d7e9f",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER);
-}
-
-static struct device_attribute dev_attr_sampler_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler[] = {
- &dev_attr_sampler_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler = {
- .name = "31dd157c-bf4e-4bab-bf2b-f5c8174af1af",
- .attrs = attrs_sampler,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "105db928-5542-466b-9128-e1f3c91426cb",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "03db94d2-b37f-4c58-a791-0d2067b013bb",
- .attrs = attrs_tdl_2,
-};
-
-static ssize_t
-show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA);
-}
-
-static struct device_attribute dev_attr_compute_extra_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extra_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extra[] = {
- &dev_attr_compute_extra_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extra = {
- .name = "aa7a3fb9-22fb-43ff-a32d-0ab6c13bbd16",
- .attrs = attrs_compute_extra,
-};
-
-static ssize_t
-show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE);
-}
-
-static struct device_attribute dev_attr_vme_pipe_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_vme_pipe_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_vme_pipe[] = {
- &dev_attr_vme_pipe_id.attr,
- NULL,
-};
-
-static struct attribute_group group_vme_pipe = {
- .name = "398a4268-ef6f-4ffc-b55f-3c7b5363ce61",
- .attrs = attrs_vme_pipe,
-};
-
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "baa3c7e4-52b6-4b85-801e-465a94b746dd",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_kblgt2(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_kblgt2(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "baa3c7e4-52b6-4b85-801e-465a94b746dd",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (ret)
- goto error_compute_l3_cache;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (ret)
- goto error_l3_2;
- }
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (ret)
- goto error_l3_3;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (ret)
- goto error_sampler;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (ret)
- goto error_compute_extra;
- }
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (ret)
- goto error_vme_pipe;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
-error_vme_pipe:
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
-error_compute_extra:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
-error_sampler:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
-error_l3_3:
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
-error_l3_2:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
-error_compute_l3_cache:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_kblgt2(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "baa3c7e4-52b6-4b85-801e-465a94b746dd";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt2.h b/drivers/gpu/drm/i915/i915_oa_kblgt2.h
index 7e61bfc4f9f5..25b803546dc1 100644
--- a/drivers/gpu/drm/i915/i915_oa_kblgt2.h
+++ b/drivers/gpu/drm/i915/i915_oa_kblgt2.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_KBLGT2_H__
#define __I915_OA_KBLGT2_H__
-extern int i915_oa_n_builtin_metric_sets_kblgt2;
-
-extern int i915_oa_select_metric_set_kblgt2(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_kblgt2(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_kblgt2(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_kblgt2(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt3.c b/drivers/gpu/drm/i915/i915_oa_kblgt3.c
index 6ed092566a32..5576afdd9a7e 100644
--- a/drivers/gpu/drm/i915/i915_oa_kblgt3.c
+++ b/drivers/gpu/drm/i915/i915_oa_kblgt3.c
@@ -31,1877 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_kblgt3.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_COMPUTE_L3_CACHE,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_L3_2,
- METRIC_SET_ID_L3_3,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_COMPUTE_EXTRA,
- METRIC_SET_ID_VME_PIPE,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_kblgt3 = 18;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic[] = {
- { _MMIO(0x9888), 0x166c01e0 },
- { _MMIO(0x9888), 0x12170280 },
- { _MMIO(0x9888), 0x12370280 },
- { _MMIO(0x9888), 0x16ec01e0 },
- { _MMIO(0x9888), 0x11930317 },
- { _MMIO(0x9888), 0x159303df },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x1a4e0380 },
- { _MMIO(0x9888), 0x0a6c0053 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x0a1b4000 },
- { _MMIO(0x9888), 0x1c1c0001 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x042f1000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c8400 },
- { _MMIO(0x9888), 0x0c4c0002 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f6600 },
- { _MMIO(0x9888), 0x100f0001 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x162ca200 },
- { _MMIO(0x9888), 0x062d8000 },
- { _MMIO(0x9888), 0x082d8000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x08133000 },
- { _MMIO(0x9888), 0x00170020 },
- { _MMIO(0x9888), 0x08170021 },
- { _MMIO(0x9888), 0x10170000 },
- { _MMIO(0x9888), 0x0633c000 },
- { _MMIO(0x9888), 0x0833c000 },
- { _MMIO(0x9888), 0x06370800 },
- { _MMIO(0x9888), 0x08370840 },
- { _MMIO(0x9888), 0x10370000 },
- { _MMIO(0x9888), 0x1ace0200 },
- { _MMIO(0x9888), 0x0aec5300 },
- { _MMIO(0x9888), 0x10ec0000 },
- { _MMIO(0x9888), 0x1cec0000 },
- { _MMIO(0x9888), 0x0a9b8000 },
- { _MMIO(0x9888), 0x1c9c0002 },
- { _MMIO(0x9888), 0x0ccc0002 },
- { _MMIO(0x9888), 0x0a8d8000 },
- { _MMIO(0x9888), 0x108f0001 },
- { _MMIO(0x9888), 0x16ac8000 },
- { _MMIO(0x9888), 0x0d933031 },
- { _MMIO(0x9888), 0x0f933e3f },
- { _MMIO(0x9888), 0x01933d00 },
- { _MMIO(0x9888), 0x0393073c },
- { _MMIO(0x9888), 0x0593000e },
- { _MMIO(0x9888), 0x1d930000 },
- { _MMIO(0x9888), 0x19930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x2f908000 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x15908000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190003f },
- { _MMIO(0x9888), 0x51902240 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x55900242 },
- { _MMIO(0x9888), 0x45900084 },
- { _MMIO(0x9888), 0x47901400 },
- { _MMIO(0x9888), 0x57902220 },
- { _MMIO(0x9888), 0x49900c60 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900002 },
- { _MMIO(0x9888), 0x43900c63 },
- { _MMIO(0x9888), 0x53902222 },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_basic;
- lens[n] = ARRAY_SIZE(mux_config_render_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x124f1c00 },
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x1a4e0820 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x064f0900 },
- { _MMIO(0x9888), 0x084f0032 },
- { _MMIO(0x9888), 0x0a4f1891 },
- { _MMIO(0x9888), 0x0c4f0e00 },
- { _MMIO(0x9888), 0x0e4f003c },
- { _MMIO(0x9888), 0x004f0d80 },
- { _MMIO(0x9888), 0x024f003b },
- { _MMIO(0x9888), 0x006c0002 },
- { _MMIO(0x9888), 0x086c0100 },
- { _MMIO(0x9888), 0x0c6c000c },
- { _MMIO(0x9888), 0x0e6c0b00 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x081b8000 },
- { _MMIO(0x9888), 0x0c1b4000 },
- { _MMIO(0x9888), 0x0e1b8000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1c8000 },
- { _MMIO(0x9888), 0x1c1c0024 },
- { _MMIO(0x9888), 0x065b8000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5bc000 },
- { _MMIO(0x9888), 0x0c5b8000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x1a5c6000 },
- { _MMIO(0x9888), 0x1c5c001b },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2000 },
- { _MMIO(0x9888), 0x0c4c0208 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020d2000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2cc000 },
- { _MMIO(0x9888), 0x162cfb00 },
- { _MMIO(0x9888), 0x182c00be },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x19900157 },
- { _MMIO(0x9888), 0x1b900158 },
- { _MMIO(0x9888), 0x1d900105 },
- { _MMIO(0x9888), 0x1f900103 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x11900fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900821 },
- { _MMIO(0x9888), 0x47900802 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900802 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900002 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900422 },
- { _MMIO(0x9888), 0x53904444 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_basic;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile[] = {
- { _MMIO(0x9888), 0x0c0e001f },
- { _MMIO(0x9888), 0x0a0f0000 },
- { _MMIO(0x9888), 0x10116800 },
- { _MMIO(0x9888), 0x178a03e0 },
- { _MMIO(0x9888), 0x11824c00 },
- { _MMIO(0x9888), 0x11830020 },
- { _MMIO(0x9888), 0x13840020 },
- { _MMIO(0x9888), 0x11850019 },
- { _MMIO(0x9888), 0x11860007 },
- { _MMIO(0x9888), 0x01870c40 },
- { _MMIO(0x9888), 0x17880000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0a4c0040 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x040d4000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020e5400 },
- { _MMIO(0x9888), 0x000e0000 },
- { _MMIO(0x9888), 0x080f0040 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x100f0000 },
- { _MMIO(0x9888), 0x0e0f0040 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06110012 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x01898000 },
- { _MMIO(0x9888), 0x0d890100 },
- { _MMIO(0x9888), 0x03898000 },
- { _MMIO(0x9888), 0x09808000 },
- { _MMIO(0x9888), 0x0b808000 },
- { _MMIO(0x9888), 0x0380c000 },
- { _MMIO(0x9888), 0x0f8a0075 },
- { _MMIO(0x9888), 0x1d8a0000 },
- { _MMIO(0x9888), 0x118a8000 },
- { _MMIO(0x9888), 0x1b8a4000 },
- { _MMIO(0x9888), 0x138a8000 },
- { _MMIO(0x9888), 0x1d81a000 },
- { _MMIO(0x9888), 0x15818000 },
- { _MMIO(0x9888), 0x17818000 },
- { _MMIO(0x9888), 0x0b820030 },
- { _MMIO(0x9888), 0x07828000 },
- { _MMIO(0x9888), 0x0d824000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x05824000 },
- { _MMIO(0x9888), 0x0d830003 },
- { _MMIO(0x9888), 0x0583000c },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x03838000 },
- { _MMIO(0x9888), 0x07838000 },
- { _MMIO(0x9888), 0x0b840980 },
- { _MMIO(0x9888), 0x03844d80 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x09848000 },
- { _MMIO(0x9888), 0x09850080 },
- { _MMIO(0x9888), 0x03850003 },
- { _MMIO(0x9888), 0x01850000 },
- { _MMIO(0x9888), 0x07860000 },
- { _MMIO(0x9888), 0x0f860400 },
- { _MMIO(0x9888), 0x09870032 },
- { _MMIO(0x9888), 0x01888052 },
- { _MMIO(0x9888), 0x11880000 },
- { _MMIO(0x9888), 0x09884000 },
- { _MMIO(0x9888), 0x1b931001 },
- { _MMIO(0x9888), 0x1d930001 },
- { _MMIO(0x9888), 0x19934000 },
- { _MMIO(0x9888), 0x1b958000 },
- { _MMIO(0x9888), 0x1d950094 },
- { _MMIO(0x9888), 0x19958000 },
- { _MMIO(0x9888), 0x09e58000 },
- { _MMIO(0x9888), 0x0be58000 },
- { _MMIO(0x9888), 0x03e5c000 },
- { _MMIO(0x9888), 0x0592c000 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d924000 },
- { _MMIO(0x9888), 0x0f924000 },
- { _MMIO(0x9888), 0x11928000 },
- { _MMIO(0x9888), 0x1392c000 },
- { _MMIO(0x9888), 0x09924000 },
- { _MMIO(0x9888), 0x01985000 },
- { _MMIO(0x9888), 0x07988000 },
- { _MMIO(0x9888), 0x09981000 },
- { _MMIO(0x9888), 0x0b982000 },
- { _MMIO(0x9888), 0x0d982000 },
- { _MMIO(0x9888), 0x0f989000 },
- { _MMIO(0x9888), 0x05982000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1190c080 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900440 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900400 },
- { _MMIO(0x9888), 0x47900c21 },
- { _MMIO(0x9888), 0x57900400 },
- { _MMIO(0x9888), 0x49900042 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900024 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900841 },
- { _MMIO(0x9888), 0x53900400 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_pipe_profile;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900064 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900150 },
- { _MMIO(0x9888), 0x21900151 },
- { _MMIO(0x9888), 0x23900152 },
- { _MMIO(0x9888), 0x25900153 },
- { _MMIO(0x9888), 0x27900154 },
- { _MMIO(0x9888), 0x29900155 },
- { _MMIO(0x9888), 0x2b900156 },
- { _MMIO(0x9888), 0x2d900157 },
- { _MMIO(0x9888), 0x2f90015f },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_reads;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901000 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900160 },
- { _MMIO(0x9888), 0x21900161 },
- { _MMIO(0x9888), 0x23900162 },
- { _MMIO(0x9888), 0x25900163 },
- { _MMIO(0x9888), 0x27900164 },
- { _MMIO(0x9888), 0x29900165 },
- { _MMIO(0x9888), 0x2b900166 },
- { _MMIO(0x9888), 0x2d900167 },
- { _MMIO(0x9888), 0x2f900150 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_writes;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fc2a },
- { _MMIO(0x2774), 0x0000bf00 },
- { _MMIO(0x2778), 0x0007fc6a },
- { _MMIO(0x277c), 0x0000bf00 },
- { _MMIO(0x2780), 0x0007fc92 },
- { _MMIO(0x2784), 0x0000bf00 },
- { _MMIO(0x2788), 0x0007fca2 },
- { _MMIO(0x278c), 0x0000bf00 },
- { _MMIO(0x2790), 0x0007fc32 },
- { _MMIO(0x2794), 0x0000bf00 },
- { _MMIO(0x2798), 0x0007fc9a },
- { _MMIO(0x279c), 0x0000bf00 },
- { _MMIO(0x27a0), 0x0007fe6a },
- { _MMIO(0x27a4), 0x0000bf00 },
- { _MMIO(0x27a8), 0x0007fe7a },
- { _MMIO(0x27ac), 0x0000bf00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended[] = {
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x141c8160 },
- { _MMIO(0x9888), 0x161c8015 },
- { _MMIO(0x9888), 0x181c0120 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4eaaa0 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0e6c0b01 },
- { _MMIO(0x9888), 0x006c0200 },
- { _MMIO(0x9888), 0x026c000c },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x001c0041 },
- { _MMIO(0x9888), 0x061c4200 },
- { _MMIO(0x9888), 0x081c4443 },
- { _MMIO(0x9888), 0x0a1c4645 },
- { _MMIO(0x9888), 0x0c1c7647 },
- { _MMIO(0x9888), 0x041c7357 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x101c0000 },
- { _MMIO(0x9888), 0x1a1c0000 },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4caa2a },
- { _MMIO(0x9888), 0x0c4c02aa },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5515 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x11907fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900040 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900802 },
- { _MMIO(0x9888), 0x47900842 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900842 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900800 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extended;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fffa },
- { _MMIO(0x2774), 0x0000fefe },
- { _MMIO(0x2778), 0x0007fffa },
- { _MMIO(0x277c), 0x0000fefd },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000fbef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000fbdf },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00101100 },
- { _MMIO(0xe45c), 0x00201200 },
- { _MMIO(0xe55c), 0x00301300 },
- { _MMIO(0xe65c), 0x00401400 },
-};
-
-static const struct i915_oa_reg mux_config_compute_l3_cache[] = {
- { _MMIO(0x9888), 0x166c0760 },
- { _MMIO(0x9888), 0x1593001e },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4e8020 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x006c0051 },
- { _MMIO(0x9888), 0x066c5000 },
- { _MMIO(0x9888), 0x086c5c5d },
- { _MMIO(0x9888), 0x0e6c5e5f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x061b8000 },
- { _MMIO(0x9888), 0x081bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1ce000 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2a00 },
- { _MMIO(0x9888), 0x0c4c0280 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f1500 },
- { _MMIO(0x9888), 0x100f0140 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162c0a00 },
- { _MMIO(0x9888), 0x182c00a0 },
- { _MMIO(0x9888), 0x03933300 },
- { _MMIO(0x9888), 0x05930032 },
- { _MMIO(0x9888), 0x11930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190030f },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900021 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x53904444 },
- { _MMIO(0x9888), 0x43900000 },
-};
-
-static int
-get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_l3_cache;
- lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x104f0232 },
- { _MMIO(0x9888), 0x124f4640 },
- { _MMIO(0x9888), 0x106c0232 },
- { _MMIO(0x9888), 0x11834400 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x004f1880 },
- { _MMIO(0x9888), 0x024f08bb },
- { _MMIO(0x9888), 0x044f001b },
- { _MMIO(0x9888), 0x046c0100 },
- { _MMIO(0x9888), 0x066c000b },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x041b8000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025bc000 },
- { _MMIO(0x9888), 0x045b4000 },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x165c8000 },
- { _MMIO(0x9888), 0x185c8000 },
- { _MMIO(0x9888), 0x0a4c00a0 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x062cc000 },
- { _MMIO(0x9888), 0x082cc000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x0f8305c0 },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x07830000 },
- { _MMIO(0x9888), 0x1d950080 },
- { _MMIO(0x9888), 0x13928000 },
- { _MMIO(0x9888), 0x0f988000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b900040 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1[] = {
- { _MMIO(0x9888), 0x126c7b40 },
- { _MMIO(0x9888), 0x166c0020 },
- { _MMIO(0x9888), 0x0a603444 },
- { _MMIO(0x9888), 0x0a613400 },
- { _MMIO(0x9888), 0x1a4ea800 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x0c6c5327 },
- { _MMIO(0x9888), 0x0e6c5425 },
- { _MMIO(0x9888), 0x006c2a00 },
- { _MMIO(0x9888), 0x026c285b },
- { _MMIO(0x9888), 0x046c005c },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0800 },
- { _MMIO(0x9888), 0x0c1bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x1c1c003c },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x10600000 },
- { _MMIO(0x9888), 0x04600000 },
- { _MMIO(0x9888), 0x0c610044 },
- { _MMIO(0x9888), 0x10610000 },
- { _MMIO(0x9888), 0x06610000 },
- { _MMIO(0x9888), 0x0c4c02a8 },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0154 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190ffc0 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900420 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900021 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900400 },
- { _MMIO(0x9888), 0x43900421 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_1;
- lens[n] = ARRAY_SIZE(mux_config_l3_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_2[] = {
- { _MMIO(0x9888), 0x126c02e0 },
- { _MMIO(0x9888), 0x146c0001 },
- { _MMIO(0x9888), 0x0a623400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x026c3324 },
- { _MMIO(0x9888), 0x046c3422 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x06614000 },
- { _MMIO(0x9888), 0x0c620044 },
- { _MMIO(0x9888), 0x10620000 },
- { _MMIO(0x9888), 0x06620000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_2;
- lens[n] = ARRAY_SIZE(mux_config_l3_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_3[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_3[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_3[] = {
- { _MMIO(0x9888), 0x126c4e80 },
- { _MMIO(0x9888), 0x146c0000 },
- { _MMIO(0x9888), 0x0a633400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x026c3321 },
- { _MMIO(0x9888), 0x046c342f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c2000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x06604000 },
- { _MMIO(0x9888), 0x0c630044 },
- { _MMIO(0x9888), 0x10630000 },
- { _MMIO(0x9888), 0x06630000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c00aa },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900002 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_3_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_3;
- lens[n] = ARRAY_SIZE(mux_config_l3_3);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000efff },
- { _MMIO(0x2778), 0x00006000 },
- { _MMIO(0x277c), 0x0000f3ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x102f3800 },
- { _MMIO(0x9888), 0x144d0500 },
- { _MMIO(0x9888), 0x120d03c0 },
- { _MMIO(0x9888), 0x140d03cf },
- { _MMIO(0x9888), 0x0c0f0004 },
- { _MMIO(0x9888), 0x0c4e4000 },
- { _MMIO(0x9888), 0x042f0480 },
- { _MMIO(0x9888), 0x082f0000 },
- { _MMIO(0x9888), 0x022f0000 },
- { _MMIO(0x9888), 0x0a4c0090 },
- { _MMIO(0x9888), 0x064d0027 },
- { _MMIO(0x9888), 0x004d0000 },
- { _MMIO(0x9888), 0x000d0d40 },
- { _MMIO(0x9888), 0x020d803f },
- { _MMIO(0x9888), 0x040d8023 },
- { _MMIO(0x9888), 0x100d0000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020f0010 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x0e0f0050 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41901400 },
- { _MMIO(0x9888), 0x43901485 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler[] = {
- { _MMIO(0x9888), 0x14152c00 },
- { _MMIO(0x9888), 0x16150005 },
- { _MMIO(0x9888), 0x121600a0 },
- { _MMIO(0x9888), 0x14352c00 },
- { _MMIO(0x9888), 0x16350005 },
- { _MMIO(0x9888), 0x123600a0 },
- { _MMIO(0x9888), 0x14552c00 },
- { _MMIO(0x9888), 0x16550005 },
- { _MMIO(0x9888), 0x125600a0 },
- { _MMIO(0x9888), 0x062f6000 },
- { _MMIO(0x9888), 0x022f2000 },
- { _MMIO(0x9888), 0x0c4c0050 },
- { _MMIO(0x9888), 0x0a4c0010 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0350 },
- { _MMIO(0x9888), 0x0c0fb000 },
- { _MMIO(0x9888), 0x0e0f00da },
- { _MMIO(0x9888), 0x182c0028 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x022dc000 },
- { _MMIO(0x9888), 0x042d4000 },
- { _MMIO(0x9888), 0x0c138000 },
- { _MMIO(0x9888), 0x0e132000 },
- { _MMIO(0x9888), 0x0413c000 },
- { _MMIO(0x9888), 0x1c140018 },
- { _MMIO(0x9888), 0x0c157000 },
- { _MMIO(0x9888), 0x0e150078 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x04162180 },
- { _MMIO(0x9888), 0x02160000 },
- { _MMIO(0x9888), 0x04174000 },
- { _MMIO(0x9888), 0x0233a000 },
- { _MMIO(0x9888), 0x04333000 },
- { _MMIO(0x9888), 0x14348000 },
- { _MMIO(0x9888), 0x16348000 },
- { _MMIO(0x9888), 0x02357870 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x04360043 },
- { _MMIO(0x9888), 0x02360000 },
- { _MMIO(0x9888), 0x04371000 },
- { _MMIO(0x9888), 0x0e538000 },
- { _MMIO(0x9888), 0x00538000 },
- { _MMIO(0x9888), 0x06533000 },
- { _MMIO(0x9888), 0x1c540020 },
- { _MMIO(0x9888), 0x12548000 },
- { _MMIO(0x9888), 0x0e557000 },
- { _MMIO(0x9888), 0x00557800 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x06560043 },
- { _MMIO(0x9888), 0x02560000 },
- { _MMIO(0x9888), 0x06571000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900060 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900060 },
-};
-
-static int
-get_sampler_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler;
- lens[n] = ARRAY_SIZE(mux_config_sampler);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x00007fff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x00009fff },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000efff },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000f3ff },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fdff },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x12120000 },
- { _MMIO(0x9888), 0x12320000 },
- { _MMIO(0x9888), 0x12520000 },
- { _MMIO(0x9888), 0x002f8000 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0015 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f03a0 },
- { _MMIO(0x9888), 0x0c0ff000 },
- { _MMIO(0x9888), 0x0e0f0095 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2d8000 },
- { _MMIO(0x9888), 0x0e2d4000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x02108000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x02118000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x02121880 },
- { _MMIO(0x9888), 0x041219b5 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x02134000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x0c308000 },
- { _MMIO(0x9888), 0x0e304000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x0c318000 },
- { _MMIO(0x9888), 0x0e314000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x0c321a80 },
- { _MMIO(0x9888), 0x0e320033 },
- { _MMIO(0x9888), 0x06320031 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x0c334000 },
- { _MMIO(0x9888), 0x0e331000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0e508000 },
- { _MMIO(0x9888), 0x00508000 },
- { _MMIO(0x9888), 0x02504000 },
- { _MMIO(0x9888), 0x0e518000 },
- { _MMIO(0x9888), 0x00518000 },
- { _MMIO(0x9888), 0x02514000 },
- { _MMIO(0x9888), 0x0e521880 },
- { _MMIO(0x9888), 0x00521a80 },
- { _MMIO(0x9888), 0x02520033 },
- { _MMIO(0x9888), 0x0e534000 },
- { _MMIO(0x9888), 0x00534000 },
- { _MMIO(0x9888), 0x02531000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900062 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x12124d60 },
- { _MMIO(0x9888), 0x12322e60 },
- { _MMIO(0x9888), 0x12524d60 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0014 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0fe000 },
- { _MMIO(0x9888), 0x0e0f0097 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x002d8000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x04121fb7 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x00308000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x00318000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x00321b80 },
- { _MMIO(0x9888), 0x0632003f },
- { _MMIO(0x9888), 0x00334000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0250c000 },
- { _MMIO(0x9888), 0x0251c000 },
- { _MMIO(0x9888), 0x02521fb7 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x02535000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900063 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extra[] = {
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extra[] = {
-};
-
-static const struct i915_oa_reg mux_config_compute_extra[] = {
- { _MMIO(0x9888), 0x121203e0 },
- { _MMIO(0x9888), 0x123203e0 },
- { _MMIO(0x9888), 0x125203e0 },
- { _MMIO(0x9888), 0x129203e0 },
- { _MMIO(0x9888), 0x12b203e0 },
- { _MMIO(0x9888), 0x12d203e0 },
- { _MMIO(0x9888), 0x024ec000 },
- { _MMIO(0x9888), 0x044ec000 },
- { _MMIO(0x9888), 0x064ec000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x0a4c0042 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f006d },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x042d8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06114000 },
- { _MMIO(0x9888), 0x06120033 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x04308000 },
- { _MMIO(0x9888), 0x04318000 },
- { _MMIO(0x9888), 0x04321980 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x04334000 },
- { _MMIO(0x9888), 0x04504000 },
- { _MMIO(0x9888), 0x04514000 },
- { _MMIO(0x9888), 0x04520033 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x04531000 },
- { _MMIO(0x9888), 0x00af8000 },
- { _MMIO(0x9888), 0x0acc0001 },
- { _MMIO(0x9888), 0x008d8000 },
- { _MMIO(0x9888), 0x028da000 },
- { _MMIO(0x9888), 0x0c8fb000 },
- { _MMIO(0x9888), 0x0e8f0001 },
- { _MMIO(0x9888), 0x06ac8000 },
- { _MMIO(0x9888), 0x02ad4000 },
- { _MMIO(0x9888), 0x02908000 },
- { _MMIO(0x9888), 0x02918000 },
- { _MMIO(0x9888), 0x02921980 },
- { _MMIO(0x9888), 0x00920000 },
- { _MMIO(0x9888), 0x02934000 },
- { _MMIO(0x9888), 0x02b04000 },
- { _MMIO(0x9888), 0x02b14000 },
- { _MMIO(0x9888), 0x02b20033 },
- { _MMIO(0x9888), 0x00b20000 },
- { _MMIO(0x9888), 0x02b31000 },
- { _MMIO(0x9888), 0x00d08000 },
- { _MMIO(0x9888), 0x00d18000 },
- { _MMIO(0x9888), 0x00d21980 },
- { _MMIO(0x9888), 0x00d34000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900002 },
- { _MMIO(0x9888), 0x53900420 },
- { _MMIO(0x9888), 0x459000a1 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_compute_extra_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extra;
- lens[n] = ARRAY_SIZE(mux_config_compute_extra);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_vme_pipe[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00100030 },
- { _MMIO(0x2774), 0x0000fff9 },
- { _MMIO(0x2778), 0x00000002 },
- { _MMIO(0x277c), 0x0000fffc },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000fff3 },
- { _MMIO(0x2788), 0x00100180 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000ffcf },
- { _MMIO(0x2798), 0x00000002 },
- { _MMIO(0x279c), 0x0000ff3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_vme_pipe[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00008003 },
-};
-
-static const struct i915_oa_reg mux_config_vme_pipe[] = {
- { _MMIO(0x9888), 0x141a5800 },
- { _MMIO(0x9888), 0x161a00c0 },
- { _MMIO(0x9888), 0x12180240 },
- { _MMIO(0x9888), 0x14180002 },
- { _MMIO(0x9888), 0x149a5800 },
- { _MMIO(0x9888), 0x169a00c0 },
- { _MMIO(0x9888), 0x12980240 },
- { _MMIO(0x9888), 0x14980002 },
- { _MMIO(0x9888), 0x1a4e3fc0 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x022f8000 },
- { _MMIO(0x9888), 0x042f3000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c9500 },
- { _MMIO(0x9888), 0x0c4c002a },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0015 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x182c000a },
- { _MMIO(0x9888), 0x04193000 },
- { _MMIO(0x9888), 0x081a28c1 },
- { _MMIO(0x9888), 0x001a0000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x0613c000 },
- { _MMIO(0x9888), 0x0813f000 },
- { _MMIO(0x9888), 0x00172000 },
- { _MMIO(0x9888), 0x06178000 },
- { _MMIO(0x9888), 0x0817a000 },
- { _MMIO(0x9888), 0x00180037 },
- { _MMIO(0x9888), 0x06180940 },
- { _MMIO(0x9888), 0x08180000 },
- { _MMIO(0x9888), 0x02180000 },
- { _MMIO(0x9888), 0x04183000 },
- { _MMIO(0x9888), 0x04afc000 },
- { _MMIO(0x9888), 0x06af3000 },
- { _MMIO(0x9888), 0x0acc4000 },
- { _MMIO(0x9888), 0x0ccc0015 },
- { _MMIO(0x9888), 0x0a8da000 },
- { _MMIO(0x9888), 0x0c8da000 },
- { _MMIO(0x9888), 0x0e8f4000 },
- { _MMIO(0x9888), 0x108f0015 },
- { _MMIO(0x9888), 0x16aca000 },
- { _MMIO(0x9888), 0x18ac000a },
- { _MMIO(0x9888), 0x06993000 },
- { _MMIO(0x9888), 0x0c9a28c1 },
- { _MMIO(0x9888), 0x009a0000 },
- { _MMIO(0x9888), 0x0a93f000 },
- { _MMIO(0x9888), 0x0c93f000 },
- { _MMIO(0x9888), 0x0a97a000 },
- { _MMIO(0x9888), 0x0c97a000 },
- { _MMIO(0x9888), 0x0a980977 },
- { _MMIO(0x9888), 0x08980000 },
- { _MMIO(0x9888), 0x04980000 },
- { _MMIO(0x9888), 0x06983000 },
- { _MMIO(0x9888), 0x119000ff },
- { _MMIO(0x9888), 0x51900040 },
- { _MMIO(0x9888), 0x41900020 },
- { _MMIO(0x9888), 0x55900004 },
- { _MMIO(0x9888), 0x45900400 },
- { _MMIO(0x9888), 0x479008a5 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900002 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_vme_pipe_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_vme_pipe;
- lens[n] = ARRAY_SIZE(mux_config_vme_pipe);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2744), 0x00800000 },
@@ -1931,6 +60,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x00000080 },
{ _MMIO(0x9888), 0x11810000 },
{ _MMIO(0x9888), 0x07810013 },
{ _MMIO(0x9888), 0x1f810000 },
@@ -1945,1096 +75,35 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x33900000 },
};
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_kblgt3(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_L3_CACHE:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_l3_cache_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_l3_cache;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_l3_cache);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_l3_cache;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_l3_cache);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_L3_2:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_2);
-
- return 0;
- case METRIC_SET_ID_L3_3:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_3_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_3;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_3);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_3;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_3);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTRA:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extra_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extra;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extra);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extra;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extra);
-
- return 0;
- case METRIC_SET_ID_VME_PIPE:
- dev_priv->perf.oa.n_mux_configs =
- get_vme_pipe_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_vme_pipe;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_vme_pipe);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_vme_pipe;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_vme_pipe);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "0286c920-2f6d-493b-b22d-7a5280df43de",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "9823aaa1-b06f-40ce-884b-cd798c79f0c2",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "c7c735f3-ce58-45cf-aa04-30b183f1faff",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "96ec2219-040b-428a-856a-6bc03363a057",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "03372b64-4996-4d3b-aa18-790e75eeb9c2",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
-}
-
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "31b4ce5a-bd61-4c1f-bb5d-f2e731412150",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE);
-}
-
-static struct device_attribute dev_attr_compute_l3_cache_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_l3_cache_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_l3_cache[] = {
- &dev_attr_compute_l3_cache_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_l3_cache = {
- .name = "2ce0911a-27fc-4887-96f0-11084fa807c3",
- .attrs = attrs_compute_l3_cache,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "546c4c1d-99b8-42fb-a107-5aaabb5314a8",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "4e93d156-9b39-4268-8544-a8e0480806d7",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2);
-}
-
-static struct device_attribute dev_attr_l3_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_2[] = {
- &dev_attr_l3_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_2 = {
- .name = "de1bec86-ca92-4b43-89fa-147653221cc0",
- .attrs = attrs_l3_2,
-};
-
-static ssize_t
-show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3);
-}
-
-static struct device_attribute dev_attr_l3_3_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_3_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_3[] = {
- &dev_attr_l3_3_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_3 = {
- .name = "e63537bb-10be-4d4a-92c4-c6b0c65e02ef",
- .attrs = attrs_l3_3,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "7a03a9f8-ec5e-46bb-8b67-1f0ff1476281",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER);
-}
-
-static struct device_attribute dev_attr_sampler_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler[] = {
- &dev_attr_sampler_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler = {
- .name = "b25d2ebf-a6e0-4b29-96be-a9b010edeeda",
- .attrs = attrs_sampler,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "469a05e5-e299-46f7-9598-7b05f3c34991",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "52f925c6-786a-4ec6-86ce-cba85c83453a",
- .attrs = attrs_tdl_2,
-};
-
-static ssize_t
-show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA);
-}
-
-static struct device_attribute dev_attr_compute_extra_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extra_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extra[] = {
- &dev_attr_compute_extra_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extra = {
- .name = "efc497ac-884e-4ee4-a4a8-15fba22aaf21",
- .attrs = attrs_compute_extra,
-};
-
-static ssize_t
-show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE);
-}
-
-static struct device_attribute dev_attr_vme_pipe_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_vme_pipe_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_vme_pipe[] = {
- &dev_attr_vme_pipe_id.attr,
- NULL,
-};
-
-static struct attribute_group group_vme_pipe = {
- .name = "bfd9764d-2c5b-4c16-bfc1-89de3ca10917",
- .attrs = attrs_vme_pipe,
-};
-
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "f1792f32-6db2-4b50-b4b2-557128f1688d",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_kblgt3(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_kblgt3(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "f1792f32-6db2-4b50-b4b2-557128f1688d",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (ret)
- goto error_compute_l3_cache;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (ret)
- goto error_l3_2;
- }
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (ret)
- goto error_l3_3;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (ret)
- goto error_sampler;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (ret)
- goto error_compute_extra;
- }
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (ret)
- goto error_vme_pipe;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
-error_vme_pipe:
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
-error_compute_extra:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
-error_sampler:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
-error_l3_3:
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
-error_l3_2:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
-error_compute_l3_cache:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_kblgt3(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "f1792f32-6db2-4b50-b4b2-557128f1688d";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_kblgt3.h b/drivers/gpu/drm/i915/i915_oa_kblgt3.h
index b0ca7f3114d3..d5b5b5c1923e 100644
--- a/drivers/gpu/drm/i915/i915_oa_kblgt3.h
+++ b/drivers/gpu/drm/i915/i915_oa_kblgt3.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_KBLGT3_H__
#define __I915_OA_KBLGT3_H__
-extern int i915_oa_n_builtin_metric_sets_kblgt3;
-
-extern int i915_oa_select_metric_set_kblgt3(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_kblgt3(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_kblgt3(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_kblgt3(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt2.c b/drivers/gpu/drm/i915/i915_oa_sklgt2.c
index 1268beda212c..890d55879946 100644
--- a/drivers/gpu/drm/i915/i915_oa_sklgt2.c
+++ b/drivers/gpu/drm/i915/i915_oa_sklgt2.c
@@ -31,2317 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_sklgt2.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_COMPUTE_L3_CACHE,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_L3_2,
- METRIC_SET_ID_L3_3,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_COMPUTE_EXTRA,
- METRIC_SET_ID_VME_PIPE,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_sklgt2 = 18;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic_1_sku_gte_0x02[] = {
- { _MMIO(0x9888), 0x166c01e0 },
- { _MMIO(0x9888), 0x12170280 },
- { _MMIO(0x9888), 0x12370280 },
- { _MMIO(0x9888), 0x11930317 },
- { _MMIO(0x9888), 0x159303df },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x1a4e0080 },
- { _MMIO(0x9888), 0x0a6c0053 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x0a1b4000 },
- { _MMIO(0x9888), 0x1c1c0001 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x042f1000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c8400 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0d2000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f6600 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x162c2200 },
- { _MMIO(0x9888), 0x062d8000 },
- { _MMIO(0x9888), 0x082d8000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x08133000 },
- { _MMIO(0x9888), 0x00170020 },
- { _MMIO(0x9888), 0x08170021 },
- { _MMIO(0x9888), 0x10170000 },
- { _MMIO(0x9888), 0x0633c000 },
- { _MMIO(0x9888), 0x0833c000 },
- { _MMIO(0x9888), 0x06370800 },
- { _MMIO(0x9888), 0x08370840 },
- { _MMIO(0x9888), 0x10370000 },
- { _MMIO(0x9888), 0x0d933031 },
- { _MMIO(0x9888), 0x0f933e3f },
- { _MMIO(0x9888), 0x01933d00 },
- { _MMIO(0x9888), 0x0393073c },
- { _MMIO(0x9888), 0x0593000e },
- { _MMIO(0x9888), 0x1d930000 },
- { _MMIO(0x9888), 0x19930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x2f908000 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x15908000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190001f },
- { _MMIO(0x9888), 0x51904400 },
- { _MMIO(0x9888), 0x41900020 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c21 },
- { _MMIO(0x9888), 0x47900061 },
- { _MMIO(0x9888), 0x57904440 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900004 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x53904444 },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- if (dev_priv->drm.pdev->revision >= 0x02) {
- regs[n] = mux_config_render_basic_1_sku_gte_0x02;
- lens[n] = ARRAY_SIZE(mux_config_render_basic_1_sku_gte_0x02);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic_0_slices_0x01_and_sku_lt_0x02[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x124f1c00 },
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901403 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4e8200 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x004f0db2 },
- { _MMIO(0x9888), 0x064f0900 },
- { _MMIO(0x9888), 0x084f1880 },
- { _MMIO(0x9888), 0x0a4f0011 },
- { _MMIO(0x9888), 0x0c4f0e3c },
- { _MMIO(0x9888), 0x0e4f1d80 },
- { _MMIO(0x9888), 0x086c0002 },
- { _MMIO(0x9888), 0x0a6c0100 },
- { _MMIO(0x9888), 0x0e6c000c },
- { _MMIO(0x9888), 0x026c000b },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x081b4000 },
- { _MMIO(0x9888), 0x0a1b8000 },
- { _MMIO(0x9888), 0x0e1b4000 },
- { _MMIO(0x9888), 0x021b4000 },
- { _MMIO(0x9888), 0x1a1c4000 },
- { _MMIO(0x9888), 0x1c1c0012 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x005bc000 },
- { _MMIO(0x9888), 0x065b8000 },
- { _MMIO(0x9888), 0x085b8000 },
- { _MMIO(0x9888), 0x0a5b4000 },
- { _MMIO(0x9888), 0x0c5bc000 },
- { _MMIO(0x9888), 0x0e5b8000 },
- { _MMIO(0x9888), 0x105c8000 },
- { _MMIO(0x9888), 0x1a5ca000 },
- { _MMIO(0x9888), 0x1c5c002d },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x0a4c0800 },
- { _MMIO(0x9888), 0x0c4c0082 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020d2000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002cc000 },
- { _MMIO(0x9888), 0x0e2cc000 },
- { _MMIO(0x9888), 0x162cbe00 },
- { _MMIO(0x9888), 0x182c00ef },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x19900157 },
- { _MMIO(0x9888), 0x1b900167 },
- { _MMIO(0x9888), 0x1d900105 },
- { _MMIO(0x9888), 0x1f900103 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0xd28), 0x00000000 },
- { _MMIO(0x9888), 0x11900fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900840 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900842 },
- { _MMIO(0x9888), 0x47900840 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900840 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900040 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900840 },
- { _MMIO(0x9888), 0x53901111 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic_0_slices_0x01_and_sku_gte_0x02[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x124f1c00 },
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901403 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x1a4e0820 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x064f0900 },
- { _MMIO(0x9888), 0x084f0032 },
- { _MMIO(0x9888), 0x0a4f1810 },
- { _MMIO(0x9888), 0x0c4f0e00 },
- { _MMIO(0x9888), 0x0e4f003c },
- { _MMIO(0x9888), 0x004f0d80 },
- { _MMIO(0x9888), 0x024f003b },
- { _MMIO(0x9888), 0x006c0002 },
- { _MMIO(0x9888), 0x086c0000 },
- { _MMIO(0x9888), 0x0c6c000c },
- { _MMIO(0x9888), 0x0e6c0b00 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x081b8000 },
- { _MMIO(0x9888), 0x0c1b4000 },
- { _MMIO(0x9888), 0x0e1b8000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1c8000 },
- { _MMIO(0x9888), 0x1c1c0024 },
- { _MMIO(0x9888), 0x065b8000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5bc000 },
- { _MMIO(0x9888), 0x0c5b8000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x1a5c6000 },
- { _MMIO(0x9888), 0x1c5c001b },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2000 },
- { _MMIO(0x9888), 0x0c4c0208 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020d2000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2cc000 },
- { _MMIO(0x9888), 0x162cfb00 },
- { _MMIO(0x9888), 0x182c00be },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x19900157 },
- { _MMIO(0x9888), 0x1b900167 },
- { _MMIO(0x9888), 0x1d900105 },
- { _MMIO(0x9888), 0x1f900103 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x11900fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900842 },
- { _MMIO(0x9888), 0x47900802 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900802 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900002 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53901111 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 2);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 2);
-
- if ((INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) &&
- (dev_priv->drm.pdev->revision < 0x02)) {
- regs[n] = mux_config_compute_basic_0_slices_0x01_and_sku_lt_0x02;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic_0_slices_0x01_and_sku_lt_0x02);
- n++;
- }
- if ((INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) &&
- (dev_priv->drm.pdev->revision >= 0x02)) {
- regs[n] = mux_config_compute_basic_0_slices_0x01_and_sku_gte_0x02;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic_0_slices_0x01_and_sku_gte_0x02);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile_0_sku_lt_0x02[] = {
- { _MMIO(0x9888), 0x0c0e001f },
- { _MMIO(0x9888), 0x0a0f0000 },
- { _MMIO(0x9888), 0x10116800 },
- { _MMIO(0x9888), 0x178a03e0 },
- { _MMIO(0x9888), 0x11824c00 },
- { _MMIO(0x9888), 0x11830020 },
- { _MMIO(0x9888), 0x13840020 },
- { _MMIO(0x9888), 0x11850019 },
- { _MMIO(0x9888), 0x11860007 },
- { _MMIO(0x9888), 0x01870c40 },
- { _MMIO(0x9888), 0x17880000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0a4c0040 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x040d4000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020e5400 },
- { _MMIO(0x9888), 0x000e0000 },
- { _MMIO(0x9888), 0x080f0040 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x100f0000 },
- { _MMIO(0x9888), 0x0e0f0040 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06110012 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x01898000 },
- { _MMIO(0x9888), 0x0d890100 },
- { _MMIO(0x9888), 0x03898000 },
- { _MMIO(0x9888), 0x09808000 },
- { _MMIO(0x9888), 0x0b808000 },
- { _MMIO(0x9888), 0x0380c000 },
- { _MMIO(0x9888), 0x0f8a0075 },
- { _MMIO(0x9888), 0x1d8a0000 },
- { _MMIO(0x9888), 0x118a8000 },
- { _MMIO(0x9888), 0x1b8a4000 },
- { _MMIO(0x9888), 0x138a8000 },
- { _MMIO(0x9888), 0x1d81a000 },
- { _MMIO(0x9888), 0x15818000 },
- { _MMIO(0x9888), 0x17818000 },
- { _MMIO(0x9888), 0x0b820030 },
- { _MMIO(0x9888), 0x07828000 },
- { _MMIO(0x9888), 0x0d824000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x05824000 },
- { _MMIO(0x9888), 0x0d830003 },
- { _MMIO(0x9888), 0x0583000c },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x03838000 },
- { _MMIO(0x9888), 0x07838000 },
- { _MMIO(0x9888), 0x0b840980 },
- { _MMIO(0x9888), 0x03844d80 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x09848000 },
- { _MMIO(0x9888), 0x09850080 },
- { _MMIO(0x9888), 0x03850003 },
- { _MMIO(0x9888), 0x01850000 },
- { _MMIO(0x9888), 0x07860000 },
- { _MMIO(0x9888), 0x0f860400 },
- { _MMIO(0x9888), 0x09870032 },
- { _MMIO(0x9888), 0x01888052 },
- { _MMIO(0x9888), 0x11880000 },
- { _MMIO(0x9888), 0x09884000 },
- { _MMIO(0x9888), 0x15968000 },
- { _MMIO(0x9888), 0x17968000 },
- { _MMIO(0x9888), 0x0f96c000 },
- { _MMIO(0x9888), 0x1f950011 },
- { _MMIO(0x9888), 0x1d950014 },
- { _MMIO(0x9888), 0x0592c000 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d924000 },
- { _MMIO(0x9888), 0x0f924000 },
- { _MMIO(0x9888), 0x11928000 },
- { _MMIO(0x9888), 0x1392c000 },
- { _MMIO(0x9888), 0x09924000 },
- { _MMIO(0x9888), 0x01985000 },
- { _MMIO(0x9888), 0x07988000 },
- { _MMIO(0x9888), 0x09981000 },
- { _MMIO(0x9888), 0x0b982000 },
- { _MMIO(0x9888), 0x0d982000 },
- { _MMIO(0x9888), 0x0f989000 },
- { _MMIO(0x9888), 0x05982000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x0b978000 },
- { _MMIO(0x9888), 0x0f974000 },
- { _MMIO(0x9888), 0x11974000 },
- { _MMIO(0x9888), 0x13978000 },
- { _MMIO(0x9888), 0x09974000 },
- { _MMIO(0xd28), 0x00000000 },
- { _MMIO(0x9888), 0x1190c080 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x419010a0 },
- { _MMIO(0x9888), 0x55904000 },
- { _MMIO(0x9888), 0x45901000 },
- { _MMIO(0x9888), 0x47900084 },
- { _MMIO(0x9888), 0x57904400 },
- { _MMIO(0x9888), 0x499000a5 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900081 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x439014a4 },
- { _MMIO(0x9888), 0x53900400 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile_0_sku_gte_0x02[] = {
- { _MMIO(0x9888), 0x0c0e001f },
- { _MMIO(0x9888), 0x0a0f0000 },
- { _MMIO(0x9888), 0x10116800 },
- { _MMIO(0x9888), 0x178a03e0 },
- { _MMIO(0x9888), 0x11824c00 },
- { _MMIO(0x9888), 0x11830020 },
- { _MMIO(0x9888), 0x13840020 },
- { _MMIO(0x9888), 0x11850019 },
- { _MMIO(0x9888), 0x11860007 },
- { _MMIO(0x9888), 0x01870c40 },
- { _MMIO(0x9888), 0x17880000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0a4c0040 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x040d4000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020e5400 },
- { _MMIO(0x9888), 0x000e0000 },
- { _MMIO(0x9888), 0x080f0040 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x100f0000 },
- { _MMIO(0x9888), 0x0e0f0040 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06110012 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x01898000 },
- { _MMIO(0x9888), 0x0d890100 },
- { _MMIO(0x9888), 0x03898000 },
- { _MMIO(0x9888), 0x09808000 },
- { _MMIO(0x9888), 0x0b808000 },
- { _MMIO(0x9888), 0x0380c000 },
- { _MMIO(0x9888), 0x0f8a0075 },
- { _MMIO(0x9888), 0x1d8a0000 },
- { _MMIO(0x9888), 0x118a8000 },
- { _MMIO(0x9888), 0x1b8a4000 },
- { _MMIO(0x9888), 0x138a8000 },
- { _MMIO(0x9888), 0x1d81a000 },
- { _MMIO(0x9888), 0x15818000 },
- { _MMIO(0x9888), 0x17818000 },
- { _MMIO(0x9888), 0x0b820030 },
- { _MMIO(0x9888), 0x07828000 },
- { _MMIO(0x9888), 0x0d824000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x05824000 },
- { _MMIO(0x9888), 0x0d830003 },
- { _MMIO(0x9888), 0x0583000c },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x03838000 },
- { _MMIO(0x9888), 0x07838000 },
- { _MMIO(0x9888), 0x0b840980 },
- { _MMIO(0x9888), 0x03844d80 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x09848000 },
- { _MMIO(0x9888), 0x09850080 },
- { _MMIO(0x9888), 0x03850003 },
- { _MMIO(0x9888), 0x01850000 },
- { _MMIO(0x9888), 0x07860000 },
- { _MMIO(0x9888), 0x0f860400 },
- { _MMIO(0x9888), 0x09870032 },
- { _MMIO(0x9888), 0x01888052 },
- { _MMIO(0x9888), 0x11880000 },
- { _MMIO(0x9888), 0x09884000 },
- { _MMIO(0x9888), 0x1b931001 },
- { _MMIO(0x9888), 0x1d930001 },
- { _MMIO(0x9888), 0x19934000 },
- { _MMIO(0x9888), 0x1b958000 },
- { _MMIO(0x9888), 0x1d950094 },
- { _MMIO(0x9888), 0x19958000 },
- { _MMIO(0x9888), 0x05e5a000 },
- { _MMIO(0x9888), 0x01e5c000 },
- { _MMIO(0x9888), 0x0592c000 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d924000 },
- { _MMIO(0x9888), 0x0f924000 },
- { _MMIO(0x9888), 0x11928000 },
- { _MMIO(0x9888), 0x1392c000 },
- { _MMIO(0x9888), 0x09924000 },
- { _MMIO(0x9888), 0x01985000 },
- { _MMIO(0x9888), 0x07988000 },
- { _MMIO(0x9888), 0x09981000 },
- { _MMIO(0x9888), 0x0b982000 },
- { _MMIO(0x9888), 0x0d982000 },
- { _MMIO(0x9888), 0x0f989000 },
- { _MMIO(0x9888), 0x05982000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1190c080 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x419010a0 },
- { _MMIO(0x9888), 0x55904000 },
- { _MMIO(0x9888), 0x45901000 },
- { _MMIO(0x9888), 0x47900084 },
- { _MMIO(0x9888), 0x57904400 },
- { _MMIO(0x9888), 0x499000a5 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900081 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x439014a4 },
- { _MMIO(0x9888), 0x53900400 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 2);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 2);
-
- if (dev_priv->drm.pdev->revision < 0x02) {
- regs[n] = mux_config_render_pipe_profile_0_sku_lt_0x02;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile_0_sku_lt_0x02);
- n++;
- }
- if (dev_priv->drm.pdev->revision >= 0x02) {
- regs[n] = mux_config_render_pipe_profile_0_sku_gte_0x02;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile_0_sku_gte_0x02);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads_0_slices_0x01_and_sku_lt_0x02[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x13946000 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x0f968000 },
- { _MMIO(0x9888), 0x1196c000 },
- { _MMIO(0x9888), 0x13964000 },
- { _MMIO(0x9888), 0x11938000 },
- { _MMIO(0x9888), 0x1b93fe00 },
- { _MMIO(0x9888), 0x01940010 },
- { _MMIO(0x9888), 0x07941100 },
- { _MMIO(0x9888), 0x09941312 },
- { _MMIO(0x9888), 0x0b941514 },
- { _MMIO(0x9888), 0x0d941716 },
- { _MMIO(0x9888), 0x11940000 },
- { _MMIO(0x9888), 0x19940000 },
- { _MMIO(0x9888), 0x1b940000 },
- { _MMIO(0x9888), 0x1d940000 },
- { _MMIO(0x9888), 0x1b954000 },
- { _MMIO(0x9888), 0x1d95a550 },
- { _MMIO(0x9888), 0x1f9502aa },
- { _MMIO(0x9888), 0x2f900157 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13908000 },
- { _MMIO(0x9888), 0x21908000 },
- { _MMIO(0x9888), 0x23908000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27908000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0xd28), 0x00000000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads_0_sku_lt_0x05_and_sku_gte_0x02[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x13946000 },
- { _MMIO(0x9888), 0x15940016 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x19930800 },
- { _MMIO(0x9888), 0x1b93aa55 },
- { _MMIO(0x9888), 0x1d9300aa },
- { _MMIO(0x9888), 0x01940010 },
- { _MMIO(0x9888), 0x07941100 },
- { _MMIO(0x9888), 0x09941312 },
- { _MMIO(0x9888), 0x0b941514 },
- { _MMIO(0x9888), 0x0d941716 },
- { _MMIO(0x9888), 0x0f940018 },
- { _MMIO(0x9888), 0x1b940000 },
- { _MMIO(0x9888), 0x11940000 },
- { _MMIO(0x9888), 0x01e58000 },
- { _MMIO(0x9888), 0x03e57000 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13908000 },
- { _MMIO(0x9888), 0x21908000 },
- { _MMIO(0x9888), 0x23908000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27908000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x2f908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c20 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900400 },
- { _MMIO(0x9888), 0x47900421 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900421 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900061 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads_0_sku_gte_0x05[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900064 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900150 },
- { _MMIO(0x9888), 0x21900151 },
- { _MMIO(0x9888), 0x23900152 },
- { _MMIO(0x9888), 0x25900153 },
- { _MMIO(0x9888), 0x27900154 },
- { _MMIO(0x9888), 0x29900155 },
- { _MMIO(0x9888), 0x2b900156 },
- { _MMIO(0x9888), 0x2d900157 },
- { _MMIO(0x9888), 0x2f90015f },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 3);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 3);
-
- if ((INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) &&
- (dev_priv->drm.pdev->revision < 0x02)) {
- regs[n] = mux_config_memory_reads_0_slices_0x01_and_sku_lt_0x02;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads_0_slices_0x01_and_sku_lt_0x02);
- n++;
- }
- if ((dev_priv->drm.pdev->revision < 0x05) &&
- (dev_priv->drm.pdev->revision >= 0x02)) {
- regs[n] = mux_config_memory_reads_0_sku_lt_0x05_and_sku_gte_0x02;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads_0_sku_lt_0x05_and_sku_gte_0x02);
- n++;
- }
- if (dev_priv->drm.pdev->revision >= 0x05) {
- regs[n] = mux_config_memory_reads_0_sku_gte_0x05;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads_0_sku_gte_0x05);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes_0_slices_0x01_and_sku_lt_0x02[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x13945400 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901400 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x0f968000 },
- { _MMIO(0x9888), 0x1196c000 },
- { _MMIO(0x9888), 0x13964000 },
- { _MMIO(0x9888), 0x11938000 },
- { _MMIO(0x9888), 0x1b93fe00 },
- { _MMIO(0x9888), 0x01940010 },
- { _MMIO(0x9888), 0x07941100 },
- { _MMIO(0x9888), 0x09941312 },
- { _MMIO(0x9888), 0x0b941514 },
- { _MMIO(0x9888), 0x0d941716 },
- { _MMIO(0x9888), 0x11940000 },
- { _MMIO(0x9888), 0x19940000 },
- { _MMIO(0x9888), 0x1b940000 },
- { _MMIO(0x9888), 0x1d940000 },
- { _MMIO(0x9888), 0x1b954000 },
- { _MMIO(0x9888), 0x1d95a550 },
- { _MMIO(0x9888), 0x1f9502aa },
- { _MMIO(0x9888), 0x2f900167 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13908000 },
- { _MMIO(0x9888), 0x21908000 },
- { _MMIO(0x9888), 0x23908000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27908000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0xd28), 0x00000000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes_0_sku_lt_0x05_and_sku_gte_0x02[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x13945400 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901400 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x19930800 },
- { _MMIO(0x9888), 0x1b93aa55 },
- { _MMIO(0x9888), 0x1d93002a },
- { _MMIO(0x9888), 0x01940010 },
- { _MMIO(0x9888), 0x07941100 },
- { _MMIO(0x9888), 0x09941312 },
- { _MMIO(0x9888), 0x0b941514 },
- { _MMIO(0x9888), 0x0d941716 },
- { _MMIO(0x9888), 0x1b940000 },
- { _MMIO(0x9888), 0x11940000 },
- { _MMIO(0x9888), 0x01e58000 },
- { _MMIO(0x9888), 0x03e57000 },
- { _MMIO(0x9888), 0x2f900167 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x13908000 },
- { _MMIO(0x9888), 0x21908000 },
- { _MMIO(0x9888), 0x23908000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27908000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c20 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900400 },
- { _MMIO(0x9888), 0x47900421 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900421 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes_0_sku_gte_0x05[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901000 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900160 },
- { _MMIO(0x9888), 0x21900161 },
- { _MMIO(0x9888), 0x23900162 },
- { _MMIO(0x9888), 0x25900163 },
- { _MMIO(0x9888), 0x27900164 },
- { _MMIO(0x9888), 0x29900165 },
- { _MMIO(0x9888), 0x2b900166 },
- { _MMIO(0x9888), 0x2d900167 },
- { _MMIO(0x9888), 0x2f900150 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 3);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 3);
-
- if ((INTEL_INFO(dev_priv)->sseu.slice_mask & 0x01) &&
- (dev_priv->drm.pdev->revision < 0x02)) {
- regs[n] = mux_config_memory_writes_0_slices_0x01_and_sku_lt_0x02;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes_0_slices_0x01_and_sku_lt_0x02);
- n++;
- }
- if ((dev_priv->drm.pdev->revision < 0x05) &&
- (dev_priv->drm.pdev->revision >= 0x02)) {
- regs[n] = mux_config_memory_writes_0_sku_lt_0x05_and_sku_gte_0x02;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes_0_sku_lt_0x05_and_sku_gte_0x02);
- n++;
- }
- if (dev_priv->drm.pdev->revision >= 0x05) {
- regs[n] = mux_config_memory_writes_0_sku_gte_0x05;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes_0_sku_gte_0x05);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fc2a },
- { _MMIO(0x2774), 0x0000bf00 },
- { _MMIO(0x2778), 0x0007fc6a },
- { _MMIO(0x277c), 0x0000bf00 },
- { _MMIO(0x2780), 0x0007fc92 },
- { _MMIO(0x2784), 0x0000bf00 },
- { _MMIO(0x2788), 0x0007fca2 },
- { _MMIO(0x278c), 0x0000bf00 },
- { _MMIO(0x2790), 0x0007fc32 },
- { _MMIO(0x2794), 0x0000bf00 },
- { _MMIO(0x2798), 0x0007fc9a },
- { _MMIO(0x279c), 0x0000bf00 },
- { _MMIO(0x27a0), 0x0007fe6a },
- { _MMIO(0x27a4), 0x0000bf00 },
- { _MMIO(0x27a8), 0x0007fe7a },
- { _MMIO(0x27ac), 0x0000bf00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended_0_subslices_0x01[] = {
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x141c8160 },
- { _MMIO(0x9888), 0x161c8015 },
- { _MMIO(0x9888), 0x181c0120 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4eaaa0 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0e6c0b01 },
- { _MMIO(0x9888), 0x006c0200 },
- { _MMIO(0x9888), 0x026c000c },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x001c0041 },
- { _MMIO(0x9888), 0x061c4200 },
- { _MMIO(0x9888), 0x081c4443 },
- { _MMIO(0x9888), 0x0a1c4645 },
- { _MMIO(0x9888), 0x0c1c7647 },
- { _MMIO(0x9888), 0x041c7357 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x101c0000 },
- { _MMIO(0x9888), 0x1a1c0000 },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4caa2a },
- { _MMIO(0x9888), 0x0c4c02aa },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5515 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0xd28), 0x00000000 },
- { _MMIO(0x9888), 0x11907fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900040 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900802 },
- { _MMIO(0x9888), 0x47900842 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900842 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900800 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- if (INTEL_INFO(dev_priv)->sseu.subslice_mask & 0x01) {
- regs[n] = mux_config_compute_extended_0_subslices_0x01;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended_0_subslices_0x01);
- n++;
- }
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fffa },
- { _MMIO(0x2774), 0x0000fefe },
- { _MMIO(0x2778), 0x0007fffa },
- { _MMIO(0x277c), 0x0000fefd },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000fbef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000fbdf },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00101100 },
- { _MMIO(0xe45c), 0x00201200 },
- { _MMIO(0xe55c), 0x00301300 },
- { _MMIO(0xe65c), 0x00401400 },
-};
-
-static const struct i915_oa_reg mux_config_compute_l3_cache[] = {
- { _MMIO(0x9888), 0x166c0760 },
- { _MMIO(0x9888), 0x1593001e },
- { _MMIO(0x9888), 0x3f901403 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4e8020 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x006c0051 },
- { _MMIO(0x9888), 0x066c5000 },
- { _MMIO(0x9888), 0x086c5c5d },
- { _MMIO(0x9888), 0x0e6c5e5f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x061b8000 },
- { _MMIO(0x9888), 0x081bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1ce000 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2a00 },
- { _MMIO(0x9888), 0x0c4c0280 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f1500 },
- { _MMIO(0x9888), 0x100f0140 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162c0a00 },
- { _MMIO(0x9888), 0x182c00a0 },
- { _MMIO(0x9888), 0x03933300 },
- { _MMIO(0x9888), 0x05930032 },
- { _MMIO(0x9888), 0x11930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900167 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190030f },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900042 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x53901111 },
- { _MMIO(0x9888), 0x43900420 },
-};
-
-static int
-get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_l3_cache;
- lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x104f0232 },
- { _MMIO(0x9888), 0x124f4640 },
- { _MMIO(0x9888), 0x106c0232 },
- { _MMIO(0x9888), 0x11834400 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x004f1880 },
- { _MMIO(0x9888), 0x024f08bb },
- { _MMIO(0x9888), 0x044f001b },
- { _MMIO(0x9888), 0x046c0100 },
- { _MMIO(0x9888), 0x066c000b },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x041b8000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025bc000 },
- { _MMIO(0x9888), 0x045b4000 },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x165c8000 },
- { _MMIO(0x9888), 0x185c8000 },
- { _MMIO(0x9888), 0x0a4c00a0 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x062cc000 },
- { _MMIO(0x9888), 0x082cc000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x0f8305c0 },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x07830000 },
- { _MMIO(0x9888), 0x1d950080 },
- { _MMIO(0x9888), 0x13928000 },
- { _MMIO(0x9888), 0x0f988000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x4b9000a0 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1[] = {
- { _MMIO(0x9888), 0x126c7b40 },
- { _MMIO(0x9888), 0x166c0020 },
- { _MMIO(0x9888), 0x0a603444 },
- { _MMIO(0x9888), 0x0a613400 },
- { _MMIO(0x9888), 0x1a4ea800 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x0c6c5327 },
- { _MMIO(0x9888), 0x0e6c5425 },
- { _MMIO(0x9888), 0x006c2a00 },
- { _MMIO(0x9888), 0x026c285b },
- { _MMIO(0x9888), 0x046c005c },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0800 },
- { _MMIO(0x9888), 0x0c1bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x1c1c003c },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x10600000 },
- { _MMIO(0x9888), 0x04600000 },
- { _MMIO(0x9888), 0x0c610044 },
- { _MMIO(0x9888), 0x10610000 },
- { _MMIO(0x9888), 0x06610000 },
- { _MMIO(0x9888), 0x0c4c02a8 },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0154 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190ffc0 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900420 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900021 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900400 },
- { _MMIO(0x9888), 0x43900421 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_1;
- lens[n] = ARRAY_SIZE(mux_config_l3_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_2[] = {
- { _MMIO(0x9888), 0x126c02e0 },
- { _MMIO(0x9888), 0x146c0001 },
- { _MMIO(0x9888), 0x0a623400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x026c3324 },
- { _MMIO(0x9888), 0x046c3422 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x06614000 },
- { _MMIO(0x9888), 0x0c620044 },
- { _MMIO(0x9888), 0x10620000 },
- { _MMIO(0x9888), 0x06620000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_2;
- lens[n] = ARRAY_SIZE(mux_config_l3_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_3[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_3[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_3[] = {
- { _MMIO(0x9888), 0x126c4e80 },
- { _MMIO(0x9888), 0x146c0000 },
- { _MMIO(0x9888), 0x0a633400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x026c3321 },
- { _MMIO(0x9888), 0x046c342f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c2000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x06604000 },
- { _MMIO(0x9888), 0x0c630044 },
- { _MMIO(0x9888), 0x10630000 },
- { _MMIO(0x9888), 0x06630000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c00aa },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900002 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_3_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_3;
- lens[n] = ARRAY_SIZE(mux_config_l3_3);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000efff },
- { _MMIO(0x2778), 0x00006000 },
- { _MMIO(0x277c), 0x0000f3ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x102f3800 },
- { _MMIO(0x9888), 0x144d0500 },
- { _MMIO(0x9888), 0x120d03c0 },
- { _MMIO(0x9888), 0x140d03cf },
- { _MMIO(0x9888), 0x0c0f0004 },
- { _MMIO(0x9888), 0x0c4e4000 },
- { _MMIO(0x9888), 0x042f0480 },
- { _MMIO(0x9888), 0x082f0000 },
- { _MMIO(0x9888), 0x022f0000 },
- { _MMIO(0x9888), 0x0a4c0090 },
- { _MMIO(0x9888), 0x064d0027 },
- { _MMIO(0x9888), 0x004d0000 },
- { _MMIO(0x9888), 0x000d0d40 },
- { _MMIO(0x9888), 0x020d803f },
- { _MMIO(0x9888), 0x040d8023 },
- { _MMIO(0x9888), 0x100d0000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020f0010 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x0e0f0050 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41901400 },
- { _MMIO(0x9888), 0x43901485 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler[] = {
- { _MMIO(0x9888), 0x14152c00 },
- { _MMIO(0x9888), 0x16150005 },
- { _MMIO(0x9888), 0x121600a0 },
- { _MMIO(0x9888), 0x14352c00 },
- { _MMIO(0x9888), 0x16350005 },
- { _MMIO(0x9888), 0x123600a0 },
- { _MMIO(0x9888), 0x14552c00 },
- { _MMIO(0x9888), 0x16550005 },
- { _MMIO(0x9888), 0x125600a0 },
- { _MMIO(0x9888), 0x062f6000 },
- { _MMIO(0x9888), 0x022f2000 },
- { _MMIO(0x9888), 0x0c4c0050 },
- { _MMIO(0x9888), 0x0a4c0010 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0350 },
- { _MMIO(0x9888), 0x0c0fb000 },
- { _MMIO(0x9888), 0x0e0f00da },
- { _MMIO(0x9888), 0x182c0028 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x022dc000 },
- { _MMIO(0x9888), 0x042d4000 },
- { _MMIO(0x9888), 0x0c138000 },
- { _MMIO(0x9888), 0x0e132000 },
- { _MMIO(0x9888), 0x0413c000 },
- { _MMIO(0x9888), 0x1c140018 },
- { _MMIO(0x9888), 0x0c157000 },
- { _MMIO(0x9888), 0x0e150078 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x04162180 },
- { _MMIO(0x9888), 0x02160000 },
- { _MMIO(0x9888), 0x04174000 },
- { _MMIO(0x9888), 0x0233a000 },
- { _MMIO(0x9888), 0x04333000 },
- { _MMIO(0x9888), 0x14348000 },
- { _MMIO(0x9888), 0x16348000 },
- { _MMIO(0x9888), 0x02357870 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x04360043 },
- { _MMIO(0x9888), 0x02360000 },
- { _MMIO(0x9888), 0x04371000 },
- { _MMIO(0x9888), 0x0e538000 },
- { _MMIO(0x9888), 0x00538000 },
- { _MMIO(0x9888), 0x06533000 },
- { _MMIO(0x9888), 0x1c540020 },
- { _MMIO(0x9888), 0x12548000 },
- { _MMIO(0x9888), 0x0e557000 },
- { _MMIO(0x9888), 0x00557800 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x06560043 },
- { _MMIO(0x9888), 0x02560000 },
- { _MMIO(0x9888), 0x06571000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900060 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900060 },
-};
-
-static int
-get_sampler_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler;
- lens[n] = ARRAY_SIZE(mux_config_sampler);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x00007fff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x00009fff },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000efff },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000f3ff },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fdff },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x12120000 },
- { _MMIO(0x9888), 0x12320000 },
- { _MMIO(0x9888), 0x12520000 },
- { _MMIO(0x9888), 0x002f8000 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0015 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f03a0 },
- { _MMIO(0x9888), 0x0c0ff000 },
- { _MMIO(0x9888), 0x0e0f0095 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2d8000 },
- { _MMIO(0x9888), 0x0e2d4000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x02108000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x02118000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x02121880 },
- { _MMIO(0x9888), 0x041219b5 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x02134000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x0c308000 },
- { _MMIO(0x9888), 0x0e304000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x0c318000 },
- { _MMIO(0x9888), 0x0e314000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x0c321a80 },
- { _MMIO(0x9888), 0x0e320033 },
- { _MMIO(0x9888), 0x06320031 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x0c334000 },
- { _MMIO(0x9888), 0x0e331000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0e508000 },
- { _MMIO(0x9888), 0x00508000 },
- { _MMIO(0x9888), 0x02504000 },
- { _MMIO(0x9888), 0x0e518000 },
- { _MMIO(0x9888), 0x00518000 },
- { _MMIO(0x9888), 0x02514000 },
- { _MMIO(0x9888), 0x0e521880 },
- { _MMIO(0x9888), 0x00521a80 },
- { _MMIO(0x9888), 0x02520033 },
- { _MMIO(0x9888), 0x0e534000 },
- { _MMIO(0x9888), 0x00534000 },
- { _MMIO(0x9888), 0x02531000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900062 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x12124d60 },
- { _MMIO(0x9888), 0x12322e60 },
- { _MMIO(0x9888), 0x12524d60 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0014 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0fe000 },
- { _MMIO(0x9888), 0x0e0f0097 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x002d8000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x04121fb7 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x00308000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x00318000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x00321b80 },
- { _MMIO(0x9888), 0x0632003f },
- { _MMIO(0x9888), 0x00334000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0250c000 },
- { _MMIO(0x9888), 0x0251c000 },
- { _MMIO(0x9888), 0x02521fb7 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x02535000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900063 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extra[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extra[] = {
- { _MMIO(0xe458), 0x00001000 },
- { _MMIO(0xe558), 0x00003002 },
- { _MMIO(0xe658), 0x00005004 },
- { _MMIO(0xe758), 0x00011010 },
- { _MMIO(0xe45c), 0x00050012 },
- { _MMIO(0xe55c), 0x00052051 },
- { _MMIO(0xe65c), 0x00000008 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extra[] = {
- { _MMIO(0x9888), 0x121203e0 },
- { _MMIO(0x9888), 0x123203e0 },
- { _MMIO(0x9888), 0x125203e0 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0a4c0040 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0e0f006c },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x042d8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06114000 },
- { _MMIO(0x9888), 0x06120033 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x04308000 },
- { _MMIO(0x9888), 0x04318000 },
- { _MMIO(0x9888), 0x04321980 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x04334000 },
- { _MMIO(0x9888), 0x04504000 },
- { _MMIO(0x9888), 0x04514000 },
- { _MMIO(0x9888), 0x04520033 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x04531000 },
- { _MMIO(0x9888), 0x1190e000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x43900c00 },
- { _MMIO(0x9888), 0x45900002 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_compute_extra_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extra;
- lens[n] = ARRAY_SIZE(mux_config_compute_extra);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_vme_pipe[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00100030 },
- { _MMIO(0x2774), 0x0000fff9 },
- { _MMIO(0x2778), 0x00000002 },
- { _MMIO(0x277c), 0x0000fffc },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000fff3 },
- { _MMIO(0x2788), 0x00100180 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000ffcf },
- { _MMIO(0x2798), 0x00000002 },
- { _MMIO(0x279c), 0x0000ff3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_vme_pipe[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00008003 },
-};
-
-static const struct i915_oa_reg mux_config_vme_pipe[] = {
- { _MMIO(0x9888), 0x141a5800 },
- { _MMIO(0x9888), 0x161a00c0 },
- { _MMIO(0x9888), 0x12180240 },
- { _MMIO(0x9888), 0x14180002 },
- { _MMIO(0x9888), 0x143a5800 },
- { _MMIO(0x9888), 0x163a00c0 },
- { _MMIO(0x9888), 0x12380240 },
- { _MMIO(0x9888), 0x14380002 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x022f8000 },
- { _MMIO(0x9888), 0x042f3000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c1500 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f9500 },
- { _MMIO(0x9888), 0x100f002a },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162c0a00 },
- { _MMIO(0x9888), 0x0a2dc000 },
- { _MMIO(0x9888), 0x0c2dc000 },
- { _MMIO(0x9888), 0x04193000 },
- { _MMIO(0x9888), 0x081a28c1 },
- { _MMIO(0x9888), 0x001a0000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x0613c000 },
- { _MMIO(0x9888), 0x0813f000 },
- { _MMIO(0x9888), 0x00172000 },
- { _MMIO(0x9888), 0x06178000 },
- { _MMIO(0x9888), 0x0817a000 },
- { _MMIO(0x9888), 0x00180037 },
- { _MMIO(0x9888), 0x06180940 },
- { _MMIO(0x9888), 0x08180000 },
- { _MMIO(0x9888), 0x02180000 },
- { _MMIO(0x9888), 0x04183000 },
- { _MMIO(0x9888), 0x06393000 },
- { _MMIO(0x9888), 0x0c3a28c1 },
- { _MMIO(0x9888), 0x003a0000 },
- { _MMIO(0x9888), 0x0a33f000 },
- { _MMIO(0x9888), 0x0c33f000 },
- { _MMIO(0x9888), 0x0a37a000 },
- { _MMIO(0x9888), 0x0c37a000 },
- { _MMIO(0x9888), 0x0a380977 },
- { _MMIO(0x9888), 0x08380000 },
- { _MMIO(0x9888), 0x04380000 },
- { _MMIO(0x9888), 0x06383000 },
- { _MMIO(0x9888), 0x119000ff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900040 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900800 },
- { _MMIO(0x9888), 0x47901000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900844 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_vme_pipe_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_vme_pipe;
- lens[n] = ARRAY_SIZE(mux_config_vme_pipe);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2714), 0xf0800000 },
@@ -2370,6 +59,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x00000080 },
{ _MMIO(0x9888), 0x11810000 },
{ _MMIO(0x9888), 0x07810016 },
{ _MMIO(0x9888), 0x1f810000 },
@@ -2384,1096 +74,35 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x33900000 },
};
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_sklgt2(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_L3_CACHE:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_l3_cache_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_l3_cache;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_l3_cache);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_l3_cache;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_l3_cache);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_L3_2:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_2);
-
- return 0;
- case METRIC_SET_ID_L3_3:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_3_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_3;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_3);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_3;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_3);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTRA:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extra_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extra;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extra);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extra;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extra);
-
- return 0;
- case METRIC_SET_ID_VME_PIPE:
- dev_priv->perf.oa.n_mux_configs =
- get_vme_pipe_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_vme_pipe;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_vme_pipe);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_vme_pipe;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_vme_pipe);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "f519e481-24d2-4d42-87c9-3fdd12c00202",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "fe47b29d-ae51-423e-bff4-27d965a95b60",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "e0ad5ae0-84ba-4f29-a723-1906c12cb774",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "9bc436dd-6130-4add-affc-283eb6eaa864",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "2ea0da8f-3527-4669-9d9d-13099a7435bf",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
-}
-
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "d97d16af-028b-4cd1-a672-6210cb5513dd",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE);
-}
-
-static struct device_attribute dev_attr_compute_l3_cache_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_l3_cache_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_l3_cache[] = {
- &dev_attr_compute_l3_cache_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_l3_cache = {
- .name = "9fb22842-e708-43f7-9752-e0e41670c39e",
- .attrs = attrs_compute_l3_cache,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "5378e2a1-4248-4188-a4ae-da25a794c603",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "f42cdd6a-b000-42cb-870f-5eb423a7f514",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2);
-}
-
-static struct device_attribute dev_attr_l3_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_2[] = {
- &dev_attr_l3_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_2 = {
- .name = "b9bf2423-d88c-4a7b-a051-627611d00dcc",
- .attrs = attrs_l3_2,
-};
-
-static ssize_t
-show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3);
-}
-
-static struct device_attribute dev_attr_l3_3_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_3_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_3[] = {
- &dev_attr_l3_3_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_3 = {
- .name = "2414a93d-d84f-406e-99c0-472161194b40",
- .attrs = attrs_l3_3,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "53a45d2d-170b-4cf5-b7bb-585120c8e2f5",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER);
-}
-
-static struct device_attribute dev_attr_sampler_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler[] = {
- &dev_attr_sampler_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler = {
- .name = "b4cff514-a91e-4798-a0b3-426ca13fc9c1",
- .attrs = attrs_sampler,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "7821d13b-9b8b-4405-9618-78cd56b62cce",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "893f1a4d-919d-4388-8cb7-746d73ea7259",
- .attrs = attrs_tdl_2,
-};
-
-static ssize_t
-show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA);
-}
-
-static struct device_attribute dev_attr_compute_extra_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extra_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extra[] = {
- &dev_attr_compute_extra_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extra = {
- .name = "41a24047-7484-4ead-ae37-de907e5ff2b2",
- .attrs = attrs_compute_extra,
-};
-
-static ssize_t
-show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE);
-}
-
-static struct device_attribute dev_attr_vme_pipe_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_vme_pipe_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_vme_pipe[] = {
- &dev_attr_vme_pipe_id.attr,
- NULL,
-};
-
-static struct attribute_group group_vme_pipe = {
- .name = "95910492-943f-44bd-9461-390240f243fd",
- .attrs = attrs_vme_pipe,
-};
-
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "1651949f-0ac0-4cb1-a06f-dafd74a407d1",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_sklgt2(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_sklgt2(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "1651949f-0ac0-4cb1-a06f-dafd74a407d1",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (ret)
- goto error_compute_l3_cache;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (ret)
- goto error_l3_2;
- }
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (ret)
- goto error_l3_3;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (ret)
- goto error_sampler;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (ret)
- goto error_compute_extra;
- }
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (ret)
- goto error_vme_pipe;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
-error_vme_pipe:
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
-error_compute_extra:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
-error_sampler:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
-error_l3_3:
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
-error_l3_2:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
-error_compute_l3_cache:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_sklgt2(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "1651949f-0ac0-4cb1-a06f-dafd74a407d1";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt2.h b/drivers/gpu/drm/i915/i915_oa_sklgt2.h
index f4397baf3328..fe1aa2c03958 100644
--- a/drivers/gpu/drm/i915/i915_oa_sklgt2.h
+++ b/drivers/gpu/drm/i915/i915_oa_sklgt2.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_SKLGT2_H__
#define __I915_OA_SKLGT2_H__
-extern int i915_oa_n_builtin_metric_sets_sklgt2;
-
-extern int i915_oa_select_metric_set_sklgt2(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_sklgt2(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_sklgt2(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_sklgt2(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt3.c b/drivers/gpu/drm/i915/i915_oa_sklgt3.c
index 7765e22dfa17..85e51addf86a 100644
--- a/drivers/gpu/drm/i915/i915_oa_sklgt3.c
+++ b/drivers/gpu/drm/i915/i915_oa_sklgt3.c
@@ -31,1876 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_sklgt3.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_COMPUTE_L3_CACHE,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_L3_2,
- METRIC_SET_ID_L3_3,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_COMPUTE_EXTRA,
- METRIC_SET_ID_VME_PIPE,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_sklgt3 = 18;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic[] = {
- { _MMIO(0x9888), 0x166c01e0 },
- { _MMIO(0x9888), 0x12170280 },
- { _MMIO(0x9888), 0x12370280 },
- { _MMIO(0x9888), 0x16ec01e0 },
- { _MMIO(0x9888), 0x11930317 },
- { _MMIO(0x9888), 0x159303df },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x1a4e0380 },
- { _MMIO(0x9888), 0x0a6c0053 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x0a1b4000 },
- { _MMIO(0x9888), 0x1c1c0001 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x042f1000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c8400 },
- { _MMIO(0x9888), 0x0c4c0002 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f6600 },
- { _MMIO(0x9888), 0x100f0001 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x162ca200 },
- { _MMIO(0x9888), 0x062d8000 },
- { _MMIO(0x9888), 0x082d8000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x08133000 },
- { _MMIO(0x9888), 0x00170020 },
- { _MMIO(0x9888), 0x08170021 },
- { _MMIO(0x9888), 0x10170000 },
- { _MMIO(0x9888), 0x0633c000 },
- { _MMIO(0x9888), 0x0833c000 },
- { _MMIO(0x9888), 0x06370800 },
- { _MMIO(0x9888), 0x08370840 },
- { _MMIO(0x9888), 0x10370000 },
- { _MMIO(0x9888), 0x1ace0200 },
- { _MMIO(0x9888), 0x0aec5300 },
- { _MMIO(0x9888), 0x10ec0000 },
- { _MMIO(0x9888), 0x1cec0000 },
- { _MMIO(0x9888), 0x0a9b8000 },
- { _MMIO(0x9888), 0x1c9c0002 },
- { _MMIO(0x9888), 0x0ccc0002 },
- { _MMIO(0x9888), 0x0a8d8000 },
- { _MMIO(0x9888), 0x108f0001 },
- { _MMIO(0x9888), 0x16ac8000 },
- { _MMIO(0x9888), 0x0d933031 },
- { _MMIO(0x9888), 0x0f933e3f },
- { _MMIO(0x9888), 0x01933d00 },
- { _MMIO(0x9888), 0x0393073c },
- { _MMIO(0x9888), 0x0593000e },
- { _MMIO(0x9888), 0x1d930000 },
- { _MMIO(0x9888), 0x19930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x2f908000 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x15908000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190003f },
- { _MMIO(0x9888), 0x51907710 },
- { _MMIO(0x9888), 0x419020a0 },
- { _MMIO(0x9888), 0x55901515 },
- { _MMIO(0x9888), 0x45900529 },
- { _MMIO(0x9888), 0x47901025 },
- { _MMIO(0x9888), 0x57907770 },
- { _MMIO(0x9888), 0x49902100 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900108 },
- { _MMIO(0x9888), 0x59900007 },
- { _MMIO(0x9888), 0x43902108 },
- { _MMIO(0x9888), 0x53907777 },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_basic;
- lens[n] = ARRAY_SIZE(mux_config_render_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x124f1c00 },
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x1a4e0820 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x064f0900 },
- { _MMIO(0x9888), 0x084f0032 },
- { _MMIO(0x9888), 0x0a4f1891 },
- { _MMIO(0x9888), 0x0c4f0e00 },
- { _MMIO(0x9888), 0x0e4f003c },
- { _MMIO(0x9888), 0x004f0d80 },
- { _MMIO(0x9888), 0x024f003b },
- { _MMIO(0x9888), 0x006c0002 },
- { _MMIO(0x9888), 0x086c0100 },
- { _MMIO(0x9888), 0x0c6c000c },
- { _MMIO(0x9888), 0x0e6c0b00 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x081b8000 },
- { _MMIO(0x9888), 0x0c1b4000 },
- { _MMIO(0x9888), 0x0e1b8000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1c8000 },
- { _MMIO(0x9888), 0x1c1c0024 },
- { _MMIO(0x9888), 0x065b8000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5bc000 },
- { _MMIO(0x9888), 0x0c5b8000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x1a5c6000 },
- { _MMIO(0x9888), 0x1c5c001b },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2000 },
- { _MMIO(0x9888), 0x0c4c0208 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020d2000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2cc000 },
- { _MMIO(0x9888), 0x162cfb00 },
- { _MMIO(0x9888), 0x182c00be },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x19900157 },
- { _MMIO(0x9888), 0x1b900158 },
- { _MMIO(0x9888), 0x1d900105 },
- { _MMIO(0x9888), 0x1f900103 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x11900fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900863 },
- { _MMIO(0x9888), 0x47900802 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900802 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900002 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900c62 },
- { _MMIO(0x9888), 0x53903333 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_basic;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile[] = {
- { _MMIO(0x9888), 0x0c0e001f },
- { _MMIO(0x9888), 0x0a0f0000 },
- { _MMIO(0x9888), 0x10116800 },
- { _MMIO(0x9888), 0x178a03e0 },
- { _MMIO(0x9888), 0x11824c00 },
- { _MMIO(0x9888), 0x11830020 },
- { _MMIO(0x9888), 0x13840020 },
- { _MMIO(0x9888), 0x11850019 },
- { _MMIO(0x9888), 0x11860007 },
- { _MMIO(0x9888), 0x01870c40 },
- { _MMIO(0x9888), 0x17880000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0a4c0040 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x040d4000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020e5400 },
- { _MMIO(0x9888), 0x000e0000 },
- { _MMIO(0x9888), 0x080f0040 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x100f0000 },
- { _MMIO(0x9888), 0x0e0f0040 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06110012 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x01898000 },
- { _MMIO(0x9888), 0x0d890100 },
- { _MMIO(0x9888), 0x03898000 },
- { _MMIO(0x9888), 0x09808000 },
- { _MMIO(0x9888), 0x0b808000 },
- { _MMIO(0x9888), 0x0380c000 },
- { _MMIO(0x9888), 0x0f8a0075 },
- { _MMIO(0x9888), 0x1d8a0000 },
- { _MMIO(0x9888), 0x118a8000 },
- { _MMIO(0x9888), 0x1b8a4000 },
- { _MMIO(0x9888), 0x138a8000 },
- { _MMIO(0x9888), 0x1d81a000 },
- { _MMIO(0x9888), 0x15818000 },
- { _MMIO(0x9888), 0x17818000 },
- { _MMIO(0x9888), 0x0b820030 },
- { _MMIO(0x9888), 0x07828000 },
- { _MMIO(0x9888), 0x0d824000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x05824000 },
- { _MMIO(0x9888), 0x0d830003 },
- { _MMIO(0x9888), 0x0583000c },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x03838000 },
- { _MMIO(0x9888), 0x07838000 },
- { _MMIO(0x9888), 0x0b840980 },
- { _MMIO(0x9888), 0x03844d80 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x09848000 },
- { _MMIO(0x9888), 0x09850080 },
- { _MMIO(0x9888), 0x03850003 },
- { _MMIO(0x9888), 0x01850000 },
- { _MMIO(0x9888), 0x07860000 },
- { _MMIO(0x9888), 0x0f860400 },
- { _MMIO(0x9888), 0x09870032 },
- { _MMIO(0x9888), 0x01888052 },
- { _MMIO(0x9888), 0x11880000 },
- { _MMIO(0x9888), 0x09884000 },
- { _MMIO(0x9888), 0x1b931001 },
- { _MMIO(0x9888), 0x1d930001 },
- { _MMIO(0x9888), 0x19934000 },
- { _MMIO(0x9888), 0x1b958000 },
- { _MMIO(0x9888), 0x1d950094 },
- { _MMIO(0x9888), 0x19958000 },
- { _MMIO(0x9888), 0x09e58000 },
- { _MMIO(0x9888), 0x0be58000 },
- { _MMIO(0x9888), 0x03e5c000 },
- { _MMIO(0x9888), 0x0592c000 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d924000 },
- { _MMIO(0x9888), 0x0f924000 },
- { _MMIO(0x9888), 0x11928000 },
- { _MMIO(0x9888), 0x1392c000 },
- { _MMIO(0x9888), 0x09924000 },
- { _MMIO(0x9888), 0x01985000 },
- { _MMIO(0x9888), 0x07988000 },
- { _MMIO(0x9888), 0x09981000 },
- { _MMIO(0x9888), 0x0b982000 },
- { _MMIO(0x9888), 0x0d982000 },
- { _MMIO(0x9888), 0x0f989000 },
- { _MMIO(0x9888), 0x05982000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1190c080 },
- { _MMIO(0x9888), 0x51901150 },
- { _MMIO(0x9888), 0x41901400 },
- { _MMIO(0x9888), 0x55905111 },
- { _MMIO(0x9888), 0x45901400 },
- { _MMIO(0x9888), 0x479004a5 },
- { _MMIO(0x9888), 0x57903455 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b9000a0 },
- { _MMIO(0x9888), 0x59900001 },
- { _MMIO(0x9888), 0x43900005 },
- { _MMIO(0x9888), 0x53900455 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_pipe_profile;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900064 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900150 },
- { _MMIO(0x9888), 0x21900151 },
- { _MMIO(0x9888), 0x23900152 },
- { _MMIO(0x9888), 0x25900153 },
- { _MMIO(0x9888), 0x27900154 },
- { _MMIO(0x9888), 0x29900155 },
- { _MMIO(0x9888), 0x2b900156 },
- { _MMIO(0x9888), 0x2d900157 },
- { _MMIO(0x9888), 0x2f90015f },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_reads;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901000 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900160 },
- { _MMIO(0x9888), 0x21900161 },
- { _MMIO(0x9888), 0x23900162 },
- { _MMIO(0x9888), 0x25900163 },
- { _MMIO(0x9888), 0x27900164 },
- { _MMIO(0x9888), 0x29900165 },
- { _MMIO(0x9888), 0x2b900166 },
- { _MMIO(0x9888), 0x2d900167 },
- { _MMIO(0x9888), 0x2f900150 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_writes;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fc2a },
- { _MMIO(0x2774), 0x0000bf00 },
- { _MMIO(0x2778), 0x0007fc6a },
- { _MMIO(0x277c), 0x0000bf00 },
- { _MMIO(0x2780), 0x0007fc92 },
- { _MMIO(0x2784), 0x0000bf00 },
- { _MMIO(0x2788), 0x0007fca2 },
- { _MMIO(0x278c), 0x0000bf00 },
- { _MMIO(0x2790), 0x0007fc32 },
- { _MMIO(0x2794), 0x0000bf00 },
- { _MMIO(0x2798), 0x0007fc9a },
- { _MMIO(0x279c), 0x0000bf00 },
- { _MMIO(0x27a0), 0x0007fe6a },
- { _MMIO(0x27a4), 0x0000bf00 },
- { _MMIO(0x27a8), 0x0007fe7a },
- { _MMIO(0x27ac), 0x0000bf00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended[] = {
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x141c8160 },
- { _MMIO(0x9888), 0x161c8015 },
- { _MMIO(0x9888), 0x181c0120 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4eaaa0 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0e6c0b01 },
- { _MMIO(0x9888), 0x006c0200 },
- { _MMIO(0x9888), 0x026c000c },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x001c0041 },
- { _MMIO(0x9888), 0x061c4200 },
- { _MMIO(0x9888), 0x081c4443 },
- { _MMIO(0x9888), 0x0a1c4645 },
- { _MMIO(0x9888), 0x0c1c7647 },
- { _MMIO(0x9888), 0x041c7357 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x101c0000 },
- { _MMIO(0x9888), 0x1a1c0000 },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4caa2a },
- { _MMIO(0x9888), 0x0c4c02aa },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5515 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x11907fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900040 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900802 },
- { _MMIO(0x9888), 0x47900842 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900842 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900800 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extended;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fffa },
- { _MMIO(0x2774), 0x0000fefe },
- { _MMIO(0x2778), 0x0007fffa },
- { _MMIO(0x277c), 0x0000fefd },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000fbef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000fbdf },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00101100 },
- { _MMIO(0xe45c), 0x00201200 },
- { _MMIO(0xe55c), 0x00301300 },
- { _MMIO(0xe65c), 0x00401400 },
-};
-
-static const struct i915_oa_reg mux_config_compute_l3_cache[] = {
- { _MMIO(0x9888), 0x166c0760 },
- { _MMIO(0x9888), 0x1593001e },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4e8020 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x006c0051 },
- { _MMIO(0x9888), 0x066c5000 },
- { _MMIO(0x9888), 0x086c5c5d },
- { _MMIO(0x9888), 0x0e6c5e5f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x061b8000 },
- { _MMIO(0x9888), 0x081bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1ce000 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2a00 },
- { _MMIO(0x9888), 0x0c4c0280 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f1500 },
- { _MMIO(0x9888), 0x100f0140 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162c0a00 },
- { _MMIO(0x9888), 0x182c00a0 },
- { _MMIO(0x9888), 0x03933300 },
- { _MMIO(0x9888), 0x05930032 },
- { _MMIO(0x9888), 0x11930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190030f },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900063 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x53903333 },
- { _MMIO(0x9888), 0x43900840 },
-};
-
-static int
-get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_l3_cache;
- lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x104f0232 },
- { _MMIO(0x9888), 0x124f4640 },
- { _MMIO(0x9888), 0x106c0232 },
- { _MMIO(0x9888), 0x11834400 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x004f1880 },
- { _MMIO(0x9888), 0x024f08bb },
- { _MMIO(0x9888), 0x044f001b },
- { _MMIO(0x9888), 0x046c0100 },
- { _MMIO(0x9888), 0x066c000b },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x041b8000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025bc000 },
- { _MMIO(0x9888), 0x045b4000 },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x165c8000 },
- { _MMIO(0x9888), 0x185c8000 },
- { _MMIO(0x9888), 0x0a4c00a0 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x062cc000 },
- { _MMIO(0x9888), 0x082cc000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x0f8305c0 },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x07830000 },
- { _MMIO(0x9888), 0x1d950080 },
- { _MMIO(0x9888), 0x13928000 },
- { _MMIO(0x9888), 0x0f988000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x59900005 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1[] = {
- { _MMIO(0x9888), 0x126c7b40 },
- { _MMIO(0x9888), 0x166c0020 },
- { _MMIO(0x9888), 0x0a603444 },
- { _MMIO(0x9888), 0x0a613400 },
- { _MMIO(0x9888), 0x1a4ea800 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x0c6c5327 },
- { _MMIO(0x9888), 0x0e6c5425 },
- { _MMIO(0x9888), 0x006c2a00 },
- { _MMIO(0x9888), 0x026c285b },
- { _MMIO(0x9888), 0x046c005c },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0800 },
- { _MMIO(0x9888), 0x0c1bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x1c1c003c },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x10600000 },
- { _MMIO(0x9888), 0x04600000 },
- { _MMIO(0x9888), 0x0c610044 },
- { _MMIO(0x9888), 0x10610000 },
- { _MMIO(0x9888), 0x06610000 },
- { _MMIO(0x9888), 0x0c4c02a8 },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0154 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190ffc0 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900420 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900021 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900400 },
- { _MMIO(0x9888), 0x43900421 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_1;
- lens[n] = ARRAY_SIZE(mux_config_l3_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_2[] = {
- { _MMIO(0x9888), 0x126c02e0 },
- { _MMIO(0x9888), 0x146c0001 },
- { _MMIO(0x9888), 0x0a623400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x026c3324 },
- { _MMIO(0x9888), 0x046c3422 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x06614000 },
- { _MMIO(0x9888), 0x0c620044 },
- { _MMIO(0x9888), 0x10620000 },
- { _MMIO(0x9888), 0x06620000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_2;
- lens[n] = ARRAY_SIZE(mux_config_l3_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_3[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_3[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_3[] = {
- { _MMIO(0x9888), 0x126c4e80 },
- { _MMIO(0x9888), 0x146c0000 },
- { _MMIO(0x9888), 0x0a633400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x026c3321 },
- { _MMIO(0x9888), 0x046c342f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c2000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x06604000 },
- { _MMIO(0x9888), 0x0c630044 },
- { _MMIO(0x9888), 0x10630000 },
- { _MMIO(0x9888), 0x06630000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c00aa },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900002 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_3_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_3;
- lens[n] = ARRAY_SIZE(mux_config_l3_3);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000efff },
- { _MMIO(0x2778), 0x00006000 },
- { _MMIO(0x277c), 0x0000f3ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x102f3800 },
- { _MMIO(0x9888), 0x144d0500 },
- { _MMIO(0x9888), 0x120d03c0 },
- { _MMIO(0x9888), 0x140d03cf },
- { _MMIO(0x9888), 0x0c0f0004 },
- { _MMIO(0x9888), 0x0c4e4000 },
- { _MMIO(0x9888), 0x042f0480 },
- { _MMIO(0x9888), 0x082f0000 },
- { _MMIO(0x9888), 0x022f0000 },
- { _MMIO(0x9888), 0x0a4c0090 },
- { _MMIO(0x9888), 0x064d0027 },
- { _MMIO(0x9888), 0x004d0000 },
- { _MMIO(0x9888), 0x000d0d40 },
- { _MMIO(0x9888), 0x020d803f },
- { _MMIO(0x9888), 0x040d8023 },
- { _MMIO(0x9888), 0x100d0000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020f0010 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x0e0f0050 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41901400 },
- { _MMIO(0x9888), 0x43901485 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler[] = {
- { _MMIO(0x9888), 0x14152c00 },
- { _MMIO(0x9888), 0x16150005 },
- { _MMIO(0x9888), 0x121600a0 },
- { _MMIO(0x9888), 0x14352c00 },
- { _MMIO(0x9888), 0x16350005 },
- { _MMIO(0x9888), 0x123600a0 },
- { _MMIO(0x9888), 0x14552c00 },
- { _MMIO(0x9888), 0x16550005 },
- { _MMIO(0x9888), 0x125600a0 },
- { _MMIO(0x9888), 0x062f6000 },
- { _MMIO(0x9888), 0x022f2000 },
- { _MMIO(0x9888), 0x0c4c0050 },
- { _MMIO(0x9888), 0x0a4c0010 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0350 },
- { _MMIO(0x9888), 0x0c0fb000 },
- { _MMIO(0x9888), 0x0e0f00da },
- { _MMIO(0x9888), 0x182c0028 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x022dc000 },
- { _MMIO(0x9888), 0x042d4000 },
- { _MMIO(0x9888), 0x0c138000 },
- { _MMIO(0x9888), 0x0e132000 },
- { _MMIO(0x9888), 0x0413c000 },
- { _MMIO(0x9888), 0x1c140018 },
- { _MMIO(0x9888), 0x0c157000 },
- { _MMIO(0x9888), 0x0e150078 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x04162180 },
- { _MMIO(0x9888), 0x02160000 },
- { _MMIO(0x9888), 0x04174000 },
- { _MMIO(0x9888), 0x0233a000 },
- { _MMIO(0x9888), 0x04333000 },
- { _MMIO(0x9888), 0x14348000 },
- { _MMIO(0x9888), 0x16348000 },
- { _MMIO(0x9888), 0x02357870 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x04360043 },
- { _MMIO(0x9888), 0x02360000 },
- { _MMIO(0x9888), 0x04371000 },
- { _MMIO(0x9888), 0x0e538000 },
- { _MMIO(0x9888), 0x00538000 },
- { _MMIO(0x9888), 0x06533000 },
- { _MMIO(0x9888), 0x1c540020 },
- { _MMIO(0x9888), 0x12548000 },
- { _MMIO(0x9888), 0x0e557000 },
- { _MMIO(0x9888), 0x00557800 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x06560043 },
- { _MMIO(0x9888), 0x02560000 },
- { _MMIO(0x9888), 0x06571000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900060 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900060 },
-};
-
-static int
-get_sampler_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler;
- lens[n] = ARRAY_SIZE(mux_config_sampler);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x00007fff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x00009fff },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000efff },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000f3ff },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fdff },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x12120000 },
- { _MMIO(0x9888), 0x12320000 },
- { _MMIO(0x9888), 0x12520000 },
- { _MMIO(0x9888), 0x002f8000 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0015 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f03a0 },
- { _MMIO(0x9888), 0x0c0ff000 },
- { _MMIO(0x9888), 0x0e0f0095 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2d8000 },
- { _MMIO(0x9888), 0x0e2d4000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x02108000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x02118000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x02121880 },
- { _MMIO(0x9888), 0x041219b5 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x02134000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x0c308000 },
- { _MMIO(0x9888), 0x0e304000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x0c318000 },
- { _MMIO(0x9888), 0x0e314000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x0c321a80 },
- { _MMIO(0x9888), 0x0e320033 },
- { _MMIO(0x9888), 0x06320031 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x0c334000 },
- { _MMIO(0x9888), 0x0e331000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0e508000 },
- { _MMIO(0x9888), 0x00508000 },
- { _MMIO(0x9888), 0x02504000 },
- { _MMIO(0x9888), 0x0e518000 },
- { _MMIO(0x9888), 0x00518000 },
- { _MMIO(0x9888), 0x02514000 },
- { _MMIO(0x9888), 0x0e521880 },
- { _MMIO(0x9888), 0x00521a80 },
- { _MMIO(0x9888), 0x02520033 },
- { _MMIO(0x9888), 0x0e534000 },
- { _MMIO(0x9888), 0x00534000 },
- { _MMIO(0x9888), 0x02531000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900062 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x12124d60 },
- { _MMIO(0x9888), 0x12322e60 },
- { _MMIO(0x9888), 0x12524d60 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0014 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0fe000 },
- { _MMIO(0x9888), 0x0e0f0097 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x002d8000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x04121fb7 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x00308000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x00318000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x00321b80 },
- { _MMIO(0x9888), 0x0632003f },
- { _MMIO(0x9888), 0x00334000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0250c000 },
- { _MMIO(0x9888), 0x0251c000 },
- { _MMIO(0x9888), 0x02521fb7 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x02535000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900063 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extra[] = {
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extra[] = {
-};
-
-static const struct i915_oa_reg mux_config_compute_extra[] = {
- { _MMIO(0x9888), 0x121203e0 },
- { _MMIO(0x9888), 0x123203e0 },
- { _MMIO(0x9888), 0x125203e0 },
- { _MMIO(0x9888), 0x129203e0 },
- { _MMIO(0x9888), 0x12b203e0 },
- { _MMIO(0x9888), 0x12d203e0 },
- { _MMIO(0x9888), 0x024ec000 },
- { _MMIO(0x9888), 0x044ec000 },
- { _MMIO(0x9888), 0x064ec000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x0a4c0042 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f006d },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x042d8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06114000 },
- { _MMIO(0x9888), 0x06120033 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x04308000 },
- { _MMIO(0x9888), 0x04318000 },
- { _MMIO(0x9888), 0x04321980 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x04334000 },
- { _MMIO(0x9888), 0x04504000 },
- { _MMIO(0x9888), 0x04514000 },
- { _MMIO(0x9888), 0x04520033 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x04531000 },
- { _MMIO(0x9888), 0x00af8000 },
- { _MMIO(0x9888), 0x0acc0001 },
- { _MMIO(0x9888), 0x008d8000 },
- { _MMIO(0x9888), 0x028da000 },
- { _MMIO(0x9888), 0x0c8fb000 },
- { _MMIO(0x9888), 0x0e8f0001 },
- { _MMIO(0x9888), 0x06ac8000 },
- { _MMIO(0x9888), 0x02ad4000 },
- { _MMIO(0x9888), 0x02908000 },
- { _MMIO(0x9888), 0x02918000 },
- { _MMIO(0x9888), 0x02921980 },
- { _MMIO(0x9888), 0x00920000 },
- { _MMIO(0x9888), 0x02934000 },
- { _MMIO(0x9888), 0x02b04000 },
- { _MMIO(0x9888), 0x02b14000 },
- { _MMIO(0x9888), 0x02b20033 },
- { _MMIO(0x9888), 0x00b20000 },
- { _MMIO(0x9888), 0x02b31000 },
- { _MMIO(0x9888), 0x00d08000 },
- { _MMIO(0x9888), 0x00d18000 },
- { _MMIO(0x9888), 0x00d21980 },
- { _MMIO(0x9888), 0x00d34000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900402 },
- { _MMIO(0x9888), 0x53901550 },
- { _MMIO(0x9888), 0x45900080 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_compute_extra_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extra;
- lens[n] = ARRAY_SIZE(mux_config_compute_extra);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_vme_pipe[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00100030 },
- { _MMIO(0x2774), 0x0000fff9 },
- { _MMIO(0x2778), 0x00000002 },
- { _MMIO(0x277c), 0x0000fffc },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000fff3 },
- { _MMIO(0x2788), 0x00100180 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000ffcf },
- { _MMIO(0x2798), 0x00000002 },
- { _MMIO(0x279c), 0x0000ff3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_vme_pipe[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00008003 },
-};
-
-static const struct i915_oa_reg mux_config_vme_pipe[] = {
- { _MMIO(0x9888), 0x141a5800 },
- { _MMIO(0x9888), 0x161a00c0 },
- { _MMIO(0x9888), 0x12180240 },
- { _MMIO(0x9888), 0x14180002 },
- { _MMIO(0x9888), 0x149a5800 },
- { _MMIO(0x9888), 0x169a00c0 },
- { _MMIO(0x9888), 0x12980240 },
- { _MMIO(0x9888), 0x14980002 },
- { _MMIO(0x9888), 0x1a4e3fc0 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x022f8000 },
- { _MMIO(0x9888), 0x042f3000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c9500 },
- { _MMIO(0x9888), 0x0c4c002a },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0015 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x182c000a },
- { _MMIO(0x9888), 0x04193000 },
- { _MMIO(0x9888), 0x081a28c1 },
- { _MMIO(0x9888), 0x001a0000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x0613c000 },
- { _MMIO(0x9888), 0x0813f000 },
- { _MMIO(0x9888), 0x00172000 },
- { _MMIO(0x9888), 0x06178000 },
- { _MMIO(0x9888), 0x0817a000 },
- { _MMIO(0x9888), 0x00180037 },
- { _MMIO(0x9888), 0x06180940 },
- { _MMIO(0x9888), 0x08180000 },
- { _MMIO(0x9888), 0x02180000 },
- { _MMIO(0x9888), 0x04183000 },
- { _MMIO(0x9888), 0x04afc000 },
- { _MMIO(0x9888), 0x06af3000 },
- { _MMIO(0x9888), 0x0acc4000 },
- { _MMIO(0x9888), 0x0ccc0015 },
- { _MMIO(0x9888), 0x0a8da000 },
- { _MMIO(0x9888), 0x0c8da000 },
- { _MMIO(0x9888), 0x0e8f4000 },
- { _MMIO(0x9888), 0x108f0015 },
- { _MMIO(0x9888), 0x16aca000 },
- { _MMIO(0x9888), 0x18ac000a },
- { _MMIO(0x9888), 0x06993000 },
- { _MMIO(0x9888), 0x0c9a28c1 },
- { _MMIO(0x9888), 0x009a0000 },
- { _MMIO(0x9888), 0x0a93f000 },
- { _MMIO(0x9888), 0x0c93f000 },
- { _MMIO(0x9888), 0x0a97a000 },
- { _MMIO(0x9888), 0x0c97a000 },
- { _MMIO(0x9888), 0x0a980977 },
- { _MMIO(0x9888), 0x08980000 },
- { _MMIO(0x9888), 0x04980000 },
- { _MMIO(0x9888), 0x06983000 },
- { _MMIO(0x9888), 0x119000ff },
- { _MMIO(0x9888), 0x51900050 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x55900115 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x47900884 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900002 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_vme_pipe_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_vme_pipe;
- lens[n] = ARRAY_SIZE(mux_config_vme_pipe);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2744), 0x00800000 },
@@ -1930,6 +60,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x00000080 },
{ _MMIO(0x9888), 0x11810000 },
{ _MMIO(0x9888), 0x07810013 },
{ _MMIO(0x9888), 0x1f810000 },
@@ -1944,1096 +75,35 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x33900000 },
};
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_sklgt3(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_L3_CACHE:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_l3_cache_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_l3_cache;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_l3_cache);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_l3_cache;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_l3_cache);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_L3_2:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_2);
-
- return 0;
- case METRIC_SET_ID_L3_3:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_3_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_3;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_3);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_3;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_3);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTRA:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extra_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extra;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extra);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extra;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extra);
-
- return 0;
- case METRIC_SET_ID_VME_PIPE:
- dev_priv->perf.oa.n_mux_configs =
- get_vme_pipe_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_vme_pipe;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_vme_pipe);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_vme_pipe;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_vme_pipe);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "4616d450-2393-4836-8146-53c5ed84d359",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "4320492b-fd03-42ac-922f-dbe1ef3b7b58",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "bd2d9cae-b9ec-4f5b-9d2f-934bed398a2d",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "4ca0f3fe-7fd3-4924-98cb-1807d9879767",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "a0c0172c-ee13-403d-99ff-2bdf6936cf14",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
-}
-
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "52435e0b-f188-42ea-8680-21a56ee20dee",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE);
-}
-
-static struct device_attribute dev_attr_compute_l3_cache_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_l3_cache_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_l3_cache[] = {
- &dev_attr_compute_l3_cache_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_l3_cache = {
- .name = "27076eeb-49f3-4fed-8423-c66506005c63",
- .attrs = attrs_compute_l3_cache,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "8071b409-c39a-4674-94d7-32962ecfb512",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "5e0b391e-9ea8-4901-b2ff-b64ff616c7ed",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2);
-}
-
-static struct device_attribute dev_attr_l3_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_2[] = {
- &dev_attr_l3_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_2 = {
- .name = "25dc828e-1d2d-426e-9546-a1d4233cdf16",
- .attrs = attrs_l3_2,
-};
-
-static ssize_t
-show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3);
-}
-
-static struct device_attribute dev_attr_l3_3_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_3_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_3[] = {
- &dev_attr_l3_3_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_3 = {
- .name = "3dba9405-2d7e-4d70-8199-e734e82fd6bf",
- .attrs = attrs_l3_3,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "76935d7b-09c9-46bf-87f1-c18b4a86ebe5",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER);
-}
-
-static struct device_attribute dev_attr_sampler_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler[] = {
- &dev_attr_sampler_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler = {
- .name = "1b34c0d6-4f4c-4d7b-833f-4aaf236d87a6",
- .attrs = attrs_sampler,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "b375c985-9953-455b-bda2-b03f7594e9db",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "3e2be2bb-884a-49bb-82c5-2358e6bd5f2d",
- .attrs = attrs_tdl_2,
-};
-
-static ssize_t
-show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA);
-}
-
-static struct device_attribute dev_attr_compute_extra_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extra_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extra[] = {
- &dev_attr_compute_extra_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extra = {
- .name = "2d80a648-7b5a-4e92-bbe7-3b5c76f2e221",
- .attrs = attrs_compute_extra,
-};
-
-static ssize_t
-show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE);
-}
-
-static struct device_attribute dev_attr_vme_pipe_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_vme_pipe_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_vme_pipe[] = {
- &dev_attr_vme_pipe_id.attr,
- NULL,
-};
-
-static struct attribute_group group_vme_pipe = {
- .name = "cfae9232-6ffc-42cc-a703-9790016925f0",
- .attrs = attrs_vme_pipe,
-};
-
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "2b985803-d3c9-4629-8a4f-634bfecba0e8",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_sklgt3(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_sklgt3(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "2b985803-d3c9-4629-8a4f-634bfecba0e8",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (ret)
- goto error_compute_l3_cache;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (ret)
- goto error_l3_2;
- }
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (ret)
- goto error_l3_3;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (ret)
- goto error_sampler;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (ret)
- goto error_compute_extra;
- }
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (ret)
- goto error_vme_pipe;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
-error_vme_pipe:
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
-error_compute_extra:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
-error_sampler:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
-error_l3_3:
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
-error_l3_2:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
-error_compute_l3_cache:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_sklgt3(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "2b985803-d3c9-4629-8a4f-634bfecba0e8";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt3.h b/drivers/gpu/drm/i915/i915_oa_sklgt3.h
index c0accb1f9b74..06746b2616c8 100644
--- a/drivers/gpu/drm/i915/i915_oa_sklgt3.h
+++ b/drivers/gpu/drm/i915/i915_oa_sklgt3.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_SKLGT3_H__
#define __I915_OA_SKLGT3_H__
-extern int i915_oa_n_builtin_metric_sets_sklgt3;
-
-extern int i915_oa_select_metric_set_sklgt3(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_sklgt3(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_sklgt3(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_sklgt3(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt4.c b/drivers/gpu/drm/i915/i915_oa_sklgt4.c
index 9ddab43a2176..bce031ee4445 100644
--- a/drivers/gpu/drm/i915/i915_oa_sklgt4.c
+++ b/drivers/gpu/drm/i915/i915_oa_sklgt4.c
@@ -31,1930 +31,6 @@
#include "i915_drv.h"
#include "i915_oa_sklgt4.h"
-enum metric_set_id {
- METRIC_SET_ID_RENDER_BASIC = 1,
- METRIC_SET_ID_COMPUTE_BASIC,
- METRIC_SET_ID_RENDER_PIPE_PROFILE,
- METRIC_SET_ID_MEMORY_READS,
- METRIC_SET_ID_MEMORY_WRITES,
- METRIC_SET_ID_COMPUTE_EXTENDED,
- METRIC_SET_ID_COMPUTE_L3_CACHE,
- METRIC_SET_ID_HDC_AND_SF,
- METRIC_SET_ID_L3_1,
- METRIC_SET_ID_L3_2,
- METRIC_SET_ID_L3_3,
- METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND,
- METRIC_SET_ID_SAMPLER,
- METRIC_SET_ID_TDL_1,
- METRIC_SET_ID_TDL_2,
- METRIC_SET_ID_COMPUTE_EXTRA,
- METRIC_SET_ID_VME_PIPE,
- METRIC_SET_ID_TEST_OA,
-};
-
-int i915_oa_n_builtin_metric_sets_sklgt4 = 18;
-
-static const struct i915_oa_reg b_counter_config_render_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_render_basic[] = {
- { _MMIO(0x9888), 0x166c01e0 },
- { _MMIO(0x9888), 0x12170280 },
- { _MMIO(0x9888), 0x12370280 },
- { _MMIO(0x9888), 0x16ec01e0 },
- { _MMIO(0x9888), 0x176c01e0 },
- { _MMIO(0x9888), 0x11930317 },
- { _MMIO(0x9888), 0x159303df },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x1a4e03b0 },
- { _MMIO(0x9888), 0x0a6c0053 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x0a1b4000 },
- { _MMIO(0x9888), 0x1c1c0001 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x042f1000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4ca400 },
- { _MMIO(0x9888), 0x0c4c0002 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f5600 },
- { _MMIO(0x9888), 0x100f0001 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x062d8000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x08133000 },
- { _MMIO(0x9888), 0x00170020 },
- { _MMIO(0x9888), 0x08170021 },
- { _MMIO(0x9888), 0x10170000 },
- { _MMIO(0x9888), 0x0633c000 },
- { _MMIO(0x9888), 0x06370800 },
- { _MMIO(0x9888), 0x10370000 },
- { _MMIO(0x9888), 0x1ace0230 },
- { _MMIO(0x9888), 0x0aec5300 },
- { _MMIO(0x9888), 0x10ec0000 },
- { _MMIO(0x9888), 0x1cec0000 },
- { _MMIO(0x9888), 0x0a9b8000 },
- { _MMIO(0x9888), 0x1c9c0002 },
- { _MMIO(0x9888), 0x0acc2000 },
- { _MMIO(0x9888), 0x0ccc0002 },
- { _MMIO(0x9888), 0x088d8000 },
- { _MMIO(0x9888), 0x0a8d8000 },
- { _MMIO(0x9888), 0x0e8f1000 },
- { _MMIO(0x9888), 0x108f0001 },
- { _MMIO(0x9888), 0x16ac8800 },
- { _MMIO(0x9888), 0x1b4e0020 },
- { _MMIO(0x9888), 0x096c5300 },
- { _MMIO(0x9888), 0x116c0000 },
- { _MMIO(0x9888), 0x1d6c0000 },
- { _MMIO(0x9888), 0x091b8000 },
- { _MMIO(0x9888), 0x1b1c8000 },
- { _MMIO(0x9888), 0x0b4c2000 },
- { _MMIO(0x9888), 0x090d8000 },
- { _MMIO(0x9888), 0x0f0f1000 },
- { _MMIO(0x9888), 0x172c0800 },
- { _MMIO(0x9888), 0x0d933031 },
- { _MMIO(0x9888), 0x0f933e3f },
- { _MMIO(0x9888), 0x01933d00 },
- { _MMIO(0x9888), 0x0393073c },
- { _MMIO(0x9888), 0x0593000e },
- { _MMIO(0x9888), 0x1d930000 },
- { _MMIO(0x9888), 0x19930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x2b908000 },
- { _MMIO(0x9888), 0x2d908000 },
- { _MMIO(0x9888), 0x2f908000 },
- { _MMIO(0x9888), 0x31908000 },
- { _MMIO(0x9888), 0x15908000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190003f },
- { _MMIO(0x9888), 0x5190ff30 },
- { _MMIO(0x9888), 0x41900060 },
- { _MMIO(0x9888), 0x55903033 },
- { _MMIO(0x9888), 0x45901421 },
- { _MMIO(0x9888), 0x47900803 },
- { _MMIO(0x9888), 0x5790fff1 },
- { _MMIO(0x9888), 0x49900001 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x5990000f },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x5390ffff },
-};
-
-static int
-get_render_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_basic;
- lens[n] = ARRAY_SIZE(mux_config_render_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_basic[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2740), 0x00000000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_basic[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_basic[] = {
- { _MMIO(0x9888), 0x104f00e0 },
- { _MMIO(0x9888), 0x124f1c00 },
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x1a4e0820 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x064f0900 },
- { _MMIO(0x9888), 0x084f0032 },
- { _MMIO(0x9888), 0x0a4f1891 },
- { _MMIO(0x9888), 0x0c4f0e00 },
- { _MMIO(0x9888), 0x0e4f003c },
- { _MMIO(0x9888), 0x004f0d80 },
- { _MMIO(0x9888), 0x024f003b },
- { _MMIO(0x9888), 0x006c0002 },
- { _MMIO(0x9888), 0x086c0100 },
- { _MMIO(0x9888), 0x0c6c000c },
- { _MMIO(0x9888), 0x0e6c0b00 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x081b8000 },
- { _MMIO(0x9888), 0x0c1b4000 },
- { _MMIO(0x9888), 0x0e1b8000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1c8000 },
- { _MMIO(0x9888), 0x1c1c0024 },
- { _MMIO(0x9888), 0x065b8000 },
- { _MMIO(0x9888), 0x085b4000 },
- { _MMIO(0x9888), 0x0a5bc000 },
- { _MMIO(0x9888), 0x0c5b8000 },
- { _MMIO(0x9888), 0x0e5b4000 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025b4000 },
- { _MMIO(0x9888), 0x1a5c6000 },
- { _MMIO(0x9888), 0x1c5c001b },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2000 },
- { _MMIO(0x9888), 0x0c4c0208 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020d2000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2cc000 },
- { _MMIO(0x9888), 0x162cfb00 },
- { _MMIO(0x9888), 0x182c00be },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x19900157 },
- { _MMIO(0x9888), 0x1b900158 },
- { _MMIO(0x9888), 0x1d900105 },
- { _MMIO(0x9888), 0x1f900103 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x11900fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900821 },
- { _MMIO(0x9888), 0x47900802 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900802 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900002 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900422 },
- { _MMIO(0x9888), 0x53905555 },
-};
-
-static int
-get_compute_basic_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_basic;
- lens[n] = ARRAY_SIZE(mux_config_compute_basic);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_render_pipe_profile[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007ffea },
- { _MMIO(0x2774), 0x00007ffc },
- { _MMIO(0x2778), 0x0007affa },
- { _MMIO(0x277c), 0x0000f5fd },
- { _MMIO(0x2780), 0x00079ffa },
- { _MMIO(0x2784), 0x0000f3fb },
- { _MMIO(0x2788), 0x0007bf7a },
- { _MMIO(0x278c), 0x0000f7e7 },
- { _MMIO(0x2790), 0x0007fefa },
- { _MMIO(0x2794), 0x0000f7cf },
- { _MMIO(0x2798), 0x00077ffa },
- { _MMIO(0x279c), 0x0000efdf },
- { _MMIO(0x27a0), 0x0006fffa },
- { _MMIO(0x27a4), 0x0000cfbf },
- { _MMIO(0x27a8), 0x0003fffa },
- { _MMIO(0x27ac), 0x00005f7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_render_pipe_profile[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_render_pipe_profile[] = {
- { _MMIO(0x9888), 0x0c0e001f },
- { _MMIO(0x9888), 0x0a0f0000 },
- { _MMIO(0x9888), 0x10116800 },
- { _MMIO(0x9888), 0x178a03e0 },
- { _MMIO(0x9888), 0x11824c00 },
- { _MMIO(0x9888), 0x11830020 },
- { _MMIO(0x9888), 0x13840020 },
- { _MMIO(0x9888), 0x11850019 },
- { _MMIO(0x9888), 0x11860007 },
- { _MMIO(0x9888), 0x01870c40 },
- { _MMIO(0x9888), 0x17880000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0a4c0040 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x040d4000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020e5400 },
- { _MMIO(0x9888), 0x000e0000 },
- { _MMIO(0x9888), 0x080f0040 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x100f0000 },
- { _MMIO(0x9888), 0x0e0f0040 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06110012 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x01898000 },
- { _MMIO(0x9888), 0x0d890100 },
- { _MMIO(0x9888), 0x03898000 },
- { _MMIO(0x9888), 0x09808000 },
- { _MMIO(0x9888), 0x0b808000 },
- { _MMIO(0x9888), 0x0380c000 },
- { _MMIO(0x9888), 0x0f8a0075 },
- { _MMIO(0x9888), 0x1d8a0000 },
- { _MMIO(0x9888), 0x118a8000 },
- { _MMIO(0x9888), 0x1b8a4000 },
- { _MMIO(0x9888), 0x138a8000 },
- { _MMIO(0x9888), 0x1d81a000 },
- { _MMIO(0x9888), 0x15818000 },
- { _MMIO(0x9888), 0x17818000 },
- { _MMIO(0x9888), 0x0b820030 },
- { _MMIO(0x9888), 0x07828000 },
- { _MMIO(0x9888), 0x0d824000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x05824000 },
- { _MMIO(0x9888), 0x0d830003 },
- { _MMIO(0x9888), 0x0583000c },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x03838000 },
- { _MMIO(0x9888), 0x07838000 },
- { _MMIO(0x9888), 0x0b840980 },
- { _MMIO(0x9888), 0x03844d80 },
- { _MMIO(0x9888), 0x11840000 },
- { _MMIO(0x9888), 0x09848000 },
- { _MMIO(0x9888), 0x09850080 },
- { _MMIO(0x9888), 0x03850003 },
- { _MMIO(0x9888), 0x01850000 },
- { _MMIO(0x9888), 0x07860000 },
- { _MMIO(0x9888), 0x0f860400 },
- { _MMIO(0x9888), 0x09870032 },
- { _MMIO(0x9888), 0x01888052 },
- { _MMIO(0x9888), 0x11880000 },
- { _MMIO(0x9888), 0x09884000 },
- { _MMIO(0x9888), 0x1b931001 },
- { _MMIO(0x9888), 0x1d930001 },
- { _MMIO(0x9888), 0x19934000 },
- { _MMIO(0x9888), 0x1b958000 },
- { _MMIO(0x9888), 0x1d950094 },
- { _MMIO(0x9888), 0x19958000 },
- { _MMIO(0x9888), 0x09e58000 },
- { _MMIO(0x9888), 0x0be58000 },
- { _MMIO(0x9888), 0x03e5c000 },
- { _MMIO(0x9888), 0x0592c000 },
- { _MMIO(0x9888), 0x0b928000 },
- { _MMIO(0x9888), 0x0d924000 },
- { _MMIO(0x9888), 0x0f924000 },
- { _MMIO(0x9888), 0x11928000 },
- { _MMIO(0x9888), 0x1392c000 },
- { _MMIO(0x9888), 0x09924000 },
- { _MMIO(0x9888), 0x01985000 },
- { _MMIO(0x9888), 0x07988000 },
- { _MMIO(0x9888), 0x09981000 },
- { _MMIO(0x9888), 0x0b982000 },
- { _MMIO(0x9888), 0x0d982000 },
- { _MMIO(0x9888), 0x0f989000 },
- { _MMIO(0x9888), 0x05982000 },
- { _MMIO(0x9888), 0x13904000 },
- { _MMIO(0x9888), 0x21904000 },
- { _MMIO(0x9888), 0x23904000 },
- { _MMIO(0x9888), 0x25908000 },
- { _MMIO(0x9888), 0x27904000 },
- { _MMIO(0x9888), 0x29908000 },
- { _MMIO(0x9888), 0x2b904000 },
- { _MMIO(0x9888), 0x2f904000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x15904000 },
- { _MMIO(0x9888), 0x17908000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b904000 },
- { _MMIO(0x9888), 0x1190c080 },
- { _MMIO(0x9888), 0x51901110 },
- { _MMIO(0x9888), 0x41900440 },
- { _MMIO(0x9888), 0x55901111 },
- { _MMIO(0x9888), 0x45900400 },
- { _MMIO(0x9888), 0x47900c21 },
- { _MMIO(0x9888), 0x57901411 },
- { _MMIO(0x9888), 0x49900042 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900024 },
- { _MMIO(0x9888), 0x59900001 },
- { _MMIO(0x9888), 0x43900841 },
- { _MMIO(0x9888), 0x53900411 },
-};
-
-static int
-get_render_pipe_profile_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_render_pipe_profile;
- lens[n] = ARRAY_SIZE(mux_config_render_pipe_profile);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_reads[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f872 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_reads[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_reads[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f900064 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900150 },
- { _MMIO(0x9888), 0x21900151 },
- { _MMIO(0x9888), 0x23900152 },
- { _MMIO(0x9888), 0x25900153 },
- { _MMIO(0x9888), 0x27900154 },
- { _MMIO(0x9888), 0x29900155 },
- { _MMIO(0x9888), 0x2b900156 },
- { _MMIO(0x9888), 0x2d900157 },
- { _MMIO(0x9888), 0x2f90015f },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_reads_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_reads;
- lens[n] = ARRAY_SIZE(mux_config_memory_reads);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_memory_writes[] = {
- { _MMIO(0x272c), 0xffffffff },
- { _MMIO(0x2728), 0xffffffff },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x271c), 0xffffffff },
- { _MMIO(0x2718), 0xffffffff },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x274c), 0x86543210 },
- { _MMIO(0x2748), 0x86543210 },
- { _MMIO(0x2744), 0x00006667 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x275c), 0x86543210 },
- { _MMIO(0x2758), 0x86543210 },
- { _MMIO(0x2754), 0x00006465 },
- { _MMIO(0x2750), 0x00000000 },
- { _MMIO(0x2770), 0x0007f81a },
- { _MMIO(0x2774), 0x0000fe00 },
- { _MMIO(0x2778), 0x0007f82a },
- { _MMIO(0x277c), 0x0000fe00 },
- { _MMIO(0x2780), 0x0007f822 },
- { _MMIO(0x2784), 0x0000fe00 },
- { _MMIO(0x2788), 0x0007f8ba },
- { _MMIO(0x278c), 0x0000fe00 },
- { _MMIO(0x2790), 0x0007f87a },
- { _MMIO(0x2794), 0x0000fe00 },
- { _MMIO(0x2798), 0x0007f8ea },
- { _MMIO(0x279c), 0x0000fe00 },
- { _MMIO(0x27a0), 0x0007f8e2 },
- { _MMIO(0x27a4), 0x0000fe00 },
- { _MMIO(0x27a8), 0x0007f8f2 },
- { _MMIO(0x27ac), 0x0000fe00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_memory_writes[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00015014 },
- { _MMIO(0xe658), 0x00025024 },
- { _MMIO(0xe758), 0x00035034 },
- { _MMIO(0xe45c), 0x00045044 },
- { _MMIO(0xe55c), 0x00055054 },
- { _MMIO(0xe65c), 0x00065064 },
-};
-
-static const struct i915_oa_reg mux_config_memory_writes[] = {
- { _MMIO(0x9888), 0x11810c00 },
- { _MMIO(0x9888), 0x1381001a },
- { _MMIO(0x9888), 0x37906800 },
- { _MMIO(0x9888), 0x3f901000 },
- { _MMIO(0x9888), 0x03811300 },
- { _MMIO(0x9888), 0x05811b12 },
- { _MMIO(0x9888), 0x0781001a },
- { _MMIO(0x9888), 0x1f810000 },
- { _MMIO(0x9888), 0x17810000 },
- { _MMIO(0x9888), 0x19810000 },
- { _MMIO(0x9888), 0x1b810000 },
- { _MMIO(0x9888), 0x1d810000 },
- { _MMIO(0x9888), 0x1b930055 },
- { _MMIO(0x9888), 0x03e58000 },
- { _MMIO(0x9888), 0x05e5c000 },
- { _MMIO(0x9888), 0x07e54000 },
- { _MMIO(0x9888), 0x13900160 },
- { _MMIO(0x9888), 0x21900161 },
- { _MMIO(0x9888), 0x23900162 },
- { _MMIO(0x9888), 0x25900163 },
- { _MMIO(0x9888), 0x27900164 },
- { _MMIO(0x9888), 0x29900165 },
- { _MMIO(0x9888), 0x2b900166 },
- { _MMIO(0x9888), 0x2d900167 },
- { _MMIO(0x9888), 0x2f900150 },
- { _MMIO(0x9888), 0x31900105 },
- { _MMIO(0x9888), 0x15900103 },
- { _MMIO(0x9888), 0x17900101 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1d908000 },
- { _MMIO(0x9888), 0x1f908000 },
- { _MMIO(0x9888), 0x11900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c60 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900c63 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c63 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900063 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_memory_writes_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_memory_writes;
- lens[n] = ARRAY_SIZE(mux_config_memory_writes);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extended[] = {
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fc2a },
- { _MMIO(0x2774), 0x0000bf00 },
- { _MMIO(0x2778), 0x0007fc6a },
- { _MMIO(0x277c), 0x0000bf00 },
- { _MMIO(0x2780), 0x0007fc92 },
- { _MMIO(0x2784), 0x0000bf00 },
- { _MMIO(0x2788), 0x0007fca2 },
- { _MMIO(0x278c), 0x0000bf00 },
- { _MMIO(0x2790), 0x0007fc32 },
- { _MMIO(0x2794), 0x0000bf00 },
- { _MMIO(0x2798), 0x0007fc9a },
- { _MMIO(0x279c), 0x0000bf00 },
- { _MMIO(0x27a0), 0x0007fe6a },
- { _MMIO(0x27a4), 0x0000bf00 },
- { _MMIO(0x27a8), 0x0007fe7a },
- { _MMIO(0x27ac), 0x0000bf00 },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extended[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00778008 },
- { _MMIO(0xe45c), 0x00088078 },
- { _MMIO(0xe55c), 0x00808708 },
- { _MMIO(0xe65c), 0x00a08908 },
-};
-
-static const struct i915_oa_reg mux_config_compute_extended[] = {
- { _MMIO(0x9888), 0x106c00e0 },
- { _MMIO(0x9888), 0x141c8160 },
- { _MMIO(0x9888), 0x161c8015 },
- { _MMIO(0x9888), 0x181c0120 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4eaaa0 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0e6c0b01 },
- { _MMIO(0x9888), 0x006c0200 },
- { _MMIO(0x9888), 0x026c000c },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x001c0041 },
- { _MMIO(0x9888), 0x061c4200 },
- { _MMIO(0x9888), 0x081c4443 },
- { _MMIO(0x9888), 0x0a1c4645 },
- { _MMIO(0x9888), 0x0c1c7647 },
- { _MMIO(0x9888), 0x041c7357 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x101c0000 },
- { _MMIO(0x9888), 0x1a1c0000 },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4caa2a },
- { _MMIO(0x9888), 0x0c4c02aa },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x000da000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x0c0f5400 },
- { _MMIO(0x9888), 0x0e0f5515 },
- { _MMIO(0x9888), 0x100f0155 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x11907fff },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900040 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900802 },
- { _MMIO(0x9888), 0x47900842 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900842 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x43900800 },
- { _MMIO(0x9888), 0x53900000 },
-};
-
-static int
-get_compute_extended_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extended;
- lens[n] = ARRAY_SIZE(mux_config_compute_extended);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_l3_cache[] = {
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2770), 0x0007fffa },
- { _MMIO(0x2774), 0x0000fefe },
- { _MMIO(0x2778), 0x0007fffa },
- { _MMIO(0x277c), 0x0000fefd },
- { _MMIO(0x2790), 0x0007fffa },
- { _MMIO(0x2794), 0x0000fbef },
- { _MMIO(0x2798), 0x0007fffa },
- { _MMIO(0x279c), 0x0000fbdf },
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_l3_cache[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00000003 },
- { _MMIO(0xe658), 0x00002001 },
- { _MMIO(0xe758), 0x00101100 },
- { _MMIO(0xe45c), 0x00201200 },
- { _MMIO(0xe55c), 0x00301300 },
- { _MMIO(0xe65c), 0x00401400 },
-};
-
-static const struct i915_oa_reg mux_config_compute_l3_cache[] = {
- { _MMIO(0x9888), 0x166c0760 },
- { _MMIO(0x9888), 0x1593001e },
- { _MMIO(0x9888), 0x3f900003 },
- { _MMIO(0x9888), 0x004e8000 },
- { _MMIO(0x9888), 0x0e4e8000 },
- { _MMIO(0x9888), 0x184e8000 },
- { _MMIO(0x9888), 0x1a4e8020 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x006c0051 },
- { _MMIO(0x9888), 0x066c5000 },
- { _MMIO(0x9888), 0x086c5c5d },
- { _MMIO(0x9888), 0x0e6c5e5f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x186c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x001b4000 },
- { _MMIO(0x9888), 0x061b8000 },
- { _MMIO(0x9888), 0x081bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x101c8000 },
- { _MMIO(0x9888), 0x1a1ce000 },
- { _MMIO(0x9888), 0x1c1c0030 },
- { _MMIO(0x9888), 0x004c8000 },
- { _MMIO(0x9888), 0x0a4c2a00 },
- { _MMIO(0x9888), 0x0c4c0280 },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f1500 },
- { _MMIO(0x9888), 0x100f0140 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162c0a00 },
- { _MMIO(0x9888), 0x182c00a0 },
- { _MMIO(0x9888), 0x03933300 },
- { _MMIO(0x9888), 0x05930032 },
- { _MMIO(0x9888), 0x11930000 },
- { _MMIO(0x9888), 0x1b930000 },
- { _MMIO(0x9888), 0x1d900157 },
- { _MMIO(0x9888), 0x1f900158 },
- { _MMIO(0x9888), 0x35900000 },
- { _MMIO(0x9888), 0x19908000 },
- { _MMIO(0x9888), 0x1b908000 },
- { _MMIO(0x9888), 0x1190030f },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900000 },
- { _MMIO(0x9888), 0x55900000 },
- { _MMIO(0x9888), 0x45900021 },
- { _MMIO(0x9888), 0x47900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x4b900000 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x53905555 },
- { _MMIO(0x9888), 0x43900000 },
-};
-
-static int
-get_compute_l3_cache_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_l3_cache;
- lens[n] = ARRAY_SIZE(mux_config_compute_l3_cache);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_hdc_and_sf[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x10800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000fdff },
-};
-
-static const struct i915_oa_reg flex_eu_config_hdc_and_sf[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_hdc_and_sf[] = {
- { _MMIO(0x9888), 0x104f0232 },
- { _MMIO(0x9888), 0x124f4640 },
- { _MMIO(0x9888), 0x106c0232 },
- { _MMIO(0x9888), 0x11834400 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x004f1880 },
- { _MMIO(0x9888), 0x024f08bb },
- { _MMIO(0x9888), 0x044f001b },
- { _MMIO(0x9888), 0x046c0100 },
- { _MMIO(0x9888), 0x066c000b },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x041b8000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x005b8000 },
- { _MMIO(0x9888), 0x025bc000 },
- { _MMIO(0x9888), 0x045b4000 },
- { _MMIO(0x9888), 0x125c8000 },
- { _MMIO(0x9888), 0x145c8000 },
- { _MMIO(0x9888), 0x165c8000 },
- { _MMIO(0x9888), 0x185c8000 },
- { _MMIO(0x9888), 0x0a4c00a0 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x022cc000 },
- { _MMIO(0x9888), 0x042cc000 },
- { _MMIO(0x9888), 0x062cc000 },
- { _MMIO(0x9888), 0x082cc000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x0f828000 },
- { _MMIO(0x9888), 0x0f8305c0 },
- { _MMIO(0x9888), 0x09830000 },
- { _MMIO(0x9888), 0x07830000 },
- { _MMIO(0x9888), 0x1d950080 },
- { _MMIO(0x9888), 0x13928000 },
- { _MMIO(0x9888), 0x0f988000 },
- { _MMIO(0x9888), 0x31904000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x59900001 },
- { _MMIO(0x9888), 0x4b900040 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_hdc_and_sf_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_hdc_and_sf;
- lens[n] = ARRAY_SIZE(mux_config_hdc_and_sf);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0xf0800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00014002 },
- { _MMIO(0x277c), 0x0000c3ff },
- { _MMIO(0x2780), 0x00010002 },
- { _MMIO(0x2784), 0x0000c7ff },
- { _MMIO(0x2788), 0x00004002 },
- { _MMIO(0x278c), 0x0000d3ff },
- { _MMIO(0x2790), 0x00100700 },
- { _MMIO(0x2794), 0x0000ff1f },
- { _MMIO(0x2798), 0x00001402 },
- { _MMIO(0x279c), 0x0000fc3f },
- { _MMIO(0x27a0), 0x00001002 },
- { _MMIO(0x27a4), 0x0000fc7f },
- { _MMIO(0x27a8), 0x00000402 },
- { _MMIO(0x27ac), 0x0000fd3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_1[] = {
- { _MMIO(0x9888), 0x126c7b40 },
- { _MMIO(0x9888), 0x166c0020 },
- { _MMIO(0x9888), 0x0a603444 },
- { _MMIO(0x9888), 0x0a613400 },
- { _MMIO(0x9888), 0x1a4ea800 },
- { _MMIO(0x9888), 0x1c4e0002 },
- { _MMIO(0x9888), 0x024e8000 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x0c6c5327 },
- { _MMIO(0x9888), 0x0e6c5425 },
- { _MMIO(0x9888), 0x006c2a00 },
- { _MMIO(0x9888), 0x026c285b },
- { _MMIO(0x9888), 0x046c005c },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1c6c0000 },
- { _MMIO(0x9888), 0x1e6c0000 },
- { _MMIO(0x9888), 0x1a6c0800 },
- { _MMIO(0x9888), 0x0c1bc000 },
- { _MMIO(0x9888), 0x0e1bc000 },
- { _MMIO(0x9888), 0x001b8000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x1c1c003c },
- { _MMIO(0x9888), 0x121c8000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x10600000 },
- { _MMIO(0x9888), 0x04600000 },
- { _MMIO(0x9888), 0x0c610044 },
- { _MMIO(0x9888), 0x10610000 },
- { _MMIO(0x9888), 0x06610000 },
- { _MMIO(0x9888), 0x0c4c02a8 },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0154 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x182c00aa },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190ffc0 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900420 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900021 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900400 },
- { _MMIO(0x9888), 0x43900421 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_l3_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_1;
- lens[n] = ARRAY_SIZE(mux_config_l3_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_2[] = {
- { _MMIO(0x9888), 0x126c02e0 },
- { _MMIO(0x9888), 0x146c0001 },
- { _MMIO(0x9888), 0x0a623400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x064f4000 },
- { _MMIO(0x9888), 0x026c3324 },
- { _MMIO(0x9888), 0x046c3422 },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c0000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c0800 },
- { _MMIO(0x9888), 0x065b4000 },
- { _MMIO(0x9888), 0x1a5c1000 },
- { _MMIO(0x9888), 0x06614000 },
- { _MMIO(0x9888), 0x0c620044 },
- { _MMIO(0x9888), 0x10620000 },
- { _MMIO(0x9888), 0x06620000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c002a },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2cc000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900000 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_2;
- lens[n] = ARRAY_SIZE(mux_config_l3_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_l3_3[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00100070 },
- { _MMIO(0x2774), 0x0000fff1 },
- { _MMIO(0x2778), 0x00028002 },
- { _MMIO(0x277c), 0x000087ff },
- { _MMIO(0x2780), 0x00020002 },
- { _MMIO(0x2784), 0x00008fff },
- { _MMIO(0x2788), 0x00008002 },
- { _MMIO(0x278c), 0x0000a7ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_l3_3[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_l3_3[] = {
- { _MMIO(0x9888), 0x126c4e80 },
- { _MMIO(0x9888), 0x146c0000 },
- { _MMIO(0x9888), 0x0a633400 },
- { _MMIO(0x9888), 0x044e8000 },
- { _MMIO(0x9888), 0x064e8000 },
- { _MMIO(0x9888), 0x084e8000 },
- { _MMIO(0x9888), 0x0a4e8000 },
- { _MMIO(0x9888), 0x0c4e8000 },
- { _MMIO(0x9888), 0x026c3321 },
- { _MMIO(0x9888), 0x046c342f },
- { _MMIO(0x9888), 0x106c0000 },
- { _MMIO(0x9888), 0x1a6c2000 },
- { _MMIO(0x9888), 0x021bc000 },
- { _MMIO(0x9888), 0x041bc000 },
- { _MMIO(0x9888), 0x061b4000 },
- { _MMIO(0x9888), 0x141c8000 },
- { _MMIO(0x9888), 0x161c8000 },
- { _MMIO(0x9888), 0x181c8000 },
- { _MMIO(0x9888), 0x1a1c1800 },
- { _MMIO(0x9888), 0x06604000 },
- { _MMIO(0x9888), 0x0c630044 },
- { _MMIO(0x9888), 0x10630000 },
- { _MMIO(0x9888), 0x06630000 },
- { _MMIO(0x9888), 0x084c8000 },
- { _MMIO(0x9888), 0x0a4c00aa },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0f4000 },
- { _MMIO(0x9888), 0x0e0f0055 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190f800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900002 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_l3_3_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_l3_3;
- lens[n] = ARRAY_SIZE(mux_config_l3_3);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x30800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x0000efff },
- { _MMIO(0x2778), 0x00006000 },
- { _MMIO(0x277c), 0x0000f3ff },
-};
-
-static const struct i915_oa_reg flex_eu_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_rasterizer_and_pixel_backend[] = {
- { _MMIO(0x9888), 0x102f3800 },
- { _MMIO(0x9888), 0x144d0500 },
- { _MMIO(0x9888), 0x120d03c0 },
- { _MMIO(0x9888), 0x140d03cf },
- { _MMIO(0x9888), 0x0c0f0004 },
- { _MMIO(0x9888), 0x0c4e4000 },
- { _MMIO(0x9888), 0x042f0480 },
- { _MMIO(0x9888), 0x082f0000 },
- { _MMIO(0x9888), 0x022f0000 },
- { _MMIO(0x9888), 0x0a4c0090 },
- { _MMIO(0x9888), 0x064d0027 },
- { _MMIO(0x9888), 0x004d0000 },
- { _MMIO(0x9888), 0x000d0d40 },
- { _MMIO(0x9888), 0x020d803f },
- { _MMIO(0x9888), 0x040d8023 },
- { _MMIO(0x9888), 0x100d0000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x020f0010 },
- { _MMIO(0x9888), 0x000f0000 },
- { _MMIO(0x9888), 0x0e0f0050 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41901400 },
- { _MMIO(0x9888), 0x43901485 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900001 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_rasterizer_and_pixel_backend_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_rasterizer_and_pixel_backend;
- lens[n] = ARRAY_SIZE(mux_config_rasterizer_and_pixel_backend);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_sampler[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x70800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
- { _MMIO(0x2770), 0x0000c000 },
- { _MMIO(0x2774), 0x0000e7ff },
- { _MMIO(0x2778), 0x00003000 },
- { _MMIO(0x277c), 0x0000f9ff },
- { _MMIO(0x2780), 0x00000c00 },
- { _MMIO(0x2784), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_sampler[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_sampler[] = {
- { _MMIO(0x9888), 0x14152c00 },
- { _MMIO(0x9888), 0x16150005 },
- { _MMIO(0x9888), 0x121600a0 },
- { _MMIO(0x9888), 0x14352c00 },
- { _MMIO(0x9888), 0x16350005 },
- { _MMIO(0x9888), 0x123600a0 },
- { _MMIO(0x9888), 0x14552c00 },
- { _MMIO(0x9888), 0x16550005 },
- { _MMIO(0x9888), 0x125600a0 },
- { _MMIO(0x9888), 0x062f6000 },
- { _MMIO(0x9888), 0x022f2000 },
- { _MMIO(0x9888), 0x0c4c0050 },
- { _MMIO(0x9888), 0x0a4c0010 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0350 },
- { _MMIO(0x9888), 0x0c0fb000 },
- { _MMIO(0x9888), 0x0e0f00da },
- { _MMIO(0x9888), 0x182c0028 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x022dc000 },
- { _MMIO(0x9888), 0x042d4000 },
- { _MMIO(0x9888), 0x0c138000 },
- { _MMIO(0x9888), 0x0e132000 },
- { _MMIO(0x9888), 0x0413c000 },
- { _MMIO(0x9888), 0x1c140018 },
- { _MMIO(0x9888), 0x0c157000 },
- { _MMIO(0x9888), 0x0e150078 },
- { _MMIO(0x9888), 0x10150000 },
- { _MMIO(0x9888), 0x04162180 },
- { _MMIO(0x9888), 0x02160000 },
- { _MMIO(0x9888), 0x04174000 },
- { _MMIO(0x9888), 0x0233a000 },
- { _MMIO(0x9888), 0x04333000 },
- { _MMIO(0x9888), 0x14348000 },
- { _MMIO(0x9888), 0x16348000 },
- { _MMIO(0x9888), 0x02357870 },
- { _MMIO(0x9888), 0x10350000 },
- { _MMIO(0x9888), 0x04360043 },
- { _MMIO(0x9888), 0x02360000 },
- { _MMIO(0x9888), 0x04371000 },
- { _MMIO(0x9888), 0x0e538000 },
- { _MMIO(0x9888), 0x00538000 },
- { _MMIO(0x9888), 0x06533000 },
- { _MMIO(0x9888), 0x1c540020 },
- { _MMIO(0x9888), 0x12548000 },
- { _MMIO(0x9888), 0x0e557000 },
- { _MMIO(0x9888), 0x00557800 },
- { _MMIO(0x9888), 0x10550000 },
- { _MMIO(0x9888), 0x06560043 },
- { _MMIO(0x9888), 0x02560000 },
- { _MMIO(0x9888), 0x06571000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900000 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900060 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900842 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900060 },
-};
-
-static int
-get_sampler_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_sampler;
- lens[n] = ARRAY_SIZE(mux_config_sampler);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_1[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00000002 },
- { _MMIO(0x2774), 0x00007fff },
- { _MMIO(0x2778), 0x00000000 },
- { _MMIO(0x277c), 0x00009fff },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000efff },
- { _MMIO(0x2788), 0x00000000 },
- { _MMIO(0x278c), 0x0000f3ff },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000fdff },
- { _MMIO(0x2798), 0x00000000 },
- { _MMIO(0x279c), 0x0000fe7f },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_1[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_1[] = {
- { _MMIO(0x9888), 0x12120000 },
- { _MMIO(0x9888), 0x12320000 },
- { _MMIO(0x9888), 0x12520000 },
- { _MMIO(0x9888), 0x002f8000 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0015 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f03a0 },
- { _MMIO(0x9888), 0x0c0ff000 },
- { _MMIO(0x9888), 0x0e0f0095 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x0c2d8000 },
- { _MMIO(0x9888), 0x0e2d4000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x02108000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x02118000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x02121880 },
- { _MMIO(0x9888), 0x041219b5 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x02134000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x0c308000 },
- { _MMIO(0x9888), 0x0e304000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x0c318000 },
- { _MMIO(0x9888), 0x0e314000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x0c321a80 },
- { _MMIO(0x9888), 0x0e320033 },
- { _MMIO(0x9888), 0x06320031 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x0c334000 },
- { _MMIO(0x9888), 0x0e331000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0e508000 },
- { _MMIO(0x9888), 0x00508000 },
- { _MMIO(0x9888), 0x02504000 },
- { _MMIO(0x9888), 0x0e518000 },
- { _MMIO(0x9888), 0x00518000 },
- { _MMIO(0x9888), 0x02514000 },
- { _MMIO(0x9888), 0x0e521880 },
- { _MMIO(0x9888), 0x00521a80 },
- { _MMIO(0x9888), 0x02520033 },
- { _MMIO(0x9888), 0x0e534000 },
- { _MMIO(0x9888), 0x00534000 },
- { _MMIO(0x9888), 0x02531000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900800 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900062 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900c00 },
- { _MMIO(0x9888), 0x43900003 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
-};
-
-static int
-get_tdl_1_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_1;
- lens[n] = ARRAY_SIZE(mux_config_tdl_1);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_tdl_2[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2744), 0x00800000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0x00800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x00800000 },
-};
-
-static const struct i915_oa_reg flex_eu_config_tdl_2[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00010003 },
- { _MMIO(0xe658), 0x00012011 },
- { _MMIO(0xe758), 0x00015014 },
- { _MMIO(0xe45c), 0x00051050 },
- { _MMIO(0xe55c), 0x00053052 },
- { _MMIO(0xe65c), 0x00055054 },
-};
-
-static const struct i915_oa_reg mux_config_tdl_2[] = {
- { _MMIO(0x9888), 0x12124d60 },
- { _MMIO(0x9888), 0x12322e60 },
- { _MMIO(0x9888), 0x12524d60 },
- { _MMIO(0x9888), 0x022f3000 },
- { _MMIO(0x9888), 0x0a4c0014 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x0c0fe000 },
- { _MMIO(0x9888), 0x0e0f0097 },
- { _MMIO(0x9888), 0x082c8000 },
- { _MMIO(0x9888), 0x0a2c8000 },
- { _MMIO(0x9888), 0x002d8000 },
- { _MMIO(0x9888), 0x062d4000 },
- { _MMIO(0x9888), 0x0410c000 },
- { _MMIO(0x9888), 0x0411c000 },
- { _MMIO(0x9888), 0x04121fb7 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x04135000 },
- { _MMIO(0x9888), 0x00308000 },
- { _MMIO(0x9888), 0x06304000 },
- { _MMIO(0x9888), 0x00318000 },
- { _MMIO(0x9888), 0x06314000 },
- { _MMIO(0x9888), 0x00321b80 },
- { _MMIO(0x9888), 0x0632003f },
- { _MMIO(0x9888), 0x00334000 },
- { _MMIO(0x9888), 0x06331000 },
- { _MMIO(0x9888), 0x0250c000 },
- { _MMIO(0x9888), 0x0251c000 },
- { _MMIO(0x9888), 0x02521fb7 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x02535000 },
- { _MMIO(0x9888), 0x1190fc00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x51900000 },
- { _MMIO(0x9888), 0x41900800 },
- { _MMIO(0x9888), 0x43900063 },
- { _MMIO(0x9888), 0x53900000 },
- { _MMIO(0x9888), 0x45900040 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_tdl_2_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_tdl_2;
- lens[n] = ARRAY_SIZE(mux_config_tdl_2);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_compute_extra[] = {
-};
-
-static const struct i915_oa_reg flex_eu_config_compute_extra[] = {
-};
-
-static const struct i915_oa_reg mux_config_compute_extra[] = {
- { _MMIO(0x9888), 0x121203e0 },
- { _MMIO(0x9888), 0x123203e0 },
- { _MMIO(0x9888), 0x125203e0 },
- { _MMIO(0x9888), 0x129203e0 },
- { _MMIO(0x9888), 0x12b203e0 },
- { _MMIO(0x9888), 0x12d203e0 },
- { _MMIO(0x9888), 0x131203e0 },
- { _MMIO(0x9888), 0x133203e0 },
- { _MMIO(0x9888), 0x135203e0 },
- { _MMIO(0x9888), 0x1a4ef000 },
- { _MMIO(0x9888), 0x1c4e0003 },
- { _MMIO(0x9888), 0x024ec000 },
- { _MMIO(0x9888), 0x044ec000 },
- { _MMIO(0x9888), 0x064ec000 },
- { _MMIO(0x9888), 0x022f4000 },
- { _MMIO(0x9888), 0x0c4c02a0 },
- { _MMIO(0x9888), 0x084ca000 },
- { _MMIO(0x9888), 0x0a4c0042 },
- { _MMIO(0x9888), 0x0c0d8000 },
- { _MMIO(0x9888), 0x0e0da000 },
- { _MMIO(0x9888), 0x000d8000 },
- { _MMIO(0x9888), 0x020da000 },
- { _MMIO(0x9888), 0x040da000 },
- { _MMIO(0x9888), 0x060d2000 },
- { _MMIO(0x9888), 0x100f0150 },
- { _MMIO(0x9888), 0x0c0f5000 },
- { _MMIO(0x9888), 0x0e0f006d },
- { _MMIO(0x9888), 0x182c00a8 },
- { _MMIO(0x9888), 0x022c8000 },
- { _MMIO(0x9888), 0x042c8000 },
- { _MMIO(0x9888), 0x062c8000 },
- { _MMIO(0x9888), 0x0c2c8000 },
- { _MMIO(0x9888), 0x042d8000 },
- { _MMIO(0x9888), 0x06104000 },
- { _MMIO(0x9888), 0x06114000 },
- { _MMIO(0x9888), 0x06120033 },
- { _MMIO(0x9888), 0x00120000 },
- { _MMIO(0x9888), 0x06131000 },
- { _MMIO(0x9888), 0x04308000 },
- { _MMIO(0x9888), 0x04318000 },
- { _MMIO(0x9888), 0x04321980 },
- { _MMIO(0x9888), 0x00320000 },
- { _MMIO(0x9888), 0x04334000 },
- { _MMIO(0x9888), 0x04504000 },
- { _MMIO(0x9888), 0x04514000 },
- { _MMIO(0x9888), 0x04520033 },
- { _MMIO(0x9888), 0x00520000 },
- { _MMIO(0x9888), 0x04531000 },
- { _MMIO(0x9888), 0x1acef000 },
- { _MMIO(0x9888), 0x1cce0003 },
- { _MMIO(0x9888), 0x00af8000 },
- { _MMIO(0x9888), 0x0ccc02a0 },
- { _MMIO(0x9888), 0x0acc0001 },
- { _MMIO(0x9888), 0x0c8d8000 },
- { _MMIO(0x9888), 0x0e8da000 },
- { _MMIO(0x9888), 0x008d8000 },
- { _MMIO(0x9888), 0x028da000 },
- { _MMIO(0x9888), 0x108f0150 },
- { _MMIO(0x9888), 0x0c8fb000 },
- { _MMIO(0x9888), 0x0e8f0001 },
- { _MMIO(0x9888), 0x18ac00a8 },
- { _MMIO(0x9888), 0x06ac8000 },
- { _MMIO(0x9888), 0x02ad4000 },
- { _MMIO(0x9888), 0x02908000 },
- { _MMIO(0x9888), 0x02918000 },
- { _MMIO(0x9888), 0x02921980 },
- { _MMIO(0x9888), 0x00920000 },
- { _MMIO(0x9888), 0x02934000 },
- { _MMIO(0x9888), 0x02b04000 },
- { _MMIO(0x9888), 0x02b14000 },
- { _MMIO(0x9888), 0x02b20033 },
- { _MMIO(0x9888), 0x00b20000 },
- { _MMIO(0x9888), 0x02b31000 },
- { _MMIO(0x9888), 0x00d08000 },
- { _MMIO(0x9888), 0x00d18000 },
- { _MMIO(0x9888), 0x00d21980 },
- { _MMIO(0x9888), 0x00d34000 },
- { _MMIO(0x9888), 0x072f8000 },
- { _MMIO(0x9888), 0x0d4c0100 },
- { _MMIO(0x9888), 0x0d0d8000 },
- { _MMIO(0x9888), 0x0f0da000 },
- { _MMIO(0x9888), 0x110f01b0 },
- { _MMIO(0x9888), 0x192c0080 },
- { _MMIO(0x9888), 0x0f2d4000 },
- { _MMIO(0x9888), 0x0f108000 },
- { _MMIO(0x9888), 0x0f118000 },
- { _MMIO(0x9888), 0x0f121980 },
- { _MMIO(0x9888), 0x01120000 },
- { _MMIO(0x9888), 0x0f134000 },
- { _MMIO(0x9888), 0x0f304000 },
- { _MMIO(0x9888), 0x0f314000 },
- { _MMIO(0x9888), 0x0f320033 },
- { _MMIO(0x9888), 0x01320000 },
- { _MMIO(0x9888), 0x0f331000 },
- { _MMIO(0x9888), 0x0d508000 },
- { _MMIO(0x9888), 0x0d518000 },
- { _MMIO(0x9888), 0x0d521980 },
- { _MMIO(0x9888), 0x01520000 },
- { _MMIO(0x9888), 0x0d534000 },
- { _MMIO(0x9888), 0x1190ff80 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900c00 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
- { _MMIO(0x9888), 0x4b900002 },
- { _MMIO(0x9888), 0x59900000 },
- { _MMIO(0x9888), 0x51901100 },
- { _MMIO(0x9888), 0x41901000 },
- { _MMIO(0x9888), 0x43901423 },
- { _MMIO(0x9888), 0x53903331 },
- { _MMIO(0x9888), 0x45900044 },
-};
-
-static int
-get_compute_extra_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_compute_extra;
- lens[n] = ARRAY_SIZE(mux_config_compute_extra);
- n++;
-
- return n;
-}
-
-static const struct i915_oa_reg b_counter_config_vme_pipe[] = {
- { _MMIO(0x2740), 0x00000000 },
- { _MMIO(0x2710), 0x00000000 },
- { _MMIO(0x2714), 0xf0800000 },
- { _MMIO(0x2720), 0x00000000 },
- { _MMIO(0x2724), 0x30800000 },
- { _MMIO(0x2770), 0x00100030 },
- { _MMIO(0x2774), 0x0000fff9 },
- { _MMIO(0x2778), 0x00000002 },
- { _MMIO(0x277c), 0x0000fffc },
- { _MMIO(0x2780), 0x00000002 },
- { _MMIO(0x2784), 0x0000fff3 },
- { _MMIO(0x2788), 0x00100180 },
- { _MMIO(0x278c), 0x0000ffcf },
- { _MMIO(0x2790), 0x00000002 },
- { _MMIO(0x2794), 0x0000ffcf },
- { _MMIO(0x2798), 0x00000002 },
- { _MMIO(0x279c), 0x0000ff3f },
-};
-
-static const struct i915_oa_reg flex_eu_config_vme_pipe[] = {
- { _MMIO(0xe458), 0x00005004 },
- { _MMIO(0xe558), 0x00008003 },
-};
-
-static const struct i915_oa_reg mux_config_vme_pipe[] = {
- { _MMIO(0x9888), 0x141a5800 },
- { _MMIO(0x9888), 0x161a00c0 },
- { _MMIO(0x9888), 0x12180240 },
- { _MMIO(0x9888), 0x14180002 },
- { _MMIO(0x9888), 0x149a5800 },
- { _MMIO(0x9888), 0x169a00c0 },
- { _MMIO(0x9888), 0x12980240 },
- { _MMIO(0x9888), 0x14980002 },
- { _MMIO(0x9888), 0x1a4e3fc0 },
- { _MMIO(0x9888), 0x002f1000 },
- { _MMIO(0x9888), 0x022f8000 },
- { _MMIO(0x9888), 0x042f3000 },
- { _MMIO(0x9888), 0x004c4000 },
- { _MMIO(0x9888), 0x0a4c9500 },
- { _MMIO(0x9888), 0x0c4c002a },
- { _MMIO(0x9888), 0x000d2000 },
- { _MMIO(0x9888), 0x060d8000 },
- { _MMIO(0x9888), 0x080da000 },
- { _MMIO(0x9888), 0x0a0da000 },
- { _MMIO(0x9888), 0x0c0da000 },
- { _MMIO(0x9888), 0x0c0f0400 },
- { _MMIO(0x9888), 0x0e0f5500 },
- { _MMIO(0x9888), 0x100f0015 },
- { _MMIO(0x9888), 0x002c8000 },
- { _MMIO(0x9888), 0x0e2c8000 },
- { _MMIO(0x9888), 0x162caa00 },
- { _MMIO(0x9888), 0x182c000a },
- { _MMIO(0x9888), 0x04193000 },
- { _MMIO(0x9888), 0x081a28c1 },
- { _MMIO(0x9888), 0x001a0000 },
- { _MMIO(0x9888), 0x00133000 },
- { _MMIO(0x9888), 0x0613c000 },
- { _MMIO(0x9888), 0x0813f000 },
- { _MMIO(0x9888), 0x00172000 },
- { _MMIO(0x9888), 0x06178000 },
- { _MMIO(0x9888), 0x0817a000 },
- { _MMIO(0x9888), 0x00180037 },
- { _MMIO(0x9888), 0x06180940 },
- { _MMIO(0x9888), 0x08180000 },
- { _MMIO(0x9888), 0x02180000 },
- { _MMIO(0x9888), 0x04183000 },
- { _MMIO(0x9888), 0x04afc000 },
- { _MMIO(0x9888), 0x06af3000 },
- { _MMIO(0x9888), 0x0acc4000 },
- { _MMIO(0x9888), 0x0ccc0015 },
- { _MMIO(0x9888), 0x0a8da000 },
- { _MMIO(0x9888), 0x0c8da000 },
- { _MMIO(0x9888), 0x0e8f4000 },
- { _MMIO(0x9888), 0x108f0015 },
- { _MMIO(0x9888), 0x16aca000 },
- { _MMIO(0x9888), 0x18ac000a },
- { _MMIO(0x9888), 0x06993000 },
- { _MMIO(0x9888), 0x0c9a28c1 },
- { _MMIO(0x9888), 0x009a0000 },
- { _MMIO(0x9888), 0x0a93f000 },
- { _MMIO(0x9888), 0x0c93f000 },
- { _MMIO(0x9888), 0x0a97a000 },
- { _MMIO(0x9888), 0x0c97a000 },
- { _MMIO(0x9888), 0x0a980977 },
- { _MMIO(0x9888), 0x08980000 },
- { _MMIO(0x9888), 0x04980000 },
- { _MMIO(0x9888), 0x06983000 },
- { _MMIO(0x9888), 0x119000ff },
- { _MMIO(0x9888), 0x51900010 },
- { _MMIO(0x9888), 0x41900060 },
- { _MMIO(0x9888), 0x55900111 },
- { _MMIO(0x9888), 0x45900c00 },
- { _MMIO(0x9888), 0x47900821 },
- { _MMIO(0x9888), 0x57900000 },
- { _MMIO(0x9888), 0x49900002 },
- { _MMIO(0x9888), 0x37900000 },
- { _MMIO(0x9888), 0x33900000 },
-};
-
-static int
-get_vme_pipe_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_vme_pipe;
- lens[n] = ARRAY_SIZE(mux_config_vme_pipe);
- n++;
-
- return n;
-}
-
static const struct i915_oa_reg b_counter_config_test_oa[] = {
{ _MMIO(0x2740), 0x00000000 },
{ _MMIO(0x2744), 0x00800000 },
@@ -1984,6 +60,7 @@ static const struct i915_oa_reg flex_eu_config_test_oa[] = {
};
static const struct i915_oa_reg mux_config_test_oa[] = {
+ { _MMIO(0x9840), 0x00000080 },
{ _MMIO(0x9888), 0x11810000 },
{ _MMIO(0x9888), 0x07810013 },
{ _MMIO(0x9888), 0x1f810000 },
@@ -1998,1096 +75,35 @@ static const struct i915_oa_reg mux_config_test_oa[] = {
{ _MMIO(0x9888), 0x33900000 },
};
-static int
-get_test_oa_mux_config(struct drm_i915_private *dev_priv,
- const struct i915_oa_reg **regs,
- int *lens)
-{
- int n = 0;
-
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs) < 1);
- BUILD_BUG_ON(ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens) < 1);
-
- regs[n] = mux_config_test_oa;
- lens[n] = ARRAY_SIZE(mux_config_test_oa);
- n++;
-
- return n;
-}
-
-int i915_oa_select_metric_set_sklgt4(struct drm_i915_private *dev_priv)
-{
- dev_priv->perf.oa.n_mux_configs = 0;
- dev_priv->perf.oa.b_counter_regs = NULL;
- dev_priv->perf.oa.b_counter_regs_len = 0;
- dev_priv->perf.oa.flex_regs = NULL;
- dev_priv->perf.oa.flex_regs_len = 0;
-
- switch (dev_priv->perf.oa.metrics_set) {
- case METRIC_SET_ID_RENDER_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_render_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_basic);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_BASIC:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_basic_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_BASIC\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_basic;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_basic);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_basic;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_basic);
-
- return 0;
- case METRIC_SET_ID_RENDER_PIPE_PROFILE:
- dev_priv->perf.oa.n_mux_configs =
- get_render_pipe_profile_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RENDER_PIPE_PROFILE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_render_pipe_profile;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_render_pipe_profile);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_render_pipe_profile;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_render_pipe_profile);
-
- return 0;
- case METRIC_SET_ID_MEMORY_READS:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_reads_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_READS\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_reads;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_reads);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_reads;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_reads);
-
- return 0;
- case METRIC_SET_ID_MEMORY_WRITES:
- dev_priv->perf.oa.n_mux_configs =
- get_memory_writes_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"MEMORY_WRITES\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_memory_writes;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_memory_writes);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_memory_writes;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_memory_writes);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTENDED:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extended_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTENDED\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extended;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extended);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extended;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extended);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_L3_CACHE:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_l3_cache_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_L3_CACHE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_l3_cache;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_l3_cache);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_l3_cache;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_l3_cache);
-
- return 0;
- case METRIC_SET_ID_HDC_AND_SF:
- dev_priv->perf.oa.n_mux_configs =
- get_hdc_and_sf_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"HDC_AND_SF\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_hdc_and_sf;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_hdc_and_sf);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_hdc_and_sf;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_hdc_and_sf);
-
- return 0;
- case METRIC_SET_ID_L3_1:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_1);
-
- return 0;
- case METRIC_SET_ID_L3_2:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_2);
-
- return 0;
- case METRIC_SET_ID_L3_3:
- dev_priv->perf.oa.n_mux_configs =
- get_l3_3_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"L3_3\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_l3_3;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_l3_3);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_l3_3;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_l3_3);
-
- return 0;
- case METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND:
- dev_priv->perf.oa.n_mux_configs =
- get_rasterizer_and_pixel_backend_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"RASTERIZER_AND_PIXEL_BACKEND\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_rasterizer_and_pixel_backend);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_rasterizer_and_pixel_backend;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_rasterizer_and_pixel_backend);
-
- return 0;
- case METRIC_SET_ID_SAMPLER:
- dev_priv->perf.oa.n_mux_configs =
- get_sampler_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"SAMPLER\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_sampler;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_sampler);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_sampler;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_sampler);
-
- return 0;
- case METRIC_SET_ID_TDL_1:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_1_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_1\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_1;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_1);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_1;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_1);
-
- return 0;
- case METRIC_SET_ID_TDL_2:
- dev_priv->perf.oa.n_mux_configs =
- get_tdl_2_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TDL_2\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_tdl_2;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_tdl_2);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_tdl_2;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_tdl_2);
-
- return 0;
- case METRIC_SET_ID_COMPUTE_EXTRA:
- dev_priv->perf.oa.n_mux_configs =
- get_compute_extra_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"COMPUTE_EXTRA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_compute_extra;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_compute_extra);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_compute_extra;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_compute_extra);
-
- return 0;
- case METRIC_SET_ID_VME_PIPE:
- dev_priv->perf.oa.n_mux_configs =
- get_vme_pipe_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"VME_PIPE\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_vme_pipe;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_vme_pipe);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_vme_pipe;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_vme_pipe);
-
- return 0;
- case METRIC_SET_ID_TEST_OA:
- dev_priv->perf.oa.n_mux_configs =
- get_test_oa_mux_config(dev_priv,
- dev_priv->perf.oa.mux_regs,
- dev_priv->perf.oa.mux_regs_lens);
- if (dev_priv->perf.oa.n_mux_configs == 0) {
- DRM_DEBUG_DRIVER("No suitable MUX config for \"TEST_OA\" metric set\n");
-
- /* EINVAL because *_register_sysfs already checked this
- * and so it wouldn't have been advertised to userspace and
- * so shouldn't have been requested
- */
- return -EINVAL;
- }
-
- dev_priv->perf.oa.b_counter_regs =
- b_counter_config_test_oa;
- dev_priv->perf.oa.b_counter_regs_len =
- ARRAY_SIZE(b_counter_config_test_oa);
-
- dev_priv->perf.oa.flex_regs =
- flex_eu_config_test_oa;
- dev_priv->perf.oa.flex_regs_len =
- ARRAY_SIZE(flex_eu_config_test_oa);
-
- return 0;
- default:
- return -ENODEV;
- }
-}
-
-static ssize_t
-show_render_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_BASIC);
-}
-
-static struct device_attribute dev_attr_render_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_basic[] = {
- &dev_attr_render_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_basic = {
- .name = "bad77c24-cc64-480d-99bf-e7b740713800",
- .attrs = attrs_render_basic,
-};
-
-static ssize_t
-show_compute_basic_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_BASIC);
-}
-
-static struct device_attribute dev_attr_compute_basic_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_basic_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_basic[] = {
- &dev_attr_compute_basic_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_basic = {
- .name = "7277228f-e7f3-4743-945a-6a2049d11377",
- .attrs = attrs_compute_basic,
-};
-
-static ssize_t
-show_render_pipe_profile_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RENDER_PIPE_PROFILE);
-}
-
-static struct device_attribute dev_attr_render_pipe_profile_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_render_pipe_profile_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_render_pipe_profile[] = {
- &dev_attr_render_pipe_profile_id.attr,
- NULL,
-};
-
-static struct attribute_group group_render_pipe_profile = {
- .name = "463c668c-3f60-49b6-8f85-d995b635b3b2",
- .attrs = attrs_render_pipe_profile,
-};
-
-static ssize_t
-show_memory_reads_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_READS);
-}
-
-static struct device_attribute dev_attr_memory_reads_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_reads_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_reads[] = {
- &dev_attr_memory_reads_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_reads = {
- .name = "3ae6e74c-72c3-4040-9bd0-7961430b8cc8",
- .attrs = attrs_memory_reads,
-};
-
-static ssize_t
-show_memory_writes_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_MEMORY_WRITES);
-}
-
-static struct device_attribute dev_attr_memory_writes_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_memory_writes_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_memory_writes[] = {
- &dev_attr_memory_writes_id.attr,
- NULL,
-};
-
-static struct attribute_group group_memory_writes = {
- .name = "055f256d-4052-467c-8dec-6064a4806433",
- .attrs = attrs_memory_writes,
-};
-
-static ssize_t
-show_compute_extended_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTENDED);
-}
-
-static struct device_attribute dev_attr_compute_extended_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extended_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extended[] = {
- &dev_attr_compute_extended_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extended = {
- .name = "753972d4-87cd-4460-824d-754463ac5054",
- .attrs = attrs_compute_extended,
-};
-
-static ssize_t
-show_compute_l3_cache_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_L3_CACHE);
-}
-
-static struct device_attribute dev_attr_compute_l3_cache_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_l3_cache_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_l3_cache[] = {
- &dev_attr_compute_l3_cache_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_l3_cache = {
- .name = "4e4392e9-8f73-457b-ab44-b49f7a0c733b",
- .attrs = attrs_compute_l3_cache,
-};
-
-static ssize_t
-show_hdc_and_sf_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_HDC_AND_SF);
-}
-
-static struct device_attribute dev_attr_hdc_and_sf_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_hdc_and_sf_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_hdc_and_sf[] = {
- &dev_attr_hdc_and_sf_id.attr,
- NULL,
-};
-
-static struct attribute_group group_hdc_and_sf = {
- .name = "730d95dd-7da8-4e1c-ab8d-c0eb1e4c1805",
- .attrs = attrs_hdc_and_sf,
-};
-
-static ssize_t
-show_l3_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_1);
-}
-
-static struct device_attribute dev_attr_l3_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_1[] = {
- &dev_attr_l3_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_1 = {
- .name = "d9e86d70-462b-462a-851e-fd63e8c13d63",
- .attrs = attrs_l3_1,
-};
-
-static ssize_t
-show_l3_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_2);
-}
-
-static struct device_attribute dev_attr_l3_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_2[] = {
- &dev_attr_l3_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_2 = {
- .name = "52200424-6ee9-48b3-b7fa-0afcf1975e4d",
- .attrs = attrs_l3_2,
-};
-
-static ssize_t
-show_l3_3_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_L3_3);
-}
-
-static struct device_attribute dev_attr_l3_3_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_l3_3_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_l3_3[] = {
- &dev_attr_l3_3_id.attr,
- NULL,
-};
-
-static struct attribute_group group_l3_3 = {
- .name = "1988315f-0a26-44df-acb0-df7ec86b1456",
- .attrs = attrs_l3_3,
-};
-
-static ssize_t
-show_rasterizer_and_pixel_backend_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_RASTERIZER_AND_PIXEL_BACKEND);
-}
-
-static struct device_attribute dev_attr_rasterizer_and_pixel_backend_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_rasterizer_and_pixel_backend_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_rasterizer_and_pixel_backend[] = {
- &dev_attr_rasterizer_and_pixel_backend_id.attr,
- NULL,
-};
-
-static struct attribute_group group_rasterizer_and_pixel_backend = {
- .name = "f1f17ca7-286e-4ae5-9d15-9fccad6c665d",
- .attrs = attrs_rasterizer_and_pixel_backend,
-};
-
-static ssize_t
-show_sampler_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_SAMPLER);
-}
-
-static struct device_attribute dev_attr_sampler_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_sampler_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_sampler[] = {
- &dev_attr_sampler_id.attr,
- NULL,
-};
-
-static struct attribute_group group_sampler = {
- .name = "00a9e0fb-3d2e-4405-852c-dce6334ffb3b",
- .attrs = attrs_sampler,
-};
-
-static ssize_t
-show_tdl_1_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_1);
-}
-
-static struct device_attribute dev_attr_tdl_1_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_1_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_1[] = {
- &dev_attr_tdl_1_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_1 = {
- .name = "13dcc50a-7ec0-409b-99d6-a3f932cedcb3",
- .attrs = attrs_tdl_1,
-};
-
-static ssize_t
-show_tdl_2_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TDL_2);
-}
-
-static struct device_attribute dev_attr_tdl_2_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_tdl_2_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_tdl_2[] = {
- &dev_attr_tdl_2_id.attr,
- NULL,
-};
-
-static struct attribute_group group_tdl_2 = {
- .name = "97875e21-6624-4aee-9191-682feb3eae21",
- .attrs = attrs_tdl_2,
-};
-
-static ssize_t
-show_compute_extra_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_COMPUTE_EXTRA);
-}
-
-static struct device_attribute dev_attr_compute_extra_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_compute_extra_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_compute_extra[] = {
- &dev_attr_compute_extra_id.attr,
- NULL,
-};
-
-static struct attribute_group group_compute_extra = {
- .name = "a5aa857d-e8f0-4dfa-8981-ce340fa748fd",
- .attrs = attrs_compute_extra,
-};
-
-static ssize_t
-show_vme_pipe_id(struct device *kdev, struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", METRIC_SET_ID_VME_PIPE);
-}
-
-static struct device_attribute dev_attr_vme_pipe_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_vme_pipe_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_vme_pipe[] = {
- &dev_attr_vme_pipe_id.attr,
- NULL,
-};
-
-static struct attribute_group group_vme_pipe = {
- .name = "0e8d8b86-4ee7-4cdd-aaaa-58adc92cb29e",
- .attrs = attrs_vme_pipe,
-};
-
static ssize_t
show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "%d\n", METRIC_SET_ID_TEST_OA);
+ return sprintf(buf, "1\n");
}
-static struct device_attribute dev_attr_test_oa_id = {
- .attr = { .name = "id", .mode = 0444 },
- .show = show_test_oa_id,
- .store = NULL,
-};
-
-static struct attribute *attrs_test_oa[] = {
- &dev_attr_test_oa_id.attr,
- NULL,
-};
-
-static struct attribute_group group_test_oa = {
- .name = "882fa433-1f4a-4a67-a962-c741888fe5f5",
- .attrs = attrs_test_oa,
-};
-
-int
-i915_perf_register_sysfs_sklgt4(struct drm_i915_private *dev_priv)
+void
+i915_perf_load_test_config_sklgt4(struct drm_i915_private *dev_priv)
{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
- int ret = 0;
+ strncpy(dev_priv->perf.oa.test_config.uuid,
+ "882fa433-1f4a-4a67-a962-c741888fe5f5",
+ UUID_STRING_LEN);
+ dev_priv->perf.oa.test_config.id = 1;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (ret)
- goto error_render_basic;
- }
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (ret)
- goto error_compute_basic;
- }
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (ret)
- goto error_render_pipe_profile;
- }
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (ret)
- goto error_memory_reads;
- }
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (ret)
- goto error_memory_writes;
- }
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (ret)
- goto error_compute_extended;
- }
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (ret)
- goto error_compute_l3_cache;
- }
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (ret)
- goto error_hdc_and_sf;
- }
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (ret)
- goto error_l3_1;
- }
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (ret)
- goto error_l3_2;
- }
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (ret)
- goto error_l3_3;
- }
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (ret)
- goto error_rasterizer_and_pixel_backend;
- }
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (ret)
- goto error_sampler;
- }
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (ret)
- goto error_tdl_1;
- }
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (ret)
- goto error_tdl_2;
- }
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (ret)
- goto error_compute_extra;
- }
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (ret)
- goto error_vme_pipe;
- }
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens)) {
- ret = sysfs_create_group(dev_priv->perf.metrics_kobj, &group_test_oa);
- if (ret)
- goto error_test_oa;
- }
+ dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
+ dev_priv->perf.oa.test_config.mux_regs_len = ARRAY_SIZE(mux_config_test_oa);
- return 0;
+ dev_priv->perf.oa.test_config.b_counter_regs = b_counter_config_test_oa;
+ dev_priv->perf.oa.test_config.b_counter_regs_len = ARRAY_SIZE(b_counter_config_test_oa);
-error_test_oa:
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
-error_vme_pipe:
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
-error_compute_extra:
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
-error_tdl_2:
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
-error_tdl_1:
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
-error_sampler:
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
-error_rasterizer_and_pixel_backend:
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
-error_l3_3:
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
-error_l3_2:
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
-error_l3_1:
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
-error_hdc_and_sf:
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
-error_compute_l3_cache:
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
-error_compute_extended:
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
-error_memory_writes:
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
-error_memory_reads:
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
-error_render_pipe_profile:
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
-error_compute_basic:
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
-error_render_basic:
- return ret;
-}
+ dev_priv->perf.oa.test_config.flex_regs = flex_eu_config_test_oa;
+ dev_priv->perf.oa.test_config.flex_regs_len = ARRAY_SIZE(flex_eu_config_test_oa);
-void
-i915_perf_unregister_sysfs_sklgt4(struct drm_i915_private *dev_priv)
-{
- const struct i915_oa_reg *mux_regs[ARRAY_SIZE(dev_priv->perf.oa.mux_regs)];
- int mux_lens[ARRAY_SIZE(dev_priv->perf.oa.mux_regs_lens)];
+ dev_priv->perf.oa.test_config.sysfs_metric.name = "882fa433-1f4a-4a67-a962-c741888fe5f5";
+ dev_priv->perf.oa.test_config.sysfs_metric.attrs = dev_priv->perf.oa.test_config.attrs;
+
+ dev_priv->perf.oa.test_config.attrs[0] = &dev_priv->perf.oa.test_config.sysfs_metric_id.attr;
- if (get_render_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_basic);
- if (get_compute_basic_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_basic);
- if (get_render_pipe_profile_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_render_pipe_profile);
- if (get_memory_reads_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_reads);
- if (get_memory_writes_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_memory_writes);
- if (get_compute_extended_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extended);
- if (get_compute_l3_cache_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_l3_cache);
- if (get_hdc_and_sf_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_hdc_and_sf);
- if (get_l3_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_1);
- if (get_l3_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_2);
- if (get_l3_3_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_l3_3);
- if (get_rasterizer_and_pixel_backend_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_rasterizer_and_pixel_backend);
- if (get_sampler_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_sampler);
- if (get_tdl_1_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_1);
- if (get_tdl_2_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_tdl_2);
- if (get_compute_extra_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_compute_extra);
- if (get_vme_pipe_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_vme_pipe);
- if (get_test_oa_mux_config(dev_priv, mux_regs, mux_lens))
- sysfs_remove_group(dev_priv->perf.metrics_kobj, &group_test_oa);
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.name = "id";
+ dev_priv->perf.oa.test_config.sysfs_metric_id.attr.mode = 0444;
+ dev_priv->perf.oa.test_config.sysfs_metric_id.show = show_test_oa_id;
}
diff --git a/drivers/gpu/drm/i915/i915_oa_sklgt4.h b/drivers/gpu/drm/i915/i915_oa_sklgt4.h
index 1b718f15f62e..944fd525c8b1 100644
--- a/drivers/gpu/drm/i915/i915_oa_sklgt4.h
+++ b/drivers/gpu/drm/i915/i915_oa_sklgt4.h
@@ -29,12 +29,6 @@
#ifndef __I915_OA_SKLGT4_H__
#define __I915_OA_SKLGT4_H__
-extern int i915_oa_n_builtin_metric_sets_sklgt4;
-
-extern int i915_oa_select_metric_set_sklgt4(struct drm_i915_private *dev_priv);
-
-extern int i915_perf_register_sysfs_sklgt4(struct drm_i915_private *dev_priv);
-
-extern void i915_perf_unregister_sysfs_sklgt4(struct drm_i915_private *dev_priv);
+extern void i915_perf_load_test_config_sklgt4(struct drm_i915_private *dev_priv);
#endif
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index b6a7e363d076..8ab003dca113 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -46,7 +46,7 @@ struct i915_params i915 __read_mostly = {
.prefault_disable = 0,
.load_detect_test = 0,
.force_reset_modeset_test = 0,
- .reset = true,
+ .reset = 2,
.error_capture = true,
.invert_brightness = 0,
.disable_display = 0,
@@ -115,8 +115,12 @@ MODULE_PARM_DESC(vbt_sdvo_panel_type,
"Override/Ignore selection of SDVO panel mode in the VBT "
"(-2=ignore, -1=auto [default], index in VBT BIOS table)");
-module_param_named_unsafe(reset, i915.reset, bool, 0600);
-MODULE_PARM_DESC(reset, "Attempt GPU resets (default: true)");
+module_param_named_unsafe(reset, i915.reset, int, 0600);
+MODULE_PARM_DESC(reset, "Attempt GPU resets (0=disabled, 1=full gpu reset, 2=engine reset [default])");
+
+module_param_named_unsafe(vbt_firmware, i915.vbt_firmware, charp, 0400);
+MODULE_PARM_DESC(vbt_firmware,
+ "Load VBT from specified file under /lib/firmware");
#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
module_param_named(error_capture, i915.error_capture, bool, 0600);
diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
index 34148cc8637c..ac844709c97e 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -28,6 +28,7 @@
#include <linux/cache.h> /* for __read_mostly */
#define I915_PARAMS_FOR_EACH(func) \
+ func(char *, vbt_firmware); \
func(int, modeset); \
func(int, panel_ignore_lid); \
func(int, semaphores); \
@@ -51,6 +52,7 @@
func(int, use_mmio_flip); \
func(int, mmio_debug); \
func(int, edp_vswing); \
+ func(int, reset); \
func(unsigned int, inject_load_failure); \
/* leave bools at the end to not create holes */ \
func(bool, alpha_support); \
@@ -60,7 +62,6 @@
func(bool, prefault_disable); \
func(bool, load_detect_test); \
func(bool, force_reset_modeset_test); \
- func(bool, reset); \
func(bool, error_capture); \
func(bool, disable_display); \
func(bool, verbose_state_checks); \
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 506ec32b9e53..09d97e0990b7 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -310,7 +310,8 @@ static const struct intel_device_info intel_haswell_info = {
BDW_COLORS, \
.has_logical_ring_contexts = 1, \
.has_full_48bit_ppgtt = 1, \
- .has_64bit_reloc = 1
+ .has_64bit_reloc = 1, \
+ .has_reset_engine = 1
#define BDW_PLATFORM \
BDW_FEATURES, \
@@ -342,6 +343,7 @@ static const struct intel_device_info intel_cherryview_info = {
.has_gmch_display = 1,
.has_aliasing_ppgtt = 1,
.has_full_ppgtt = 1,
+ .has_reset_engine = 1,
.display_mmio_offset = VLV_DISPLAY_BASE,
GEN_CHV_PIPEOFFSETS,
CURSOR_OFFSETS,
@@ -387,6 +389,7 @@ static const struct intel_device_info intel_skylake_gt3_info = {
.has_aliasing_ppgtt = 1, \
.has_full_ppgtt = 1, \
.has_full_48bit_ppgtt = 1, \
+ .has_reset_engine = 1, \
GEN_DEFAULT_PIPEOFFSETS, \
IVB_CURSOR_OFFSETS, \
BDW_COLORS
@@ -395,6 +398,7 @@ static const struct intel_device_info intel_broxton_info = {
GEN9_LP_FEATURES,
.platform = INTEL_BROXTON,
.ddb_size = 512,
+ .has_reset_engine = false,
};
static const struct intel_device_info intel_geminilake_info = {
@@ -446,6 +450,7 @@ static const struct intel_device_info intel_cannonlake_info = {
.gen = 10,
.ddb_size = 1024,
.has_csr = 1,
+ .color = { .degamma_lut_size = 0, .gamma_lut_size = 1024 }
};
/*
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index 9cd22f83b0cf..94185d610673 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -193,6 +193,7 @@
#include <linux/anon_inodes.h>
#include <linux/sizes.h>
+#include <linux/uuid.h>
#include "i915_drv.h"
#include "i915_oa_hsw.h"
@@ -357,6 +358,54 @@ struct perf_open_properties {
int oa_period_exponent;
};
+static void free_oa_config(struct drm_i915_private *dev_priv,
+ struct i915_oa_config *oa_config)
+{
+ if (!PTR_ERR(oa_config->flex_regs))
+ kfree(oa_config->flex_regs);
+ if (!PTR_ERR(oa_config->b_counter_regs))
+ kfree(oa_config->b_counter_regs);
+ if (!PTR_ERR(oa_config->mux_regs))
+ kfree(oa_config->mux_regs);
+ kfree(oa_config);
+}
+
+static void put_oa_config(struct drm_i915_private *dev_priv,
+ struct i915_oa_config *oa_config)
+{
+ if (!atomic_dec_and_test(&oa_config->ref_count))
+ return;
+
+ free_oa_config(dev_priv, oa_config);
+}
+
+static int get_oa_config(struct drm_i915_private *dev_priv,
+ int metrics_set,
+ struct i915_oa_config **out_config)
+{
+ int ret;
+
+ if (metrics_set == 1) {
+ *out_config = &dev_priv->perf.oa.test_config;
+ atomic_inc(&dev_priv->perf.oa.test_config.ref_count);
+ return 0;
+ }
+
+ ret = mutex_lock_interruptible(&dev_priv->perf.metrics_lock);
+ if (ret)
+ return ret;
+
+ *out_config = idr_find(&dev_priv->perf.metrics_idr, metrics_set);
+ if (!*out_config)
+ ret = -EINVAL;
+ else
+ atomic_inc(&(*out_config)->ref_count);
+
+ mutex_unlock(&dev_priv->perf.metrics_lock);
+
+ return ret;
+}
+
static u32 gen8_oa_hw_tail_read(struct drm_i915_private *dev_priv)
{
return I915_READ(GEN8_OATAILPTR) & GEN8_OATAILPTR_MASK;
@@ -1246,10 +1295,12 @@ static void i915_oa_stream_destroy(struct i915_perf_stream *stream)
BUG_ON(stream != dev_priv->perf.oa.exclusive_stream);
/*
- * Unset exclusive_stream first, it might be checked while
- * disabling the metric set on gen8+.
+ * Unset exclusive_stream first, it will be checked while disabling
+ * the metric set on gen8+.
*/
+ mutex_lock(&dev_priv->drm.struct_mutex);
dev_priv->perf.oa.exclusive_stream = NULL;
+ mutex_unlock(&dev_priv->drm.struct_mutex);
dev_priv->perf.oa.ops.disable_metric_set(dev_priv);
@@ -1261,6 +1312,8 @@ static void i915_oa_stream_destroy(struct i915_perf_stream *stream)
if (stream->ctx)
oa_put_render_ctx_id(stream);
+ put_oa_config(dev_priv, stream->oa_config);
+
if (dev_priv->perf.oa.spurious_report_rs.missed) {
DRM_NOTE("%d spurious OA report notices suppressed due to ratelimiting\n",
dev_priv->perf.oa.spurious_report_rs.missed);
@@ -1440,9 +1493,9 @@ unlock:
static void config_oa_regs(struct drm_i915_private *dev_priv,
const struct i915_oa_reg *regs,
- int n_regs)
+ u32 n_regs)
{
- int i;
+ u32 i;
for (i = 0; i < n_regs; i++) {
const struct i915_oa_reg *reg = regs + i;
@@ -1451,17 +1504,9 @@ static void config_oa_regs(struct drm_i915_private *dev_priv,
}
}
-static int hsw_enable_metric_set(struct drm_i915_private *dev_priv)
+static int hsw_enable_metric_set(struct drm_i915_private *dev_priv,
+ const struct i915_oa_config *oa_config)
{
- int ret = i915_oa_select_metric_set_hsw(dev_priv);
- int i;
-
- if (ret)
- return ret;
-
- I915_WRITE(GDT_CHICKEN_BITS, (I915_READ(GDT_CHICKEN_BITS) |
- GT_NOA_ENABLE));
-
/* PRM:
*
* OA unit is using “crclk” for its functionality. When trunk
@@ -1476,10 +1521,7 @@ static int hsw_enable_metric_set(struct drm_i915_private *dev_priv)
I915_WRITE(GEN6_UCGCTL1, (I915_READ(GEN6_UCGCTL1) |
GEN6_CSUNIT_CLOCK_GATE_DISABLE));
- for (i = 0; i < dev_priv->perf.oa.n_mux_configs; i++) {
- config_oa_regs(dev_priv, dev_priv->perf.oa.mux_regs[i],
- dev_priv->perf.oa.mux_regs_lens[i]);
- }
+ config_oa_regs(dev_priv, oa_config->mux_regs, oa_config->mux_regs_len);
/* It apparently takes a fairly long time for a new MUX
* configuration to be be applied after these register writes.
@@ -1504,8 +1546,8 @@ static int hsw_enable_metric_set(struct drm_i915_private *dev_priv)
*/
usleep_range(15000, 20000);
- config_oa_regs(dev_priv, dev_priv->perf.oa.b_counter_regs,
- dev_priv->perf.oa.b_counter_regs_len);
+ config_oa_regs(dev_priv, oa_config->b_counter_regs,
+ oa_config->b_counter_regs_len);
return 0;
}
@@ -1529,11 +1571,10 @@ static void hsw_disable_metric_set(struct drm_i915_private *dev_priv)
* in the case that the OA unit has been disabled.
*/
static void gen8_update_reg_state_unlocked(struct i915_gem_context *ctx,
- u32 *reg_state)
+ u32 *reg_state,
+ const struct i915_oa_config *oa_config)
{
struct drm_i915_private *dev_priv = ctx->i915;
- const struct i915_oa_reg *flex_regs = dev_priv->perf.oa.flex_regs;
- int n_flex_regs = dev_priv->perf.oa.flex_regs_len;
u32 ctx_oactxctrl = dev_priv->perf.oa.ctx_oactxctrl_offset;
u32 ctx_flexeu0 = dev_priv->perf.oa.ctx_flexeu0_offset;
/* The MMIO offsets for Flex EU registers aren't contiguous */
@@ -1565,12 +1606,15 @@ static void gen8_update_reg_state_unlocked(struct i915_gem_context *ctx,
* will be an explicit 'No Event' we can select, but not yet...
*/
u32 value = 0;
- int j;
- for (j = 0; j < n_flex_regs; j++) {
- if (i915_mmio_reg_offset(flex_regs[j].addr) == mmio) {
- value = flex_regs[j].value;
- break;
+ if (oa_config) {
+ u32 j;
+
+ for (j = 0; j < oa_config->flex_regs_len; j++) {
+ if (i915_mmio_reg_offset(oa_config->flex_regs[j].addr) == mmio) {
+ value = oa_config->flex_regs[j].value;
+ break;
+ }
}
}
@@ -1583,11 +1627,10 @@ static void gen8_update_reg_state_unlocked(struct i915_gem_context *ctx,
* Same as gen8_update_reg_state_unlocked only through the batchbuffer. This
* is only used by the kernel context.
*/
-static int gen8_emit_oa_config(struct drm_i915_gem_request *req)
+static int gen8_emit_oa_config(struct drm_i915_gem_request *req,
+ const struct i915_oa_config *oa_config)
{
struct drm_i915_private *dev_priv = req->i915;
- const struct i915_oa_reg *flex_regs = dev_priv->perf.oa.flex_regs;
- int n_flex_regs = dev_priv->perf.oa.flex_regs_len;
/* The MMIO offsets for Flex EU registers aren't contiguous */
u32 flex_mmio[] = {
i915_mmio_reg_offset(EU_PERF_CNTL0),
@@ -1601,11 +1644,11 @@ static int gen8_emit_oa_config(struct drm_i915_gem_request *req)
u32 *cs;
int i;
- cs = intel_ring_begin(req, n_flex_regs * 2 + 4);
+ cs = intel_ring_begin(req, ARRAY_SIZE(flex_mmio) * 2 + 4);
if (IS_ERR(cs))
return PTR_ERR(cs);
- *cs++ = MI_LOAD_REGISTER_IMM(n_flex_regs + 1);
+ *cs++ = MI_LOAD_REGISTER_IMM(ARRAY_SIZE(flex_mmio) + 1);
*cs++ = i915_mmio_reg_offset(GEN8_OACTXCONTROL);
*cs++ = (dev_priv->perf.oa.period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) |
@@ -1622,12 +1665,15 @@ static int gen8_emit_oa_config(struct drm_i915_gem_request *req)
* yet...
*/
u32 value = 0;
- int j;
- for (j = 0; j < n_flex_regs; j++) {
- if (i915_mmio_reg_offset(flex_regs[j].addr) == mmio) {
- value = flex_regs[j].value;
- break;
+ if (oa_config) {
+ u32 j;
+
+ for (j = 0; j < oa_config->flex_regs_len; j++) {
+ if (i915_mmio_reg_offset(oa_config->flex_regs[j].addr) == mmio) {
+ value = oa_config->flex_regs[j].value;
+ break;
+ }
}
}
@@ -1641,7 +1687,8 @@ static int gen8_emit_oa_config(struct drm_i915_gem_request *req)
return 0;
}
-static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_priv)
+static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_priv,
+ const struct i915_oa_config *oa_config)
{
struct intel_engine_cs *engine = dev_priv->engine[RCS];
struct i915_gem_timeline *timeline;
@@ -1656,7 +1703,7 @@ static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_pr
if (IS_ERR(req))
return PTR_ERR(req);
- ret = gen8_emit_oa_config(req);
+ ret = gen8_emit_oa_config(req, oa_config);
if (ret) {
i915_add_request(req);
return ret;
@@ -1707,6 +1754,7 @@ static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_pr
* Note: it's only the RCS/Render context that has any OA state.
*/
static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
+ const struct i915_oa_config *oa_config,
bool interruptible)
{
struct i915_gem_context *ctx;
@@ -1724,7 +1772,7 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
}
/* Switch away from any user context. */
- ret = gen8_switch_to_updated_kernel_context(dev_priv);
+ ret = gen8_switch_to_updated_kernel_context(dev_priv, oa_config);
if (ret)
goto out;
@@ -1746,7 +1794,7 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
goto out;
/* Update all contexts now that we've stalled the submission. */
- list_for_each_entry(ctx, &dev_priv->context_list, link) {
+ list_for_each_entry(ctx, &dev_priv->contexts.list, link) {
struct intel_context *ce = &ctx->engine[RCS];
u32 *regs;
@@ -1763,7 +1811,7 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
ce->state->obj->mm.dirty = true;
regs += LRC_STATE_PN * PAGE_SIZE / sizeof(*regs);
- gen8_update_reg_state_unlocked(ctx, regs);
+ gen8_update_reg_state_unlocked(ctx, regs, oa_config);
i915_gem_object_unpin_map(ce->state->obj);
}
@@ -1774,13 +1822,10 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv,
return ret;
}
-static int gen8_enable_metric_set(struct drm_i915_private *dev_priv)
+static int gen8_enable_metric_set(struct drm_i915_private *dev_priv,
+ const struct i915_oa_config *oa_config)
{
- int ret = dev_priv->perf.oa.ops.select_metric_set(dev_priv);
- int i;
-
- if (ret)
- return ret;
+ int ret;
/*
* We disable slice/unslice clock ratio change reports on SKL since
@@ -1817,19 +1862,14 @@ static int gen8_enable_metric_set(struct drm_i915_private *dev_priv)
* to make sure all slices/subslices are ON before writing to NOA
* registers.
*/
- ret = gen8_configure_all_contexts(dev_priv, true);
+ ret = gen8_configure_all_contexts(dev_priv, oa_config, true);
if (ret)
return ret;
- I915_WRITE(GDT_CHICKEN_BITS, 0xA0);
- for (i = 0; i < dev_priv->perf.oa.n_mux_configs; i++) {
- config_oa_regs(dev_priv, dev_priv->perf.oa.mux_regs[i],
- dev_priv->perf.oa.mux_regs_lens[i]);
- }
- I915_WRITE(GDT_CHICKEN_BITS, 0x80);
+ config_oa_regs(dev_priv, oa_config->mux_regs, oa_config->mux_regs_len);
- config_oa_regs(dev_priv, dev_priv->perf.oa.b_counter_regs,
- dev_priv->perf.oa.b_counter_regs_len);
+ config_oa_regs(dev_priv, oa_config->b_counter_regs,
+ oa_config->b_counter_regs_len);
return 0;
}
@@ -1837,7 +1877,11 @@ static int gen8_enable_metric_set(struct drm_i915_private *dev_priv)
static void gen8_disable_metric_set(struct drm_i915_private *dev_priv)
{
/* Reset all contexts' slices/subslices configurations. */
- gen8_configure_all_contexts(dev_priv, false);
+ gen8_configure_all_contexts(dev_priv, NULL, false);
+
+ I915_WRITE(GDT_CHICKEN_BITS, (I915_READ(GDT_CHICKEN_BITS) &
+ ~GT_NOA_ENABLE));
+
}
static void gen7_oa_enable(struct drm_i915_private *dev_priv)
@@ -2011,11 +2055,6 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
return -EBUSY;
}
- if (!props->metrics_set) {
- DRM_DEBUG("OA metric set not specified\n");
- return -EINVAL;
- }
-
if (!props->oa_format) {
DRM_DEBUG("OA report format not specified\n");
return -EINVAL;
@@ -2055,8 +2094,6 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
dev_priv->perf.oa.oa_buffer.format =
dev_priv->perf.oa.oa_formats[props->oa_format].format;
- dev_priv->perf.oa.metrics_set = props->metrics_set;
-
dev_priv->perf.oa.periodic = props->oa_periodic;
if (dev_priv->perf.oa.periodic)
dev_priv->perf.oa.period_exponent = props->oa_period_exponent;
@@ -2067,6 +2104,10 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
return ret;
}
+ ret = get_oa_config(dev_priv, props->metrics_set, &stream->oa_config);
+ if (ret)
+ goto err_config;
+
/* PRM - observability performance counters:
*
* OACONTROL, performance counter enable, note:
@@ -2086,22 +2127,39 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
if (ret)
goto err_oa_buf_alloc;
- ret = dev_priv->perf.oa.ops.enable_metric_set(dev_priv);
+ ret = dev_priv->perf.oa.ops.enable_metric_set(dev_priv,
+ stream->oa_config);
if (ret)
goto err_enable;
stream->ops = &i915_oa_stream_ops;
+ /* Lock device for exclusive_stream access late because
+ * enable_metric_set() might lock as well on gen8+.
+ */
+ ret = i915_mutex_lock_interruptible(&dev_priv->drm);
+ if (ret)
+ goto err_lock;
+
dev_priv->perf.oa.exclusive_stream = stream;
+ mutex_unlock(&dev_priv->drm.struct_mutex);
+
return 0;
+err_lock:
+ dev_priv->perf.oa.ops.disable_metric_set(dev_priv);
+
err_enable:
free_oa_buffer(dev_priv);
err_oa_buf_alloc:
+ put_oa_config(dev_priv, stream->oa_config);
+
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
intel_runtime_pm_put(dev_priv);
+
+err_config:
if (stream->ctx)
oa_put_render_ctx_id(stream);
@@ -2112,15 +2170,14 @@ void i915_oa_init_reg_state(struct intel_engine_cs *engine,
struct i915_gem_context *ctx,
u32 *reg_state)
{
- struct drm_i915_private *dev_priv = engine->i915;
+ struct i915_perf_stream *stream;
if (engine->id != RCS)
return;
- if (!dev_priv->perf.initialized)
- return;
-
- gen8_update_reg_state_unlocked(ctx, reg_state);
+ stream = engine->i915->perf.oa.exclusive_stream;
+ if (stream)
+ gen8_update_reg_state_unlocked(ctx, reg_state, stream->oa_config);
}
/**
@@ -2444,7 +2501,7 @@ static void i915_perf_destroy_locked(struct i915_perf_stream *stream)
list_del(&stream->link);
if (stream->ctx)
- i915_gem_context_put_unlocked(stream->ctx);
+ i915_gem_context_put(stream->ctx);
kfree(stream);
}
@@ -2483,27 +2540,6 @@ static const struct file_operations fops = {
};
-static struct i915_gem_context *
-lookup_context(struct drm_i915_private *dev_priv,
- struct drm_i915_file_private *file_priv,
- u32 ctx_user_handle)
-{
- struct i915_gem_context *ctx;
- int ret;
-
- ret = i915_mutex_lock_interruptible(&dev_priv->drm);
- if (ret)
- return ERR_PTR(ret);
-
- ctx = i915_gem_context_lookup(file_priv, ctx_user_handle);
- if (!IS_ERR(ctx))
- i915_gem_context_get(ctx);
-
- mutex_unlock(&dev_priv->drm.struct_mutex);
-
- return ctx;
-}
-
/**
* i915_perf_open_ioctl_locked - DRM ioctl() for userspace to open a stream FD
* @dev_priv: i915 device instance
@@ -2545,12 +2581,11 @@ i915_perf_open_ioctl_locked(struct drm_i915_private *dev_priv,
u32 ctx_handle = props->ctx_handle;
struct drm_i915_file_private *file_priv = file->driver_priv;
- specific_ctx = lookup_context(dev_priv, file_priv, ctx_handle);
- if (IS_ERR(specific_ctx)) {
- ret = PTR_ERR(specific_ctx);
- if (ret != -EINTR)
- DRM_DEBUG("Failed to look up context with ID %u for opening perf stream\n",
- ctx_handle);
+ specific_ctx = i915_gem_context_lookup(file_priv, ctx_handle);
+ if (!specific_ctx) {
+ DRM_DEBUG("Failed to look up context with ID %u for opening perf stream\n",
+ ctx_handle);
+ ret = -ENOENT;
goto err;
}
}
@@ -2633,7 +2668,7 @@ err_alloc:
kfree(stream);
err_ctx:
if (specific_ctx)
- i915_gem_context_put_unlocked(specific_ctx);
+ i915_gem_context_put(specific_ctx);
err:
return ret;
}
@@ -2665,7 +2700,7 @@ static int read_properties_unlocked(struct drm_i915_private *dev_priv,
struct perf_open_properties *props)
{
u64 __user *uprop = uprops;
- int i;
+ u32 i;
memset(props, 0, sizeof(struct perf_open_properties));
@@ -2712,8 +2747,7 @@ static int read_properties_unlocked(struct drm_i915_private *dev_priv,
props->sample_flags |= SAMPLE_OA_REPORT;
break;
case DRM_I915_PERF_PROP_OA_METRICS_SET:
- if (value == 0 ||
- value > dev_priv->perf.oa.n_builtin_sets) {
+ if (value == 0) {
DRM_DEBUG("Unknown OA metric set ID\n");
return -EINVAL;
}
@@ -2852,6 +2886,8 @@ int i915_perf_open_ioctl(struct drm_device *dev, void *data,
*/
void i915_perf_register(struct drm_i915_private *dev_priv)
{
+ int ret;
+
if (!dev_priv->perf.initialized)
return;
@@ -2867,44 +2903,42 @@ void i915_perf_register(struct drm_i915_private *dev_priv)
if (!dev_priv->perf.metrics_kobj)
goto exit;
+ sysfs_attr_init(&dev_priv->perf.oa.test_config.sysfs_metric_id.attr);
+
if (IS_HASWELL(dev_priv)) {
- if (i915_perf_register_sysfs_hsw(dev_priv))
- goto sysfs_error;
+ i915_perf_load_test_config_hsw(dev_priv);
} else if (IS_BROADWELL(dev_priv)) {
- if (i915_perf_register_sysfs_bdw(dev_priv))
- goto sysfs_error;
+ i915_perf_load_test_config_bdw(dev_priv);
} else if (IS_CHERRYVIEW(dev_priv)) {
- if (i915_perf_register_sysfs_chv(dev_priv))
- goto sysfs_error;
+ i915_perf_load_test_config_chv(dev_priv);
} else if (IS_SKYLAKE(dev_priv)) {
- if (IS_SKL_GT2(dev_priv)) {
- if (i915_perf_register_sysfs_sklgt2(dev_priv))
- goto sysfs_error;
- } else if (IS_SKL_GT3(dev_priv)) {
- if (i915_perf_register_sysfs_sklgt3(dev_priv))
- goto sysfs_error;
- } else if (IS_SKL_GT4(dev_priv)) {
- if (i915_perf_register_sysfs_sklgt4(dev_priv))
- goto sysfs_error;
- } else
- goto sysfs_error;
+ if (IS_SKL_GT2(dev_priv))
+ i915_perf_load_test_config_sklgt2(dev_priv);
+ else if (IS_SKL_GT3(dev_priv))
+ i915_perf_load_test_config_sklgt3(dev_priv);
+ else if (IS_SKL_GT4(dev_priv))
+ i915_perf_load_test_config_sklgt4(dev_priv);
} else if (IS_BROXTON(dev_priv)) {
- if (i915_perf_register_sysfs_bxt(dev_priv))
- goto sysfs_error;
+ i915_perf_load_test_config_bxt(dev_priv);
} else if (IS_KABYLAKE(dev_priv)) {
- if (IS_KBL_GT2(dev_priv)) {
- if (i915_perf_register_sysfs_kblgt2(dev_priv))
- goto sysfs_error;
- } else if (IS_KBL_GT3(dev_priv)) {
- if (i915_perf_register_sysfs_kblgt3(dev_priv))
- goto sysfs_error;
- } else
- goto sysfs_error;
+ if (IS_KBL_GT2(dev_priv))
+ i915_perf_load_test_config_kblgt2(dev_priv);
+ else if (IS_KBL_GT3(dev_priv))
+ i915_perf_load_test_config_kblgt3(dev_priv);
} else if (IS_GEMINILAKE(dev_priv)) {
- if (i915_perf_register_sysfs_glk(dev_priv))
- goto sysfs_error;
+ i915_perf_load_test_config_glk(dev_priv);
}
+ if (dev_priv->perf.oa.test_config.id == 0)
+ goto sysfs_error;
+
+ ret = sysfs_create_group(dev_priv->perf.metrics_kobj,
+ &dev_priv->perf.oa.test_config.sysfs_metric);
+ if (ret)
+ goto sysfs_error;
+
+ atomic_set(&dev_priv->perf.oa.test_config.ref_count, 1);
+
goto exit;
sysfs_error:
@@ -2929,34 +2963,375 @@ void i915_perf_unregister(struct drm_i915_private *dev_priv)
if (!dev_priv->perf.metrics_kobj)
return;
- if (IS_HASWELL(dev_priv))
- i915_perf_unregister_sysfs_hsw(dev_priv);
- else if (IS_BROADWELL(dev_priv))
- i915_perf_unregister_sysfs_bdw(dev_priv);
- else if (IS_CHERRYVIEW(dev_priv))
- i915_perf_unregister_sysfs_chv(dev_priv);
- else if (IS_SKYLAKE(dev_priv)) {
- if (IS_SKL_GT2(dev_priv))
- i915_perf_unregister_sysfs_sklgt2(dev_priv);
- else if (IS_SKL_GT3(dev_priv))
- i915_perf_unregister_sysfs_sklgt3(dev_priv);
- else if (IS_SKL_GT4(dev_priv))
- i915_perf_unregister_sysfs_sklgt4(dev_priv);
- } else if (IS_BROXTON(dev_priv))
- i915_perf_unregister_sysfs_bxt(dev_priv);
- else if (IS_KABYLAKE(dev_priv)) {
- if (IS_KBL_GT2(dev_priv))
- i915_perf_unregister_sysfs_kblgt2(dev_priv);
- else if (IS_KBL_GT3(dev_priv))
- i915_perf_unregister_sysfs_kblgt3(dev_priv);
- } else if (IS_GEMINILAKE(dev_priv))
- i915_perf_unregister_sysfs_glk(dev_priv);
-
+ sysfs_remove_group(dev_priv->perf.metrics_kobj,
+ &dev_priv->perf.oa.test_config.sysfs_metric);
kobject_put(dev_priv->perf.metrics_kobj);
dev_priv->perf.metrics_kobj = NULL;
}
+static bool gen8_is_valid_flex_addr(struct drm_i915_private *dev_priv, u32 addr)
+{
+ static const i915_reg_t flex_eu_regs[] = {
+ EU_PERF_CNTL0,
+ EU_PERF_CNTL1,
+ EU_PERF_CNTL2,
+ EU_PERF_CNTL3,
+ EU_PERF_CNTL4,
+ EU_PERF_CNTL5,
+ EU_PERF_CNTL6,
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(flex_eu_regs); i++) {
+ if (flex_eu_regs[i].reg == addr)
+ return true;
+ }
+ return false;
+}
+
+static bool gen7_is_valid_b_counter_addr(struct drm_i915_private *dev_priv, u32 addr)
+{
+ return (addr >= OASTARTTRIG1.reg && addr <= OASTARTTRIG8.reg) ||
+ (addr >= OAREPORTTRIG1.reg && addr <= OAREPORTTRIG8.reg) ||
+ (addr >= OACEC0_0.reg && addr <= OACEC7_1.reg);
+}
+
+static bool gen7_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr)
+{
+ return addr == HALF_SLICE_CHICKEN2.reg ||
+ (addr >= MICRO_BP0_0.reg && addr <= NOA_WRITE.reg) ||
+ (addr >= OA_PERFCNT1_LO.reg && addr <= OA_PERFCNT2_HI.reg) ||
+ (addr >= OA_PERFMATRIX_LO.reg && addr <= OA_PERFMATRIX_HI.reg);
+}
+
+static bool gen8_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr)
+{
+ return gen7_is_valid_mux_addr(dev_priv, addr) ||
+ addr == WAIT_FOR_RC6_EXIT.reg ||
+ (addr >= RPM_CONFIG0.reg && addr <= NOA_CONFIG(8).reg);
+}
+
+static bool hsw_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr)
+{
+ return gen7_is_valid_mux_addr(dev_priv, addr) ||
+ (addr >= 0x25100 && addr <= 0x2FF90) ||
+ addr == 0x9ec0;
+}
+
+static bool chv_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr)
+{
+ return gen7_is_valid_mux_addr(dev_priv, addr) ||
+ (addr >= 0x182300 && addr <= 0x1823A4);
+}
+
+static uint32_t mask_reg_value(u32 reg, u32 val)
+{
+ /* HALF_SLICE_CHICKEN2 is programmed with a the
+ * WaDisableSTUnitPowerOptimization workaround. Make sure the value
+ * programmed by userspace doesn't change this.
+ */
+ if (HALF_SLICE_CHICKEN2.reg == reg)
+ val = val & ~_MASKED_BIT_ENABLE(GEN8_ST_PO_DISABLE);
+
+ /* WAIT_FOR_RC6_EXIT has only one bit fullfilling the function
+ * indicated by its name and a bunch of selection fields used by OA
+ * configs.
+ */
+ if (WAIT_FOR_RC6_EXIT.reg == reg)
+ val = val & ~_MASKED_BIT_ENABLE(HSW_WAIT_FOR_RC6_EXIT_ENABLE);
+
+ return val;
+}
+
+static struct i915_oa_reg *alloc_oa_regs(struct drm_i915_private *dev_priv,
+ bool (*is_valid)(struct drm_i915_private *dev_priv, u32 addr),
+ u32 __user *regs,
+ u32 n_regs)
+{
+ struct i915_oa_reg *oa_regs;
+ int err;
+ u32 i;
+
+ if (!n_regs)
+ return NULL;
+
+ if (!access_ok(VERIFY_READ, regs, n_regs * sizeof(u32) * 2))
+ return ERR_PTR(-EFAULT);
+
+ /* No is_valid function means we're not allowing any register to be programmed. */
+ GEM_BUG_ON(!is_valid);
+ if (!is_valid)
+ return ERR_PTR(-EINVAL);
+
+ oa_regs = kmalloc_array(n_regs, sizeof(*oa_regs), GFP_KERNEL);
+ if (!oa_regs)
+ return ERR_PTR(-ENOMEM);
+
+ for (i = 0; i < n_regs; i++) {
+ u32 addr, value;
+
+ err = get_user(addr, regs);
+ if (err)
+ goto addr_err;
+
+ if (!is_valid(dev_priv, addr)) {
+ DRM_DEBUG("Invalid oa_reg address: %X\n", addr);
+ err = -EINVAL;
+ goto addr_err;
+ }
+
+ err = get_user(value, regs + 1);
+ if (err)
+ goto addr_err;
+
+ oa_regs[i].addr = _MMIO(addr);
+ oa_regs[i].value = mask_reg_value(addr, value);
+
+ regs += 2;
+ }
+
+ return oa_regs;
+
+addr_err:
+ kfree(oa_regs);
+ return ERR_PTR(err);
+}
+
+static ssize_t show_dynamic_id(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct i915_oa_config *oa_config =
+ container_of(attr, typeof(*oa_config), sysfs_metric_id);
+
+ return sprintf(buf, "%d\n", oa_config->id);
+}
+
+static int create_dynamic_oa_sysfs_entry(struct drm_i915_private *dev_priv,
+ struct i915_oa_config *oa_config)
+{
+ sysfs_attr_init(&oa_config->sysfs_metric_id.attr);
+ oa_config->sysfs_metric_id.attr.name = "id";
+ oa_config->sysfs_metric_id.attr.mode = S_IRUGO;
+ oa_config->sysfs_metric_id.show = show_dynamic_id;
+ oa_config->sysfs_metric_id.store = NULL;
+
+ oa_config->attrs[0] = &oa_config->sysfs_metric_id.attr;
+ oa_config->attrs[1] = NULL;
+
+ oa_config->sysfs_metric.name = oa_config->uuid;
+ oa_config->sysfs_metric.attrs = oa_config->attrs;
+
+ return sysfs_create_group(dev_priv->perf.metrics_kobj,
+ &oa_config->sysfs_metric);
+}
+
+/**
+ * i915_perf_add_config_ioctl - DRM ioctl() for userspace to add a new OA config
+ * @dev: drm device
+ * @data: ioctl data (pointer to struct drm_i915_perf_oa_config) copied from
+ * userspace (unvalidated)
+ * @file: drm file
+ *
+ * Validates the submitted OA register to be saved into a new OA config that
+ * can then be used for programming the OA unit and its NOA network.
+ *
+ * Returns: A new allocated config number to be used with the perf open ioctl
+ * or a negative error code on failure.
+ */
+int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_perf_oa_config *args = data;
+ struct i915_oa_config *oa_config, *tmp;
+ int err, id;
+
+ if (!dev_priv->perf.initialized) {
+ DRM_DEBUG("i915 perf interface not available for this system\n");
+ return -ENOTSUPP;
+ }
+
+ if (!dev_priv->perf.metrics_kobj) {
+ DRM_DEBUG("OA metrics weren't advertised via sysfs\n");
+ return -EINVAL;
+ }
+
+ if (i915_perf_stream_paranoid && !capable(CAP_SYS_ADMIN)) {
+ DRM_DEBUG("Insufficient privileges to add i915 OA config\n");
+ return -EACCES;
+ }
+
+ if ((!args->mux_regs_ptr || !args->n_mux_regs) &&
+ (!args->boolean_regs_ptr || !args->n_boolean_regs) &&
+ (!args->flex_regs_ptr || !args->n_flex_regs)) {
+ DRM_DEBUG("No OA registers given\n");
+ return -EINVAL;
+ }
+
+ oa_config = kzalloc(sizeof(*oa_config), GFP_KERNEL);
+ if (!oa_config) {
+ DRM_DEBUG("Failed to allocate memory for the OA config\n");
+ return -ENOMEM;
+ }
+
+ atomic_set(&oa_config->ref_count, 1);
+
+ if (!uuid_is_valid(args->uuid)) {
+ DRM_DEBUG("Invalid uuid format for OA config\n");
+ err = -EINVAL;
+ goto reg_err;
+ }
+
+ /* Last character in oa_config->uuid will be 0 because oa_config is
+ * kzalloc.
+ */
+ memcpy(oa_config->uuid, args->uuid, sizeof(args->uuid));
+
+ oa_config->mux_regs_len = args->n_mux_regs;
+ oa_config->mux_regs =
+ alloc_oa_regs(dev_priv,
+ dev_priv->perf.oa.ops.is_valid_mux_reg,
+ u64_to_user_ptr(args->mux_regs_ptr),
+ args->n_mux_regs);
+
+ if (IS_ERR(oa_config->mux_regs)) {
+ DRM_DEBUG("Failed to create OA config for mux_regs\n");
+ err = PTR_ERR(oa_config->mux_regs);
+ goto reg_err;
+ }
+
+ oa_config->b_counter_regs_len = args->n_boolean_regs;
+ oa_config->b_counter_regs =
+ alloc_oa_regs(dev_priv,
+ dev_priv->perf.oa.ops.is_valid_b_counter_reg,
+ u64_to_user_ptr(args->boolean_regs_ptr),
+ args->n_boolean_regs);
+
+ if (IS_ERR(oa_config->b_counter_regs)) {
+ DRM_DEBUG("Failed to create OA config for b_counter_regs\n");
+ err = PTR_ERR(oa_config->b_counter_regs);
+ goto reg_err;
+ }
+
+ if (INTEL_GEN(dev_priv) < 8) {
+ if (args->n_flex_regs != 0) {
+ err = -EINVAL;
+ goto reg_err;
+ }
+ } else {
+ oa_config->flex_regs_len = args->n_flex_regs;
+ oa_config->flex_regs =
+ alloc_oa_regs(dev_priv,
+ dev_priv->perf.oa.ops.is_valid_flex_reg,
+ u64_to_user_ptr(args->flex_regs_ptr),
+ args->n_flex_regs);
+
+ if (IS_ERR(oa_config->flex_regs)) {
+ DRM_DEBUG("Failed to create OA config for flex_regs\n");
+ err = PTR_ERR(oa_config->flex_regs);
+ goto reg_err;
+ }
+ }
+
+ err = mutex_lock_interruptible(&dev_priv->perf.metrics_lock);
+ if (err)
+ goto reg_err;
+
+ /* We shouldn't have too many configs, so this iteration shouldn't be
+ * too costly.
+ */
+ idr_for_each_entry(&dev_priv->perf.metrics_idr, tmp, id) {
+ if (!strcmp(tmp->uuid, oa_config->uuid)) {
+ DRM_DEBUG("OA config already exists with this uuid\n");
+ err = -EADDRINUSE;
+ goto sysfs_err;
+ }
+ }
+
+ err = create_dynamic_oa_sysfs_entry(dev_priv, oa_config);
+ if (err) {
+ DRM_DEBUG("Failed to create sysfs entry for OA config\n");
+ goto sysfs_err;
+ }
+
+ /* Config id 0 is invalid, id 1 for kernel stored test config. */
+ oa_config->id = idr_alloc(&dev_priv->perf.metrics_idr,
+ oa_config, 2,
+ 0, GFP_KERNEL);
+ if (oa_config->id < 0) {
+ DRM_DEBUG("Failed to create sysfs entry for OA config\n");
+ err = oa_config->id;
+ goto sysfs_err;
+ }
+
+ mutex_unlock(&dev_priv->perf.metrics_lock);
+
+ return oa_config->id;
+
+sysfs_err:
+ mutex_unlock(&dev_priv->perf.metrics_lock);
+reg_err:
+ put_oa_config(dev_priv, oa_config);
+ DRM_DEBUG("Failed to add new OA config\n");
+ return err;
+}
+
+/**
+ * i915_perf_remove_config_ioctl - DRM ioctl() for userspace to remove an OA config
+ * @dev: drm device
+ * @data: ioctl data (pointer to u64 integer) copied from userspace
+ * @file: drm file
+ *
+ * Configs can be removed while being used, the will stop appearing in sysfs
+ * and their content will be freed when the stream using the config is closed.
+ *
+ * Returns: 0 on success or a negative error code on failure.
+ */
+int i915_perf_remove_config_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u64 *arg = data;
+ struct i915_oa_config *oa_config;
+ int ret;
+
+ if (!dev_priv->perf.initialized) {
+ DRM_DEBUG("i915 perf interface not available for this system\n");
+ return -ENOTSUPP;
+ }
+
+ if (i915_perf_stream_paranoid && !capable(CAP_SYS_ADMIN)) {
+ DRM_DEBUG("Insufficient privileges to remove i915 OA config\n");
+ return -EACCES;
+ }
+
+ ret = mutex_lock_interruptible(&dev_priv->perf.metrics_lock);
+ if (ret)
+ goto lock_err;
+
+ oa_config = idr_find(&dev_priv->perf.metrics_idr, *arg);
+ if (!oa_config) {
+ DRM_DEBUG("Failed to remove unknown OA config\n");
+ ret = -ENOENT;
+ goto config_err;
+ }
+
+ GEM_BUG_ON(*arg != oa_config->id);
+
+ sysfs_remove_group(dev_priv->perf.metrics_kobj,
+ &oa_config->sysfs_metric);
+
+ idr_remove(&dev_priv->perf.metrics_idr, *arg);
+ put_oa_config(dev_priv, oa_config);
+
+config_err:
+ mutex_unlock(&dev_priv->perf.metrics_lock);
+lock_err:
+ return ret;
+}
+
static struct ctl_table oa_table[] = {
{
.procname = "perf_stream_paranoid",
@@ -3010,9 +3385,14 @@ static struct ctl_table dev_root[] = {
*/
void i915_perf_init(struct drm_i915_private *dev_priv)
{
- dev_priv->perf.oa.n_builtin_sets = 0;
+ dev_priv->perf.oa.timestamp_frequency = 0;
if (IS_HASWELL(dev_priv)) {
+ dev_priv->perf.oa.ops.is_valid_b_counter_reg =
+ gen7_is_valid_b_counter_addr;
+ dev_priv->perf.oa.ops.is_valid_mux_reg =
+ hsw_is_valid_mux_addr;
+ dev_priv->perf.oa.ops.is_valid_flex_reg = NULL;
dev_priv->perf.oa.ops.init_oa_buffer = gen7_init_oa_buffer;
dev_priv->perf.oa.ops.enable_metric_set = hsw_enable_metric_set;
dev_priv->perf.oa.ops.disable_metric_set = hsw_disable_metric_set;
@@ -3025,9 +3405,6 @@ void i915_perf_init(struct drm_i915_private *dev_priv)
dev_priv->perf.oa.timestamp_frequency = 12500000;
dev_priv->perf.oa.oa_formats = hsw_oa_formats;
-
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_hsw;
} else if (i915.enable_execlists) {
/* Note: that although we could theoretically also support the
* legacy ringbuffer mode on BDW (and earlier iterations of
@@ -3035,6 +3412,22 @@ void i915_perf_init(struct drm_i915_private *dev_priv)
* worth the complexity to maintain now that BDW+ enable
* execlist mode by default.
*/
+ dev_priv->perf.oa.ops.is_valid_b_counter_reg =
+ gen7_is_valid_b_counter_addr;
+ dev_priv->perf.oa.ops.is_valid_mux_reg =
+ gen8_is_valid_mux_addr;
+ dev_priv->perf.oa.ops.is_valid_flex_reg =
+ gen8_is_valid_flex_addr;
+
+ dev_priv->perf.oa.ops.init_oa_buffer = gen8_init_oa_buffer;
+ dev_priv->perf.oa.ops.enable_metric_set = gen8_enable_metric_set;
+ dev_priv->perf.oa.ops.disable_metric_set = gen8_disable_metric_set;
+ dev_priv->perf.oa.ops.oa_enable = gen8_oa_enable;
+ dev_priv->perf.oa.ops.oa_disable = gen8_oa_disable;
+ dev_priv->perf.oa.ops.read = gen8_oa_read;
+ dev_priv->perf.oa.ops.oa_hw_tail_read = gen8_oa_hw_tail_read;
+
+ dev_priv->perf.oa.oa_formats = gen8_plus_oa_formats;
if (IS_GEN8(dev_priv)) {
dev_priv->perf.oa.ctx_oactxctrl_offset = 0x120;
@@ -3043,85 +3436,35 @@ void i915_perf_init(struct drm_i915_private *dev_priv)
dev_priv->perf.oa.timestamp_frequency = 12500000;
dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<25);
-
- if (IS_BROADWELL(dev_priv)) {
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_bdw;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_bdw;
- } else if (IS_CHERRYVIEW(dev_priv)) {
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_chv;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_chv;
+ if (IS_CHERRYVIEW(dev_priv)) {
+ dev_priv->perf.oa.ops.is_valid_mux_reg =
+ chv_is_valid_mux_addr;
}
} else if (IS_GEN9(dev_priv)) {
dev_priv->perf.oa.ctx_oactxctrl_offset = 0x128;
dev_priv->perf.oa.ctx_flexeu0_offset = 0x3de;
- dev_priv->perf.oa.timestamp_frequency = 12000000;
-
dev_priv->perf.oa.gen8_valid_ctx_bit = (1<<16);
- if (IS_SKL_GT2(dev_priv)) {
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_sklgt2;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_sklgt2;
- } else if (IS_SKL_GT3(dev_priv)) {
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_sklgt3;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_sklgt3;
- } else if (IS_SKL_GT4(dev_priv)) {
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_sklgt4;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_sklgt4;
- } else if (IS_BROXTON(dev_priv)) {
+ switch (dev_priv->info.platform) {
+ case INTEL_BROXTON:
+ case INTEL_GEMINILAKE:
dev_priv->perf.oa.timestamp_frequency = 19200000;
-
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_bxt;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_bxt;
- } else if (IS_KBL_GT2(dev_priv)) {
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_kblgt2;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_kblgt2;
- } else if (IS_KBL_GT3(dev_priv)) {
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_kblgt3;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_kblgt3;
- } else if (IS_GEMINILAKE(dev_priv)) {
- dev_priv->perf.oa.timestamp_frequency = 19200000;
-
- dev_priv->perf.oa.n_builtin_sets =
- i915_oa_n_builtin_metric_sets_glk;
- dev_priv->perf.oa.ops.select_metric_set =
- i915_oa_select_metric_set_glk;
+ break;
+ case INTEL_SKYLAKE:
+ case INTEL_KABYLAKE:
+ dev_priv->perf.oa.timestamp_frequency = 12000000;
+ break;
+ default:
+ /* Leave timestamp_frequency to 0 so we can
+ * detect unsupported platforms.
+ */
+ break;
}
}
-
- if (dev_priv->perf.oa.n_builtin_sets) {
- dev_priv->perf.oa.ops.init_oa_buffer = gen8_init_oa_buffer;
- dev_priv->perf.oa.ops.enable_metric_set =
- gen8_enable_metric_set;
- dev_priv->perf.oa.ops.disable_metric_set =
- gen8_disable_metric_set;
- dev_priv->perf.oa.ops.oa_enable = gen8_oa_enable;
- dev_priv->perf.oa.ops.oa_disable = gen8_oa_disable;
- dev_priv->perf.oa.ops.read = gen8_oa_read;
- dev_priv->perf.oa.ops.oa_hw_tail_read =
- gen8_oa_hw_tail_read;
-
- dev_priv->perf.oa.oa_formats = gen8_plus_oa_formats;
- }
}
- if (dev_priv->perf.oa.n_builtin_sets) {
+ if (dev_priv->perf.oa.timestamp_frequency) {
hrtimer_init(&dev_priv->perf.oa.poll_check_timer,
CLOCK_MONOTONIC, HRTIMER_MODE_REL);
dev_priv->perf.oa.poll_check_timer.function = oa_poll_check_timer_cb;
@@ -3135,10 +3478,23 @@ void i915_perf_init(struct drm_i915_private *dev_priv)
dev_priv->perf.oa.timestamp_frequency / 2;
dev_priv->perf.sysctl_header = register_sysctl_table(dev_root);
+ mutex_init(&dev_priv->perf.metrics_lock);
+ idr_init(&dev_priv->perf.metrics_idr);
+
dev_priv->perf.initialized = true;
}
}
+static int destroy_config(int id, void *p, void *data)
+{
+ struct drm_i915_private *dev_priv = data;
+ struct i915_oa_config *oa_config = p;
+
+ put_oa_config(dev_priv, oa_config);
+
+ return 0;
+}
+
/**
* i915_perf_fini - Counter part to i915_perf_init()
* @dev_priv: i915 device instance
@@ -3148,6 +3504,9 @@ void i915_perf_fini(struct drm_i915_private *dev_priv)
if (!dev_priv->perf.initialized)
return;
+ idr_for_each(&dev_priv->perf.metrics_idr, destroy_config, dev_priv);
+ idr_destroy(&dev_priv->perf.metrics_idr);
+
unregister_sysctl_table(dev_priv->perf.sysctl_header);
memset(&dev_priv->perf.oa.ops, 0, sizeof(dev_priv->perf.oa.ops));
diff --git a/drivers/gpu/drm/i915/i915_pvinfo.h b/drivers/gpu/drm/i915/i915_pvinfo.h
index 2cfe96d3e5d1..0679a58cdbae 100644
--- a/drivers/gpu/drm/i915/i915_pvinfo.h
+++ b/drivers/gpu/drm/i915/i915_pvinfo.h
@@ -49,12 +49,18 @@ enum vgt_g2v_type {
VGT_G2V_MAX,
};
+/*
+ * VGT capabilities type
+ */
+#define VGT_CAPS_FULL_48BIT_PPGTT BIT(2)
+
struct vgt_if {
u64 magic; /* VGT_MAGIC */
u16 version_major;
u16 version_minor;
u32 vgt_id; /* ID of vGT instance */
- u32 rsv1[12]; /* pad to offset 0x40 */
+ u32 vgt_caps; /* VGT capabilities */
+ u32 rsv1[11]; /* pad to offset 0x40 */
/*
* Data structure to describe the balooning info of resources.
* Each VM can only have one portion of continuous area for now.
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 64cc674b652a..ed7cd9ee2c2a 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -25,6 +25,97 @@
#ifndef _I915_REG_H_
#define _I915_REG_H_
+/**
+ * DOC: The i915 register macro definition style guide
+ *
+ * Follow the style described here for new macros, and while changing existing
+ * macros. Do **not** mass change existing definitions just to update the style.
+ *
+ * Layout
+ * ''''''
+ *
+ * Keep helper macros near the top. For example, _PIPE() and friends.
+ *
+ * Prefix macros that generally should not be used outside of this file with
+ * underscore '_'. For example, _PIPE() and friends, single instances of
+ * registers that are defined solely for the use by function-like macros.
+ *
+ * Avoid using the underscore prefixed macros outside of this file. There are
+ * exceptions, but keep them to a minimum.
+ *
+ * There are two basic types of register definitions: Single registers and
+ * register groups. Register groups are registers which have two or more
+ * instances, for example one per pipe, port, transcoder, etc. Register groups
+ * should be defined using function-like macros.
+ *
+ * For single registers, define the register offset first, followed by register
+ * contents.
+ *
+ * For register groups, define the register instance offsets first, prefixed
+ * with underscore, followed by a function-like macro choosing the right
+ * instance based on the parameter, followed by register contents.
+ *
+ * Define the register contents (i.e. bit and bit field macros) from most
+ * significant to least significant bit. Indent the register content macros
+ * using two extra spaces between ``#define`` and the macro name.
+ *
+ * For bit fields, define a ``_MASK`` and a ``_SHIFT`` macro. Define bit field
+ * contents so that they are already shifted in place, and can be directly
+ * OR'd. For convenience, function-like macros may be used to define bit fields,
+ * but do note that the macros may be needed to read as well as write the
+ * register contents.
+ *
+ * Define bits using ``(1 << N)`` instead of ``BIT(N)``. We may change this in
+ * the future, but this is the prevailing style. Do **not** add ``_BIT`` suffix
+ * to the name.
+ *
+ * Group the register and its contents together without blank lines, separate
+ * from other registers and their contents with one blank line.
+ *
+ * Indent macro values from macro names using TABs. Align values vertically. Use
+ * braces in macro values as needed to avoid unintended precedence after macro
+ * substitution. Use spaces in macro values according to kernel coding
+ * style. Use lower case in hexadecimal values.
+ *
+ * Naming
+ * ''''''
+ *
+ * Try to name registers according to the specs. If the register name changes in
+ * the specs from platform to another, stick to the original name.
+ *
+ * Try to re-use existing register macro definitions. Only add new macros for
+ * new register offsets, or when the register contents have changed enough to
+ * warrant a full redefinition.
+ *
+ * When a register macro changes for a new platform, prefix the new macro using
+ * the platform acronym or generation. For example, ``SKL_`` or ``GEN8_``. The
+ * prefix signifies the start platform/generation using the register.
+ *
+ * When a bit (field) macro changes or gets added for a new platform, while
+ * retaining the existing register macro, add a platform acronym or generation
+ * suffix to the name. For example, ``_SKL`` or ``_GEN8``.
+ *
+ * Examples
+ * ''''''''
+ *
+ * (Note that the values in the example are indented using spaces instead of
+ * TABs to avoid misalignment in generated documentation. Use TABs in the
+ * definitions.)::
+ *
+ * #define _FOO_A 0xf000
+ * #define _FOO_B 0xf001
+ * #define FOO(pipe) _MMIO_PIPE(pipe, _FOO_A, _FOO_B)
+ * #define FOO_ENABLE (1 << 31)
+ * #define FOO_MODE_MASK (0xf << 16)
+ * #define FOO_MODE_SHIFT 16
+ * #define FOO_MODE_BAR (0 << 16)
+ * #define FOO_MODE_BAZ (1 << 16)
+ * #define FOO_MODE_QUX_SNB (2 << 16)
+ *
+ * #define BAR _MMIO(0xb000)
+ * #define GEN8_BAR _MMIO(0xb888)
+ */
+
typedef struct {
uint32_t reg;
} i915_reg_t;
@@ -229,6 +320,28 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
#define GEN8_RPCS_EU_MIN_SHIFT 0
#define GEN8_RPCS_EU_MIN_MASK (0xf << GEN8_RPCS_EU_MIN_SHIFT)
+#define WAIT_FOR_RC6_EXIT _MMIO(0x20CC)
+/* HSW only */
+#define HSW_SELECTIVE_READ_ADDRESSING_SHIFT 2
+#define HSW_SELECTIVE_READ_ADDRESSING_MASK (0x3 << HSW_SLECTIVE_READ_ADDRESSING_SHIFT)
+#define HSW_SELECTIVE_WRITE_ADDRESS_SHIFT 4
+#define HSW_SELECTIVE_WRITE_ADDRESS_MASK (0x7 << HSW_SELECTIVE_WRITE_ADDRESS_SHIFT)
+/* HSW+ */
+#define HSW_WAIT_FOR_RC6_EXIT_ENABLE (1 << 0)
+#define HSW_RCS_CONTEXT_ENABLE (1 << 7)
+#define HSW_RCS_INHIBIT (1 << 8)
+/* Gen8 */
+#define GEN8_SELECTIVE_WRITE_ADDRESS_SHIFT 4
+#define GEN8_SELECTIVE_WRITE_ADDRESS_MASK (0x3 << GEN8_SELECTIVE_WRITE_ADDRESS_SHIFT)
+#define GEN8_SELECTIVE_WRITE_ADDRESS_SHIFT 4
+#define GEN8_SELECTIVE_WRITE_ADDRESS_MASK (0x3 << GEN8_SELECTIVE_WRITE_ADDRESS_SHIFT)
+#define GEN8_SELECTIVE_WRITE_ADDRESSING_ENABLE (1 << 6)
+#define GEN8_SELECTIVE_READ_SUBSLICE_SELECT_SHIFT 9
+#define GEN8_SELECTIVE_READ_SUBSLICE_SELECT_MASK (0x3 << GEN8_SELECTIVE_READ_SUBSLICE_SELECT_SHIFT)
+#define GEN8_SELECTIVE_READ_SLICE_SELECT_SHIFT 11
+#define GEN8_SELECTIVE_READ_SLICE_SELECT_MASK (0x3 << GEN8_SELECTIVE_READ_SLICE_SELECT_SHIFT)
+#define GEN8_SELECTIVE_READ_ADDRESSING_ENABLE (1 << 13)
+
#define GAM_ECOCHK _MMIO(0x4090)
#define BDW_DISABLE_HDC_INVALIDATION (1<<25)
#define ECOCHK_SNB_BIT (1<<10)
@@ -729,119 +842,10 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
#define EU_PERF_CNTL5 _MMIO(0xe55c)
#define EU_PERF_CNTL6 _MMIO(0xe65c)
-#define GDT_CHICKEN_BITS _MMIO(0x9840)
-#define GT_NOA_ENABLE 0x00000080
-
/*
* OA Boolean state
*/
-#define OAREPORTTRIG1 _MMIO(0x2740)
-#define OAREPORTTRIG1_THRESHOLD_MASK 0xffff
-#define OAREPORTTRIG1_EDGE_LEVEL_TRIGER_SELECT_MASK 0xffff0000 /* 0=level */
-
-#define OAREPORTTRIG2 _MMIO(0x2744)
-#define OAREPORTTRIG2_INVERT_A_0 (1<<0)
-#define OAREPORTTRIG2_INVERT_A_1 (1<<1)
-#define OAREPORTTRIG2_INVERT_A_2 (1<<2)
-#define OAREPORTTRIG2_INVERT_A_3 (1<<3)
-#define OAREPORTTRIG2_INVERT_A_4 (1<<4)
-#define OAREPORTTRIG2_INVERT_A_5 (1<<5)
-#define OAREPORTTRIG2_INVERT_A_6 (1<<6)
-#define OAREPORTTRIG2_INVERT_A_7 (1<<7)
-#define OAREPORTTRIG2_INVERT_A_8 (1<<8)
-#define OAREPORTTRIG2_INVERT_A_9 (1<<9)
-#define OAREPORTTRIG2_INVERT_A_10 (1<<10)
-#define OAREPORTTRIG2_INVERT_A_11 (1<<11)
-#define OAREPORTTRIG2_INVERT_A_12 (1<<12)
-#define OAREPORTTRIG2_INVERT_A_13 (1<<13)
-#define OAREPORTTRIG2_INVERT_A_14 (1<<14)
-#define OAREPORTTRIG2_INVERT_A_15 (1<<15)
-#define OAREPORTTRIG2_INVERT_B_0 (1<<16)
-#define OAREPORTTRIG2_INVERT_B_1 (1<<17)
-#define OAREPORTTRIG2_INVERT_B_2 (1<<18)
-#define OAREPORTTRIG2_INVERT_B_3 (1<<19)
-#define OAREPORTTRIG2_INVERT_C_0 (1<<20)
-#define OAREPORTTRIG2_INVERT_C_1 (1<<21)
-#define OAREPORTTRIG2_INVERT_D_0 (1<<22)
-#define OAREPORTTRIG2_THRESHOLD_ENABLE (1<<23)
-#define OAREPORTTRIG2_REPORT_TRIGGER_ENABLE (1<<31)
-
-#define OAREPORTTRIG3 _MMIO(0x2748)
-#define OAREPORTTRIG3_NOA_SELECT_MASK 0xf
-#define OAREPORTTRIG3_NOA_SELECT_8_SHIFT 0
-#define OAREPORTTRIG3_NOA_SELECT_9_SHIFT 4
-#define OAREPORTTRIG3_NOA_SELECT_10_SHIFT 8
-#define OAREPORTTRIG3_NOA_SELECT_11_SHIFT 12
-#define OAREPORTTRIG3_NOA_SELECT_12_SHIFT 16
-#define OAREPORTTRIG3_NOA_SELECT_13_SHIFT 20
-#define OAREPORTTRIG3_NOA_SELECT_14_SHIFT 24
-#define OAREPORTTRIG3_NOA_SELECT_15_SHIFT 28
-
-#define OAREPORTTRIG4 _MMIO(0x274c)
-#define OAREPORTTRIG4_NOA_SELECT_MASK 0xf
-#define OAREPORTTRIG4_NOA_SELECT_0_SHIFT 0
-#define OAREPORTTRIG4_NOA_SELECT_1_SHIFT 4
-#define OAREPORTTRIG4_NOA_SELECT_2_SHIFT 8
-#define OAREPORTTRIG4_NOA_SELECT_3_SHIFT 12
-#define OAREPORTTRIG4_NOA_SELECT_4_SHIFT 16
-#define OAREPORTTRIG4_NOA_SELECT_5_SHIFT 20
-#define OAREPORTTRIG4_NOA_SELECT_6_SHIFT 24
-#define OAREPORTTRIG4_NOA_SELECT_7_SHIFT 28
-
-#define OAREPORTTRIG5 _MMIO(0x2750)
-#define OAREPORTTRIG5_THRESHOLD_MASK 0xffff
-#define OAREPORTTRIG5_EDGE_LEVEL_TRIGER_SELECT_MASK 0xffff0000 /* 0=level */
-
-#define OAREPORTTRIG6 _MMIO(0x2754)
-#define OAREPORTTRIG6_INVERT_A_0 (1<<0)
-#define OAREPORTTRIG6_INVERT_A_1 (1<<1)
-#define OAREPORTTRIG6_INVERT_A_2 (1<<2)
-#define OAREPORTTRIG6_INVERT_A_3 (1<<3)
-#define OAREPORTTRIG6_INVERT_A_4 (1<<4)
-#define OAREPORTTRIG6_INVERT_A_5 (1<<5)
-#define OAREPORTTRIG6_INVERT_A_6 (1<<6)
-#define OAREPORTTRIG6_INVERT_A_7 (1<<7)
-#define OAREPORTTRIG6_INVERT_A_8 (1<<8)
-#define OAREPORTTRIG6_INVERT_A_9 (1<<9)
-#define OAREPORTTRIG6_INVERT_A_10 (1<<10)
-#define OAREPORTTRIG6_INVERT_A_11 (1<<11)
-#define OAREPORTTRIG6_INVERT_A_12 (1<<12)
-#define OAREPORTTRIG6_INVERT_A_13 (1<<13)
-#define OAREPORTTRIG6_INVERT_A_14 (1<<14)
-#define OAREPORTTRIG6_INVERT_A_15 (1<<15)
-#define OAREPORTTRIG6_INVERT_B_0 (1<<16)
-#define OAREPORTTRIG6_INVERT_B_1 (1<<17)
-#define OAREPORTTRIG6_INVERT_B_2 (1<<18)
-#define OAREPORTTRIG6_INVERT_B_3 (1<<19)
-#define OAREPORTTRIG6_INVERT_C_0 (1<<20)
-#define OAREPORTTRIG6_INVERT_C_1 (1<<21)
-#define OAREPORTTRIG6_INVERT_D_0 (1<<22)
-#define OAREPORTTRIG6_THRESHOLD_ENABLE (1<<23)
-#define OAREPORTTRIG6_REPORT_TRIGGER_ENABLE (1<<31)
-
-#define OAREPORTTRIG7 _MMIO(0x2758)
-#define OAREPORTTRIG7_NOA_SELECT_MASK 0xf
-#define OAREPORTTRIG7_NOA_SELECT_8_SHIFT 0
-#define OAREPORTTRIG7_NOA_SELECT_9_SHIFT 4
-#define OAREPORTTRIG7_NOA_SELECT_10_SHIFT 8
-#define OAREPORTTRIG7_NOA_SELECT_11_SHIFT 12
-#define OAREPORTTRIG7_NOA_SELECT_12_SHIFT 16
-#define OAREPORTTRIG7_NOA_SELECT_13_SHIFT 20
-#define OAREPORTTRIG7_NOA_SELECT_14_SHIFT 24
-#define OAREPORTTRIG7_NOA_SELECT_15_SHIFT 28
-
-#define OAREPORTTRIG8 _MMIO(0x275c)
-#define OAREPORTTRIG8_NOA_SELECT_MASK 0xf
-#define OAREPORTTRIG8_NOA_SELECT_0_SHIFT 0
-#define OAREPORTTRIG8_NOA_SELECT_1_SHIFT 4
-#define OAREPORTTRIG8_NOA_SELECT_2_SHIFT 8
-#define OAREPORTTRIG8_NOA_SELECT_3_SHIFT 12
-#define OAREPORTTRIG8_NOA_SELECT_4_SHIFT 16
-#define OAREPORTTRIG8_NOA_SELECT_5_SHIFT 20
-#define OAREPORTTRIG8_NOA_SELECT_6_SHIFT 24
-#define OAREPORTTRIG8_NOA_SELECT_7_SHIFT 28
-
#define OASTARTTRIG1 _MMIO(0x2710)
#define OASTARTTRIG1_THRESHOLD_COUNT_MASK_MBZ 0xffff0000
#define OASTARTTRIG1_THRESHOLD_MASK 0xffff
@@ -956,6 +960,112 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
#define OASTARTTRIG8_NOA_SELECT_6_SHIFT 24
#define OASTARTTRIG8_NOA_SELECT_7_SHIFT 28
+#define OAREPORTTRIG1 _MMIO(0x2740)
+#define OAREPORTTRIG1_THRESHOLD_MASK 0xffff
+#define OAREPORTTRIG1_EDGE_LEVEL_TRIGER_SELECT_MASK 0xffff0000 /* 0=level */
+
+#define OAREPORTTRIG2 _MMIO(0x2744)
+#define OAREPORTTRIG2_INVERT_A_0 (1<<0)
+#define OAREPORTTRIG2_INVERT_A_1 (1<<1)
+#define OAREPORTTRIG2_INVERT_A_2 (1<<2)
+#define OAREPORTTRIG2_INVERT_A_3 (1<<3)
+#define OAREPORTTRIG2_INVERT_A_4 (1<<4)
+#define OAREPORTTRIG2_INVERT_A_5 (1<<5)
+#define OAREPORTTRIG2_INVERT_A_6 (1<<6)
+#define OAREPORTTRIG2_INVERT_A_7 (1<<7)
+#define OAREPORTTRIG2_INVERT_A_8 (1<<8)
+#define OAREPORTTRIG2_INVERT_A_9 (1<<9)
+#define OAREPORTTRIG2_INVERT_A_10 (1<<10)
+#define OAREPORTTRIG2_INVERT_A_11 (1<<11)
+#define OAREPORTTRIG2_INVERT_A_12 (1<<12)
+#define OAREPORTTRIG2_INVERT_A_13 (1<<13)
+#define OAREPORTTRIG2_INVERT_A_14 (1<<14)
+#define OAREPORTTRIG2_INVERT_A_15 (1<<15)
+#define OAREPORTTRIG2_INVERT_B_0 (1<<16)
+#define OAREPORTTRIG2_INVERT_B_1 (1<<17)
+#define OAREPORTTRIG2_INVERT_B_2 (1<<18)
+#define OAREPORTTRIG2_INVERT_B_3 (1<<19)
+#define OAREPORTTRIG2_INVERT_C_0 (1<<20)
+#define OAREPORTTRIG2_INVERT_C_1 (1<<21)
+#define OAREPORTTRIG2_INVERT_D_0 (1<<22)
+#define OAREPORTTRIG2_THRESHOLD_ENABLE (1<<23)
+#define OAREPORTTRIG2_REPORT_TRIGGER_ENABLE (1<<31)
+
+#define OAREPORTTRIG3 _MMIO(0x2748)
+#define OAREPORTTRIG3_NOA_SELECT_MASK 0xf
+#define OAREPORTTRIG3_NOA_SELECT_8_SHIFT 0
+#define OAREPORTTRIG3_NOA_SELECT_9_SHIFT 4
+#define OAREPORTTRIG3_NOA_SELECT_10_SHIFT 8
+#define OAREPORTTRIG3_NOA_SELECT_11_SHIFT 12
+#define OAREPORTTRIG3_NOA_SELECT_12_SHIFT 16
+#define OAREPORTTRIG3_NOA_SELECT_13_SHIFT 20
+#define OAREPORTTRIG3_NOA_SELECT_14_SHIFT 24
+#define OAREPORTTRIG3_NOA_SELECT_15_SHIFT 28
+
+#define OAREPORTTRIG4 _MMIO(0x274c)
+#define OAREPORTTRIG4_NOA_SELECT_MASK 0xf
+#define OAREPORTTRIG4_NOA_SELECT_0_SHIFT 0
+#define OAREPORTTRIG4_NOA_SELECT_1_SHIFT 4
+#define OAREPORTTRIG4_NOA_SELECT_2_SHIFT 8
+#define OAREPORTTRIG4_NOA_SELECT_3_SHIFT 12
+#define OAREPORTTRIG4_NOA_SELECT_4_SHIFT 16
+#define OAREPORTTRIG4_NOA_SELECT_5_SHIFT 20
+#define OAREPORTTRIG4_NOA_SELECT_6_SHIFT 24
+#define OAREPORTTRIG4_NOA_SELECT_7_SHIFT 28
+
+#define OAREPORTTRIG5 _MMIO(0x2750)
+#define OAREPORTTRIG5_THRESHOLD_MASK 0xffff
+#define OAREPORTTRIG5_EDGE_LEVEL_TRIGER_SELECT_MASK 0xffff0000 /* 0=level */
+
+#define OAREPORTTRIG6 _MMIO(0x2754)
+#define OAREPORTTRIG6_INVERT_A_0 (1<<0)
+#define OAREPORTTRIG6_INVERT_A_1 (1<<1)
+#define OAREPORTTRIG6_INVERT_A_2 (1<<2)
+#define OAREPORTTRIG6_INVERT_A_3 (1<<3)
+#define OAREPORTTRIG6_INVERT_A_4 (1<<4)
+#define OAREPORTTRIG6_INVERT_A_5 (1<<5)
+#define OAREPORTTRIG6_INVERT_A_6 (1<<6)
+#define OAREPORTTRIG6_INVERT_A_7 (1<<7)
+#define OAREPORTTRIG6_INVERT_A_8 (1<<8)
+#define OAREPORTTRIG6_INVERT_A_9 (1<<9)
+#define OAREPORTTRIG6_INVERT_A_10 (1<<10)
+#define OAREPORTTRIG6_INVERT_A_11 (1<<11)
+#define OAREPORTTRIG6_INVERT_A_12 (1<<12)
+#define OAREPORTTRIG6_INVERT_A_13 (1<<13)
+#define OAREPORTTRIG6_INVERT_A_14 (1<<14)
+#define OAREPORTTRIG6_INVERT_A_15 (1<<15)
+#define OAREPORTTRIG6_INVERT_B_0 (1<<16)
+#define OAREPORTTRIG6_INVERT_B_1 (1<<17)
+#define OAREPORTTRIG6_INVERT_B_2 (1<<18)
+#define OAREPORTTRIG6_INVERT_B_3 (1<<19)
+#define OAREPORTTRIG6_INVERT_C_0 (1<<20)
+#define OAREPORTTRIG6_INVERT_C_1 (1<<21)
+#define OAREPORTTRIG6_INVERT_D_0 (1<<22)
+#define OAREPORTTRIG6_THRESHOLD_ENABLE (1<<23)
+#define OAREPORTTRIG6_REPORT_TRIGGER_ENABLE (1<<31)
+
+#define OAREPORTTRIG7 _MMIO(0x2758)
+#define OAREPORTTRIG7_NOA_SELECT_MASK 0xf
+#define OAREPORTTRIG7_NOA_SELECT_8_SHIFT 0
+#define OAREPORTTRIG7_NOA_SELECT_9_SHIFT 4
+#define OAREPORTTRIG7_NOA_SELECT_10_SHIFT 8
+#define OAREPORTTRIG7_NOA_SELECT_11_SHIFT 12
+#define OAREPORTTRIG7_NOA_SELECT_12_SHIFT 16
+#define OAREPORTTRIG7_NOA_SELECT_13_SHIFT 20
+#define OAREPORTTRIG7_NOA_SELECT_14_SHIFT 24
+#define OAREPORTTRIG7_NOA_SELECT_15_SHIFT 28
+
+#define OAREPORTTRIG8 _MMIO(0x275c)
+#define OAREPORTTRIG8_NOA_SELECT_MASK 0xf
+#define OAREPORTTRIG8_NOA_SELECT_0_SHIFT 0
+#define OAREPORTTRIG8_NOA_SELECT_1_SHIFT 4
+#define OAREPORTTRIG8_NOA_SELECT_2_SHIFT 8
+#define OAREPORTTRIG8_NOA_SELECT_3_SHIFT 12
+#define OAREPORTTRIG8_NOA_SELECT_4_SHIFT 16
+#define OAREPORTTRIG8_NOA_SELECT_5_SHIFT 20
+#define OAREPORTTRIG8_NOA_SELECT_6_SHIFT 24
+#define OAREPORTTRIG8_NOA_SELECT_7_SHIFT 28
+
/* CECX_0 */
#define OACEC_COMPARE_LESS_OR_EQUAL 6
#define OACEC_COMPARE_NOT_EQUAL 5
@@ -994,6 +1104,51 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
#define OACEC7_0 _MMIO(0x27a8)
#define OACEC7_1 _MMIO(0x27ac)
+/* OA perf counters */
+#define OA_PERFCNT1_LO _MMIO(0x91B8)
+#define OA_PERFCNT1_HI _MMIO(0x91BC)
+#define OA_PERFCNT2_LO _MMIO(0x91C0)
+#define OA_PERFCNT2_HI _MMIO(0x91C4)
+
+#define OA_PERFMATRIX_LO _MMIO(0x91C8)
+#define OA_PERFMATRIX_HI _MMIO(0x91CC)
+
+/* RPM unit config (Gen8+) */
+#define RPM_CONFIG0 _MMIO(0x0D00)
+#define RPM_CONFIG1 _MMIO(0x0D04)
+
+/* RPC unit config (Gen8+) */
+#define RPM_CONFIG _MMIO(0x0D08)
+
+/* NOA (Gen8+) */
+#define NOA_CONFIG(i) _MMIO(0x0D0C + (i) * 4)
+
+#define MICRO_BP0_0 _MMIO(0x9800)
+#define MICRO_BP0_2 _MMIO(0x9804)
+#define MICRO_BP0_1 _MMIO(0x9808)
+
+#define MICRO_BP1_0 _MMIO(0x980C)
+#define MICRO_BP1_2 _MMIO(0x9810)
+#define MICRO_BP1_1 _MMIO(0x9814)
+
+#define MICRO_BP2_0 _MMIO(0x9818)
+#define MICRO_BP2_2 _MMIO(0x981C)
+#define MICRO_BP2_1 _MMIO(0x9820)
+
+#define MICRO_BP3_0 _MMIO(0x9824)
+#define MICRO_BP3_2 _MMIO(0x9828)
+#define MICRO_BP3_1 _MMIO(0x982C)
+
+#define MICRO_BP_TRIGGER _MMIO(0x9830)
+#define MICRO_BP3_COUNT_STATUS01 _MMIO(0x9834)
+#define MICRO_BP3_COUNT_STATUS23 _MMIO(0x9838)
+#define MICRO_BP_FIRED_ARMED _MMIO(0x983C)
+
+#define GDT_CHICKEN_BITS _MMIO(0x9840)
+#define GT_NOA_ENABLE 0x00000080
+
+#define NOA_DATA _MMIO(0x986C)
+#define NOA_WRITE _MMIO(0x9888)
#define _GEN7_PIPEA_DE_LOAD_SL 0x70068
#define _GEN7_PIPEB_DE_LOAD_SL 0x71068
@@ -1063,9 +1218,26 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
#define DP_SSS_RESET(pipe) _DP_SSS(0x2, (pipe))
#define DP_SSS_PWR_GATE(pipe) _DP_SSS(0x3, (pipe))
-/* See the PUNIT HAS v0.8 for the below bits */
-enum punit_power_well {
- /* These numbers are fixed and must match the position of the pw bits */
+/*
+ * i915_power_well_id:
+ *
+ * Platform specific IDs used to look up power wells and - except for custom
+ * power wells - to define request/status register flag bit positions. As such
+ * the set of IDs on a given platform must be unique and except for custom
+ * power wells their value must stay fixed.
+ */
+enum i915_power_well_id {
+ /*
+ * I830
+ * - custom power well
+ */
+ I830_DISP_PW_PIPES = 0,
+
+ /*
+ * VLV/CHV
+ * - PUNIT_REG_PWRGT_CTRL (bit: id*2),
+ * PUNIT_REG_PWRGT_STATUS (bit: id*2) (PUNIT HAS v0.8)
+ */
PUNIT_POWER_WELL_RENDER = 0,
PUNIT_POWER_WELL_MEDIA = 1,
PUNIT_POWER_WELL_DISP2D = 3,
@@ -1077,14 +1249,20 @@ enum punit_power_well {
PUNIT_POWER_WELL_DPIO_RX0 = 10,
PUNIT_POWER_WELL_DPIO_RX1 = 11,
PUNIT_POWER_WELL_DPIO_CMN_D = 12,
-
- /* Not actual bit groups. Used as IDs for lookup_power_well() */
- PUNIT_POWER_WELL_ALWAYS_ON,
-};
-
-enum skl_disp_power_wells {
- /* These numbers are fixed and must match the position of the pw bits */
- SKL_DISP_PW_MISC_IO,
+ /* - custom power well */
+ CHV_DISP_PW_PIPE_A, /* 13 */
+
+ /*
+ * HSW/BDW
+ * - HSW_PWR_WELL_CTL_DRIVER(0) (status bit: id*2, req bit: id*2+1)
+ */
+ HSW_DISP_PW_GLOBAL = 15,
+
+ /*
+ * GEN9+
+ * - HSW_PWR_WELL_CTL_DRIVER(0) (status bit: id*2, req bit: id*2+1)
+ */
+ SKL_DISP_PW_MISC_IO = 0,
SKL_DISP_PW_DDI_A_E,
GLK_DISP_PW_DDI_A = SKL_DISP_PW_DDI_A_E,
CNL_DISP_PW_DDI_A = SKL_DISP_PW_DDI_A_E,
@@ -1103,18 +1281,20 @@ enum skl_disp_power_wells {
SKL_DISP_PW_1 = 14,
SKL_DISP_PW_2,
- /* Not actual bit groups. Used as IDs for lookup_power_well() */
- SKL_DISP_PW_ALWAYS_ON,
+ /* - custom power wells */
SKL_DISP_PW_DC_OFF,
-
BXT_DPIO_CMN_A,
BXT_DPIO_CMN_BC,
- GLK_DPIO_CMN_C,
+ GLK_DPIO_CMN_C, /* 19 */
+
+ /*
+ * Multiple platforms.
+ * Must start following the highest ID of any platform.
+ * - custom power wells
+ */
+ I915_DISP_PW_ALWAYS_ON = 20,
};
-#define SKL_POWER_WELL_STATE(pw) (1 << ((pw) * 2))
-#define SKL_POWER_WELL_REQ(pw) (1 << (((pw) * 2) + 1))
-
#define PUNIT_REG_PWRGT_CTRL 0x60
#define PUNIT_REG_PWRGT_STATUS 0x61
#define PUNIT_PWRGT_MASK(power_well) (3 << ((power_well) * 2))
@@ -2156,6 +2336,7 @@ enum skl_disp_power_wells {
#define DONE_REG _MMIO(0x40b0)
#define GEN8_PRIVATE_PAT_LO _MMIO(0x40e0)
#define GEN8_PRIVATE_PAT_HI _MMIO(0x40e0 + 4)
+#define GEN10_PAT_INDEX(index) _MMIO(0x40e0 + index*4)
#define BSD_HWS_PGA_GEN7 _MMIO(0x04180)
#define BLT_HWS_PGA_GEN7 _MMIO(0x04280)
#define VEBOX_HWS_PGA_GEN7 _MMIO(0x04380)
@@ -3522,7 +3703,7 @@ enum skl_disp_power_wells {
#define INTERVAL_1_28_US(us) roundup(((us) * 100) >> 7, 25)
#define INTERVAL_1_33_US(us) (((us) * 3) >> 2)
#define INTERVAL_0_833_US(us) (((us) * 6) / 5)
-#define GT_INTERVAL_FROM_US(dev_priv, us) (IS_GEN9(dev_priv) ? \
+#define GT_INTERVAL_FROM_US(dev_priv, us) (INTEL_GEN(dev_priv) >= 9 ? \
(IS_GEN9_LP(dev_priv) ? \
INTERVAL_0_833_US(us) : \
INTERVAL_1_33_US(us)) : \
@@ -3531,7 +3712,7 @@ enum skl_disp_power_wells {
#define INTERVAL_1_28_TO_US(interval) (((interval) << 7) / 100)
#define INTERVAL_1_33_TO_US(interval) (((interval) << 2) / 3)
#define INTERVAL_0_833_TO_US(interval) (((interval) * 5) / 6)
-#define GT_PM_INTERVAL_TO_US(dev_priv, interval) (IS_GEN9(dev_priv) ? \
+#define GT_PM_INTERVAL_TO_US(dev_priv, interval) (INTEL_GEN(dev_priv) >= 9 ? \
(IS_GEN9_LP(dev_priv) ? \
INTERVAL_0_833_TO_US(interval) : \
INTERVAL_1_33_TO_US(interval)) : \
@@ -3783,6 +3964,7 @@ enum {
#define EDP_PSR_CTL _MMIO(dev_priv->psr_mmio_base + 0)
#define EDP_PSR_ENABLE (1<<31)
#define BDW_PSR_SINGLE_FRAME (1<<30)
+#define EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK (1<<29) /* SW can't modify */
#define EDP_PSR_LINK_STANDBY (1<<27)
#define EDP_PSR_MIN_LINK_ENTRY_TIME_MASK (3<<25)
#define EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES (0<<25)
@@ -5227,6 +5409,9 @@ enum {
#define _PIPE_MISC_A 0x70030
#define _PIPE_MISC_B 0x71030
+#define PIPEMISC_YUV420_ENABLE (1<<27)
+#define PIPEMISC_YUV420_MODE_FULL_BLEND (1<<26)
+#define PIPEMISC_OUTPUT_COLORSPACE_YUV (1<<11)
#define PIPEMISC_DITHER_BPC_MASK (7<<5)
#define PIPEMISC_DITHER_8_BPC (0<<5)
#define PIPEMISC_DITHER_10_BPC (1<<5)
@@ -6106,6 +6291,10 @@ enum {
#define _PLANE_KEYMSK_2_A 0x70298
#define _PLANE_KEYMAX_1_A 0x701a0
#define _PLANE_KEYMAX_2_A 0x702a0
+#define _PLANE_AUX_DIST_1_A 0x701c0
+#define _PLANE_AUX_DIST_2_A 0x702c0
+#define _PLANE_AUX_OFFSET_1_A 0x701c4
+#define _PLANE_AUX_OFFSET_2_A 0x702c4
#define _PLANE_COLOR_CTL_1_A 0x701CC /* GLK+ */
#define _PLANE_COLOR_CTL_2_A 0x702CC /* GLK+ */
#define _PLANE_COLOR_CTL_3_A 0x703CC /* GLK+ */
@@ -6212,6 +6401,24 @@ enum {
#define PLANE_NV12_BUF_CFG(pipe, plane) \
_MMIO_PLANE(plane, _PLANE_NV12_BUF_CFG_1(pipe), _PLANE_NV12_BUF_CFG_2(pipe))
+#define _PLANE_AUX_DIST_1_B 0x711c0
+#define _PLANE_AUX_DIST_2_B 0x712c0
+#define _PLANE_AUX_DIST_1(pipe) \
+ _PIPE(pipe, _PLANE_AUX_DIST_1_A, _PLANE_AUX_DIST_1_B)
+#define _PLANE_AUX_DIST_2(pipe) \
+ _PIPE(pipe, _PLANE_AUX_DIST_2_A, _PLANE_AUX_DIST_2_B)
+#define PLANE_AUX_DIST(pipe, plane) \
+ _MMIO_PLANE(plane, _PLANE_AUX_DIST_1(pipe), _PLANE_AUX_DIST_2(pipe))
+
+#define _PLANE_AUX_OFFSET_1_B 0x711c4
+#define _PLANE_AUX_OFFSET_2_B 0x712c4
+#define _PLANE_AUX_OFFSET_1(pipe) \
+ _PIPE(pipe, _PLANE_AUX_OFFSET_1_A, _PLANE_AUX_OFFSET_1_B)
+#define _PLANE_AUX_OFFSET_2(pipe) \
+ _PIPE(pipe, _PLANE_AUX_OFFSET_2_A, _PLANE_AUX_OFFSET_2_B)
+#define PLANE_AUX_OFFSET(pipe, plane) \
+ _MMIO_PLANE(plane, _PLANE_AUX_OFFSET_1(pipe), _PLANE_AUX_OFFSET_2(pipe))
+
#define _PLANE_COLOR_CTL_1_B 0x711CC
#define _PLANE_COLOR_CTL_2_B 0x712CC
#define _PLANE_COLOR_CTL_3_B 0x713CC
@@ -6695,6 +6902,7 @@ enum {
# define CHICKEN3_DGMG_DONE_FIX_DISABLE (1 << 2)
#define CHICKEN_PAR1_1 _MMIO(0x42080)
+#define SKL_RC_HASH_OUTSIDE (1 << 15)
#define DPA_MASK_VBLANK_SRD (1 << 15)
#define FORCE_ARB_IDLE_PLANES (1 << 14)
#define SKL_EDP_PSR_FIX_RDWRAP (1 << 3)
@@ -6703,12 +6911,10 @@ enum {
#define KVM_CONFIG_CHANGE_NOTIFICATION_SELECT (1 << 14)
#define CHICKEN_MISC_2 _MMIO(0x42084)
-#define GLK_CL0_PWR_DOWN (1 << 10)
-#define GLK_CL1_PWR_DOWN (1 << 11)
+#define CNL_COMP_PWR_DOWN (1 << 23)
#define GLK_CL2_PWR_DOWN (1 << 12)
-
-#define CHICKEN_MISC_2 _MMIO(0x42084)
-#define COMP_PWR_DOWN (1 << 23)
+#define GLK_CL1_PWR_DOWN (1 << 11)
+#define GLK_CL0_PWR_DOWN (1 << 10)
#define _CHICKEN_PIPESL_1_A 0x420b0
#define _CHICKEN_PIPESL_1_B 0x420b4
@@ -7984,12 +8190,31 @@ enum {
#define SKL_AUD_CODEC_WAKE_SIGNAL (1 << 15)
/* HSW Power Wells */
-#define HSW_PWR_WELL_BIOS _MMIO(0x45400) /* CTL1 */
-#define HSW_PWR_WELL_DRIVER _MMIO(0x45404) /* CTL2 */
-#define HSW_PWR_WELL_KVMR _MMIO(0x45408) /* CTL3 */
-#define HSW_PWR_WELL_DEBUG _MMIO(0x4540C) /* CTL4 */
-#define HSW_PWR_WELL_ENABLE_REQUEST (1<<31)
-#define HSW_PWR_WELL_STATE_ENABLED (1<<30)
+#define _HSW_PWR_WELL_CTL1 0x45400
+#define _HSW_PWR_WELL_CTL2 0x45404
+#define _HSW_PWR_WELL_CTL3 0x45408
+#define _HSW_PWR_WELL_CTL4 0x4540C
+
+/*
+ * Each power well control register contains up to 16 (request, status) HW
+ * flag tuples. The register index and HW flag shift is determined by the
+ * power well ID (see i915_power_well_id). There are 4 possible sources of
+ * power well requests each source having its own set of control registers:
+ * BIOS, DRIVER, KVMR, DEBUG.
+ */
+#define _HSW_PW_REG_IDX(pw) ((pw) >> 4)
+#define _HSW_PW_SHIFT(pw) (((pw) & 0xf) * 2)
+/* TODO: Add all PWR_WELL_CTL registers below for new platforms */
+#define HSW_PWR_WELL_CTL_BIOS(pw) _MMIO(_PICK(_HSW_PW_REG_IDX(pw), \
+ _HSW_PWR_WELL_CTL1))
+#define HSW_PWR_WELL_CTL_DRIVER(pw) _MMIO(_PICK(_HSW_PW_REG_IDX(pw), \
+ _HSW_PWR_WELL_CTL2))
+#define HSW_PWR_WELL_CTL_KVMR _MMIO(_HSW_PWR_WELL_CTL3)
+#define HSW_PWR_WELL_CTL_DEBUG(pw) _MMIO(_PICK(_HSW_PW_REG_IDX(pw), \
+ _HSW_PWR_WELL_CTL4))
+
+#define HSW_PWR_WELL_CTL_REQ(pw) (1 << (_HSW_PW_SHIFT(pw) + 1))
+#define HSW_PWR_WELL_CTL_STATE(pw) (1 << _HSW_PW_SHIFT(pw))
#define HSW_PWR_WELL_CTL5 _MMIO(0x45410)
#define HSW_PWR_WELL_ENABLE_SINGLE_STEP (1<<31)
#define HSW_PWR_WELL_PWR_GATE_OVERRIDE (1<<20)
@@ -7997,11 +8222,17 @@ enum {
#define HSW_PWR_WELL_CTL6 _MMIO(0x45414)
/* SKL Fuse Status */
+enum skl_power_gate {
+ SKL_PG0,
+ SKL_PG1,
+ SKL_PG2,
+};
+
#define SKL_FUSE_STATUS _MMIO(0x42000)
-#define SKL_FUSE_DOWNLOAD_STATUS (1<<31)
-#define SKL_FUSE_PG0_DIST_STATUS (1<<27)
-#define SKL_FUSE_PG1_DIST_STATUS (1<<26)
-#define SKL_FUSE_PG2_DIST_STATUS (1<<25)
+#define SKL_FUSE_DOWNLOAD_STATUS (1<<31)
+/* PG0 (HW control->no power well ID), PG1..PG2 (SKL_DISP_PW1..SKL_DISP_PW2) */
+#define SKL_PW_TO_PG(pw) ((pw) - SKL_DISP_PW_1 + SKL_PG1)
+#define SKL_FUSE_PG_DIST_STATUS(pg) (1 << (27 - (pg)))
/* Per-pipe DDI Function Control */
#define _TRANS_DDI_FUNC_CTL_A 0x60400
@@ -8343,6 +8574,7 @@ enum {
#define DPLL_CFGCR0_LINK_RATE_3240 (6 << 25)
#define DPLL_CFGCR0_LINK_RATE_4050 (7 << 25)
#define DPLL_CFGCR0_DCO_FRACTION_MASK (0x7fff << 10)
+#define DPLL_CFGCR0_DCO_FRAC_SHIFT (10)
#define DPLL_CFGCR0_DCO_FRACTION(x) ((x) << 10)
#define DPLL_CFGCR0_DCO_INTEGER_MASK (0x3ff)
#define CNL_DPLL_CFGCR0(pll) _MMIO_PLL(pll, _CNL_DPLL0_CFGCR0, _CNL_DPLL1_CFGCR0)
@@ -8350,6 +8582,7 @@ enum {
#define _CNL_DPLL0_CFGCR1 0x6C004
#define _CNL_DPLL1_CFGCR1 0x6C084
#define DPLL_CFGCR1_QDIV_RATIO_MASK (0xff << 10)
+#define DPLL_CFGCR1_QDIV_RATIO_SHIFT (10)
#define DPLL_CFGCR1_QDIV_RATIO(x) ((x) << 10)
#define DPLL_CFGCR1_QDIV_MODE(x) ((x) << 9)
#define DPLL_CFGCR1_KDIV_MASK (7 << 6)
diff --git a/drivers/gpu/drm/i915/i915_selftest.h b/drivers/gpu/drm/i915/i915_selftest.h
index 9d7d86f1733d..78e1a1b168ff 100644
--- a/drivers/gpu/drm/i915/i915_selftest.h
+++ b/drivers/gpu/drm/i915/i915_selftest.h
@@ -101,6 +101,4 @@ bool __igt_timeout(unsigned long timeout, const char *fmt, ...);
#define igt_timeout(t, fmt, ...) \
__igt_timeout((t), KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
-#define igt_can_mi_store_dword_imm(D) (INTEL_GEN(D) > 2)
-
#endif /* !__I915_SELFTEST_H__ */
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index 1eef3fae4db3..d61c8727f756 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -96,7 +96,7 @@ static struct attribute *rc6_attrs[] = {
NULL
};
-static struct attribute_group rc6_attr_group = {
+static const struct attribute_group rc6_attr_group = {
.name = power_group_name,
.attrs = rc6_attrs
};
@@ -107,7 +107,7 @@ static struct attribute *rc6p_attrs[] = {
NULL
};
-static struct attribute_group rc6p_attr_group = {
+static const struct attribute_group rc6p_attr_group = {
.name = power_group_name,
.attrs = rc6p_attrs
};
@@ -117,7 +117,7 @@ static struct attribute *media_rc6_attrs[] = {
NULL
};
-static struct attribute_group media_rc6_attr_group = {
+static const struct attribute_group media_rc6_attr_group = {
.name = power_group_name,
.attrs = media_rc6_attrs
};
@@ -209,7 +209,7 @@ i915_l3_write(struct file *filp, struct kobject *kobj,
memcpy(*remap_info + (offset/4), buf, count);
/* NB: We defer the remapping until we switch to the context */
- list_for_each_entry(ctx, &dev_priv->context_list, link)
+ list_for_each_entry(ctx, &dev_priv->contexts.list, link)
ctx->remap_slice |= (1<<slice);
ret = count;
@@ -220,7 +220,7 @@ out:
return ret;
}
-static struct bin_attribute dpf_attrs = {
+static const struct bin_attribute dpf_attrs = {
.attr = {.name = "l3_parity", .mode = (S_IRUSR | S_IWUSR)},
.size = GEN7_L3LOG_SIZE,
.read = i915_l3_read,
@@ -229,7 +229,7 @@ static struct bin_attribute dpf_attrs = {
.private = (void *)0
};
-static struct bin_attribute dpf_attrs_1 = {
+static const struct bin_attribute dpf_attrs_1 = {
.attr = {.name = "l3_parity_slice_1", .mode = (S_IRUSR | S_IWUSR)},
.size = GEN7_L3LOG_SIZE,
.read = i915_l3_read,
@@ -253,7 +253,7 @@ static ssize_t gt_act_freq_mhz_show(struct device *kdev,
ret = intel_gpu_freq(dev_priv, (freq >> 8) & 0xff);
} else {
u32 rpstat = I915_READ(GEN6_RPSTAT1);
- if (IS_GEN9(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 9)
ret = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT;
else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
ret = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
@@ -532,7 +532,7 @@ static ssize_t error_state_write(struct file *file, struct kobject *kobj,
return count;
}
-static struct bin_attribute error_state_attr = {
+static const struct bin_attribute error_state_attr = {
.attr.name = "error",
.attr.mode = S_IRUSR | S_IWUSR,
.size = 0,
diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
index cf7a958e4d3c..5fe9f3f39467 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.c
+++ b/drivers/gpu/drm/i915/i915_vgpu.c
@@ -75,10 +75,17 @@ void i915_check_vgpu(struct drm_i915_private *dev_priv)
return;
}
+ dev_priv->vgpu.caps = __raw_i915_read32(dev_priv, vgtif_reg(vgt_caps));
+
dev_priv->vgpu.active = true;
DRM_INFO("Virtual GPU for Intel GVT-g detected.\n");
}
+bool intel_vgpu_has_full_48bit_ppgtt(struct drm_i915_private *dev_priv)
+{
+ return dev_priv->vgpu.caps & VGT_CAPS_FULL_48BIT_PPGTT;
+}
+
struct _balloon_info_ {
/*
* There are up to 2 regions per mappable/unmappable graphic
diff --git a/drivers/gpu/drm/i915/i915_vgpu.h b/drivers/gpu/drm/i915/i915_vgpu.h
index 3c3b2d24e830..b72bd2956b70 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.h
+++ b/drivers/gpu/drm/i915/i915_vgpu.h
@@ -27,6 +27,9 @@
#include "i915_pvinfo.h"
void i915_check_vgpu(struct drm_i915_private *dev_priv);
+
+bool intel_vgpu_has_full_48bit_ppgtt(struct drm_i915_private *dev_priv);
+
int intel_vgt_balloon(struct drm_i915_private *dev_priv);
void intel_vgt_deballoon(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 1cfe137cdc32..02d1a5eacb00 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -579,11 +579,17 @@ err_unpin:
static void i915_vma_destroy(struct i915_vma *vma)
{
+ int i;
+
GEM_BUG_ON(vma->node.allocated);
GEM_BUG_ON(i915_vma_is_active(vma));
GEM_BUG_ON(!i915_vma_is_closed(vma));
GEM_BUG_ON(vma->fence);
+ for (i = 0; i < ARRAY_SIZE(vma->last_read); i++)
+ GEM_BUG_ON(i915_gem_active_isset(&vma->last_read[i]));
+ GEM_BUG_ON(i915_gem_active_isset(&vma->last_fence));
+
list_del(&vma->vm_link);
if (!i915_vma_is_ggtt(vma))
i915_ppgtt_put(i915_vm_to_ppgtt(vma->vm));
@@ -591,33 +597,11 @@ static void i915_vma_destroy(struct i915_vma *vma)
kmem_cache_free(to_i915(vma->obj->base.dev)->vmas, vma);
}
-void i915_vma_unlink_ctx(struct i915_vma *vma)
-{
- struct i915_gem_context *ctx = vma->ctx;
-
- if (ctx->vma_lut.ht_size & I915_CTX_RESIZE_IN_PROGRESS) {
- cancel_work_sync(&ctx->vma_lut.resize);
- ctx->vma_lut.ht_size &= ~I915_CTX_RESIZE_IN_PROGRESS;
- }
-
- __hlist_del(&vma->ctx_node);
- ctx->vma_lut.ht_count--;
-
- if (i915_vma_is_ggtt(vma))
- vma->obj->vma_hashed = NULL;
- vma->ctx = NULL;
-
- i915_vma_put(vma);
-}
-
void i915_vma_close(struct i915_vma *vma)
{
GEM_BUG_ON(i915_vma_is_closed(vma));
vma->flags |= I915_VMA_CLOSED;
- if (vma->ctx)
- i915_vma_unlink_ctx(vma);
-
list_del(&vma->obj_link);
rb_erase(&vma->obj_node, &vma->obj->vma_tree);
@@ -680,9 +664,8 @@ int i915_vma_unbind(struct i915_vma *vma)
__i915_vma_unpin(vma);
if (ret)
return ret;
-
- GEM_BUG_ON(i915_vma_is_active(vma));
}
+ GEM_BUG_ON(i915_vma_is_active(vma));
if (i915_vma_is_pinned(vma))
return -EBUSY;
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 4a673fc1a432..1fd61e88cfd0 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -112,13 +112,9 @@ struct i915_vma {
/**
* Used for performing relocations during execbuffer insertion.
*/
- struct drm_i915_gem_exec_object2 *exec_entry;
+ unsigned int *exec_flags;
struct hlist_node exec_node;
u32 exec_handle;
-
- struct i915_gem_context *ctx;
- struct hlist_node ctx_node;
- u32 ctx_handle;
};
struct i915_vma *
@@ -284,12 +280,12 @@ static inline void __i915_vma_pin(struct i915_vma *vma)
static inline void __i915_vma_unpin(struct i915_vma *vma)
{
- GEM_BUG_ON(!i915_vma_is_pinned(vma));
vma->flags--;
}
static inline void i915_vma_unpin(struct i915_vma *vma)
{
+ GEM_BUG_ON(!i915_vma_is_pinned(vma));
GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
__i915_vma_unpin(vma);
}
diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
index 4325cb0a04f5..ee76fab7bb6f 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -114,6 +114,8 @@ int intel_plane_atomic_check_with_state(struct intel_crtc_state *crtc_state,
struct drm_i915_private *dev_priv = to_i915(plane->dev);
struct drm_plane_state *state = &intel_state->base;
struct intel_plane *intel_plane = to_intel_plane(plane);
+ const struct drm_display_mode *adjusted_mode =
+ &crtc_state->base.adjusted_mode;
int ret;
/*
@@ -173,6 +175,19 @@ int intel_plane_atomic_check_with_state(struct intel_crtc_state *crtc_state,
if (ret)
return ret;
+ /*
+ * Y-tiling is not supported in IF-ID Interlace mode in
+ * GEN9 and above.
+ */
+ if (state->fb && INTEL_GEN(dev_priv) >= 9 && crtc_state->base.enable &&
+ adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+ if (state->fb->modifier == I915_FORMAT_MOD_Y_TILED ||
+ state->fb->modifier == I915_FORMAT_MOD_Yf_TILED) {
+ DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n");
+ return -EINVAL;
+ }
+ }
+
/* FIXME pre-g4x don't work like this */
if (intel_state->base.visible)
crtc_state->active_planes |= BIT(intel_plane->id);
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 639d45c1dd2e..183e87e8ea31 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -1120,8 +1120,8 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
bool is_dvi, is_hdmi, is_dp, is_edp, is_crt;
uint8_t aux_channel, ddc_pin;
/* Each DDI port can have more than one value on the "DVO Port" field,
- * so look for all the possible values for each port and abort if more
- * than one is found. */
+ * so look for all the possible values for each port.
+ */
int dvo_ports[][3] = {
{DVO_PORT_HDMIA, DVO_PORT_DPA, -1},
{DVO_PORT_HDMIB, DVO_PORT_DPB, -1},
@@ -1130,7 +1130,10 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
{DVO_PORT_CRT, DVO_PORT_HDMIE, DVO_PORT_DPE},
};
- /* Find the child device to use, abort if more than one found. */
+ /*
+ * Find the first child device to reference the port, report if more
+ * than one found.
+ */
for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
it = dev_priv->vbt.child_dev + i;
@@ -1140,11 +1143,11 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
if (it->common.dvo_port == dvo_ports[port][j]) {
if (child) {
- DRM_DEBUG_KMS("More than one child device for port %c in VBT.\n",
+ DRM_DEBUG_KMS("More than one child device for port %c in VBT, using the first.\n",
port_name(port));
- return;
+ } else {
+ child = it;
}
- child = it;
}
}
}
@@ -1187,6 +1190,15 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
if (is_dvi) {
info->alternate_ddc_pin = ddc_pin;
+ /*
+ * All VBTs that we got so far for B Stepping has this
+ * information wrong for Port D. So, let's just ignore for now.
+ */
+ if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0) &&
+ port == PORT_D) {
+ info->alternate_ddc_pin = 0;
+ }
+
sanitize_ddc_pin(dev_priv, port);
}
diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c
index 306c6b06b330..8e4e829682b9 100644
--- a/drivers/gpu/drm/i915/intel_color.c
+++ b/drivers/gpu/drm/i915/intel_color.c
@@ -41,6 +41,22 @@
#define LEGACY_LUT_LENGTH (sizeof(struct drm_color_lut) * 256)
+/* Post offset values for RGB->YCBCR conversion */
+#define POSTOFF_RGB_TO_YUV_HI 0x800
+#define POSTOFF_RGB_TO_YUV_ME 0x100
+#define POSTOFF_RGB_TO_YUV_LO 0x800
+
+/*
+ * These values are direct register values specified in the Bspec,
+ * for RGB->YUV conversion matrix (colorspace BT709)
+ */
+#define CSC_RGB_TO_YUV_RU_GU 0x2ba809d8
+#define CSC_RGB_TO_YUV_BU 0x37e80000
+#define CSC_RGB_TO_YUV_RY_GY 0x1e089cc0
+#define CSC_RGB_TO_YUV_BY 0xb5280000
+#define CSC_RGB_TO_YUV_RV_GV 0xbce89ad8
+#define CSC_RGB_TO_YUV_BV 0x1e080000
+
/*
* Extract the CSC coefficient from a CTM coefficient (in U32.32 fixed point
* format). This macro takes the coefficient we want transformed and the
@@ -91,6 +107,30 @@ static void ctm_mult_by_limited(uint64_t *result, int64_t *input)
}
}
+void i9xx_load_ycbcr_conversion_matrix(struct intel_crtc *intel_crtc)
+{
+ int pipe = intel_crtc->pipe;
+ struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
+
+ I915_WRITE(PIPE_CSC_PREOFF_HI(pipe), 0);
+ I915_WRITE(PIPE_CSC_PREOFF_ME(pipe), 0);
+ I915_WRITE(PIPE_CSC_PREOFF_LO(pipe), 0);
+
+ I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe), CSC_RGB_TO_YUV_RU_GU);
+ I915_WRITE(PIPE_CSC_COEFF_BU(pipe), CSC_RGB_TO_YUV_BU);
+
+ I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe), CSC_RGB_TO_YUV_RY_GY);
+ I915_WRITE(PIPE_CSC_COEFF_BY(pipe), CSC_RGB_TO_YUV_BY);
+
+ I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe), CSC_RGB_TO_YUV_RV_GV);
+ I915_WRITE(PIPE_CSC_COEFF_BV(pipe), CSC_RGB_TO_YUV_BV);
+
+ I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), POSTOFF_RGB_TO_YUV_HI);
+ I915_WRITE(PIPE_CSC_POSTOFF_ME(pipe), POSTOFF_RGB_TO_YUV_ME);
+ I915_WRITE(PIPE_CSC_POSTOFF_LO(pipe), POSTOFF_RGB_TO_YUV_LO);
+ I915_WRITE(PIPE_CSC_MODE(pipe), 0);
+}
+
/* Set up the pipe CSC unit. */
static void i9xx_load_csc_matrix(struct drm_crtc_state *crtc_state)
{
@@ -101,7 +141,10 @@ static void i9xx_load_csc_matrix(struct drm_crtc_state *crtc_state)
uint16_t coeffs[9] = { 0, };
struct intel_crtc_state *intel_crtc_state = to_intel_crtc_state(crtc_state);
- if (crtc_state->ctm) {
+ if (intel_crtc_state->ycbcr420) {
+ i9xx_load_ycbcr_conversion_matrix(intel_crtc);
+ return;
+ } else if (crtc_state->ctm) {
struct drm_color_ctm *ctm =
(struct drm_color_ctm *)crtc_state->ctm->data;
uint64_t input[9] = { 0, };
@@ -398,6 +441,7 @@ static void bdw_load_gamma_lut(struct drm_crtc_state *state, u32 offset)
}
/* Program the max register to clamp values > 1.0. */
+ i = lut_size - 1;
I915_WRITE(PREC_PAL_GC_MAX(pipe, 0),
drm_color_lut_extract(lut[i].red, 16));
I915_WRITE(PREC_PAL_GC_MAX(pipe, 1),
@@ -615,7 +659,7 @@ void intel_color_init(struct drm_crtc *crtc)
IS_BROXTON(dev_priv)) {
dev_priv->display.load_csc_matrix = i9xx_load_csc_matrix;
dev_priv->display.load_luts = broadwell_load_luts;
- } else if (IS_GEMINILAKE(dev_priv)) {
+ } else if (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) {
dev_priv->display.load_csc_matrix = i9xx_load_csc_matrix;
dev_priv->display.load_luts = glk_load_luts;
} else {
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 84a1f5e85153..70e0ff41070c 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -802,12 +802,10 @@ void intel_crt_reset(struct drm_encoder *encoder)
*/
static const struct drm_connector_funcs intel_crt_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.late_register = intel_connector_register,
.early_unregister = intel_connector_unregister,
.destroy = intel_crt_destroy,
- .set_property = drm_atomic_helper_connector_set_property,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
};
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 80e96f1f49d2..4b4fd1f8110b 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1103,6 +1103,62 @@ static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
return dco_freq / (p0 * p1 * p2 * 5);
}
+static int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv,
+ uint32_t pll_id)
+{
+ uint32_t cfgcr0, cfgcr1;
+ uint32_t p0, p1, p2, dco_freq, ref_clock;
+
+ cfgcr0 = I915_READ(CNL_DPLL_CFGCR0(pll_id));
+ cfgcr1 = I915_READ(CNL_DPLL_CFGCR1(pll_id));
+
+ p0 = cfgcr1 & DPLL_CFGCR1_PDIV_MASK;
+ p2 = cfgcr1 & DPLL_CFGCR1_KDIV_MASK;
+
+ if (cfgcr1 & DPLL_CFGCR1_QDIV_MODE(1))
+ p1 = (cfgcr1 & DPLL_CFGCR1_QDIV_RATIO_MASK) >>
+ DPLL_CFGCR1_QDIV_RATIO_SHIFT;
+ else
+ p1 = 1;
+
+
+ switch (p0) {
+ case DPLL_CFGCR1_PDIV_2:
+ p0 = 2;
+ break;
+ case DPLL_CFGCR1_PDIV_3:
+ p0 = 3;
+ break;
+ case DPLL_CFGCR1_PDIV_5:
+ p0 = 5;
+ break;
+ case DPLL_CFGCR1_PDIV_7:
+ p0 = 7;
+ break;
+ }
+
+ switch (p2) {
+ case DPLL_CFGCR1_KDIV_1:
+ p2 = 1;
+ break;
+ case DPLL_CFGCR1_KDIV_2:
+ p2 = 2;
+ break;
+ case DPLL_CFGCR1_KDIV_4:
+ p2 = 4;
+ break;
+ }
+
+ ref_clock = dev_priv->cdclk.hw.ref;
+
+ dco_freq = (cfgcr0 & DPLL_CFGCR0_DCO_INTEGER_MASK) * ref_clock;
+
+ dco_freq += (((cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK) >>
+ DPLL_CFGCR0_DCO_FRAC_SHIFT) * ref_clock) / 0x8000;
+
+ return dco_freq / (p0 * p1 * p2 * 5);
+}
+
static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
{
int dotclock;
@@ -1118,12 +1174,68 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
else
dotclock = pipe_config->port_clock;
+ if (pipe_config->ycbcr420)
+ dotclock *= 2;
+
if (pipe_config->pixel_multiplier)
dotclock /= pipe_config->pixel_multiplier;
pipe_config->base.adjusted_mode.crtc_clock = dotclock;
}
+static void cnl_ddi_clock_get(struct intel_encoder *encoder,
+ struct intel_crtc_state *pipe_config)
+{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ int link_clock = 0;
+ uint32_t cfgcr0, pll_id;
+
+ pll_id = intel_get_shared_dpll_id(dev_priv, pipe_config->shared_dpll);
+
+ cfgcr0 = I915_READ(CNL_DPLL_CFGCR0(pll_id));
+
+ if (cfgcr0 & DPLL_CFGCR0_HDMI_MODE) {
+ link_clock = cnl_calc_wrpll_link(dev_priv, pll_id);
+ } else {
+ link_clock = cfgcr0 & DPLL_CFGCR0_LINK_RATE_MASK;
+
+ switch (link_clock) {
+ case DPLL_CFGCR0_LINK_RATE_810:
+ link_clock = 81000;
+ break;
+ case DPLL_CFGCR0_LINK_RATE_1080:
+ link_clock = 108000;
+ break;
+ case DPLL_CFGCR0_LINK_RATE_1350:
+ link_clock = 135000;
+ break;
+ case DPLL_CFGCR0_LINK_RATE_1620:
+ link_clock = 162000;
+ break;
+ case DPLL_CFGCR0_LINK_RATE_2160:
+ link_clock = 216000;
+ break;
+ case DPLL_CFGCR0_LINK_RATE_2700:
+ link_clock = 270000;
+ break;
+ case DPLL_CFGCR0_LINK_RATE_3240:
+ link_clock = 324000;
+ break;
+ case DPLL_CFGCR0_LINK_RATE_4050:
+ link_clock = 405000;
+ break;
+ default:
+ WARN(1, "Unsupported link rate\n");
+ break;
+ }
+ link_clock *= 2;
+ }
+
+ pipe_config->port_clock = link_clock;
+
+ ddi_dotclock_get(pipe_config);
+}
+
static void skl_ddi_clock_get(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
{
@@ -1267,6 +1379,8 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
skl_ddi_clock_get(encoder, pipe_config);
else if (IS_GEN9_LP(dev_priv))
bxt_ddi_clock_get(encoder, pipe_config);
+ else if (IS_CANNONLAKE(dev_priv))
+ cnl_ddi_clock_get(encoder, pipe_config);
}
void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state)
@@ -1762,7 +1876,7 @@ cnl_get_buf_trans_edp(struct drm_i915_private *dev_priv,
if (dev_priv->vbt.edp.low_vswing) {
if (voltage == VOLTAGE_INFO_0_85V) {
*n_entries = ARRAY_SIZE(cnl_ddi_translations_edp_0_85V);
- return cnl_ddi_translations_dp_0_85V;
+ return cnl_ddi_translations_edp_0_85V;
} else if (voltage == VOLTAGE_INFO_0_95V) {
*n_entries = ARRAY_SIZE(cnl_ddi_translations_edp_0_95V);
return cnl_ddi_translations_edp_0_95V;
@@ -1868,9 +1982,12 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level)
if ((intel_dp) && (type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP)) {
width = intel_dp->lane_count;
rate = intel_dp->link_rate;
- } else {
+ } else if (type == INTEL_OUTPUT_HDMI) {
width = 4;
/* Rate is always < than 6GHz for HDMI */
+ } else {
+ MISSING_CASE(type);
+ return;
}
/*
@@ -1896,8 +2013,8 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level)
val = I915_READ(CNL_PORT_TX_DW4_LN(port, ln));
val &= ~LOADGEN_SELECT;
- if (((rate < 600000) && (width == 4) && (ln >= 1)) ||
- ((rate < 600000) && (width < 4) && ((ln == 1) || (ln == 2)))) {
+ if ((rate <= 600000 && width == 4 && ln >= 1) ||
+ (rate <= 600000 && width < 4 && (ln == 1 || ln == 2))) {
val |= LOADGEN_SELECT;
}
I915_WRITE(CNL_PORT_TX_DW4_LN(port, ln), val);
diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c
index 77d3214e1a77..5f91ddc78c7a 100644
--- a/drivers/gpu/drm/i915/intel_device_info.c
+++ b/drivers/gpu/drm/i915/intel_device_info.c
@@ -363,7 +363,7 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
*/
if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE ||
sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED ||
- (dev_priv->pch_type == PCH_CPT &&
+ (HAS_PCH_CPT(dev_priv) &&
!(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) {
DRM_INFO("Display fused off, disabling\n");
info->num_pipes = 0;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index dec9e58545a1..0e93ec201fe3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -49,11 +49,6 @@
#include <linux/dma_remapping.h>
#include <linux/reservation.h>
-static bool is_mmio_work(struct intel_flip_work *work)
-{
- return work->mmio_work.func;
-}
-
/* Primary plane formats for gen <= 3 */
static const uint32_t i8xx_primary_formats[] = {
DRM_FORMAT_C8,
@@ -72,6 +67,12 @@ static const uint32_t i965_primary_formats[] = {
DRM_FORMAT_XBGR2101010,
};
+static const uint64_t i9xx_format_modifiers[] = {
+ I915_FORMAT_MOD_X_TILED,
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_FORMAT_MOD_INVALID
+};
+
static const uint32_t skl_primary_formats[] = {
DRM_FORMAT_C8,
DRM_FORMAT_RGB565,
@@ -87,11 +88,34 @@ static const uint32_t skl_primary_formats[] = {
DRM_FORMAT_VYUY,
};
+static const uint64_t skl_format_modifiers_noccs[] = {
+ I915_FORMAT_MOD_Yf_TILED,
+ I915_FORMAT_MOD_Y_TILED,
+ I915_FORMAT_MOD_X_TILED,
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_FORMAT_MOD_INVALID
+};
+
+static const uint64_t skl_format_modifiers_ccs[] = {
+ I915_FORMAT_MOD_Yf_TILED_CCS,
+ I915_FORMAT_MOD_Y_TILED_CCS,
+ I915_FORMAT_MOD_Yf_TILED,
+ I915_FORMAT_MOD_Y_TILED,
+ I915_FORMAT_MOD_X_TILED,
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_FORMAT_MOD_INVALID
+};
+
/* Cursor formats */
static const uint32_t intel_cursor_formats[] = {
DRM_FORMAT_ARGB8888,
};
+static const uint64_t cursor_format_modifiers[] = {
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_FORMAT_MOD_INVALID
+};
+
static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config);
static void ironlake_pch_clock_get(struct intel_crtc *crtc,
@@ -1777,7 +1801,7 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
/* FDI must be feeding us bits for PCH ports */
assert_fdi_tx_enabled(dev_priv, (enum pipe) cpu_transcoder);
- assert_fdi_rx_enabled(dev_priv, TRANSCODER_A);
+ assert_fdi_rx_enabled(dev_priv, PIPE_A);
/* Workaround: set timing override bit. */
val = I915_READ(TRANS_CHICKEN2(PIPE_A));
@@ -1853,16 +1877,16 @@ void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv)
I915_WRITE(TRANS_CHICKEN2(PIPE_A), val);
}
-enum transcoder intel_crtc_pch_transcoder(struct intel_crtc *crtc)
+enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
WARN_ON(!crtc->config->has_pch_encoder);
if (HAS_PCH_LPT(dev_priv))
- return TRANSCODER_A;
+ return PIPE_A;
else
- return (enum transcoder) crtc->pipe;
+ return crtc->pipe;
}
/**
@@ -1901,7 +1925,7 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
if (crtc->config->has_pch_encoder) {
/* if driving the PCH, we need FDI enabled */
assert_fdi_rx_pll_enabled(dev_priv,
- (enum pipe) intel_crtc_pch_transcoder(crtc));
+ intel_crtc_pch_transcoder(crtc));
assert_fdi_tx_pll_enabled(dev_priv,
(enum pipe) cpu_transcoder);
}
@@ -1999,11 +2023,19 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int plane)
return 128;
else
return 512;
+ case I915_FORMAT_MOD_Y_TILED_CCS:
+ if (plane == 1)
+ return 128;
+ /* fall through */
case I915_FORMAT_MOD_Y_TILED:
if (IS_GEN2(dev_priv) || HAS_128_BYTE_Y_TILING(dev_priv))
return 128;
else
return 512;
+ case I915_FORMAT_MOD_Yf_TILED_CCS:
+ if (plane == 1)
+ return 128;
+ /* fall through */
case I915_FORMAT_MOD_Yf_TILED:
switch (cpp) {
case 1:
@@ -2110,7 +2142,7 @@ static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
struct drm_i915_private *dev_priv = to_i915(fb->dev);
/* AUX_DIST needs only 4K alignment */
- if (fb->format->format == DRM_FORMAT_NV12 && plane == 1)
+ if (plane == 1)
return 4096;
switch (fb->modifier) {
@@ -2120,6 +2152,8 @@ static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
if (INTEL_GEN(dev_priv) >= 9)
return 256 * 1024;
return 0;
+ case I915_FORMAT_MOD_Y_TILED_CCS:
+ case I915_FORMAT_MOD_Yf_TILED_CCS:
case I915_FORMAT_MOD_Y_TILED:
case I915_FORMAT_MOD_Yf_TILED:
return 1 * 1024 * 1024;
@@ -2162,6 +2196,8 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
*/
intel_runtime_pm_get(dev_priv);
+ atomic_inc(&dev_priv->gpu_error.pending_fb_pin);
+
vma = i915_gem_object_pin_to_display_plane(obj, alignment, &view);
if (IS_ERR(vma))
goto err;
@@ -2189,6 +2225,8 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
i915_vma_get(vma);
err:
+ atomic_dec(&dev_priv->gpu_error.pending_fb_pin);
+
intel_runtime_pm_put(dev_priv);
return vma;
}
@@ -2427,12 +2465,48 @@ static unsigned int intel_fb_modifier_to_tiling(uint64_t fb_modifier)
case I915_FORMAT_MOD_X_TILED:
return I915_TILING_X;
case I915_FORMAT_MOD_Y_TILED:
+ case I915_FORMAT_MOD_Y_TILED_CCS:
return I915_TILING_Y;
default:
return I915_TILING_NONE;
}
}
+static const struct drm_format_info ccs_formats[] = {
+ { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
+ { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
+ { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
+ { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
+};
+
+static const struct drm_format_info *
+lookup_format_info(const struct drm_format_info formats[],
+ int num_formats, u32 format)
+{
+ int i;
+
+ for (i = 0; i < num_formats; i++) {
+ if (formats[i].format == format)
+ return &formats[i];
+ }
+
+ return NULL;
+}
+
+static const struct drm_format_info *
+intel_get_format_info(const struct drm_mode_fb_cmd2 *cmd)
+{
+ switch (cmd->modifier[0]) {
+ case I915_FORMAT_MOD_Y_TILED_CCS:
+ case I915_FORMAT_MOD_Yf_TILED_CCS:
+ return lookup_format_info(ccs_formats,
+ ARRAY_SIZE(ccs_formats),
+ cmd->pixel_format);
+ default:
+ return NULL;
+ }
+}
+
static int
intel_fill_fb_info(struct drm_i915_private *dev_priv,
struct drm_framebuffer *fb)
@@ -2456,6 +2530,36 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
intel_fb_offset_to_xy(&x, &y, fb, i);
+ if ((fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+ fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) && i == 1) {
+ int hsub = fb->format->hsub;
+ int vsub = fb->format->vsub;
+ int tile_width, tile_height;
+ int main_x, main_y;
+ int ccs_x, ccs_y;
+
+ intel_tile_dims(fb, i, &tile_width, &tile_height);
+
+ ccs_x = (x * hsub) % (tile_width * hsub);
+ ccs_y = (y * vsub) % (tile_height * vsub);
+ main_x = intel_fb->normal[0].x % (tile_width * hsub);
+ main_y = intel_fb->normal[0].y % (tile_height * vsub);
+
+ /*
+ * CCS doesn't have its own x/y offset register, so the intra CCS tile
+ * x/y offsets must match between CCS and the main surface.
+ */
+ if (main_x != ccs_x || main_y != ccs_y) {
+ DRM_DEBUG_KMS("Bad CCS x/y (main %d,%d ccs %d,%d) full (main %d,%d ccs %d,%d)\n",
+ main_x, main_y,
+ ccs_x, ccs_y,
+ intel_fb->normal[0].x,
+ intel_fb->normal[0].y,
+ x, y);
+ return -EINVAL;
+ }
+ }
+
/*
* The fence (if used) is aligned to the start of the object
* so having the framebuffer wrap around across the edge of the
@@ -2664,20 +2768,6 @@ out_unref_obj:
return false;
}
-/* Update plane->state->fb to match plane->fb after driver-internal updates */
-static void
-update_state_fb(struct drm_plane *plane)
-{
- if (plane->fb == plane->state->fb)
- return;
-
- if (plane->state->fb)
- drm_framebuffer_unreference(plane->state->fb);
- plane->state->fb = plane->fb;
- if (plane->state->fb)
- drm_framebuffer_reference(plane->state->fb);
-}
-
static void
intel_set_plane_visible(struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state,
@@ -2830,6 +2920,9 @@ static int skl_max_plane_width(const struct drm_framebuffer *fb, int plane,
break;
}
break;
+ case I915_FORMAT_MOD_Y_TILED_CCS:
+ case I915_FORMAT_MOD_Yf_TILED_CCS:
+ /* FIXME AUX plane? */
case I915_FORMAT_MOD_Y_TILED:
case I915_FORMAT_MOD_Yf_TILED:
switch (cpp) {
@@ -2852,6 +2945,44 @@ static int skl_max_plane_width(const struct drm_framebuffer *fb, int plane,
return 2048;
}
+static bool skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state,
+ int main_x, int main_y, u32 main_offset)
+{
+ const struct drm_framebuffer *fb = plane_state->base.fb;
+ int hsub = fb->format->hsub;
+ int vsub = fb->format->vsub;
+ int aux_x = plane_state->aux.x;
+ int aux_y = plane_state->aux.y;
+ u32 aux_offset = plane_state->aux.offset;
+ u32 alignment = intel_surf_alignment(fb, 1);
+
+ while (aux_offset >= main_offset && aux_y <= main_y) {
+ int x, y;
+
+ if (aux_x == main_x && aux_y == main_y)
+ break;
+
+ if (aux_offset == 0)
+ break;
+
+ x = aux_x / hsub;
+ y = aux_y / vsub;
+ aux_offset = intel_adjust_tile_offset(&x, &y, plane_state, 1,
+ aux_offset, aux_offset - alignment);
+ aux_x = x * hsub + aux_x % hsub;
+ aux_y = y * vsub + aux_y % vsub;
+ }
+
+ if (aux_x != main_x || aux_y != main_y)
+ return false;
+
+ plane_state->aux.offset = aux_offset;
+ plane_state->aux.x = aux_x;
+ plane_state->aux.y = aux_y;
+
+ return true;
+}
+
static int skl_check_main_surface(struct intel_plane_state *plane_state)
{
const struct drm_framebuffer *fb = plane_state->base.fb;
@@ -2894,7 +3025,7 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
while ((x + w) * cpp > fb->pitches[0]) {
if (offset == 0) {
- DRM_DEBUG_KMS("Unable to find suitable display surface offset\n");
+ DRM_DEBUG_KMS("Unable to find suitable display surface offset due to X-tiling\n");
return -EINVAL;
}
@@ -2903,6 +3034,26 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
}
}
+ /*
+ * CCS AUX surface doesn't have its own x/y offsets, we must make sure
+ * they match with the main surface x/y offsets.
+ */
+ if (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+ fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) {
+ while (!skl_check_main_ccs_coordinates(plane_state, x, y, offset)) {
+ if (offset == 0)
+ break;
+
+ offset = intel_adjust_tile_offset(&x, &y, plane_state, 0,
+ offset, offset - alignment);
+ }
+
+ if (x != plane_state->aux.x || y != plane_state->aux.y) {
+ DRM_DEBUG_KMS("Unable to find suitable display surface offset due to CCS\n");
+ return -EINVAL;
+ }
+ }
+
plane_state->main.offset = offset;
plane_state->main.x = x;
plane_state->main.y = y;
@@ -2939,6 +3090,49 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
return 0;
}
+static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
+{
+ struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
+ struct intel_crtc *crtc = to_intel_crtc(plane_state->base.crtc);
+ const struct drm_framebuffer *fb = plane_state->base.fb;
+ int src_x = plane_state->base.src.x1 >> 16;
+ int src_y = plane_state->base.src.y1 >> 16;
+ int hsub = fb->format->hsub;
+ int vsub = fb->format->vsub;
+ int x = src_x / hsub;
+ int y = src_y / vsub;
+ u32 offset;
+
+ switch (plane->id) {
+ case PLANE_PRIMARY:
+ case PLANE_SPRITE0:
+ break;
+ default:
+ DRM_DEBUG_KMS("RC support only on plane 1 and 2\n");
+ return -EINVAL;
+ }
+
+ if (crtc->pipe == PIPE_C) {
+ DRM_DEBUG_KMS("No RC support on pipe C\n");
+ return -EINVAL;
+ }
+
+ if (plane_state->base.rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180)) {
+ DRM_DEBUG_KMS("RC support only with 0/180 degree rotation %x\n",
+ plane_state->base.rotation);
+ return -EINVAL;
+ }
+
+ intel_add_fb_offsets(&x, &y, plane_state, 1);
+ offset = intel_compute_tile_offset(&x, &y, plane_state, 1);
+
+ plane_state->aux.offset = offset;
+ plane_state->aux.x = x * hsub + src_x % hsub;
+ plane_state->aux.y = y * vsub + src_y % vsub;
+
+ return 0;
+}
+
int skl_check_plane_surface(struct intel_plane_state *plane_state)
{
const struct drm_framebuffer *fb = plane_state->base.fb;
@@ -2962,6 +3156,11 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
ret = skl_check_nv12_aux_surface(plane_state);
if (ret)
return ret;
+ } else if (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+ fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS) {
+ ret = skl_check_ccs_aux_surface(plane_state);
+ if (ret)
+ return ret;
} else {
plane_state->aux.offset = ~0xfff;
plane_state->aux.x = 0;
@@ -3268,8 +3467,12 @@ static u32 skl_plane_ctl_tiling(uint64_t fb_modifier)
return PLANE_CTL_TILED_X;
case I915_FORMAT_MOD_Y_TILED:
return PLANE_CTL_TILED_Y;
+ case I915_FORMAT_MOD_Y_TILED_CCS:
+ return PLANE_CTL_TILED_Y | PLANE_CTL_DECOMPRESSION_ENABLE;
case I915_FORMAT_MOD_Yf_TILED:
return PLANE_CTL_TILED_YF;
+ case I915_FORMAT_MOD_Yf_TILED_CCS:
+ return PLANE_CTL_TILED_YF | PLANE_CTL_DECOMPRESSION_ENABLE;
default:
MISSING_CASE(fb_modifier);
}
@@ -3311,7 +3514,7 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
plane_ctl = PLANE_CTL_ENABLE;
- if (!IS_GEMINILAKE(dev_priv)) {
+ if (!IS_GEMINILAKE(dev_priv) && !IS_CANNONLAKE(dev_priv)) {
plane_ctl |=
PLANE_CTL_PIPE_GAMMA_ENABLE |
PLANE_CTL_PIPE_CSC_ENABLE |
@@ -3342,6 +3545,7 @@ static void skylake_update_primary_plane(struct intel_plane *plane,
u32 plane_ctl = plane_state->ctl;
unsigned int rotation = plane_state->base.rotation;
u32 stride = skl_plane_stride(fb, 0, rotation);
+ u32 aux_stride = skl_plane_stride(fb, 1, rotation);
u32 surf_addr = plane_state->main.offset;
int scaler_id = plane_state->scaler_id;
int src_x = plane_state->main.x;
@@ -3367,7 +3571,7 @@ static void skylake_update_primary_plane(struct intel_plane *plane,
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
- if (IS_GEMINILAKE(dev_priv)) {
+ if (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) {
I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
PLANE_COLOR_PIPE_GAMMA_ENABLE |
PLANE_COLOR_PIPE_CSC_ENABLE |
@@ -3378,6 +3582,10 @@ static void skylake_update_primary_plane(struct intel_plane *plane,
I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (src_y << 16) | src_x);
I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
+ I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
+ (plane_state->aux.offset - surf_addr) | aux_stride);
+ I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
+ (plane_state->aux.y << 16) | plane_state->aux.x);
if (scaler_id >= 0) {
uint32_t ps_ctrl = 0;
@@ -3419,34 +3627,6 @@ static void skylake_disable_primary_plane(struct intel_plane *primary,
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
}
-static void intel_complete_page_flips(struct drm_i915_private *dev_priv)
-{
- struct intel_crtc *crtc;
-
- for_each_intel_crtc(&dev_priv->drm, crtc)
- intel_finish_page_flip_cs(dev_priv, crtc->pipe);
-}
-
-static void intel_update_primary_planes(struct drm_device *dev)
-{
- struct drm_crtc *crtc;
-
- for_each_crtc(dev, crtc) {
- struct intel_plane *plane = to_intel_plane(crtc->primary);
- struct intel_plane_state *plane_state =
- to_intel_plane_state(plane->base.state);
-
- if (plane_state->base.visible) {
- trace_intel_update_plane(&plane->base,
- to_intel_crtc(crtc));
-
- plane->update_plane(plane,
- to_intel_crtc_state(crtc->state),
- plane_state);
- }
- }
-}
-
static int
__intel_display_resume(struct drm_device *dev,
struct drm_atomic_state *state,
@@ -3499,6 +3679,21 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
struct drm_atomic_state *state;
int ret;
+
+ /* reset doesn't touch the display */
+ if (!i915.force_reset_modeset_test &&
+ !gpu_reset_clobbers_display(dev_priv))
+ return;
+
+ /* We have a modeset vs reset deadlock, defensively unbreak it. */
+ set_bit(I915_RESET_MODESET, &dev_priv->gpu_error.flags);
+ wake_up_all(&dev_priv->gpu_error.wait_queue);
+
+ if (atomic_read(&dev_priv->gpu_error.pending_fb_pin)) {
+ DRM_DEBUG_KMS("Modeset potentially stuck, unbreaking through wedging\n");
+ i915_gem_set_wedged(dev_priv);
+ }
+
/*
* Need mode_config.mutex so that we don't
* trample ongoing ->detect() and whatnot.
@@ -3512,12 +3707,6 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv)
drm_modeset_backoff(ctx);
}
-
- /* reset doesn't touch the display, but flips might get nuked anyway, */
- if (!i915.force_reset_modeset_test &&
- !gpu_reset_clobbers_display(dev_priv))
- return;
-
/*
* Disabling the crtcs gracefully seems nicer. Also the
* g33 docs say we should at least disable all the planes.
@@ -3547,33 +3736,22 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
struct drm_atomic_state *state = dev_priv->modeset_restore_state;
int ret;
- /*
- * Flips in the rings will be nuked by the reset,
- * so complete all pending flips so that user space
- * will get its events and not get stuck.
- */
- intel_complete_page_flips(dev_priv);
+ /* reset doesn't touch the display */
+ if (!i915.force_reset_modeset_test &&
+ !gpu_reset_clobbers_display(dev_priv))
+ return;
+
+ if (!state)
+ goto unlock;
dev_priv->modeset_restore_state = NULL;
/* reset doesn't touch the display */
if (!gpu_reset_clobbers_display(dev_priv)) {
- if (!state) {
- /*
- * Flips in the rings have been nuked by the reset,
- * so update the base address of all primary
- * planes to the the last fb to make sure we're
- * showing the correct fb after a reset.
- *
- * FIXME: Atomic will make this obsolete since we won't schedule
- * CS-based flips (which might get lost in gpu resets) any more.
- */
- intel_update_primary_planes(dev);
- } else {
- ret = __intel_display_resume(dev, state, ctx);
+ /* for testing only restore the display */
+ ret = __intel_display_resume(dev, state, ctx);
if (ret)
DRM_ERROR("Restoring old state failed with %i\n", ret);
- }
} else {
/*
* The display has been reset as well,
@@ -3597,40 +3775,13 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
intel_hpd_init(dev_priv);
}
- if (state)
- drm_atomic_state_put(state);
+ drm_atomic_state_put(state);
+unlock:
drm_modeset_drop_locks(ctx);
drm_modeset_acquire_fini(ctx);
mutex_unlock(&dev->mode_config.mutex);
-}
-static bool abort_flip_on_reset(struct intel_crtc *crtc)
-{
- struct i915_gpu_error *error = &to_i915(crtc->base.dev)->gpu_error;
-
- if (i915_reset_backoff(error))
- return true;
-
- if (crtc->reset_count != i915_reset_count(error))
- return true;
-
- return false;
-}
-
-static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- bool pending;
-
- if (abort_flip_on_reset(intel_crtc))
- return false;
-
- spin_lock_irq(&dev->event_lock);
- pending = to_intel_crtc(crtc)->flip_work != NULL;
- spin_unlock_irq(&dev->event_lock);
-
- return pending;
+ clear_bit(I915_RESET_MODESET, &dev_priv->gpu_error.flags);
}
static void intel_update_pipe_config(struct intel_crtc *crtc,
@@ -4187,21 +4338,22 @@ static void ironlake_fdi_disable(struct drm_crtc *crtc)
bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv)
{
- struct intel_crtc *crtc;
-
- /* Note that we don't need to be called with mode_config.lock here
- * as our list of CRTC objects is static for the lifetime of the
- * device and so cannot disappear as we iterate. Similarly, we can
- * happily treat the predicates as racy, atomic checks as userspace
- * cannot claim and pin a new fb without at least acquring the
- * struct_mutex and so serialising with us.
- */
- for_each_intel_crtc(&dev_priv->drm, crtc) {
- if (atomic_read(&crtc->unpin_work_count) == 0)
+ struct drm_crtc *crtc;
+ bool cleanup_done;
+
+ drm_for_each_crtc(crtc, &dev_priv->drm) {
+ struct drm_crtc_commit *commit;
+ spin_lock(&crtc->commit_lock);
+ commit = list_first_entry_or_null(&crtc->commit_list,
+ struct drm_crtc_commit, commit_entry);
+ cleanup_done = commit ?
+ try_wait_for_completion(&commit->cleanup_done) : true;
+ spin_unlock(&crtc->commit_lock);
+
+ if (cleanup_done)
continue;
- if (crtc->flip_work)
- intel_wait_for_vblank(dev_priv, crtc->pipe);
+ drm_crtc_wait_one_vblank(crtc);
return true;
}
@@ -4209,57 +4361,6 @@ bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv)
return false;
}
-static void page_flip_completed(struct intel_crtc *intel_crtc)
-{
- struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
- struct intel_flip_work *work = intel_crtc->flip_work;
-
- intel_crtc->flip_work = NULL;
-
- if (work->event)
- drm_crtc_send_vblank_event(&intel_crtc->base, work->event);
-
- drm_crtc_vblank_put(&intel_crtc->base);
-
- wake_up_all(&dev_priv->pending_flip_queue);
- trace_i915_flip_complete(intel_crtc->plane,
- work->pending_flip_obj);
-
- queue_work(dev_priv->wq, &work->unpin_work);
-}
-
-static int intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
- long ret;
-
- WARN_ON(waitqueue_active(&dev_priv->pending_flip_queue));
-
- ret = wait_event_interruptible_timeout(
- dev_priv->pending_flip_queue,
- !intel_crtc_has_pending_flip(crtc),
- 60*HZ);
-
- if (ret < 0)
- return ret;
-
- if (ret == 0) {
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_flip_work *work;
-
- spin_lock_irq(&dev->event_lock);
- work = intel_crtc->flip_work;
- if (work && !is_mmio_work(work)) {
- WARN_ONCE(1, "Removing stuck page flip\n");
- page_flip_completed(intel_crtc);
- }
- spin_unlock_irq(&dev->event_lock);
- }
-
- return 0;
-}
-
void lpt_disable_iclkip(struct drm_i915_private *dev_priv)
{
u32 temp;
@@ -4579,7 +4680,7 @@ static void lpt_pch_enable(const struct intel_crtc_state *crtc_state)
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
- assert_pch_transcoder_disabled(dev_priv, TRANSCODER_A);
+ assert_pch_transcoder_disabled(dev_priv, PIPE_A);
lpt_program_iclkip(crtc);
@@ -4612,6 +4713,9 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
&crtc_state->scaler_state;
struct intel_crtc *intel_crtc =
to_intel_crtc(crtc_state->base.crtc);
+ struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
+ const struct drm_display_mode *adjusted_mode =
+ &crtc_state->base.adjusted_mode;
int need_scaling;
/*
@@ -4621,6 +4725,21 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
*/
need_scaling = src_w != dst_w || src_h != dst_h;
+ if (crtc_state->ycbcr420 && scaler_user == SKL_CRTC_INDEX)
+ need_scaling = true;
+
+ /*
+ * Scaling/fitting not supported in IF-ID mode in GEN9+
+ * TODO: Interlace fetch mode doesn't support YUV420 planar formats.
+ * Once NV12 is enabled, handle it here while allocating scaler
+ * for NV12.
+ */
+ if (INTEL_GEN(dev_priv) >= 9 && crtc_state->base.enable &&
+ need_scaling && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+ DRM_DEBUG_KMS("Pipe/Plane scaling not supported with IF-ID mode\n");
+ return -EINVAL;
+ }
+
/*
* if plane is being disabled or scaler is no more required or force detach
* - free scaler binded to this plane/crtc
@@ -5332,8 +5451,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
return;
if (intel_crtc->config->has_pch_encoder)
- intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
- false);
+ intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
intel_encoders_pre_pll_enable(crtc, pipe_config, old_state);
@@ -5418,8 +5536,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
intel_wait_for_vblank(dev_priv, pipe);
intel_wait_for_vblank(dev_priv, pipe);
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
- intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
- true);
+ intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
}
/* If we change the relative order between pipe/planes enabling, we need
@@ -5516,8 +5633,7 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
if (intel_crtc->config->has_pch_encoder)
- intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
- false);
+ intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
intel_encoders_disable(crtc, old_crtc_state, old_state);
@@ -5545,8 +5661,7 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
intel_encoders_post_disable(crtc, old_crtc_state, old_state);
if (old_crtc_state->has_pch_encoder)
- intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
- true);
+ intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
}
static void i9xx_pfit_enable(struct intel_crtc *crtc)
@@ -5855,8 +5970,6 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc,
return;
if (crtc->primary->state->visible) {
- WARN_ON(intel_crtc->flip_work);
-
intel_pre_disable_primary_noatomic(crtc);
intel_crtc_disable_planes(crtc, 1 << drm_plane_index(crtc->primary));
@@ -6265,6 +6378,16 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
return -EINVAL;
}
+ if (pipe_config->ycbcr420 && pipe_config->base.ctm) {
+ /*
+ * There is only one pipe CSC unit per pipe, and we need that
+ * for output conversion from RGB->YCBCR. So if CTM is already
+ * applied we can't support YCBCR420 output.
+ */
+ DRM_DEBUG_KMS("YCBCR420 and CTM together are not possible\n");
+ return -EINVAL;
+ }
+
/*
* Pipe horizontal size must be even in:
* - DVO ganged mode
@@ -8058,6 +8181,7 @@ static void haswell_set_pipemisc(struct drm_crtc *crtc)
{
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_crtc_state *config = intel_crtc->config;
if (IS_BROADWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 9) {
u32 val = 0;
@@ -8083,6 +8207,12 @@ static void haswell_set_pipemisc(struct drm_crtc *crtc)
if (intel_crtc->config->dither)
val |= PIPEMISC_DITHER_ENABLE | PIPEMISC_DITHER_TYPE_SP;
+ if (config->ycbcr420) {
+ val |= PIPEMISC_OUTPUT_COLORSPACE_YUV |
+ PIPEMISC_YUV420_ENABLE |
+ PIPEMISC_YUV420_MODE_FULL_BLEND;
+ }
+
I915_WRITE(PIPEMISC(intel_crtc->pipe), val);
}
}
@@ -8410,10 +8540,16 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
fb->modifier = I915_FORMAT_MOD_X_TILED;
break;
case PLANE_CTL_TILED_Y:
- fb->modifier = I915_FORMAT_MOD_Y_TILED;
+ if (val & PLANE_CTL_DECOMPRESSION_ENABLE)
+ fb->modifier = I915_FORMAT_MOD_Y_TILED_CCS;
+ else
+ fb->modifier = I915_FORMAT_MOD_Y_TILED;
break;
case PLANE_CTL_TILED_YF:
- fb->modifier = I915_FORMAT_MOD_Yf_TILED;
+ if (val & PLANE_CTL_DECOMPRESSION_ENABLE)
+ fb->modifier = I915_FORMAT_MOD_Yf_TILED_CCS;
+ else
+ fb->modifier = I915_FORMAT_MOD_Yf_TILED;
break;
default:
MISSING_CASE(tiling);
@@ -8647,7 +8783,8 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
I915_STATE_WARN(crtc->active, "CRTC for pipe %c enabled\n",
pipe_name(crtc->pipe));
- I915_STATE_WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on\n");
+ I915_STATE_WARN(I915_READ(HSW_PWR_WELL_CTL_DRIVER(HSW_DISP_PW_GLOBAL)),
+ "Display power well on\n");
I915_STATE_WARN(I915_READ(SPLL_CTL) & SPLL_PLL_ENABLE, "SPLL enabled\n");
I915_STATE_WARN(I915_READ(WRPLL_CTL(0)) & WRPLL_PLL_ENABLE, "WRPLL1 enabled\n");
I915_STATE_WARN(I915_READ(WRPLL_CTL(1)) & WRPLL_PLL_ENABLE, "WRPLL2 enabled\n");
@@ -9117,6 +9254,8 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
u64 power_domain_mask;
bool active;
+ intel_crtc_init_scalers(crtc, pipe_config);
+
power_domain = POWER_DOMAIN_PIPE(crtc->pipe);
if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
return false;
@@ -9145,11 +9284,21 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
pipe_config->gamma_mode =
I915_READ(GAMMA_MODE(crtc->pipe)) & GAMMA_MODE_MODE_MASK;
- if (INTEL_GEN(dev_priv) >= 9) {
- intel_crtc_init_scalers(crtc, pipe_config);
+ if (IS_BROADWELL(dev_priv) || dev_priv->info.gen >= 9) {
+ u32 tmp = I915_READ(PIPEMISC(crtc->pipe));
+ bool clrspace_yuv = tmp & PIPEMISC_OUTPUT_COLORSPACE_YUV;
+
+ if (IS_GEMINILAKE(dev_priv) || dev_priv->info.gen >= 10) {
+ bool blend_mode_420 = tmp &
+ PIPEMISC_YUV420_MODE_FULL_BLEND;
- pipe_config->scaler_state.scaler_id = -1;
- pipe_config->scaler_state.scaler_users &= ~(1 << SKL_CRTC_INDEX);
+ pipe_config->ycbcr420 = tmp & PIPEMISC_YUV420_ENABLE;
+ if (pipe_config->ycbcr420 != clrspace_yuv ||
+ pipe_config->ycbcr420 != blend_mode_420)
+ DRM_DEBUG_KMS("Bad 4:2:0 mode (%08x)\n", tmp);
+ } else if (clrspace_yuv) {
+ DRM_DEBUG_KMS("YCbCr 4:2:0 Unsupported\n");
+ }
}
power_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe);
@@ -9540,7 +9689,16 @@ static void i9xx_update_cursor(struct intel_plane *plane,
* On some platforms writing CURCNTR first will also
* cause CURPOS to be armed by the CURBASE write.
* Without the CURCNTR write the CURPOS write would
- * arm itself.
+ * arm itself. Thus we always start the full update
+ * with a CURCNTR write.
+ *
+ * On other platforms CURPOS always requires the
+ * CURBASE write to arm the update. Additonally
+ * a write to any of the cursor register will cancel
+ * an already armed cursor update. Thus leaving out
+ * the CURBASE write after CURPOS could lead to a
+ * cursor that doesn't appear to move, or even change
+ * shape. Thus we always write CURBASE.
*
* CURCNTR and CUR_FBC_CTL are always
* armed by the CURBASE write only.
@@ -9559,6 +9717,7 @@ static void i9xx_update_cursor(struct intel_plane *plane,
plane->cursor.cntl = cntl;
} else {
I915_WRITE_FW(CURPOS(pipe), pos);
+ I915_WRITE_FW(CURBASE(pipe), base);
}
POSTING_READ_FW(CURBASE(pipe));
@@ -10119,849 +10278,11 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
static void intel_crtc_destroy(struct drm_crtc *crtc)
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct drm_device *dev = crtc->dev;
- struct intel_flip_work *work;
-
- spin_lock_irq(&dev->event_lock);
- work = intel_crtc->flip_work;
- intel_crtc->flip_work = NULL;
- spin_unlock_irq(&dev->event_lock);
-
- if (work) {
- cancel_work_sync(&work->mmio_work);
- cancel_work_sync(&work->unpin_work);
- kfree(work);
- }
drm_crtc_cleanup(crtc);
-
kfree(intel_crtc);
}
-static void intel_unpin_work_fn(struct work_struct *__work)
-{
- struct intel_flip_work *work =
- container_of(__work, struct intel_flip_work, unpin_work);
- struct intel_crtc *crtc = to_intel_crtc(work->crtc);
- struct drm_device *dev = crtc->base.dev;
- struct drm_plane *primary = crtc->base.primary;
-
- if (is_mmio_work(work))
- flush_work(&work->mmio_work);
-
- mutex_lock(&dev->struct_mutex);
- intel_unpin_fb_vma(work->old_vma);
- i915_gem_object_put(work->pending_flip_obj);
- mutex_unlock(&dev->struct_mutex);
-
- i915_gem_request_put(work->flip_queued_req);
-
- intel_frontbuffer_flip_complete(to_i915(dev),
- to_intel_plane(primary)->frontbuffer_bit);
- intel_fbc_post_update(crtc);
- drm_framebuffer_unreference(work->old_fb);
-
- BUG_ON(atomic_read(&crtc->unpin_work_count) == 0);
- atomic_dec(&crtc->unpin_work_count);
-
- kfree(work);
-}
-
-/* Is 'a' after or equal to 'b'? */
-static bool g4x_flip_count_after_eq(u32 a, u32 b)
-{
- return !((a - b) & 0x80000000);
-}
-
-static bool __pageflip_finished_cs(struct intel_crtc *crtc,
- struct intel_flip_work *work)
-{
- struct drm_device *dev = crtc->base.dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
-
- if (abort_flip_on_reset(crtc))
- return true;
-
- /*
- * The relevant registers doen't exist on pre-ctg.
- * As the flip done interrupt doesn't trigger for mmio
- * flips on gmch platforms, a flip count check isn't
- * really needed there. But since ctg has the registers,
- * include it in the check anyway.
- */
- if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv))
- return true;
-
- /*
- * BDW signals flip done immediately if the plane
- * is disabled, even if the plane enable is already
- * armed to occur at the next vblank :(
- */
-
- /*
- * A DSPSURFLIVE check isn't enough in case the mmio and CS flips
- * used the same base address. In that case the mmio flip might
- * have completed, but the CS hasn't even executed the flip yet.
- *
- * A flip count check isn't enough as the CS might have updated
- * the base address just after start of vblank, but before we
- * managed to process the interrupt. This means we'd complete the
- * CS flip too soon.
- *
- * Combining both checks should get us a good enough result. It may
- * still happen that the CS flip has been executed, but has not
- * yet actually completed. But in case the base address is the same
- * anyway, we don't really care.
- */
- return (I915_READ(DSPSURFLIVE(crtc->plane)) & ~0xfff) ==
- crtc->flip_work->gtt_offset &&
- g4x_flip_count_after_eq(I915_READ(PIPE_FLIPCOUNT_G4X(crtc->pipe)),
- crtc->flip_work->flip_count);
-}
-
-static bool
-__pageflip_finished_mmio(struct intel_crtc *crtc,
- struct intel_flip_work *work)
-{
- /*
- * MMIO work completes when vblank is different from
- * flip_queued_vblank.
- *
- * Reset counter value doesn't matter, this is handled by
- * i915_wait_request finishing early, so no need to handle
- * reset here.
- */
- return intel_crtc_get_vblank_counter(crtc) != work->flip_queued_vblank;
-}
-
-
-static bool pageflip_finished(struct intel_crtc *crtc,
- struct intel_flip_work *work)
-{
- if (!atomic_read(&work->pending))
- return false;
-
- smp_rmb();
-
- if (is_mmio_work(work))
- return __pageflip_finished_mmio(crtc, work);
- else
- return __pageflip_finished_cs(crtc, work);
-}
-
-void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe)
-{
- struct drm_device *dev = &dev_priv->drm;
- struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
- struct intel_flip_work *work;
- unsigned long flags;
-
- /* Ignore early vblank irqs */
- if (!crtc)
- return;
-
- /*
- * This is called both by irq handlers and the reset code (to complete
- * lost pageflips) so needs the full irqsave spinlocks.
- */
- spin_lock_irqsave(&dev->event_lock, flags);
- work = crtc->flip_work;
-
- if (work != NULL &&
- !is_mmio_work(work) &&
- pageflip_finished(crtc, work))
- page_flip_completed(crtc);
-
- spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
-void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe)
-{
- struct drm_device *dev = &dev_priv->drm;
- struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
- struct intel_flip_work *work;
- unsigned long flags;
-
- /* Ignore early vblank irqs */
- if (!crtc)
- return;
-
- /*
- * This is called both by irq handlers and the reset code (to complete
- * lost pageflips) so needs the full irqsave spinlocks.
- */
- spin_lock_irqsave(&dev->event_lock, flags);
- work = crtc->flip_work;
-
- if (work != NULL &&
- is_mmio_work(work) &&
- pageflip_finished(crtc, work))
- page_flip_completed(crtc);
-
- spin_unlock_irqrestore(&dev->event_lock, flags);
-}
-
-static inline void intel_mark_page_flip_active(struct intel_crtc *crtc,
- struct intel_flip_work *work)
-{
- work->flip_queued_vblank = intel_crtc_get_vblank_counter(crtc);
-
- /* Ensure that the work item is consistent when activating it ... */
- smp_mb__before_atomic();
- atomic_set(&work->pending, 1);
-}
-
-static int intel_gen2_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 flip_mask, *cs;
-
- cs = intel_ring_begin(req, 6);
- if (IS_ERR(cs))
- return PTR_ERR(cs);
-
- /* Can't queue multiple flips, so wait for the previous
- * one to finish before executing the next.
- */
- if (intel_crtc->plane)
- flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
- else
- flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
- *cs++ = MI_WAIT_FOR_EVENT | flip_mask;
- *cs++ = MI_NOOP;
- *cs++ = MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
- *cs++ = fb->pitches[0];
- *cs++ = intel_crtc->flip_work->gtt_offset;
- *cs++ = 0; /* aux display base address, unused */
-
- return 0;
-}
-
-static int intel_gen3_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 flip_mask, *cs;
-
- cs = intel_ring_begin(req, 6);
- if (IS_ERR(cs))
- return PTR_ERR(cs);
-
- if (intel_crtc->plane)
- flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
- else
- flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
- *cs++ = MI_WAIT_FOR_EVENT | flip_mask;
- *cs++ = MI_NOOP;
- *cs++ = MI_DISPLAY_FLIP_I915 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
- *cs++ = fb->pitches[0];
- *cs++ = intel_crtc->flip_work->gtt_offset;
- *cs++ = MI_NOOP;
-
- return 0;
-}
-
-static int intel_gen4_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 pf, pipesrc, *cs;
-
- cs = intel_ring_begin(req, 4);
- if (IS_ERR(cs))
- return PTR_ERR(cs);
-
- /* i965+ uses the linear or tiled offsets from the
- * Display Registers (which do not change across a page-flip)
- * so we need only reprogram the base address.
- */
- *cs++ = MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
- *cs++ = fb->pitches[0];
- *cs++ = intel_crtc->flip_work->gtt_offset |
- intel_fb_modifier_to_tiling(fb->modifier);
-
- /* XXX Enabling the panel-fitter across page-flip is so far
- * untested on non-native modes, so ignore it for now.
- * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE;
- */
- pf = 0;
- pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
- *cs++ = pf | pipesrc;
-
- return 0;
-}
-
-static int intel_gen6_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 pf, pipesrc, *cs;
-
- cs = intel_ring_begin(req, 4);
- if (IS_ERR(cs))
- return PTR_ERR(cs);
-
- *cs++ = MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane);
- *cs++ = fb->pitches[0] | intel_fb_modifier_to_tiling(fb->modifier);
- *cs++ = intel_crtc->flip_work->gtt_offset;
-
- /* Contrary to the suggestions in the documentation,
- * "Enable Panel Fitter" does not seem to be required when page
- * flipping with a non-native mode, and worse causes a normal
- * modeset to fail.
- * pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE;
- */
- pf = 0;
- pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
- *cs++ = pf | pipesrc;
-
- return 0;
-}
-
-static int intel_gen7_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- u32 *cs, plane_bit = 0;
- int len, ret;
-
- switch (intel_crtc->plane) {
- case PLANE_A:
- plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_A;
- break;
- case PLANE_B:
- plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_B;
- break;
- case PLANE_C:
- plane_bit = MI_DISPLAY_FLIP_IVB_PLANE_C;
- break;
- default:
- WARN_ONCE(1, "unknown plane in flip command\n");
- return -ENODEV;
- }
-
- len = 4;
- if (req->engine->id == RCS) {
- len += 6;
- /*
- * On Gen 8, SRM is now taking an extra dword to accommodate
- * 48bits addresses, and we need a NOOP for the batch size to
- * stay even.
- */
- if (IS_GEN8(dev_priv))
- len += 2;
- }
-
- /*
- * BSpec MI_DISPLAY_FLIP for IVB:
- * "The full packet must be contained within the same cache line."
- *
- * Currently the LRI+SRM+MI_DISPLAY_FLIP all fit within the same
- * cacheline, if we ever start emitting more commands before
- * the MI_DISPLAY_FLIP we may need to first emit everything else,
- * then do the cacheline alignment, and finally emit the
- * MI_DISPLAY_FLIP.
- */
- ret = intel_ring_cacheline_align(req);
- if (ret)
- return ret;
-
- cs = intel_ring_begin(req, len);
- if (IS_ERR(cs))
- return PTR_ERR(cs);
-
- /* Unmask the flip-done completion message. Note that the bspec says that
- * we should do this for both the BCS and RCS, and that we must not unmask
- * more than one flip event at any time (or ensure that one flip message
- * can be sent by waiting for flip-done prior to queueing new flips).
- * Experimentation says that BCS works despite DERRMR masking all
- * flip-done completion events and that unmasking all planes at once
- * for the RCS also doesn't appear to drop events. Setting the DERRMR
- * to zero does lead to lockups within MI_DISPLAY_FLIP.
- */
- if (req->engine->id == RCS) {
- *cs++ = MI_LOAD_REGISTER_IMM(1);
- *cs++ = i915_mmio_reg_offset(DERRMR);
- *cs++ = ~(DERRMR_PIPEA_PRI_FLIP_DONE |
- DERRMR_PIPEB_PRI_FLIP_DONE |
- DERRMR_PIPEC_PRI_FLIP_DONE);
- if (IS_GEN8(dev_priv))
- *cs++ = MI_STORE_REGISTER_MEM_GEN8 |
- MI_SRM_LRM_GLOBAL_GTT;
- else
- *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
- *cs++ = i915_mmio_reg_offset(DERRMR);
- *cs++ = i915_ggtt_offset(req->engine->scratch) + 256;
- if (IS_GEN8(dev_priv)) {
- *cs++ = 0;
- *cs++ = MI_NOOP;
- }
- }
-
- *cs++ = MI_DISPLAY_FLIP_I915 | plane_bit;
- *cs++ = fb->pitches[0] | intel_fb_modifier_to_tiling(fb->modifier);
- *cs++ = intel_crtc->flip_work->gtt_offset;
- *cs++ = MI_NOOP;
-
- return 0;
-}
-
-static bool use_mmio_flip(struct intel_engine_cs *engine,
- struct drm_i915_gem_object *obj)
-{
- /*
- * This is not being used for older platforms, because
- * non-availability of flip done interrupt forces us to use
- * CS flips. Older platforms derive flip done using some clever
- * tricks involving the flip_pending status bits and vblank irqs.
- * So using MMIO flips there would disrupt this mechanism.
- */
-
- if (engine == NULL)
- return true;
-
- if (INTEL_GEN(engine->i915) < 5)
- return false;
-
- if (i915.use_mmio_flip < 0)
- return false;
- else if (i915.use_mmio_flip > 0)
- return true;
- else if (i915.enable_execlists)
- return true;
-
- return engine != i915_gem_object_last_write_engine(obj);
-}
-
-static void skl_do_mmio_flip(struct intel_crtc *intel_crtc,
- unsigned int rotation,
- struct intel_flip_work *work)
-{
- struct drm_device *dev = intel_crtc->base.dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct drm_framebuffer *fb = intel_crtc->base.primary->fb;
- const enum pipe pipe = intel_crtc->pipe;
- u32 ctl, stride = skl_plane_stride(fb, 0, rotation);
-
- ctl = I915_READ(PLANE_CTL(pipe, 0));
- ctl &= ~PLANE_CTL_TILED_MASK;
- switch (fb->modifier) {
- case DRM_FORMAT_MOD_LINEAR:
- break;
- case I915_FORMAT_MOD_X_TILED:
- ctl |= PLANE_CTL_TILED_X;
- break;
- case I915_FORMAT_MOD_Y_TILED:
- ctl |= PLANE_CTL_TILED_Y;
- break;
- case I915_FORMAT_MOD_Yf_TILED:
- ctl |= PLANE_CTL_TILED_YF;
- break;
- default:
- MISSING_CASE(fb->modifier);
- }
-
- /*
- * Both PLANE_CTL and PLANE_STRIDE are not updated on vblank but on
- * PLANE_SURF updates, the update is then guaranteed to be atomic.
- */
- I915_WRITE(PLANE_CTL(pipe, 0), ctl);
- I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
-
- I915_WRITE(PLANE_SURF(pipe, 0), work->gtt_offset);
- POSTING_READ(PLANE_SURF(pipe, 0));
-}
-
-static void ilk_do_mmio_flip(struct intel_crtc *intel_crtc,
- struct intel_flip_work *work)
-{
- struct drm_device *dev = intel_crtc->base.dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct drm_framebuffer *fb = intel_crtc->base.primary->fb;
- i915_reg_t reg = DSPCNTR(intel_crtc->plane);
- u32 dspcntr;
-
- dspcntr = I915_READ(reg);
-
- if (fb->modifier == I915_FORMAT_MOD_X_TILED)
- dspcntr |= DISPPLANE_TILED;
- else
- dspcntr &= ~DISPPLANE_TILED;
-
- I915_WRITE(reg, dspcntr);
-
- I915_WRITE(DSPSURF(intel_crtc->plane), work->gtt_offset);
- POSTING_READ(DSPSURF(intel_crtc->plane));
-}
-
-static void intel_mmio_flip_work_func(struct work_struct *w)
-{
- struct intel_flip_work *work =
- container_of(w, struct intel_flip_work, mmio_work);
- struct intel_crtc *crtc = to_intel_crtc(work->crtc);
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- struct intel_framebuffer *intel_fb =
- to_intel_framebuffer(crtc->base.primary->fb);
- struct drm_i915_gem_object *obj = intel_fb->obj;
-
- WARN_ON(i915_gem_object_wait(obj, 0, MAX_SCHEDULE_TIMEOUT, NULL) < 0);
-
- intel_pipe_update_start(crtc);
-
- if (INTEL_GEN(dev_priv) >= 9)
- skl_do_mmio_flip(crtc, work->rotation, work);
- else
- /* use_mmio_flip() retricts MMIO flips to ilk+ */
- ilk_do_mmio_flip(crtc, work);
-
- intel_pipe_update_end(crtc, work);
-}
-
-static int intel_default_queue_flip(struct drm_device *dev,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_i915_gem_object *obj,
- struct drm_i915_gem_request *req,
- uint32_t flags)
-{
- return -ENODEV;
-}
-
-static bool __pageflip_stall_check_cs(struct drm_i915_private *dev_priv,
- struct intel_crtc *intel_crtc,
- struct intel_flip_work *work)
-{
- u32 addr, vblank;
-
- if (!atomic_read(&work->pending))
- return false;
-
- smp_rmb();
-
- vblank = intel_crtc_get_vblank_counter(intel_crtc);
- if (work->flip_ready_vblank == 0) {
- if (work->flip_queued_req &&
- !i915_gem_request_completed(work->flip_queued_req))
- return false;
-
- work->flip_ready_vblank = vblank;
- }
-
- if (vblank - work->flip_ready_vblank < 3)
- return false;
-
- /* Potential stall - if we see that the flip has happened,
- * assume a missed interrupt. */
- if (INTEL_GEN(dev_priv) >= 4)
- addr = I915_HI_DISPBASE(I915_READ(DSPSURF(intel_crtc->plane)));
- else
- addr = I915_READ(DSPADDR(intel_crtc->plane));
-
- /* There is a potential issue here with a false positive after a flip
- * to the same address. We could address this by checking for a
- * non-incrementing frame counter.
- */
- return addr == work->gtt_offset;
-}
-
-void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe)
-{
- struct drm_device *dev = &dev_priv->drm;
- struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
- struct intel_flip_work *work;
-
- WARN_ON(!in_interrupt());
-
- if (crtc == NULL)
- return;
-
- spin_lock(&dev->event_lock);
- work = crtc->flip_work;
-
- if (work != NULL && !is_mmio_work(work) &&
- __pageflip_stall_check_cs(dev_priv, crtc, work)) {
- WARN_ONCE(1,
- "Kicking stuck page flip: queued at %d, now %d\n",
- work->flip_queued_vblank, intel_crtc_get_vblank_counter(crtc));
- page_flip_completed(crtc);
- work = NULL;
- }
-
- if (work != NULL && !is_mmio_work(work) &&
- intel_crtc_get_vblank_counter(crtc) - work->flip_queued_vblank > 1)
- intel_queue_rps_boost_for_request(work->flip_queued_req);
- spin_unlock(&dev->event_lock);
-}
-
-__maybe_unused
-static int intel_crtc_page_flip(struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_pending_vblank_event *event,
- uint32_t page_flip_flags)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct drm_framebuffer *old_fb = crtc->primary->fb;
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct drm_plane *primary = crtc->primary;
- enum pipe pipe = intel_crtc->pipe;
- struct intel_flip_work *work;
- struct intel_engine_cs *engine;
- bool mmio_flip;
- struct drm_i915_gem_request *request;
- struct i915_vma *vma;
- int ret;
-
- /*
- * drm_mode_page_flip_ioctl() should already catch this, but double
- * check to be safe. In the future we may enable pageflipping from
- * a disabled primary plane.
- */
- if (WARN_ON(intel_fb_obj(old_fb) == NULL))
- return -EBUSY;
-
- /* Can't change pixel format via MI display flips. */
- if (fb->format != crtc->primary->fb->format)
- return -EINVAL;
-
- /*
- * TILEOFF/LINOFF registers can't be changed via MI display flips.
- * Note that pitch changes could also affect these register.
- */
- if (INTEL_GEN(dev_priv) > 3 &&
- (fb->offsets[0] != crtc->primary->fb->offsets[0] ||
- fb->pitches[0] != crtc->primary->fb->pitches[0]))
- return -EINVAL;
-
- if (i915_terminally_wedged(&dev_priv->gpu_error))
- goto out_hang;
-
- work = kzalloc(sizeof(*work), GFP_KERNEL);
- if (work == NULL)
- return -ENOMEM;
-
- work->event = event;
- work->crtc = crtc;
- work->old_fb = old_fb;
- INIT_WORK(&work->unpin_work, intel_unpin_work_fn);
-
- ret = drm_crtc_vblank_get(crtc);
- if (ret)
- goto free_work;
-
- /* We borrow the event spin lock for protecting flip_work */
- spin_lock_irq(&dev->event_lock);
- if (intel_crtc->flip_work) {
- /* Before declaring the flip queue wedged, check if
- * the hardware completed the operation behind our backs.
- */
- if (pageflip_finished(intel_crtc, intel_crtc->flip_work)) {
- DRM_DEBUG_DRIVER("flip queue: previous flip completed, continuing\n");
- page_flip_completed(intel_crtc);
- } else {
- DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
- spin_unlock_irq(&dev->event_lock);
-
- drm_crtc_vblank_put(crtc);
- kfree(work);
- return -EBUSY;
- }
- }
- intel_crtc->flip_work = work;
- spin_unlock_irq(&dev->event_lock);
-
- if (atomic_read(&intel_crtc->unpin_work_count) >= 2)
- flush_workqueue(dev_priv->wq);
-
- /* Reference the objects for the scheduled work. */
- drm_framebuffer_reference(work->old_fb);
-
- crtc->primary->fb = fb;
- update_state_fb(crtc->primary);
-
- work->pending_flip_obj = i915_gem_object_get(obj);
-
- ret = i915_mutex_lock_interruptible(dev);
- if (ret)
- goto cleanup;
-
- intel_crtc->reset_count = i915_reset_count(&dev_priv->gpu_error);
- if (i915_reset_backoff_or_wedged(&dev_priv->gpu_error)) {
- ret = -EIO;
- goto unlock;
- }
-
- atomic_inc(&intel_crtc->unpin_work_count);
-
- if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
- work->flip_count = I915_READ(PIPE_FLIPCOUNT_G4X(pipe)) + 1;
-
- if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
- engine = dev_priv->engine[BCS];
- if (fb->modifier != old_fb->modifier)
- /* vlv: DISPLAY_FLIP fails to change tiling */
- engine = NULL;
- } else if (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)) {
- engine = dev_priv->engine[BCS];
- } else if (INTEL_GEN(dev_priv) >= 7) {
- engine = i915_gem_object_last_write_engine(obj);
- if (engine == NULL || engine->id != RCS)
- engine = dev_priv->engine[BCS];
- } else {
- engine = dev_priv->engine[RCS];
- }
-
- mmio_flip = use_mmio_flip(engine, obj);
-
- vma = intel_pin_and_fence_fb_obj(fb, primary->state->rotation);
- if (IS_ERR(vma)) {
- ret = PTR_ERR(vma);
- goto cleanup_pending;
- }
-
- work->old_vma = to_intel_plane_state(primary->state)->vma;
- to_intel_plane_state(primary->state)->vma = vma;
-
- work->gtt_offset = i915_ggtt_offset(vma) + intel_crtc->dspaddr_offset;
- work->rotation = crtc->primary->state->rotation;
-
- /*
- * There's the potential that the next frame will not be compatible with
- * FBC, so we want to call pre_update() before the actual page flip.
- * The problem is that pre_update() caches some information about the fb
- * object, so we want to do this only after the object is pinned. Let's
- * be on the safe side and do this immediately before scheduling the
- * flip.
- */
- intel_fbc_pre_update(intel_crtc, intel_crtc->config,
- to_intel_plane_state(primary->state));
-
- if (mmio_flip) {
- INIT_WORK(&work->mmio_work, intel_mmio_flip_work_func);
- queue_work(system_unbound_wq, &work->mmio_work);
- } else {
- request = i915_gem_request_alloc(engine,
- dev_priv->kernel_context);
- if (IS_ERR(request)) {
- ret = PTR_ERR(request);
- goto cleanup_unpin;
- }
-
- ret = i915_gem_request_await_object(request, obj, false);
- if (ret)
- goto cleanup_request;
-
- ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, request,
- page_flip_flags);
- if (ret)
- goto cleanup_request;
-
- intel_mark_page_flip_active(intel_crtc, work);
-
- work->flip_queued_req = i915_gem_request_get(request);
- i915_add_request(request);
- }
-
- i915_gem_object_wait_priority(obj, 0, I915_PRIORITY_DISPLAY);
- i915_gem_track_fb(intel_fb_obj(old_fb), obj,
- to_intel_plane(primary)->frontbuffer_bit);
- mutex_unlock(&dev->struct_mutex);
-
- intel_frontbuffer_flip_prepare(to_i915(dev),
- to_intel_plane(primary)->frontbuffer_bit);
-
- trace_i915_flip_request(intel_crtc->plane, obj);
-
- return 0;
-
-cleanup_request:
- i915_add_request(request);
-cleanup_unpin:
- to_intel_plane_state(primary->state)->vma = work->old_vma;
- intel_unpin_fb_vma(vma);
-cleanup_pending:
- atomic_dec(&intel_crtc->unpin_work_count);
-unlock:
- mutex_unlock(&dev->struct_mutex);
-cleanup:
- crtc->primary->fb = old_fb;
- update_state_fb(crtc->primary);
-
- i915_gem_object_put(obj);
- drm_framebuffer_unreference(work->old_fb);
-
- spin_lock_irq(&dev->event_lock);
- intel_crtc->flip_work = NULL;
- spin_unlock_irq(&dev->event_lock);
-
- drm_crtc_vblank_put(crtc);
-free_work:
- kfree(work);
-
- if (ret == -EIO) {
- struct drm_atomic_state *state;
- struct drm_plane_state *plane_state;
-
-out_hang:
- state = drm_atomic_state_alloc(dev);
- if (!state)
- return -ENOMEM;
- state->acquire_ctx = dev->mode_config.acquire_ctx;
-
-retry:
- plane_state = drm_atomic_get_plane_state(state, primary);
- ret = PTR_ERR_OR_ZERO(plane_state);
- if (!ret) {
- drm_atomic_set_fb_for_plane(plane_state, fb);
-
- ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
- if (!ret)
- ret = drm_atomic_commit(state);
- }
-
- if (ret == -EDEADLK) {
- drm_modeset_backoff(state->acquire_ctx);
- drm_atomic_state_clear(state);
- goto retry;
- }
-
- drm_atomic_state_put(state);
-
- if (ret == 0 && event) {
- spin_lock_irq(&dev->event_lock);
- drm_crtc_send_vblank_event(crtc, event);
- spin_unlock_irq(&dev->event_lock);
- }
- }
- return ret;
-}
-
-
/**
* intel_wm_need_update - Check whether watermarks need updating
* @plane: drm plane
@@ -11359,6 +10680,9 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
pipe_config->fdi_lanes,
&pipe_config->fdi_m_n);
+ if (pipe_config->ycbcr420)
+ DRM_DEBUG_KMS("YCbCr 4:2:0 output enabled\n");
+
if (intel_crtc_has_dp_encoder(pipe_config)) {
intel_dump_m_n_config(pipe_config, "dp m_n",
pipe_config->lane_count, &pipe_config->dp_m_n);
@@ -11930,6 +11254,7 @@ intel_pipe_config_compare(struct drm_i915_private *dev_priv,
PIPE_CONF_CHECK_I(hdmi_scrambling);
PIPE_CONF_CHECK_I(hdmi_high_tmds_clock_ratio);
PIPE_CONF_CHECK_I(has_infoframe);
+ PIPE_CONF_CHECK_I(ycbcr420);
PIPE_CONF_CHECK_I(has_audio);
@@ -12771,31 +12096,7 @@ static int intel_atomic_check(struct drm_device *dev,
static int intel_atomic_prepare_commit(struct drm_device *dev,
struct drm_atomic_state *state)
{
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct drm_crtc_state *crtc_state;
- struct drm_crtc *crtc;
- int i, ret;
-
- for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
- if (state->legacy_cursor_update)
- continue;
-
- ret = intel_crtc_wait_for_pending_flips(crtc);
- if (ret)
- return ret;
-
- if (atomic_read(&to_intel_crtc(crtc)->unpin_work_count) >= 2)
- flush_workqueue(dev_priv->wq);
- }
-
- ret = mutex_lock_interruptible(&dev->struct_mutex);
- if (ret)
- return ret;
-
- ret = drm_atomic_helper_prepare_planes(dev, state);
- mutex_unlock(&dev->struct_mutex);
-
- return ret;
+ return drm_atomic_helper_prepare_planes(dev, state);
}
u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
@@ -12803,7 +12104,7 @@ u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
struct drm_device *dev = crtc->base.dev;
if (!dev->max_vblank_count)
- return drm_accurate_vblank_count(&crtc->base);
+ return drm_crtc_accurate_vblank_count(&crtc->base);
return dev->driver->get_vblank_counter(dev, crtc->pipe);
}
@@ -13006,6 +12307,30 @@ static void intel_atomic_helper_free_state_worker(struct work_struct *work)
intel_atomic_helper_free_state(dev_priv);
}
+static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_state)
+{
+ struct wait_queue_entry wait_fence, wait_reset;
+ struct drm_i915_private *dev_priv = to_i915(intel_state->base.dev);
+
+ init_wait_entry(&wait_fence, 0);
+ init_wait_entry(&wait_reset, 0);
+ for (;;) {
+ prepare_to_wait(&intel_state->commit_ready.wait,
+ &wait_fence, TASK_UNINTERRUPTIBLE);
+ prepare_to_wait(&dev_priv->gpu_error.wait_queue,
+ &wait_reset, TASK_UNINTERRUPTIBLE);
+
+
+ if (i915_sw_fence_done(&intel_state->commit_ready)
+ || test_bit(I915_RESET_MODESET, &dev_priv->gpu_error.flags))
+ break;
+
+ schedule();
+ }
+ finish_wait(&intel_state->commit_ready.wait, &wait_fence);
+ finish_wait(&dev_priv->gpu_error.wait_queue, &wait_reset);
+}
+
static void intel_atomic_commit_tail(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
@@ -13019,6 +12344,8 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
unsigned crtc_vblank_mask = 0;
int i;
+ intel_atomic_commit_fence_wait(intel_state);
+
drm_atomic_helper_wait_for_dependencies(state);
if (intel_state->modeset)
@@ -13158,9 +12485,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET);
}
- mutex_lock(&dev->struct_mutex);
drm_atomic_helper_cleanup_planes(dev, state);
- mutex_unlock(&dev->struct_mutex);
drm_atomic_helper_commit_cleanup_done(state);
@@ -13186,10 +12511,8 @@ intel_atomic_commit_ready(struct i915_sw_fence *fence,
switch (notify) {
case FENCE_COMPLETE:
- if (state->base.commit_work.func)
- queue_work(system_unbound_wq, &state->base.commit_work);
+ /* we do blocking waits in the worker, nothing to do here */
break;
-
case FENCE_FREE:
{
struct intel_atomic_helper *helper =
@@ -13271,7 +12594,13 @@ static int intel_atomic_commit(struct drm_device *dev,
if (INTEL_GEN(dev_priv) < 9)
state->legacy_cursor_update = false;
- drm_atomic_helper_swap_state(state, true);
+ ret = drm_atomic_helper_swap_state(state, true);
+ if (ret) {
+ i915_sw_fence_commit(&intel_state->commit_ready);
+
+ drm_atomic_helper_cleanup_planes(dev, state);
+ return ret;
+ }
dev_priv->wm.distrust_bios_wm = false;
intel_shared_dpll_swap_state(state);
intel_atomic_track_fbs(state);
@@ -13285,14 +12614,14 @@ static int intel_atomic_commit(struct drm_device *dev,
}
drm_atomic_state_get(state);
- INIT_WORK(&state->commit_work,
- nonblock ? intel_atomic_commit_work : NULL);
+ INIT_WORK(&state->commit_work, intel_atomic_commit_work);
i915_sw_fence_commit(&intel_state->commit_ready);
- if (!nonblock) {
- i915_sw_fence_wait(&intel_state->commit_ready);
+ if (nonblock)
+ queue_work(system_unbound_wq, &state->commit_work);
+ else
intel_atomic_commit_tail(state);
- }
+
return 0;
}
@@ -13300,7 +12629,6 @@ static int intel_atomic_commit(struct drm_device *dev,
static const struct drm_crtc_funcs intel_crtc_funcs = {
.gamma_set = drm_atomic_helper_legacy_gamma_set,
.set_config = drm_atomic_helper_set_config,
- .set_property = drm_atomic_helper_crtc_set_property,
.destroy = intel_crtc_destroy,
.page_flip = drm_atomic_helper_page_flip,
.atomic_duplicate_state = intel_crtc_duplicate_state,
@@ -13334,32 +12662,6 @@ intel_prepare_plane_fb(struct drm_plane *plane,
struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->state->fb);
int ret;
- if (obj) {
- if (plane->type == DRM_PLANE_TYPE_CURSOR &&
- INTEL_INFO(dev_priv)->cursor_needs_physical) {
- const int align = intel_cursor_alignment(dev_priv);
-
- ret = i915_gem_object_attach_phys(obj, align);
- if (ret) {
- DRM_DEBUG_KMS("failed to attach phys object\n");
- return ret;
- }
- } else {
- struct i915_vma *vma;
-
- vma = intel_pin_and_fence_fb_obj(fb, new_state->rotation);
- if (IS_ERR(vma)) {
- DRM_DEBUG_KMS("failed to pin object\n");
- return PTR_ERR(vma);
- }
-
- to_intel_plane_state(new_state)->vma = vma;
- }
- }
-
- if (!obj && !old_obj)
- return 0;
-
if (old_obj) {
struct drm_crtc_state *crtc_state =
drm_atomic_get_existing_crtc_state(new_state->state,
@@ -13398,6 +12700,38 @@ intel_prepare_plane_fb(struct drm_plane *plane,
if (!obj)
return 0;
+ ret = i915_gem_object_pin_pages(obj);
+ if (ret)
+ return ret;
+
+ ret = mutex_lock_interruptible(&dev_priv->drm.struct_mutex);
+ if (ret) {
+ i915_gem_object_unpin_pages(obj);
+ return ret;
+ }
+
+ if (plane->type == DRM_PLANE_TYPE_CURSOR &&
+ INTEL_INFO(dev_priv)->cursor_needs_physical) {
+ const int align = intel_cursor_alignment(dev_priv);
+
+ ret = i915_gem_object_attach_phys(obj, align);
+ } else {
+ struct i915_vma *vma;
+
+ vma = intel_pin_and_fence_fb_obj(fb, new_state->rotation);
+ if (!IS_ERR(vma))
+ to_intel_plane_state(new_state)->vma = vma;
+ else
+ ret = PTR_ERR(vma);
+ }
+
+ i915_gem_object_wait_priority(obj, 0, I915_PRIORITY_DISPLAY);
+
+ mutex_unlock(&dev_priv->drm.struct_mutex);
+ i915_gem_object_unpin_pages(obj);
+ if (ret)
+ return ret;
+
if (!new_state->fence) { /* implicit fencing */
ret = i915_sw_fence_await_reservation(&intel_state->commit_ready,
obj->resv, NULL,
@@ -13405,8 +12739,6 @@ intel_prepare_plane_fb(struct drm_plane *plane,
GFP_KERNEL);
if (ret < 0)
return ret;
-
- i915_gem_object_wait_priority(obj, 0, I915_PRIORITY_DISPLAY);
}
return 0;
@@ -13429,8 +12761,11 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
/* Should only be called after a successful intel_prepare_plane_fb()! */
vma = fetch_and_zero(&to_intel_plane_state(old_state)->vma);
- if (vma)
+ if (vma) {
+ mutex_lock(&plane->dev->struct_mutex);
intel_unpin_fb_vma(vma);
+ mutex_unlock(&plane->dev->struct_mutex);
+ }
}
int
@@ -13557,7 +12892,7 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc,
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- intel_pipe_update_end(intel_crtc, NULL);
+ intel_pipe_update_end(intel_crtc);
}
/**
@@ -13573,15 +12908,110 @@ void intel_plane_destroy(struct drm_plane *plane)
kfree(to_intel_plane(plane));
}
-const struct drm_plane_funcs intel_plane_funcs = {
+static bool i8xx_mod_supported(uint32_t format, uint64_t modifier)
+{
+ switch (format) {
+ case DRM_FORMAT_C8:
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_XRGB1555:
+ case DRM_FORMAT_XRGB8888:
+ return modifier == DRM_FORMAT_MOD_LINEAR ||
+ modifier == I915_FORMAT_MOD_X_TILED;
+ default:
+ return false;
+ }
+}
+
+static bool i965_mod_supported(uint32_t format, uint64_t modifier)
+{
+ switch (format) {
+ case DRM_FORMAT_C8:
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_XRGB2101010:
+ case DRM_FORMAT_XBGR2101010:
+ return modifier == DRM_FORMAT_MOD_LINEAR ||
+ modifier == I915_FORMAT_MOD_X_TILED;
+ default:
+ return false;
+ }
+}
+
+static bool skl_mod_supported(uint32_t format, uint64_t modifier)
+{
+ switch (format) {
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_ABGR8888:
+ if (modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
+ modifier == I915_FORMAT_MOD_Y_TILED_CCS)
+ return true;
+ /* fall through */
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_XRGB2101010:
+ case DRM_FORMAT_XBGR2101010:
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_YVYU:
+ case DRM_FORMAT_UYVY:
+ case DRM_FORMAT_VYUY:
+ if (modifier == I915_FORMAT_MOD_Yf_TILED)
+ return true;
+ /* fall through */
+ case DRM_FORMAT_C8:
+ if (modifier == DRM_FORMAT_MOD_LINEAR ||
+ modifier == I915_FORMAT_MOD_X_TILED ||
+ modifier == I915_FORMAT_MOD_Y_TILED)
+ return true;
+ /* fall through */
+ default:
+ return false;
+ }
+}
+
+static bool intel_primary_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+ struct drm_i915_private *dev_priv = to_i915(plane->dev);
+
+ if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID))
+ return false;
+
+ if ((modifier >> 56) != DRM_FORMAT_MOD_VENDOR_INTEL &&
+ modifier != DRM_FORMAT_MOD_LINEAR)
+ return false;
+
+ if (INTEL_GEN(dev_priv) >= 9)
+ return skl_mod_supported(format, modifier);
+ else if (INTEL_GEN(dev_priv) >= 4)
+ return i965_mod_supported(format, modifier);
+ else
+ return i8xx_mod_supported(format, modifier);
+
+ unreachable();
+}
+
+static bool intel_cursor_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+ if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID))
+ return false;
+
+ return modifier == DRM_FORMAT_MOD_LINEAR && format == DRM_FORMAT_ARGB8888;
+}
+
+static struct drm_plane_funcs intel_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = intel_plane_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
.atomic_get_property = intel_plane_atomic_get_property,
.atomic_set_property = intel_plane_atomic_set_property,
.atomic_duplicate_state = intel_plane_duplicate_state,
.atomic_destroy_state = intel_plane_destroy_state,
+ .format_mod_supported = intel_primary_plane_format_mod_supported,
};
static int
@@ -13600,7 +13030,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
struct intel_plane *intel_plane = to_intel_plane(plane);
struct drm_framebuffer *old_fb;
struct drm_crtc_state *crtc_state = crtc->state;
- struct i915_vma *old_vma;
+ struct i915_vma *old_vma, *vma;
/*
* When crtc is inactive or there is a modeset pending,
@@ -13658,8 +13088,6 @@ intel_legacy_cursor_update(struct drm_plane *plane,
goto out_unlock;
}
} else {
- struct i915_vma *vma;
-
vma = intel_pin_and_fence_fb_obj(fb, new_plane_state->rotation);
if (IS_ERR(vma)) {
DRM_DEBUG_KMS("failed to pin object\n");
@@ -13682,7 +13110,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
*to_intel_plane_state(old_plane_state) = *to_intel_plane_state(new_plane_state);
new_plane_state->fence = NULL;
new_plane_state->fb = old_fb;
- to_intel_plane_state(new_plane_state)->vma = old_vma;
+ to_intel_plane_state(new_plane_state)->vma = NULL;
if (plane->state->visible) {
trace_intel_update_plane(plane, to_intel_crtc(crtc));
@@ -13694,7 +13122,8 @@ intel_legacy_cursor_update(struct drm_plane *plane,
intel_plane->disable_plane(intel_plane, to_intel_crtc(crtc));
}
- intel_cleanup_plane_fb(plane, new_plane_state);
+ if (old_vma)
+ intel_unpin_fb_vma(old_vma);
out_unlock:
mutex_unlock(&dev_priv->drm.struct_mutex);
@@ -13712,11 +13141,11 @@ static const struct drm_plane_funcs intel_cursor_plane_funcs = {
.update_plane = intel_legacy_cursor_update,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = intel_plane_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
.atomic_get_property = intel_plane_atomic_get_property,
.atomic_set_property = intel_plane_atomic_set_property,
.atomic_duplicate_state = intel_plane_duplicate_state,
.atomic_destroy_state = intel_plane_destroy_state,
+ .format_mod_supported = intel_cursor_plane_format_mod_supported,
};
static struct intel_plane *
@@ -13727,6 +13156,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
const uint32_t *intel_primary_formats;
unsigned int supported_rotations;
unsigned int num_formats;
+ const uint64_t *modifiers;
int ret;
primary = kzalloc(sizeof(*primary), GFP_KERNEL);
@@ -13762,21 +13192,34 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
primary->frontbuffer_bit = INTEL_FRONTBUFFER_PRIMARY(pipe);
primary->check_plane = intel_check_primary_plane;
- if (INTEL_GEN(dev_priv) >= 9) {
+ if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
+ intel_primary_formats = skl_primary_formats;
+ num_formats = ARRAY_SIZE(skl_primary_formats);
+ modifiers = skl_format_modifiers_ccs;
+
+ primary->update_plane = skylake_update_primary_plane;
+ primary->disable_plane = skylake_disable_primary_plane;
+ } else if (INTEL_GEN(dev_priv) >= 9) {
intel_primary_formats = skl_primary_formats;
num_formats = ARRAY_SIZE(skl_primary_formats);
+ if (pipe < PIPE_C)
+ modifiers = skl_format_modifiers_ccs;
+ else
+ modifiers = skl_format_modifiers_noccs;
primary->update_plane = skylake_update_primary_plane;
primary->disable_plane = skylake_disable_primary_plane;
} else if (INTEL_GEN(dev_priv) >= 4) {
intel_primary_formats = i965_primary_formats;
num_formats = ARRAY_SIZE(i965_primary_formats);
+ modifiers = i9xx_format_modifiers;
primary->update_plane = i9xx_update_primary_plane;
primary->disable_plane = i9xx_disable_primary_plane;
} else {
intel_primary_formats = i8xx_primary_formats;
num_formats = ARRAY_SIZE(i8xx_primary_formats);
+ modifiers = i9xx_format_modifiers;
primary->update_plane = i9xx_update_primary_plane;
primary->disable_plane = i9xx_disable_primary_plane;
@@ -13786,18 +13229,21 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
ret = drm_universal_plane_init(&dev_priv->drm, &primary->base,
0, &intel_plane_funcs,
intel_primary_formats, num_formats,
+ modifiers,
DRM_PLANE_TYPE_PRIMARY,
"plane 1%c", pipe_name(pipe));
else if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
ret = drm_universal_plane_init(&dev_priv->drm, &primary->base,
0, &intel_plane_funcs,
intel_primary_formats, num_formats,
+ modifiers,
DRM_PLANE_TYPE_PRIMARY,
"primary %c", pipe_name(pipe));
else
ret = drm_universal_plane_init(&dev_priv->drm, &primary->base,
0, &intel_plane_funcs,
intel_primary_formats, num_formats,
+ modifiers,
DRM_PLANE_TYPE_PRIMARY,
"plane %c", plane_name(primary->plane));
if (ret)
@@ -13883,6 +13329,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
0, &intel_cursor_plane_funcs,
intel_cursor_formats,
ARRAY_SIZE(intel_cursor_formats),
+ cursor_format_modifiers,
DRM_PLANE_TYPE_CURSOR,
"cursor %c", pipe_name(pipe));
if (ret)
@@ -14405,10 +13852,12 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
struct drm_mode_fb_cmd2 *mode_cmd)
{
struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
+ struct drm_framebuffer *fb = &intel_fb->base;
struct drm_format_name_buf format_name;
- u32 pitch_limit, stride_alignment;
+ u32 pitch_limit;
unsigned int tiling, stride;
int ret = -EINVAL;
+ int i;
i915_gem_object_lock(obj);
obj->framebuffer_references++;
@@ -14437,6 +13886,19 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
/* Passed in modifier sanity checking. */
switch (mode_cmd->modifier[0]) {
+ case I915_FORMAT_MOD_Y_TILED_CCS:
+ case I915_FORMAT_MOD_Yf_TILED_CCS:
+ switch (mode_cmd->pixel_format) {
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_ARGB8888:
+ break;
+ default:
+ DRM_DEBUG_KMS("RC supported only with RGB8888 formats\n");
+ goto err;
+ }
+ /* fall through */
case I915_FORMAT_MOD_Y_TILED:
case I915_FORMAT_MOD_Yf_TILED:
if (INTEL_GEN(dev_priv) < 9) {
@@ -14541,25 +14003,46 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
if (mode_cmd->offsets[0] != 0)
goto err;
- drm_helper_mode_fill_fb_struct(&dev_priv->drm,
- &intel_fb->base, mode_cmd);
+ drm_helper_mode_fill_fb_struct(&dev_priv->drm, fb, mode_cmd);
- stride_alignment = intel_fb_stride_alignment(&intel_fb->base, 0);
- if (mode_cmd->pitches[0] & (stride_alignment - 1)) {
- DRM_DEBUG_KMS("pitch (%d) must be at least %u byte aligned\n",
- mode_cmd->pitches[0], stride_alignment);
- goto err;
+ for (i = 0; i < fb->format->num_planes; i++) {
+ u32 stride_alignment;
+
+ if (mode_cmd->handles[i] != mode_cmd->handles[0]) {
+ DRM_DEBUG_KMS("bad plane %d handle\n", i);
+ return -EINVAL;
+ }
+
+ stride_alignment = intel_fb_stride_alignment(fb, i);
+
+ /*
+ * Display WA #0531: skl,bxt,kbl,glk
+ *
+ * Render decompression and plane width > 3840
+ * combined with horizontal panning requires the
+ * plane stride to be a multiple of 4. We'll just
+ * require the entire fb to accommodate that to avoid
+ * potential runtime errors at plane configuration time.
+ */
+ if (IS_GEN9(dev_priv) && i == 0 && fb->width > 3840 &&
+ (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+ fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS))
+ stride_alignment *= 4;
+
+ if (fb->pitches[i] & (stride_alignment - 1)) {
+ DRM_DEBUG_KMS("plane %d pitch (%d) must be at least %u byte aligned\n",
+ i, fb->pitches[i], stride_alignment);
+ goto err;
+ }
}
intel_fb->obj = obj;
- ret = intel_fill_fb_info(dev_priv, &intel_fb->base);
+ ret = intel_fill_fb_info(dev_priv, fb);
if (ret)
goto err;
- ret = drm_framebuffer_init(obj->base.dev,
- &intel_fb->base,
- &intel_fb_funcs);
+ ret = drm_framebuffer_init(&dev_priv->drm, fb, &intel_fb_funcs);
if (ret) {
DRM_ERROR("framebuffer init failed %d\n", ret);
goto err;
@@ -14607,6 +14090,7 @@ static void intel_atomic_state_free(struct drm_atomic_state *state)
static const struct drm_mode_config_funcs intel_mode_funcs = {
.fb_create = intel_user_framebuffer_create,
+ .get_format_info = intel_get_format_info,
.output_poll_changed = intel_fbdev_output_poll_changed,
.atomic_check = intel_atomic_check,
.atomic_commit = intel_atomic_commit,
@@ -14706,34 +14190,6 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv)
dev_priv->display.update_crtcs = skl_update_crtcs;
else
dev_priv->display.update_crtcs = intel_update_crtcs;
-
- switch (INTEL_INFO(dev_priv)->gen) {
- case 2:
- dev_priv->display.queue_flip = intel_gen2_queue_flip;
- break;
-
- case 3:
- dev_priv->display.queue_flip = intel_gen3_queue_flip;
- break;
-
- case 4:
- case 5:
- dev_priv->display.queue_flip = intel_gen4_queue_flip;
- break;
-
- case 6:
- dev_priv->display.queue_flip = intel_gen6_queue_flip;
- break;
- case 7:
- case 8: /* FIXME(BDW): Check that the gen8 RCS flip works. */
- dev_priv->display.queue_flip = intel_gen7_queue_flip;
- break;
- case 9:
- /* Drop through - unsupported since execlist only. */
- default:
- /* Default just returns -ENODEV to indicate unsupported */
- dev_priv->display.queue_flip = intel_default_queue_flip;
- }
}
/*
@@ -14765,6 +14221,17 @@ static void quirk_backlight_present(struct drm_device *dev)
DRM_INFO("applying backlight present quirk\n");
}
+/* Toshiba Satellite P50-C-18C requires T12 delay to be min 800ms
+ * which is 300 ms greater than eDP spec T12 min.
+ */
+static void quirk_increase_t12_delay(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = to_i915(dev);
+
+ dev_priv->quirks |= QUIRK_INCREASE_T12_DELAY;
+ DRM_INFO("Applying T12 delay quirk\n");
+}
+
struct intel_quirk {
int device;
int subsystem_vendor;
@@ -14848,6 +14315,9 @@ static struct intel_quirk intel_quirks[] = {
/* Dell Chromebook 11 (2015 version) */
{ 0x0a16, 0x1028, 0x0a35, quirk_backlight_present },
+
+ /* Toshiba Satellite P50-C-18C */
+ { 0x191B, 0x1179, 0xF840, quirk_increase_t12_delay },
};
static void intel_init_quirks(struct drm_device *dev)
@@ -15650,7 +15120,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
vlv_wm_get_hw_state(dev);
vlv_wm_sanitize(dev_priv);
- } else if (IS_GEN9(dev_priv)) {
+ } else if (INTEL_GEN(dev_priv) >= 9) {
skl_wm_get_hw_state(dev);
} else if (HAS_PCH_SPLIT(dev_priv)) {
ilk_wm_get_hw_state(dev);
@@ -15757,6 +15227,9 @@ void intel_modeset_cleanup(struct drm_device *dev)
*/
drm_kms_helper_poll_fini(dev);
+ /* poll work can call into fbdev, hence clean that up afterwards */
+ intel_fbdev_fini(dev_priv);
+
intel_unregister_dsm_handler();
intel_fbc_global_disable(dev_priv);
@@ -15876,7 +15349,8 @@ intel_display_capture_error_state(struct drm_i915_private *dev_priv)
return NULL;
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
- error->power_well_driver = I915_READ(HSW_PWR_WELL_DRIVER);
+ error->power_well_driver =
+ I915_READ(HSW_PWR_WELL_CTL_DRIVER(HSW_DISP_PW_GLOBAL));
for_each_pipe(dev_priv, i) {
error->pipe[i].power_domain_on =
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 64fa774c855b..4fd4853b2250 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -97,6 +97,9 @@ static const int bxt_rates[] = { 162000, 216000, 243000, 270000,
324000, 432000, 540000 };
static const int skl_rates[] = { 162000, 216000, 270000,
324000, 432000, 540000 };
+static const int cnl_rates[] = { 162000, 216000, 270000,
+ 324000, 432000, 540000,
+ 648000, 810000 };
static const int default_rates[] = { 162000, 270000, 540000 };
/**
@@ -229,8 +232,10 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp)
{
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
+ enum port port = dig_port->port;
const int *source_rates;
int size;
+ u32 voltage;
/* This should only be done once */
WARN_ON(intel_dp->source_rates || intel_dp->num_source_rates);
@@ -238,6 +243,13 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp)
if (IS_GEN9_LP(dev_priv)) {
source_rates = bxt_rates;
size = ARRAY_SIZE(bxt_rates);
+ } else if (IS_CANNONLAKE(dev_priv)) {
+ source_rates = cnl_rates;
+ size = ARRAY_SIZE(cnl_rates);
+ voltage = I915_READ(CNL_PORT_COMP_DW3) & VOLTAGE_INFO_MASK;
+ if (port == PORT_A || port == PORT_D ||
+ voltage == VOLTAGE_INFO_0_85V)
+ size -= 2;
} else if (IS_GEN9_BC(dev_priv)) {
source_rates = skl_rates;
size = ARRAY_SIZE(skl_rates);
@@ -322,19 +334,20 @@ static int intel_dp_common_len_rate_limit(struct intel_dp *intel_dp,
return 0;
}
-static bool intel_dp_link_params_valid(struct intel_dp *intel_dp)
+static bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate,
+ uint8_t lane_count)
{
/*
* FIXME: we need to synchronize the current link parameters with
* hardware readout. Currently fast link training doesn't work on
* boot-up.
*/
- if (intel_dp->link_rate == 0 ||
- intel_dp->link_rate > intel_dp->max_link_rate)
+ if (link_rate == 0 ||
+ link_rate > intel_dp->max_link_rate)
return false;
- if (intel_dp->lane_count == 0 ||
- intel_dp->lane_count > intel_dp_max_lane_count(intel_dp))
+ if (lane_count == 0 ||
+ lane_count > intel_dp_max_lane_count(intel_dp))
return false;
return true;
@@ -1606,6 +1619,23 @@ static int intel_dp_compute_bpp(struct intel_dp *intel_dp,
return bpp;
}
+static bool intel_edp_compare_alt_mode(struct drm_display_mode *m1,
+ struct drm_display_mode *m2)
+{
+ bool bres = false;
+
+ if (m1 && m2)
+ bres = (m1->hdisplay == m2->hdisplay &&
+ m1->hsync_start == m2->hsync_start &&
+ m1->hsync_end == m2->hsync_end &&
+ m1->htotal == m2->htotal &&
+ m1->vdisplay == m2->vdisplay &&
+ m1->vsync_start == m2->vsync_start &&
+ m1->vsync_end == m2->vsync_end &&
+ m1->vtotal == m2->vtotal);
+ return bres;
+}
+
bool
intel_dp_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config,
@@ -1652,8 +1682,16 @@ intel_dp_compute_config(struct intel_encoder *encoder,
pipe_config->has_audio = intel_conn_state->force_audio == HDMI_AUDIO_ON;
if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
- intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
- adjusted_mode);
+ struct drm_display_mode *panel_mode =
+ intel_connector->panel.alt_fixed_mode;
+ struct drm_display_mode *req_mode = &pipe_config->base.mode;
+
+ if (!intel_edp_compare_alt_mode(req_mode, panel_mode))
+ panel_mode = intel_connector->panel.fixed_mode;
+
+ drm_mode_debug_printmodeline(panel_mode);
+
+ intel_fixed_panel_mode(panel_mode, adjusted_mode);
if (INTEL_GEN(dev_priv) >= 9) {
int ret;
@@ -1677,12 +1715,18 @@ intel_dp_compute_config(struct intel_encoder *encoder,
if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) {
int index;
- index = intel_dp_rate_index(intel_dp->common_rates,
- intel_dp->num_common_rates,
- intel_dp->compliance.test_link_rate);
- if (index >= 0)
- min_clock = max_clock = index;
- min_lane_count = max_lane_count = intel_dp->compliance.test_lane_count;
+ /* Validate the compliance test data since max values
+ * might have changed due to link train fallback.
+ */
+ if (intel_dp_link_params_valid(intel_dp, intel_dp->compliance.test_link_rate,
+ intel_dp->compliance.test_lane_count)) {
+ index = intel_dp_rate_index(intel_dp->common_rates,
+ intel_dp->num_common_rates,
+ intel_dp->compliance.test_link_rate);
+ if (index >= 0)
+ min_clock = max_clock = index;
+ min_lane_count = max_lane_count = intel_dp->compliance.test_lane_count;
+ }
}
DRM_DEBUG_KMS("DP link computation with max lane count %i "
"max bw %d pixel clock %iKHz\n",
@@ -3963,8 +4007,7 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
static uint8_t intel_dp_autotest_link_training(struct intel_dp *intel_dp)
{
int status = 0;
- int min_lane_count = 1;
- int link_rate_index, test_link_rate;
+ int test_link_rate;
uint8_t test_lane_count, test_link_bw;
/* (DP CTS 1.2)
* 4.3.1.11
@@ -3978,10 +4021,6 @@ static uint8_t intel_dp_autotest_link_training(struct intel_dp *intel_dp)
return DP_TEST_NAK;
}
test_lane_count &= DP_MAX_LANE_COUNT_MASK;
- /* Validate the requested lane count */
- if (test_lane_count < min_lane_count ||
- test_lane_count > intel_dp->max_link_lane_count)
- return DP_TEST_NAK;
status = drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_LINK_RATE,
&test_link_bw);
@@ -3989,12 +4028,11 @@ static uint8_t intel_dp_autotest_link_training(struct intel_dp *intel_dp)
DRM_DEBUG_KMS("Link Rate read failed\n");
return DP_TEST_NAK;
}
- /* Validate the requested link rate */
test_link_rate = drm_dp_bw_code_to_link_rate(test_link_bw);
- link_rate_index = intel_dp_rate_index(intel_dp->common_rates,
- intel_dp->num_common_rates,
- test_link_rate);
- if (link_rate_index < 0)
+
+ /* Validate the requested link rate and lane count */
+ if (!intel_dp_link_params_valid(intel_dp, test_link_rate,
+ test_lane_count))
return DP_TEST_NAK;
intel_dp->compliance.test_lane_count = test_lane_count;
@@ -4263,7 +4301,8 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
* Validate the cached values of intel_dp->link_rate and
* intel_dp->lane_count before attempting to retrain.
*/
- if (!intel_dp_link_params_valid(intel_dp))
+ if (!intel_dp_link_params_valid(intel_dp, intel_dp->link_rate,
+ intel_dp->lane_count))
return;
/* Retrain if Channel EQ or CR not ok */
@@ -4418,8 +4457,6 @@ static bool ibx_digital_port_connected(struct drm_i915_private *dev_priv,
u32 bit;
switch (port->port) {
- case PORT_A:
- return true;
case PORT_B:
bit = SDE_PORTB_HOTPLUG;
break;
@@ -4443,8 +4480,6 @@ static bool cpt_digital_port_connected(struct drm_i915_private *dev_priv,
u32 bit;
switch (port->port) {
- case PORT_A:
- return true;
case PORT_B:
bit = SDE_PORTB_HOTPLUG_CPT;
break;
@@ -4454,12 +4489,28 @@ static bool cpt_digital_port_connected(struct drm_i915_private *dev_priv,
case PORT_D:
bit = SDE_PORTD_HOTPLUG_CPT;
break;
+ default:
+ MISSING_CASE(port->port);
+ return false;
+ }
+
+ return I915_READ(SDEISR) & bit;
+}
+
+static bool spt_digital_port_connected(struct drm_i915_private *dev_priv,
+ struct intel_digital_port *port)
+{
+ u32 bit;
+
+ switch (port->port) {
+ case PORT_A:
+ bit = SDE_PORTA_HOTPLUG_SPT;
+ break;
case PORT_E:
bit = SDE_PORTE_HOTPLUG_SPT;
break;
default:
- MISSING_CASE(port->port);
- return false;
+ return cpt_digital_port_connected(dev_priv, port);
}
return I915_READ(SDEISR) & bit;
@@ -4511,6 +4562,42 @@ static bool gm45_digital_port_connected(struct drm_i915_private *dev_priv,
return I915_READ(PORT_HOTPLUG_STAT) & bit;
}
+static bool ilk_digital_port_connected(struct drm_i915_private *dev_priv,
+ struct intel_digital_port *port)
+{
+ if (port->port == PORT_A)
+ return I915_READ(DEISR) & DE_DP_A_HOTPLUG;
+ else
+ return ibx_digital_port_connected(dev_priv, port);
+}
+
+static bool snb_digital_port_connected(struct drm_i915_private *dev_priv,
+ struct intel_digital_port *port)
+{
+ if (port->port == PORT_A)
+ return I915_READ(DEISR) & DE_DP_A_HOTPLUG;
+ else
+ return cpt_digital_port_connected(dev_priv, port);
+}
+
+static bool ivb_digital_port_connected(struct drm_i915_private *dev_priv,
+ struct intel_digital_port *port)
+{
+ if (port->port == PORT_A)
+ return I915_READ(DEISR) & DE_DP_A_HOTPLUG_IVB;
+ else
+ return cpt_digital_port_connected(dev_priv, port);
+}
+
+static bool bdw_digital_port_connected(struct drm_i915_private *dev_priv,
+ struct intel_digital_port *port)
+{
+ if (port->port == PORT_A)
+ return I915_READ(GEN8_DE_PORT_ISR) & GEN8_PORT_DP_A_HOTPLUG;
+ else
+ return cpt_digital_port_connected(dev_priv, port);
+}
+
static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
struct intel_digital_port *intel_dig_port)
{
@@ -4518,7 +4605,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
enum port port;
u32 bit;
- intel_hpd_pin_to_port(intel_encoder->hpd_pin, &port);
+ port = intel_hpd_pin_to_port(intel_encoder->hpd_pin);
switch (port) {
case PORT_A:
bit = BXT_DE_PORT_HP_DDIA;
@@ -4547,16 +4634,25 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
struct intel_digital_port *port)
{
- if (HAS_PCH_IBX(dev_priv))
- return ibx_digital_port_connected(dev_priv, port);
- else if (HAS_PCH_SPLIT(dev_priv))
- return cpt_digital_port_connected(dev_priv, port);
+ if (HAS_GMCH_DISPLAY(dev_priv)) {
+ if (IS_GM45(dev_priv))
+ return gm45_digital_port_connected(dev_priv, port);
+ else
+ return g4x_digital_port_connected(dev_priv, port);
+ }
+
+ if (IS_GEN5(dev_priv))
+ return ilk_digital_port_connected(dev_priv, port);
+ else if (IS_GEN6(dev_priv))
+ return snb_digital_port_connected(dev_priv, port);
+ else if (IS_GEN7(dev_priv))
+ return ivb_digital_port_connected(dev_priv, port);
+ else if (IS_GEN8(dev_priv))
+ return bdw_digital_port_connected(dev_priv, port);
else if (IS_GEN9_LP(dev_priv))
return bxt_digital_port_connected(dev_priv, port);
- else if (IS_GM45(dev_priv))
- return gm45_digital_port_connected(dev_priv, port);
else
- return g4x_digital_port_connected(dev_priv, port);
+ return spt_digital_port_connected(dev_priv, port);
}
static struct edid *
@@ -4950,10 +5046,8 @@ void intel_dp_encoder_reset(struct drm_encoder *encoder)
}
static const struct drm_connector_funcs intel_dp_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.force = intel_dp_force,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.atomic_get_property = intel_digital_connector_atomic_get_property,
.atomic_set_property = intel_digital_connector_atomic_set_property,
.late_register = intel_dp_connector_register,
@@ -5121,12 +5215,8 @@ intel_pps_readout_hw_state(struct drm_i915_private *dev_priv,
PANEL_POWER_DOWN_DELAY_SHIFT;
if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv)) {
- u16 tmp = (pp_ctl & BXT_POWER_CYCLE_DELAY_MASK) >>
- BXT_POWER_CYCLE_DELAY_SHIFT;
- if (tmp > 0)
- seq->t11_t12 = (tmp - 1) * 1000;
- else
- seq->t11_t12 = 0;
+ seq->t11_t12 = ((pp_ctl & BXT_POWER_CYCLE_DELAY_MASK) >>
+ BXT_POWER_CYCLE_DELAY_SHIFT) * 1000;
} else {
seq->t11_t12 = ((pp_div & PANEL_POWER_CYCLE_DELAY_MASK) >>
PANEL_POWER_CYCLE_DELAY_SHIFT) * 1000;
@@ -5177,6 +5267,21 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
intel_pps_dump_state("cur", &cur);
vbt = dev_priv->vbt.edp.pps;
+ /* On Toshiba Satellite P50-C-18C system the VBT T12 delay
+ * of 500ms appears to be too short. Ocassionally the panel
+ * just fails to power back on. Increasing the delay to 800ms
+ * seems sufficient to avoid this problem.
+ */
+ if (dev_priv->quirks & QUIRK_INCREASE_T12_DELAY) {
+ vbt.t11_t12 = max_t(u16, vbt.t11_t12, 800 * 10);
+ DRM_DEBUG_KMS("Increasing T12 panel delay as per the quirk to %d\n",
+ vbt.t11_t12);
+ }
+ /* T11_T12 delay is special and actually in units of 100ms, but zero
+ * based in the hw (so we need to add 100 ms). But the sw vbt
+ * table multiplies it with 1000 to make it in units of 100usec,
+ * too. */
+ vbt.t11_t12 += 100 * 10;
/* Upper limits from eDP 1.3 spec. Note that we use the clunky units of
* our hw here, which are all in 100usec. */
@@ -5280,7 +5385,7 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv)) {
pp_div = I915_READ(regs.pp_ctrl);
pp_div &= ~BXT_POWER_CYCLE_DELAY_MASK;
- pp_div |= (DIV_ROUND_UP((seq->t11_t12 + 1), 1000)
+ pp_div |= (DIV_ROUND_UP(seq->t11_t12, 1000)
<< BXT_POWER_CYCLE_DELAY_SHIFT);
} else {
pp_div = ((100 * div)/2 - 1) << PP_REFERENCE_DIVIDER_SHIFT;
@@ -5714,6 +5819,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_display_mode *fixed_mode = NULL;
+ struct drm_display_mode *alt_fixed_mode = NULL;
struct drm_display_mode *downclock_mode = NULL;
bool has_dpcd;
struct drm_display_mode *scan;
@@ -5769,13 +5875,14 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
}
intel_connector->edid = edid;
- /* prefer fixed mode from EDID if available */
+ /* prefer fixed mode from EDID if available, save an alt mode also */
list_for_each_entry(scan, &connector->probed_modes, head) {
if ((scan->type & DRM_MODE_TYPE_PREFERRED)) {
fixed_mode = drm_mode_duplicate(dev, scan);
downclock_mode = intel_dp_drrs_init(
intel_connector, fixed_mode);
- break;
+ } else if (!alt_fixed_mode) {
+ alt_fixed_mode = drm_mode_duplicate(dev, scan);
}
}
@@ -5812,7 +5919,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
pipe_name(pipe));
}
- intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
+ intel_panel_init(&intel_connector->panel, fixed_mode, alt_fixed_mode,
+ downclock_mode);
intel_connector->panel.backlight.power = intel_edp_backlight_power;
intel_panel_setup_backlight(connector, pipe);
@@ -5838,26 +5946,22 @@ intel_dp_init_connector_port_info(struct intel_digital_port *intel_dig_port)
struct intel_encoder *encoder = &intel_dig_port->base;
struct intel_dp *intel_dp = &intel_dig_port->dp;
+ encoder->hpd_pin = intel_hpd_pin(intel_dig_port->port);
+
switch (intel_dig_port->port) {
case PORT_A:
- encoder->hpd_pin = HPD_PORT_A;
intel_dp->aux_power_domain = POWER_DOMAIN_AUX_A;
break;
case PORT_B:
- encoder->hpd_pin = HPD_PORT_B;
intel_dp->aux_power_domain = POWER_DOMAIN_AUX_B;
break;
case PORT_C:
- encoder->hpd_pin = HPD_PORT_C;
intel_dp->aux_power_domain = POWER_DOMAIN_AUX_C;
break;
case PORT_D:
- encoder->hpd_pin = HPD_PORT_D;
intel_dp->aux_power_domain = POWER_DOMAIN_AUX_D;
break;
case PORT_E:
- encoder->hpd_pin = HPD_PORT_E;
-
/* FIXME: Check VBT for actual wiring of PORT E */
intel_dp->aux_power_domain = POWER_DOMAIN_AUX_D;
break;
diff --git a/drivers/gpu/drm/i915/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/intel_dp_aux_backlight.c
index 228ca06d9f0b..d2830ba3162e 100644
--- a/drivers/gpu/drm/i915/intel_dp_aux_backlight.c
+++ b/drivers/gpu/drm/i915/intel_dp_aux_backlight.c
@@ -98,13 +98,87 @@ intel_dp_aux_set_backlight(const struct drm_connector_state *conn_state, u32 lev
}
}
+/*
+ * Set PWM Frequency divider to match desired frequency in vbt.
+ * The PWM Frequency is calculated as 27Mhz / (F x P).
+ * - Where F = PWM Frequency Pre-Divider value programmed by field 7:0 of the
+ * EDP_BACKLIGHT_FREQ_SET register (DPCD Address 00728h)
+ * - Where P = 2^Pn, where Pn is the value programmed by field 4:0 of the
+ * EDP_PWMGEN_BIT_COUNT register (DPCD Address 00724h)
+ */
+static bool intel_dp_aux_set_pwm_freq(struct intel_connector *connector)
+{
+ struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base);
+ int freq, fxp, fxp_min, fxp_max, fxp_actual, f = 1;
+ u8 pn, pn_min, pn_max;
+
+ /* Find desired value of (F x P)
+ * Note that, if F x P is out of supported range, the maximum value or
+ * minimum value will applied automatically. So no need to check that.
+ */
+ freq = dev_priv->vbt.backlight.pwm_freq_hz;
+ DRM_DEBUG_KMS("VBT defined backlight frequency %u Hz\n", freq);
+ if (!freq) {
+ DRM_DEBUG_KMS("Use panel default backlight frequency\n");
+ return false;
+ }
+
+ fxp = DIV_ROUND_CLOSEST(KHz(DP_EDP_BACKLIGHT_FREQ_BASE_KHZ), freq);
+
+ /* Use highest possible value of Pn for more granularity of brightness
+ * adjustment while satifying the conditions below.
+ * - Pn is in the range of Pn_min and Pn_max
+ * - F is in the range of 1 and 255
+ * - FxP is within 25% of desired value.
+ * Note: 25% is arbitrary value and may need some tweak.
+ */
+ if (drm_dp_dpcd_readb(&intel_dp->aux,
+ DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, &pn_min) != 1) {
+ DRM_DEBUG_KMS("Failed to read pwmgen bit count cap min\n");
+ return false;
+ }
+ if (drm_dp_dpcd_readb(&intel_dp->aux,
+ DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, &pn_max) != 1) {
+ DRM_DEBUG_KMS("Failed to read pwmgen bit count cap max\n");
+ return false;
+ }
+ pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
+ pn_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
+
+ fxp_min = DIV_ROUND_CLOSEST(fxp * 3, 4);
+ fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4);
+ if (fxp_min < (1 << pn_min) || (255 << pn_max) < fxp_max) {
+ DRM_DEBUG_KMS("VBT defined backlight frequency out of range\n");
+ return false;
+ }
+
+ for (pn = pn_max; pn >= pn_min; pn--) {
+ f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255);
+ fxp_actual = f << pn;
+ if (fxp_min <= fxp_actual && fxp_actual <= fxp_max)
+ break;
+ }
+
+ if (drm_dp_dpcd_writeb(&intel_dp->aux,
+ DP_EDP_PWMGEN_BIT_COUNT, pn) < 0) {
+ DRM_DEBUG_KMS("Failed to write aux pwmgen bit count\n");
+ return false;
+ }
+ if (drm_dp_dpcd_writeb(&intel_dp->aux,
+ DP_EDP_BACKLIGHT_FREQ_SET, (u8) f) < 0) {
+ DRM_DEBUG_KMS("Failed to write aux backlight freq\n");
+ return false;
+ }
+ return true;
+}
+
static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct intel_connector *connector = to_intel_connector(conn_state->connector);
struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base);
- uint8_t dpcd_buf = 0;
- uint8_t edp_backlight_mode = 0;
+ uint8_t dpcd_buf, new_dpcd_buf, edp_backlight_mode;
if (drm_dp_dpcd_readb(&intel_dp->aux,
DP_EDP_BACKLIGHT_MODE_SET_REGISTER, &dpcd_buf) != 1) {
@@ -113,18 +187,15 @@ static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_st
return;
}
+ new_dpcd_buf = dpcd_buf;
edp_backlight_mode = dpcd_buf & DP_EDP_BACKLIGHT_CONTROL_MODE_MASK;
switch (edp_backlight_mode) {
case DP_EDP_BACKLIGHT_CONTROL_MODE_PWM:
case DP_EDP_BACKLIGHT_CONTROL_MODE_PRESET:
case DP_EDP_BACKLIGHT_CONTROL_MODE_PRODUCT:
- dpcd_buf &= ~DP_EDP_BACKLIGHT_CONTROL_MODE_MASK;
- dpcd_buf |= DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD;
- if (drm_dp_dpcd_writeb(&intel_dp->aux,
- DP_EDP_BACKLIGHT_MODE_SET_REGISTER, dpcd_buf) < 0) {
- DRM_DEBUG_KMS("Failed to write aux backlight mode\n");
- }
+ new_dpcd_buf &= ~DP_EDP_BACKLIGHT_CONTROL_MODE_MASK;
+ new_dpcd_buf |= DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD;
break;
/* Do nothing when it is already DPCD mode */
@@ -133,6 +204,17 @@ static void intel_dp_aux_enable_backlight(const struct intel_crtc_state *crtc_st
break;
}
+ if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_FREQ_AUX_SET_CAP)
+ if (intel_dp_aux_set_pwm_freq(connector))
+ new_dpcd_buf |= DP_EDP_BACKLIGHT_FREQ_AUX_SET_ENABLE;
+
+ if (new_dpcd_buf != dpcd_buf) {
+ if (drm_dp_dpcd_writeb(&intel_dp->aux,
+ DP_EDP_BACKLIGHT_MODE_SET_REGISTER, new_dpcd_buf) < 0) {
+ DRM_DEBUG_KMS("Failed to write aux backlight mode\n");
+ }
+ }
+
set_aux_backlight_enable(intel_dp, true);
intel_dp_aux_set_backlight(conn_state, connector->panel.backlight.level);
}
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index b79c1c0e404c..05907fa8a553 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -321,12 +321,16 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
if (!intel_dp_link_training_channel_equalization(intel_dp))
goto failure_handling;
- DRM_DEBUG_KMS("Link Training Passed at Link Rate = %d, Lane count = %d",
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Link Training Passed at Link Rate = %d, Lane count = %d",
+ intel_connector->base.base.id,
+ intel_connector->base.name,
intel_dp->link_rate, intel_dp->lane_count);
return;
failure_handling:
- DRM_DEBUG_KMS("Link Training failed at link rate = %d, lane count = %d",
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d",
+ intel_connector->base.base.id,
+ intel_connector->base.name,
intel_dp->link_rate, intel_dp->lane_count);
if (!intel_dp_get_link_train_fallback_values(intel_dp,
intel_dp->link_rate,
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 2cf046beae0f..93fc8ab9bb31 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -346,10 +346,8 @@ intel_dp_mst_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs intel_dp_mst_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = intel_dp_mst_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.late_register = intel_connector_register,
.early_unregister = intel_connector_unregister,
.destroy = intel_dp_mst_connector_destroy,
@@ -372,6 +370,9 @@ intel_dp_mst_mode_valid(struct drm_connector *connector,
int bpp = 24; /* MST uses fixed bpp */
int max_rate, mode_rate, max_lanes, max_link_clock;
+ if (!intel_dp)
+ return MODE_ERROR;
+
max_link_clock = intel_dp_max_link_rate(intel_dp);
max_lanes = intel_dp_max_lane_count(intel_dp);
@@ -443,28 +444,6 @@ static bool intel_dp_mst_get_hw_state(struct intel_connector *connector)
return false;
}
-static void intel_connector_add_to_fbdev(struct intel_connector *connector)
-{
-#ifdef CONFIG_DRM_FBDEV_EMULATION
- struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-
- if (dev_priv->fbdev)
- drm_fb_helper_add_one_connector(&dev_priv->fbdev->helper,
- &connector->base);
-#endif
-}
-
-static void intel_connector_remove_from_fbdev(struct intel_connector *connector)
-{
-#ifdef CONFIG_DRM_FBDEV_EMULATION
- struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
-
- if (dev_priv->fbdev)
- drm_fb_helper_remove_one_connector(&dev_priv->fbdev->helper,
- &connector->base);
-#endif
-}
-
static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *pathprop)
{
struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr);
@@ -500,31 +479,32 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
static void intel_dp_register_mst_connector(struct drm_connector *connector)
{
- struct intel_connector *intel_connector = to_intel_connector(connector);
- struct drm_device *dev = connector->dev;
+ struct drm_i915_private *dev_priv = to_i915(connector->dev);
- drm_modeset_lock_all(dev);
- intel_connector_add_to_fbdev(intel_connector);
- drm_modeset_unlock_all(dev);
+ if (dev_priv->fbdev)
+ drm_fb_helper_add_one_connector(&dev_priv->fbdev->helper,
+ connector);
- drm_connector_register(&intel_connector->base);
+ drm_connector_register(connector);
}
static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
struct drm_connector *connector)
{
struct intel_connector *intel_connector = to_intel_connector(connector);
- struct drm_device *dev = connector->dev;
+ struct drm_i915_private *dev_priv = to_i915(connector->dev);
drm_connector_unregister(connector);
- /* need to nuke the connector */
- drm_modeset_lock_all(dev);
- intel_connector_remove_from_fbdev(intel_connector);
+ if (dev_priv->fbdev)
+ drm_fb_helper_remove_one_connector(&dev_priv->fbdev->helper,
+ connector);
+ /* prevent race with the check in ->detect */
+ drm_modeset_lock(&connector->dev->mode_config.connection_mutex, NULL);
intel_connector->mst_port = NULL;
- drm_modeset_unlock_all(dev);
+ drm_modeset_unlock(&connector->dev->mode_config.connection_mutex);
- drm_connector_unreference(&intel_connector->base);
+ drm_connector_unreference(connector);
DRM_DEBUG_KMS("\n");
}
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 2f7b0e64f628..a2a3d93d67bd 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -2379,6 +2379,15 @@ cnl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
return pll;
}
+static void cnl_dump_hw_state(struct drm_i915_private *dev_priv,
+ struct intel_dpll_hw_state *hw_state)
+{
+ DRM_DEBUG_KMS("dpll_hw_state: "
+ "cfgcr0: 0x%x, cfgcr1: 0x%x\n",
+ hw_state->cfgcr0,
+ hw_state->cfgcr1);
+}
+
static const struct intel_shared_dpll_funcs cnl_ddi_pll_funcs = {
.enable = cnl_ddi_pll_enable,
.disable = cnl_ddi_pll_disable,
@@ -2395,7 +2404,7 @@ static const struct dpll_info cnl_plls[] = {
static const struct intel_dpll_mgr cnl_pll_mgr = {
.dpll_info = cnl_plls,
.get_dpll = cnl_get_dpll,
- .dump_hw_state = skl_dump_hw_state,
+ .dump_hw_state = cnl_dump_hw_state,
};
/**
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d93efb49a2e2..fa47285918f4 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -265,6 +265,7 @@ struct intel_encoder {
struct intel_panel {
struct drm_display_mode *fixed_mode;
+ struct drm_display_mode *alt_fixed_mode;
struct drm_display_mode *downclock_mode;
/* backlight */
@@ -780,13 +781,15 @@ struct intel_crtc_state {
/* HDMI High TMDS char rate ratio */
bool hdmi_high_tmds_clock_ratio;
+
+ /* output format is YCBCR 4:2:0 */
+ bool ycbcr420;
};
struct intel_crtc {
struct drm_crtc base;
enum pipe pipe;
enum plane plane;
- u8 lut_r[256], lut_g[256], lut_b[256];
/*
* Whether the crtc and the connected output pipeline is active. Implies
* that crtc->enabled is set, i.e. the current mode configuration has
@@ -797,9 +800,6 @@ struct intel_crtc {
u8 plane_ids_mask;
unsigned long long enabled_power_domains;
struct intel_overlay *overlay;
- struct intel_flip_work *flip_work;
-
- atomic_t unpin_work_count;
/* Display surface base address adjustement for pageflips. Note that on
* gen4+ this only adjusts up to a tile, offsets within a tile are
@@ -1132,24 +1132,6 @@ intel_get_crtc_for_plane(struct drm_i915_private *dev_priv, enum plane plane)
return dev_priv->plane_to_crtc_mapping[plane];
}
-struct intel_flip_work {
- struct work_struct unpin_work;
- struct work_struct mmio_work;
-
- struct drm_crtc *crtc;
- struct i915_vma *old_vma;
- struct drm_framebuffer *old_fb;
- struct drm_i915_gem_object *pending_flip_obj;
- struct drm_pending_vblank_event *event;
- atomic_t pending;
- u32 flip_count;
- u32 gtt_offset;
- struct drm_i915_gem_request *flip_queued_req;
- u32 flip_queued_vblank;
- u32 flip_ready_vblank;
- unsigned int rotation;
-};
-
struct intel_load_detect_pipe {
struct drm_atomic_state *restore_state;
};
@@ -1211,12 +1193,12 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
enum pipe pipe, bool enable);
bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
- enum transcoder pch_transcoder,
+ enum pipe pch_transcoder,
bool enable);
void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
enum pipe pipe);
void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
- enum transcoder pch_transcoder);
+ enum pipe pch_transcoder);
void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv);
void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv);
@@ -1251,9 +1233,9 @@ static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv)
int intel_get_crtc_scanline(struct intel_crtc *crtc);
void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
- unsigned int pipe_mask);
+ u8 pipe_mask);
void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv,
- unsigned int pipe_mask);
+ u8 pipe_mask);
void gen9_reset_guc_interrupts(struct drm_i915_private *dev_priv);
void gen9_enable_guc_interrupts(struct drm_i915_private *dev_priv);
void gen9_disable_guc_interrupts(struct drm_i915_private *dev_priv);
@@ -1326,7 +1308,7 @@ void intel_set_cdclk(struct drm_i915_private *dev_priv,
/* intel_display.c */
void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe);
void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe);
-enum transcoder intel_crtc_pch_transcoder(struct intel_crtc *crtc);
+enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc);
void intel_update_rawclk(struct drm_i915_private *dev_priv);
int vlv_get_hpll_vco(struct drm_i915_private *dev_priv);
int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
@@ -1335,7 +1317,6 @@ int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
const char *name, u32 reg);
void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv);
void lpt_disable_iclkip(struct drm_i915_private *dev_priv);
-extern const struct drm_plane_funcs intel_plane_funcs;
void intel_init_display_hooks(struct drm_i915_private *dev_priv);
unsigned int intel_fb_xy_to_linear(int x, int y,
const struct intel_plane_state *state,
@@ -1408,9 +1389,6 @@ void intel_unpin_fb_vma(struct i915_vma *vma);
struct drm_framebuffer *
intel_framebuffer_create(struct drm_i915_gem_object *obj,
struct drm_mode_fb_cmd2 *mode_cmd);
-void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe);
-void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe);
-void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe);
int intel_prepare_plane_fb(struct drm_plane *plane,
struct drm_plane_state *new_state);
void intel_cleanup_plane_fb(struct drm_plane *plane,
@@ -1597,7 +1575,8 @@ void intel_hpd_poll_init(struct drm_i915_private *dev_priv);
#ifdef CONFIG_DRM_FBDEV_EMULATION
extern int intel_fbdev_init(struct drm_device *dev);
extern void intel_fbdev_initial_config_async(struct drm_device *dev);
-extern void intel_fbdev_fini(struct drm_device *dev);
+extern void intel_fbdev_unregister(struct drm_i915_private *dev_priv);
+extern void intel_fbdev_fini(struct drm_i915_private *dev_priv);
extern void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous);
extern void intel_fbdev_output_poll_changed(struct drm_device *dev);
extern void intel_fbdev_restore_mode(struct drm_device *dev);
@@ -1611,7 +1590,11 @@ static inline void intel_fbdev_initial_config_async(struct drm_device *dev)
{
}
-static inline void intel_fbdev_fini(struct drm_device *dev)
+static inline void intel_fbdev_unregister(struct drm_i915_private *dev_priv)
+{
+}
+
+static inline void intel_fbdev_fini(struct drm_i915_private *dev_priv)
{
}
@@ -1696,6 +1679,7 @@ void intel_overlay_reset(struct drm_i915_private *dev_priv);
/* intel_panel.c */
int intel_panel_init(struct intel_panel *panel,
struct drm_display_mode *fixed_mode,
+ struct drm_display_mode *alt_fixed_mode,
struct drm_display_mode *downclock_mode);
void intel_panel_fini(struct intel_panel *panel);
void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
@@ -1858,9 +1842,8 @@ void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv);
void gen6_rps_busy(struct drm_i915_private *dev_priv);
void gen6_rps_reset_ei(struct drm_i915_private *dev_priv);
void gen6_rps_idle(struct drm_i915_private *dev_priv);
-void gen6_rps_boost(struct drm_i915_private *dev_priv,
- struct intel_rps_client *rps,
- unsigned long submitted);
+void gen6_rps_boost(struct drm_i915_gem_request *rq,
+ struct intel_rps_client *rps);
void intel_queue_rps_boost_for_request(struct drm_i915_gem_request *req);
void g4x_wm_get_hw_state(struct drm_device *dev);
void vlv_wm_get_hw_state(struct drm_device *dev);
@@ -1902,7 +1885,7 @@ struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv,
int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv);
void intel_pipe_update_start(struct intel_crtc *crtc);
-void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work);
+void intel_pipe_update_end(struct intel_crtc *crtc);
/* intel_tv.c */
void intel_tv_init(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 50ec836da8b1..f0c11aec5ea5 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -1653,12 +1653,10 @@ static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs
};
static const struct drm_connector_funcs intel_dsi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.late_register = intel_connector_register,
.early_unregister = intel_connector_unregister,
.destroy = intel_dsi_connector_destroy,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.atomic_get_property = intel_digital_connector_atomic_get_property,
.atomic_set_property = intel_digital_connector_atomic_set_property,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
@@ -1851,7 +1849,7 @@ void intel_dsi_init(struct drm_i915_private *dev_priv)
connector->display_info.width_mm = fixed_mode->width_mm;
connector->display_info.height_mm = fixed_mode->height_mm;
- intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
+ intel_panel_init(&intel_connector->panel, fixed_mode, NULL, NULL);
intel_panel_setup_backlight(connector, INVALID_PIPE);
intel_dsi_add_properties(intel_connector);
diff --git a/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c b/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c
index 6e09ceb71500..150a156f3b1e 100644
--- a/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c
+++ b/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c
@@ -46,7 +46,7 @@ static u32 dcs_get_backlight(struct intel_connector *connector)
struct intel_encoder *encoder = connector->encoder;
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
struct mipi_dsi_device *dsi_device;
- u8 data;
+ u8 data = 0;
enum port port;
/* FIXME: Need to take care of 16 bit brightness level */
diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c
index 7158c7ce9c09..91c07b0c8db9 100644
--- a/drivers/gpu/drm/i915/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c
@@ -306,7 +306,7 @@ static void bxt_exec_gpio(struct drm_i915_private *dev_priv,
if (!gpio_desc) {
gpio_desc = devm_gpiod_get_index(dev_priv->drm.dev,
- "panel", gpio_index,
+ NULL, gpio_index,
value ? GPIOD_OUT_LOW :
GPIOD_OUT_HIGH);
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index c1544a53095d..c0a027274c06 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -344,13 +344,11 @@ static void intel_dvo_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs intel_dvo_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = intel_dvo_detect,
.late_register = intel_connector_register,
.early_unregister = intel_connector_unregister,
.destroy = intel_dvo_destroy,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
};
@@ -554,7 +552,7 @@ void intel_dvo_init(struct drm_i915_private *dev_priv)
*/
intel_panel_init(&intel_connector->panel,
intel_dvo_get_current_mode(connector),
- NULL);
+ NULL, NULL);
intel_dvo->panel_wants_dither = true;
}
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index 5b4de719bec3..9ab596941372 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -149,6 +149,7 @@ __intel_engine_context_size(struct drm_i915_private *dev_priv, u8 class)
switch (INTEL_GEN(dev_priv)) {
default:
MISSING_CASE(INTEL_GEN(dev_priv));
+ case 10:
case 9:
return GEN9_LR_CONTEXT_RENDER_SIZE;
case 8:
@@ -291,11 +292,9 @@ cleanup:
*/
int intel_engines_init(struct drm_i915_private *dev_priv)
{
- struct intel_device_info *device_info = mkwrite_device_info(dev_priv);
struct intel_engine_cs *engine;
enum intel_engine_id id, err_id;
- unsigned int mask = 0;
- int err = 0;
+ int err;
for_each_engine(engine, dev_priv, id) {
const struct engine_class_info *class_info =
@@ -306,40 +305,30 @@ int intel_engines_init(struct drm_i915_private *dev_priv)
init = class_info->init_execlists;
else
init = class_info->init_legacy;
- if (!init) {
- kfree(engine);
- dev_priv->engine[id] = NULL;
- continue;
- }
+
+ err = -EINVAL;
+ err_id = id;
+
+ if (GEM_WARN_ON(!init))
+ goto cleanup;
err = init(engine);
- if (err) {
- err_id = id;
+ if (err)
goto cleanup;
- }
GEM_BUG_ON(!engine->submit_request);
- mask |= ENGINE_MASK(id);
}
- /*
- * Catch failures to update intel_engines table when the new engines
- * are added to the driver by a warning and disabling the forgotten
- * engines.
- */
- if (WARN_ON(mask != INTEL_INFO(dev_priv)->ring_mask))
- device_info->ring_mask = mask;
-
- device_info->num_rings = hweight32(mask);
-
return 0;
cleanup:
for_each_engine(engine, dev_priv, id) {
- if (id >= err_id)
+ if (id >= err_id) {
kfree(engine);
- else
+ dev_priv->engine[id] = NULL;
+ } else {
dev_priv->gt.cleanup_engine(engine);
+ }
}
return err;
}
@@ -348,9 +337,6 @@ void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno)
{
struct drm_i915_private *dev_priv = engine->i915;
- GEM_BUG_ON(!intel_engine_is_idle(engine));
- GEM_BUG_ON(i915_gem_active_isset(&engine->timeline->last_request));
-
/* Our semaphore implementation is strictly monotonic (i.e. we proceed
* so long as the semaphore value in the register/page is greater
* than the sync value), so whenever we reset the seqno,
@@ -1294,6 +1280,10 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine)
if (port_request(&engine->execlist_port[0]))
return false;
+ /* ELSP is empty, but there are ready requests? */
+ if (READ_ONCE(engine->execlist_first))
+ return false;
+
/* Ring stopped? */
if (!ring_is_idle(engine))
return false;
@@ -1340,6 +1330,7 @@ void intel_engines_mark_idle(struct drm_i915_private *i915)
for_each_engine(engine, i915, id) {
intel_engine_disarm_breadcrumbs(engine);
i915_gem_batch_pool_fini(&engine->batch_pool);
+ tasklet_kill(&engine->irq_tasklet);
engine->no_priolist = false;
}
}
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 860b8c26d29b..3fca9fa39a8e 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -461,6 +461,8 @@ static void intel_fbc_schedule_activation(struct intel_crtc *crtc)
struct intel_fbc_work *work = &fbc->work;
WARN_ON(!mutex_is_locked(&fbc->lock));
+ if (WARN_ON(!fbc->enabled))
+ return;
if (drm_crtc_vblank_get(&crtc->base)) {
DRM_ERROR("vblank not available for FBC on pipe %c\n",
@@ -1216,7 +1218,7 @@ static void intel_fbc_underrun_work_fn(struct work_struct *work)
mutex_lock(&fbc->lock);
/* Maybe we were scheduled twice. */
- if (fbc->underrun_detected)
+ if (fbc->underrun_detected || !fbc->enabled)
goto out;
DRM_DEBUG_KMS("Disabling FBC due to FIFO underrun.\n");
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
index 0c4cde6b2e6f..262e75c00dd2 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -232,7 +232,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
strcpy(info->fix.id, "inteldrmfb");
- info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &intelfb_ops;
/* setup aperture base/size for vesafb takeover */
@@ -281,27 +280,6 @@ out_unlock:
return ret;
}
-/** Sets the color ramps on behalf of RandR */
-static void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
- intel_crtc->lut_r[regno] = red >> 8;
- intel_crtc->lut_g[regno] = green >> 8;
- intel_crtc->lut_b[regno] = blue >> 8;
-}
-
-static void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno)
-{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
- *red = intel_crtc->lut_r[regno] << 8;
- *green = intel_crtc->lut_g[regno] << 8;
- *blue = intel_crtc->lut_b[regno] << 8;
-}
-
static struct drm_fb_helper_crtc *
intel_fb_helper_crtc(struct drm_fb_helper *fb_helper, struct drm_crtc *crtc)
{
@@ -352,14 +330,20 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
unsigned int count = min(fb_helper->connector_count, BITS_PER_LONG);
int i, j;
bool *save_enabled;
- bool fallback = true;
+ bool fallback = true, ret = true;
int num_connectors_enabled = 0;
int num_connectors_detected = 0;
+ struct drm_modeset_acquire_ctx ctx;
save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL);
if (!save_enabled)
return false;
+ drm_modeset_acquire_init(&ctx, 0);
+
+ while (drm_modeset_lock_all_ctx(fb_helper->dev, &ctx) != 0)
+ drm_modeset_backoff(&ctx);
+
memcpy(save_enabled, enabled, count);
mask = GENMASK(count - 1, 0);
conn_configured = 0;
@@ -370,7 +354,6 @@ retry:
struct drm_connector *connector;
struct drm_encoder *encoder;
struct drm_fb_helper_crtc *new_crtc;
- struct intel_crtc *intel_crtc;
fb_conn = fb_helper->connector_info[i];
connector = fb_conn->connector;
@@ -412,13 +395,6 @@ retry:
num_connectors_enabled++;
- intel_crtc = to_intel_crtc(connector->state->crtc);
- for (j = 0; j < 256; j++) {
- intel_crtc->lut_r[j] = j;
- intel_crtc->lut_g[j] = j;
- intel_crtc->lut_b[j] = j;
- }
-
new_crtc = intel_fb_helper_crtc(fb_helper,
connector->state->crtc);
@@ -509,18 +485,18 @@ retry:
bail:
DRM_DEBUG_KMS("Not using firmware configuration\n");
memcpy(enabled, save_enabled, count);
- kfree(save_enabled);
- return false;
+ ret = false;
}
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+
kfree(save_enabled);
- return true;
+ return ret;
}
static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
.initial_config = intel_fb_initial_config,
- .gamma_set = intel_crtc_fb_gamma_set,
- .gamma_get = intel_crtc_fb_gamma_get,
.fb_probe = intelfb_create,
};
@@ -531,8 +507,6 @@ static void intel_fbdev_destroy(struct intel_fbdev *ifbdev)
* trying to rectify all the possible error paths leading here.
*/
- drm_fb_helper_unregister_fbi(&ifbdev->helper);
-
drm_fb_helper_fini(&ifbdev->helper);
if (ifbdev->vma) {
@@ -720,8 +694,10 @@ static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
/* Due to peculiar init order wrt to hpd handling this is separate. */
if (drm_fb_helper_initial_config(&ifbdev->helper,
- ifbdev->preferred_bpp))
- intel_fbdev_fini(ifbdev->helper.dev);
+ ifbdev->preferred_bpp)) {
+ intel_fbdev_unregister(to_i915(ifbdev->helper.dev));
+ intel_fbdev_fini(to_i915(ifbdev->helper.dev));
+ }
}
void intel_fbdev_initial_config_async(struct drm_device *dev)
@@ -744,9 +720,8 @@ static void intel_fbdev_sync(struct intel_fbdev *ifbdev)
ifbdev->cookie = 0;
}
-void intel_fbdev_fini(struct drm_device *dev)
+void intel_fbdev_unregister(struct drm_i915_private *dev_priv)
{
- struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_fbdev *ifbdev = dev_priv->fbdev;
if (!ifbdev)
@@ -756,8 +731,17 @@ void intel_fbdev_fini(struct drm_device *dev)
if (!current_is_async())
intel_fbdev_sync(ifbdev);
+ drm_fb_helper_unregister_fbi(&ifbdev->helper);
+}
+
+void intel_fbdev_fini(struct drm_i915_private *dev_priv)
+{
+ struct intel_fbdev *ifbdev = fetch_and_zero(&dev_priv->fbdev);
+
+ if (!ifbdev)
+ return;
+
intel_fbdev_destroy(ifbdev);
- dev_priv->fbdev = NULL;
}
void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous)
@@ -813,7 +797,7 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev)
{
struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
- if (ifbdev && ifbdev->vma)
+ if (ifbdev)
drm_fb_helper_hotplug_event(&ifbdev->helper);
}
diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c
index d484862cc7df..5a7cca32c0fa 100644
--- a/drivers/gpu/drm/i915/intel_fifo_underrun.c
+++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c
@@ -313,11 +313,11 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
* Returns the previous state of underrun reporting.
*/
bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
- enum transcoder pch_transcoder,
+ enum pipe pch_transcoder,
bool enable)
{
struct intel_crtc *crtc =
- intel_get_crtc_for_pipe(dev_priv, (enum pipe) pch_transcoder);
+ intel_get_crtc_for_pipe(dev_priv, pch_transcoder);
unsigned long flags;
bool old;
@@ -390,7 +390,7 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
* interrupt to avoid an irq storm.
*/
void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
- enum transcoder pch_transcoder)
+ enum pipe pch_transcoder)
{
if (intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder,
false)) {
diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c
index 52d5b82790d9..c17ed0e62b67 100644
--- a/drivers/gpu/drm/i915/intel_gvt.c
+++ b/drivers/gpu/drm/i915/intel_gvt.c
@@ -45,7 +45,7 @@ static bool is_supported_device(struct drm_i915_private *dev_priv)
return true;
if (IS_SKYLAKE(dev_priv))
return true;
- if (IS_KABYLAKE(dev_priv) && INTEL_DEVID(dev_priv) == 0x591D)
+ if (IS_KABYLAKE(dev_priv))
return true;
return false;
}
diff --git a/drivers/gpu/drm/i915/intel_hangcheck.c b/drivers/gpu/drm/i915/intel_hangcheck.c
index 9b0ece427bdc..d9d87d96fb69 100644
--- a/drivers/gpu/drm/i915/intel_hangcheck.c
+++ b/drivers/gpu/drm/i915/intel_hangcheck.c
@@ -324,7 +324,7 @@ hangcheck_get_action(struct intel_engine_cs *engine,
if (engine->hangcheck.seqno != hc->seqno)
return ENGINE_ACTIVE_SEQNO;
- if (i915_seqno_passed(hc->seqno, intel_engine_last_submit(engine)))
+ if (intel_engine_is_idle(engine))
return ENGINE_IDLE;
return engine_stuck(engine, hc->acthd);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index ec0779a52d53..e8abea7594ec 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -459,22 +459,31 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
const struct drm_display_mode *adjusted_mode =
&crtc_state->base.adjusted_mode;
+ struct drm_connector *connector = &intel_hdmi->attached_connector->base;
+ bool is_hdmi2_sink = connector->display_info.hdmi.scdc.supported;
union hdmi_infoframe frame;
int ret;
ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
- adjusted_mode);
+ adjusted_mode,
+ is_hdmi2_sink);
if (ret < 0) {
DRM_ERROR("couldn't fill AVI infoframe\n");
return;
}
+ if (crtc_state->ycbcr420)
+ frame.avi.colorspace = HDMI_COLORSPACE_YUV420;
+ else
+ frame.avi.colorspace = HDMI_COLORSPACE_RGB;
+
drm_hdmi_avi_infoframe_quant_range(&frame.avi, adjusted_mode,
crtc_state->limited_color_range ?
HDMI_QUANTIZATION_RANGE_LIMITED :
HDMI_QUANTIZATION_RANGE_FULL,
intel_hdmi->rgb_quant_range_selectable);
+ /* TODO: handle pixel repetition for YCBCR420 outputs */
intel_write_infoframe(encoder, crtc_state, &frame);
}
@@ -1292,6 +1301,9 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
clock *= 2;
+ if (drm_mode_is_420_only(&connector->display_info, mode))
+ clock /= 2;
+
/* check if we can do 8bpc */
status = hdmi_port_clock_valid(hdmi, clock, true, force_dvi);
@@ -1321,14 +1333,21 @@ static bool hdmi_12bpc_possible(struct intel_crtc_state *crtc_state)
if (crtc_state->output_types != 1 << INTEL_OUTPUT_HDMI)
return false;
- for_each_connector_in_state(state, connector, connector_state, i) {
+ for_each_new_connector_in_state(state, connector, connector_state, i) {
const struct drm_display_info *info = &connector->display_info;
if (connector_state->crtc != crtc_state->base.crtc)
continue;
- if ((info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_36) == 0)
- return false;
+ if (crtc_state->ycbcr420) {
+ const struct drm_hdmi_info *hdmi = &info->hdmi;
+
+ if (!(hdmi->y420_dc_modes & DRM_EDID_YCBCR420_DC_36))
+ return false;
+ } else {
+ if (!(info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_36))
+ return false;
+ }
}
/* Display Wa #1139 */
@@ -1339,6 +1358,36 @@ static bool hdmi_12bpc_possible(struct intel_crtc_state *crtc_state)
return true;
}
+static bool
+intel_hdmi_ycbcr420_config(struct drm_connector *connector,
+ struct intel_crtc_state *config,
+ int *clock_12bpc, int *clock_8bpc)
+{
+ struct intel_crtc *intel_crtc = to_intel_crtc(config->base.crtc);
+
+ if (!connector->ycbcr_420_allowed) {
+ DRM_ERROR("Platform doesn't support YCBCR420 output\n");
+ return false;
+ }
+
+ /* YCBCR420 TMDS rate requirement is half the pixel clock */
+ config->port_clock /= 2;
+ *clock_12bpc /= 2;
+ *clock_8bpc /= 2;
+ config->ycbcr420 = true;
+
+ /* YCBCR 420 output conversion needs a scaler */
+ if (skl_update_scaler_crtc(config)) {
+ DRM_DEBUG_KMS("Scaler allocation for output failed\n");
+ return false;
+ }
+
+ intel_pch_panel_fitting(intel_crtc, config,
+ DRM_MODE_SCALE_FULLSCREEN);
+
+ return true;
+}
+
bool intel_hdmi_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state)
@@ -1346,7 +1395,8 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
- struct drm_scdc *scdc = &conn_state->connector->display_info.hdmi.scdc;
+ struct drm_connector *connector = conn_state->connector;
+ struct drm_scdc *scdc = &connector->display_info.hdmi.scdc;
struct intel_digital_connector_state *intel_conn_state =
to_intel_digital_connector_state(conn_state);
int clock_8bpc = pipe_config->base.adjusted_mode.crtc_clock;
@@ -1376,6 +1426,14 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
clock_12bpc *= 2;
}
+ if (drm_mode_is_420_only(&connector->display_info, adjusted_mode)) {
+ if (!intel_hdmi_ycbcr420_config(connector, pipe_config,
+ &clock_12bpc, &clock_8bpc)) {
+ DRM_ERROR("Can't support YCBCR420 output\n");
+ return false;
+ }
+ }
+
if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv))
pipe_config->has_pch_encoder = true;
@@ -1703,11 +1761,9 @@ static void intel_hdmi_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = intel_hdmi_detect,
.force = intel_hdmi_force,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.atomic_get_property = intel_digital_connector_atomic_get_property,
.atomic_set_property = intel_digital_connector_atomic_set_property,
.late_register = intel_connector_register,
@@ -1787,45 +1843,114 @@ void intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder,
DRM_DEBUG_KMS("sink scrambling handled\n");
}
-static u8 intel_hdmi_ddc_pin(struct drm_i915_private *dev_priv,
- enum port port)
+static u8 chv_port_to_ddc_pin(struct drm_i915_private *dev_priv, enum port port)
{
- const struct ddi_vbt_port_info *info =
- &dev_priv->vbt.ddi_port_info[port];
u8 ddc_pin;
- if (info->alternate_ddc_pin) {
- DRM_DEBUG_KMS("Using DDC pin 0x%x for port %c (VBT)\n",
- info->alternate_ddc_pin, port_name(port));
- return info->alternate_ddc_pin;
+ switch (port) {
+ case PORT_B:
+ ddc_pin = GMBUS_PIN_DPB;
+ break;
+ case PORT_C:
+ ddc_pin = GMBUS_PIN_DPC;
+ break;
+ case PORT_D:
+ ddc_pin = GMBUS_PIN_DPD_CHV;
+ break;
+ default:
+ MISSING_CASE(port);
+ ddc_pin = GMBUS_PIN_DPB;
+ break;
}
+ return ddc_pin;
+}
+
+static u8 bxt_port_to_ddc_pin(struct drm_i915_private *dev_priv, enum port port)
+{
+ u8 ddc_pin;
switch (port) {
case PORT_B:
- if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv))
- ddc_pin = GMBUS_PIN_1_BXT;
- else
- ddc_pin = GMBUS_PIN_DPB;
+ ddc_pin = GMBUS_PIN_1_BXT;
break;
case PORT_C:
- if (IS_GEN9_LP(dev_priv) || HAS_PCH_CNP(dev_priv))
- ddc_pin = GMBUS_PIN_2_BXT;
- else
- ddc_pin = GMBUS_PIN_DPC;
+ ddc_pin = GMBUS_PIN_2_BXT;
+ break;
+ default:
+ MISSING_CASE(port);
+ ddc_pin = GMBUS_PIN_1_BXT;
+ break;
+ }
+ return ddc_pin;
+}
+
+static u8 cnp_port_to_ddc_pin(struct drm_i915_private *dev_priv,
+ enum port port)
+{
+ u8 ddc_pin;
+
+ switch (port) {
+ case PORT_B:
+ ddc_pin = GMBUS_PIN_1_BXT;
+ break;
+ case PORT_C:
+ ddc_pin = GMBUS_PIN_2_BXT;
break;
case PORT_D:
- if (HAS_PCH_CNP(dev_priv))
- ddc_pin = GMBUS_PIN_4_CNP;
- else if (IS_CHERRYVIEW(dev_priv))
- ddc_pin = GMBUS_PIN_DPD_CHV;
- else
- ddc_pin = GMBUS_PIN_DPD;
+ ddc_pin = GMBUS_PIN_4_CNP;
+ break;
+ default:
+ MISSING_CASE(port);
+ ddc_pin = GMBUS_PIN_1_BXT;
+ break;
+ }
+ return ddc_pin;
+}
+
+static u8 g4x_port_to_ddc_pin(struct drm_i915_private *dev_priv,
+ enum port port)
+{
+ u8 ddc_pin;
+
+ switch (port) {
+ case PORT_B:
+ ddc_pin = GMBUS_PIN_DPB;
+ break;
+ case PORT_C:
+ ddc_pin = GMBUS_PIN_DPC;
+ break;
+ case PORT_D:
+ ddc_pin = GMBUS_PIN_DPD;
break;
default:
MISSING_CASE(port);
ddc_pin = GMBUS_PIN_DPB;
break;
}
+ return ddc_pin;
+}
+
+static u8 intel_hdmi_ddc_pin(struct drm_i915_private *dev_priv,
+ enum port port)
+{
+ const struct ddi_vbt_port_info *info =
+ &dev_priv->vbt.ddi_port_info[port];
+ u8 ddc_pin;
+
+ if (info->alternate_ddc_pin) {
+ DRM_DEBUG_KMS("Using DDC pin 0x%x for port %c (VBT)\n",
+ info->alternate_ddc_pin, port_name(port));
+ return info->alternate_ddc_pin;
+ }
+
+ if (IS_CHERRYVIEW(dev_priv))
+ ddc_pin = chv_port_to_ddc_pin(dev_priv, port);
+ else if (IS_GEN9_LP(dev_priv))
+ ddc_pin = bxt_port_to_ddc_pin(dev_priv, port);
+ else if (HAS_PCH_CNP(dev_priv))
+ ddc_pin = cnp_port_to_ddc_pin(dev_priv, port);
+ else
+ ddc_pin = g4x_port_to_ddc_pin(dev_priv, port);
DRM_DEBUG_KMS("Using DDC pin 0x%x for port %c (platform default)\n",
ddc_pin, port_name(port));
@@ -1859,25 +1984,14 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
connector->doublescan_allowed = 0;
connector->stereo_allowed = 1;
+ if (IS_GEMINILAKE(dev_priv))
+ connector->ycbcr_420_allowed = true;
+
intel_hdmi->ddc_bus = intel_hdmi_ddc_pin(dev_priv, port);
- switch (port) {
- case PORT_B:
- intel_encoder->hpd_pin = HPD_PORT_B;
- break;
- case PORT_C:
- intel_encoder->hpd_pin = HPD_PORT_C;
- break;
- case PORT_D:
- intel_encoder->hpd_pin = HPD_PORT_D;
- break;
- case PORT_E:
- intel_encoder->hpd_pin = HPD_PORT_E;
- break;
- default:
- MISSING_CASE(port);
+ if (WARN_ON(port == PORT_A))
return;
- }
+ intel_encoder->hpd_pin = intel_hpd_pin(port);
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
intel_hdmi->write_infoframe = vlv_write_infoframe;
diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
index f1200272a699..875d5d218d5c 100644
--- a/drivers/gpu/drm/i915/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/intel_hotplug.c
@@ -76,26 +76,54 @@
* it will use i915_hotplug_work_func where this logic is handled.
*/
-bool intel_hpd_pin_to_port(enum hpd_pin pin, enum port *port)
+/**
+ * intel_hpd_port - return port hard associated with certain pin.
+ * @pin: the hpd pin to get associated port
+ *
+ * Return port that is associatade with @pin and PORT_NONE if no port is
+ * hard associated with that @pin.
+ */
+enum port intel_hpd_pin_to_port(enum hpd_pin pin)
{
switch (pin) {
case HPD_PORT_A:
- *port = PORT_A;
- return true;
+ return PORT_A;
case HPD_PORT_B:
- *port = PORT_B;
- return true;
+ return PORT_B;
case HPD_PORT_C:
- *port = PORT_C;
- return true;
+ return PORT_C;
case HPD_PORT_D:
- *port = PORT_D;
- return true;
+ return PORT_D;
case HPD_PORT_E:
- *port = PORT_E;
- return true;
+ return PORT_E;
+ default:
+ return PORT_NONE; /* no port for this pin */
+ }
+}
+
+/**
+ * intel_hpd_pin - return pin hard associated with certain port.
+ * @port: the hpd port to get associated pin
+ *
+ * Return pin that is associatade with @port and HDP_NONE if no pin is
+ * hard associated with that @port.
+ */
+enum hpd_pin intel_hpd_pin(enum port port)
+{
+ switch (port) {
+ case PORT_A:
+ return HPD_PORT_A;
+ case PORT_B:
+ return HPD_PORT_B;
+ case PORT_C:
+ return HPD_PORT_C;
+ case PORT_D:
+ return HPD_PORT_D;
+ case PORT_E:
+ return HPD_PORT_E;
default:
- return false; /* no hpd */
+ MISSING_CASE(port);
+ return HPD_NONE;
}
}
@@ -389,8 +417,9 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
if (!(BIT(i) & pin_mask))
continue;
- is_dig_port = intel_hpd_pin_to_port(i, &port) &&
- dev_priv->hotplug.irq_port[port];
+ port = intel_hpd_pin_to_port(i);
+ is_dig_port = port != PORT_NONE &&
+ dev_priv->hotplug.irq_port[port];
if (is_dig_port) {
bool long_hpd = long_mask & BIT(i);
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 3c9e00d4ba5a..6698826954e1 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -592,7 +592,6 @@ gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
int ret;
intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
- mutex_lock(&dev_priv->gmbus_mutex);
if (bus->force_bit) {
ret = i2c_bit_algo.master_xfer(adapter, msgs, num);
@@ -604,7 +603,6 @@ gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
bus->force_bit |= GMBUS_FORCE_BIT_RETRY;
}
- mutex_unlock(&dev_priv->gmbus_mutex);
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
return ret;
@@ -624,6 +622,39 @@ static const struct i2c_algorithm gmbus_algorithm = {
.functionality = gmbus_func
};
+static void gmbus_lock_bus(struct i2c_adapter *adapter,
+ unsigned int flags)
+{
+ struct intel_gmbus *bus = to_intel_gmbus(adapter);
+ struct drm_i915_private *dev_priv = bus->dev_priv;
+
+ mutex_lock(&dev_priv->gmbus_mutex);
+}
+
+static int gmbus_trylock_bus(struct i2c_adapter *adapter,
+ unsigned int flags)
+{
+ struct intel_gmbus *bus = to_intel_gmbus(adapter);
+ struct drm_i915_private *dev_priv = bus->dev_priv;
+
+ return mutex_trylock(&dev_priv->gmbus_mutex);
+}
+
+static void gmbus_unlock_bus(struct i2c_adapter *adapter,
+ unsigned int flags)
+{
+ struct intel_gmbus *bus = to_intel_gmbus(adapter);
+ struct drm_i915_private *dev_priv = bus->dev_priv;
+
+ mutex_unlock(&dev_priv->gmbus_mutex);
+}
+
+const struct i2c_lock_operations gmbus_lock_ops = {
+ .lock_bus = gmbus_lock_bus,
+ .trylock_bus = gmbus_trylock_bus,
+ .unlock_bus = gmbus_unlock_bus,
+};
+
/**
* intel_gmbus_setup - instantiate all Intel i2c GMBuses
* @dev_priv: i915 device private
@@ -665,6 +696,7 @@ int intel_setup_gmbus(struct drm_i915_private *dev_priv)
bus->dev_priv = dev_priv;
bus->adapter.algo = &gmbus_algorithm;
+ bus->adapter.lock_ops = &gmbus_lock_ops;
/*
* We wish to retry with bit banging
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 7404cf2aac28..b0738d2b2a7f 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1306,6 +1306,31 @@ static void reset_common_ring(struct intel_engine_cs *engine,
{
struct execlist_port *port = engine->execlist_port;
struct intel_context *ce;
+ unsigned int n;
+
+ /*
+ * Catch up with any missed context-switch interrupts.
+ *
+ * Ideally we would just read the remaining CSB entries now that we
+ * know the gpu is idle. However, the CSB registers are sometimes^W
+ * often trashed across a GPU reset! Instead we have to rely on
+ * guessing the missed context-switch events by looking at what
+ * requests were completed.
+ */
+ if (!request) {
+ for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++)
+ i915_gem_request_put(port_request(&port[n]));
+ memset(engine->execlist_port, 0, sizeof(engine->execlist_port));
+ return;
+ }
+
+ if (request->ctx != port_request(port)->ctx) {
+ i915_gem_request_put(port_request(port));
+ port[0] = port[1];
+ memset(&port[1], 0, sizeof(port[1]));
+ }
+
+ GEM_BUG_ON(request->ctx != port_request(port)->ctx);
/* If the request was innocent, we leave the request in the ELSP
* and will try to replay it on restarting. The context image may
@@ -1317,7 +1342,7 @@ static void reset_common_ring(struct intel_engine_cs *engine,
* and have to at least restore the RING register in the context
* image back to the expected values to skip over the guilty request.
*/
- if (!request || request->fence.error != -EIO)
+ if (request->fence.error != -EIO)
return;
/* We want a simple context + ring to execute the breadcrumb update.
@@ -1339,15 +1364,6 @@ static void reset_common_ring(struct intel_engine_cs *engine,
request->ring->head = request->postfix;
intel_ring_update_space(request->ring);
- /* Catch up with any missed context-switch interrupts */
- if (request->ctx != port_request(port)->ctx) {
- i915_gem_request_put(port_request(port));
- port[0] = port[1];
- memset(&port[1], 0, sizeof(port[1]));
- }
-
- GEM_BUG_ON(request->ctx != port_request(port)->ctx);
-
/* Reset WaIdleLiteRestore:bdw,skl as well */
request->tail =
intel_ring_wrap(request->ring,
@@ -2071,7 +2087,7 @@ void intel_lr_context_resume(struct drm_i915_private *dev_priv)
* So to avoid that we reset the context images upon resume. For
* simplicity, we just zero everything out.
*/
- list_for_each_entry(ctx, &dev_priv->context_list, link) {
+ list_for_each_entry(ctx, &dev_priv->contexts.list, link) {
for_each_engine(engine, dev_priv, id) {
struct intel_context *ce = &ctx->engine[engine->id];
u32 *reg;
diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
index 52b3a1fd4059..57ef5833c427 100644
--- a/drivers/gpu/drm/i915/intel_lrc.h
+++ b/drivers/gpu/drm/i915/intel_lrc.h
@@ -63,7 +63,6 @@ enum {
};
/* Logical Rings */
-void intel_logical_ring_stop(struct intel_engine_cs *engine);
void intel_logical_ring_cleanup(struct intel_engine_cs *engine);
int logical_render_ring_init(struct intel_engine_cs *engine);
int logical_xcs_ring_init(struct intel_engine_cs *engine);
diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c
index 5abef482eacf..beb9baaf2f2e 100644
--- a/drivers/gpu/drm/i915/intel_lspcon.c
+++ b/drivers/gpu/drm/i915/intel_lspcon.c
@@ -210,8 +210,8 @@ bool lspcon_init(struct intel_digital_port *intel_dig_port)
struct drm_device *dev = intel_dig_port->base.base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
- if (!IS_GEN9(dev_priv)) {
- DRM_ERROR("LSPCON is supported on GEN9 only\n");
+ if (!HAS_LSPCON(dev_priv)) {
+ DRM_ERROR("LSPCON is not supported on this platform\n");
return false;
}
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 6fe5d7c3bc23..8e215777c7f4 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -595,10 +595,8 @@ static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs
};
static const struct drm_connector_funcs intel_lvds_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = intel_lvds_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.atomic_get_property = intel_digital_connector_atomic_get_property,
.atomic_set_property = intel_digital_connector_atomic_set_property,
.late_register = intel_connector_register,
@@ -1140,7 +1138,8 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
out:
mutex_unlock(&dev->mode_config.mutex);
- intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
+ intel_panel_init(&intel_connector->panel, fixed_mode, NULL,
+ downclock_mode);
intel_panel_setup_backlight(connector, INVALID_PIPE);
lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder);
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
index 2bd03001cc70..98154efcb2f4 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -27,6 +27,7 @@
#include <linux/acpi.h>
#include <linux/dmi.h>
+#include <linux/firmware.h>
#include <acpi/video.h>
#include <drm/drmP.h>
@@ -829,6 +830,10 @@ void intel_opregion_unregister(struct drm_i915_private *dev_priv)
memunmap(opregion->rvda);
opregion->rvda = NULL;
}
+ if (opregion->vbt_firmware) {
+ kfree(opregion->vbt_firmware);
+ opregion->vbt_firmware = NULL;
+ }
opregion->header = NULL;
opregion->acpi = NULL;
opregion->swsci = NULL;
@@ -912,6 +917,43 @@ static const struct dmi_system_id intel_no_opregion_vbt[] = {
{ }
};
+static int intel_load_vbt_firmware(struct drm_i915_private *dev_priv)
+{
+ struct intel_opregion *opregion = &dev_priv->opregion;
+ const struct firmware *fw = NULL;
+ const char *name = i915.vbt_firmware;
+ int ret;
+
+ if (!name || !*name)
+ return -ENOENT;
+
+ ret = request_firmware(&fw, name, &dev_priv->drm.pdev->dev);
+ if (ret) {
+ DRM_ERROR("Requesting VBT firmware \"%s\" failed (%d)\n",
+ name, ret);
+ return ret;
+ }
+
+ if (intel_bios_is_valid_vbt(fw->data, fw->size)) {
+ opregion->vbt_firmware = kmemdup(fw->data, fw->size, GFP_KERNEL);
+ if (opregion->vbt_firmware) {
+ DRM_DEBUG_KMS("Found valid VBT firmware \"%s\"\n", name);
+ opregion->vbt = opregion->vbt_firmware;
+ opregion->vbt_size = fw->size;
+ ret = 0;
+ } else {
+ ret = -ENOMEM;
+ }
+ } else {
+ DRM_DEBUG_KMS("Invalid VBT firmware \"%s\"\n", name);
+ ret = -EINVAL;
+ }
+
+ release_firmware(fw);
+
+ return ret;
+}
+
int intel_opregion_setup(struct drm_i915_private *dev_priv)
{
struct intel_opregion *opregion = &dev_priv->opregion;
@@ -974,6 +1016,9 @@ int intel_opregion_setup(struct drm_i915_private *dev_priv)
if (mboxes & MBOX_ASLE_EXT)
DRM_DEBUG_DRIVER("ASLE extension supported\n");
+ if (intel_load_vbt_firmware(dev_priv) == 0)
+ goto out;
+
if (dmi_check_system(intel_no_opregion_vbt))
goto out;
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index b96aed941b97..aace22e7ccac 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -799,9 +799,13 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
if (ret != 0)
return ret;
+ atomic_inc(&dev_priv->gpu_error.pending_fb_pin);
+
vma = i915_gem_object_pin_to_display_plane(new_bo, 0, NULL);
- if (IS_ERR(vma))
- return PTR_ERR(vma);
+ if (IS_ERR(vma)) {
+ ret = PTR_ERR(vma);
+ goto out_pin_section;
+ }
ret = i915_vma_put_fence(vma);
if (ret)
@@ -886,6 +890,9 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
out_unpin:
i915_gem_object_unpin_from_display_plane(vma);
+out_pin_section:
+ atomic_dec(&dev_priv->gpu_error.pending_fb_pin);
+
return ret;
}
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 96c2cbd81869..a17b1de7d7e0 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -110,7 +110,8 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
/* Native modes don't need fitting */
if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
- adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h)
+ adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h &&
+ !pipe_config->ycbcr420)
goto done;
switch (fitting_mode) {
@@ -469,7 +470,7 @@ static u32 intel_panel_compute_brightness(struct intel_connector *connector,
if (i915.invert_brightness > 0 ||
dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) {
- return panel->backlight.max - val;
+ return panel->backlight.max - val + panel->backlight.min;
}
return val;
@@ -1919,11 +1920,13 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel)
int intel_panel_init(struct intel_panel *panel,
struct drm_display_mode *fixed_mode,
+ struct drm_display_mode *alt_fixed_mode,
struct drm_display_mode *downclock_mode)
{
intel_panel_init_backlight_funcs(panel);
panel->fixed_mode = fixed_mode;
+ panel->alt_fixed_mode = alt_fixed_mode;
panel->downclock_mode = downclock_mode;
return 0;
@@ -1937,6 +1940,10 @@ void intel_panel_fini(struct intel_panel *panel)
if (panel->fixed_mode)
drm_mode_destroy(intel_connector->base.dev, panel->fixed_mode);
+ if (panel->alt_fixed_mode)
+ drm_mode_destroy(intel_connector->base.dev,
+ panel->alt_fixed_mode);
+
if (panel->downclock_mode)
drm_mode_destroy(intel_connector->base.dev,
panel->downclock_mode);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 48ea0fca1f72..ed662937ec3c 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -62,6 +62,20 @@ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
I915_WRITE(CHICKEN_PAR1_1,
I915_READ(CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP);
+ /*
+ * Display WA#0390: skl,bxt,kbl,glk
+ *
+ * Must match Sampler, Pixel Back End, and Media
+ * (0xE194 bit 8, 0x7014 bit 13, 0x4DDC bits 27 and 31).
+ *
+ * Including bits outside the page in the hash would
+ * require 2 (or 4?) MiB alignment of resources. Just
+ * assume the defaul hashing mode which only uses bits
+ * within the page.
+ */
+ I915_WRITE(CHICKEN_PAR1_1,
+ I915_READ(CHICKEN_PAR1_1) & ~SKL_RC_HASH_OUTSIDE);
+
I915_WRITE(GEN8_CONFIG0,
I915_READ(GEN8_CONFIG0) | GEN9_DEFAULT_FIXES);
@@ -78,6 +92,12 @@ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
/* WaFbcHighMemBwCorruptionAvoidance:skl,bxt,kbl,cfl */
I915_WRITE(ILK_DPFC_CHICKEN, I915_READ(ILK_DPFC_CHICKEN) |
ILK_DPFC_DISABLE_DUMMY0);
+
+ if (IS_SKYLAKE(dev_priv)) {
+ /* WaDisableDopClockGating */
+ I915_WRITE(GEN7_MISCCPCTL, I915_READ(GEN7_MISCCPCTL)
+ & ~GEN7_DOP_CLOCK_GATE_ENABLE);
+ }
}
static void bxt_init_clock_gating(struct drm_i915_private *dev_priv)
@@ -2758,7 +2778,7 @@ hsw_compute_linetime_wm(const struct intel_crtc_state *cstate)
static void intel_read_wm_latency(struct drm_i915_private *dev_priv,
uint16_t wm[8])
{
- if (IS_GEN9(dev_priv)) {
+ if (INTEL_GEN(dev_priv) >= 9) {
uint32_t val;
int ret, i;
int level, max_level = ilk_wm_max_level(dev_priv);
@@ -2818,7 +2838,7 @@ static void intel_read_wm_latency(struct drm_i915_private *dev_priv,
}
/*
- * WaWmMemoryReadLatency:skl,glk
+ * WaWmMemoryReadLatency:skl+,glk
*
* punit doesn't take into account the read latency so we need
* to add 2us to the various latency levels we retrieve from the
@@ -2857,6 +2877,8 @@ static void intel_read_wm_latency(struct drm_i915_private *dev_priv,
wm[0] = 7;
wm[1] = (mltr >> MLTR_WM1_SHIFT) & ILK_SRLT_MASK;
wm[2] = (mltr >> MLTR_WM2_SHIFT) & ILK_SRLT_MASK;
+ } else {
+ MISSING_CASE(INTEL_DEVID(dev_priv));
}
}
@@ -2912,7 +2934,7 @@ static void intel_print_wm_latency(struct drm_i915_private *dev_priv,
* - latencies are in us on gen9.
* - before then, WM1+ latency values are in 0.5us units
*/
- if (IS_GEN9(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 9)
latency *= 10;
else if (level > 0)
latency *= 5;
@@ -3530,8 +3552,6 @@ bool ilk_disable_lp_wm(struct drm_device *dev)
return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
}
-#define SKL_SAGV_BLOCK_TIME 30 /* µs */
-
/*
* FIXME: We still don't have the proper code detect if we need to apply the WA,
* so assume we'll always need it in order to avoid underruns.
@@ -3549,7 +3569,8 @@ static bool skl_needs_memory_bw_wa(struct intel_atomic_state *state)
static bool
intel_has_sagv(struct drm_i915_private *dev_priv)
{
- if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv))
+ if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv) ||
+ IS_CANNONLAKE(dev_priv))
return true;
if (IS_SKYLAKE(dev_priv) &&
@@ -3655,12 +3676,13 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state)
struct intel_crtc_state *cstate;
enum pipe pipe;
int level, latency;
+ int sagv_block_time_us = IS_GEN9(dev_priv) ? 30 : 20;
if (!intel_has_sagv(dev_priv))
return false;
/*
- * SKL workaround: bspec recommends we disable the SAGV when we have
+ * SKL+ workaround: bspec recommends we disable the SAGV when we have
* more then one pipe enabled
*
* If there are no active CRTCs, no additional checks need be performed
@@ -3699,11 +3721,11 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state)
latency += 15;
/*
- * If any of the planes on this pipe don't enable wm levels
- * that incur memory latencies higher then 30µs we can't enable
- * the SAGV
+ * If any of the planes on this pipe don't enable wm levels that
+ * incur memory latencies higher than sagv_block_time_us we
+ * can't enable the SAGV.
*/
- if (latency < SKL_SAGV_BLOCK_TIME)
+ if (latency < sagv_block_time_us)
return false;
}
@@ -3837,7 +3859,7 @@ skl_plane_downscale_amount(const struct intel_crtc_state *cstate,
uint_fixed_16_16_t downscale_h, downscale_w;
if (WARN_ON(!intel_wm_plane_visible(cstate, pstate)))
- return u32_to_fixed_16_16(0);
+ return u32_to_fixed16(0);
/* n.b., src is 16.16 fixed point, dst is whole integer */
if (plane->id == PLANE_CURSOR) {
@@ -3861,10 +3883,10 @@ skl_plane_downscale_amount(const struct intel_crtc_state *cstate,
dst_h = drm_rect_height(&pstate->base.dst);
}
- fp_w_ratio = fixed_16_16_div(src_w, dst_w);
- fp_h_ratio = fixed_16_16_div(src_h, dst_h);
- downscale_w = max_fixed_16_16(fp_w_ratio, u32_to_fixed_16_16(1));
- downscale_h = max_fixed_16_16(fp_h_ratio, u32_to_fixed_16_16(1));
+ fp_w_ratio = div_fixed16(src_w, dst_w);
+ fp_h_ratio = div_fixed16(src_h, dst_h);
+ downscale_w = max_fixed16(fp_w_ratio, u32_to_fixed16(1));
+ downscale_h = max_fixed16(fp_h_ratio, u32_to_fixed16(1));
return mul_fixed16(downscale_w, downscale_h);
}
@@ -3872,7 +3894,7 @@ skl_plane_downscale_amount(const struct intel_crtc_state *cstate,
static uint_fixed_16_16_t
skl_pipe_downscale_amount(const struct intel_crtc_state *crtc_state)
{
- uint_fixed_16_16_t pipe_downscale = u32_to_fixed_16_16(1);
+ uint_fixed_16_16_t pipe_downscale = u32_to_fixed16(1);
if (!crtc_state->base.enable)
return pipe_downscale;
@@ -3891,10 +3913,10 @@ skl_pipe_downscale_amount(const struct intel_crtc_state *crtc_state)
if (!dst_w || !dst_h)
return pipe_downscale;
- fp_w_ratio = fixed_16_16_div(src_w, dst_w);
- fp_h_ratio = fixed_16_16_div(src_h, dst_h);
- downscale_w = max_fixed_16_16(fp_w_ratio, u32_to_fixed_16_16(1));
- downscale_h = max_fixed_16_16(fp_h_ratio, u32_to_fixed_16_16(1));
+ fp_w_ratio = div_fixed16(src_w, dst_w);
+ fp_h_ratio = div_fixed16(src_h, dst_h);
+ downscale_w = max_fixed16(fp_w_ratio, u32_to_fixed16(1));
+ downscale_h = max_fixed16(fp_h_ratio, u32_to_fixed16(1));
pipe_downscale = mul_fixed16(downscale_w, downscale_h);
}
@@ -3913,14 +3935,14 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
int crtc_clock, dotclk;
uint32_t pipe_max_pixel_rate;
uint_fixed_16_16_t pipe_downscale;
- uint_fixed_16_16_t max_downscale = u32_to_fixed_16_16(1);
+ uint_fixed_16_16_t max_downscale = u32_to_fixed16(1);
if (!cstate->base.enable)
return 0;
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
uint_fixed_16_16_t plane_downscale;
- uint_fixed_16_16_t fp_9_div_8 = fixed_16_16_div(9, 8);
+ uint_fixed_16_16_t fp_9_div_8 = div_fixed16(9, 8);
int bpp;
if (!intel_wm_plane_visible(cstate,
@@ -3938,7 +3960,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
plane_downscale = mul_fixed16(plane_downscale,
fp_9_div_8);
- max_downscale = max_fixed_16_16(plane_downscale, max_downscale);
+ max_downscale = max_fixed16(plane_downscale, max_downscale);
}
pipe_downscale = skl_pipe_downscale_amount(cstate);
@@ -4071,7 +4093,9 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
/* For Non Y-tile return 8-blocks */
if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
- fb->modifier != I915_FORMAT_MOD_Yf_TILED)
+ fb->modifier != I915_FORMAT_MOD_Yf_TILED &&
+ fb->modifier != I915_FORMAT_MOD_Y_TILED_CCS &&
+ fb->modifier != I915_FORMAT_MOD_Yf_TILED_CCS)
return 8;
/*
@@ -4266,8 +4290,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
* should allow pixel_rate up to ~2 GHz which seems sufficient since max
* 2xcdclk is 1350 MHz and the pixel rate should never exceed that.
*/
-static uint_fixed_16_16_t skl_wm_method1(uint32_t pixel_rate, uint8_t cpp,
- uint32_t latency)
+static uint_fixed_16_16_t
+skl_wm_method1(const struct drm_i915_private *dev_priv, uint32_t pixel_rate,
+ uint8_t cpp, uint32_t latency)
{
uint32_t wm_intermediate_val;
uint_fixed_16_16_t ret;
@@ -4276,7 +4301,11 @@ static uint_fixed_16_16_t skl_wm_method1(uint32_t pixel_rate, uint8_t cpp,
return FP_16_16_MAX;
wm_intermediate_val = latency * pixel_rate * cpp;
- ret = fixed_16_16_div_u64(wm_intermediate_val, 1000 * 512);
+ ret = div_fixed16(wm_intermediate_val, 1000 * 512);
+
+ if (INTEL_GEN(dev_priv) >= 10)
+ ret = add_fixed16_u32(ret, 1);
+
return ret;
}
@@ -4294,7 +4323,7 @@ static uint_fixed_16_16_t skl_wm_method2(uint32_t pixel_rate,
wm_intermediate_val = latency * pixel_rate;
wm_intermediate_val = DIV_ROUND_UP(wm_intermediate_val,
pipe_htotal * 1000);
- ret = mul_u32_fixed_16_16(wm_intermediate_val, plane_blocks_per_line);
+ ret = mul_u32_fixed16(wm_intermediate_val, plane_blocks_per_line);
return ret;
}
@@ -4306,15 +4335,15 @@ intel_get_linetime_us(struct intel_crtc_state *cstate)
uint_fixed_16_16_t linetime_us;
if (!cstate->base.active)
- return u32_to_fixed_16_16(0);
+ return u32_to_fixed16(0);
pixel_rate = cstate->pixel_rate;
if (WARN_ON(pixel_rate == 0))
- return u32_to_fixed_16_16(0);
+ return u32_to_fixed16(0);
crtc_htotal = cstate->base.adjusted_mode.crtc_htotal;
- linetime_us = fixed_16_16_div_u64(crtc_htotal * 1000, pixel_rate);
+ linetime_us = div_fixed16(crtc_htotal * 1000, pixel_rate);
return linetime_us;
}
@@ -4361,7 +4390,7 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
uint32_t plane_bytes_per_line;
uint32_t res_blocks, res_lines;
uint8_t cpp;
- uint32_t width = 0, height = 0;
+ uint32_t width = 0;
uint32_t plane_pixel_rate;
uint_fixed_16_16_t y_tile_minimum;
uint32_t y_min_scanlines;
@@ -4377,7 +4406,9 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
}
y_tiled = fb->modifier == I915_FORMAT_MOD_Y_TILED ||
- fb->modifier == I915_FORMAT_MOD_Yf_TILED;
+ fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
+ fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+ fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
x_tiled = fb->modifier == I915_FORMAT_MOD_X_TILED;
/* Display WA #1141: kbl,cfl */
@@ -4390,7 +4421,6 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
if (plane->id == PLANE_CURSOR) {
width = intel_pstate->base.crtc_w;
- height = intel_pstate->base.crtc_h;
} else {
/*
* Src coordinates are already rotated by 270 degrees for
@@ -4398,16 +4428,13 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
* GTT mapping), hence no need to account for rotation here.
*/
width = drm_rect_width(&intel_pstate->base.src) >> 16;
- height = drm_rect_height(&intel_pstate->base.src) >> 16;
}
- cpp = fb->format->cpp[0];
+ cpp = (fb->format->format == DRM_FORMAT_NV12) ? fb->format->cpp[1] :
+ fb->format->cpp[0];
plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, intel_pstate);
if (drm_rotation_90_or_270(pstate->rotation)) {
- int cpp = (fb->format->format == DRM_FORMAT_NV12) ?
- fb->format->cpp[1] :
- fb->format->cpp[0];
switch (cpp) {
case 1:
@@ -4434,51 +4461,62 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
if (y_tiled) {
interm_pbpl = DIV_ROUND_UP(plane_bytes_per_line *
y_min_scanlines, 512);
- plane_blocks_per_line = fixed_16_16_div(interm_pbpl,
+
+ if (INTEL_GEN(dev_priv) >= 10)
+ interm_pbpl++;
+
+ plane_blocks_per_line = div_fixed16(interm_pbpl,
y_min_scanlines);
- } else if (x_tiled) {
+ } else if (x_tiled && INTEL_GEN(dev_priv) == 9) {
interm_pbpl = DIV_ROUND_UP(plane_bytes_per_line, 512);
- plane_blocks_per_line = u32_to_fixed_16_16(interm_pbpl);
+ plane_blocks_per_line = u32_to_fixed16(interm_pbpl);
} else {
interm_pbpl = DIV_ROUND_UP(plane_bytes_per_line, 512) + 1;
- plane_blocks_per_line = u32_to_fixed_16_16(interm_pbpl);
+ plane_blocks_per_line = u32_to_fixed16(interm_pbpl);
}
- method1 = skl_wm_method1(plane_pixel_rate, cpp, latency);
+ method1 = skl_wm_method1(dev_priv, plane_pixel_rate, cpp, latency);
method2 = skl_wm_method2(plane_pixel_rate,
cstate->base.adjusted_mode.crtc_htotal,
latency,
plane_blocks_per_line);
- y_tile_minimum = mul_u32_fixed_16_16(y_min_scanlines,
- plane_blocks_per_line);
+ y_tile_minimum = mul_u32_fixed16(y_min_scanlines,
+ plane_blocks_per_line);
if (y_tiled) {
- selected_result = max_fixed_16_16(method2, y_tile_minimum);
+ selected_result = max_fixed16(method2, y_tile_minimum);
} else {
uint32_t linetime_us;
- linetime_us = fixed_16_16_to_u32_round_up(
+ linetime_us = fixed16_to_u32_round_up(
intel_get_linetime_us(cstate));
if ((cpp * cstate->base.adjusted_mode.crtc_htotal / 512 < 1) &&
(plane_bytes_per_line / 512 < 1))
selected_result = method2;
- else if ((ddb_allocation && ddb_allocation /
- fixed_16_16_to_u32_round_up(plane_blocks_per_line)) >= 1)
- selected_result = min_fixed_16_16(method1, method2);
+ else if (ddb_allocation >=
+ fixed16_to_u32_round_up(plane_blocks_per_line))
+ selected_result = min_fixed16(method1, method2);
else if (latency >= linetime_us)
- selected_result = min_fixed_16_16(method1, method2);
+ selected_result = min_fixed16(method1, method2);
else
selected_result = method1;
}
- res_blocks = fixed_16_16_to_u32_round_up(selected_result) + 1;
+ res_blocks = fixed16_to_u32_round_up(selected_result) + 1;
res_lines = div_round_up_fixed16(selected_result,
plane_blocks_per_line);
+ /* Display WA #1125: skl,bxt,kbl,glk */
+ if (level == 0 &&
+ (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+ fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS))
+ res_blocks += fixed16_to_u32_round_up(y_tile_minimum);
+
+ /* Display WA #1126: skl,bxt,kbl,glk */
if (level >= 1 && level <= 7) {
if (y_tiled) {
- res_blocks += fixed_16_16_to_u32_round_up(y_tile_minimum);
+ res_blocks += fixed16_to_u32_round_up(y_tile_minimum);
res_lines += y_min_scanlines;
} else {
res_blocks++;
@@ -4563,8 +4601,7 @@ skl_compute_linetime_wm(struct intel_crtc_state *cstate)
if (is_fixed16_zero(linetime_us))
return 0;
- linetime_wm = fixed_16_16_to_u32_round_up(mul_u32_fixed_16_16(8,
- linetime_us));
+ linetime_wm = fixed16_to_u32_round_up(mul_u32_fixed16(8, linetime_us));
/* Display WA #1135: bxt. */
if (IS_BROXTON(dev_priv) && dev_priv->ipc_enabled)
@@ -5852,7 +5889,7 @@ static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val)
* the hw runs at the minimal clock before selecting the desired
* frequency, if the down threshold expires in that window we will not
* receive a down interrupt. */
- if (IS_GEN9(dev_priv)) {
+ if (INTEL_GEN(dev_priv) >= 9) {
limits = (dev_priv->rps.max_freq_softlimit) << 23;
if (val <= dev_priv->rps.min_freq_softlimit)
limits |= (dev_priv->rps.min_freq_softlimit) << 14;
@@ -5994,7 +6031,7 @@ static int gen6_set_rps(struct drm_i915_private *dev_priv, u8 val)
if (val != dev_priv->rps.cur_freq) {
gen6_set_rps_thresholds(dev_priv, val);
- if (IS_GEN9(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 9)
I915_WRITE(GEN6_RPNSWREQ,
GEN9_FREQUENCY(val));
else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
@@ -6126,47 +6163,35 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv)
gen6_sanitize_rps_pm_mask(dev_priv, ~0));
}
mutex_unlock(&dev_priv->rps.hw_lock);
-
- spin_lock(&dev_priv->rps.client_lock);
- while (!list_empty(&dev_priv->rps.clients))
- list_del_init(dev_priv->rps.clients.next);
- spin_unlock(&dev_priv->rps.client_lock);
}
-void gen6_rps_boost(struct drm_i915_private *dev_priv,
- struct intel_rps_client *rps,
- unsigned long submitted)
+void gen6_rps_boost(struct drm_i915_gem_request *rq,
+ struct intel_rps_client *rps)
{
+ struct drm_i915_private *i915 = rq->i915;
+ bool boost;
+
/* This is intentionally racy! We peek at the state here, then
* validate inside the RPS worker.
*/
- if (!(dev_priv->gt.awake &&
- dev_priv->rps.enabled &&
- dev_priv->rps.cur_freq < dev_priv->rps.boost_freq))
+ if (!i915->rps.enabled)
return;
- /* Force a RPS boost (and don't count it against the client) if
- * the GPU is severely congested.
- */
- if (rps && time_after(jiffies, submitted + DRM_I915_THROTTLE_JIFFIES))
- rps = NULL;
-
- spin_lock(&dev_priv->rps.client_lock);
- if (rps == NULL || list_empty(&rps->link)) {
- spin_lock_irq(&dev_priv->irq_lock);
- if (dev_priv->rps.interrupts_enabled) {
- dev_priv->rps.client_boost = true;
- schedule_work(&dev_priv->rps.work);
- }
- spin_unlock_irq(&dev_priv->irq_lock);
-
- if (rps != NULL) {
- list_add(&rps->link, &dev_priv->rps.clients);
- rps->boosts++;
- } else
- dev_priv->rps.boosts++;
+ boost = false;
+ spin_lock_irq(&rq->lock);
+ if (!rq->waitboost && !i915_gem_request_completed(rq)) {
+ atomic_inc(&i915->rps.num_waiters);
+ rq->waitboost = true;
+ boost = true;
}
- spin_unlock(&dev_priv->rps.client_lock);
+ spin_unlock_irq(&rq->lock);
+ if (!boost)
+ return;
+
+ if (READ_ONCE(i915->rps.cur_freq) < i915->rps.boost_freq)
+ schedule_work(&i915->rps.work);
+
+ atomic_inc(rps ? &rps->boosts : &i915->rps.boosts);
}
int intel_set_rps(struct drm_i915_private *dev_priv, u8 val)
@@ -6365,7 +6390,7 @@ static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv)
dev_priv->rps.efficient_freq = dev_priv->rps.rp1_freq;
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) ||
- IS_GEN9_BC(dev_priv)) {
+ IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
u32 ddcc_status = 0;
if (sandybridge_pcode_read(dev_priv,
@@ -6378,7 +6403,7 @@ static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv)
dev_priv->rps.max_freq);
}
- if (IS_GEN9_BC(dev_priv)) {
+ if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
/* Store the frequency values in 16.66 MHZ units, which is
* the natural hardware unit for SKL
*/
@@ -6684,7 +6709,7 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
/* convert DDR frequency from units of 266.6MHz to bandwidth */
min_ring_freq = mult_frac(min_ring_freq, 8, 3);
- if (IS_GEN9_BC(dev_priv)) {
+ if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
/* Convert GT frequency to 50 HZ units */
min_gpu_freq = dev_priv->rps.min_freq / GEN9_FREQ_SCALER;
max_gpu_freq = dev_priv->rps.max_freq / GEN9_FREQ_SCALER;
@@ -6702,7 +6727,7 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
int diff = max_gpu_freq - gpu_freq;
unsigned int ia_freq = 0, ring_freq = 0;
- if (IS_GEN9_BC(dev_priv)) {
+ if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
/*
* ring_freq = 2 * GT. ring_freq is in 100MHz units
* No floor required for ring frequency on SKL.
@@ -7833,7 +7858,7 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
} else if (INTEL_GEN(dev_priv) >= 9) {
gen9_enable_rc6(dev_priv);
gen9_enable_rps(dev_priv);
- if (IS_GEN9_BC(dev_priv))
+ if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv))
gen6_update_ring_freq(dev_priv);
} else if (IS_BROADWELL(dev_priv)) {
gen8_enable_rps(dev_priv);
@@ -8848,6 +8873,7 @@ static inline int gen6_check_mailbox_status(struct drm_i915_private *dev_priv)
case GEN6_PCODE_SUCCESS:
return 0;
case GEN6_PCODE_UNIMPLEMENTED_CMD:
+ return -ENODEV;
case GEN6_PCODE_ILLEGAL_CMD:
return -ENXIO;
case GEN6_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE:
@@ -8895,7 +8921,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val
*/
if (I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) {
- DRM_DEBUG_DRIVER("warning: pcode (read) mailbox access failed\n");
+ DRM_DEBUG_DRIVER("warning: pcode (read from mbox %x) mailbox access failed for %ps\n",
+ mbox, __builtin_return_address(0));
return -EAGAIN;
}
@@ -8906,7 +8933,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val
if (__intel_wait_for_register_fw(dev_priv,
GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0,
500, 0, NULL)) {
- DRM_ERROR("timeout waiting for pcode read (%d) to finish\n", mbox);
+ DRM_ERROR("timeout waiting for pcode read (from mbox %x) to finish for %ps\n",
+ mbox, __builtin_return_address(0));
return -ETIMEDOUT;
}
@@ -8919,8 +8947,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val
status = gen6_check_mailbox_status(dev_priv);
if (status) {
- DRM_DEBUG_DRIVER("warning: pcode (read) mailbox access failed: %d\n",
- status);
+ DRM_DEBUG_DRIVER("warning: pcode (read from mbox %x) mailbox access failed for %ps: %d\n",
+ mbox, __builtin_return_address(0), status);
return status;
}
@@ -8940,7 +8968,8 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
*/
if (I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) {
- DRM_DEBUG_DRIVER("warning: pcode (write) mailbox access failed\n");
+ DRM_DEBUG_DRIVER("warning: pcode (write of 0x%08x to mbox %x) mailbox access failed for %ps\n",
+ val, mbox, __builtin_return_address(0));
return -EAGAIN;
}
@@ -8951,7 +8980,8 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
if (__intel_wait_for_register_fw(dev_priv,
GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0,
500, 0, NULL)) {
- DRM_ERROR("timeout waiting for pcode write (%d) to finish\n", mbox);
+ DRM_ERROR("timeout waiting for pcode write of 0x%08x to mbox %x to finish for %ps\n",
+ val, mbox, __builtin_return_address(0));
return -ETIMEDOUT;
}
@@ -8963,8 +8993,8 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
status = gen6_check_mailbox_status(dev_priv);
if (status) {
- DRM_DEBUG_DRIVER("warning: pcode (write) mailbox access failed: %d\n",
- status);
+ DRM_DEBUG_DRIVER("warning: pcode (write of 0x%08x to mbox %x) mailbox access failed for %ps: %d\n",
+ val, mbox, __builtin_return_address(0), status);
return status;
}
@@ -9078,7 +9108,7 @@ static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val)
int intel_gpu_freq(struct drm_i915_private *dev_priv, int val)
{
- if (IS_GEN9(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 9)
return DIV_ROUND_CLOSEST(val * GT_FREQUENCY_MULTIPLIER,
GEN9_FREQ_SCALER);
else if (IS_CHERRYVIEW(dev_priv))
@@ -9091,7 +9121,7 @@ int intel_gpu_freq(struct drm_i915_private *dev_priv, int val)
int intel_freq_opcode(struct drm_i915_private *dev_priv, int val)
{
- if (IS_GEN9(dev_priv))
+ if (INTEL_GEN(dev_priv) >= 9)
return DIV_ROUND_CLOSEST(val * GEN9_FREQ_SCALER,
GT_FREQUENCY_MULTIPLIER);
else if (IS_CHERRYVIEW(dev_priv))
@@ -9113,7 +9143,7 @@ static void __intel_rps_boost_work(struct work_struct *work)
struct drm_i915_gem_request *req = boost->req;
if (!i915_gem_request_completed(req))
- gen6_rps_boost(req->i915, NULL, req->emitted_jiffies);
+ gen6_rps_boost(req, NULL);
i915_gem_request_put(req);
kfree(boost);
@@ -9142,11 +9172,10 @@ void intel_queue_rps_boost_for_request(struct drm_i915_gem_request *req)
void intel_pm_setup(struct drm_i915_private *dev_priv)
{
mutex_init(&dev_priv->rps.hw_lock);
- spin_lock_init(&dev_priv->rps.client_lock);
INIT_DELAYED_WORK(&dev_priv->rps.autoenable_work,
__intel_autoenable_gt_powersave);
- INIT_LIST_HEAD(&dev_priv->rps.clients);
+ atomic_set(&dev_priv->rps.num_waiters, 0);
dev_priv->pm.suspended = false;
atomic_set(&dev_priv->pm.wakeref_count, 0);
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index 559f1ab42bfc..1b31ab002dae 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -315,6 +315,7 @@ static void intel_enable_source_psr1(struct intel_dp *intel_dp)
else
val |= EDP_PSR_TP1_TP2_SEL;
+ val |= I915_READ(EDP_PSR_CTL) & EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK;
I915_WRITE(EDP_PSR_CTL, val);
}
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen9.c b/drivers/gpu/drm/i915/intel_renderstate_gen9.c
index 16a7ec273bd9..7d3ac02f0177 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen9.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen9.c
@@ -20,7 +20,7 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
- * Generated by: intel-gpu-tools-1.8-220-g01153e7
+ * Generated by: intel-gpu-tools-1.19-177-g68e2eab2
*/
#include "intel_renderstate.h"
@@ -873,7 +873,7 @@ static const u32 gen9_null_state_batch[] = {
0x00000000,
0x00000000,
0x78550003,
- 0x00000000,
+ 0x0000000f,
0x00000000,
0x00000000,
0x00000000,
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index acd1da9b62a3..cdf084ef5aae 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1712,6 +1712,9 @@ u32 *intel_ring_begin(struct drm_i915_gem_request *req,
unsigned int total_bytes;
u32 *cs;
+ /* Packets must be qword aligned. */
+ GEM_BUG_ON(num_dwords & 1);
+
total_bytes = bytes + req->reserved_space;
GEM_BUG_ON(total_bytes > ring->effective_size);
@@ -2140,7 +2143,7 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv,
engine->emit_breadcrumb = gen6_sema_emit_breadcrumb;
- num_rings = hweight32(INTEL_INFO(dev_priv)->ring_mask) - 1;
+ num_rings = INTEL_INFO(dev_priv)->num_rings - 1;
if (INTEL_GEN(dev_priv) >= 8) {
engine->emit_breadcrumb_sz += num_rings * 6;
} else {
@@ -2184,8 +2187,7 @@ int intel_init_render_ring_buffer(struct intel_engine_cs *engine)
engine->semaphore.signal = gen8_rcs_signal;
- num_rings =
- hweight32(INTEL_INFO(dev_priv)->ring_mask) - 1;
+ num_rings = INTEL_INFO(dev_priv)->num_rings - 1;
engine->emit_breadcrumb_sz += num_rings * 8;
}
} else if (INTEL_GEN(dev_priv) >= 6) {
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 6aa20ac8cde3..02d8974bf9ab 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -121,6 +121,7 @@ struct intel_engine_hangcheck {
unsigned long action_timestamp;
int deadlock;
struct intel_instdone instdone;
+ struct drm_i915_gem_request *active_request;
bool stalled;
};
@@ -734,4 +735,16 @@ bool intel_engines_are_idle(struct drm_i915_private *dev_priv);
void intel_engines_mark_idle(struct drm_i915_private *i915);
void intel_engines_reset_default_submission(struct drm_i915_private *i915);
+static inline bool
+__intel_engine_can_store_dword(unsigned int gen, unsigned int class)
+{
+ if (gen <= 2)
+ return false; /* uses physical not virtual addresses */
+
+ if (gen == 6 && class == VIDEO_DECODE_CLASS)
+ return false; /* b0rked */
+
+ return true;
+}
+
#endif /* _INTEL_RINGBUFFER_H_ */
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index efe80ed5fd4d..b66d8e136aa3 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -50,10 +50,11 @@
*/
bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
- int power_well_id);
+ enum i915_power_well_id power_well_id);
static struct i915_power_well *
-lookup_power_well(struct drm_i915_private *dev_priv, int power_well_id);
+lookup_power_well(struct drm_i915_private *dev_priv,
+ enum i915_power_well_id power_well_id);
const char *
intel_display_power_domain_str(enum intel_display_power_domain domain)
@@ -168,18 +169,6 @@ static void intel_power_well_put(struct drm_i915_private *dev_priv,
intel_power_well_disable(dev_priv, power_well);
}
-/*
- * We should only use the power well if we explicitly asked the hardware to
- * enable it, so check if it's enabled and also check if we've requested it to
- * be enabled.
- */
-static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- return I915_READ(HSW_PWR_WELL_DRIVER) ==
- (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED);
-}
-
/**
* __intel_display_power_is_enabled - unlocked check for a power domain
* @dev_priv: i915 device instance
@@ -278,7 +267,8 @@ void intel_display_set_init_power(struct drm_i915_private *dev_priv,
* to be enabled, and it will only be disabled if none of the registers is
* requesting it to be enabled.
*/
-static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv)
+static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv,
+ u8 irq_pipe_mask, bool has_vga)
{
struct pci_dev *pdev = dev_priv->drm.pdev;
@@ -292,264 +282,158 @@ static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv)
* sure vgacon can keep working normally without triggering interrupts
* and error messages.
*/
- vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO);
- outb(inb(VGA_MSR_READ), VGA_MSR_WRITE);
- vga_put(pdev, VGA_RSRC_LEGACY_IO);
+ if (has_vga) {
+ vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO);
+ outb(inb(VGA_MSR_READ), VGA_MSR_WRITE);
+ vga_put(pdev, VGA_RSRC_LEGACY_IO);
+ }
- if (IS_BROADWELL(dev_priv))
- gen8_irq_power_well_post_enable(dev_priv,
- 1 << PIPE_C | 1 << PIPE_B);
+ if (irq_pipe_mask)
+ gen8_irq_power_well_post_enable(dev_priv, irq_pipe_mask);
}
-static void hsw_power_well_pre_disable(struct drm_i915_private *dev_priv)
+static void hsw_power_well_pre_disable(struct drm_i915_private *dev_priv,
+ u8 irq_pipe_mask)
{
- if (IS_BROADWELL(dev_priv))
- gen8_irq_power_well_pre_disable(dev_priv,
- 1 << PIPE_C | 1 << PIPE_B);
+ if (irq_pipe_mask)
+ gen8_irq_power_well_pre_disable(dev_priv, irq_pipe_mask);
}
-static void skl_power_well_post_enable(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
+
+static void hsw_wait_for_power_well_enable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
{
- struct pci_dev *pdev = dev_priv->drm.pdev;
+ enum i915_power_well_id id = power_well->id;
+
+ /* Timeout for PW1:10 us, AUX:not specified, other PWs:20 us. */
+ WARN_ON(intel_wait_for_register(dev_priv,
+ HSW_PWR_WELL_CTL_DRIVER(id),
+ HSW_PWR_WELL_CTL_STATE(id),
+ HSW_PWR_WELL_CTL_STATE(id),
+ 1));
+}
+
+static u32 hsw_power_well_requesters(struct drm_i915_private *dev_priv,
+ enum i915_power_well_id id)
+{
+ u32 req_mask = HSW_PWR_WELL_CTL_REQ(id);
+ u32 ret;
+
+ ret = I915_READ(HSW_PWR_WELL_CTL_BIOS(id)) & req_mask ? 1 : 0;
+ ret |= I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) & req_mask ? 2 : 0;
+ ret |= I915_READ(HSW_PWR_WELL_CTL_KVMR) & req_mask ? 4 : 0;
+ ret |= I915_READ(HSW_PWR_WELL_CTL_DEBUG(id)) & req_mask ? 8 : 0;
+
+ return ret;
+}
+
+static void hsw_wait_for_power_well_disable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ enum i915_power_well_id id = power_well->id;
+ bool disabled;
+ u32 reqs;
/*
- * After we re-enable the power well, if we touch VGA register 0x3d5
- * we'll get unclaimed register interrupts. This stops after we write
- * anything to the VGA MSR register. The vgacon module uses this
- * register all the time, so if we unbind our driver and, as a
- * consequence, bind vgacon, we'll get stuck in an infinite loop at
- * console_unlock(). So make here we touch the VGA MSR register, making
- * sure vgacon can keep working normally without triggering interrupts
- * and error messages.
+ * Bspec doesn't require waiting for PWs to get disabled, but still do
+ * this for paranoia. The known cases where a PW will be forced on:
+ * - a KVMR request on any power well via the KVMR request register
+ * - a DMC request on PW1 and MISC_IO power wells via the BIOS and
+ * DEBUG request registers
+ * Skip the wait in case any of the request bits are set and print a
+ * diagnostic message.
*/
- if (power_well->id == SKL_DISP_PW_2) {
- vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO);
- outb(inb(VGA_MSR_READ), VGA_MSR_WRITE);
- vga_put(pdev, VGA_RSRC_LEGACY_IO);
+ wait_for((disabled = !(I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) &
+ HSW_PWR_WELL_CTL_STATE(id))) ||
+ (reqs = hsw_power_well_requesters(dev_priv, id)), 1);
+ if (disabled)
+ return;
- gen8_irq_power_well_post_enable(dev_priv,
- 1 << PIPE_C | 1 << PIPE_B);
- }
+ DRM_DEBUG_KMS("%s forced on (bios:%d driver:%d kvmr:%d debug:%d)\n",
+ power_well->name,
+ !!(reqs & 1), !!(reqs & 2), !!(reqs & 4), !!(reqs & 8));
}
-static void skl_power_well_pre_disable(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
+static void gen9_wait_for_power_well_fuses(struct drm_i915_private *dev_priv,
+ enum skl_power_gate pg)
{
- if (power_well->id == SKL_DISP_PW_2)
- gen8_irq_power_well_pre_disable(dev_priv,
- 1 << PIPE_C | 1 << PIPE_B);
+ /* Timeout 5us for PG#0, for other PGs 1us */
+ WARN_ON(intel_wait_for_register(dev_priv, SKL_FUSE_STATUS,
+ SKL_FUSE_PG_DIST_STATUS(pg),
+ SKL_FUSE_PG_DIST_STATUS(pg), 1));
}
-static void hsw_set_power_well(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well, bool enable)
+static void hsw_power_well_enable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
{
- bool is_enabled, enable_requested;
- uint32_t tmp;
-
- tmp = I915_READ(HSW_PWR_WELL_DRIVER);
- is_enabled = tmp & HSW_PWR_WELL_STATE_ENABLED;
- enable_requested = tmp & HSW_PWR_WELL_ENABLE_REQUEST;
-
- if (enable) {
- if (!enable_requested)
- I915_WRITE(HSW_PWR_WELL_DRIVER,
- HSW_PWR_WELL_ENABLE_REQUEST);
-
- if (!is_enabled) {
- DRM_DEBUG_KMS("Enabling power well\n");
- if (intel_wait_for_register(dev_priv,
- HSW_PWR_WELL_DRIVER,
- HSW_PWR_WELL_STATE_ENABLED,
- HSW_PWR_WELL_STATE_ENABLED,
- 20))
- DRM_ERROR("Timeout enabling power well\n");
- hsw_power_well_post_enable(dev_priv);
- }
+ enum i915_power_well_id id = power_well->id;
+ bool wait_fuses = power_well->hsw.has_fuses;
+ enum skl_power_gate pg;
+ u32 val;
- } else {
- if (enable_requested) {
- hsw_power_well_pre_disable(dev_priv);
- I915_WRITE(HSW_PWR_WELL_DRIVER, 0);
- POSTING_READ(HSW_PWR_WELL_DRIVER);
- DRM_DEBUG_KMS("Requesting to disable the power well\n");
- }
+ if (wait_fuses) {
+ pg = SKL_PW_TO_PG(id);
+ /*
+ * For PW1 we have to wait both for the PW0/PG0 fuse state
+ * before enabling the power well and PW1/PG1's own fuse
+ * state after the enabling. For all other power wells with
+ * fuses we only have to wait for that PW/PG's fuse state
+ * after the enabling.
+ */
+ if (pg == SKL_PG1)
+ gen9_wait_for_power_well_fuses(dev_priv, SKL_PG0);
}
+
+ val = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id));
+ I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id), val | HSW_PWR_WELL_CTL_REQ(id));
+ hsw_wait_for_power_well_enable(dev_priv, power_well);
+
+ if (wait_fuses)
+ gen9_wait_for_power_well_fuses(dev_priv, pg);
+
+ hsw_power_well_post_enable(dev_priv, power_well->hsw.irq_pipe_mask,
+ power_well->hsw.has_vga);
}
-#define SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_E_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_AUX_D) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
- BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define SKL_DISPLAY_DDI_IO_A_E_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_E_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define SKL_DISPLAY_DDI_IO_B_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define SKL_DISPLAY_DDI_IO_C_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define SKL_DISPLAY_DDI_IO_D_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_D_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define SKL_DISPLAY_DC_OFF_POWER_DOMAINS ( \
- SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
- BIT_ULL(POWER_DOMAIN_MODESET) | \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
+static void hsw_power_well_disable(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ enum i915_power_well_id id = power_well->id;
+ u32 val;
-#define BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
- BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_GMBUS) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define BXT_DISPLAY_DC_OFF_POWER_DOMAINS ( \
- BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
- BIT_ULL(POWER_DOMAIN_MODESET) | \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define BXT_DPIO_CMN_A_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_A_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define BXT_DPIO_CMN_BC_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_INIT))
+ hsw_power_well_pre_disable(dev_priv, power_well->hsw.irq_pipe_mask);
-#define GLK_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
- BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define GLK_DISPLAY_DDI_IO_A_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO))
-#define GLK_DISPLAY_DDI_IO_B_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO))
-#define GLK_DISPLAY_DDI_IO_C_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO))
-#define GLK_DPIO_CMN_A_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_A_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define GLK_DPIO_CMN_B_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define GLK_DPIO_CMN_C_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define GLK_DISPLAY_AUX_A_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define GLK_DISPLAY_AUX_B_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define GLK_DISPLAY_AUX_C_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define GLK_DISPLAY_DC_OFF_POWER_DOMAINS ( \
- GLK_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
- BIT_ULL(POWER_DOMAIN_MODESET) | \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
+ val = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id));
+ I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id),
+ val & ~HSW_PWR_WELL_CTL_REQ(id));
+ hsw_wait_for_power_well_disable(dev_priv, power_well);
+}
-#define CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_E_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_AUX_D) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
- BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_DDI_A_IO_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_E_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_DDI_B_IO_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_DDI_C_IO_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_DDI_D_IO_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_D_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_AUX_A_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_AUX_B_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_AUX_C_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_AUX_D_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_D) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_DC_OFF_POWER_DOMAINS ( \
- CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
- BIT_ULL(POWER_DOMAIN_MODESET) | \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
+/*
+ * We should only use the power well if we explicitly asked the hardware to
+ * enable it, so check if it's enabled and also check if we've requested it to
+ * be enabled.
+ */
+static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv,
+ struct i915_power_well *power_well)
+{
+ enum i915_power_well_id id = power_well->id;
+ u32 mask = HSW_PWR_WELL_CTL_REQ(id) | HSW_PWR_WELL_CTL_STATE(id);
+
+ return (I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) & mask) == mask;
+}
static void assert_can_enable_dc9(struct drm_i915_private *dev_priv)
{
+ enum i915_power_well_id id = SKL_DISP_PW_2;
+
WARN_ONCE((I915_READ(DC_STATE_EN) & DC_STATE_EN_DC9),
"DC9 already programmed to be enabled.\n");
WARN_ONCE(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5,
"DC5 still not disabled to enable DC9.\n");
- WARN_ONCE(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on.\n");
+ WARN_ONCE(I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) &
+ HSW_PWR_WELL_CTL_REQ(id),
+ "Power well 2 on.\n");
WARN_ONCE(intel_irqs_enabled(dev_priv),
"Interrupts not disabled yet.\n");
@@ -744,223 +628,39 @@ void skl_disable_dc6(struct drm_i915_private *dev_priv)
gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
}
-static void
-gen9_sanitize_power_well_requests(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- enum skl_disp_power_wells power_well_id = power_well->id;
- u32 val;
- u32 mask;
-
- mask = SKL_POWER_WELL_REQ(power_well_id);
-
- val = I915_READ(HSW_PWR_WELL_KVMR);
- if (WARN_ONCE(val & mask, "Clearing unexpected KVMR request for %s\n",
- power_well->name))
- I915_WRITE(HSW_PWR_WELL_KVMR, val & ~mask);
-
- val = I915_READ(HSW_PWR_WELL_BIOS);
- val |= I915_READ(HSW_PWR_WELL_DEBUG);
-
- if (!(val & mask))
- return;
-
- /*
- * DMC is known to force on the request bits for power well 1 on SKL
- * and BXT and the misc IO power well on SKL but we don't expect any
- * other request bits to be set, so WARN for those.
- */
- if (power_well_id == SKL_DISP_PW_1 ||
- (IS_GEN9_BC(dev_priv) &&
- power_well_id == SKL_DISP_PW_MISC_IO))
- DRM_DEBUG_DRIVER("Clearing auxiliary requests for %s forced on "
- "by DMC\n", power_well->name);
- else
- WARN_ONCE(1, "Clearing unexpected auxiliary requests for %s\n",
- power_well->name);
-
- I915_WRITE(HSW_PWR_WELL_BIOS, val & ~mask);
- I915_WRITE(HSW_PWR_WELL_DEBUG, val & ~mask);
-}
-
-static void skl_set_power_well(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well, bool enable)
-{
- uint32_t tmp, fuse_status;
- uint32_t req_mask, state_mask;
- bool is_enabled, enable_requested, check_fuse_status = false;
-
- tmp = I915_READ(HSW_PWR_WELL_DRIVER);
- fuse_status = I915_READ(SKL_FUSE_STATUS);
-
- switch (power_well->id) {
- case SKL_DISP_PW_1:
- if (intel_wait_for_register(dev_priv,
- SKL_FUSE_STATUS,
- SKL_FUSE_PG0_DIST_STATUS,
- SKL_FUSE_PG0_DIST_STATUS,
- 1)) {
- DRM_ERROR("PG0 not enabled\n");
- return;
- }
- break;
- case SKL_DISP_PW_2:
- if (!(fuse_status & SKL_FUSE_PG1_DIST_STATUS)) {
- DRM_ERROR("PG1 in disabled state\n");
- return;
- }
- break;
- case SKL_DISP_PW_MISC_IO:
- case SKL_DISP_PW_DDI_A_E: /* GLK_DISP_PW_DDI_A, CNL_DISP_PW_DDI_A */
- case SKL_DISP_PW_DDI_B:
- case SKL_DISP_PW_DDI_C:
- case SKL_DISP_PW_DDI_D:
- case GLK_DISP_PW_AUX_A: /* CNL_DISP_PW_AUX_A */
- case GLK_DISP_PW_AUX_B: /* CNL_DISP_PW_AUX_B */
- case GLK_DISP_PW_AUX_C: /* CNL_DISP_PW_AUX_C */
- case CNL_DISP_PW_AUX_D:
- break;
- default:
- WARN(1, "Unknown power well %lu\n", power_well->id);
- return;
- }
-
- req_mask = SKL_POWER_WELL_REQ(power_well->id);
- enable_requested = tmp & req_mask;
- state_mask = SKL_POWER_WELL_STATE(power_well->id);
- is_enabled = tmp & state_mask;
-
- if (!enable && enable_requested)
- skl_power_well_pre_disable(dev_priv, power_well);
-
- if (enable) {
- if (!enable_requested) {
- WARN((tmp & state_mask) &&
- !I915_READ(HSW_PWR_WELL_BIOS),
- "Invalid for power well status to be enabled, unless done by the BIOS, \
- when request is to disable!\n");
- I915_WRITE(HSW_PWR_WELL_DRIVER, tmp | req_mask);
- }
-
- if (!is_enabled) {
- DRM_DEBUG_KMS("Enabling %s\n", power_well->name);
- check_fuse_status = true;
- }
- } else {
- if (enable_requested) {
- I915_WRITE(HSW_PWR_WELL_DRIVER, tmp & ~req_mask);
- POSTING_READ(HSW_PWR_WELL_DRIVER);
- DRM_DEBUG_KMS("Disabling %s\n", power_well->name);
- }
-
- gen9_sanitize_power_well_requests(dev_priv, power_well);
- }
-
- if (wait_for(!!(I915_READ(HSW_PWR_WELL_DRIVER) & state_mask) == enable,
- 1))
- DRM_ERROR("%s %s timeout\n",
- power_well->name, enable ? "enable" : "disable");
-
- if (check_fuse_status) {
- if (power_well->id == SKL_DISP_PW_1) {
- if (intel_wait_for_register(dev_priv,
- SKL_FUSE_STATUS,
- SKL_FUSE_PG1_DIST_STATUS,
- SKL_FUSE_PG1_DIST_STATUS,
- 1))
- DRM_ERROR("PG1 distributing status timeout\n");
- } else if (power_well->id == SKL_DISP_PW_2) {
- if (intel_wait_for_register(dev_priv,
- SKL_FUSE_STATUS,
- SKL_FUSE_PG2_DIST_STATUS,
- SKL_FUSE_PG2_DIST_STATUS,
- 1))
- DRM_ERROR("PG2 distributing status timeout\n");
- }
- }
-
- if (enable && !is_enabled)
- skl_power_well_post_enable(dev_priv, power_well);
-}
-
static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- /* Take over the request bit if set by BIOS. */
- if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE_REQUEST) {
- if (!(I915_READ(HSW_PWR_WELL_DRIVER) &
- HSW_PWR_WELL_ENABLE_REQUEST))
- I915_WRITE(HSW_PWR_WELL_DRIVER,
- HSW_PWR_WELL_ENABLE_REQUEST);
- I915_WRITE(HSW_PWR_WELL_BIOS, 0);
- }
-}
-
-static void hsw_power_well_enable(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- hsw_set_power_well(dev_priv, power_well, true);
-}
-
-static void hsw_power_well_disable(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- hsw_set_power_well(dev_priv, power_well, false);
-}
-
-static bool skl_power_well_enabled(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- uint32_t mask = SKL_POWER_WELL_REQ(power_well->id) |
- SKL_POWER_WELL_STATE(power_well->id);
-
- return (I915_READ(HSW_PWR_WELL_DRIVER) & mask) == mask;
-}
-
-static void skl_power_well_sync_hw(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- uint32_t mask = SKL_POWER_WELL_REQ(power_well->id);
- uint32_t bios_req = I915_READ(HSW_PWR_WELL_BIOS);
+ enum i915_power_well_id id = power_well->id;
+ u32 mask = HSW_PWR_WELL_CTL_REQ(id);
+ u32 bios_req = I915_READ(HSW_PWR_WELL_CTL_BIOS(id));
/* Take over the request bit if set by BIOS. */
if (bios_req & mask) {
- uint32_t drv_req = I915_READ(HSW_PWR_WELL_DRIVER);
+ u32 drv_req = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id));
if (!(drv_req & mask))
- I915_WRITE(HSW_PWR_WELL_DRIVER, drv_req | mask);
- I915_WRITE(HSW_PWR_WELL_BIOS, bios_req & ~mask);
+ I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id), drv_req | mask);
+ I915_WRITE(HSW_PWR_WELL_CTL_BIOS(id), bios_req & ~mask);
}
}
-static void skl_power_well_enable(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- skl_set_power_well(dev_priv, power_well, true);
-}
-
-static void skl_power_well_disable(struct drm_i915_private *dev_priv,
- struct i915_power_well *power_well)
-{
- skl_set_power_well(dev_priv, power_well, false);
-}
-
static void bxt_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- bxt_ddi_phy_init(dev_priv, power_well->data);
+ bxt_ddi_phy_init(dev_priv, power_well->bxt.phy);
}
static void bxt_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- bxt_ddi_phy_uninit(dev_priv, power_well->data);
+ bxt_ddi_phy_uninit(dev_priv, power_well->bxt.phy);
}
static bool bxt_dpio_cmn_power_well_enabled(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- return bxt_ddi_phy_is_enabled(dev_priv, power_well->data);
+ return bxt_ddi_phy_is_enabled(dev_priv, power_well->bxt.phy);
}
static void bxt_verify_ddi_phy_power_wells(struct drm_i915_private *dev_priv)
@@ -969,16 +669,16 @@ static void bxt_verify_ddi_phy_power_wells(struct drm_i915_private *dev_priv)
power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_A);
if (power_well->count > 0)
- bxt_ddi_phy_verify_state(dev_priv, power_well->data);
+ bxt_ddi_phy_verify_state(dev_priv, power_well->bxt.phy);
power_well = lookup_power_well(dev_priv, BXT_DPIO_CMN_BC);
if (power_well->count > 0)
- bxt_ddi_phy_verify_state(dev_priv, power_well->data);
+ bxt_ddi_phy_verify_state(dev_priv, power_well->bxt.phy);
if (IS_GEMINILAKE(dev_priv)) {
power_well = lookup_power_well(dev_priv, GLK_DPIO_CMN_C);
if (power_well->count > 0)
- bxt_ddi_phy_verify_state(dev_priv, power_well->data);
+ bxt_ddi_phy_verify_state(dev_priv, power_well->bxt.phy);
}
}
@@ -1076,7 +776,7 @@ static void i830_pipes_power_well_sync_hw(struct drm_i915_private *dev_priv,
static void vlv_set_power_well(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well, bool enable)
{
- enum punit_power_well power_well_id = power_well->id;
+ enum i915_power_well_id power_well_id = power_well->id;
u32 mask;
u32 state;
u32 ctrl;
@@ -1124,7 +824,7 @@ static void vlv_power_well_disable(struct drm_i915_private *dev_priv,
static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- int power_well_id = power_well->id;
+ enum i915_power_well_id power_well_id = power_well->id;
bool enabled = false;
u32 mask;
u32 state;
@@ -1311,8 +1011,9 @@ static void vlv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
#define POWER_DOMAIN_MASK (GENMASK_ULL(POWER_DOMAIN_NUM - 1, 0))
-static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_priv,
- int power_well_id)
+static struct i915_power_well *
+lookup_power_well(struct drm_i915_private *dev_priv,
+ enum i915_power_well_id power_well_id)
{
struct i915_power_domains *power_domains = &dev_priv->power_domains;
int i;
@@ -1659,7 +1360,7 @@ void chv_phy_powergate_lanes(struct intel_encoder *encoder,
static bool chv_pipe_power_well_enabled(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- enum pipe pipe = power_well->id;
+ enum pipe pipe = PIPE_A;
bool enabled;
u32 state, ctrl;
@@ -1689,7 +1390,7 @@ static void chv_set_pipe_power_well(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well,
bool enable)
{
- enum pipe pipe = power_well->id;
+ enum pipe pipe = PIPE_A;
u32 state;
u32 ctrl;
@@ -1722,7 +1423,7 @@ out:
static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- WARN_ON_ONCE(power_well->id != PIPE_A);
+ WARN_ON_ONCE(power_well->id != CHV_DISP_PW_PIPE_A);
chv_set_pipe_power_well(dev_priv, power_well, true);
@@ -1732,7 +1433,7 @@ static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv,
static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
- WARN_ON_ONCE(power_well->id != PIPE_A);
+ WARN_ON_ONCE(power_well->id != CHV_DISP_PW_PIPE_A);
vlv_display_power_well_deinit(dev_priv);
@@ -1848,37 +1549,13 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
intel_runtime_pm_put(dev_priv);
}
-#define HSW_DISPLAY_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PIPE_B) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C) | \
- BIT_ULL(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_CRT) | /* DDI E */ \
- BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-
-#define BDW_DISPLAY_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PIPE_B) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_CRT) | /* DDI E */ \
- BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
+#define I830_PIPES_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PIPE_A) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
BIT_ULL(POWER_DOMAIN_INIT))
#define VLV_DISPLAY_POWER_DOMAINS ( \
@@ -1961,13 +1638,201 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
BIT_ULL(POWER_DOMAIN_AUX_D) | \
BIT_ULL(POWER_DOMAIN_INIT))
-#define I830_PIPES_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PIPE_A) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B) | \
- BIT_ULL(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
+#define HSW_DISPLAY_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PIPE_B) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_CRT) | /* DDI E */ \
+ BIT_ULL(POWER_DOMAIN_VGA) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+
+#define BDW_DISPLAY_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PIPE_B) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_CRT) | /* DDI E */ \
+ BIT_ULL(POWER_DOMAIN_VGA) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+
+#define SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_E_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_AUX_C) | \
+ BIT_ULL(POWER_DOMAIN_AUX_D) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_VGA) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DDI_IO_A_E_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_E_IO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DDI_IO_B_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DDI_IO_C_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DDI_IO_D_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_D_IO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define SKL_DISPLAY_DC_OFF_POWER_DOMAINS ( \
+ SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
+ BIT_ULL(POWER_DOMAIN_MODESET) | \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+
+#define BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_AUX_C) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_VGA) | \
+ BIT_ULL(POWER_DOMAIN_GMBUS) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define BXT_DISPLAY_DC_OFF_POWER_DOMAINS ( \
+ BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
+ BIT_ULL(POWER_DOMAIN_MODESET) | \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define BXT_DPIO_CMN_A_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_A_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define BXT_DPIO_CMN_BC_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_AUX_C) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+
+#define GLK_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_AUX_C) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_VGA) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define GLK_DISPLAY_DDI_IO_A_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO))
+#define GLK_DISPLAY_DDI_IO_B_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO))
+#define GLK_DISPLAY_DDI_IO_C_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO))
+#define GLK_DPIO_CMN_A_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_A_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define GLK_DPIO_CMN_B_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define GLK_DPIO_CMN_C_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_C) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define GLK_DISPLAY_AUX_A_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define GLK_DISPLAY_AUX_B_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define GLK_DISPLAY_AUX_C_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_C) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define GLK_DISPLAY_DC_OFF_POWER_DOMAINS ( \
+ GLK_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
+ BIT_ULL(POWER_DOMAIN_MODESET) | \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+
+#define CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_AUX_C) | \
+ BIT_ULL(POWER_DOMAIN_AUX_D) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_VGA) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_DDI_A_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_DDI_B_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_DDI_C_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_DDI_D_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_D_IO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_AUX_A_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_AUX_B_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_AUX_C_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_C) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_AUX_D_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_D) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+#define CNL_DISPLAY_DC_OFF_POWER_DOMAINS ( \
+ CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
+ BIT_ULL(POWER_DOMAIN_MODESET) | \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
BIT_ULL(POWER_DOMAIN_INIT))
static const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
@@ -1997,6 +1862,7 @@ static struct i915_power_well i9xx_always_on_power_well[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
};
@@ -2013,11 +1879,13 @@ static struct i915_power_well i830_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "pipes",
.domains = I830_PIPES_POWER_DOMAINS,
.ops = &i830_pipes_power_well_ops,
+ .id = I830_DISP_PW_PIPES,
},
};
@@ -2028,13 +1896,6 @@ static const struct i915_power_well_ops hsw_power_well_ops = {
.is_enabled = hsw_power_well_enabled,
};
-static const struct i915_power_well_ops skl_power_well_ops = {
- .sync_hw = skl_power_well_sync_hw,
- .enable = skl_power_well_enable,
- .disable = skl_power_well_disable,
- .is_enabled = skl_power_well_enabled,
-};
-
static const struct i915_power_well_ops gen9_dc_off_power_well_ops = {
.sync_hw = i9xx_power_well_sync_hw_noop,
.enable = gen9_dc_off_power_well_enable,
@@ -2055,11 +1916,16 @@ static struct i915_power_well hsw_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "display",
.domains = HSW_DISPLAY_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
+ .id = HSW_DISP_PW_GLOBAL,
+ {
+ .hsw.has_vga = true,
+ },
},
};
@@ -2069,11 +1935,17 @@ static struct i915_power_well bdw_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "display",
.domains = BDW_DISPLAY_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
+ .id = HSW_DISP_PW_GLOBAL,
+ {
+ .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
+ .hsw.has_vga = true,
+ },
},
};
@@ -2104,7 +1976,7 @@ static struct i915_power_well vlv_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
- .id = PUNIT_POWER_WELL_ALWAYS_ON,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "display",
@@ -2162,6 +2034,7 @@ static struct i915_power_well chv_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "display",
@@ -2171,7 +2044,7 @@ static struct i915_power_well chv_power_wells[] = {
* required for any pipe to work.
*/
.domains = CHV_DISPLAY_POWER_DOMAINS,
- .id = PIPE_A,
+ .id = CHV_DISP_PW_PIPE_A,
.ops = &chv_pipe_power_well_ops,
},
{
@@ -2189,7 +2062,7 @@ static struct i915_power_well chv_power_wells[] = {
};
bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
- int power_well_id)
+ enum i915_power_well_id power_well_id)
{
struct i915_power_well *power_well;
bool ret;
@@ -2206,20 +2079,23 @@ static struct i915_power_well skl_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
- .id = SKL_DISP_PW_ALWAYS_ON,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "power well 1",
/* Handled by the DMC firmware */
.domains = 0,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_1,
+ {
+ .hsw.has_fuses = true,
+ },
},
{
.name = "MISC IO power well",
/* Handled by the DMC firmware */
.domains = 0,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_MISC_IO,
},
{
@@ -2231,31 +2107,36 @@ static struct i915_power_well skl_power_wells[] = {
{
.name = "power well 2",
.domains = SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_2,
+ {
+ .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
+ .hsw.has_vga = true,
+ .hsw.has_fuses = true,
+ },
},
{
.name = "DDI A/E IO power well",
.domains = SKL_DISPLAY_DDI_IO_A_E_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_A_E,
},
{
.name = "DDI B IO power well",
.domains = SKL_DISPLAY_DDI_IO_B_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_B,
},
{
.name = "DDI C IO power well",
.domains = SKL_DISPLAY_DDI_IO_C_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_C,
},
{
.name = "DDI D IO power well",
.domains = SKL_DISPLAY_DDI_IO_D_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_D,
},
};
@@ -2266,12 +2147,16 @@ static struct i915_power_well bxt_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "power well 1",
.domains = 0,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_1,
+ {
+ .hsw.has_fuses = true,
+ },
},
{
.name = "DC off",
@@ -2282,22 +2167,31 @@ static struct i915_power_well bxt_power_wells[] = {
{
.name = "power well 2",
.domains = BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_2,
+ {
+ .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
+ .hsw.has_vga = true,
+ .hsw.has_fuses = true,
+ },
},
{
.name = "dpio-common-a",
.domains = BXT_DPIO_CMN_A_POWER_DOMAINS,
.ops = &bxt_dpio_cmn_power_well_ops,
.id = BXT_DPIO_CMN_A,
- .data = DPIO_PHY1,
+ {
+ .bxt.phy = DPIO_PHY1,
+ },
},
{
.name = "dpio-common-bc",
.domains = BXT_DPIO_CMN_BC_POWER_DOMAINS,
.ops = &bxt_dpio_cmn_power_well_ops,
.id = BXT_DPIO_CMN_BC,
- .data = DPIO_PHY0,
+ {
+ .bxt.phy = DPIO_PHY0,
+ },
},
};
@@ -2307,13 +2201,17 @@ static struct i915_power_well glk_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "power well 1",
/* Handled by the DMC firmware */
.domains = 0,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_1,
+ {
+ .hsw.has_fuses = true,
+ },
},
{
.name = "DC off",
@@ -2324,64 +2222,75 @@ static struct i915_power_well glk_power_wells[] = {
{
.name = "power well 2",
.domains = GLK_DISPLAY_POWERWELL_2_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_2,
+ {
+ .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
+ .hsw.has_vga = true,
+ .hsw.has_fuses = true,
+ },
},
{
.name = "dpio-common-a",
.domains = GLK_DPIO_CMN_A_POWER_DOMAINS,
.ops = &bxt_dpio_cmn_power_well_ops,
.id = BXT_DPIO_CMN_A,
- .data = DPIO_PHY1,
+ {
+ .bxt.phy = DPIO_PHY1,
+ },
},
{
.name = "dpio-common-b",
.domains = GLK_DPIO_CMN_B_POWER_DOMAINS,
.ops = &bxt_dpio_cmn_power_well_ops,
.id = BXT_DPIO_CMN_BC,
- .data = DPIO_PHY0,
+ {
+ .bxt.phy = DPIO_PHY0,
+ },
},
{
.name = "dpio-common-c",
.domains = GLK_DPIO_CMN_C_POWER_DOMAINS,
.ops = &bxt_dpio_cmn_power_well_ops,
.id = GLK_DPIO_CMN_C,
- .data = DPIO_PHY2,
+ {
+ .bxt.phy = DPIO_PHY2,
+ },
},
{
.name = "AUX A",
.domains = GLK_DISPLAY_AUX_A_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = GLK_DISP_PW_AUX_A,
},
{
.name = "AUX B",
.domains = GLK_DISPLAY_AUX_B_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = GLK_DISP_PW_AUX_B,
},
{
.name = "AUX C",
.domains = GLK_DISPLAY_AUX_C_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = GLK_DISP_PW_AUX_C,
},
{
.name = "DDI A IO power well",
.domains = GLK_DISPLAY_DDI_IO_A_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = GLK_DISP_PW_DDI_A,
},
{
.name = "DDI B IO power well",
.domains = GLK_DISPLAY_DDI_IO_B_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_B,
},
{
.name = "DDI C IO power well",
.domains = GLK_DISPLAY_DDI_IO_C_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_C,
},
};
@@ -2392,36 +2301,40 @@ static struct i915_power_well cnl_power_wells[] = {
.always_on = 1,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
+ .id = I915_DISP_PW_ALWAYS_ON,
},
{
.name = "power well 1",
/* Handled by the DMC firmware */
.domains = 0,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_1,
+ {
+ .hsw.has_fuses = true,
+ },
},
{
.name = "AUX A",
.domains = CNL_DISPLAY_AUX_A_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = CNL_DISP_PW_AUX_A,
},
{
.name = "AUX B",
.domains = CNL_DISPLAY_AUX_B_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = CNL_DISP_PW_AUX_B,
},
{
.name = "AUX C",
.domains = CNL_DISPLAY_AUX_C_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = CNL_DISP_PW_AUX_C,
},
{
.name = "AUX D",
.domains = CNL_DISPLAY_AUX_D_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = CNL_DISP_PW_AUX_D,
},
{
@@ -2433,31 +2346,36 @@ static struct i915_power_well cnl_power_wells[] = {
{
.name = "power well 2",
.domains = CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_2,
+ {
+ .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
+ .hsw.has_vga = true,
+ .hsw.has_fuses = true,
+ },
},
{
.name = "DDI A IO power well",
.domains = CNL_DISPLAY_DDI_A_IO_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = CNL_DISP_PW_DDI_A,
},
{
.name = "DDI B IO power well",
.domains = CNL_DISPLAY_DDI_B_IO_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_B,
},
{
.name = "DDI C IO power well",
.domains = CNL_DISPLAY_DDI_C_IO_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_C,
},
{
.name = "DDI D IO power well",
.domains = CNL_DISPLAY_DDI_D_IO_POWER_DOMAINS,
- .ops = &skl_power_well_ops,
+ .ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_DDI_D,
},
};
@@ -2479,7 +2397,7 @@ static uint32_t get_allowed_dc_mask(const struct drm_i915_private *dev_priv,
int requested_dc;
int max_dc;
- if (IS_GEN9_BC(dev_priv)) {
+ if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
max_dc = 2;
mask = 0;
} else if (IS_GEN9_LP(dev_priv)) {
@@ -2521,6 +2439,22 @@ static uint32_t get_allowed_dc_mask(const struct drm_i915_private *dev_priv,
return mask;
}
+static void assert_power_well_ids_unique(struct drm_i915_private *dev_priv)
+{
+ struct i915_power_domains *power_domains = &dev_priv->power_domains;
+ u64 power_well_ids;
+ int i;
+
+ power_well_ids = 0;
+ for (i = 0; i < power_domains->power_well_count; i++) {
+ enum i915_power_well_id id = power_domains->power_wells[i].id;
+
+ WARN_ON(id >= sizeof(power_well_ids) * 8);
+ WARN_ON(power_well_ids & BIT_ULL(id));
+ power_well_ids |= BIT_ULL(id);
+ }
+}
+
#define set_power_wells(power_domains, __power_wells) ({ \
(power_domains)->power_wells = (__power_wells); \
(power_domains)->power_well_count = ARRAY_SIZE(__power_wells); \
@@ -2572,6 +2506,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
set_power_wells(power_domains, i9xx_always_on_power_well);
}
+ assert_power_well_ids_unique(dev_priv);
+
return 0;
}
@@ -2694,13 +2630,18 @@ static void skl_display_core_uninit(struct drm_i915_private *dev_priv)
mutex_lock(&power_domains->lock);
- well = lookup_power_well(dev_priv, SKL_DISP_PW_MISC_IO);
- intel_power_well_disable(dev_priv, well);
-
+ /*
+ * BSpec says to keep the MISC IO power well enabled here, only
+ * remove our request for power well 1.
+ * Note that even though the driver's request is removed power well 1
+ * may stay enabled after this due to DMC's own request on it.
+ */
well = lookup_power_well(dev_priv, SKL_DISP_PW_1);
intel_power_well_disable(dev_priv, well);
mutex_unlock(&power_domains->lock);
+
+ usleep_range(10, 30); /* 10 us delay per Bspec */
}
void bxt_display_core_init(struct drm_i915_private *dev_priv,
@@ -2751,13 +2692,19 @@ void bxt_display_core_uninit(struct drm_i915_private *dev_priv)
/* The spec doesn't call for removing the reset handshake flag */
- /* Disable PG1 */
+ /*
+ * Disable PW1 (PG1).
+ * Note that even though the driver's request is removed power well 1
+ * may stay enabled after this due to DMC's own request on it.
+ */
mutex_lock(&power_domains->lock);
well = lookup_power_well(dev_priv, SKL_DISP_PW_1);
intel_power_well_disable(dev_priv, well);
mutex_unlock(&power_domains->lock);
+
+ usleep_range(10, 30); /* 10 us delay per Bspec */
}
#define CNL_PROCMON_IDX(val) \
@@ -2796,7 +2743,7 @@ static void cnl_display_core_init(struct drm_i915_private *dev_priv, bool resume
/* 2. Enable Comp */
val = I915_READ(CHICKEN_MISC_2);
- val &= ~COMP_PWR_DOWN;
+ val &= ~CNL_COMP_PWR_DOWN;
I915_WRITE(CHICKEN_MISC_2, val);
val = I915_READ(CNL_PORT_COMP_DW3);
@@ -2821,7 +2768,10 @@ static void cnl_display_core_init(struct drm_i915_private *dev_priv, bool resume
val |= CL_POWER_DOWN_ENABLE;
I915_WRITE(CNL_PORT_CL1CM_DW5, val);
- /* 4. Enable Power Well 1 (PG1) and Aux IO Power */
+ /*
+ * 4. Enable Power Well 1 (PG1).
+ * The AUX IO power wells will be enabled on demand.
+ */
mutex_lock(&power_domains->lock);
well = lookup_power_well(dev_priv, SKL_DISP_PW_1);
intel_power_well_enable(dev_priv, well);
@@ -2853,15 +2803,21 @@ static void cnl_display_core_uninit(struct drm_i915_private *dev_priv)
/* 3. Disable CD clock */
cnl_uninit_cdclk(dev_priv);
- /* 4. Disable Power Well 1 (PG1) and Aux IO Power */
+ /*
+ * 4. Disable Power Well 1 (PG1).
+ * The AUX IO power wells are toggled on demand, so they are already
+ * disabled at this point.
+ */
mutex_lock(&power_domains->lock);
well = lookup_power_well(dev_priv, SKL_DISP_PW_1);
intel_power_well_disable(dev_priv, well);
mutex_unlock(&power_domains->lock);
+ usleep_range(10, 30); /* 10 us delay per Bspec */
+
/* 5. Disable Comp */
val = I915_READ(CHICKEN_MISC_2);
- val |= COMP_PWR_DOWN;
+ val |= CNL_COMP_PWR_DOWN;
I915_WRITE(CHICKEN_MISC_2, val);
}
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 3f8f30b412cd..3dc38c2ef4c3 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -451,23 +451,24 @@ static const char * const cmd_status_names[] = {
"Scaling not supported"
};
-static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd,
- const void *args, int args_len)
+static bool __intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd,
+ const void *args, int args_len,
+ bool unlocked)
{
u8 *buf, status;
struct i2c_msg *msgs;
int i, ret = true;
- /* Would be simpler to allocate both in one go ? */
+ /* Would be simpler to allocate both in one go ? */
buf = kzalloc(args_len * 2 + 2, GFP_KERNEL);
if (!buf)
return false;
msgs = kcalloc(args_len + 3, sizeof(*msgs), GFP_KERNEL);
if (!msgs) {
- kfree(buf);
+ kfree(buf);
return false;
- }
+ }
intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len);
@@ -498,7 +499,10 @@ static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd,
msgs[i+2].len = 1;
msgs[i+2].buf = &status;
- ret = i2c_transfer(intel_sdvo->i2c, msgs, i+3);
+ if (unlocked)
+ ret = i2c_transfer(intel_sdvo->i2c, msgs, i+3);
+ else
+ ret = __i2c_transfer(intel_sdvo->i2c, msgs, i+3);
if (ret < 0) {
DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
ret = false;
@@ -516,6 +520,12 @@ out:
return ret;
}
+static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd,
+ const void *args, int args_len)
+{
+ return __intel_sdvo_write_cmd(intel_sdvo, cmd, args, args_len, true);
+}
+
static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo,
void *response, int response_len)
{
@@ -602,13 +612,13 @@ static int intel_sdvo_get_pixel_multiplier(const struct drm_display_mode *adjust
return 4;
}
-static bool intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo,
- u8 ddc_bus)
+static bool __intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo,
+ u8 ddc_bus)
{
/* This must be the immediately preceding write before the i2c xfer */
- return intel_sdvo_write_cmd(intel_sdvo,
- SDVO_CMD_SET_CONTROL_BUS_SWITCH,
- &ddc_bus, 1);
+ return __intel_sdvo_write_cmd(intel_sdvo,
+ SDVO_CMD_SET_CONTROL_BUS_SWITCH,
+ &ddc_bus, 1, false);
}
static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len)
@@ -996,7 +1006,8 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo,
ssize_t len;
ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
- &pipe_config->base.adjusted_mode);
+ &pipe_config->base.adjusted_mode,
+ false);
if (ret < 0) {
DRM_ERROR("couldn't fill AVI infoframe\n");
return false;
@@ -1343,13 +1354,15 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
}
- if (INTEL_PCH_TYPE(dev_priv) >= PCH_CPT)
+ if (HAS_PCH_CPT(dev_priv))
sdvox |= SDVO_PIPE_SEL_CPT(crtc->pipe);
else
sdvox |= SDVO_PIPE_SEL(crtc->pipe);
- if (crtc_state->has_audio)
+ if (crtc_state->has_audio) {
+ WARN_ON_ONCE(INTEL_GEN(dev_priv) < 4);
sdvox |= SDVO_AUDIO_ENABLE;
+ }
if (INTEL_GEN(dev_priv) >= 4) {
/* done in crtc_mode_set as the dpll_md reg must be written early */
@@ -1479,6 +1492,9 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
if (sdvox & HDMI_COLOR_RANGE_16_235)
pipe_config->limited_color_range = true;
+ if (sdvox & SDVO_AUDIO_ENABLE)
+ pipe_config->has_audio = true;
+
if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ENCODE,
&val, 1)) {
if (val == SDVO_ENCODE_HDMI)
@@ -2192,10 +2208,8 @@ intel_sdvo_connector_duplicate_state(struct drm_connector *connector)
}
static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = intel_sdvo_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.atomic_get_property = intel_sdvo_connector_atomic_get_property,
.atomic_set_property = intel_sdvo_connector_atomic_set_property,
.late_register = intel_sdvo_connector_register,
@@ -2454,6 +2468,7 @@ static bool
intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
{
struct drm_encoder *encoder = &intel_sdvo->base.base;
+ struct drm_i915_private *dev_priv = to_i915(encoder->dev);
struct drm_connector *connector;
struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
struct intel_connector *intel_connector;
@@ -2489,7 +2504,9 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
connector->connector_type = DRM_MODE_CONNECTOR_DVID;
- if (intel_sdvo_is_hdmi_connector(intel_sdvo, device)) {
+ /* gen3 doesn't do the hdmi bits in the SDVO register */
+ if (INTEL_GEN(dev_priv) >= 4 &&
+ intel_sdvo_is_hdmi_connector(intel_sdvo, device)) {
connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
intel_sdvo->is_hdmi = true;
}
@@ -2925,7 +2942,7 @@ static int intel_sdvo_ddc_proxy_xfer(struct i2c_adapter *adapter,
{
struct intel_sdvo *sdvo = adapter->algo_data;
- if (!intel_sdvo_set_control_bus_switch(sdvo, sdvo->ddc_bus))
+ if (!__intel_sdvo_set_control_bus_switch(sdvo, sdvo->ddc_bus))
return -EIO;
return sdvo->i2c->algo->master_xfer(sdvo->i2c, msgs, num);
@@ -2942,6 +2959,33 @@ static const struct i2c_algorithm intel_sdvo_ddc_proxy = {
.functionality = intel_sdvo_ddc_proxy_func
};
+static void proxy_lock_bus(struct i2c_adapter *adapter,
+ unsigned int flags)
+{
+ struct intel_sdvo *sdvo = adapter->algo_data;
+ sdvo->i2c->lock_ops->lock_bus(sdvo->i2c, flags);
+}
+
+static int proxy_trylock_bus(struct i2c_adapter *adapter,
+ unsigned int flags)
+{
+ struct intel_sdvo *sdvo = adapter->algo_data;
+ return sdvo->i2c->lock_ops->trylock_bus(sdvo->i2c, flags);
+}
+
+static void proxy_unlock_bus(struct i2c_adapter *adapter,
+ unsigned int flags)
+{
+ struct intel_sdvo *sdvo = adapter->algo_data;
+ sdvo->i2c->lock_ops->unlock_bus(sdvo->i2c, flags);
+}
+
+const struct i2c_lock_operations proxy_lock_ops = {
+ .lock_bus = proxy_lock_bus,
+ .trylock_bus = proxy_trylock_bus,
+ .unlock_bus = proxy_unlock_bus,
+};
+
static bool
intel_sdvo_init_ddc_proxy(struct intel_sdvo *sdvo,
struct drm_i915_private *dev_priv)
@@ -2954,6 +2998,7 @@ intel_sdvo_init_ddc_proxy(struct intel_sdvo *sdvo,
sdvo->ddc.dev.parent = &pdev->dev;
sdvo->ddc.algo_data = sdvo;
sdvo->ddc.algo = &intel_sdvo_ddc_proxy;
+ sdvo->ddc.lock_ops = &proxy_lock_ops;
return i2c_add_adapter(&sdvo->ddc) == 0;
}
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 0c650c2cbca8..524933b01483 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -30,6 +30,7 @@
* support.
*/
#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_rect.h>
@@ -176,7 +177,7 @@ void intel_pipe_update_start(struct intel_crtc *crtc)
* re-enables interrupts and verifies the update was actually completed
* before a vblank using the value of @start_vbl_count.
*/
-void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work)
+void intel_pipe_update_end(struct intel_crtc *crtc)
{
enum pipe pipe = crtc->pipe;
int scanline_end = intel_get_crtc_scanline(crtc);
@@ -184,12 +185,6 @@ void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work
ktime_t end_vbl_time = ktime_get();
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- if (work) {
- work->flip_queued_vblank = end_vbl_count;
- smp_mb__before_atomic();
- atomic_set(&work->pending, 1);
- }
-
trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end);
/* We're still in the vblank-evade critical section, this can't race.
@@ -244,6 +239,7 @@ skl_update_plane(struct intel_plane *plane,
u32 surf_addr = plane_state->main.offset;
unsigned int rotation = plane_state->base.rotation;
u32 stride = skl_plane_stride(fb, 0, rotation);
+ u32 aux_stride = skl_plane_stride(fb, 1, rotation);
int crtc_x = plane_state->base.dst.x1;
int crtc_y = plane_state->base.dst.y1;
uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
@@ -262,7 +258,7 @@ skl_update_plane(struct intel_plane *plane,
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
- if (IS_GEMINILAKE(dev_priv)) {
+ if (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) {
I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
PLANE_COLOR_PIPE_GAMMA_ENABLE |
PLANE_COLOR_PIPE_CSC_ENABLE |
@@ -278,6 +274,10 @@ skl_update_plane(struct intel_plane *plane,
I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
+ I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
+ (plane_state->aux.offset - surf_addr) | aux_stride);
+ I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
+ (plane_state->aux.y << 16) | plane_state->aux.x);
/* program plane scaler */
if (plane_state->scaler_id >= 0) {
@@ -1038,6 +1038,12 @@ static const uint32_t g4x_plane_formats[] = {
DRM_FORMAT_VYUY,
};
+static const uint64_t i9xx_plane_format_modifiers[] = {
+ I915_FORMAT_MOD_X_TILED,
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_FORMAT_MOD_INVALID
+};
+
static const uint32_t snb_plane_formats[] = {
DRM_FORMAT_XBGR8888,
DRM_FORMAT_XRGB8888,
@@ -1073,6 +1079,122 @@ static uint32_t skl_plane_formats[] = {
DRM_FORMAT_VYUY,
};
+static const uint64_t skl_plane_format_modifiers[] = {
+ I915_FORMAT_MOD_X_TILED,
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_FORMAT_MOD_INVALID
+};
+
+static bool g4x_sprite_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+ switch (format) {
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_YVYU:
+ case DRM_FORMAT_UYVY:
+ case DRM_FORMAT_VYUY:
+ if (modifier == DRM_FORMAT_MOD_LINEAR ||
+ modifier == I915_FORMAT_MOD_X_TILED)
+ return true;
+ /* fall through */
+ default:
+ return false;
+ }
+}
+
+static bool vlv_sprite_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+ switch (format) {
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_YVYU:
+ case DRM_FORMAT_UYVY:
+ case DRM_FORMAT_VYUY:
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_XBGR2101010:
+ case DRM_FORMAT_ABGR2101010:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_ABGR8888:
+ if (modifier == DRM_FORMAT_MOD_LINEAR ||
+ modifier == I915_FORMAT_MOD_X_TILED)
+ return true;
+ /* fall through */
+ default:
+ return false;
+ }
+}
+
+static bool skl_sprite_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+ /* This is the same as primary plane since SKL has universal planes */
+ switch (format) {
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_XRGB2101010:
+ case DRM_FORMAT_XBGR2101010:
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_YVYU:
+ case DRM_FORMAT_UYVY:
+ case DRM_FORMAT_VYUY:
+ if (modifier == I915_FORMAT_MOD_Yf_TILED)
+ return true;
+ /* fall through */
+ case DRM_FORMAT_C8:
+ if (modifier == DRM_FORMAT_MOD_LINEAR ||
+ modifier == I915_FORMAT_MOD_X_TILED ||
+ modifier == I915_FORMAT_MOD_Y_TILED)
+ return true;
+ /* fall through */
+ default:
+ return false;
+ }
+}
+
+static bool intel_sprite_plane_format_mod_supported(struct drm_plane *plane,
+ uint32_t format,
+ uint64_t modifier)
+{
+ struct drm_i915_private *dev_priv = to_i915(plane->dev);
+
+ if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID))
+ return false;
+
+ if ((modifier >> 56) != DRM_FORMAT_MOD_VENDOR_INTEL &&
+ modifier != DRM_FORMAT_MOD_LINEAR)
+ return false;
+
+ if (INTEL_GEN(dev_priv) >= 9)
+ return skl_sprite_plane_format_mod_supported(plane, format, modifier);
+ else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+ return vlv_sprite_plane_format_mod_supported(plane, format, modifier);
+ else
+ return g4x_sprite_plane_format_mod_supported(plane, format, modifier);
+
+ unreachable();
+}
+
+static const struct drm_plane_funcs intel_sprite_plane_funcs = {
+ .update_plane = drm_atomic_helper_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
+ .destroy = intel_plane_destroy,
+ .atomic_get_property = intel_plane_atomic_get_property,
+ .atomic_set_property = intel_plane_atomic_set_property,
+ .atomic_duplicate_state = intel_plane_duplicate_state,
+ .atomic_destroy_state = intel_plane_destroy_state,
+ .format_mod_supported = intel_sprite_plane_format_mod_supported,
+};
+
struct intel_plane *
intel_sprite_plane_create(struct drm_i915_private *dev_priv,
enum pipe pipe, int plane)
@@ -1081,6 +1203,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
struct intel_plane_state *state = NULL;
unsigned long possible_crtcs;
const uint32_t *plane_formats;
+ const uint64_t *modifiers;
unsigned int supported_rotations;
int num_plane_formats;
int ret;
@@ -1098,7 +1221,17 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
}
intel_plane->base.state = &state->base;
- if (INTEL_GEN(dev_priv) >= 9) {
+ if (INTEL_GEN(dev_priv) >= 10) {
+ intel_plane->can_scale = true;
+ state->scaler_id = -1;
+
+ intel_plane->update_plane = skl_update_plane;
+ intel_plane->disable_plane = skl_disable_plane;
+
+ plane_formats = skl_plane_formats;
+ num_plane_formats = ARRAY_SIZE(skl_plane_formats);
+ modifiers = skl_plane_format_modifiers;
+ } else if (INTEL_GEN(dev_priv) >= 9) {
intel_plane->can_scale = true;
state->scaler_id = -1;
@@ -1107,6 +1240,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
plane_formats = skl_plane_formats;
num_plane_formats = ARRAY_SIZE(skl_plane_formats);
+ modifiers = skl_plane_format_modifiers;
} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
intel_plane->can_scale = false;
intel_plane->max_downscale = 1;
@@ -1116,6 +1250,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
plane_formats = vlv_plane_formats;
num_plane_formats = ARRAY_SIZE(vlv_plane_formats);
+ modifiers = i9xx_plane_format_modifiers;
} else if (INTEL_GEN(dev_priv) >= 7) {
if (IS_IVYBRIDGE(dev_priv)) {
intel_plane->can_scale = true;
@@ -1130,6 +1265,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
plane_formats = snb_plane_formats;
num_plane_formats = ARRAY_SIZE(snb_plane_formats);
+ modifiers = i9xx_plane_format_modifiers;
} else {
intel_plane->can_scale = true;
intel_plane->max_downscale = 16;
@@ -1137,6 +1273,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
intel_plane->update_plane = g4x_update_plane;
intel_plane->disable_plane = g4x_disable_plane;
+ modifiers = i9xx_plane_format_modifiers;
if (IS_GEN6(dev_priv)) {
plane_formats = snb_plane_formats;
num_plane_formats = ARRAY_SIZE(snb_plane_formats);
@@ -1169,14 +1306,16 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
if (INTEL_GEN(dev_priv) >= 9)
ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
- possible_crtcs, &intel_plane_funcs,
+ possible_crtcs, &intel_sprite_plane_funcs,
plane_formats, num_plane_formats,
+ modifiers,
DRM_PLANE_TYPE_OVERLAY,
"plane %d%c", plane + 2, pipe_name(pipe));
else
ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
- possible_crtcs, &intel_plane_funcs,
+ possible_crtcs, &intel_sprite_plane_funcs,
plane_formats, num_plane_formats,
+ modifiers,
DRM_PLANE_TYPE_OVERLAY,
"sprite %c", sprite_name(pipe, plane));
if (ret)
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 784df024e230..906893c006d8 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1407,11 +1407,9 @@ intel_tv_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs intel_tv_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.late_register = intel_connector_register,
.early_unregister = intel_connector_unregister,
.destroy = intel_tv_destroy,
- .set_property = drm_atomic_helper_connector_set_property,
.fill_modes = drm_helper_probe_single_connector_modes,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
index 27e072cc96eb..0178ba42a0e5 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -94,7 +94,7 @@ void intel_uc_sanitize_options(struct drm_i915_private *dev_priv)
i915.enable_guc_submission = HAS_GUC_SCHED(dev_priv);
}
-static void guc_write_irq_trigger(struct intel_guc *guc)
+static void gen8_guc_raise_irq(struct intel_guc *guc)
{
struct drm_i915_private *dev_priv = guc_to_i915(guc);
@@ -109,7 +109,7 @@ void intel_uc_init_early(struct drm_i915_private *dev_priv)
mutex_init(&guc->send_mutex);
guc->send = intel_guc_send_nop;
- guc->notify = guc_write_irq_trigger;
+ guc->notify = gen8_guc_raise_irq;
}
static void fetch_uc_fw(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 9882724bc2b6..1d7b879cc68c 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -643,7 +643,7 @@ find_fw_domain(struct drm_i915_private *dev_priv, u32 offset)
{ .start = (s), .end = (e), .domains = (d) }
#define HAS_FWTABLE(dev_priv) \
- (IS_GEN9(dev_priv) || \
+ (INTEL_GEN(dev_priv) >= 9 || \
IS_CHERRYVIEW(dev_priv) || \
IS_VALLEYVIEW(dev_priv))
@@ -1072,7 +1072,7 @@ static void intel_uncore_fw_domains_init(struct drm_i915_private *dev_priv)
dev_priv->uncore.fw_clear = _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL);
}
- if (IS_GEN9(dev_priv)) {
+ if (INTEL_GEN(dev_priv) >= 9) {
dev_priv->uncore.funcs.force_wake_get = fw_domains_get;
dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
@@ -1497,7 +1497,6 @@ static int gen6_reset_engines(struct drm_i915_private *dev_priv,
[VECS] = GEN6_GRDOM_VECS,
};
u32 hw_mask;
- int ret;
if (engine_mask == ALL_ENGINES) {
hw_mask = GEN6_GRDOM_FULL;
@@ -1509,11 +1508,7 @@ static int gen6_reset_engines(struct drm_i915_private *dev_priv,
hw_mask |= hw_engine_mask[engine->id];
}
- ret = gen6_hw_domain_reset(dev_priv, hw_mask);
-
- intel_uncore_forcewake_reset(dev_priv, true);
-
- return ret;
+ return gen6_hw_domain_reset(dev_priv, hw_mask);
}
/**
@@ -1719,6 +1714,17 @@ bool intel_has_gpu_reset(struct drm_i915_private *dev_priv)
return intel_get_gpu_reset(dev_priv) != NULL;
}
+/*
+ * When GuC submission is enabled, GuC manages ELSP and can initiate the
+ * engine reset too. For now, fall back to full GPU reset if it is enabled.
+ */
+bool intel_has_reset_engine(struct drm_i915_private *dev_priv)
+{
+ return (dev_priv->info.has_reset_engine &&
+ !dev_priv->guc.execbuf_client &&
+ i915.reset >= 2);
+}
+
int intel_guc_reset(struct drm_i915_private *dev_priv)
{
int ret;
diff --git a/drivers/gpu/drm/i915/selftests/huge_gem_object.c b/drivers/gpu/drm/i915/selftests/huge_gem_object.c
index caf76af36aba..c5c7e8efbdd3 100644
--- a/drivers/gpu/drm/i915/selftests/huge_gem_object.c
+++ b/drivers/gpu/drm/i915/selftests/huge_gem_object.c
@@ -111,6 +111,7 @@ huge_gem_object(struct drm_i915_private *i915,
dma_addr_t dma_size)
{
struct drm_i915_gem_object *obj;
+ unsigned int cache_level;
GEM_BUG_ON(!phys_size || phys_size > dma_size);
GEM_BUG_ON(!IS_ALIGNED(phys_size, PAGE_SIZE));
@@ -128,9 +129,8 @@ huge_gem_object(struct drm_i915_private *i915,
obj->base.read_domains = I915_GEM_DOMAIN_CPU;
obj->base.write_domain = I915_GEM_DOMAIN_CPU;
- obj->cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
- obj->cache_coherent = i915_gem_object_is_coherent(obj);
- obj->cache_dirty = !obj->cache_coherent;
+ cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
+ i915_gem_object_set_cache_coherency(obj, cache_level);
obj->scratch = phys_size;
return obj;
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c b/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c
index 95d4aebc0181..35d778d70626 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_coherency.c
@@ -241,7 +241,7 @@ static bool always_valid(struct drm_i915_private *i915)
static bool needs_mi_store_dword(struct drm_i915_private *i915)
{
- return igt_can_mi_store_dword_imm(i915);
+ return intel_engine_can_store_dword(i915->engine[RCS]);
}
static const struct igt_coherency_mode {
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
index 12b85b3278cd..fb0a58fc8348 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
@@ -38,8 +38,6 @@ gpu_fill_dw(struct i915_vma *vma, u64 offset, unsigned long count, u32 value)
u32 *cmd;
int err;
- GEM_BUG_ON(!igt_can_mi_store_dword_imm(vma->vm->i915));
-
size = (4 * count + 1) * sizeof(u32);
size = round_up(size, PAGE_SIZE);
obj = i915_gem_object_create_internal(vma->vm->i915, size);
@@ -123,6 +121,7 @@ static int gpu_fill(struct drm_i915_gem_object *obj,
int err;
GEM_BUG_ON(obj->base.size > vm->total);
+ GEM_BUG_ON(!intel_engine_can_store_dword(engine));
vma = i915_vma_instance(obj, vm, NULL);
if (IS_ERR(vma))
@@ -359,6 +358,9 @@ static int igt_ctx_exec(void *arg)
}
for_each_engine(engine, i915, id) {
+ if (!intel_engine_can_store_dword(engine))
+ continue;
+
if (!obj) {
obj = create_test_object(ctx, file, &objects);
if (IS_ERR(obj)) {
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 50710e3f1caa..6b132caffa18 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -197,6 +197,9 @@ static int lowlevel_hole(struct drm_i915_private *i915,
{
I915_RND_STATE(seed_prng);
unsigned int size;
+ struct i915_vma mock_vma;
+
+ memset(&mock_vma, 0, sizeof(struct i915_vma));
/* Keep creating larger objects until one cannot fit into the hole */
for (size = 12; (hole_end - hole_start) >> size; size++) {
@@ -255,8 +258,11 @@ static int lowlevel_hole(struct drm_i915_private *i915,
vm->allocate_va_range(vm, addr, BIT_ULL(size)))
break;
- vm->insert_entries(vm, obj->mm.pages, addr,
- I915_CACHE_NONE, 0);
+ mock_vma.pages = obj->mm.pages;
+ mock_vma.node.size = BIT_ULL(size);
+ mock_vma.node.start = addr;
+
+ vm->insert_entries(vm, &mock_vma, I915_CACHE_NONE, 0);
}
count = n;
diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
index fb9072d5877f..2e86ec136b35 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -186,16 +186,20 @@ static int igt_vma_create(void *arg)
goto end;
}
- list_for_each_entry_safe(ctx, cn, &contexts, link)
+ list_for_each_entry_safe(ctx, cn, &contexts, link) {
+ list_del_init(&ctx->link);
mock_context_close(ctx);
+ }
}
end:
/* Final pass to lookup all created contexts */
err = create_vmas(i915, &objects, &contexts);
out:
- list_for_each_entry_safe(ctx, cn, &contexts, link)
+ list_for_each_entry_safe(ctx, cn, &contexts, link) {
+ list_del_init(&ctx->link);
mock_context_close(ctx);
+ }
list_for_each_entry_safe(obj, on, &objects, st_link)
i915_gem_object_put(obj);
diff --git a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c
index aa31d6c0cdfb..02e52a146ed8 100644
--- a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c
+++ b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c
@@ -22,8 +22,13 @@
*
*/
+#include <linux/kthread.h>
+
#include "../i915_selftest.h"
+#include "mock_context.h"
+#include "mock_drm.h"
+
struct hang {
struct drm_i915_private *i915;
struct drm_i915_gem_object *hws;
@@ -248,9 +253,6 @@ static int igt_hang_sanitycheck(void *arg)
/* Basic check that we can execute our hanging batch */
- if (!igt_can_mi_store_dword_imm(i915))
- return 0;
-
mutex_lock(&i915->drm.struct_mutex);
err = hang_init(&h, i915);
if (err)
@@ -259,6 +261,9 @@ static int igt_hang_sanitycheck(void *arg)
for_each_engine(engine, i915, id) {
long timeout;
+ if (!intel_engine_can_store_dword(engine))
+ continue;
+
rq = hang_create_request(&h, engine, i915->kernel_context);
if (IS_ERR(rq)) {
err = PTR_ERR(rq);
@@ -292,6 +297,37 @@ unlock:
return err;
}
+static void global_reset_lock(struct drm_i915_private *i915)
+{
+ struct intel_engine_cs *engine;
+ enum intel_engine_id id;
+
+ while (test_and_set_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags))
+ wait_event(i915->gpu_error.reset_queue,
+ !test_bit(I915_RESET_BACKOFF,
+ &i915->gpu_error.flags));
+
+ for_each_engine(engine, i915, id) {
+ while (test_and_set_bit(I915_RESET_ENGINE + id,
+ &i915->gpu_error.flags))
+ wait_on_bit(&i915->gpu_error.flags,
+ I915_RESET_ENGINE + id,
+ TASK_UNINTERRUPTIBLE);
+ }
+}
+
+static void global_reset_unlock(struct drm_i915_private *i915)
+{
+ struct intel_engine_cs *engine;
+ enum intel_engine_id id;
+
+ for_each_engine(engine, i915, id)
+ clear_bit(I915_RESET_ENGINE + id, &i915->gpu_error.flags);
+
+ clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+ wake_up_all(&i915->gpu_error.reset_queue);
+}
+
static int igt_global_reset(void *arg)
{
struct drm_i915_private *i915 = arg;
@@ -300,13 +336,13 @@ static int igt_global_reset(void *arg)
/* Check that we can issue a global GPU reset */
- set_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+ global_reset_lock(i915);
set_bit(I915_RESET_HANDOFF, &i915->gpu_error.flags);
mutex_lock(&i915->drm.struct_mutex);
reset_count = i915_reset_count(&i915->gpu_error);
- i915_reset(i915);
+ i915_reset(i915, I915_RESET_QUIET);
if (i915_reset_count(&i915->gpu_error) == reset_count) {
pr_err("No GPU reset recorded!\n");
@@ -315,7 +351,214 @@ static int igt_global_reset(void *arg)
mutex_unlock(&i915->drm.struct_mutex);
GEM_BUG_ON(test_bit(I915_RESET_HANDOFF, &i915->gpu_error.flags));
- clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+ global_reset_unlock(i915);
+
+ if (i915_terminally_wedged(&i915->gpu_error))
+ err = -EIO;
+
+ return err;
+}
+
+static int igt_reset_engine(void *arg)
+{
+ struct drm_i915_private *i915 = arg;
+ struct intel_engine_cs *engine;
+ enum intel_engine_id id;
+ unsigned int reset_count, reset_engine_count;
+ int err = 0;
+
+ /* Check that we can issue a global GPU and engine reset */
+
+ if (!intel_has_reset_engine(i915))
+ return 0;
+
+ for_each_engine(engine, i915, id) {
+ set_bit(I915_RESET_ENGINE + engine->id, &i915->gpu_error.flags);
+ reset_count = i915_reset_count(&i915->gpu_error);
+ reset_engine_count = i915_reset_engine_count(&i915->gpu_error,
+ engine);
+
+ err = i915_reset_engine(engine, I915_RESET_QUIET);
+ if (err) {
+ pr_err("i915_reset_engine failed\n");
+ break;
+ }
+
+ if (i915_reset_count(&i915->gpu_error) != reset_count) {
+ pr_err("Full GPU reset recorded! (engine reset expected)\n");
+ err = -EINVAL;
+ break;
+ }
+
+ if (i915_reset_engine_count(&i915->gpu_error, engine) ==
+ reset_engine_count) {
+ pr_err("No %s engine reset recorded!\n", engine->name);
+ err = -EINVAL;
+ break;
+ }
+
+ clear_bit(I915_RESET_ENGINE + engine->id,
+ &i915->gpu_error.flags);
+ }
+
+ if (i915_terminally_wedged(&i915->gpu_error))
+ err = -EIO;
+
+ return err;
+}
+
+static int active_engine(void *data)
+{
+ struct intel_engine_cs *engine = data;
+ struct drm_i915_gem_request *rq[2] = {};
+ struct i915_gem_context *ctx[2];
+ struct drm_file *file;
+ unsigned long count = 0;
+ int err = 0;
+
+ file = mock_file(engine->i915);
+ if (IS_ERR(file))
+ return PTR_ERR(file);
+
+ mutex_lock(&engine->i915->drm.struct_mutex);
+ ctx[0] = live_context(engine->i915, file);
+ mutex_unlock(&engine->i915->drm.struct_mutex);
+ if (IS_ERR(ctx[0])) {
+ err = PTR_ERR(ctx[0]);
+ goto err_file;
+ }
+
+ mutex_lock(&engine->i915->drm.struct_mutex);
+ ctx[1] = live_context(engine->i915, file);
+ mutex_unlock(&engine->i915->drm.struct_mutex);
+ if (IS_ERR(ctx[1])) {
+ err = PTR_ERR(ctx[1]);
+ i915_gem_context_put(ctx[0]);
+ goto err_file;
+ }
+
+ while (!kthread_should_stop()) {
+ unsigned int idx = count++ & 1;
+ struct drm_i915_gem_request *old = rq[idx];
+ struct drm_i915_gem_request *new;
+
+ mutex_lock(&engine->i915->drm.struct_mutex);
+ new = i915_gem_request_alloc(engine, ctx[idx]);
+ if (IS_ERR(new)) {
+ mutex_unlock(&engine->i915->drm.struct_mutex);
+ err = PTR_ERR(new);
+ break;
+ }
+
+ rq[idx] = i915_gem_request_get(new);
+ i915_add_request(new);
+ mutex_unlock(&engine->i915->drm.struct_mutex);
+
+ if (old) {
+ i915_wait_request(old, 0, MAX_SCHEDULE_TIMEOUT);
+ i915_gem_request_put(old);
+ }
+ }
+
+ for (count = 0; count < ARRAY_SIZE(rq); count++)
+ i915_gem_request_put(rq[count]);
+
+err_file:
+ mock_file_free(engine->i915, file);
+ return err;
+}
+
+static int igt_reset_active_engines(void *arg)
+{
+ struct drm_i915_private *i915 = arg;
+ struct intel_engine_cs *engine, *active;
+ enum intel_engine_id id, tmp;
+ int err = 0;
+
+ /* Check that issuing a reset on one engine does not interfere
+ * with any other engine.
+ */
+
+ if (!intel_has_reset_engine(i915))
+ return 0;
+
+ for_each_engine(engine, i915, id) {
+ struct task_struct *threads[I915_NUM_ENGINES];
+ unsigned long resets[I915_NUM_ENGINES];
+ unsigned long global = i915_reset_count(&i915->gpu_error);
+ IGT_TIMEOUT(end_time);
+
+ memset(threads, 0, sizeof(threads));
+ for_each_engine(active, i915, tmp) {
+ struct task_struct *tsk;
+
+ if (active == engine)
+ continue;
+
+ resets[tmp] = i915_reset_engine_count(&i915->gpu_error,
+ active);
+
+ tsk = kthread_run(active_engine, active,
+ "igt/%s", active->name);
+ if (IS_ERR(tsk)) {
+ err = PTR_ERR(tsk);
+ goto unwind;
+ }
+
+ threads[tmp] = tsk;
+ get_task_struct(tsk);
+ }
+
+ set_bit(I915_RESET_ENGINE + engine->id, &i915->gpu_error.flags);
+ do {
+ err = i915_reset_engine(engine, I915_RESET_QUIET);
+ if (err) {
+ pr_err("i915_reset_engine(%s) failed, err=%d\n",
+ engine->name, err);
+ break;
+ }
+ } while (time_before(jiffies, end_time));
+ clear_bit(I915_RESET_ENGINE + engine->id,
+ &i915->gpu_error.flags);
+
+unwind:
+ for_each_engine(active, i915, tmp) {
+ int ret;
+
+ if (!threads[tmp])
+ continue;
+
+ ret = kthread_stop(threads[tmp]);
+ if (ret) {
+ pr_err("kthread for active engine %s failed, err=%d\n",
+ active->name, ret);
+ if (!err)
+ err = ret;
+ }
+ put_task_struct(threads[tmp]);
+
+ if (resets[tmp] != i915_reset_engine_count(&i915->gpu_error,
+ active)) {
+ pr_err("Innocent engine %s was reset (count=%ld)\n",
+ active->name,
+ i915_reset_engine_count(&i915->gpu_error,
+ active) - resets[tmp]);
+ err = -EIO;
+ }
+ }
+
+ if (global != i915_reset_count(&i915->gpu_error)) {
+ pr_err("Global reset (count=%ld)!\n",
+ i915_reset_count(&i915->gpu_error) - global);
+ err = -EIO;
+ }
+
+ if (err)
+ break;
+
+ cond_resched();
+ }
+
if (i915_terminally_wedged(&i915->gpu_error))
err = -EIO;
@@ -356,9 +599,12 @@ static int igt_wait_reset(void *arg)
long timeout;
int err;
+ if (!intel_engine_can_store_dword(i915->engine[RCS]))
+ return 0;
+
/* Check that we detect a stuck waiter and issue a reset */
- set_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+ global_reset_lock(i915);
mutex_lock(&i915->drm.struct_mutex);
err = hang_init(&h, i915);
@@ -403,7 +649,7 @@ fini:
hang_fini(&h);
unlock:
mutex_unlock(&i915->drm.struct_mutex);
- clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+ global_reset_unlock(i915);
if (i915_terminally_wedged(&i915->gpu_error))
return -EIO;
@@ -421,10 +667,8 @@ static int igt_reset_queue(void *arg)
/* Check that we replay pending requests following a hang */
- if (!igt_can_mi_store_dword_imm(i915))
- return 0;
+ global_reset_lock(i915);
- set_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
mutex_lock(&i915->drm.struct_mutex);
err = hang_init(&h, i915);
if (err)
@@ -435,6 +679,9 @@ static int igt_reset_queue(void *arg)
IGT_TIMEOUT(end_time);
unsigned int count;
+ if (!intel_engine_can_store_dword(engine))
+ continue;
+
prev = hang_create_request(&h, engine, i915->kernel_context);
if (IS_ERR(prev)) {
err = PTR_ERR(prev);
@@ -471,7 +718,7 @@ static int igt_reset_queue(void *arg)
reset_count = fake_hangcheck(prev);
- i915_reset(i915);
+ i915_reset(i915, I915_RESET_QUIET);
GEM_BUG_ON(test_bit(I915_RESET_HANDOFF,
&i915->gpu_error.flags));
@@ -518,7 +765,7 @@ fini:
hang_fini(&h);
unlock:
mutex_unlock(&i915->drm.struct_mutex);
- clear_bit(I915_RESET_BACKOFF, &i915->gpu_error.flags);
+ global_reset_unlock(i915);
if (i915_terminally_wedged(&i915->gpu_error))
return -EIO;
@@ -526,13 +773,83 @@ unlock:
return err;
}
+static int igt_handle_error(void *arg)
+{
+ struct drm_i915_private *i915 = arg;
+ struct intel_engine_cs *engine = i915->engine[RCS];
+ struct hang h;
+ struct drm_i915_gem_request *rq;
+ struct i915_gpu_state *error;
+ int err;
+
+ /* Check that we can issue a global GPU and engine reset */
+
+ if (!intel_has_reset_engine(i915))
+ return 0;
+
+ if (!intel_engine_can_store_dword(i915->engine[RCS]))
+ return 0;
+
+ mutex_lock(&i915->drm.struct_mutex);
+
+ err = hang_init(&h, i915);
+ if (err)
+ goto err_unlock;
+
+ rq = hang_create_request(&h, engine, i915->kernel_context);
+ if (IS_ERR(rq)) {
+ err = PTR_ERR(rq);
+ goto err_fini;
+ }
+
+ i915_gem_request_get(rq);
+ __i915_add_request(rq, true);
+
+ if (!wait_for_hang(&h, rq)) {
+ pr_err("Failed to start request %x\n", rq->fence.seqno);
+ err = -EIO;
+ goto err_request;
+ }
+
+ mutex_unlock(&i915->drm.struct_mutex);
+
+ /* Temporarily disable error capture */
+ error = xchg(&i915->gpu_error.first_error, (void *)-1);
+
+ engine->hangcheck.stalled = true;
+ engine->hangcheck.seqno = intel_engine_get_seqno(engine);
+
+ i915_handle_error(i915, intel_engine_flag(engine), "%s", __func__);
+
+ xchg(&i915->gpu_error.first_error, error);
+
+ mutex_lock(&i915->drm.struct_mutex);
+
+ if (rq->fence.error != -EIO) {
+ pr_err("Guilty request not identified!\n");
+ err = -EINVAL;
+ goto err_request;
+ }
+
+err_request:
+ i915_gem_request_put(rq);
+err_fini:
+ hang_fini(&h);
+err_unlock:
+ mutex_unlock(&i915->drm.struct_mutex);
+ return err;
+}
+
int intel_hangcheck_live_selftests(struct drm_i915_private *i915)
{
static const struct i915_subtest tests[] = {
SUBTEST(igt_hang_sanitycheck),
SUBTEST(igt_global_reset),
+ SUBTEST(igt_reset_engine),
+ SUBTEST(igt_reset_active_engines),
SUBTEST(igt_wait_reset),
SUBTEST(igt_reset_queue),
+ SUBTEST(igt_handle_error),
};
if (!intel_has_gpu_reset(i915))
diff --git a/drivers/gpu/drm/i915/selftests/mock_context.c b/drivers/gpu/drm/i915/selftests/mock_context.c
index f8b9cc212b02..098ce643ad07 100644
--- a/drivers/gpu/drm/i915/selftests/mock_context.c
+++ b/drivers/gpu/drm/i915/selftests/mock_context.c
@@ -40,18 +40,13 @@ mock_context(struct drm_i915_private *i915,
INIT_LIST_HEAD(&ctx->link);
ctx->i915 = i915;
- ctx->vma_lut.ht_bits = VMA_HT_BITS;
- ctx->vma_lut.ht_size = BIT(VMA_HT_BITS);
- ctx->vma_lut.ht = kcalloc(ctx->vma_lut.ht_size,
- sizeof(*ctx->vma_lut.ht),
- GFP_KERNEL);
- if (!ctx->vma_lut.ht)
- goto err_free;
-
- ret = ida_simple_get(&i915->context_hw_ida,
+ INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
+ INIT_LIST_HEAD(&ctx->handles_list);
+
+ ret = ida_simple_get(&i915->contexts.hw_ida,
0, MAX_CONTEXT_HW_ID, GFP_KERNEL);
if (ret < 0)
- goto err_vma_ht;
+ goto err_handles;
ctx->hw_id = ret;
if (name) {
@@ -66,9 +61,7 @@ mock_context(struct drm_i915_private *i915,
return ctx;
-err_vma_ht:
- kvfree(ctx->vma_lut.ht);
-err_free:
+err_handles:
kfree(ctx);
return NULL;
@@ -86,3 +79,20 @@ void mock_context_close(struct i915_gem_context *ctx)
i915_gem_context_put(ctx);
}
+
+void mock_init_contexts(struct drm_i915_private *i915)
+{
+ INIT_LIST_HEAD(&i915->contexts.list);
+ ida_init(&i915->contexts.hw_ida);
+
+ INIT_WORK(&i915->contexts.free_work, contexts_free_worker);
+ init_llist_head(&i915->contexts.free_list);
+}
+
+struct i915_gem_context *
+live_context(struct drm_i915_private *i915, struct drm_file *file)
+{
+ lockdep_assert_held(&i915->drm.struct_mutex);
+
+ return i915_gem_create_context(i915, file->driver_priv);
+}
diff --git a/drivers/gpu/drm/i915/selftests/mock_context.h b/drivers/gpu/drm/i915/selftests/mock_context.h
index 2427e5c0916a..2f432c03d413 100644
--- a/drivers/gpu/drm/i915/selftests/mock_context.h
+++ b/drivers/gpu/drm/i915/selftests/mock_context.h
@@ -25,10 +25,15 @@
#ifndef __MOCK_CONTEXT_H
#define __MOCK_CONTEXT_H
+void mock_init_contexts(struct drm_i915_private *i915);
+
struct i915_gem_context *
mock_context(struct drm_i915_private *i915,
const char *name);
void mock_context_close(struct i915_gem_context *ctx);
+struct i915_gem_context *
+live_context(struct drm_i915_private *i915, struct drm_file *file);
+
#endif /* !__MOCK_CONTEXT_H */
diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.c b/drivers/gpu/drm/i915/selftests/mock_engine.c
index 5b18a2dc19a8..fc0fd7498689 100644
--- a/drivers/gpu/drm/i915/selftests/mock_engine.c
+++ b/drivers/gpu/drm/i915/selftests/mock_engine.c
@@ -123,10 +123,12 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
}
struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
- const char *name)
+ const char *name,
+ int id)
{
struct mock_engine *engine;
- static int id;
+
+ GEM_BUG_ON(id >= I915_NUM_ENGINES);
engine = kzalloc(sizeof(*engine) + PAGE_SIZE, GFP_KERNEL);
if (!engine)
@@ -141,7 +143,7 @@ struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
/* minimal engine setup for requests */
engine->base.i915 = i915;
snprintf(engine->base.name, sizeof(engine->base.name), "%s", name);
- engine->base.id = id++;
+ engine->base.id = id;
engine->base.status_page.page_addr = (void *)(engine + 1);
engine->base.context_pin = mock_context_pin;
diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.h b/drivers/gpu/drm/i915/selftests/mock_engine.h
index e5e240216ba3..133d0c21790d 100644
--- a/drivers/gpu/drm/i915/selftests/mock_engine.h
+++ b/drivers/gpu/drm/i915/selftests/mock_engine.h
@@ -40,7 +40,8 @@ struct mock_engine {
};
struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
- const char *name);
+ const char *name,
+ int id);
void mock_engine_flush(struct intel_engine_cs *engine);
void mock_engine_reset(struct intel_engine_cs *engine);
void mock_engine_free(struct intel_engine_cs *engine);
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 627e2aa09766..678723430d78 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -22,6 +22,7 @@
*
*/
+#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include "mock_engine.h"
@@ -53,15 +54,17 @@ static void mock_device_release(struct drm_device *dev)
mutex_lock(&i915->drm.struct_mutex);
mock_device_flush(i915);
+ i915_gem_contexts_lost(i915);
mutex_unlock(&i915->drm.struct_mutex);
cancel_delayed_work_sync(&i915->gt.retire_work);
cancel_delayed_work_sync(&i915->gt.idle_work);
+ i915_gem_drain_workqueue(i915);
mutex_lock(&i915->drm.struct_mutex);
for_each_engine(engine, i915, id)
mock_engine_free(engine);
- i915_gem_context_fini(i915);
+ i915_gem_contexts_fini(i915);
mutex_unlock(&i915->drm.struct_mutex);
drain_workqueue(i915->wq);
@@ -108,6 +111,23 @@ static void mock_idle_work_handler(struct work_struct *work)
{
}
+static int pm_domain_resume(struct device *dev)
+{
+ return pm_generic_runtime_resume(dev);
+}
+
+static int pm_domain_suspend(struct device *dev)
+{
+ return pm_generic_runtime_suspend(dev);
+}
+
+static struct dev_pm_domain pm_domain = {
+ .ops = {
+ .runtime_suspend = pm_domain_suspend,
+ .runtime_resume = pm_domain_resume,
+ },
+};
+
struct drm_i915_private *mock_gem_device(void)
{
struct drm_i915_private *i915;
@@ -126,8 +146,10 @@ struct drm_i915_private *mock_gem_device(void)
dev_set_name(&pdev->dev, "mock");
dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ dev_pm_domain_set(&pdev->dev, &pm_domain);
+ pm_runtime_enable(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
- pm_runtime_get_sync(&pdev->dev);
+ WARN_ON(pm_runtime_get_sync(&pdev->dev));
i915 = (struct drm_i915_private *)(pdev + 1);
pci_set_drvdata(pdev, i915);
@@ -160,7 +182,7 @@ struct drm_i915_private *mock_gem_device(void)
INIT_LIST_HEAD(&i915->mm.unbound_list);
INIT_LIST_HEAD(&i915->mm.bound_list);
- ida_init(&i915->context_hw_ida);
+ mock_init_contexts(i915);
INIT_DELAYED_WORK(&i915->gt.retire_work, mock_retire_work_handler);
INIT_DELAYED_WORK(&i915->gt.idle_work, mock_idle_work_handler);
@@ -204,9 +226,9 @@ struct drm_i915_private *mock_gem_device(void)
mutex_unlock(&i915->drm.struct_mutex);
mkwrite_device_info(i915)->ring_mask = BIT(0);
- i915->engine[RCS] = mock_engine(i915, "mock");
+ i915->engine[RCS] = mock_engine(i915, "mock", RCS);
if (!i915->engine[RCS])
- goto err_dependencies;
+ goto err_priorities;
i915->kernel_context = mock_context(i915, NULL);
if (!i915->kernel_context)
diff --git a/drivers/gpu/drm/i915/selftests/mock_gtt.c b/drivers/gpu/drm/i915/selftests/mock_gtt.c
index a61309c7cb3e..f2118cf535a0 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gtt.c
@@ -33,8 +33,7 @@ static void mock_insert_page(struct i915_address_space *vm,
}
static void mock_insert_entries(struct i915_address_space *vm,
- struct sg_table *st,
- u64 start,
+ struct i915_vma *vma,
enum i915_cache_level level, u32 flags)
{
}
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index 95e2181963d9..f91cb72d0830 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -115,7 +115,7 @@ static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
struct drm_plane *plane;
- struct drm_plane_state *old_plane_state;
+ struct drm_plane_state *old_plane_state, *new_plane_state;
bool plane_disabling = false;
int i;
@@ -127,15 +127,15 @@ static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state)
drm_atomic_helper_commit_modeset_enables(dev, state);
- for_each_plane_in_state(state, plane, old_plane_state, i) {
- if (drm_atomic_plane_disabling(old_plane_state, plane->state))
+ for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
+ if (drm_atomic_plane_disabling(old_plane_state, new_plane_state))
plane_disabling = true;
}
if (plane_disabling) {
drm_atomic_helper_wait_for_vblanks(dev, state);
- for_each_plane_in_state(state, plane, old_plane_state, i)
+ for_each_old_plane_in_state(state, plane, old_plane_state, i)
ipu_plane_disable_deferred(plane);
}
@@ -182,8 +182,6 @@ static struct drm_driver imx_drm_driver = {
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index 8b05ecb8fdef..56dd7a9a8e25 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -389,7 +389,6 @@ static int imx_ldb_encoder_atomic_check(struct drm_encoder *encoder,
static const struct drm_connector_funcs imx_ldb_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = imx_drm_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index 4826bb781723..bc27c2699464 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -341,7 +341,6 @@ static int imx_tve_atomic_check(struct drm_encoder *encoder,
}
static const struct drm_connector_funcs imx_tve_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = imx_drm_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
index 5456c15d962c..53e0b24beda6 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -50,7 +50,8 @@ static inline struct ipu_crtc *to_ipu_crtc(struct drm_crtc *crtc)
return container_of(crtc, struct ipu_crtc, base);
}
-static void ipu_crtc_enable(struct drm_crtc *crtc)
+static void ipu_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
@@ -293,7 +294,7 @@ static const struct drm_crtc_helper_funcs ipu_helper_funcs = {
.atomic_check = ipu_crtc_atomic_check,
.atomic_begin = ipu_crtc_atomic_begin,
.atomic_disable = ipu_crtc_atomic_disable,
- .enable = ipu_crtc_enable,
+ .atomic_enable = ipu_crtc_atomic_enable,
};
static void ipu_put_resources(struct ipu_crtc *ipu_crtc)
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
index 49546222c6d3..227309b01206 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -54,7 +54,7 @@ static const uint32_t ipu_plane_formats[] = {
DRM_FORMAT_RGBA8888,
DRM_FORMAT_RGBX8888,
DRM_FORMAT_BGRA8888,
- DRM_FORMAT_BGRA8888,
+ DRM_FORMAT_BGRX8888,
DRM_FORMAT_UYVY,
DRM_FORMAT_VYUY,
DRM_FORMAT_YUYV,
@@ -496,6 +496,27 @@ static int ipu_chan_assign_axi_id(int ipu_chan)
}
}
+static void ipu_calculate_bursts(u32 width, u32 cpp, u32 stride,
+ u8 *burstsize, u8 *num_bursts)
+{
+ const unsigned int width_bytes = width * cpp;
+ unsigned int npb, bursts;
+
+ /* Maximum number of pixels per burst without overshooting stride */
+ for (npb = 64 / cpp; npb > 0; --npb) {
+ if (round_up(width_bytes, npb * cpp) <= stride)
+ break;
+ }
+ *burstsize = npb;
+
+ /* Maximum number of consecutive bursts without overshooting stride */
+ for (bursts = 8; bursts > 1; bursts /= 2) {
+ if (round_up(width_bytes, npb * cpp * bursts) <= stride)
+ break;
+ }
+ *num_bursts = bursts;
+}
+
static void ipu_plane_atomic_update(struct drm_plane *plane,
struct drm_plane_state *old_state)
{
@@ -509,6 +530,9 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
unsigned long alpha_eba = 0;
enum ipu_color_space ics;
unsigned int axi_id = 0;
+ const struct drm_format_info *info;
+ u8 burstsize, num_bursts;
+ u32 width, height;
int active;
if (ipu_plane->dp_flow == IPU_DP_FLOW_SYNC_FG)
@@ -525,8 +549,8 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
ipu_prg_channel_configure(ipu_plane->ipu_ch, axi_id,
drm_rect_width(&state->src) >> 16,
drm_rect_height(&state->src) >> 16,
- state->fb->pitches[0],
- state->fb->format->format, &eba);
+ fb->pitches[0],
+ fb->format->format, &eba);
}
if (old_state->fb && !drm_atomic_crtc_needs_modeset(crtc_state)) {
@@ -553,11 +577,11 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
ipu_dp_set_global_alpha(ipu_plane->dp, true, 0, true);
break;
case IPU_DP_FLOW_SYNC_FG:
- ics = ipu_drm_fourcc_to_colorspace(state->fb->format->format);
+ ics = ipu_drm_fourcc_to_colorspace(fb->format->format);
ipu_dp_setup_channel(ipu_plane->dp, ics,
IPUV3_COLORSPACE_UNKNOWN);
/* Enable local alpha on partial plane */
- switch (state->fb->format->format) {
+ switch (fb->format->format) {
case DRM_FORMAT_ARGB1555:
case DRM_FORMAT_ABGR1555:
case DRM_FORMAT_RGBA5551:
@@ -583,15 +607,21 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
ipu_dmfc_config_wait4eot(ipu_plane->dmfc, drm_rect_width(dst));
+ width = drm_rect_width(&state->src) >> 16;
+ height = drm_rect_height(&state->src) >> 16;
+ info = drm_format_info(fb->format->format);
+ ipu_calculate_bursts(width, info->cpp[0], fb->pitches[0],
+ &burstsize, &num_bursts);
+
ipu_cpmem_zero(ipu_plane->ipu_ch);
- ipu_cpmem_set_resolution(ipu_plane->ipu_ch,
- drm_rect_width(&state->src) >> 16,
- drm_rect_height(&state->src) >> 16);
- ipu_cpmem_set_fmt(ipu_plane->ipu_ch, state->fb->format->format);
+ ipu_cpmem_set_resolution(ipu_plane->ipu_ch, width, height);
+ ipu_cpmem_set_fmt(ipu_plane->ipu_ch, fb->format->format);
+ ipu_cpmem_set_burstsize(ipu_plane->ipu_ch, burstsize);
ipu_cpmem_set_high_priority(ipu_plane->ipu_ch);
ipu_idmac_set_double_buffer(ipu_plane->ipu_ch, 1);
- ipu_cpmem_set_stride(ipu_plane->ipu_ch, state->fb->pitches[0]);
+ ipu_cpmem_set_stride(ipu_plane->ipu_ch, fb->pitches[0]);
ipu_cpmem_set_axi_id(ipu_plane->ipu_ch, axi_id);
+
switch (fb->format->format) {
case DRM_FORMAT_YUV420:
case DRM_FORMAT_YVU420:
@@ -631,6 +661,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
case DRM_FORMAT_RGBX8888_A8:
case DRM_FORMAT_BGRX8888_A8:
alpha_eba = drm_plane_state_to_eba(state, 1);
+ num_bursts = 0;
dev_dbg(ipu_plane->base.dev->dev, "phys = %lu %lu, x = %d, y = %d",
eba, alpha_eba, state->src.x1 >> 16, state->src.y1 >> 16);
@@ -644,8 +675,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
ipu_cpmem_set_format_passthrough(ipu_plane->alpha_ch, 8);
ipu_cpmem_set_high_priority(ipu_plane->alpha_ch);
ipu_idmac_set_double_buffer(ipu_plane->alpha_ch, 1);
- ipu_cpmem_set_stride(ipu_plane->alpha_ch,
- state->fb->pitches[1]);
+ ipu_cpmem_set_stride(ipu_plane->alpha_ch, fb->pitches[1]);
ipu_cpmem_set_burstsize(ipu_plane->alpha_ch, 16);
ipu_cpmem_set_buffer(ipu_plane->alpha_ch, 0, alpha_eba);
ipu_cpmem_set_buffer(ipu_plane->alpha_ch, 1, alpha_eba);
@@ -657,6 +687,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
}
ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 0, eba);
ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 1, eba);
+ ipu_idmac_lock_enable(ipu_plane->ipu_ch, num_bursts);
ipu_plane_enable(ipu_plane);
}
@@ -675,7 +706,7 @@ int ipu_planes_assign_pre(struct drm_device *dev,
int available_pres = ipu_prg_max_active_channels();
int i;
- for_each_plane_in_state(state, plane, plane_state, i) {
+ for_each_new_plane_in_state(state, plane, plane_state, i) {
struct ipu_plane_state *ipu_state =
to_ipu_plane_state(plane_state);
struct ipu_plane *ipu_plane = to_ipu_plane(plane);
@@ -718,8 +749,8 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
ret = drm_universal_plane_init(dev, &ipu_plane->base, possible_crtcs,
&ipu_plane_funcs, ipu_plane_formats,
- ARRAY_SIZE(ipu_plane_formats), type,
- NULL);
+ ARRAY_SIZE(ipu_plane_formats),
+ NULL, type, NULL);
if (ret) {
DRM_ERROR("failed to initialize plane\n");
kfree(ipu_plane);
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
index 636031a30e17..8def97d75030 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -135,7 +135,6 @@ static int imx_pd_encoder_atomic_check(struct drm_encoder *encoder,
}
static const struct drm_connector_funcs imx_pd_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = imx_drm_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
@@ -237,7 +236,7 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
/* port@1 is the output port */
ret = drm_of_find_panel_or_bridge(np, 1, 0, &imxpd->panel, &imxpd->bridge);
- if (ret)
+ if (ret && ret != -ENODEV)
return ret;
imxpd->dev = dev;
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c
index ef79a6d55646..f609b62b8be6 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_color.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c
@@ -84,8 +84,8 @@ static int mtk_disp_color_bind(struct device *dev, struct device *master,
ret = mtk_ddp_comp_register(drm_dev, &priv->ddp_comp);
if (ret < 0) {
- dev_err(dev, "Failed to register component %s: %d\n",
- dev->of_node->full_name, ret);
+ dev_err(dev, "Failed to register component %pOF: %d\n",
+ dev->of_node, ret);
return ret;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 35bc5babdbf7..978782a77629 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -235,8 +235,8 @@ static int mtk_disp_ovl_bind(struct device *dev, struct device *master,
ret = mtk_ddp_comp_register(drm_dev, &priv->ddp_comp);
if (ret < 0) {
- dev_err(dev, "Failed to register component %s: %d\n",
- dev->of_node->full_name, ret);
+ dev_err(dev, "Failed to register component %pOF: %d\n",
+ dev->of_node, ret);
return ret;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index b68a51376f83..585943c81e1f 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -155,8 +155,8 @@ static int mtk_disp_rdma_bind(struct device *dev, struct device *master,
ret = mtk_ddp_comp_register(drm_dev, &priv->ddp_comp);
if (ret < 0) {
- dev_err(dev, "Failed to register component %s: %d\n",
- dev->of_node->full_name, ret);
+ dev_err(dev, "Failed to register component %pOF: %d\n",
+ dev->of_node, ret);
return ret;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 32ca351ecd09..e80a603e5fb0 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -605,8 +605,8 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data)
ret = mtk_ddp_comp_register(drm_dev, &dpi->ddp_comp);
if (ret < 0) {
- dev_err(dev, "Failed to register component %s: %d\n",
- dev->of_node->full_name, ret);
+ dev_err(dev, "Failed to register component %pOF: %d\n",
+ dev->of_node, ret);
return ret;
}
@@ -710,7 +710,7 @@ static int mtk_dpi_probe(struct platform_device *pdev)
if (!bridge_node)
return -ENODEV;
- dev_info(dev, "Found bridge node: %s\n", bridge_node->full_name);
+ dev_info(dev, "Found bridge node: %pOF\n", bridge_node);
dpi->bridge = of_drm_find_bridge(bridge_node);
of_node_put(bridge_node);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index cb32c9369f3a..658b8dd45b83 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -366,7 +366,8 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
}
}
-static void mtk_drm_crtc_enable(struct drm_crtc *crtc)
+static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
@@ -390,7 +391,8 @@ static void mtk_drm_crtc_enable(struct drm_crtc *crtc)
mtk_crtc->enabled = true;
}
-static void mtk_drm_crtc_disable(struct drm_crtc *crtc)
+static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
@@ -487,10 +489,10 @@ static const struct drm_crtc_funcs mtk_crtc_funcs = {
static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
.mode_fixup = mtk_drm_crtc_mode_fixup,
.mode_set_nofb = mtk_drm_crtc_mode_set_nofb,
- .enable = mtk_drm_crtc_enable,
- .disable = mtk_drm_crtc_disable,
.atomic_begin = mtk_drm_crtc_atomic_begin,
.atomic_flush = mtk_drm_crtc_atomic_flush,
+ .atomic_enable = mtk_drm_crtc_atomic_enable,
+ .atomic_disable = mtk_drm_crtc_atomic_disable,
};
static int mtk_drm_crtc_init(struct drm_device *drm,
@@ -577,8 +579,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
node = priv->comp_node[comp_id];
comp = priv->ddp_comp[comp_id];
if (!comp) {
- dev_err(dev, "Component %s not initialized\n",
- node->full_name);
+ dev_err(dev, "Component %pOF not initialized\n", node);
ret = -ENODEV;
goto unprepare;
}
@@ -586,8 +587,8 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
ret = clk_prepare(comp->clk);
if (ret) {
dev_err(dev,
- "Failed to prepare clock for component %s: %d\n",
- node->full_name, ret);
+ "Failed to prepare clock for component %pOF: %d\n",
+ node, ret);
goto unprepare;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 07d7ea2268ef..4672317e3ad1 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -295,15 +295,13 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
larb_node = of_parse_phandle(node, "mediatek,larb", 0);
if (!larb_node) {
dev_err(dev,
- "Missing mediadek,larb phandle in %s node\n",
- node->full_name);
+ "Missing mediadek,larb phandle in %pOF node\n", node);
return -EINVAL;
}
larb_pdev = of_find_device_by_node(larb_node);
if (!larb_pdev) {
- dev_warn(dev, "Waiting for larb device %s\n",
- larb_node->full_name);
+ dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
of_node_put(larb_node);
return -EPROBE_DEFER;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 41d2cffe953e..a2ca90fc403c 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -48,11 +48,11 @@ static void mtk_atomic_schedule(struct mtk_drm_private *private,
static void mtk_atomic_wait_for_fences(struct drm_atomic_state *state)
{
struct drm_plane *plane;
- struct drm_plane_state *plane_state;
+ struct drm_plane_state *new_plane_state;
int i;
- for_each_plane_in_state(state, plane, plane_state, i)
- mtk_fb_wait(plane->state->fb);
+ for_each_new_plane_in_state(state, plane, new_plane_state, i)
+ mtk_fb_wait(new_plane_state->fb);
}
static void mtk_atomic_complete(struct mtk_drm_private *private,
@@ -109,7 +109,12 @@ static int mtk_atomic_commit(struct drm_device *drm,
mutex_lock(&private->commit.lock);
flush_work(&private->commit.work);
- drm_atomic_helper_swap_state(state, true);
+ ret = drm_atomic_helper_swap_state(state, true);
+ if (ret) {
+ mutex_unlock(&private->commit.lock);
+ drm_atomic_helper_cleanup_planes(drm, state);
+ return ret;
+ }
drm_atomic_state_get(state);
if (async)
@@ -187,8 +192,8 @@ static int mtk_drm_kms_init(struct drm_device *drm)
pdev = of_find_device_by_node(private->mutex_node);
if (!pdev) {
- dev_err(drm->dev, "Waiting for disp-mutex device %s\n",
- private->mutex_node->full_name);
+ dev_err(drm->dev, "Waiting for disp-mutex device %pOF\n",
+ private->mutex_node);
of_node_put(private->mutex_node);
return -EPROBE_DEFER;
}
@@ -266,7 +271,6 @@ static void mtk_drm_kms_deinit(struct drm_device *drm)
{
drm_kms_helper_poll_fini(drm);
- drm_vblank_cleanup(drm);
component_unbind_all(drm->dev, drm);
drm_mode_config_cleanup(drm);
}
@@ -289,8 +293,6 @@ static struct drm_driver mtk_drm_driver = {
.gem_free_object_unlocked = mtk_drm_gem_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = mtk_drm_gem_dumb_create,
- .dumb_map_offset = mtk_drm_gem_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
@@ -417,8 +419,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
continue;
if (!of_device_is_available(node)) {
- dev_dbg(dev, "Skipping disabled component %s\n",
- node->full_name);
+ dev_dbg(dev, "Skipping disabled component %pOF\n",
+ node);
continue;
}
@@ -431,8 +433,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
comp_id = mtk_ddp_comp_get_id(node, comp_type);
if (comp_id < 0) {
- dev_warn(dev, "Skipping unknown component %s\n",
- node->full_name);
+ dev_warn(dev, "Skipping unknown component %pOF\n",
+ node);
continue;
}
@@ -448,8 +450,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
comp_type == MTK_DISP_RDMA ||
comp_type == MTK_DSI ||
comp_type == MTK_DPI) {
- dev_info(dev, "Adding component match for %s\n",
- node->full_name);
+ dev_info(dev, "Adding component match for %pOF\n",
+ node);
drm_of_component_match_add(dev, &match, compare_of,
node);
} else {
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_fb.c b/drivers/gpu/drm/mediatek/mtk_drm_fb.c
index d4246c9dceae..0d8d506695f9 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_fb.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_fb.c
@@ -58,7 +58,7 @@ static void mtk_drm_fb_destroy(struct drm_framebuffer *fb)
drm_framebuffer_cleanup(fb);
- drm_gem_object_unreference_unlocked(mtk_fb->gem_obj);
+ drm_gem_object_put_unlocked(mtk_fb->gem_obj);
kfree(mtk_fb);
}
@@ -160,6 +160,6 @@ struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev,
return &mtk_fb->base;
unreference:
- drm_gem_object_unreference_unlocked(gem);
+ drm_gem_object_put_unlocked(gem);
return ERR_PTR(ret);
}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
index 7abc550ebc00..f595ac816b55 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
@@ -122,7 +122,7 @@ int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
goto err_handle_create;
/* drop reference from allocate - handle holds it now. */
- drm_gem_object_unreference_unlocked(&mtk_gem->base);
+ drm_gem_object_put_unlocked(&mtk_gem->base);
return 0;
@@ -131,31 +131,6 @@ err_handle_create:
return ret;
}
-int mtk_drm_gem_dumb_map_offset(struct drm_file *file_priv,
- struct drm_device *dev, uint32_t handle,
- uint64_t *offset)
-{
- struct drm_gem_object *obj;
- int ret;
-
- obj = drm_gem_object_lookup(file_priv, handle);
- if (!obj) {
- DRM_ERROR("failed to lookup gem object.\n");
- return -EINVAL;
- }
-
- ret = drm_gem_create_mmap_offset(obj);
- if (ret)
- goto out;
-
- *offset = drm_vma_node_offset_addr(&obj->vma_node);
- DRM_DEBUG_KMS("offset = 0x%llx\n", *offset);
-
-out:
- drm_gem_object_unreference_unlocked(obj);
- return ret;
-}
-
static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj,
struct vm_area_struct *vma)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.h b/drivers/gpu/drm/mediatek/mtk_drm_gem.h
index 2752718fa5b2..534639b43a1c 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.h
@@ -46,9 +46,6 @@ struct mtk_drm_gem_obj *mtk_drm_gem_create(struct drm_device *dev, size_t size,
bool alloc_kmap);
int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
struct drm_mode_create_dumb *args);
-int mtk_drm_gem_dumb_map_offset(struct drm_file *file_priv,
- struct drm_device *dev, uint32_t handle,
- uint64_t *offset);
int mtk_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
int mtk_drm_gem_mmap_buf(struct drm_gem_object *obj,
struct vm_area_struct *vma);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index 1a59b9ab4aa8..6f121891430f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -175,7 +175,7 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
err = drm_universal_plane_init(dev, plane, possible_crtcs,
&mtk_plane_funcs, formats,
- ARRAY_SIZE(formats), type, NULL);
+ ARRAY_SIZE(formats), NULL, type, NULL);
if (err) {
DRM_ERROR("failed to initialize plane\n");
return err;
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 97253c8f813b..7e5e24c2152a 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -766,7 +766,6 @@ static const struct drm_encoder_helper_funcs mtk_dsi_encoder_helper_funcs = {
};
static const struct drm_connector_funcs mtk_dsi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
@@ -1048,8 +1047,8 @@ static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
ret = mtk_ddp_comp_register(drm, &dsi->ddp_comp);
if (ret < 0) {
- dev_err(dev, "Failed to register component %s: %d\n",
- dev->of_node->full_name, ret);
+ dev_err(dev, "Failed to register component %pOF: %d\n",
+ dev->of_node, ret);
return ret;
}
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 71eb4fbbfc85..690c67507cbc 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -975,7 +975,7 @@ static int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi *hdmi,
u8 buffer[17];
ssize_t err;
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (err < 0) {
dev_err(hdmi->dev,
"Failed to get AVI infoframe from mode: %zd\n", err);
@@ -1261,7 +1261,6 @@ static struct drm_encoder *mtk_hdmi_conn_best_enc(struct drm_connector *conn)
}
static const struct drm_connector_funcs mtk_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = hdmi_conn_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = hdmi_conn_destroy,
@@ -1456,8 +1455,8 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
cec_pdev = of_find_device_by_node(cec_np);
if (!cec_pdev) {
- dev_err(hdmi->dev, "Waiting for CEC device %s\n",
- cec_np->full_name);
+ dev_err(hdmi->dev, "Waiting for CEC device %pOF\n",
+ cec_np);
return -EPROBE_DEFER;
}
hdmi->cec_dev = &cec_pdev->dev;
@@ -1501,8 +1500,8 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
i2c_np = of_parse_phandle(remote, "ddc-i2c-bus", 0);
if (!i2c_np) {
- dev_err(dev, "Failed to find ddc-i2c-bus node in %s\n",
- remote->full_name);
+ dev_err(dev, "Failed to find ddc-i2c-bus node in %pOF\n",
+ remote);
of_node_put(remote);
return -EINVAL;
}
diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
index c986eb03b9d9..5155f0179b61 100644
--- a/drivers/gpu/drm/meson/meson_crtc.c
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -79,7 +79,8 @@ static const struct drm_crtc_funcs meson_crtc_funcs = {
};
-static void meson_crtc_enable(struct drm_crtc *crtc)
+static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
struct drm_crtc_state *crtc_state = crtc->state;
@@ -102,7 +103,8 @@ static void meson_crtc_enable(struct drm_crtc *crtc)
priv->viu.osd1_enabled = true;
}
-static void meson_crtc_disable(struct drm_crtc *crtc)
+static void meson_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
struct meson_drm *priv = meson_crtc->priv;
@@ -149,10 +151,10 @@ static void meson_crtc_atomic_flush(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs meson_crtc_helper_funcs = {
- .enable = meson_crtc_enable,
- .disable = meson_crtc_disable,
.atomic_begin = meson_crtc_atomic_begin,
.atomic_flush = meson_crtc_atomic_flush,
+ .atomic_enable = meson_crtc_atomic_enable,
+ .atomic_disable = meson_crtc_atomic_disable,
};
void meson_crtc_irq(struct meson_drm *priv)
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index 4d98fac92795..7742c7d81ed8 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -116,8 +116,6 @@ static struct drm_driver meson_driver = {
/* GEM Ops */
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_destroy = drm_gem_dumb_destroy,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
@@ -303,9 +301,8 @@ static const struct component_master_ops meson_drv_master_ops = {
static int compare_of(struct device *dev, void *data)
{
- DRM_DEBUG_DRIVER("Comparing of node %s with %s\n",
- of_node_full_name(dev->of_node),
- of_node_full_name(data));
+ DRM_DEBUG_DRIVER("Comparing of node %pOF with %pOF\n",
+ dev->of_node, data);
return dev->of_node == data;
}
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
index a32d3b6e2e12..17e96fa47868 100644
--- a/drivers/gpu/drm/meson/meson_plane.c
+++ b/drivers/gpu/drm/meson/meson_plane.c
@@ -223,6 +223,7 @@ int meson_plane_create(struct meson_drm *priv)
&meson_plane_funcs,
supported_drm_formats,
ARRAY_SIZE(supported_drm_formats),
+ NULL,
DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane");
drm_plane_helper_add(plane, &meson_plane_helper_funcs);
diff --git a/drivers/gpu/drm/meson/meson_venc_cvbs.c b/drivers/gpu/drm/meson/meson_venc_cvbs.c
index 00775b397dba..79d95ca8a0c0 100644
--- a/drivers/gpu/drm/meson/meson_venc_cvbs.c
+++ b/drivers/gpu/drm/meson/meson_venc_cvbs.c
@@ -118,7 +118,6 @@ static int meson_cvbs_connector_mode_valid(struct drm_connector *connector,
}
static const struct drm_connector_funcs meson_cvbs_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = meson_cvbs_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = meson_cvbs_connector_destroy,
diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c
index 63ba0699d107..1aad27813c23 100644
--- a/drivers/gpu/drm/mga/mga_drv.c
+++ b/drivers/gpu/drm/mga/mga_drv.c
@@ -62,7 +62,6 @@ static struct drm_driver driver = {
.load = mga_driver_load,
.unload = mga_driver_unload,
.lastclose = mga_driver_lastclose,
- .set_busid = drm_pci_set_busid,
.dma_quiescent = mga_driver_dma_quiescent,
.get_vblank_counter = mga_get_vblank_counter,
.enable_vblank = mga_enable_vblank,
@@ -90,12 +89,12 @@ static struct pci_driver mga_pci_driver = {
static int __init mga_init(void)
{
driver.num_ioctls = mga_max_ioctl;
- return drm_pci_init(&driver, &mga_pci_driver);
+ return drm_legacy_pci_init(&driver, &mga_pci_driver);
}
static void __exit mga_exit(void)
{
- drm_pci_exit(&driver, &mga_pci_driver);
+ drm_legacy_pci_exit(&driver, &mga_pci_driver);
}
module_init(mga_init);
diff --git a/drivers/gpu/drm/mgag200/mgag200_cursor.c b/drivers/gpu/drm/mgag200/mgag200_cursor.c
index 2ac3fcbfea7b..968e20379d54 100644
--- a/drivers/gpu/drm/mgag200/mgag200_cursor.c
+++ b/drivers/gpu/drm/mgag200/mgag200_cursor.c
@@ -248,7 +248,7 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc,
out_unreserve1:
mgag200_bo_unreserve(pixels_2);
out_unref:
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 9ac007880328..74cdde2ee474 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -91,7 +91,6 @@ static struct drm_driver driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET,
.load = mgag200_driver_load,
.unload = mgag200_driver_unload,
- .set_busid = drm_pci_set_busid,
.fops = &mgag200_driver_fops,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
@@ -103,7 +102,6 @@ static struct drm_driver driver = {
.gem_free_object_unlocked = mgag200_gem_free_object,
.dumb_create = mgag200_dumb_create,
.dumb_map_offset = mgag200_dumb_mmap_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
};
static struct pci_driver mgag200_pci_driver = {
@@ -120,12 +118,13 @@ static int __init mgag200_init(void)
if (mgag200_modeset == 0)
return -EINVAL;
- return drm_pci_init(&driver, &mgag200_pci_driver);
+
+ return pci_register_driver(&mgag200_pci_driver);
}
static void __exit mgag200_exit(void)
{
- drm_pci_exit(&driver, &mgag200_pci_driver);
+ pci_unregister_driver(&mgag200_pci_driver);
}
module_init(mgag200_init);
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index c88b6ec88dd2..04f1dfba12e5 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -237,11 +237,6 @@ mgag200_bo(struct ttm_buffer_object *bo)
{
return container_of(bo, struct mgag200_bo, bo);
}
- /* mgag200_crtc.c */
-void mga_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno);
-void mga_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno);
/* mgag200_mode.c */
int mgag200_modeset_init(struct mga_device *mdev);
diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c b/drivers/gpu/drm/mgag200/mgag200_fb.c
index 5d3b1fac906f..30726c9fe28c 100644
--- a/drivers/gpu/drm/mgag200/mgag200_fb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_fb.c
@@ -210,7 +210,6 @@ static int mgag200fb_create(struct drm_fb_helper *helper,
strcpy(info->fix.id, "mgadrmfb");
- info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &mgag200fb_ops;
/* setup aperture base/size for vesafb takeover */
@@ -233,7 +232,7 @@ static int mgag200fb_create(struct drm_fb_helper *helper,
err_alloc_fbi:
vfree(sysram);
err_sysram:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return ret;
}
@@ -246,7 +245,7 @@ static int mga_fbdev_destroy(struct drm_device *dev,
drm_fb_helper_unregister_fbi(&mfbdev->helper);
if (mfb->obj) {
- drm_gem_object_unreference_unlocked(mfb->obj);
+ drm_gem_object_put_unlocked(mfb->obj);
mfb->obj = NULL;
}
drm_fb_helper_fini(&mfbdev->helper);
@@ -258,8 +257,6 @@ static int mga_fbdev_destroy(struct drm_device *dev,
}
static const struct drm_fb_helper_funcs mga_fb_helper_funcs = {
- .gamma_set = mga_crtc_fb_gamma_set,
- .gamma_get = mga_crtc_fb_gamma_get,
.fb_probe = mgag200fb_create,
};
diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c
index dce8a3eb5a10..780f983b0294 100644
--- a/drivers/gpu/drm/mgag200/mgag200_main.c
+++ b/drivers/gpu/drm/mgag200/mgag200_main.c
@@ -18,7 +18,7 @@ static void mga_user_framebuffer_destroy(struct drm_framebuffer *fb)
{
struct mga_framebuffer *mga_fb = to_mga_framebuffer(fb);
- drm_gem_object_unreference_unlocked(mga_fb->obj);
+ drm_gem_object_put_unlocked(mga_fb->obj);
drm_framebuffer_cleanup(fb);
kfree(fb);
}
@@ -59,13 +59,13 @@ mgag200_user_framebuffer_create(struct drm_device *dev,
mga_fb = kzalloc(sizeof(*mga_fb), GFP_KERNEL);
if (!mga_fb) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(-ENOMEM);
}
ret = mgag200_framebuffer_init(dev, mga_fb, mode_cmd, obj);
if (ret) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
kfree(mga_fb);
return ERR_PTR(ret);
}
@@ -317,7 +317,7 @@ int mgag200_dumb_create(struct drm_file *file,
return ret;
ret = drm_gem_handle_create(file, gobj, &handle);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (ret)
return ret;
@@ -366,6 +366,6 @@ mgag200_dumb_mmap_offset(struct drm_file *file,
bo = gem_to_mga_bo(obj);
*offset = mgag200_bo_mmap_offset(bo);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return 0;
}
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index f4b53588e071..5e9cd4c0e8b6 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -27,15 +27,19 @@
static void mga_crtc_load_lut(struct drm_crtc *crtc)
{
- struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct mga_device *mdev = dev->dev_private;
struct drm_framebuffer *fb = crtc->primary->fb;
+ u16 *r_ptr, *g_ptr, *b_ptr;
int i;
if (!crtc->enabled)
return;
+ r_ptr = crtc->gamma_store;
+ g_ptr = r_ptr + crtc->gamma_size;
+ b_ptr = g_ptr + crtc->gamma_size;
+
WREG8(DAC_INDEX + MGA1064_INDEX, 0);
if (fb && fb->format->cpp[0] * 8 == 16) {
@@ -46,25 +50,27 @@ static void mga_crtc_load_lut(struct drm_crtc *crtc)
if (i > (MGAG200_LUT_SIZE >> 1)) {
r = b = 0;
} else {
- r = mga_crtc->lut_r[i << 1];
- b = mga_crtc->lut_b[i << 1];
+ r = *r_ptr++ >> 8;
+ b = *b_ptr++ >> 8;
+ r_ptr++;
+ b_ptr++;
}
} else {
- r = mga_crtc->lut_r[i];
- b = mga_crtc->lut_b[i];
+ r = *r_ptr++ >> 8;
+ b = *b_ptr++ >> 8;
}
/* VGA registers */
WREG8(DAC_INDEX + MGA1064_COL_PAL, r);
- WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_g[i]);
+ WREG8(DAC_INDEX + MGA1064_COL_PAL, *g_ptr++ >> 8);
WREG8(DAC_INDEX + MGA1064_COL_PAL, b);
}
return;
}
for (i = 0; i < MGAG200_LUT_SIZE; i++) {
/* VGA registers */
- WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_r[i]);
- WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_g[i]);
- WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_b[i]);
+ WREG8(DAC_INDEX + MGA1064_COL_PAL, *r_ptr++ >> 8);
+ WREG8(DAC_INDEX + MGA1064_COL_PAL, *g_ptr++ >> 8);
+ WREG8(DAC_INDEX + MGA1064_COL_PAL, *b_ptr++ >> 8);
}
}
@@ -1399,14 +1405,6 @@ static int mga_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
- int i;
-
- for (i = 0; i < size; i++) {
- mga_crtc->lut_r[i] = red[i] >> 8;
- mga_crtc->lut_g[i] = green[i] >> 8;
- mga_crtc->lut_b[i] = blue[i] >> 8;
- }
mga_crtc_load_lut(crtc);
return 0;
@@ -1455,14 +1453,12 @@ static const struct drm_crtc_helper_funcs mga_helper_funcs = {
.mode_set_base = mga_crtc_mode_set_base,
.prepare = mga_crtc_prepare,
.commit = mga_crtc_commit,
- .load_lut = mga_crtc_load_lut,
};
/* CRTC setup */
static void mga_crtc_init(struct mga_device *mdev)
{
struct mga_crtc *mga_crtc;
- int i;
mga_crtc = kzalloc(sizeof(struct mga_crtc) +
(MGAG200FB_CONN_LIMIT * sizeof(struct drm_connector *)),
@@ -1476,37 +1472,9 @@ static void mga_crtc_init(struct mga_device *mdev)
drm_mode_crtc_set_gamma_size(&mga_crtc->base, MGAG200_LUT_SIZE);
mdev->mode_info.crtc = mga_crtc;
- for (i = 0; i < MGAG200_LUT_SIZE; i++) {
- mga_crtc->lut_r[i] = i;
- mga_crtc->lut_g[i] = i;
- mga_crtc->lut_b[i] = i;
- }
-
drm_crtc_helper_add(&mga_crtc->base, &mga_helper_funcs);
}
-/** Sets the color ramps on behalf of fbcon */
-void mga_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
- struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
-
- mga_crtc->lut_r[regno] = red >> 8;
- mga_crtc->lut_g[regno] = green >> 8;
- mga_crtc->lut_b[regno] = blue >> 8;
-}
-
-/** Gets the color ramps on behalf of fbcon */
-void mga_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno)
-{
- struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
-
- *red = (u16)mga_crtc->lut_r[regno] << 8;
- *green = (u16)mga_crtc->lut_g[regno] << 8;
- *blue = (u16)mga_crtc->lut_b[regno] << 8;
-}
-
/*
* The encoder comes after the CRTC in the output pipeline, but before
* the connector. It's responsible for ensuring that the digital
diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index b638d192ce5e..99d39b2aefa6 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -5,7 +5,7 @@ config DRM_MSM
depends on ARCH_QCOM || (ARM && COMPILE_TEST)
depends on OF && COMMON_CLK
depends on MMU
- select QCOM_MDT_LOADER
+ select QCOM_MDT_LOADER if ARCH_QCOM
select REGULATOR
select DRM_KMS_HELPER
select DRM_PANEL
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index 0e3828ed1e46..7791313405b5 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -486,8 +486,6 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
adreno_gpu = &a3xx_gpu->base;
gpu = &adreno_gpu->base;
- a3xx_gpu->pdev = pdev;
-
gpu->perfcntrs = perfcntrs;
gpu->num_perfcntrs = ARRAY_SIZE(perfcntrs);
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h
index 85ff66cbddd6..ab60dc9e344e 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h
@@ -28,7 +28,6 @@
struct a3xx_gpu {
struct adreno_gpu base;
- struct platform_device *pdev;
/* if OCMEM is used for GMEM: */
uint32_t ocmem_base;
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
index 19abf229b08d..58341ef6f15b 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
@@ -568,8 +568,6 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
adreno_gpu = &a4xx_gpu->base;
gpu = &adreno_gpu->base;
- a4xx_gpu->pdev = pdev;
-
gpu->perfcntrs = NULL;
gpu->num_perfcntrs = 0;
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.h b/drivers/gpu/drm/msm/adreno/a4xx_gpu.h
index 01247204ac92..f757184328a3 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.h
@@ -23,7 +23,6 @@
struct a4xx_gpu {
struct adreno_gpu base;
- struct platform_device *pdev;
/* if OCMEM is used for GMEM: */
uint32_t ocmem_base;
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index b4b54f1c24bc..17c59d839e6f 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -15,7 +15,7 @@
#include <linux/cpumask.h>
#include <linux/qcom_scm.h>
#include <linux/dma-mapping.h>
-#include <linux/of_reserved_mem.h>
+#include <linux/of_address.h>
#include <linux/soc/qcom/mdt_loader.h>
#include "msm_gem.h"
#include "msm_mmu.h"
@@ -26,16 +26,34 @@ static void a5xx_dump(struct msm_gpu *gpu);
#define GPU_PAS_ID 13
-#if IS_ENABLED(CONFIG_QCOM_MDT_LOADER)
-
static int zap_shader_load_mdt(struct device *dev, const char *fwname)
{
const struct firmware *fw;
+ struct device_node *np;
+ struct resource r;
phys_addr_t mem_phys;
ssize_t mem_size;
void *mem_region = NULL;
int ret;
+ if (!IS_ENABLED(CONFIG_ARCH_QCOM))
+ return -EINVAL;
+
+ np = of_get_child_by_name(dev->of_node, "zap-shader");
+ if (!np)
+ return -ENODEV;
+
+ np = of_parse_phandle(np, "memory-region", 0);
+ if (!np)
+ return -EINVAL;
+
+ ret = of_address_to_resource(np, 0, &r);
+ if (ret)
+ return ret;
+
+ mem_phys = r.start;
+ mem_size = resource_size(&r);
+
/* Request the MDT file for the firmware */
ret = request_firmware(&fw, fwname, dev);
if (ret) {
@@ -51,7 +69,7 @@ static int zap_shader_load_mdt(struct device *dev, const char *fwname)
}
/* Allocate memory for the firmware image */
- mem_region = dmam_alloc_coherent(dev, mem_size, &mem_phys, GFP_KERNEL);
+ mem_region = memremap(mem_phys, mem_size, MEMREMAP_WC);
if (!mem_region) {
ret = -ENOMEM;
goto out;
@@ -69,16 +87,13 @@ static int zap_shader_load_mdt(struct device *dev, const char *fwname)
DRM_DEV_ERROR(dev, "Unable to authorize the image\n");
out:
+ if (mem_region)
+ memunmap(mem_region);
+
release_firmware(fw);
return ret;
}
-#else
-static int zap_shader_load_mdt(struct device *dev, const char *fwname)
-{
- return -ENODEV;
-}
-#endif
static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
struct msm_file_private *ctx)
@@ -117,12 +132,10 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
gpu->funcs->flush(gpu);
}
-struct a5xx_hwcg {
+static const struct {
u32 offset;
u32 value;
-};
-
-static const struct a5xx_hwcg a530_hwcg[] = {
+} a5xx_hwcg[] = {
{REG_A5XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
{REG_A5XX_RBBM_CLOCK_CNTL_SP1, 0x02222222},
{REG_A5XX_RBBM_CLOCK_CNTL_SP2, 0x02222222},
@@ -217,38 +230,16 @@ static const struct a5xx_hwcg a530_hwcg[] = {
{REG_A5XX_RBBM_CLOCK_DELAY_VFD, 0x00002222}
};
-static const struct {
- int (*test)(struct adreno_gpu *gpu);
- const struct a5xx_hwcg *regs;
- unsigned int count;
-} a5xx_hwcg_regs[] = {
- { adreno_is_a530, a530_hwcg, ARRAY_SIZE(a530_hwcg), },
-};
-
-static void _a5xx_enable_hwcg(struct msm_gpu *gpu,
- const struct a5xx_hwcg *regs, unsigned int count)
+void a5xx_set_hwcg(struct msm_gpu *gpu, bool state)
{
unsigned int i;
- for (i = 0; i < count; i++)
- gpu_write(gpu, regs[i].offset, regs[i].value);
+ for (i = 0; i < ARRAY_SIZE(a5xx_hwcg); i++)
+ gpu_write(gpu, a5xx_hwcg[i].offset,
+ state ? a5xx_hwcg[i].value : 0);
- gpu_write(gpu, REG_A5XX_RBBM_CLOCK_CNTL, 0xAAA8AA00);
- gpu_write(gpu, REG_A5XX_RBBM_ISDB_CNT, 0x182);
-}
-
-static void a5xx_enable_hwcg(struct msm_gpu *gpu)
-{
- struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(a5xx_hwcg_regs); i++) {
- if (a5xx_hwcg_regs[i].test(adreno_gpu)) {
- _a5xx_enable_hwcg(gpu, a5xx_hwcg_regs[i].regs,
- a5xx_hwcg_regs[i].count);
- return;
- }
- }
+ gpu_write(gpu, REG_A5XX_RBBM_CLOCK_CNTL, state ? 0xAAA8AA00 : 0);
+ gpu_write(gpu, REG_A5XX_RBBM_ISDB_CNT, state ? 0x182 : 0x180);
}
static int a5xx_me_init(struct msm_gpu *gpu)
@@ -293,28 +284,14 @@ static int a5xx_me_init(struct msm_gpu *gpu)
static struct drm_gem_object *a5xx_ucode_load_bo(struct msm_gpu *gpu,
const struct firmware *fw, u64 *iova)
{
- struct drm_device *drm = gpu->dev;
struct drm_gem_object *bo;
void *ptr;
- bo = msm_gem_new_locked(drm, fw->size - 4, MSM_BO_UNCACHED);
- if (IS_ERR(bo))
- return bo;
-
- ptr = msm_gem_get_vaddr(bo);
- if (!ptr) {
- drm_gem_object_unreference(bo);
- return ERR_PTR(-ENOMEM);
- }
-
- if (iova) {
- int ret = msm_gem_get_iova(bo, gpu->aspace, iova);
+ ptr = msm_gem_kernel_new_locked(gpu->dev, fw->size - 4,
+ MSM_BO_UNCACHED | MSM_BO_GPU_READONLY, gpu->aspace, &bo, iova);
- if (ret) {
- drm_gem_object_unreference(bo);
- return ERR_PTR(ret);
- }
- }
+ if (IS_ERR(ptr))
+ return ERR_CAST(ptr);
memcpy(ptr, &fw->data[4], fw->size - 4);
@@ -377,51 +354,11 @@ static int a5xx_zap_shader_resume(struct msm_gpu *gpu)
return ret;
}
-/* Set up a child device to "own" the zap shader */
-static int a5xx_zap_shader_dev_init(struct device *parent, struct device *dev)
-{
- struct device_node *node;
- int ret;
-
- if (dev->parent)
- return 0;
-
- /* Find the sub-node for the zap shader */
- node = of_get_child_by_name(parent->of_node, "zap-shader");
- if (!node) {
- DRM_DEV_ERROR(parent, "zap-shader not found in device tree\n");
- return -ENODEV;
- }
-
- dev->parent = parent;
- dev->of_node = node;
- dev_set_name(dev, "adreno_zap_shader");
-
- ret = device_register(dev);
- if (ret) {
- DRM_DEV_ERROR(parent, "Couldn't register zap shader device\n");
- goto out;
- }
-
- ret = of_reserved_mem_device_init(dev);
- if (ret) {
- DRM_DEV_ERROR(parent, "Unable to set up the reserved memory\n");
- device_unregister(dev);
- }
-
-out:
- if (ret)
- dev->parent = NULL;
-
- return ret;
-}
-
static int a5xx_zap_shader_init(struct msm_gpu *gpu)
{
static bool loaded;
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
- struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
- struct platform_device *pdev = a5xx_gpu->pdev;
+ struct platform_device *pdev = gpu->pdev;
int ret;
/*
@@ -444,11 +381,7 @@ static int a5xx_zap_shader_init(struct msm_gpu *gpu)
return -ENODEV;
}
- ret = a5xx_zap_shader_dev_init(&pdev->dev, &a5xx_gpu->zap_dev);
-
- if (!ret)
- ret = zap_shader_load_mdt(&a5xx_gpu->zap_dev,
- adreno_gpu->info->zapfw);
+ ret = zap_shader_load_mdt(&pdev->dev, adreno_gpu->info->zapfw);
loaded = !ret;
@@ -462,6 +395,7 @@ static int a5xx_zap_shader_init(struct msm_gpu *gpu)
A5XX_RBBM_INT_0_MASK_RBBM_ETS_MS_TIMEOUT | \
A5XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNC_OVERFLOW | \
A5XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
+ A5XX_RBBM_INT_0_MASK_MISC_HANG_DETECT | \
A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS | \
A5XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
A5XX_RBBM_INT_0_MASK_GPMU_VOLTAGE_DROOP)
@@ -545,7 +479,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL1, 0xA6FFFFFF);
/* Enable HWCG */
- a5xx_enable_hwcg(gpu);
+ a5xx_set_hwcg(gpu, true);
gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F);
@@ -691,9 +625,6 @@ static void a5xx_destroy(struct msm_gpu *gpu)
DBG("%s", gpu->name);
- if (a5xx_gpu->zap_dev.parent)
- device_unregister(&a5xx_gpu->zap_dev);
-
if (a5xx_gpu->pm4_bo) {
if (a5xx_gpu->pm4_iova)
msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->aspace);
@@ -867,6 +798,27 @@ static void a5xx_gpmu_err_irq(struct msm_gpu *gpu)
dev_err_ratelimited(gpu->dev->dev, "GPMU | voltage droop\n");
}
+static void a5xx_fault_detect_irq(struct msm_gpu *gpu)
+{
+ struct drm_device *dev = gpu->dev;
+ struct msm_drm_private *priv = dev->dev_private;
+
+ dev_err(dev->dev, "gpu fault fence %x status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n",
+ gpu->funcs->last_fence(gpu),
+ gpu_read(gpu, REG_A5XX_RBBM_STATUS),
+ gpu_read(gpu, REG_A5XX_CP_RB_RPTR),
+ gpu_read(gpu, REG_A5XX_CP_RB_WPTR),
+ gpu_read64(gpu, REG_A5XX_CP_IB1_BASE, REG_A5XX_CP_IB1_BASE_HI),
+ gpu_read(gpu, REG_A5XX_CP_IB1_BUFSZ),
+ gpu_read64(gpu, REG_A5XX_CP_IB2_BASE, REG_A5XX_CP_IB2_BASE_HI),
+ gpu_read(gpu, REG_A5XX_CP_IB2_BUFSZ));
+
+ /* Turn off the hangcheck timer to keep it from bothering us */
+ del_timer(&gpu->hangcheck_timer);
+
+ queue_work(priv->wq, &gpu->recover_work);
+}
+
#define RBBM_ERROR_MASK \
(A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR | \
A5XX_RBBM_INT_0_MASK_RBBM_TRANSFER_TIMEOUT | \
@@ -893,6 +845,9 @@ static irqreturn_t a5xx_irq(struct msm_gpu *gpu)
if (status & A5XX_RBBM_INT_0_MASK_CP_HW_ERROR)
a5xx_cp_err_irq(gpu);
+ if (status & A5XX_RBBM_INT_0_MASK_MISC_HANG_DETECT)
+ a5xx_fault_detect_irq(gpu);
+
if (status & A5XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
a5xx_uche_err_irq(gpu);
@@ -920,31 +875,30 @@ static const u32 a5xx_registers[] = {
0x0000, 0x0002, 0x0004, 0x0020, 0x0022, 0x0026, 0x0029, 0x002B,
0x002E, 0x0035, 0x0038, 0x0042, 0x0044, 0x0044, 0x0047, 0x0095,
0x0097, 0x00BB, 0x03A0, 0x0464, 0x0469, 0x046F, 0x04D2, 0x04D3,
- 0x04E0, 0x0533, 0x0540, 0x0555, 0xF400, 0xF400, 0xF800, 0xF807,
- 0x0800, 0x081A, 0x081F, 0x0841, 0x0860, 0x0860, 0x0880, 0x08A0,
- 0x0B00, 0x0B12, 0x0B15, 0x0B28, 0x0B78, 0x0B7F, 0x0BB0, 0x0BBD,
- 0x0BC0, 0x0BC6, 0x0BD0, 0x0C53, 0x0C60, 0x0C61, 0x0C80, 0x0C82,
- 0x0C84, 0x0C85, 0x0C90, 0x0C98, 0x0CA0, 0x0CA0, 0x0CB0, 0x0CB2,
- 0x2180, 0x2185, 0x2580, 0x2585, 0x0CC1, 0x0CC1, 0x0CC4, 0x0CC7,
- 0x0CCC, 0x0CCC, 0x0CD0, 0x0CD8, 0x0CE0, 0x0CE5, 0x0CE8, 0x0CE8,
- 0x0CEC, 0x0CF1, 0x0CFB, 0x0D0E, 0x2100, 0x211E, 0x2140, 0x2145,
- 0x2500, 0x251E, 0x2540, 0x2545, 0x0D10, 0x0D17, 0x0D20, 0x0D23,
- 0x0D30, 0x0D30, 0x20C0, 0x20C0, 0x24C0, 0x24C0, 0x0E40, 0x0E43,
- 0x0E4A, 0x0E4A, 0x0E50, 0x0E57, 0x0E60, 0x0E7C, 0x0E80, 0x0E8E,
- 0x0E90, 0x0E96, 0x0EA0, 0x0EA8, 0x0EB0, 0x0EB2, 0xE140, 0xE147,
- 0xE150, 0xE187, 0xE1A0, 0xE1A9, 0xE1B0, 0xE1B6, 0xE1C0, 0xE1C7,
- 0xE1D0, 0xE1D1, 0xE200, 0xE201, 0xE210, 0xE21C, 0xE240, 0xE268,
- 0xE000, 0xE006, 0xE010, 0xE09A, 0xE0A0, 0xE0A4, 0xE0AA, 0xE0EB,
- 0xE100, 0xE105, 0xE380, 0xE38F, 0xE3B0, 0xE3B0, 0xE400, 0xE405,
- 0xE408, 0xE4E9, 0xE4F0, 0xE4F0, 0xE280, 0xE280, 0xE282, 0xE2A3,
- 0xE2A5, 0xE2C2, 0xE940, 0xE947, 0xE950, 0xE987, 0xE9A0, 0xE9A9,
- 0xE9B0, 0xE9B6, 0xE9C0, 0xE9C7, 0xE9D0, 0xE9D1, 0xEA00, 0xEA01,
- 0xEA10, 0xEA1C, 0xEA40, 0xEA68, 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
+ 0x04E0, 0x0533, 0x0540, 0x0555, 0x0800, 0x081A, 0x081F, 0x0841,
+ 0x0860, 0x0860, 0x0880, 0x08A0, 0x0B00, 0x0B12, 0x0B15, 0x0B28,
+ 0x0B78, 0x0B7F, 0x0BB0, 0x0BBD, 0x0BC0, 0x0BC6, 0x0BD0, 0x0C53,
+ 0x0C60, 0x0C61, 0x0C80, 0x0C82, 0x0C84, 0x0C85, 0x0C90, 0x0C98,
+ 0x0CA0, 0x0CA0, 0x0CB0, 0x0CB2, 0x2180, 0x2185, 0x2580, 0x2585,
+ 0x0CC1, 0x0CC1, 0x0CC4, 0x0CC7, 0x0CCC, 0x0CCC, 0x0CD0, 0x0CD8,
+ 0x0CE0, 0x0CE5, 0x0CE8, 0x0CE8, 0x0CEC, 0x0CF1, 0x0CFB, 0x0D0E,
+ 0x2100, 0x211E, 0x2140, 0x2145, 0x2500, 0x251E, 0x2540, 0x2545,
+ 0x0D10, 0x0D17, 0x0D20, 0x0D23, 0x0D30, 0x0D30, 0x20C0, 0x20C0,
+ 0x24C0, 0x24C0, 0x0E40, 0x0E43, 0x0E4A, 0x0E4A, 0x0E50, 0x0E57,
+ 0x0E60, 0x0E7C, 0x0E80, 0x0E8E, 0x0E90, 0x0E96, 0x0EA0, 0x0EA8,
+ 0x0EB0, 0x0EB2, 0xE140, 0xE147, 0xE150, 0xE187, 0xE1A0, 0xE1A9,
+ 0xE1B0, 0xE1B6, 0xE1C0, 0xE1C7, 0xE1D0, 0xE1D1, 0xE200, 0xE201,
+ 0xE210, 0xE21C, 0xE240, 0xE268, 0xE000, 0xE006, 0xE010, 0xE09A,
+ 0xE0A0, 0xE0A4, 0xE0AA, 0xE0EB, 0xE100, 0xE105, 0xE380, 0xE38F,
+ 0xE3B0, 0xE3B0, 0xE400, 0xE405, 0xE408, 0xE4E9, 0xE4F0, 0xE4F0,
+ 0xE280, 0xE280, 0xE282, 0xE2A3, 0xE2A5, 0xE2C2, 0xE940, 0xE947,
+ 0xE950, 0xE987, 0xE9A0, 0xE9A9, 0xE9B0, 0xE9B6, 0xE9C0, 0xE9C7,
+ 0xE9D0, 0xE9D1, 0xEA00, 0xEA01, 0xEA10, 0xEA1C, 0xEA40, 0xEA68,
+ 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
};
static void a5xx_dump(struct msm_gpu *gpu)
@@ -1020,7 +974,14 @@ 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
@@ -1064,7 +1025,6 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
adreno_gpu = &a5xx_gpu->base;
gpu = &adreno_gpu->base;
- a5xx_gpu->pdev = pdev;
adreno_gpu->registers = a5xx_registers;
adreno_gpu->reg_offsets = a5xx_register_offsets;
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
index 6638bc85645d..e94451685bf8 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
@@ -23,7 +23,6 @@
struct a5xx_gpu {
struct adreno_gpu base;
- struct platform_device *pdev;
struct drm_gem_object *pm4_bo;
uint64_t pm4_iova;
@@ -36,8 +35,6 @@ struct a5xx_gpu {
uint32_t gpmu_dwords;
uint32_t lm_leakage;
-
- struct device zap_dev;
};
#define to_a5xx_gpu(x) container_of(x, struct a5xx_gpu, base)
@@ -59,5 +56,6 @@ static inline int spin_usecs(struct msm_gpu *gpu, uint32_t usecs,
}
bool a5xx_idle(struct msm_gpu *gpu);
+void a5xx_set_hwcg(struct msm_gpu *gpu, bool state);
#endif /* __A5XX_GPU_H__ */
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_power.c b/drivers/gpu/drm/msm/adreno/a5xx_power.c
index 87af6eea0483..04aab1dcae2b 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_power.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_power.c
@@ -294,16 +294,10 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu)
*/
bosize = (cmds_size + (cmds_size / TYPE4_MAX_PAYLOAD) + 1) << 2;
- a5xx_gpu->gpmu_bo = msm_gem_new_locked(drm, bosize, MSM_BO_UNCACHED);
- if (IS_ERR(a5xx_gpu->gpmu_bo))
- goto err;
-
- if (msm_gem_get_iova(a5xx_gpu->gpmu_bo, gpu->aspace,
- &a5xx_gpu->gpmu_iova))
- goto err;
-
- ptr = msm_gem_get_vaddr(a5xx_gpu->gpmu_bo);
- if (!ptr)
+ ptr = msm_gem_kernel_new_locked(drm, bosize,
+ MSM_BO_UNCACHED | MSM_BO_GPU_READONLY, gpu->aspace,
+ &a5xx_gpu->gpmu_bo, &a5xx_gpu->gpmu_iova);
+ if (IS_ERR(ptr))
goto err;
while (cmds_size > 0) {
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index f1ab2703674a..c8b4ac254bb5 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -48,8 +48,15 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value)
*value = adreno_gpu->base.fast_rate;
return 0;
case MSM_PARAM_TIMESTAMP:
- if (adreno_gpu->funcs->get_timestamp)
- return adreno_gpu->funcs->get_timestamp(gpu, value);
+ if (adreno_gpu->funcs->get_timestamp) {
+ int ret;
+
+ pm_runtime_get_sync(&gpu->pdev->dev);
+ ret = adreno_gpu->funcs->get_timestamp(gpu, value);
+ pm_runtime_put_autosuspend(&gpu->pdev->dev);
+
+ return ret;
+ }
return -EINVAL;
default:
DBG("%s: invalid param: %u", gpu->name, param);
@@ -330,11 +337,6 @@ void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords)
DRM_ERROR("%s: timeout waiting for ringbuffer space\n", gpu->name);
}
-static const char *iommu_ports[] = {
- "gfx3d_user", "gfx3d_priv",
- "gfx3d1_user", "gfx3d1_priv",
-};
-
int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
struct adreno_gpu *adreno_gpu, const struct adreno_gpu_funcs *funcs)
{
@@ -366,15 +368,15 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
adreno_gpu_config.ringsz = RB_SIZE;
+ pm_runtime_set_autosuspend_delay(&pdev->dev, DRM_MSM_INACTIVE_PERIOD);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+
ret = msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base,
adreno_gpu->info->name, &adreno_gpu_config);
if (ret)
return ret;
- pm_runtime_set_autosuspend_delay(&pdev->dev, DRM_MSM_INACTIVE_PERIOD);
- pm_runtime_use_autosuspend(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
-
ret = request_firmware(&adreno_gpu->pm4, adreno_gpu->info->pm4fw, drm->dev);
if (ret) {
dev_err(drm->dev, "failed to load %s PM4 firmware: %d\n",
@@ -389,37 +391,17 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
return ret;
}
- if (gpu->aspace && gpu->aspace->mmu) {
- struct msm_mmu *mmu = gpu->aspace->mmu;
- ret = mmu->funcs->attach(mmu, iommu_ports,
- ARRAY_SIZE(iommu_ports));
- if (ret)
- return ret;
- }
+ adreno_gpu->memptrs = msm_gem_kernel_new(drm,
+ sizeof(*adreno_gpu->memptrs), MSM_BO_UNCACHED, gpu->aspace,
+ &adreno_gpu->memptrs_bo, &adreno_gpu->memptrs_iova);
- adreno_gpu->memptrs_bo = msm_gem_new(drm, sizeof(*adreno_gpu->memptrs),
- MSM_BO_UNCACHED);
- if (IS_ERR(adreno_gpu->memptrs_bo)) {
- ret = PTR_ERR(adreno_gpu->memptrs_bo);
- adreno_gpu->memptrs_bo = NULL;
- dev_err(drm->dev, "could not allocate memptrs: %d\n", ret);
- return ret;
- }
-
- adreno_gpu->memptrs = msm_gem_get_vaddr(adreno_gpu->memptrs_bo);
if (IS_ERR(adreno_gpu->memptrs)) {
- dev_err(drm->dev, "could not vmap memptrs\n");
- return -ENOMEM;
- }
-
- ret = msm_gem_get_iova(adreno_gpu->memptrs_bo, gpu->aspace,
- &adreno_gpu->memptrs_iova);
- if (ret) {
- dev_err(drm->dev, "could not map memptrs: %d\n", ret);
- return ret;
+ ret = PTR_ERR(adreno_gpu->memptrs);
+ adreno_gpu->memptrs = NULL;
+ dev_err(drm->dev, "could not allocate memptrs: %d\n", ret);
}
- return 0;
+ return ret;
}
void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
@@ -439,10 +421,4 @@ void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
release_firmware(adreno_gpu->pfp);
msm_gpu_cleanup(gpu);
-
- if (gpu->aspace) {
- gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu,
- iommu_ports, ARRAY_SIZE(iommu_ports));
- msm_gem_address_space_put(gpu->aspace);
- }
}
diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c
index 311c1c1e7d6c..98742d7af6dc 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.c
+++ b/drivers/gpu/drm/msm/dsi/dsi.c
@@ -161,12 +161,17 @@ static const struct of_device_id dt_match[] = {
{}
};
+static const struct dev_pm_ops dsi_pm_ops = {
+ SET_RUNTIME_PM_OPS(msm_dsi_runtime_suspend, msm_dsi_runtime_resume, NULL)
+};
+
static struct platform_driver dsi_driver = {
.probe = dsi_dev_probe,
.remove = dsi_dev_remove,
.driver = {
.name = "msm_dsi",
.of_match_table = dt_match,
+ .pm = &dsi_pm_ops,
},
};
diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 9e6017387efb..2302046197a8 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -179,6 +179,8 @@ void msm_dsi_host_destroy(struct mipi_dsi_host *host);
int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
struct drm_device *dev);
int msm_dsi_host_init(struct msm_dsi *msm_dsi);
+int msm_dsi_runtime_suspend(struct device *dev);
+int msm_dsi_runtime_resume(struct device *dev);
/* dsi phy */
struct msm_dsi_phy;
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 9e9c5696bc03..dbb31a014419 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -135,7 +135,6 @@ struct msm_dsi_host {
struct completion video_comp;
struct mutex dev_mutex;
struct mutex cmd_mutex;
- struct mutex clk_mutex;
spinlock_t intr_lock; /* Protect interrupt ctrl register */
u32 err_work_state;
@@ -221,6 +220,8 @@ static const struct msm_dsi_cfg_handler *dsi_get_config(
goto put_gdsc;
}
+ pm_runtime_get_sync(dev);
+
ret = regulator_enable(gdsc_reg);
if (ret) {
pr_err("%s: unable to enable gdsc\n", __func__);
@@ -247,6 +248,7 @@ disable_clks:
clk_disable_unprepare(ahb_clk);
disable_gdsc:
regulator_disable(gdsc_reg);
+ pm_runtime_put_autosuspend(dev);
put_clk:
clk_put(ahb_clk);
put_gdsc:
@@ -455,6 +457,34 @@ static void dsi_bus_clk_disable(struct msm_dsi_host *msm_host)
clk_disable_unprepare(msm_host->bus_clks[i]);
}
+int msm_dsi_runtime_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct msm_dsi *msm_dsi = platform_get_drvdata(pdev);
+ struct mipi_dsi_host *host = msm_dsi->host;
+ struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+ if (!msm_host->cfg_hnd)
+ return 0;
+
+ dsi_bus_clk_disable(msm_host);
+
+ return 0;
+}
+
+int msm_dsi_runtime_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct msm_dsi *msm_dsi = platform_get_drvdata(pdev);
+ struct mipi_dsi_host *host = msm_dsi->host;
+ struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+ if (!msm_host->cfg_hnd)
+ return 0;
+
+ return dsi_bus_clk_enable(msm_host);
+}
+
static int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host)
{
int ret;
@@ -596,35 +626,6 @@ static void dsi_link_clk_disable(struct msm_dsi_host *msm_host)
}
}
-static int dsi_clk_ctrl(struct msm_dsi_host *msm_host, bool enable)
-{
- int ret = 0;
-
- mutex_lock(&msm_host->clk_mutex);
- if (enable) {
- ret = dsi_bus_clk_enable(msm_host);
- if (ret) {
- pr_err("%s: Can not enable bus clk, %d\n",
- __func__, ret);
- goto unlock_ret;
- }
- ret = dsi_link_clk_enable(msm_host);
- if (ret) {
- pr_err("%s: Can not enable link clk, %d\n",
- __func__, ret);
- dsi_bus_clk_disable(msm_host);
- goto unlock_ret;
- }
- } else {
- dsi_link_clk_disable(msm_host);
- dsi_bus_clk_disable(msm_host);
- }
-
-unlock_ret:
- mutex_unlock(&msm_host->clk_mutex);
- return ret;
-}
-
static int dsi_calc_clk_rate(struct msm_dsi_host *msm_host)
{
struct drm_display_mode *mode = msm_host->mode;
@@ -1699,6 +1700,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
}
msm_host->pdev = pdev;
+ msm_dsi->host = &msm_host->base;
ret = dsi_host_parse_dt(msm_host);
if (ret) {
@@ -1713,6 +1715,8 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
goto fail;
}
+ pm_runtime_enable(&pdev->dev);
+
msm_host->cfg_hnd = dsi_get_config(msm_host);
if (!msm_host->cfg_hnd) {
ret = -EINVAL;
@@ -1753,7 +1757,6 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
init_completion(&msm_host->video_comp);
mutex_init(&msm_host->dev_mutex);
mutex_init(&msm_host->cmd_mutex);
- mutex_init(&msm_host->clk_mutex);
spin_lock_init(&msm_host->intr_lock);
/* setup workqueue */
@@ -1761,7 +1764,6 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
INIT_WORK(&msm_host->err_work, dsi_err_worker);
INIT_WORK(&msm_host->hpd_work, dsi_hpd_worker);
- msm_dsi->host = &msm_host->base;
msm_dsi->id = msm_host->id;
DBG("Dsi Host %d initialized", msm_host->id);
@@ -1783,9 +1785,10 @@ void msm_dsi_host_destroy(struct mipi_dsi_host *host)
msm_host->workqueue = NULL;
}
- mutex_destroy(&msm_host->clk_mutex);
mutex_destroy(&msm_host->cmd_mutex);
mutex_destroy(&msm_host->dev_mutex);
+
+ pm_runtime_disable(&msm_host->pdev->dev);
}
int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
@@ -1881,7 +1884,8 @@ int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host,
* mdss interrupt is generated in mdp core clock domain
* mdp clock need to be enabled to receive dsi interrupt
*/
- dsi_clk_ctrl(msm_host, 1);
+ pm_runtime_get_sync(&msm_host->pdev->dev);
+ dsi_link_clk_enable(msm_host);
/* TODO: vote for bus bandwidth */
@@ -1911,7 +1915,8 @@ void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host,
/* TODO: unvote for bus bandwidth */
- dsi_clk_ctrl(msm_host, 0);
+ dsi_link_clk_disable(msm_host);
+ pm_runtime_put_autosuspend(&msm_host->pdev->dev);
}
int msm_dsi_host_cmd_tx(struct mipi_dsi_host *host,
@@ -2137,6 +2142,13 @@ void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host,
struct msm_dsi_phy_clk_request *clk_req)
{
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+ int ret;
+
+ ret = dsi_calc_clk_rate(msm_host);
+ if (ret) {
+ pr_err("%s: unable to calc clk rate, %d\n", __func__, ret);
+ return;
+ }
clk_req->bitclk_rate = msm_host->byte_clk_rate * 8;
clk_req->escclk_rate = msm_host->esc_clk_rate;
@@ -2153,8 +2165,11 @@ int msm_dsi_host_enable(struct mipi_dsi_host *host)
* and only turned on before MDP START.
* This part of code should be enabled once mdp driver support it.
*/
- /* if (msm_panel->mode == MSM_DSI_CMD_MODE)
- dsi_clk_ctrl(msm_host, 0); */
+ /* if (msm_panel->mode == MSM_DSI_CMD_MODE) {
+ * dsi_link_clk_disable(msm_host);
+ * pm_runtime_put_autosuspend(&msm_host->pdev->dev);
+ * }
+ */
return 0;
}
@@ -2210,9 +2225,11 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
goto unlock_ret;
}
- ret = dsi_clk_ctrl(msm_host, 1);
+ pm_runtime_get_sync(&msm_host->pdev->dev);
+ ret = dsi_link_clk_enable(msm_host);
if (ret) {
- pr_err("%s: failed to enable clocks. ret=%d\n", __func__, ret);
+ pr_err("%s: failed to enable link clocks. ret=%d\n",
+ __func__, ret);
goto fail_disable_reg;
}
@@ -2236,7 +2253,8 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
return 0;
fail_disable_clk:
- dsi_clk_ctrl(msm_host, 0);
+ dsi_link_clk_disable(msm_host);
+ pm_runtime_put_autosuspend(&msm_host->pdev->dev);
fail_disable_reg:
dsi_host_regulator_disable(msm_host);
unlock_ret:
@@ -2261,7 +2279,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host)
pinctrl_pm_select_sleep_state(&msm_host->pdev->dev);
- dsi_clk_ctrl(msm_host, 0);
+ dsi_link_clk_disable(msm_host);
+ pm_runtime_put_autosuspend(&msm_host->pdev->dev);
dsi_host_regulator_disable(msm_host);
@@ -2280,7 +2299,6 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host,
struct drm_display_mode *mode)
{
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
- int ret;
if (msm_host->mode) {
drm_mode_destroy(msm_host->dev, msm_host->mode);
@@ -2293,12 +2311,6 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host,
return -ENOMEM;
}
- ret = dsi_calc_clk_rate(msm_host);
- if (ret) {
- pr_err("%s: unable to calc clk rate, %d\n", __func__, ret);
- return ret;
- }
-
return 0;
}
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index a879ffa534b4..855248132b2b 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -626,7 +626,6 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge,
}
static const struct drm_connector_funcs dsi_mgr_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = dsi_mgr_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = dsi_mgr_connector_destroy,
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
index 0c2eb9c9a1fc..7c9bf91bc22b 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
@@ -373,7 +373,7 @@ static int dsi_phy_enable_resource(struct msm_dsi_phy *phy)
static void dsi_phy_disable_resource(struct msm_dsi_phy *phy)
{
clk_disable_unprepare(phy->ahb_clk);
- pm_runtime_put_sync(&phy->pdev->dev);
+ pm_runtime_put_autosuspend(&phy->pdev->dev);
}
static const struct of_device_id dsi_phy_dt_match[] = {
diff --git a/drivers/gpu/drm/msm/edp/edp_connector.c b/drivers/gpu/drm/msm/edp/edp_connector.c
index 5960628ceb93..6f3fc6b0f0a3 100644
--- a/drivers/gpu/drm/msm/edp/edp_connector.c
+++ b/drivers/gpu/drm/msm/edp/edp_connector.c
@@ -92,7 +92,6 @@ static int edp_connector_mode_valid(struct drm_connector *connector,
}
static const struct drm_connector_funcs edp_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = edp_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = edp_connector_destroy,
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index a968cad509c2..17e069a133a4 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -239,6 +239,8 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev)
hdmi->pwr_clks[i] = clk;
}
+ pm_runtime_enable(&pdev->dev);
+
hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0);
hdmi->i2c = msm_hdmi_i2c_init(hdmi);
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index ae40e7179d4f..7e357077ed26 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -35,6 +35,8 @@ static void msm_hdmi_power_on(struct drm_bridge *bridge)
const struct hdmi_platform_config *config = hdmi->config;
int i, ret;
+ pm_runtime_get_sync(&hdmi->pdev->dev);
+
for (i = 0; i < config->pwr_reg_cnt; i++) {
ret = regulator_enable(hdmi->pwr_regs[i]);
if (ret) {
@@ -84,6 +86,8 @@ static void power_off(struct drm_bridge *bridge)
config->pwr_reg_names[i], ret);
}
}
+
+ pm_runtime_put_autosuspend(&hdmi->pdev->dev);
}
#define AVI_IFRAME_LINE_NUMBER 1
@@ -97,7 +101,7 @@ static void msm_hdmi_config_avi_infoframe(struct hdmi *hdmi)
u32 val;
int len;
- drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode);
+ drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false);
len = hdmi_infoframe_pack(&frame, buffer, sizeof(buffer));
if (len < 0) {
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
index a2515b466ce5..c0848dfedd50 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
@@ -137,6 +137,36 @@ err:
return ret;
}
+static void enable_hpd_clocks(struct hdmi *hdmi, bool enable)
+{
+ const struct hdmi_platform_config *config = hdmi->config;
+ struct device *dev = &hdmi->pdev->dev;
+ int i, ret;
+
+ if (enable) {
+ for (i = 0; i < config->hpd_clk_cnt; i++) {
+ if (config->hpd_freq && config->hpd_freq[i]) {
+ ret = clk_set_rate(hdmi->hpd_clks[i],
+ config->hpd_freq[i]);
+ if (ret)
+ dev_warn(dev,
+ "failed to set clk %s (%d)\n",
+ config->hpd_clk_names[i], ret);
+ }
+
+ ret = clk_prepare_enable(hdmi->hpd_clks[i]);
+ if (ret) {
+ dev_err(dev,
+ "failed to enable hpd clk: %s (%d)\n",
+ config->hpd_clk_names[i], ret);
+ }
+ }
+ } else {
+ for (i = config->hpd_clk_cnt - 1; i >= 0; i--)
+ clk_disable_unprepare(hdmi->hpd_clks[i]);
+ }
+}
+
static int hpd_enable(struct hdmi_connector *hdmi_connector)
{
struct hdmi *hdmi = hdmi_connector->hdmi;
@@ -167,22 +197,8 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector)
goto fail;
}
- for (i = 0; i < config->hpd_clk_cnt; i++) {
- if (config->hpd_freq && config->hpd_freq[i]) {
- ret = clk_set_rate(hdmi->hpd_clks[i],
- config->hpd_freq[i]);
- if (ret)
- dev_warn(dev, "failed to set clk %s (%d)\n",
- config->hpd_clk_names[i], ret);
- }
-
- ret = clk_prepare_enable(hdmi->hpd_clks[i]);
- if (ret) {
- dev_err(dev, "failed to enable hpd clk: %s (%d)\n",
- config->hpd_clk_names[i], ret);
- goto fail;
- }
- }
+ pm_runtime_get_sync(dev);
+ enable_hpd_clocks(hdmi, true);
msm_hdmi_set_mode(hdmi, false);
msm_hdmi_phy_reset(hdmi);
@@ -225,8 +241,8 @@ static void hdp_disable(struct hdmi_connector *hdmi_connector)
msm_hdmi_set_mode(hdmi, false);
- for (i = 0; i < config->hpd_clk_cnt; i++)
- clk_disable_unprepare(hdmi->hpd_clks[i]);
+ enable_hpd_clocks(hdmi, false);
+ pm_runtime_put_autosuspend(dev);
ret = gpio_config(hdmi, false);
if (ret)
@@ -285,7 +301,16 @@ void msm_hdmi_connector_irq(struct drm_connector *connector)
static enum drm_connector_status detect_reg(struct hdmi *hdmi)
{
- uint32_t hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
+ uint32_t hpd_int_status;
+
+ pm_runtime_get_sync(&hdmi->pdev->dev);
+ enable_hpd_clocks(hdmi, true);
+
+ hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
+
+ enable_hpd_clocks(hdmi, false);
+ pm_runtime_put_autosuspend(&hdmi->pdev->dev);
+
return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ?
connector_status_connected : connector_status_disconnected;
}
@@ -407,7 +432,6 @@ static int msm_hdmi_connector_mode_valid(struct drm_connector *connector,
}
static const struct drm_connector_funcs hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = hdmi_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = hdmi_connector_destroy,
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
index 615e1def64d9..47fa2aba1983 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
@@ -279,7 +279,8 @@ static void mdp4_crtc_mode_set_nofb(struct drm_crtc *crtc)
}
}
-static void mdp4_crtc_disable(struct drm_crtc *crtc)
+static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
struct mdp4_kms *mdp4_kms = get_kms(crtc);
@@ -295,7 +296,8 @@ static void mdp4_crtc_disable(struct drm_crtc *crtc)
mdp4_crtc->enabled = false;
}
-static void mdp4_crtc_enable(struct drm_crtc *crtc)
+static void mdp4_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
struct mdp4_kms *mdp4_kms = get_kms(crtc);
@@ -482,7 +484,6 @@ static const struct drm_crtc_funcs mdp4_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.destroy = mdp4_crtc_destroy,
.page_flip = drm_atomic_helper_page_flip,
- .set_property = drm_atomic_helper_crtc_set_property,
.cursor_set = mdp4_crtc_cursor_set,
.cursor_move = mdp4_crtc_cursor_move,
.reset = drm_atomic_helper_crtc_reset,
@@ -492,11 +493,11 @@ static const struct drm_crtc_funcs mdp4_crtc_funcs = {
static const struct drm_crtc_helper_funcs mdp4_crtc_helper_funcs = {
.mode_set_nofb = mdp4_crtc_mode_set_nofb,
- .disable = mdp4_crtc_disable,
- .enable = mdp4_crtc_enable,
.atomic_check = mdp4_crtc_atomic_check,
.atomic_begin = mdp4_crtc_atomic_begin,
.atomic_flush = mdp4_crtc_atomic_flush,
+ .atomic_enable = mdp4_crtc_atomic_enable,
+ .atomic_disable = mdp4_crtc_atomic_disable,
};
static void mdp4_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus)
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
index bcd1f5cac72c..f7f087419ed8 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
@@ -114,7 +114,7 @@ static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *st
mdp4_enable(mdp4_kms);
/* see 119ecb7fd */
- for_each_crtc_in_state(state, crtc, crtc_state, i)
+ for_each_new_crtc_in_state(state, crtc, crtc_state, i)
drm_crtc_vblank_get(crtc);
}
@@ -126,7 +126,7 @@ static void mdp4_complete_commit(struct msm_kms *kms, struct drm_atomic_state *s
struct drm_crtc_state *crtc_state;
/* see 119ecb7fd */
- for_each_crtc_in_state(state, crtc, crtc_state, i)
+ for_each_new_crtc_in_state(state, crtc, crtc_state, i)
drm_crtc_vblank_put(crtc);
mdp4_disable(mdp4_kms);
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c
index 353429b05733..e3b1c86b7aae 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c
@@ -91,7 +91,6 @@ static int mdp4_lvds_connector_mode_valid(struct drm_connector *connector,
}
static const struct drm_connector_funcs mdp4_lvds_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = mdp4_lvds_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = mdp4_lvds_connector_destroy,
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
index a20e3d644523..7a1ad3af08e3 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
@@ -401,7 +401,7 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev,
type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
ret = drm_universal_plane_init(dev, plane, 0xff, &mdp4_plane_funcs,
mdp4_plane->formats, mdp4_plane->nformats,
- type, NULL);
+ NULL, type, NULL);
if (ret)
goto fail;
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c
index aa7402e03f67..60790df91bfa 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_cmd_encoder.c
@@ -192,6 +192,7 @@ int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
{
struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder);
struct mdp5_kms *mdp5_kms;
+ struct device *dev;
int intf_num;
u32 data = 0;
@@ -214,14 +215,16 @@ int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
/* Smart Panel, Sync mode */
data |= MDP5_SPLIT_DPL_UPPER_SMART_PANEL;
+ dev = &mdp5_kms->pdev->dev;
+
/* Make sure clocks are on when connectors calling this function. */
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_UPPER, data);
mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_LOWER,
MDP5_SPLIT_DPL_LOWER_SMART_PANEL);
mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_EN, 1);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
return 0;
}
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
index cb5415d6c04b..6fcb58ab718c 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
@@ -221,8 +221,8 @@ static void blend_setup(struct drm_crtc *crtc)
struct mdp5_ctl *ctl = mdp5_cstate->ctl;
uint32_t blend_op, fg_alpha, bg_alpha, ctl_blend_flags = 0;
unsigned long flags;
- enum mdp5_pipe stage[STAGE_MAX + 1][MAX_PIPE_STAGE] = { SSPP_NONE };
- enum mdp5_pipe r_stage[STAGE_MAX + 1][MAX_PIPE_STAGE] = { SSPP_NONE };
+ enum mdp5_pipe stage[STAGE_MAX + 1][MAX_PIPE_STAGE] = { { SSPP_NONE } };
+ enum mdp5_pipe r_stage[STAGE_MAX + 1][MAX_PIPE_STAGE] = { { SSPP_NONE } };
int i, plane_cnt = 0;
bool bg_alpha_enabled = false;
u32 mixer_op_mode = 0;
@@ -409,11 +409,13 @@ static void mdp5_crtc_mode_set_nofb(struct drm_crtc *crtc)
spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags);
}
-static void mdp5_crtc_disable(struct drm_crtc *crtc)
+static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
struct mdp5_kms *mdp5_kms = get_kms(crtc);
+ struct device *dev = &mdp5_kms->pdev->dev;
DBG("%s", crtc->name);
@@ -424,23 +426,28 @@ static void mdp5_crtc_disable(struct drm_crtc *crtc)
mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->pp_done);
mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->err);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
mdp5_crtc->enabled = false;
}
-static void mdp5_crtc_enable(struct drm_crtc *crtc)
+static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
struct mdp5_kms *mdp5_kms = get_kms(crtc);
+ struct device *dev = &mdp5_kms->pdev->dev;
DBG("%s", crtc->name);
if (WARN_ON(mdp5_crtc->enabled))
return;
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
+
+ mdp5_crtc_mode_set_nofb(crtc);
+
mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err);
if (mdp5_cstate->cmd_mode)
@@ -531,7 +538,7 @@ static bool is_fullscreen(struct drm_crtc_state *cstate,
((pstate->crtc_y + pstate->crtc_h) >= cstate->mode.vdisplay);
}
-enum mdp_mixer_stage_id get_start_stage(struct drm_crtc *crtc,
+static enum mdp_mixer_stage_id get_start_stage(struct drm_crtc *crtc,
struct drm_crtc_state *new_crtc_state,
struct drm_plane_state *bpstate)
{
@@ -725,6 +732,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline;
struct drm_device *dev = crtc->dev;
struct mdp5_kms *mdp5_kms = get_kms(crtc);
+ struct platform_device *pdev = mdp5_kms->pdev;
struct msm_kms *kms = &mdp5_kms->base.base;
struct drm_gem_object *cursor_bo, *old_bo = NULL;
uint32_t blendcfg, stride;
@@ -753,6 +761,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
if (!handle) {
DBG("Cursor off");
cursor_enable = false;
+ pm_runtime_get_sync(&pdev->dev);
goto set_cursor;
}
@@ -767,6 +776,8 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
lm = mdp5_cstate->pipeline.mixer->lm;
stride = width * drm_format_plane_cpp(DRM_FORMAT_ARGB8888, 0);
+ pm_runtime_get_sync(&pdev->dev);
+
spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags);
old_bo = mdp5_crtc->cursor.scanout_bo;
@@ -793,6 +804,8 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags);
+ pm_runtime_put_autosuspend(&pdev->dev);
+
set_cursor:
ret = mdp5_ctl_set_cursor(ctl, pipeline, 0, cursor_enable);
if (ret) {
@@ -804,6 +817,7 @@ set_cursor:
crtc_flush(crtc, flush_mask);
end:
+ pm_runtime_put_autosuspend(&pdev->dev);
if (old_bo) {
drm_flip_work_queue(&mdp5_crtc->unref_cursor_work, old_bo);
/* enable vblank to complete cursor work: */
@@ -836,6 +850,8 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
get_roi(crtc, &roi_w, &roi_h);
+ pm_runtime_get_sync(&mdp5_kms->pdev->dev);
+
spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags);
mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(lm),
MDP5_LM_CURSOR_SIZE_ROI_H(roi_h) |
@@ -847,6 +863,8 @@ static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
crtc_flush(crtc, flush_mask);
+ pm_runtime_put_autosuspend(&mdp5_kms->pdev->dev);
+
return 0;
}
@@ -917,7 +935,6 @@ static const struct drm_crtc_funcs mdp5_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.destroy = mdp5_crtc_destroy,
.page_flip = drm_atomic_helper_page_flip,
- .set_property = drm_atomic_helper_crtc_set_property,
.reset = mdp5_crtc_reset,
.atomic_duplicate_state = mdp5_crtc_duplicate_state,
.atomic_destroy_state = mdp5_crtc_destroy_state,
@@ -930,7 +947,6 @@ static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = {
.set_config = drm_atomic_helper_set_config,
.destroy = mdp5_crtc_destroy,
.page_flip = drm_atomic_helper_page_flip,
- .set_property = drm_atomic_helper_crtc_set_property,
.reset = mdp5_crtc_reset,
.atomic_duplicate_state = mdp5_crtc_duplicate_state,
.atomic_destroy_state = mdp5_crtc_destroy_state,
@@ -939,11 +955,11 @@ static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = {
static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = {
.mode_set_nofb = mdp5_crtc_mode_set_nofb,
- .disable = mdp5_crtc_disable,
- .enable = mdp5_crtc_enable,
.atomic_check = mdp5_crtc_atomic_check,
.atomic_begin = mdp5_crtc_atomic_begin,
.atomic_flush = mdp5_crtc_atomic_flush,
+ .atomic_enable = mdp5_crtc_atomic_enable,
+ .atomic_disable = mdp5_crtc_atomic_disable,
};
static void mdp5_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
index 97f3294fbfc6..5b851380d3f2 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c
@@ -297,9 +297,13 @@ static void mdp5_encoder_enable(struct drm_encoder *encoder)
{
struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
struct mdp5_interface *intf = mdp5_encoder->intf;
+ /* this isn't right I think */
+ struct drm_crtc_state *cstate = encoder->crtc->state;
+
+ mdp5_encoder_mode_set(encoder, &cstate->mode, &cstate->adjusted_mode);
if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
- mdp5_cmd_encoder_disable(encoder);
+ mdp5_cmd_encoder_enable(encoder);
else
mdp5_vid_encoder_enable(encoder);
}
@@ -320,7 +324,6 @@ static int mdp5_encoder_atomic_check(struct drm_encoder *encoder,
}
static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = {
- .mode_set = mdp5_encoder_mode_set,
.disable = mdp5_encoder_disable,
.enable = mdp5_encoder_enable,
.atomic_check = mdp5_encoder_atomic_check,
@@ -350,6 +353,7 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder,
struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
struct mdp5_encoder *mdp5_slave_enc = to_mdp5_encoder(slave_encoder);
struct mdp5_kms *mdp5_kms;
+ struct device *dev;
int intf_num;
u32 data = 0;
@@ -369,8 +373,10 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder,
else
return -EINVAL;
+ dev = &mdp5_kms->pdev->dev;
/* Make sure clocks are on when connectors calling this function. */
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
+
/* Dumb Panel, Sync mode */
mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_UPPER, 0);
mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_LOWER, data);
@@ -378,7 +384,7 @@ int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder,
mdp5_ctl_pair(mdp5_encoder->ctl, mdp5_slave_enc->ctl, true);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
return 0;
}
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
index 3ce8b9dec9c1..bb5deb00c899 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
@@ -49,16 +49,19 @@ static void mdp5_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus)
void mdp5_irq_preinstall(struct msm_kms *kms)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
- mdp5_enable(mdp5_kms);
+ struct device *dev = &mdp5_kms->pdev->dev;
+
+ pm_runtime_get_sync(dev);
mdp5_write(mdp5_kms, REG_MDP5_INTR_CLEAR, 0xffffffff);
mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
}
int mdp5_irq_postinstall(struct msm_kms *kms)
{
struct mdp_kms *mdp_kms = to_mdp_kms(kms);
struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms);
+ struct device *dev = &mdp5_kms->pdev->dev;
struct mdp_irq *error_handler = &mdp5_kms->error_handler;
error_handler->irq = mdp5_irq_error_handler;
@@ -67,9 +70,9 @@ int mdp5_irq_postinstall(struct msm_kms *kms)
MDP5_IRQ_INTF2_UNDER_RUN |
MDP5_IRQ_INTF3_UNDER_RUN;
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
mdp_irq_register(mdp_kms, error_handler);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
return 0;
}
@@ -77,9 +80,11 @@ int mdp5_irq_postinstall(struct msm_kms *kms)
void mdp5_irq_uninstall(struct msm_kms *kms)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
- mdp5_enable(mdp5_kms);
+ struct device *dev = &mdp5_kms->pdev->dev;
+
+ pm_runtime_get_sync(dev);
mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
}
irqreturn_t mdp5_irq(struct msm_kms *kms)
@@ -109,11 +114,12 @@ irqreturn_t mdp5_irq(struct msm_kms *kms)
int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+ struct device *dev = &mdp5_kms->pdev->dev;
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
mdp_update_vblank_mask(to_mdp_kms(kms),
mdp5_crtc_vblank(crtc), true);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
return 0;
}
@@ -121,9 +127,10 @@ int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+ struct device *dev = &mdp5_kms->pdev->dev;
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
mdp_update_vblank_mask(to_mdp_kms(kms),
mdp5_crtc_vblank(crtc), false);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
}
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 5d13fa5381ee..f7c0698fec40 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -30,11 +30,10 @@ static const char *iommu_ports[] = {
static int mdp5_hw_init(struct msm_kms *kms)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
- struct platform_device *pdev = mdp5_kms->pdev;
+ struct device *dev = &mdp5_kms->pdev->dev;
unsigned long flags;
- pm_runtime_get_sync(&pdev->dev);
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
/* Magic unknown register writes:
*
@@ -66,8 +65,7 @@ static int mdp5_hw_init(struct msm_kms *kms)
mdp5_ctlm_hw_reset(mdp5_kms->ctlm);
- mdp5_disable(mdp5_kms);
- pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_put_sync(dev);
return 0;
}
@@ -111,8 +109,9 @@ static void mdp5_swap_state(struct msm_kms *kms, struct drm_atomic_state *state)
static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+ struct device *dev = &mdp5_kms->pdev->dev;
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
if (mdp5_kms->smp)
mdp5_smp_prepare_commit(mdp5_kms->smp, &mdp5_kms->state->smp);
@@ -121,11 +120,12 @@ static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *st
static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+ struct device *dev = &mdp5_kms->pdev->dev;
if (mdp5_kms->smp)
mdp5_smp_complete_commit(mdp5_kms->smp, &mdp5_kms->state->smp);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
}
static void mdp5_wait_for_crtc_commit_done(struct msm_kms *kms,
@@ -249,6 +249,9 @@ int mdp5_disable(struct mdp5_kms *mdp5_kms)
{
DBG("");
+ mdp5_kms->enable_count--;
+ WARN_ON(mdp5_kms->enable_count < 0);
+
clk_disable_unprepare(mdp5_kms->ahb_clk);
clk_disable_unprepare(mdp5_kms->axi_clk);
clk_disable_unprepare(mdp5_kms->core_clk);
@@ -262,6 +265,8 @@ int mdp5_enable(struct mdp5_kms *mdp5_kms)
{
DBG("");
+ mdp5_kms->enable_count++;
+
clk_prepare_enable(mdp5_kms->ahb_clk);
clk_prepare_enable(mdp5_kms->axi_clk);
clk_prepare_enable(mdp5_kms->core_clk);
@@ -486,11 +491,12 @@ fail:
static void read_mdp_hw_revision(struct mdp5_kms *mdp5_kms,
u32 *major, u32 *minor)
{
+ struct device *dev = &mdp5_kms->pdev->dev;
u32 version;
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(dev);
version = mdp5_read(mdp5_kms, REG_MDP5_HW_VERSION);
- mdp5_disable(mdp5_kms);
+ pm_runtime_put_autosuspend(dev);
*major = FIELD(version, MDP5_HW_VERSION_MAJOR);
*minor = FIELD(version, MDP5_HW_VERSION_MINOR);
@@ -502,7 +508,7 @@ static int get_clk(struct platform_device *pdev, struct clk **clkp,
const char *name, bool mandatory)
{
struct device *dev = &pdev->dev;
- struct clk *clk = devm_clk_get(dev, name);
+ struct clk *clk = msm_clk_get(pdev, name);
if (IS_ERR(clk) && mandatory) {
dev_err(dev, "failed to get %s (%ld)\n", name, PTR_ERR(clk));
return PTR_ERR(clk);
@@ -643,7 +649,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
* have left things on, in which case we'll start getting faults if
* we don't disable):
*/
- mdp5_enable(mdp5_kms);
+ pm_runtime_get_sync(&pdev->dev);
for (i = 0; i < MDP5_INTF_NUM_MAX; i++) {
if (mdp5_cfg_intf_is_virtual(config->hw->intf.connect[i]) ||
!config->hw->intf.base[i])
@@ -652,7 +658,6 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
mdp5_write(mdp5_kms, REG_MDP5_INTF_FRAME_LINE_COUNT_EN(i), 0x3);
}
- mdp5_disable(mdp5_kms);
mdelay(16);
if (config->platform.iommu) {
@@ -678,6 +683,8 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
aspace = NULL;;
}
+ pm_runtime_put_autosuspend(&pdev->dev);
+
ret = modeset_init(mdp5_kms);
if (ret) {
dev_err(&pdev->dev, "modeset_init failed: %d\n", ret);
@@ -887,21 +894,21 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
}
/* mandatory clocks: */
- ret = get_clk(pdev, &mdp5_kms->axi_clk, "bus_clk", true);
+ ret = get_clk(pdev, &mdp5_kms->axi_clk, "bus", true);
if (ret)
goto fail;
- ret = get_clk(pdev, &mdp5_kms->ahb_clk, "iface_clk", true);
+ ret = get_clk(pdev, &mdp5_kms->ahb_clk, "iface", true);
if (ret)
goto fail;
- ret = get_clk(pdev, &mdp5_kms->core_clk, "core_clk", true);
+ ret = get_clk(pdev, &mdp5_kms->core_clk, "core", true);
if (ret)
goto fail;
- ret = get_clk(pdev, &mdp5_kms->vsync_clk, "vsync_clk", true);
+ ret = get_clk(pdev, &mdp5_kms->vsync_clk, "vsync", true);
if (ret)
goto fail;
/* optional clocks: */
- get_clk(pdev, &mdp5_kms->lut_clk, "lut_clk", false);
+ get_clk(pdev, &mdp5_kms->lut_clk, "lut", false);
/* we need to set a default rate before enabling. Set a safe
* rate first, then figure out hw revision, and then set a
@@ -1005,6 +1012,30 @@ static int mdp5_dev_remove(struct platform_device *pdev)
return 0;
}
+static __maybe_unused int mdp5_runtime_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
+
+ DBG("");
+
+ return mdp5_disable(mdp5_kms);
+}
+
+static __maybe_unused int mdp5_runtime_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
+
+ DBG("");
+
+ return mdp5_enable(mdp5_kms);
+}
+
+static const struct dev_pm_ops mdp5_pm_ops = {
+ SET_RUNTIME_PM_OPS(mdp5_runtime_suspend, mdp5_runtime_resume, NULL)
+};
+
static const struct of_device_id mdp5_dt_match[] = {
{ .compatible = "qcom,mdp5", },
/* to support downstream DT files */
@@ -1019,6 +1050,7 @@ static struct platform_driver mdp5_driver = {
.driver = {
.name = "msm_mdp",
.of_match_table = mdp5_dt_match,
+ .pm = &mdp5_pm_ops,
},
};
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
index 17caa0e8c8ae..9b3fe01089d1 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
@@ -76,6 +76,8 @@ struct mdp5_kms {
bool rpm_enabled;
struct mdp_irq error_handler;
+
+ int enable_count;
};
#define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base)
@@ -167,11 +169,13 @@ struct mdp5_encoder {
static inline void mdp5_write(struct mdp5_kms *mdp5_kms, u32 reg, u32 data)
{
+ WARN_ON(mdp5_kms->enable_count <= 0);
msm_writel(data, mdp5_kms->mmio + reg);
}
static inline u32 mdp5_read(struct mdp5_kms *mdp5_kms, u32 reg)
{
+ WARN_ON(mdp5_kms->enable_count <= 0);
return msm_readl(mdp5_kms->mmio + reg);
}
@@ -255,9 +259,6 @@ static inline uint32_t lm2ppdone(struct mdp5_hw_mixer *mixer)
return MDP5_IRQ_PING_PONG_0_DONE << mixer->pp;
}
-int mdp5_disable(struct mdp5_kms *mdp5_kms);
-int mdp5_enable(struct mdp5_kms *mdp5_kms);
-
void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
uint32_t old_irqmask);
void mdp5_irq_preinstall(struct msm_kms *kms);
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c
index 9c34d7824988..f2a0db7a8a03 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mdss.c
@@ -31,6 +31,10 @@ struct msm_mdss {
struct regulator *vdd;
+ struct clk *ahb_clk;
+ struct clk *axi_clk;
+ struct clk *vsync_clk;
+
struct {
volatile unsigned long enabled_mask;
struct irq_domain *domain;
@@ -140,6 +144,51 @@ static int mdss_irq_domain_init(struct msm_mdss *mdss)
return 0;
}
+int msm_mdss_enable(struct msm_mdss *mdss)
+{
+ DBG("");
+
+ clk_prepare_enable(mdss->ahb_clk);
+ if (mdss->axi_clk)
+ clk_prepare_enable(mdss->axi_clk);
+ if (mdss->vsync_clk)
+ clk_prepare_enable(mdss->vsync_clk);
+
+ return 0;
+}
+
+int msm_mdss_disable(struct msm_mdss *mdss)
+{
+ DBG("");
+
+ if (mdss->vsync_clk)
+ clk_disable_unprepare(mdss->vsync_clk);
+ if (mdss->axi_clk)
+ clk_disable_unprepare(mdss->axi_clk);
+ clk_disable_unprepare(mdss->ahb_clk);
+
+ return 0;
+}
+
+static int msm_mdss_get_clocks(struct msm_mdss *mdss)
+{
+ struct platform_device *pdev = to_platform_device(mdss->dev->dev);
+
+ mdss->ahb_clk = msm_clk_get(pdev, "iface");
+ if (IS_ERR(mdss->ahb_clk))
+ mdss->ahb_clk = NULL;
+
+ mdss->axi_clk = msm_clk_get(pdev, "bus");
+ if (IS_ERR(mdss->axi_clk))
+ mdss->axi_clk = NULL;
+
+ mdss->vsync_clk = msm_clk_get(pdev, "vsync");
+ if (IS_ERR(mdss->vsync_clk))
+ mdss->vsync_clk = NULL;
+
+ return 0;
+}
+
void msm_mdss_destroy(struct drm_device *dev)
{
struct msm_drm_private *priv = dev->dev_private;
@@ -153,8 +202,6 @@ void msm_mdss_destroy(struct drm_device *dev)
regulator_disable(mdss->vdd);
- pm_runtime_put_sync(dev->dev);
-
pm_runtime_disable(dev->dev);
}
@@ -190,6 +237,12 @@ int msm_mdss_init(struct drm_device *dev)
goto fail;
}
+ ret = msm_mdss_get_clocks(mdss);
+ if (ret) {
+ dev_err(dev->dev, "failed to get clocks: %d\n", ret);
+ goto fail;
+ }
+
/* Regulator to enable GDSCs in downstream kernels */
mdss->vdd = devm_regulator_get(dev->dev, "vdd");
if (IS_ERR(mdss->vdd)) {
@@ -221,12 +274,6 @@ int msm_mdss_init(struct drm_device *dev)
pm_runtime_enable(dev->dev);
- /*
- * TODO: This is needed as the MDSS GDSC is only tied to MDSS's power
- * domain. Remove this once runtime PM is adapted for all the devices.
- */
- pm_runtime_get_sync(dev->dev);
-
return 0;
fail_irq:
regulator_disable(mdss->vdd);
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
index fe3a4de1a433..4b22ac3413a1 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
@@ -246,7 +246,6 @@ static const struct drm_plane_funcs mdp5_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = mdp5_plane_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
.atomic_set_property = mdp5_plane_atomic_set_property,
.atomic_get_property = mdp5_plane_atomic_get_property,
.reset = mdp5_plane_reset,
@@ -259,7 +258,6 @@ static const struct drm_plane_funcs mdp5_cursor_plane_funcs = {
.update_plane = mdp5_update_cursor_plane_legacy,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = mdp5_plane_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
.atomic_set_property = mdp5_plane_atomic_set_property,
.atomic_get_property = mdp5_plane_atomic_get_property,
.reset = mdp5_plane_reset,
@@ -890,8 +888,8 @@ static int mdp5_plane_mode_set(struct drm_plane *plane,
struct mdp5_hw_pipe *right_hwpipe;
const struct mdp_format *format;
uint32_t nplanes, config = 0;
- struct phase_step step = { 0 };
- struct pixel_ext pe = { 0 };
+ struct phase_step step = { { 0 } };
+ struct pixel_ext pe = { { 0 } };
uint32_t hdecm = 0, vdecm = 0;
uint32_t pix_format;
unsigned int rotation;
@@ -1139,12 +1137,12 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev,
ret = drm_universal_plane_init(dev, plane, 0xff,
&mdp5_cursor_plane_funcs,
mdp5_plane->formats, mdp5_plane->nformats,
- type, NULL);
+ NULL, type, NULL);
else
ret = drm_universal_plane_init(dev, plane, 0xff,
&mdp5_plane_funcs,
mdp5_plane->formats, mdp5_plane->nformats,
- type, NULL);
+ NULL, type, NULL);
if (ret)
goto fail;
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c
index 58f712d37e7f..ae4983d9d0a5 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c
@@ -28,6 +28,13 @@ struct mdp5_smp {
int blk_cnt;
int blk_size;
+
+ /* register cache */
+ u32 alloc_w[22];
+ u32 alloc_r[22];
+ u32 pipe_reqprio_fifo_wm0[SSPP_MAX];
+ u32 pipe_reqprio_fifo_wm1[SSPP_MAX];
+ u32 pipe_reqprio_fifo_wm2[SSPP_MAX];
};
static inline
@@ -98,16 +105,15 @@ static int smp_request_block(struct mdp5_smp *smp,
static void set_fifo_thresholds(struct mdp5_smp *smp,
enum mdp5_pipe pipe, int nblks)
{
- struct mdp5_kms *mdp5_kms = get_kms(smp);
u32 smp_entries_per_blk = smp->blk_size / (128 / BITS_PER_BYTE);
u32 val;
/* 1/4 of SMP pool that is being fetched */
val = (nblks * smp_entries_per_blk) / 4;
- mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_0(pipe), val * 1);
- mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_1(pipe), val * 2);
- mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_2(pipe), val * 3);
+ smp->pipe_reqprio_fifo_wm0[pipe] = val * 1;
+ smp->pipe_reqprio_fifo_wm1[pipe] = val * 2;
+ smp->pipe_reqprio_fifo_wm2[pipe] = val * 3;
}
/*
@@ -222,7 +228,6 @@ void mdp5_smp_release(struct mdp5_smp *smp, struct mdp5_smp_state *state,
static unsigned update_smp_state(struct mdp5_smp *smp,
u32 cid, mdp5_smp_state_t *assigned)
{
- struct mdp5_kms *mdp5_kms = get_kms(smp);
int cnt = smp->blk_cnt;
unsigned nblks = 0;
u32 blk, val;
@@ -231,7 +236,7 @@ static unsigned update_smp_state(struct mdp5_smp *smp,
int idx = blk / 3;
int fld = blk % 3;
- val = mdp5_read(mdp5_kms, REG_MDP5_SMP_ALLOC_W_REG(idx));
+ val = smp->alloc_w[idx];
switch (fld) {
case 0:
@@ -248,8 +253,8 @@ static unsigned update_smp_state(struct mdp5_smp *smp,
break;
}
- mdp5_write(mdp5_kms, REG_MDP5_SMP_ALLOC_W_REG(idx), val);
- mdp5_write(mdp5_kms, REG_MDP5_SMP_ALLOC_R_REG(idx), val);
+ smp->alloc_w[idx] = val;
+ smp->alloc_r[idx] = val;
nblks++;
}
@@ -257,6 +262,39 @@ static unsigned update_smp_state(struct mdp5_smp *smp,
return nblks;
}
+static void write_smp_alloc_regs(struct mdp5_smp *smp)
+{
+ struct mdp5_kms *mdp5_kms = get_kms(smp);
+ int i, num_regs;
+
+ num_regs = smp->blk_cnt / 3 + 1;
+
+ for (i = 0; i < num_regs; i++) {
+ mdp5_write(mdp5_kms, REG_MDP5_SMP_ALLOC_W_REG(i),
+ smp->alloc_w[i]);
+ mdp5_write(mdp5_kms, REG_MDP5_SMP_ALLOC_R_REG(i),
+ smp->alloc_r[i]);
+ }
+}
+
+static void write_smp_fifo_regs(struct mdp5_smp *smp)
+{
+ struct mdp5_kms *mdp5_kms = get_kms(smp);
+ int i;
+
+ for (i = 0; i < mdp5_kms->num_hwpipes; i++) {
+ struct mdp5_hw_pipe *hwpipe = mdp5_kms->hwpipes[i];
+ enum mdp5_pipe pipe = hwpipe->pipe;
+
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_0(pipe),
+ smp->pipe_reqprio_fifo_wm0[pipe]);
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_1(pipe),
+ smp->pipe_reqprio_fifo_wm1[pipe]);
+ mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_2(pipe),
+ smp->pipe_reqprio_fifo_wm2[pipe]);
+ }
+}
+
void mdp5_smp_prepare_commit(struct mdp5_smp *smp, struct mdp5_smp_state *state)
{
enum mdp5_pipe pipe;
@@ -277,6 +315,9 @@ void mdp5_smp_prepare_commit(struct mdp5_smp *smp, struct mdp5_smp_state *state)
set_fifo_thresholds(smp, pipe, nblks);
}
+ write_smp_alloc_regs(smp);
+ write_smp_fifo_regs(smp);
+
state->assigned = 0;
}
@@ -289,6 +330,8 @@ void mdp5_smp_complete_commit(struct mdp5_smp *smp, struct mdp5_smp_state *state
set_fifo_thresholds(smp, pipe, 0);
}
+ write_smp_fifo_regs(smp);
+
state->released = 0;
}
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index 9633a68b14d7..025d454163b0 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -84,13 +84,13 @@ static void msm_atomic_wait_for_commit_done(struct drm_device *dev,
struct drm_atomic_state *old_state)
{
struct drm_crtc *crtc;
- struct drm_crtc_state *crtc_state;
+ struct drm_crtc_state *new_crtc_state;
struct msm_drm_private *priv = old_state->dev->dev_private;
struct msm_kms *kms = priv->kms;
int i;
- for_each_crtc_in_state(old_state, crtc, crtc_state, i) {
- if (!crtc->state->enable)
+ for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
+ if (!new_crtc_state->active)
continue;
kms->funcs->wait_for_crtc_commit_done(kms, crtc);
@@ -195,7 +195,7 @@ int msm_atomic_commit(struct drm_device *dev,
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
struct drm_plane *plane;
- struct drm_plane_state *plane_state;
+ struct drm_plane_state *old_plane_state, *new_plane_state;
int i, ret;
ret = drm_atomic_helper_prepare_planes(dev, state);
@@ -211,19 +211,19 @@ int msm_atomic_commit(struct drm_device *dev,
/*
* Figure out what crtcs we have:
*/
- for_each_crtc_in_state(state, crtc, crtc_state, i)
+ for_each_new_crtc_in_state(state, crtc, crtc_state, i)
c->crtc_mask |= drm_crtc_mask(crtc);
/*
* Figure out what fence to wait for:
*/
- for_each_plane_in_state(state, plane, plane_state, i) {
- if ((plane->state->fb != plane_state->fb) && plane_state->fb) {
- struct drm_gem_object *obj = msm_framebuffer_bo(plane_state->fb, 0);
+ for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
+ if ((new_plane_state->fb != old_plane_state->fb) && new_plane_state->fb) {
+ struct drm_gem_object *obj = msm_framebuffer_bo(new_plane_state->fb, 0);
struct msm_gem_object *msm_obj = to_msm_bo(obj);
struct dma_fence *fence = reservation_object_get_excl_rcu(msm_obj->resv);
- drm_atomic_set_fence_for_plane(plane_state, fence);
+ drm_atomic_set_fence_for_plane(new_plane_state, fence);
}
}
@@ -232,20 +232,18 @@ int msm_atomic_commit(struct drm_device *dev,
* mark our set of crtc's as busy:
*/
ret = start_atomic(dev->dev_private, c->crtc_mask);
- if (ret) {
- kfree(c);
- goto error;
- }
+ if (ret)
+ goto err_free;
+
+ BUG_ON(drm_atomic_helper_swap_state(state, false) < 0);
/*
* This is the point of no return - everything below never fails except
* when the hw goes bonghits. Which means we can commit the new state on
* the software side now.
+ *
+ * swap driver private state while still holding state_lock
*/
-
- drm_atomic_helper_swap_state(state, true);
-
- /* swap driver private state while still holding state_lock */
if (to_kms_state(state)->state)
priv->kms->funcs->swap_state(priv->kms, state);
@@ -275,6 +273,8 @@ int msm_atomic_commit(struct drm_device *dev,
return 0;
+err_free:
+ kfree(c);
error:
drm_atomic_helper_cleanup_planes(dev, state);
return ret;
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index f49f6ac5585c..606df7bea97b 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -73,6 +73,10 @@ bool dumpstate = false;
MODULE_PARM_DESC(dumpstate, "Dump KMS state on errors");
module_param(dumpstate, bool, 0600);
+static bool modeset = true;
+MODULE_PARM_DESC(modeset, "Use kernel modesetting [KMS] (1=on (default), 0=disable)");
+module_param(modeset, bool, 0600);
+
/*
* Util/helpers:
*/
@@ -832,7 +836,6 @@ static struct drm_driver msm_driver = {
.gem_vm_ops = &vm_ops,
.dumb_create = msm_gem_dumb_create,
.dumb_map_offset = msm_gem_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_export = drm_gem_prime_export,
@@ -879,8 +882,37 @@ static int msm_pm_resume(struct device *dev)
}
#endif
+#ifdef CONFIG_PM
+static int msm_runtime_suspend(struct device *dev)
+{
+ struct drm_device *ddev = dev_get_drvdata(dev);
+ struct msm_drm_private *priv = ddev->dev_private;
+
+ DBG("");
+
+ if (priv->mdss)
+ return msm_mdss_disable(priv->mdss);
+
+ return 0;
+}
+
+static int msm_runtime_resume(struct device *dev)
+{
+ struct drm_device *ddev = dev_get_drvdata(dev);
+ struct msm_drm_private *priv = ddev->dev_private;
+
+ DBG("");
+
+ if (priv->mdss)
+ return msm_mdss_enable(priv->mdss);
+
+ return 0;
+}
+#endif
+
static const struct dev_pm_ops msm_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(msm_pm_suspend, msm_pm_resume)
+ SET_RUNTIME_PM_OPS(msm_runtime_suspend, msm_runtime_resume, NULL)
};
/*
@@ -1104,6 +1136,9 @@ static struct platform_driver msm_platform_driver = {
static int __init msm_drm_register(void)
{
+ if (!modeset)
+ return -EINVAL;
+
DBG("init");
msm_mdp_register();
msm_dsi_register();
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index fc8d24f7c084..5e8109c07560 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -55,8 +55,6 @@ struct msm_fence_cb;
struct msm_gem_address_space;
struct msm_gem_vma;
-#define NUM_DOMAINS 2 /* one for KMS, then one per gpu core (?) */
-
struct msm_file_private {
/* currently we don't do anything useful with this.. but when
* per-context address spaces are supported we'd keep track of
@@ -237,6 +235,12 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev,
uint32_t size, uint32_t flags);
struct drm_gem_object *msm_gem_new_locked(struct drm_device *dev,
uint32_t size, uint32_t flags);
+void *msm_gem_kernel_new(struct drm_device *dev, uint32_t size,
+ uint32_t flags, struct msm_gem_address_space *aspace,
+ struct drm_gem_object **bo, uint64_t *iova);
+void *msm_gem_kernel_new_locked(struct drm_device *dev, uint32_t size,
+ uint32_t flags, struct msm_gem_address_space *aspace,
+ struct drm_gem_object **bo, uint64_t *iova);
struct drm_gem_object *msm_gem_import(struct drm_device *dev,
struct dma_buf *dmabuf, struct sg_table *sgt);
@@ -248,10 +252,10 @@ uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb,
struct msm_gem_address_space *aspace, int plane);
struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane);
const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb);
-struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
- const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos);
struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd);
+struct drm_framebuffer * msm_alloc_stolen_fb(struct drm_device *dev,
+ int w, int h, int p, uint32_t format);
struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev);
void msm_fbdev_free(struct drm_device *dev);
diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
index 6ecb7b170316..fc175e724ad6 100644
--- a/drivers/gpu/drm/msm/msm_fb.c
+++ b/drivers/gpu/drm/msm/msm_fb.c
@@ -20,6 +20,7 @@
#include "msm_drv.h"
#include "msm_kms.h"
+#include "msm_gem.h"
struct msm_framebuffer {
struct drm_framebuffer base;
@@ -28,6 +29,8 @@ struct msm_framebuffer {
};
#define to_msm_framebuffer(x) container_of(x, struct msm_framebuffer, base)
+static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
+ const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos);
static int msm_framebuffer_create_handle(struct drm_framebuffer *fb,
struct drm_file *file_priv,
@@ -161,7 +164,7 @@ out_unref:
return ERR_PTR(ret);
}
-struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
+static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos)
{
struct msm_drm_private *priv = dev->dev_private;
@@ -237,3 +240,43 @@ fail:
return ERR_PTR(ret);
}
+
+struct drm_framebuffer *
+msm_alloc_stolen_fb(struct drm_device *dev, int w, int h, int p, uint32_t format)
+{
+ struct drm_mode_fb_cmd2 mode_cmd = {
+ .pixel_format = format,
+ .width = w,
+ .height = h,
+ .pitches = { p },
+ };
+ struct drm_gem_object *bo;
+ struct drm_framebuffer *fb;
+ int size;
+
+ /* allocate backing bo */
+ size = mode_cmd.pitches[0] * mode_cmd.height;
+ DBG("allocating %d bytes for fb %d", size, dev->primary->index);
+ bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC | MSM_BO_STOLEN);
+ if (IS_ERR(bo)) {
+ dev_warn(dev->dev, "could not allocate stolen bo\n");
+ /* try regular bo: */
+ bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC);
+ }
+ if (IS_ERR(bo)) {
+ dev_err(dev->dev, "failed to allocate buffer object\n");
+ return ERR_CAST(bo);
+ }
+
+ fb = msm_framebuffer_init(dev, &mode_cmd, &bo);
+ if (IS_ERR(fb)) {
+ dev_err(dev->dev, "failed to allocate fb\n");
+ /* note: if fb creation failed, we can't rely on fb destroy
+ * to unref the bo:
+ */
+ drm_gem_object_unreference_unlocked(bo);
+ return ERR_CAST(fb);
+ }
+
+ return fb;
+}
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index 5ecf4ff9a059..c178563fcd4d 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -19,7 +19,6 @@
#include <drm/drm_fb_helper.h>
#include "msm_drv.h"
-#include "msm_gem.h"
#include "msm_kms.h"
extern int msm_gem_mmap_obj(struct drm_gem_object *obj,
@@ -35,7 +34,6 @@ static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma);
struct msm_fbdev {
struct drm_fb_helper base;
struct drm_framebuffer *fb;
- struct drm_gem_object *bo;
};
static struct fb_ops msm_fb_ops = {
@@ -57,16 +55,16 @@ static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
struct drm_fb_helper *helper = (struct drm_fb_helper *)info->par;
struct msm_fbdev *fbdev = to_msm_fbdev(helper);
- struct drm_gem_object *drm_obj = fbdev->bo;
+ struct drm_gem_object *bo = msm_framebuffer_bo(fbdev->fb, 0);
int ret = 0;
- ret = drm_gem_mmap_obj(drm_obj, drm_obj->size, vma);
+ ret = drm_gem_mmap_obj(bo, bo->size, vma);
if (ret) {
pr_err("%s:drm_gem_mmap_obj fail\n", __func__);
return ret;
}
- return msm_gem_mmap_obj(drm_obj, vma);
+ return msm_gem_mmap_obj(bo, vma);
}
static int msm_fbdev_create(struct drm_fb_helper *helper,
@@ -76,47 +74,30 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
struct drm_device *dev = helper->dev;
struct msm_drm_private *priv = dev->dev_private;
struct drm_framebuffer *fb = NULL;
+ struct drm_gem_object *bo;
struct fb_info *fbi = NULL;
- struct drm_mode_fb_cmd2 mode_cmd = {0};
uint64_t paddr;
- int ret, size;
+ uint32_t format;
+ int ret, pitch;
+
+ format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth);
DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width,
sizes->surface_height, sizes->surface_bpp,
sizes->fb_width, sizes->fb_height);
- mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
- sizes->surface_depth);
-
- mode_cmd.width = sizes->surface_width;
- mode_cmd.height = sizes->surface_height;
-
- mode_cmd.pitches[0] = align_pitch(
- mode_cmd.width, sizes->surface_bpp);
+ pitch = align_pitch(sizes->surface_width, sizes->surface_bpp);
+ fb = msm_alloc_stolen_fb(dev, sizes->surface_width,
+ sizes->surface_height, pitch, format);
- /* allocate backing bo */
- size = mode_cmd.pitches[0] * mode_cmd.height;
- DBG("allocating %d bytes for fb %d", size, dev->primary->index);
- fbdev->bo = msm_gem_new(dev, size, MSM_BO_SCANOUT |
- MSM_BO_WC | MSM_BO_STOLEN);
- if (IS_ERR(fbdev->bo)) {
- ret = PTR_ERR(fbdev->bo);
- fbdev->bo = NULL;
- dev_err(dev->dev, "failed to allocate buffer object: %d\n", ret);
- goto fail;
- }
-
- fb = msm_framebuffer_init(dev, &mode_cmd, &fbdev->bo);
if (IS_ERR(fb)) {
dev_err(dev->dev, "failed to allocate fb\n");
- /* note: if fb creation failed, we can't rely on fb destroy
- * to unref the bo:
- */
- drm_gem_object_unreference_unlocked(fbdev->bo);
ret = PTR_ERR(fb);
goto fail;
}
+ bo = msm_framebuffer_bo(fb, 0);
+
mutex_lock(&dev->struct_mutex);
/*
@@ -124,7 +105,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
* in panic (ie. lock-safe, etc) we could avoid pinning the
* buffer now:
*/
- ret = msm_gem_get_iova(fbdev->bo, priv->kms->aspace, &paddr);
+ ret = msm_gem_get_iova(bo, priv->kms->aspace, &paddr);
if (ret) {
dev_err(dev->dev, "failed to get buffer obj iova: %d\n", ret);
goto fail_unlock;
@@ -143,7 +124,6 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
helper->fb = fb;
fbi->par = helper;
- fbi->flags = FBINFO_DEFAULT;
fbi->fbops = &msm_fb_ops;
strcpy(fbi->fix.id, "msm");
@@ -153,14 +133,14 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
dev->mode_config.fb_base = paddr;
- fbi->screen_base = msm_gem_get_vaddr(fbdev->bo);
+ fbi->screen_base = msm_gem_get_vaddr(bo);
if (IS_ERR(fbi->screen_base)) {
ret = PTR_ERR(fbi->screen_base);
goto fail_unlock;
}
- fbi->screen_size = fbdev->bo->size;
+ fbi->screen_size = bo->size;
fbi->fix.smem_start = paddr;
- fbi->fix.smem_len = fbdev->bo->size;
+ fbi->fix.smem_len = bo->size;
DBG("par=%p, %dx%d", fbi->par, fbi->var.xres, fbi->var.yres);
DBG("allocated %dx%d fb", fbdev->fb->width, fbdev->fb->height);
@@ -242,7 +222,9 @@ void msm_fbdev_free(struct drm_device *dev)
/* this will free the backing object */
if (fbdev->fb) {
- msm_gem_put_vaddr(fbdev->bo);
+ struct drm_gem_object *bo =
+ msm_framebuffer_bo(fbdev->fb, 0);
+ msm_gem_put_vaddr(bo);
drm_framebuffer_remove(fbdev->fb);
}
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 65f35544c1ec..f15821a0d900 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -383,8 +383,10 @@ int msm_gem_get_iova(struct drm_gem_object *obj,
struct page **pages;
vma = add_vma(obj, aspace);
- if (IS_ERR(vma))
- return PTR_ERR(vma);
+ if (IS_ERR(vma)) {
+ ret = PTR_ERR(vma);
+ goto unlock;
+ }
pages = get_pages(obj);
if (IS_ERR(pages)) {
@@ -405,7 +407,7 @@ int msm_gem_get_iova(struct drm_gem_object *obj,
fail:
del_vma(vma);
-
+unlock:
mutex_unlock(&msm_obj->lock);
return ret;
}
@@ -928,8 +930,12 @@ static struct drm_gem_object *_msm_gem_new(struct drm_device *dev,
if (use_vram) {
struct msm_gem_vma *vma;
struct page **pages;
+ struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+ mutex_lock(&msm_obj->lock);
vma = add_vma(obj, NULL);
+ mutex_unlock(&msm_obj->lock);
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
goto fail;
@@ -1018,3 +1024,49 @@ fail:
drm_gem_object_unreference_unlocked(obj);
return ERR_PTR(ret);
}
+
+static void *_msm_gem_kernel_new(struct drm_device *dev, uint32_t size,
+ uint32_t flags, struct msm_gem_address_space *aspace,
+ struct drm_gem_object **bo, uint64_t *iova, bool locked)
+{
+ void *vaddr;
+ struct drm_gem_object *obj = _msm_gem_new(dev, size, flags, locked);
+ int ret;
+
+ if (IS_ERR(obj))
+ return ERR_CAST(obj);
+
+ if (iova) {
+ ret = msm_gem_get_iova(obj, aspace, iova);
+ if (ret) {
+ drm_gem_object_unreference(obj);
+ return ERR_PTR(ret);
+ }
+ }
+
+ vaddr = msm_gem_get_vaddr(obj);
+ if (!vaddr) {
+ msm_gem_put_iova(obj, aspace);
+ drm_gem_object_unreference(obj);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ if (bo)
+ *bo = obj;
+
+ return vaddr;
+}
+
+void *msm_gem_kernel_new(struct drm_device *dev, uint32_t size,
+ uint32_t flags, struct msm_gem_address_space *aspace,
+ struct drm_gem_object **bo, uint64_t *iova)
+{
+ return _msm_gem_kernel_new(dev, size, flags, aspace, bo, iova, false);
+}
+
+void *msm_gem_kernel_new_locked(struct drm_device *dev, uint32_t size,
+ uint32_t flags, struct msm_gem_address_space *aspace,
+ struct drm_gem_object **bo, uint64_t *iova)
+{
+ return _msm_gem_kernel_new(dev, size, flags, aspace, bo, iova, true);
+}
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index 6bfca7470141..8a75c0bd8a78 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -34,8 +34,8 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev,
struct msm_gpu *gpu, uint32_t nr_bos, uint32_t nr_cmds)
{
struct msm_gem_submit *submit;
- uint64_t sz = sizeof(*submit) + (nr_bos * sizeof(submit->bos[0])) +
- (nr_cmds * sizeof(submit->cmd[0]));
+ uint64_t sz = sizeof(*submit) + ((u64)nr_bos * sizeof(submit->bos[0])) +
+ ((u64)nr_cmds * sizeof(submit->cmd[0]));
if (sz > SIZE_MAX)
return NULL;
@@ -451,7 +451,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
if (ret)
goto out;
- if (!(args->fence & MSM_SUBMIT_NO_IMPLICIT)) {
+ if (!(args->flags & MSM_SUBMIT_NO_IMPLICIT)) {
ret = submit_fence_sync(submit);
if (ret)
goto out;
diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c
index c36321bc8714..d34e331554f3 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -42,7 +42,7 @@ void
msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
struct msm_gem_vma *vma, struct sg_table *sgt)
{
- if (!vma->iova)
+ if (!aspace || !vma->iova)
return;
if (aspace->mmu) {
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 9f3dbc236ab3..ffbff27600e0 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -562,11 +562,49 @@ static int get_clocks(struct platform_device *pdev, struct msm_gpu *gpu)
return 0;
}
+static struct msm_gem_address_space *
+msm_gpu_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev,
+ uint64_t va_start, uint64_t va_end)
+{
+ struct iommu_domain *iommu;
+ struct msm_gem_address_space *aspace;
+ int ret;
+
+ /*
+ * Setup IOMMU.. eventually we will (I think) do this once per context
+ * and have separate page tables per context. For now, to keep things
+ * simple and to get something working, just use a single address space:
+ */
+ iommu = iommu_domain_alloc(&platform_bus_type);
+ if (!iommu)
+ return NULL;
+
+ iommu->geometry.aperture_start = va_start;
+ iommu->geometry.aperture_end = va_end;
+
+ dev_info(gpu->dev->dev, "%s: using IOMMU\n", gpu->name);
+
+ aspace = msm_gem_address_space_create(&pdev->dev, iommu, "gpu");
+ if (IS_ERR(aspace)) {
+ dev_err(gpu->dev->dev, "failed to init iommu: %ld\n",
+ PTR_ERR(aspace));
+ iommu_domain_free(iommu);
+ return ERR_CAST(aspace);
+ }
+
+ ret = aspace->mmu->funcs->attach(aspace->mmu, NULL, 0);
+ if (ret) {
+ msm_gem_address_space_put(aspace);
+ return ERR_PTR(ret);
+ }
+
+ return aspace;
+}
+
int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs,
const char *name, struct msm_gpu_config *config)
{
- struct iommu_domain *iommu;
int ret;
if (WARN_ON(gpu->num_perfcntrs > ARRAY_SIZE(gpu->last_cntrs)))
@@ -636,28 +674,19 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
if (IS_ERR(gpu->gpu_cx))
gpu->gpu_cx = NULL;
- /* Setup IOMMU.. eventually we will (I think) do this once per context
- * and have separate page tables per context. For now, to keep things
- * simple and to get something working, just use a single address space:
- */
- iommu = iommu_domain_alloc(&platform_bus_type);
- if (iommu) {
- iommu->geometry.aperture_start = config->va_start;
- iommu->geometry.aperture_end = config->va_end;
-
- dev_info(drm->dev, "%s: using IOMMU\n", name);
- gpu->aspace = msm_gem_address_space_create(&pdev->dev,
- iommu, "gpu");
- if (IS_ERR(gpu->aspace)) {
- ret = PTR_ERR(gpu->aspace);
- dev_err(drm->dev, "failed to init iommu: %d\n", ret);
- gpu->aspace = NULL;
- iommu_domain_free(iommu);
- goto fail;
- }
+ gpu->pdev = pdev;
+ platform_set_drvdata(pdev, gpu);
+
+ bs_init(gpu);
- } else {
+ gpu->aspace = msm_gpu_create_address_space(gpu, pdev,
+ config->va_start, config->va_end);
+
+ if (gpu->aspace == NULL)
dev_info(drm->dev, "%s: no IOMMU, fallback to VRAM carveout!\n", name);
+ else if (IS_ERR(gpu->aspace)) {
+ ret = PTR_ERR(gpu->aspace);
+ goto fail;
}
/* Create ringbuffer: */
@@ -669,14 +698,10 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
goto fail;
}
- gpu->pdev = pdev;
- platform_set_drvdata(pdev, gpu);
-
- bs_init(gpu);
-
return 0;
fail:
+ platform_set_drvdata(pdev, NULL);
return ret;
}
@@ -693,7 +718,9 @@ void msm_gpu_cleanup(struct msm_gpu *gpu)
msm_gem_put_iova(gpu->rb->bo, gpu->aspace);
msm_ringbuffer_destroy(gpu->rb);
}
-
- if (gpu->fctx)
- msm_fence_context_free(gpu->fctx);
+ if (gpu->aspace) {
+ gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu,
+ NULL, 0);
+ msm_gem_address_space_put(gpu->aspace);
+ }
}
diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
index a8f2ba5e5f07..17d5824417ad 100644
--- a/drivers/gpu/drm/msm/msm_kms.h
+++ b/drivers/gpu/drm/msm/msm_kms.h
@@ -99,5 +99,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev);
struct msm_kms *mdp5_kms_init(struct drm_device *dev);
int msm_mdss_init(struct drm_device *dev);
void msm_mdss_destroy(struct drm_device *dev);
+int msm_mdss_enable(struct msm_mdss *mdss);
+int msm_mdss_disable(struct msm_mdss *mdss);
#endif /* __MSM_KMS_H__ */
diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c
index 791bca3c6a9c..bf065a540130 100644
--- a/drivers/gpu/drm/msm/msm_ringbuffer.c
+++ b/drivers/gpu/drm/msm/msm_ringbuffer.c
@@ -33,16 +33,14 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int size)
}
ring->gpu = gpu;
- ring->bo = msm_gem_new(gpu->dev, size, MSM_BO_WC);
- if (IS_ERR(ring->bo)) {
- ret = PTR_ERR(ring->bo);
- ring->bo = NULL;
- goto fail;
- }
- ring->start = msm_gem_get_vaddr(ring->bo);
+ /* Pass NULL for the iova pointer - we will map it later */
+ ring->start = msm_gem_kernel_new(gpu->dev, size, MSM_BO_WC,
+ gpu->aspace, &ring->bo, NULL);
+
if (IS_ERR(ring->start)) {
ret = PTR_ERR(ring->start);
+ ring->start = 0;
goto fail;
}
ring->end = ring->start + (size / 4);
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index d1b9c34c7c00..7fbad9cb656e 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -190,7 +190,7 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags)
}
ret = drm_simple_display_pipe_init(drm, &mxsfb->pipe, &mxsfb_funcs,
- mxsfb_formats, ARRAY_SIZE(mxsfb_formats),
+ mxsfb_formats, ARRAY_SIZE(mxsfb_formats), NULL,
&mxsfb->connector);
if (ret < 0) {
dev_err(drm->dev, "Cannot setup simple display pipe\n");
@@ -256,7 +256,6 @@ static void mxsfb_unload(struct drm_device *drm)
drm_kms_helper_poll_fini(drm);
drm_mode_config_cleanup(drm);
- drm_vblank_cleanup(drm);
pm_runtime_get_sync(drm->dev);
drm_irq_uninstall(drm);
@@ -335,11 +334,9 @@ static struct drm_driver mxsfb_driver = {
.irq_uninstall = mxsfb_irq_preinstall,
.enable_vblank = mxsfb_enable_vblank,
.disable_vblank = mxsfb_disable_vblank,
- .gem_free_object = drm_gem_cma_free_object,
+ .gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_export = drm_gem_prime_export,
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_out.c b/drivers/gpu/drm/mxsfb/mxsfb_out.c
index f7d729aa09bd..e5edf016a439 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_out.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_out.c
@@ -74,7 +74,6 @@ static void mxsfb_panel_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs mxsfb_panel_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = mxsfb_panel_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = mxsfb_panel_connector_destroy,
diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
index 4b4b0b496262..6aa6ee16dcbd 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
@@ -764,13 +764,18 @@ nv_crtc_gamma_load(struct drm_crtc *crtc)
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct drm_device *dev = nv_crtc->base.dev;
struct rgb { uint8_t r, g, b; } __attribute__((packed)) *rgbs;
+ u16 *r, *g, *b;
int i;
rgbs = (struct rgb *)nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index].DAC;
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
+
for (i = 0; i < 256; i++) {
- rgbs[i].r = nv_crtc->lut.r[i] >> 8;
- rgbs[i].g = nv_crtc->lut.g[i] >> 8;
- rgbs[i].b = nv_crtc->lut.b[i] >> 8;
+ rgbs[i].r = *r++ >> 8;
+ rgbs[i].g = *g++ >> 8;
+ rgbs[i].b = *b++ >> 8;
}
nouveau_hw_load_state_palette(dev, nv_crtc->index, &nv04_display(dev)->mode_reg);
@@ -792,13 +797,6 @@ nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
struct drm_modeset_acquire_ctx *ctx)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- int i;
-
- for (i = 0; i < size; i++) {
- nv_crtc->lut.r[i] = r[i];
- nv_crtc->lut.g[i] = g[i];
- nv_crtc->lut.b[i] = b[i];
- }
/* We need to know the depth before we upload, but it's possible to
* get called before a framebuffer is bound. If this is the case,
@@ -1095,25 +1093,51 @@ static const struct drm_crtc_helper_funcs nv04_crtc_helper_funcs = {
.mode_set = nv_crtc_mode_set,
.mode_set_base = nv04_crtc_mode_set_base,
.mode_set_base_atomic = nv04_crtc_mode_set_base_atomic,
- .load_lut = nv_crtc_gamma_load,
.disable = nv_crtc_disable,
};
+static const uint32_t modeset_formats[] = {
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_XRGB1555,
+};
+
+static struct drm_plane *
+create_primary_plane(struct drm_device *dev)
+{
+ struct drm_plane *primary;
+ int ret;
+
+ primary = kzalloc(sizeof(*primary), GFP_KERNEL);
+ if (primary == NULL) {
+ DRM_DEBUG_KMS("Failed to allocate primary plane\n");
+ return NULL;
+ }
+
+ /* possible_crtc's will be filled in later by crtc_init */
+ ret = drm_universal_plane_init(dev, primary, 0,
+ &drm_primary_helper_funcs,
+ modeset_formats,
+ ARRAY_SIZE(modeset_formats), NULL,
+ DRM_PLANE_TYPE_PRIMARY, NULL);
+ if (ret) {
+ kfree(primary);
+ primary = NULL;
+ }
+
+ return primary;
+}
+
int
nv04_crtc_create(struct drm_device *dev, int crtc_num)
{
struct nouveau_crtc *nv_crtc;
- int ret, i;
+ int ret;
nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL);
if (!nv_crtc)
return -ENOMEM;
- for (i = 0; i < 256; i++) {
- nv_crtc->lut.r[i] = i << 8;
- nv_crtc->lut.g[i] = i << 8;
- nv_crtc->lut.b[i] = i << 8;
- }
nv_crtc->lut.depth = 0;
nv_crtc->index = crtc_num;
@@ -1122,7 +1146,9 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num)
nv_crtc->save = nv_crtc_save;
nv_crtc->restore = nv_crtc_restore;
- drm_crtc_init(dev, &nv_crtc->base, &nv04_crtc_funcs);
+ drm_crtc_init_with_planes(dev, &nv_crtc->base,
+ create_primary_plane(dev), NULL,
+ &nv04_crtc_funcs, NULL);
drm_crtc_helper_add(&nv_crtc->base, &nv04_crtc_helper_funcs);
drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256);
diff --git a/drivers/gpu/drm/nouveau/dispnv04/overlay.c b/drivers/gpu/drm/nouveau/dispnv04/overlay.c
index e54944d23268..c8c2333f24ee 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/overlay.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/overlay.c
@@ -63,6 +63,7 @@ static uint32_t formats[] = {
DRM_FORMAT_YUYV,
DRM_FORMAT_UYVY,
DRM_FORMAT_NV12,
+ DRM_FORMAT_NV21,
};
/* Sine can be approximated with
@@ -90,6 +91,26 @@ cos_mul(int degrees, int factor)
}
static int
+verify_scaling(const struct drm_framebuffer *fb, uint8_t shift,
+ uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h,
+ uint32_t crtc_w, uint32_t crtc_h)
+{
+ if (crtc_w < (src_w >> shift) || crtc_h < (src_h >> shift)) {
+ DRM_DEBUG_KMS("Unsuitable framebuffer scaling: %dx%d -> %dx%d\n",
+ src_w, src_h, crtc_w, crtc_h);
+ return -ERANGE;
+ }
+
+ if (src_x != 0 || src_y != 0) {
+ DRM_DEBUG_KMS("Unsuitable framebuffer offset: %d,%d\n",
+ src_x, src_y);
+ return -ERANGE;
+ }
+
+ return 0;
+}
+
+static int
nv10_update_plane(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,
@@ -107,7 +128,9 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
bool flip = nv_plane->flip;
int soff = NV_PCRTC0_SIZE * nv_crtc->index;
int soff2 = NV_PCRTC0_SIZE * !nv_crtc->index;
- int format, ret;
+ unsigned shift = drm->client.device.info.chipset >= 0x30 ? 1 : 3;
+ unsigned format = 0;
+ int ret;
/* Source parameters given in 16.16 fixed point, ignore fractional. */
src_x >>= 16;
@@ -115,18 +138,9 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
src_w >>= 16;
src_h >>= 16;
- format = ALIGN(src_w * 4, 0x100);
-
- if (format > 0xffff)
- return -ERANGE;
-
- if (drm->client.device.info.chipset >= 0x30) {
- if (crtc_w < (src_w >> 1) || crtc_h < (src_h >> 1))
- return -ERANGE;
- } else {
- if (crtc_w < (src_w >> 3) || crtc_h < (src_h >> 3))
- return -ERANGE;
- }
+ ret = verify_scaling(fb, shift, 0, 0, src_w, src_h, crtc_w, crtc_h);
+ if (ret)
+ return ret;
ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM, false);
if (ret)
@@ -146,21 +160,23 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
nvif_wr32(dev, NV_PVIDEO_POINT_OUT(flip), crtc_y << 16 | crtc_x);
nvif_wr32(dev, NV_PVIDEO_SIZE_OUT(flip), crtc_h << 16 | crtc_w);
- if (fb->format->format != DRM_FORMAT_UYVY)
+ if (fb->format->format == DRM_FORMAT_YUYV ||
+ fb->format->format == DRM_FORMAT_NV12)
format |= NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8;
- if (fb->format->format == DRM_FORMAT_NV12)
+ if (fb->format->format == DRM_FORMAT_NV12 ||
+ fb->format->format == DRM_FORMAT_NV21)
format |= NV_PVIDEO_FORMAT_PLANAR;
if (nv_plane->iturbt_709)
format |= NV_PVIDEO_FORMAT_MATRIX_ITURBT709;
if (nv_plane->colorkey & (1 << 24))
format |= NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY;
- if (fb->format->format == DRM_FORMAT_NV12) {
+ if (format & NV_PVIDEO_FORMAT_PLANAR) {
nvif_wr32(dev, NV_PVIDEO_UVPLANE_BASE(flip), 0);
nvif_wr32(dev, NV_PVIDEO_UVPLANE_OFFSET_BUFF(flip),
nv_fb->nvbo->bo.offset + fb->offsets[1]);
}
- nvif_wr32(dev, NV_PVIDEO_FORMAT(flip), format);
+ nvif_wr32(dev, NV_PVIDEO_FORMAT(flip), format | fb->pitches[0]);
nvif_wr32(dev, NV_PVIDEO_STOP, 0);
/* TODO: wait for vblank? */
nvif_wr32(dev, NV_PVIDEO_BUFFER, flip ? 0x10 : 0x1);
@@ -357,7 +373,7 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
struct nouveau_bo *cur = nv_plane->cur;
uint32_t overlay = 1;
int brightness = (nv_plane->brightness - 512) * 62 / 512;
- int pitch, ret, i;
+ int ret, i;
/* Source parameters given in 16.16 fixed point, ignore fractional. */
src_x >>= 16;
@@ -365,17 +381,9 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
src_w >>= 16;
src_h >>= 16;
- pitch = ALIGN(src_w * 4, 0x100);
-
- if (pitch > 0xffff)
- return -ERANGE;
-
- /* TODO: Compute an offset? Not sure how to do this for YUYV. */
- if (src_x != 0 || src_y != 0)
- return -ERANGE;
-
- if (crtc_w < src_w || crtc_h < src_h)
- return -ERANGE;
+ ret = verify_scaling(fb, 0, src_x, src_y, src_w, src_h, crtc_w, crtc_h);
+ if (ret)
+ return ret;
ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM, false);
if (ret)
@@ -389,8 +397,9 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
for (i = 0; i < 2; i++) {
nvif_wr32(dev, NV_PVIDEO_BUFF0_START_ADDRESS + 4 * i,
- nv_fb->nvbo->bo.offset);
- nvif_wr32(dev, NV_PVIDEO_BUFF0_PITCH_LENGTH + 4 * i, pitch);
+ nv_fb->nvbo->bo.offset);
+ nvif_wr32(dev, NV_PVIDEO_BUFF0_PITCH_LENGTH + 4 * i,
+ fb->pitches[0]);
nvif_wr32(dev, NV_PVIDEO_BUFF0_OFFSET + 4 * i, 0);
}
nvif_wr32(dev, NV_PVIDEO_WINDOW_START, crtc_y << 16 | crtc_x);
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h
index e8e77ee24776..deb477282dde 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h
@@ -18,6 +18,7 @@ enum dcb_connector_type {
DCB_CONNECTOR_HDMI_C = 0x63,
DCB_CONNECTOR_DMS59_DP0 = 0x64,
DCB_CONNECTOR_DMS59_DP1 = 0x65,
+ DCB_CONNECTOR_WFD = 0x70,
DCB_CONNECTOR_NONE = 0xff
};
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h
index 4892a65ddd48..903d117603d8 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h
@@ -6,6 +6,7 @@ enum dcb_output_type {
DCB_OUTPUT_TMDS = 0x2,
DCB_OUTPUT_LVDS = 0x3,
DCB_OUTPUT_DP = 0x6,
+ DCB_OUTPUT_WFD = 0x8,
DCB_OUTPUT_EOL = 0xe,
DCB_OUTPUT_UNUSED = 0xf,
DCB_OUTPUT_ANY = -1,
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
index b268b96faece..1bfd93b85575 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
@@ -96,4 +96,5 @@ int g84_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
int gt215_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
int gf119_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
int gm107_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
+int gm200_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index b998c33af18a..dd6fba55ad5d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -351,11 +351,8 @@ static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios)
struct lvdstableheader lth;
if (bios->fp.fptablepointer == 0x0) {
- /* Apple cards don't have the fp table; the laptops use DDC */
- /* The table is also missing on some x86 IGPs */
-#ifndef __powerpc__
- NV_ERROR(drm, "Pointer to flat panel table invalid\n");
-#endif
+ /* Most laptop cards lack an fp table. They use DDC. */
+ NV_DEBUG(drm, "Pointer to flat panel table invalid\n");
bios->digital_min_front_porch = 0x4b;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 147b22163f9f..70d8e0d69ad5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -770,9 +770,6 @@ nouveau_connector_set_property(struct drm_connector *connector,
struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
int ret;
- if (drm_drv_uses_atomic_modeset(connector->dev))
- return drm_atomic_helper_connector_set_property(connector, property, value);
-
ret = connector->funcs->atomic_set_property(&nv_connector->base,
&asyc->state,
property, value);
@@ -1075,17 +1072,9 @@ nouveau_connector_helper_funcs = {
.best_encoder = nouveau_connector_best_encoder,
};
-static int
-nouveau_connector_dpms(struct drm_connector *connector, int mode)
-{
- if (drm_drv_uses_atomic_modeset(connector->dev))
- return drm_atomic_helper_connector_dpms(connector, mode);
- return drm_helper_connector_dpms(connector, mode);
-}
-
static const struct drm_connector_funcs
nouveau_connector_funcs = {
- .dpms = nouveau_connector_dpms,
+ .dpms = drm_helper_connector_dpms,
.reset = nouveau_conn_reset,
.detect = nouveau_connector_detect,
.force = nouveau_connector_force,
@@ -1100,7 +1089,7 @@ nouveau_connector_funcs = {
static const struct drm_connector_funcs
nouveau_connector_funcs_lvds = {
- .dpms = nouveau_connector_dpms,
+ .dpms = drm_helper_connector_dpms,
.reset = nouveau_conn_reset,
.detect = nouveau_connector_detect_lvds,
.force = nouveau_connector_force,
@@ -1158,8 +1147,6 @@ nouveau_connector_aux_xfer(struct drm_dp_aux *obj, struct drm_dp_aux_msg *msg)
return -ENODEV;
if (WARN_ON(msg->size > 16))
return -E2BIG;
- if (msg->size == 0)
- return msg->size;
ret = nvkm_i2c_aux_acquire(aux);
if (ret)
@@ -1197,6 +1184,7 @@ drm_conntype_from_dcb(enum dcb_connector_type dcb)
case DCB_CONNECTOR_HDMI_0 :
case DCB_CONNECTOR_HDMI_1 :
case DCB_CONNECTOR_HDMI_C : return DRM_MODE_CONNECTOR_HDMIA;
+ case DCB_CONNECTOR_WFD : return DRM_MODE_CONNECTOR_VIRTUAL;
default:
break;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_crtc.h b/drivers/gpu/drm/nouveau/nouveau_crtc.h
index 050fcf30a0d2..b7a18fbee6dc 100644
--- a/drivers/gpu/drm/nouveau/nouveau_crtc.h
+++ b/drivers/gpu/drm/nouveau/nouveau_crtc.h
@@ -61,9 +61,6 @@ struct nouveau_crtc {
struct {
struct nouveau_bo *nvbo;
- uint16_t r[256];
- uint16_t g[256];
- uint16_t b[256];
int depth;
} lut;
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 8d1df5678eaa..2e7785f49e6d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -159,8 +159,6 @@ nouveau_display_vblank_fini(struct drm_device *dev)
{
struct drm_crtc *crtc;
- drm_vblank_cleanup(dev);
-
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
nvif_notify_fini(&nv_crtc->vblank);
@@ -233,9 +231,30 @@ nouveau_framebuffer_new(struct drm_device *dev,
struct nouveau_bo *nvbo,
struct nouveau_framebuffer **pfb)
{
+ struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_framebuffer *fb;
int ret;
+ /* YUV overlays have special requirements pre-NV50 */
+ if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA &&
+
+ (mode_cmd->pixel_format == DRM_FORMAT_YUYV ||
+ mode_cmd->pixel_format == DRM_FORMAT_UYVY ||
+ mode_cmd->pixel_format == DRM_FORMAT_NV12 ||
+ mode_cmd->pixel_format == DRM_FORMAT_NV21) &&
+ (mode_cmd->pitches[0] & 0x3f || /* align 64 */
+ mode_cmd->pitches[0] >= 0x10000 || /* at most 64k pitch */
+ (mode_cmd->pitches[1] && /* pitches for planes must match */
+ mode_cmd->pitches[0] != mode_cmd->pitches[1]))) {
+ struct drm_format_name_buf format_name;
+ DRM_DEBUG_KMS("Unsuitable framebuffer: format: %s; pitches: 0x%x\n 0x%x\n",
+ drm_get_format_name(mode_cmd->pixel_format,
+ &format_name),
+ mode_cmd->pitches[0],
+ mode_cmd->pitches[1]);
+ return -EINVAL;
+ }
+
if (!(fb = *pfb = kzalloc(sizeof(*fb), GFP_KERNEL)))
return -ENOMEM;
@@ -409,7 +428,6 @@ nouveau_display_fini(struct drm_device *dev, bool suspend)
struct nouveau_display *disp = nouveau_display(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
struct drm_connector *connector;
- struct drm_crtc *crtc;
if (!suspend) {
if (drm_drv_uses_atomic_modeset(dev))
@@ -418,10 +436,6 @@ nouveau_display_fini(struct drm_device *dev, bool suspend)
drm_crtc_force_disable_all(dev);
}
- /* Make sure that drm and hw vblank irqs get properly disabled. */
- drm_for_each_crtc(crtc, dev)
- drm_crtc_vblank_off(crtc);
-
/* disable flip completion events */
nvif_notify_put(&drm->flip);
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 90757af9bc73..595630d1fb9e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -585,18 +585,18 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime)
nouveau_led_suspend(dev);
if (dev->mode_config.num_crtc) {
- NV_INFO(drm, "suspending console...\n");
+ NV_DEBUG(drm, "suspending console...\n");
nouveau_fbcon_set_suspend(dev, 1);
- NV_INFO(drm, "suspending display...\n");
+ NV_DEBUG(drm, "suspending display...\n");
ret = nouveau_display_suspend(dev, runtime);
if (ret)
return ret;
}
- NV_INFO(drm, "evicting buffers...\n");
+ NV_DEBUG(drm, "evicting buffers...\n");
ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM);
- NV_INFO(drm, "waiting for kernel channels to go idle...\n");
+ NV_DEBUG(drm, "waiting for kernel channels to go idle...\n");
if (drm->cechan) {
ret = nouveau_channel_idle(drm->cechan);
if (ret)
@@ -609,7 +609,7 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime)
goto fail_display;
}
- NV_INFO(drm, "suspending fence...\n");
+ NV_DEBUG(drm, "suspending fence...\n");
if (drm->fence && nouveau_fence(drm)->suspend) {
if (!nouveau_fence(drm)->suspend(drm)) {
ret = -ENOMEM;
@@ -617,7 +617,7 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime)
}
}
- NV_INFO(drm, "suspending object tree...\n");
+ NV_DEBUG(drm, "suspending object tree...\n");
ret = nvif_client_suspend(&drm->client.base);
if (ret)
goto fail_client;
@@ -630,7 +630,7 @@ fail_client:
fail_display:
if (dev->mode_config.num_crtc) {
- NV_INFO(drm, "resuming display...\n");
+ NV_DEBUG(drm, "resuming display...\n");
nouveau_display_resume(dev, runtime);
}
return ret;
@@ -641,19 +641,19 @@ nouveau_do_resume(struct drm_device *dev, bool runtime)
{
struct nouveau_drm *drm = nouveau_drm(dev);
- NV_INFO(drm, "resuming object tree...\n");
+ NV_DEBUG(drm, "resuming object tree...\n");
nvif_client_resume(&drm->client.base);
- NV_INFO(drm, "resuming fence...\n");
+ NV_DEBUG(drm, "resuming fence...\n");
if (drm->fence && nouveau_fence(drm)->resume)
nouveau_fence(drm)->resume(drm);
nouveau_run_vbios_init(dev);
if (dev->mode_config.num_crtc) {
- NV_INFO(drm, "resuming display...\n");
+ NV_DEBUG(drm, "resuming display...\n");
nouveau_display_resume(dev, runtime);
- NV_INFO(drm, "resuming console...\n");
+ NV_DEBUG(drm, "resuming console...\n");
nouveau_fbcon_set_suspend(dev, 0);
}
@@ -998,7 +998,6 @@ driver_stub = {
.dumb_create = nouveau_display_dumb_create,
.dumb_map_offset = nouveau_display_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
@@ -1098,7 +1097,6 @@ static int __init
nouveau_drm_init(void)
{
driver_pci = driver_stub;
- driver_pci.set_busid = drm_pci_set_busid;
driver_platform = driver_stub;
nouveau_display_options();
@@ -1117,7 +1115,12 @@ nouveau_drm_init(void)
nouveau_register_dsm_handler();
nouveau_backlight_ctor();
- return drm_pci_init(&driver_pci, &nouveau_drm_pci_driver);
+
+#ifdef CONFIG_PCI
+ return pci_register_driver(&nouveau_drm_pci_driver);
+#else
+ return 0;
+#endif
}
static void __exit
@@ -1126,7 +1129,9 @@ nouveau_drm_exit(void)
if (!nouveau_modeset)
return;
- drm_pci_exit(&driver_pci, &nouveau_drm_pci_driver);
+#ifdef CONFIG_PCI
+ pci_unregister_driver(&nouveau_drm_pci_driver);
+#endif
nouveau_backlight_dtor();
nouveau_unregister_dsm_handler();
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 2665a078b6da..f7707849bb53 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -278,26 +278,6 @@ nouveau_fbcon_accel_init(struct drm_device *dev)
info->fbops = &nouveau_fbcon_ops;
}
-static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
- struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
-
- nv_crtc->lut.r[regno] = red;
- nv_crtc->lut.g[regno] = green;
- nv_crtc->lut.b[regno] = blue;
-}
-
-static void nouveau_fbcon_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno)
-{
- struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
-
- *red = nv_crtc->lut.r[regno];
- *green = nv_crtc->lut.g[regno];
- *blue = nv_crtc->lut.b[regno];
-}
-
static void
nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbdev *fbcon)
{
@@ -467,8 +447,6 @@ void nouveau_fbcon_gpu_lockup(struct fb_info *info)
}
static const struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = {
- .gamma_set = nouveau_fbcon_gamma_set,
- .gamma_get = nouveau_fbcon_gamma_get,
.fb_probe = nouveau_fbcon_create,
};
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c
index 999c35a25498..b0ad7fcefcf5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c
@@ -179,7 +179,8 @@ nouveau_gart_manager_new(struct ttm_mem_type_manager *man,
}
static void
-nouveau_gart_manager_debug(struct ttm_mem_type_manager *man, const char *prefix)
+nouveau_gart_manager_debug(struct ttm_mem_type_manager *man,
+ struct drm_printer *printer)
{
}
@@ -252,7 +253,8 @@ nv04_gart_manager_new(struct ttm_mem_type_manager *man,
}
static void
-nv04_gart_manager_debug(struct ttm_mem_type_manager *man, const char *prefix)
+nv04_gart_manager_debug(struct ttm_mem_type_manager *man,
+ struct drm_printer *printer)
{
}
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index e3132a2ce34d..2dbf62a2ac41 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -1055,7 +1055,6 @@ nv50_wndw = {
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = nv50_wndw_destroy,
.reset = nv50_wndw_reset,
- .set_property = drm_atomic_helper_plane_set_property,
.atomic_duplicate_state = nv50_wndw_atomic_duplicate_state,
.atomic_destroy_state = nv50_wndw_atomic_destroy_state,
};
@@ -1083,8 +1082,9 @@ nv50_wndw_ctor(const struct nv50_wndw_func *func, struct drm_device *dev,
wndw->func = func;
wndw->dmac = dmac;
- ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw, format,
- nformat, type, "%s-%d", name, index);
+ ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw,
+ format, nformat, NULL,
+ type, "%s-%d", name, index);
if (ret)
return ret;
@@ -2103,7 +2103,7 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state)
NV_ATOMIC(drm, "%s atomic_check %d\n", crtc->name, asyh->state.active);
if (asyh->state.active) {
- for_each_connector_in_state(asyh->state.state, conn, conns, i) {
+ for_each_new_connector_in_state(asyh->state.state, conn, conns, i) {
if (conns->crtc == crtc) {
asyc = nouveau_conn_atom(conns);
break;
@@ -2204,28 +2204,29 @@ nv50_head_lut_load(struct drm_crtc *crtc)
struct nv50_disp *disp = nv50_disp(crtc->dev);
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo);
+ u16 *r, *g, *b;
int i;
- for (i = 0; i < 256; i++) {
- u16 r = nv_crtc->lut.r[i] >> 2;
- u16 g = nv_crtc->lut.g[i] >> 2;
- u16 b = nv_crtc->lut.b[i] >> 2;
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
+ for (i = 0; i < 256; i++) {
if (disp->disp->oclass < GF110_DISP) {
- writew(r + 0x0000, lut + (i * 0x08) + 0);
- writew(g + 0x0000, lut + (i * 0x08) + 2);
- writew(b + 0x0000, lut + (i * 0x08) + 4);
+ writew((*r++ >> 2) + 0x0000, lut + (i * 0x08) + 0);
+ writew((*g++ >> 2) + 0x0000, lut + (i * 0x08) + 2);
+ writew((*b++ >> 2) + 0x0000, lut + (i * 0x08) + 4);
} else {
- writew(r + 0x6000, lut + (i * 0x20) + 0);
- writew(g + 0x6000, lut + (i * 0x20) + 2);
- writew(b + 0x6000, lut + (i * 0x20) + 4);
+ /* 0x6000 interferes with the 14-bit color??? */
+ writew((*r++ >> 2) + 0x6000, lut + (i * 0x20) + 0);
+ writew((*g++ >> 2) + 0x6000, lut + (i * 0x20) + 2);
+ writew((*b++ >> 2) + 0x6000, lut + (i * 0x20) + 4);
}
}
}
static const struct drm_crtc_helper_funcs
nv50_head_help = {
- .load_lut = nv50_head_lut_load,
.atomic_check = nv50_head_atomic_check,
};
@@ -2234,15 +2235,6 @@ nv50_head_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- u32 i;
-
- for (i = 0; i < size; i++) {
- nv_crtc->lut.r[i] = r[i];
- nv_crtc->lut.g[i] = g[i];
- nv_crtc->lut.b[i] = b[i];
- }
-
nv50_head_lut_load(crtc);
return 0;
}
@@ -2325,7 +2317,6 @@ nv50_head_func = {
.destroy = nv50_head_destroy,
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
- .set_property = drm_atomic_helper_crtc_set_property,
.atomic_duplicate_state = nv50_head_atomic_duplicate_state,
.atomic_destroy_state = nv50_head_atomic_destroy_state,
};
@@ -2340,19 +2331,13 @@ nv50_head_create(struct drm_device *dev, int index)
struct nv50_base *base;
struct nv50_curs *curs;
struct drm_crtc *crtc;
- int ret, i;
+ int ret;
head = kzalloc(sizeof(*head), GFP_KERNEL);
if (!head)
return -ENOMEM;
head->base.index = index;
- for (i = 0; i < 256; i++) {
- head->base.lut.r[i] = i << 8;
- head->base.lut.g[i] = i << 8;
- head->base.lut.b[i] = i << 8;
- }
-
ret = nv50_base_new(drm, head, &base);
if (ret == 0)
ret = nv50_curs_new(drm, head, &curs);
@@ -2762,7 +2747,8 @@ nv50_hdmi_enable(struct drm_encoder *encoder, struct drm_display_mode *mode)
if (!drm_detect_hdmi_monitor(nv_connector->edid))
return;
- ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame.avi, mode);
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame.avi, mode,
+ false);
if (!ret) {
/* We have an AVI InfoFrame, populate it to the display */
args.pwr.avi_infoframe_length
@@ -3119,11 +3105,9 @@ nv50_mstc_destroy(struct drm_connector *connector)
static const struct drm_connector_funcs
nv50_mstc = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = nouveau_conn_reset,
.detect = nv50_mstc_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.destroy = nv50_mstc_destroy,
.atomic_duplicate_state = nouveau_conn_atomic_duplicate_state,
.atomic_destroy_state = nouveau_conn_atomic_destroy_state,
@@ -3157,7 +3141,7 @@ nv50_mstc_new(struct nv50_mstm *mstm, struct drm_dp_mst_port *port,
mstc->connector.funcs->reset(&mstc->connector);
nouveau_conn_attach_properties(&mstc->connector);
- for (i = 0; i < ARRAY_SIZE(mstm->msto) && mstm->msto; i++)
+ for (i = 0; i < ARRAY_SIZE(mstm->msto) && mstm->msto[i]; i++)
drm_mode_connector_attach_encoder(&mstc->connector, &mstm->msto[i]->encoder);
drm_object_attach_property(&mstc->connector.base, dev->mode_config.path_property, 0);
@@ -3674,15 +3658,24 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
drm_mode_connector_attach_encoder(connector, encoder);
if (dcbe->type == DCB_OUTPUT_DP) {
+ struct nv50_disp *disp = nv50_disp(encoder->dev);
struct nvkm_i2c_aux *aux =
nvkm_i2c_aux_find(i2c, dcbe->i2c_index);
if (aux) {
- nv_encoder->i2c = &nv_connector->aux.ddc;
+ if (disp->disp->oclass < GF110_DISP) {
+ /* HW has no support for address-only
+ * transactions, so we're required to
+ * use custom I2C-over-AUX code.
+ */
+ nv_encoder->i2c = &aux->i2c;
+ } else {
+ nv_encoder->i2c = &nv_connector->aux.ddc;
+ }
nv_encoder->aux = aux;
}
/*TODO: Use DP Info Table to check for support. */
- if (nv50_disp(encoder->dev)->disp->oclass >= GF110_DISP) {
+ if (disp->disp->oclass >= GF110_DISP) {
ret = nv50_mstm_new(nv_encoder, &nv_connector->aux, 16,
nv_connector->base.base.id,
&nv_encoder->dp.mstm);
@@ -3904,9 +3897,9 @@ static void
nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
- struct drm_crtc_state *crtc_state;
+ struct drm_crtc_state *new_crtc_state, *old_crtc_state;
struct drm_crtc *crtc;
- struct drm_plane_state *plane_state;
+ struct drm_plane_state *new_plane_state;
struct drm_plane *plane;
struct nouveau_drm *drm = nouveau_drm(dev);
struct nv50_disp *disp = nv50_disp(dev);
@@ -3925,12 +3918,14 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
mutex_lock(&disp->mutex);
/* Disable head(s). */
- for_each_crtc_in_state(state, crtc, crtc_state, i) {
- struct nv50_head_atom *asyh = nv50_head_atom(crtc->state);
+ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+ struct nv50_head_atom *asyh = nv50_head_atom(new_crtc_state);
struct nv50_head *head = nv50_head(crtc);
NV_ATOMIC(drm, "%s: clr %04x (set %04x)\n", crtc->name,
asyh->clr.mask, asyh->set.mask);
+ if (old_crtc_state->active && !new_crtc_state->active)
+ drm_crtc_vblank_off(crtc);
if (asyh->clr.mask) {
nv50_head_flush_clr(head, asyh, atom->flush_disable);
@@ -3939,8 +3934,8 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
}
/* Disable plane(s). */
- for_each_plane_in_state(state, plane, plane_state, i) {
- struct nv50_wndw_atom *asyw = nv50_wndw_atom(plane->state);
+ for_each_new_plane_in_state(state, plane, new_plane_state, i) {
+ struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state);
struct nv50_wndw *wndw = nv50_wndw(plane);
NV_ATOMIC(drm, "%s: clr %02x (set %02x)\n", plane->name,
@@ -4005,8 +4000,8 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
}
/* Update head(s). */
- for_each_crtc_in_state(state, crtc, crtc_state, i) {
- struct nv50_head_atom *asyh = nv50_head_atom(crtc->state);
+ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+ struct nv50_head_atom *asyh = nv50_head_atom(new_crtc_state);
struct nv50_head *head = nv50_head(crtc);
NV_ATOMIC(drm, "%s: set %04x (clr %04x)\n", crtc->name,
@@ -4016,16 +4011,18 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
nv50_head_flush_set(head, asyh);
interlock_core = 1;
}
- }
- for_each_crtc_in_state(state, crtc, crtc_state, i) {
- if (crtc->state->event)
- drm_crtc_vblank_get(crtc);
+ if (new_crtc_state->active) {
+ if (!old_crtc_state->active)
+ drm_crtc_vblank_on(crtc);
+ if (new_crtc_state->event)
+ drm_crtc_vblank_get(crtc);
+ }
}
/* Update plane(s). */
- for_each_plane_in_state(state, plane, plane_state, i) {
- struct nv50_wndw_atom *asyw = nv50_wndw_atom(plane->state);
+ for_each_new_plane_in_state(state, plane, new_plane_state, i) {
+ struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state);
struct nv50_wndw *wndw = nv50_wndw(plane);
NV_ATOMIC(drm, "%s: set %02x (clr %02x)\n", plane->name,
@@ -4055,24 +4052,27 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
mutex_unlock(&disp->mutex);
/* Wait for HW to signal completion. */
- for_each_plane_in_state(state, plane, plane_state, i) {
- struct nv50_wndw_atom *asyw = nv50_wndw_atom(plane->state);
+ for_each_new_plane_in_state(state, plane, new_plane_state, i) {
+ struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state);
struct nv50_wndw *wndw = nv50_wndw(plane);
int ret = nv50_wndw_wait_armed(wndw, asyw);
if (ret)
NV_ERROR(drm, "%s: timeout\n", plane->name);
}
- for_each_crtc_in_state(state, crtc, crtc_state, i) {
- if (crtc->state->event) {
+ for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
+ if (new_crtc_state->event) {
unsigned long flags;
/* Get correct count/ts if racing with vblank irq */
- drm_accurate_vblank_count(crtc);
+ if (new_crtc_state->active)
+ drm_crtc_accurate_vblank_count(crtc);
spin_lock_irqsave(&crtc->dev->event_lock, flags);
- drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ drm_crtc_send_vblank_event(crtc, new_crtc_state->event);
spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
- crtc->state->event = NULL;
- drm_crtc_vblank_put(crtc);
+
+ new_crtc_state->event = NULL;
+ if (new_crtc_state->active)
+ drm_crtc_vblank_put(crtc);
}
}
@@ -4096,7 +4096,7 @@ nv50_disp_atomic_commit(struct drm_device *dev,
{
struct nouveau_drm *drm = nouveau_drm(dev);
struct nv50_disp *disp = nv50_disp(dev);
- struct drm_plane_state *plane_state;
+ struct drm_plane_state *old_plane_state;
struct drm_plane *plane;
struct drm_crtc *crtc;
bool active = false;
@@ -4119,12 +4119,17 @@ nv50_disp_atomic_commit(struct drm_device *dev,
if (!nonblock) {
ret = drm_atomic_helper_wait_for_fences(dev, state, true);
if (ret)
- goto done;
+ goto err_cleanup;
}
- for_each_plane_in_state(state, plane, plane_state, i) {
- struct nv50_wndw_atom *asyw = nv50_wndw_atom(plane_state);
+ ret = drm_atomic_helper_swap_state(state, true);
+ if (ret)
+ goto err_cleanup;
+
+ for_each_old_plane_in_state(state, plane, old_plane_state, i) {
+ struct nv50_wndw_atom *asyw = nv50_wndw_atom(old_plane_state);
struct nv50_wndw *wndw = nv50_wndw(plane);
+
if (asyw->set.image) {
asyw->ntfy.handle = wndw->dmac->sync.handle;
asyw->ntfy.offset = wndw->ntfy;
@@ -4135,7 +4140,6 @@ nv50_disp_atomic_commit(struct drm_device *dev,
}
}
- drm_atomic_helper_swap_state(state, true);
drm_atomic_state_get(state);
if (nonblock)
@@ -4147,7 +4151,7 @@ nv50_disp_atomic_commit(struct drm_device *dev,
if (crtc->state->enable) {
if (!drm->have_disp_power_ref) {
drm->have_disp_power_ref = true;
- return ret;
+ return 0;
}
active = true;
break;
@@ -4159,6 +4163,9 @@ nv50_disp_atomic_commit(struct drm_device *dev,
drm->have_disp_power_ref = false;
}
+err_cleanup:
+ if (ret)
+ drm_atomic_helper_cleanup_planes(dev, state);
done:
pm_runtime_put_autosuspend(dev->dev);
return ret;
@@ -4185,18 +4192,19 @@ nv50_disp_outp_atomic_add(struct nv50_atom *atom, struct drm_encoder *encoder)
static int
nv50_disp_outp_atomic_check_clr(struct nv50_atom *atom,
- struct drm_connector *connector)
+ struct drm_connector_state *old_connector_state)
{
- struct drm_encoder *encoder = connector->state->best_encoder;
- struct drm_crtc_state *crtc_state;
+ struct drm_encoder *encoder = old_connector_state->best_encoder;
+ struct drm_crtc_state *old_crtc_state, *new_crtc_state;
struct drm_crtc *crtc;
struct nv50_outp_atom *outp;
- if (!(crtc = connector->state->crtc))
+ if (!(crtc = old_connector_state->crtc))
return 0;
- crtc_state = drm_atomic_get_existing_crtc_state(&atom->state, crtc);
- if (crtc->state->active && drm_atomic_crtc_needs_modeset(crtc_state)) {
+ old_crtc_state = drm_atomic_get_old_crtc_state(&atom->state, crtc);
+ new_crtc_state = drm_atomic_get_new_crtc_state(&atom->state, crtc);
+ if (old_crtc_state->active && drm_atomic_crtc_needs_modeset(new_crtc_state)) {
outp = nv50_disp_outp_atomic_add(atom, encoder);
if (IS_ERR(outp))
return PTR_ERR(outp);
@@ -4217,15 +4225,15 @@ nv50_disp_outp_atomic_check_set(struct nv50_atom *atom,
struct drm_connector_state *connector_state)
{
struct drm_encoder *encoder = connector_state->best_encoder;
- struct drm_crtc_state *crtc_state;
+ struct drm_crtc_state *new_crtc_state;
struct drm_crtc *crtc;
struct nv50_outp_atom *outp;
if (!(crtc = connector_state->crtc))
return 0;
- crtc_state = drm_atomic_get_existing_crtc_state(&atom->state, crtc);
- if (crtc_state->active && drm_atomic_crtc_needs_modeset(crtc_state)) {
+ new_crtc_state = drm_atomic_get_new_crtc_state(&atom->state, crtc);
+ if (new_crtc_state->active && drm_atomic_crtc_needs_modeset(new_crtc_state)) {
outp = nv50_disp_outp_atomic_add(atom, encoder);
if (IS_ERR(outp))
return PTR_ERR(outp);
@@ -4241,7 +4249,7 @@ static int
nv50_disp_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
{
struct nv50_atom *atom = nv50_atom(state);
- struct drm_connector_state *connector_state;
+ struct drm_connector_state *old_connector_state, *new_connector_state;
struct drm_connector *connector;
int ret, i;
@@ -4249,12 +4257,12 @@ nv50_disp_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
if (ret)
return ret;
- for_each_connector_in_state(state, connector, connector_state, i) {
- ret = nv50_disp_outp_atomic_check_clr(atom, connector);
+ for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i) {
+ ret = nv50_disp_outp_atomic_check_clr(atom, old_connector_state);
if (ret)
return ret;
- ret = nv50_disp_outp_atomic_check_set(atom, connector_state);
+ ret = nv50_disp_outp_atomic_check_set(atom, new_connector_state);
if (ret)
return ret;
}
@@ -4443,11 +4451,13 @@ nv50_display_create(struct drm_device *dev)
/* create crtc objects to represent the hw heads */
if (disp->disp->oclass >= GF110_DISP)
- crtcs = nvif_rd32(&device->object, 0x022448);
+ crtcs = nvif_rd32(&device->object, 0x612004) & 0xf;
else
- crtcs = 2;
+ crtcs = 0x3;
- for (i = 0; i < crtcs; i++) {
+ for (i = 0; i < fls(crtcs); i++) {
+ if (!(crtcs & (1 << i)))
+ continue;
ret = nv50_head_create(dev, i);
if (ret)
goto out;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
index 7bdc7a5ae723..e096a5d9c292 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
@@ -2043,6 +2043,7 @@ nv120_chipset = {
.mxm = nv50_mxm_new,
.pci = gk104_pci_new,
.pmu = gm107_pmu_new,
+ .therm = gm200_therm_new,
.secboot = gm200_secboot_new,
.timer = gk20a_timer_new,
.top = gk104_top_new,
@@ -2077,6 +2078,7 @@ nv124_chipset = {
.mxm = nv50_mxm_new,
.pci = gk104_pci_new,
.pmu = gm107_pmu_new,
+ .therm = gm200_therm_new,
.secboot = gm200_secboot_new,
.timer = gk20a_timer_new,
.top = gk104_top_new,
@@ -2111,6 +2113,7 @@ nv126_chipset = {
.mxm = nv50_mxm_new,
.pci = gk104_pci_new,
.pmu = gm107_pmu_new,
+ .therm = gm200_therm_new,
.secboot = gm200_secboot_new,
.timer = gk20a_timer_new,
.top = gk104_top_new,
@@ -2321,6 +2324,35 @@ nv137_chipset = {
};
static const struct nvkm_device_chip
+nv138_chipset = {
+ .name = "GP108",
+ .bar = gf100_bar_new,
+ .bios = nvkm_bios_new,
+ .bus = gf100_bus_new,
+ .devinit = gm200_devinit_new,
+ .fb = gp102_fb_new,
+ .fuse = gm107_fuse_new,
+ .gpio = gk104_gpio_new,
+ .i2c = gm200_i2c_new,
+ .ibus = gm200_ibus_new,
+ .imem = nv50_instmem_new,
+ .ltc = gp100_ltc_new,
+ .mc = gp100_mc_new,
+ .mmu = gf100_mmu_new,
+ .pci = gp100_pci_new,
+ .pmu = gp102_pmu_new,
+ .timer = gk20a_timer_new,
+ .top = gk104_top_new,
+ .ce[0] = gp102_ce_new,
+ .ce[1] = gp102_ce_new,
+ .ce[2] = gp102_ce_new,
+ .ce[3] = gp102_ce_new,
+ .disp = gp102_disp_new,
+ .dma = gf119_dma_new,
+ .fifo = gp100_fifo_new,
+};
+
+static const struct nvkm_device_chip
nv13b_chipset = {
.name = "GP10B",
.bar = gk20a_bar_new,
@@ -2782,6 +2814,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
case 0x134: device->chip = &nv134_chipset; break;
case 0x136: device->chip = &nv136_chipset; break;
case 0x137: device->chip = &nv137_chipset; break;
+ case 0x138: device->chip = &nv138_chipset; break;
case 0x13b: device->chip = &nv13b_chipset; break;
default:
nvdev_error(device, "unknown chipset (%08x)\n", boot0);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
index c7c84d34d97e..93a75e5b2791 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
@@ -267,6 +267,8 @@ nvkm_disp_oneinit(struct nvkm_engine *engine)
/* Create output path objects for each VBIOS display path. */
i = -1;
while ((data = dcb_outp_parse(bios, ++i, &ver, &hdr, &dcbE))) {
+ if (ver < 0x40) /* No support for chipsets prior to NV50. */
+ break;
if (dcbE.type == DCB_OUTPUT_UNUSED)
continue;
if (dcbE.type == DCB_OUTPUT_EOL)
@@ -283,6 +285,10 @@ nvkm_disp_oneinit(struct nvkm_engine *engine)
case DCB_OUTPUT_DP:
ret = nvkm_dp_new(disp, i, &dcbE, &outp);
break;
+ case DCB_OUTPUT_WFD:
+ /* No support for WFD yet. */
+ ret = -ENODEV;
+ continue;
default:
nvkm_warn(subdev, "dcb %d type %d unknown\n",
i, dcbE.type);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c
index b33552757647..9fd7ae331308 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c
@@ -92,5 +92,8 @@ gf119_head = {
int
gf119_head_new(struct nvkm_disp *disp, int id)
{
+ struct nvkm_device *device = disp->engine.subdev.device;
+ if (!(nvkm_rd32(device, 0x612004) & (0x00000001 << id)))
+ return 0;
return nvkm_head_new_(&gf119_head, disp, id);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
index a24312fb0228..a1e8bf48b778 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
@@ -22,6 +22,7 @@ struct nvkm_ior {
unsigned proto_evo:4;
enum nvkm_ior_proto {
CRT,
+ TV,
TMDS,
LVDS,
DP,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h
index 19c635663399..6ea19466f436 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.h
@@ -22,7 +22,7 @@ struct nv50_disp {
u8 type[3];
} pior;
- struct nv50_disp_chan *chan[17];
+ struct nv50_disp_chan *chan[21];
};
void nv50_disp_super_1(struct nv50_disp *);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
index 85aff85394ac..be9e7f8c3b23 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
@@ -62,6 +62,7 @@ nvkm_outp_xlat(struct nvkm_outp *outp, enum nvkm_ior_type *type)
case 0:
switch (outp->info.type) {
case DCB_OUTPUT_ANALOG: *type = DAC; return CRT;
+ case DCB_OUTPUT_TV : *type = DAC; return TV;
case DCB_OUTPUT_TMDS : *type = SOR; return TMDS;
case DCB_OUTPUT_LVDS : *type = SOR; return LVDS;
case DCB_OUTPUT_DP : *type = SOR; return DP;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c
index 8a8895246d26..7fea7d45202f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c
@@ -124,6 +124,8 @@ nv31_mpeg_tile(struct nvkm_engine *engine, int i, struct nvkm_fb_tile *tile)
static bool
nv31_mpeg_mthd_dma(struct nvkm_device *device, u32 mthd, u32 data)
{
+ struct nv31_mpeg *mpeg = nv31_mpeg(device->mpeg);
+ struct nvkm_subdev *subdev = &mpeg->engine.subdev;
u32 inst = data << 4;
u32 dma0 = nvkm_rd32(device, 0x700000 + inst);
u32 dma1 = nvkm_rd32(device, 0x700004 + inst);
@@ -132,8 +134,11 @@ nv31_mpeg_mthd_dma(struct nvkm_device *device, u32 mthd, u32 data)
u32 size = dma1 + 1;
/* only allow linear DMA objects */
- if (!(dma0 & 0x00002000))
+ if (!(dma0 & 0x00002000)) {
+ nvkm_error(subdev, "inst %08x dma0 %08x dma1 %08x dma2 %08x\n",
+ inst, dma0, dma1, dma2);
return false;
+ }
if (mthd == 0x0190) {
/* DMA_CMD */
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c
index 16de5bd94b14..b5ec7c504dc6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c
@@ -31,6 +31,8 @@ bool
nv40_mpeg_mthd_dma(struct nvkm_device *device, u32 mthd, u32 data)
{
struct nvkm_instmem *imem = device->imem;
+ struct nv31_mpeg *mpeg = nv31_mpeg(device->mpeg);
+ struct nvkm_subdev *subdev = &mpeg->engine.subdev;
u32 inst = data << 4;
u32 dma0 = nvkm_instmem_rd32(imem, inst + 0);
u32 dma1 = nvkm_instmem_rd32(imem, inst + 4);
@@ -39,8 +41,11 @@ nv40_mpeg_mthd_dma(struct nvkm_device *device, u32 mthd, u32 data)
u32 size = dma1 + 1;
/* only allow linear DMA objects */
- if (!(dma0 & 0x00002000))
+ if (!(dma0 & 0x00002000)) {
+ nvkm_error(subdev, "inst %08x dma0 %08x dma1 %08x dma2 %08x\n",
+ inst, dma0, dma1, dma2);
return false;
+ }
if (mthd == 0x0190) {
/* DMA_CMD */
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c
index d45d7947a964..77273b53672c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c
@@ -251,7 +251,7 @@ cmd_write(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_hdr *cmd,
struct nvkm_msgqueue_queue *queue)
{
const struct nvkm_subdev *subdev = priv->falcon->owner;
- static unsigned long timeout = ~0;
+ static unsigned timeout = 2000;
unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout);
int ret = -EAGAIN;
bool commit = true;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
index c794b2c2d21e..676c167c95b9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
@@ -24,6 +24,7 @@
#include "gf100.h"
#include <core/gpuobj.h>
+#include <core/option.h>
#include <subdev/fb.h>
#include <subdev/mmu.h>
@@ -59,6 +60,8 @@ gf100_bar_ctor_vm(struct gf100_bar *bar, struct gf100_bar_vm *bar_vm,
return ret;
bar_len = device->func->resource_size(device, bar_nr);
+ if (bar_nr == 3 && bar->bar2_halve)
+ bar_len >>= 1;
ret = nvkm_vm_new(device, 0, bar_len, 0, key, &vm);
if (ret)
@@ -129,7 +132,9 @@ gf100_bar_init(struct nvkm_bar *base)
if (bar->bar[0].mem) {
addr = nvkm_memory_addr(bar->bar[0].mem) >> 12;
- nvkm_wr32(device, 0x001714, 0xc0000000 | addr);
+ if (bar->bar2_halve)
+ addr |= 0x40000000;
+ nvkm_wr32(device, 0x001714, 0x80000000 | addr);
}
return 0;
@@ -161,6 +166,7 @@ gf100_bar_new_(const struct nvkm_bar_func *func, struct nvkm_device *device,
if (!(bar = kzalloc(sizeof(*bar), GFP_KERNEL)))
return -ENOMEM;
nvkm_bar_ctor(func, device, index, &bar->base);
+ bar->bar2_halve = nvkm_boolopt(device->cfgopt, "NvBar2Halve", false);
*pbar = &bar->base;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h
index f7dea69640d8..20a5255362ba 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h
@@ -11,6 +11,7 @@ struct gf100_bar_vm {
struct gf100_bar {
struct nvkm_bar base;
+ bool bar2_halve;
struct gf100_bar_vm bar[2];
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
index 3841ad6be99e..a239e73562c8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
@@ -60,12 +60,12 @@ gf100_fb_oneinit(struct nvkm_fb *base)
size = min(size, 0x1000);
ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, size, 0x1000,
- false, &fb->base.mmu_rd);
+ true, &fb->base.mmu_rd);
if (ret)
return ret;
ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, size, 0x1000,
- false, &fb->base.mmu_wr);
+ true, &fb->base.mmu_wr);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild
index 48f01e40b8fc..b768e66a472b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/Kbuild
@@ -25,6 +25,7 @@ nvkm-y += nvkm/subdev/i2c/bit.o
nvkm-y += nvkm/subdev/i2c/aux.o
nvkm-y += nvkm/subdev/i2c/auxg94.o
+nvkm-y += nvkm/subdev/i2c/auxgf119.o
nvkm-y += nvkm/subdev/i2c/auxgm200.o
nvkm-y += nvkm/subdev/i2c/anx9805.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c
index d172e42dd228..4c1f547da463 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c
@@ -117,6 +117,10 @@ int
nvkm_i2c_aux_xfer(struct nvkm_i2c_aux *aux, bool retry, u8 type,
u32 addr, u8 *data, u8 *size)
{
+ if (!*size && !aux->func->address_only) {
+ AUX_ERR(aux, "address-only transaction dropped");
+ return -ENOSYS;
+ }
return aux->func->xfer(aux, retry, type, addr, data, size);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h
index 27a4a39c87f0..9587ab456d9e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h
@@ -3,6 +3,7 @@
#include "pad.h"
struct nvkm_i2c_aux_func {
+ bool address_only;
int (*xfer)(struct nvkm_i2c_aux *, bool retry, u8 type,
u32 addr, u8 *data, u8 *size);
int (*lnk_ctl)(struct nvkm_i2c_aux *, int link_nr, int link_bw,
@@ -17,7 +18,12 @@ void nvkm_i2c_aux_del(struct nvkm_i2c_aux **);
int nvkm_i2c_aux_xfer(struct nvkm_i2c_aux *, bool retry, u8 type,
u32 addr, u8 *data, u8 *size);
+int g94_i2c_aux_new_(const struct nvkm_i2c_aux_func *, struct nvkm_i2c_pad *,
+ int, u8, struct nvkm_i2c_aux **);
+
int g94_i2c_aux_new(struct nvkm_i2c_pad *, int, u8, struct nvkm_i2c_aux **);
+int g94_i2c_aux_xfer(struct nvkm_i2c_aux *, bool, u8, u32, u8 *, u8 *);
+int gf119_i2c_aux_new(struct nvkm_i2c_pad *, int, u8, struct nvkm_i2c_aux **);
int gm200_i2c_aux_new(struct nvkm_i2c_pad *, int, u8, struct nvkm_i2c_aux **);
#define AUX_MSG(b,l,f,a...) do { \
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c
index ab8cb196c34e..c8ab1b5741a3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c
@@ -72,7 +72,7 @@ g94_i2c_aux_init(struct g94_i2c_aux *aux)
return 0;
}
-static int
+int
g94_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry,
u8 type, u32 addr, u8 *data, u8 *size)
{
@@ -105,9 +105,9 @@ g94_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry,
}
ctrl = nvkm_rd32(device, 0x00e4e4 + base);
- ctrl &= ~0x0001f0ff;
+ ctrl &= ~0x0001f1ff;
ctrl |= type << 12;
- ctrl |= *size - 1;
+ ctrl |= (*size ? (*size - 1) : 0x00000100);
nvkm_wr32(device, 0x00e4e0 + base, addr);
/* (maybe) retry transaction a number of times on failure... */
@@ -160,14 +160,10 @@ out:
return ret < 0 ? ret : (stat & 0x000f0000) >> 16;
}
-static const struct nvkm_i2c_aux_func
-g94_i2c_aux_func = {
- .xfer = g94_i2c_aux_xfer,
-};
-
int
-g94_i2c_aux_new(struct nvkm_i2c_pad *pad, int index, u8 drive,
- struct nvkm_i2c_aux **paux)
+g94_i2c_aux_new_(const struct nvkm_i2c_aux_func *func,
+ struct nvkm_i2c_pad *pad, int index, u8 drive,
+ struct nvkm_i2c_aux **paux)
{
struct g94_i2c_aux *aux;
@@ -175,8 +171,20 @@ g94_i2c_aux_new(struct nvkm_i2c_pad *pad, int index, u8 drive,
return -ENOMEM;
*paux = &aux->base;
- nvkm_i2c_aux_ctor(&g94_i2c_aux_func, pad, index, &aux->base);
+ nvkm_i2c_aux_ctor(func, pad, index, &aux->base);
aux->ch = drive;
aux->base.intr = 1 << aux->ch;
return 0;
}
+
+static const struct nvkm_i2c_aux_func
+g94_i2c_aux = {
+ .xfer = g94_i2c_aux_xfer,
+};
+
+int
+g94_i2c_aux_new(struct nvkm_i2c_pad *pad, int index, u8 drive,
+ struct nvkm_i2c_aux **paux)
+{
+ return g94_i2c_aux_new_(&g94_i2c_aux, pad, index, drive, paux);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c
new file mode 100644
index 000000000000..dab40cd8fe3a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgf119.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2017 Red Hat 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.
+ */
+#include "aux.h"
+
+static const struct nvkm_i2c_aux_func
+gf119_i2c_aux = {
+ .address_only = true,
+ .xfer = g94_i2c_aux_xfer,
+};
+
+int
+gf119_i2c_aux_new(struct nvkm_i2c_pad *pad, int index, u8 drive,
+ struct nvkm_i2c_aux **paux)
+{
+ return g94_i2c_aux_new_(&gf119_i2c_aux, pad, index, drive, paux);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c
index ee091fa79628..7ef60895f43a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c
@@ -105,9 +105,9 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry,
}
ctrl = nvkm_rd32(device, 0x00d954 + base);
- ctrl &= ~0x0001f0ff;
+ ctrl &= ~0x0001f1ff;
ctrl |= type << 12;
- ctrl |= *size - 1;
+ ctrl |= (*size ? (*size - 1) : 0x00000100);
nvkm_wr32(device, 0x00d950 + base, addr);
/* (maybe) retry transaction a number of times on failure... */
@@ -162,6 +162,7 @@ out:
static const struct nvkm_i2c_aux_func
gm200_i2c_aux_func = {
+ .address_only = true,
.xfer = gm200_i2c_aux_xfer,
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgf119.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgf119.c
index d53212f1aa52..3bc4d0310076 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgf119.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/padgf119.c
@@ -28,7 +28,7 @@
static const struct nvkm_i2c_pad_func
gf119_i2c_pad_s_func = {
.bus_new_4 = gf119_i2c_bus_new,
- .aux_new_6 = g94_i2c_aux_new,
+ .aux_new_6 = gf119_i2c_aux_new,
.mode = g94_i2c_pad_mode,
};
@@ -41,7 +41,7 @@ gf119_i2c_pad_s_new(struct nvkm_i2c *i2c, int id, struct nvkm_i2c_pad **ppad)
static const struct nvkm_i2c_pad_func
gf119_i2c_pad_x_func = {
.bus_new_4 = gf119_i2c_bus_new,
- .aux_new_6 = g94_i2c_aux_new,
+ .aux_new_6 = gf119_i2c_aux_new,
};
int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
index d2c4d6033abb..f93766418056 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
@@ -27,6 +27,7 @@ static const struct nvkm_mc_map
gf100_mc_reset[] = {
{ 0x00020000, NVKM_ENGINE_MSPDEC },
{ 0x00008000, NVKM_ENGINE_MSVLD },
+ { 0x00002000, NVKM_SUBDEV_PMU, true },
{ 0x00001000, NVKM_ENGINE_GR },
{ 0x00000100, NVKM_ENGINE_FIFO },
{ 0x00000080, NVKM_ENGINE_CE1 },
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
index eb9b278198b2..a4cb82495cee 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
@@ -192,6 +192,10 @@ nvkm_pci_new_(const struct nvkm_pci_func *func, struct nvkm_device *device,
}
}
+#ifdef __BIG_ENDIAN
+ pci->msi = false;
+#endif
+
pci->msi = nvkm_boolopt(device->cfgopt, "NvMSI", pci->msi);
if (pci->msi && func->msi_rearm) {
pci->msi = pci_enable_msi(pci->pdev) == 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
index 3306f9fe7140..ce70a193caa7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
@@ -75,7 +75,7 @@ nvkm_pmu_reset(struct nvkm_pmu *pmu)
{
struct nvkm_device *device = pmu->subdev.device;
- if (!(nvkm_rd32(device, 0x000200) & 0x00002000))
+ if (!pmu->func->enabled(pmu))
return 0;
/* Inhibit interrupts, and wait for idle. */
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c
index 0e36d4cb7201..0b458656e870 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c
@@ -24,13 +24,30 @@
#include "priv.h"
#include "fuc/gf100.fuc3.h"
+#include <subdev/mc.h>
+
+void
+gf100_pmu_reset(struct nvkm_pmu *pmu)
+{
+ struct nvkm_device *device = pmu->subdev.device;
+ nvkm_mc_disable(device, NVKM_SUBDEV_PMU);
+ nvkm_mc_enable(device, NVKM_SUBDEV_PMU);
+}
+
+bool
+gf100_pmu_enabled(struct nvkm_pmu *pmu)
+{
+ return nvkm_mc_enabled(pmu->subdev.device, NVKM_SUBDEV_PMU);
+}
+
static const struct nvkm_pmu_func
gf100_pmu = {
.code.data = gf100_pmu_code,
.code.size = sizeof(gf100_pmu_code),
.data.data = gf100_pmu_data,
.data.size = sizeof(gf100_pmu_data),
- .reset = gt215_pmu_reset,
+ .enabled = gf100_pmu_enabled,
+ .reset = gf100_pmu_reset,
.init = gt215_pmu_init,
.fini = gt215_pmu_fini,
.intr = gt215_pmu_intr,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c
index 0e4ba4248b15..3dfa79d4fb13 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c
@@ -30,7 +30,8 @@ gf119_pmu = {
.code.size = sizeof(gf119_pmu_code),
.data.data = gf119_pmu_data,
.data.size = sizeof(gf119_pmu_data),
- .reset = gt215_pmu_reset,
+ .enabled = gf100_pmu_enabled,
+ .reset = gf100_pmu_reset,
.init = gt215_pmu_init,
.fini = gt215_pmu_fini,
.intr = gt215_pmu_intr,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c
index 2ad858d825ac..8f7ec10fd2a4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c
@@ -109,7 +109,8 @@ gk104_pmu = {
.code.size = sizeof(gk104_pmu_code),
.data.data = gk104_pmu_data,
.data.size = sizeof(gk104_pmu_data),
- .reset = gt215_pmu_reset,
+ .enabled = gf100_pmu_enabled,
+ .reset = gf100_pmu_reset,
.init = gt215_pmu_init,
.fini = gt215_pmu_fini,
.intr = gt215_pmu_intr,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c
index fc4b8ecfdaeb..345741d55a56 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c
@@ -88,7 +88,8 @@ gk110_pmu = {
.code.size = sizeof(gk110_pmu_code),
.data.data = gk110_pmu_data,
.data.size = sizeof(gk110_pmu_data),
- .reset = gt215_pmu_reset,
+ .enabled = gf100_pmu_enabled,
+ .reset = gf100_pmu_reset,
.init = gt215_pmu_init,
.fini = gt215_pmu_fini,
.intr = gt215_pmu_intr,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c
index e9a91277683a..e4acf7876ea1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c
@@ -30,7 +30,8 @@ gk208_pmu = {
.code.size = sizeof(gk208_pmu_code),
.data.data = gk208_pmu_data,
.data.size = sizeof(gk208_pmu_data),
- .reset = gt215_pmu_reset,
+ .enabled = gf100_pmu_enabled,
+ .reset = gf100_pmu_reset,
.init = gt215_pmu_init,
.fini = gt215_pmu_fini,
.intr = gt215_pmu_intr,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c
index 978aae3c1001..05e81855c367 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c
@@ -196,9 +196,10 @@ gk20a_dvfs_data= {
static const struct nvkm_pmu_func
gk20a_pmu = {
+ .enabled = gf100_pmu_enabled,
.init = gk20a_pmu_init,
.fini = gk20a_pmu_fini,
- .reset = gt215_pmu_reset,
+ .reset = gf100_pmu_reset,
};
int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c
index 9a248ed75f09..459df1ef9e70 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c
@@ -32,7 +32,8 @@ gm107_pmu = {
.code.size = sizeof(gm107_pmu_code),
.data.data = gm107_pmu_data,
.data.size = sizeof(gm107_pmu_data),
- .reset = gt215_pmu_reset,
+ .enabled = gf100_pmu_enabled,
+ .reset = gf100_pmu_reset,
.init = gt215_pmu_init,
.fini = gt215_pmu_fini,
.intr = gt215_pmu_intr,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c
index 44bef22bce52..31c843145c7a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c
@@ -38,6 +38,7 @@ gm20b_pmu_recv(struct nvkm_pmu *pmu)
static const struct nvkm_pmu_func
gm20b_pmu = {
+ .enabled = gf100_pmu_enabled,
.intr = gt215_pmu_intr,
.recv = gm20b_pmu_recv,
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp100.c
index 6c41c20c85a7..e210cd6af816 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp100.c
@@ -25,7 +25,8 @@
static const struct nvkm_pmu_func
gp100_pmu = {
- .reset = gt215_pmu_reset,
+ .enabled = gf100_pmu_enabled,
+ .reset = gf100_pmu_reset,
};
int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c
index f017352206c9..98c7a2a8afc4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c
@@ -31,8 +31,15 @@ gp102_pmu_reset(struct nvkm_pmu *pmu)
nvkm_mask(device, 0x10a3c0, 0x00000001, 0x00000000);
}
+static bool
+gp102_pmu_enabled(struct nvkm_pmu *pmu)
+{
+ return !(nvkm_rd32(pmu->subdev.device, 0x10a3c0) & 0x00000001);
+}
+
static const struct nvkm_pmu_func
gp102_pmu = {
+ .enabled = gp102_pmu_enabled,
.reset = gp102_pmu_reset,
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c
index 90d428b3be97..e04216daea58 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c
@@ -180,13 +180,19 @@ gt215_pmu_fini(struct nvkm_pmu *pmu)
nvkm_wr32(pmu->subdev.device, 0x10a014, 0x00000060);
}
-void
+static void
gt215_pmu_reset(struct nvkm_pmu *pmu)
{
struct nvkm_device *device = pmu->subdev.device;
- nvkm_mask(device, 0x000200, 0x00002000, 0x00000000);
- nvkm_mask(device, 0x000200, 0x00002000, 0x00002000);
- nvkm_rd32(device, 0x000200);
+ nvkm_mask(device, 0x022210, 0x00000001, 0x00000000);
+ nvkm_mask(device, 0x022210, 0x00000001, 0x00000001);
+ nvkm_rd32(device, 0x022210);
+}
+
+static bool
+gt215_pmu_enabled(struct nvkm_pmu *pmu)
+{
+ return nvkm_rd32(pmu->subdev.device, 0x022210) & 0x00000001;
}
int
@@ -241,6 +247,7 @@ gt215_pmu = {
.code.size = sizeof(gt215_pmu_code),
.data.data = gt215_pmu_data,
.data.size = sizeof(gt215_pmu_data),
+ .enabled = gt215_pmu_enabled,
.reset = gt215_pmu_reset,
.init = gt215_pmu_init,
.fini = gt215_pmu_fini,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h
index 096cba069f72..a4c48a10cd47 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h
@@ -20,6 +20,7 @@ struct nvkm_pmu_func {
u32 size;
} data;
+ bool (*enabled)(struct nvkm_pmu *);
void (*reset)(struct nvkm_pmu *);
int (*init)(struct nvkm_pmu *);
void (*fini)(struct nvkm_pmu *);
@@ -30,12 +31,14 @@ struct nvkm_pmu_func {
void (*pgob)(struct nvkm_pmu *, bool);
};
-void gt215_pmu_reset(struct nvkm_pmu *);
int gt215_pmu_init(struct nvkm_pmu *);
void gt215_pmu_fini(struct nvkm_pmu *);
void gt215_pmu_intr(struct nvkm_pmu *);
void gt215_pmu_recv(struct nvkm_pmu *);
int gt215_pmu_send(struct nvkm_pmu *, u32[2], u32, u32, u32, u32);
+bool gf100_pmu_enabled(struct nvkm_pmu *);
+void gf100_pmu_reset(struct nvkm_pmu *);
+
void gk110_pmu_pgob(struct nvkm_pmu *, bool);
#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
index 135758ba3e28..2bafcc1d1818 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
@@ -11,3 +11,4 @@ nvkm-y += nvkm/subdev/therm/g84.o
nvkm-y += nvkm/subdev/therm/gt215.o
nvkm-y += nvkm/subdev/therm/gf119.o
nvkm-y += nvkm/subdev/therm/gm107.o
+nvkm-y += nvkm/subdev/therm/gm200.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c
index 86e81930d8ee..96f8da40ac82 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c
@@ -203,7 +203,7 @@ g84_therm_fini(struct nvkm_therm *therm)
nvkm_wr32(device, 0x1100, 0x10000); /* PBUS */
}
-static void
+void
g84_therm_init(struct nvkm_therm *therm)
{
g84_sensor_setup(therm);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm200.c
new file mode 100644
index 000000000000..73dc78093d5d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm200.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2017 Karol Herbst
+ *
+ * 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: Karol Herbst
+ */
+#include "priv.h"
+
+static const struct nvkm_therm_func
+gm200_therm = {
+ .init = g84_therm_init,
+ .fini = g84_therm_fini,
+ .temp_get = g84_temp_get,
+ .program_alarms = nvkm_therm_program_alarms_polling,
+};
+
+int
+gm200_therm_new(struct nvkm_device *device, int index,
+ struct nvkm_therm **ptherm)
+{
+ return nvkm_therm_new_(&gm200_therm, device, index, ptherm);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h
index 235a5d8daff6..1f46e371d7c4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h
@@ -111,6 +111,7 @@ void g84_therm_fini(struct nvkm_therm *);
int gt215_therm_fan_sense(struct nvkm_therm *);
+void g84_therm_init(struct nvkm_therm *);
void gf119_therm_init(struct nvkm_therm *);
int nvkm_fanpwm_create(struct nvkm_therm *, struct dcb_gpio_func *);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c
index e93b2410c38b..ddb2b2c600ca 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c
@@ -83,7 +83,7 @@ nvkm_therm_sensor_event(struct nvkm_therm *therm, enum nvkm_therm_thrs thrs,
{
struct nvkm_subdev *subdev = &therm->subdev;
bool active;
- const char *thresolds[] = {
+ static const char * const thresholds[] = {
"fanboost", "downclock", "critical", "shutdown"
};
int temperature = therm->func->temp_get(therm);
@@ -94,10 +94,10 @@ nvkm_therm_sensor_event(struct nvkm_therm *therm, enum nvkm_therm_thrs thrs,
if (dir == NVKM_THERM_THRS_FALLING)
nvkm_info(subdev,
"temperature (%i C) went below the '%s' threshold\n",
- temperature, thresolds[thrs]);
+ temperature, thresholds[thrs]);
else
nvkm_info(subdev, "temperature (%i C) hit the '%s' threshold\n",
- temperature, thresolds[thrs]);
+ temperature, thresholds[thrs]);
active = (dir == NVKM_THERM_THRS_RISING);
switch (thrs) {
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
index e1fa143a5625..542a76503fbd 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
@@ -198,6 +198,9 @@ static int tvc_probe(struct platform_device *pdev)
struct omap_dss_device *dssdev;
int r;
+ if (!pdev->dev.of_node)
+ return -ENODEV;
+
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index 79cb69f1acf5..d9d25df6fc1b 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -15,6 +15,7 @@
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
+#include <linux/mutex.h>
#include <drm/drm_edid.h>
@@ -37,6 +38,10 @@ static const struct videomode hdmic_default_vm = {
struct panel_drv_data {
struct omap_dss_device dssdev;
struct omap_dss_device *in;
+ void (*hpd_cb)(void *cb_data, enum drm_connector_status status);
+ void *hpd_cb_data;
+ bool hpd_enabled;
+ struct mutex hpd_lock;
struct device *dev;
@@ -167,6 +172,70 @@ static bool hdmic_detect(struct omap_dss_device *dssdev)
return in->ops.hdmi->detect(in);
}
+static int hdmic_register_hpd_cb(struct omap_dss_device *dssdev,
+ void (*cb)(void *cb_data,
+ enum drm_connector_status status),
+ void *cb_data)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ if (gpio_is_valid(ddata->hpd_gpio)) {
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_cb = cb;
+ ddata->hpd_cb_data = cb_data;
+ mutex_unlock(&ddata->hpd_lock);
+ return 0;
+ } else if (in->ops.hdmi->register_hpd_cb) {
+ return in->ops.hdmi->register_hpd_cb(in, cb, cb_data);
+ }
+
+ return -ENOTSUPP;
+}
+
+static void hdmic_unregister_hpd_cb(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ if (gpio_is_valid(ddata->hpd_gpio)) {
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_cb = NULL;
+ ddata->hpd_cb_data = NULL;
+ mutex_unlock(&ddata->hpd_lock);
+ } else if (in->ops.hdmi->unregister_hpd_cb) {
+ in->ops.hdmi->unregister_hpd_cb(in);
+ }
+}
+
+static void hdmic_enable_hpd(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ if (gpio_is_valid(ddata->hpd_gpio)) {
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_enabled = true;
+ mutex_unlock(&ddata->hpd_lock);
+ } else if (in->ops.hdmi->enable_hpd) {
+ in->ops.hdmi->enable_hpd(in);
+ }
+}
+
+static void hdmic_disable_hpd(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ if (gpio_is_valid(ddata->hpd_gpio)) {
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_enabled = false;
+ mutex_unlock(&ddata->hpd_lock);
+ } else if (in->ops.hdmi->disable_hpd) {
+ in->ops.hdmi->disable_hpd(in);
+ }
+}
+
static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
@@ -197,10 +266,34 @@ static struct omap_dss_driver hdmic_driver = {
.read_edid = hdmic_read_edid,
.detect = hdmic_detect,
+ .register_hpd_cb = hdmic_register_hpd_cb,
+ .unregister_hpd_cb = hdmic_unregister_hpd_cb,
+ .enable_hpd = hdmic_enable_hpd,
+ .disable_hpd = hdmic_disable_hpd,
.set_hdmi_mode = hdmic_set_hdmi_mode,
.set_hdmi_infoframe = hdmic_set_infoframe,
};
+static irqreturn_t hdmic_hpd_isr(int irq, void *data)
+{
+ struct panel_drv_data *ddata = data;
+
+ mutex_lock(&ddata->hpd_lock);
+ if (ddata->hpd_enabled && ddata->hpd_cb) {
+ enum drm_connector_status status;
+
+ if (hdmic_detect(&ddata->dssdev))
+ status = connector_status_connected;
+ else
+ status = connector_status_disconnected;
+
+ ddata->hpd_cb(ddata->hpd_cb_data, status);
+ }
+ mutex_unlock(&ddata->hpd_lock);
+
+ return IRQ_HANDLED;
+}
+
static int hdmic_probe_of(struct platform_device *pdev)
{
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
@@ -246,11 +339,22 @@ static int hdmic_probe(struct platform_device *pdev)
if (r)
return r;
+ mutex_init(&ddata->hpd_lock);
+
if (gpio_is_valid(ddata->hpd_gpio)) {
r = devm_gpio_request_one(&pdev->dev, ddata->hpd_gpio,
GPIOF_DIR_IN, "hdmi_hpd");
if (r)
goto err_reg;
+
+ r = devm_request_threaded_irq(&pdev->dev,
+ gpio_to_irq(ddata->hpd_gpio),
+ NULL, hdmic_hpd_isr,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
+ IRQF_ONESHOT,
+ "hdmic hpd", ddata);
+ if (r)
+ goto err_reg;
}
ddata->vm = hdmic_default_vm;
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
index 58276a48112e..a9e9d667c55e 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
@@ -15,12 +15,17 @@
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/gpio/consumer.h>
+#include <linux/mutex.h>
#include "../dss/omapdss.h"
struct panel_drv_data {
struct omap_dss_device dssdev;
struct omap_dss_device *in;
+ void (*hpd_cb)(void *cb_data, enum drm_connector_status status);
+ void *hpd_cb_data;
+ bool hpd_enabled;
+ struct mutex hpd_lock;
struct gpio_desc *ct_cp_hpd_gpio;
struct gpio_desc *ls_oe_gpio;
@@ -162,6 +167,49 @@ static bool tpd_detect(struct omap_dss_device *dssdev)
return gpiod_get_value_cansleep(ddata->hpd_gpio);
}
+static int tpd_register_hpd_cb(struct omap_dss_device *dssdev,
+ void (*cb)(void *cb_data,
+ enum drm_connector_status status),
+ void *cb_data)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_cb = cb;
+ ddata->hpd_cb_data = cb_data;
+ mutex_unlock(&ddata->hpd_lock);
+
+ return 0;
+}
+
+static void tpd_unregister_hpd_cb(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_cb = NULL;
+ ddata->hpd_cb_data = NULL;
+ mutex_unlock(&ddata->hpd_lock);
+}
+
+static void tpd_enable_hpd(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_enabled = true;
+ mutex_unlock(&ddata->hpd_lock);
+}
+
+static void tpd_disable_hpd(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ mutex_lock(&ddata->hpd_lock);
+ ddata->hpd_enabled = false;
+ mutex_unlock(&ddata->hpd_lock);
+}
+
static int tpd_set_infoframe(struct omap_dss_device *dssdev,
const struct hdmi_avi_infoframe *avi)
{
@@ -193,10 +241,34 @@ static const struct omapdss_hdmi_ops tpd_hdmi_ops = {
.read_edid = tpd_read_edid,
.detect = tpd_detect,
+ .register_hpd_cb = tpd_register_hpd_cb,
+ .unregister_hpd_cb = tpd_unregister_hpd_cb,
+ .enable_hpd = tpd_enable_hpd,
+ .disable_hpd = tpd_disable_hpd,
.set_infoframe = tpd_set_infoframe,
.set_hdmi_mode = tpd_set_hdmi_mode,
};
+static irqreturn_t tpd_hpd_isr(int irq, void *data)
+{
+ struct panel_drv_data *ddata = data;
+
+ mutex_lock(&ddata->hpd_lock);
+ if (ddata->hpd_enabled && ddata->hpd_cb) {
+ enum drm_connector_status status;
+
+ if (tpd_detect(&ddata->dssdev))
+ status = connector_status_connected;
+ else
+ status = connector_status_disconnected;
+
+ ddata->hpd_cb(ddata->hpd_cb_data, status);
+ }
+ mutex_unlock(&ddata->hpd_lock);
+
+ return IRQ_HANDLED;
+}
+
static int tpd_probe_of(struct platform_device *pdev)
{
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
@@ -261,6 +333,15 @@ static int tpd_probe(struct platform_device *pdev)
ddata->hpd_gpio = gpio;
+ mutex_init(&ddata->hpd_lock);
+
+ r = devm_request_threaded_irq(&pdev->dev, gpiod_to_irq(ddata->hpd_gpio),
+ NULL, tpd_hpd_isr,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "tpd12s015 hpd", ddata);
+ if (r)
+ goto err_gpio;
+
dssdev = &ddata->dssdev;
dssdev->ops.hdmi = &tpd_hdmi_ops;
dssdev->dev = &pdev->dev;
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
index 6468a765f3d1..e065f7e10cca 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
@@ -231,6 +231,9 @@ static int panel_dpi_probe(struct platform_device *pdev)
struct omap_dss_device *dssdev;
int r;
+ if (!pdev->dev.of_node)
+ return -ENODEV;
+
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
if (ddata == NULL)
return -ENOMEM;
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 76787a75a4dc..92c556ac22c7 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -554,7 +554,7 @@ static struct attribute *dsicm_attrs[] = {
NULL,
};
-static struct attribute_group dsicm_attr_group = {
+static const struct attribute_group dsicm_attr_group = {
.attrs = dsicm_attrs,
};
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
index c90474afaebd..74d13969b9ca 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
@@ -19,7 +19,7 @@
#include "../dss/omapdss.h"
-static struct videomode lb035q02_vm = {
+static const struct videomode lb035q02_vm = {
.hactive = 320,
.vactive = 240,
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
index 346aefdb015f..8e5bff4e5226 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
@@ -503,7 +503,7 @@ static struct attribute *bldev_attrs[] = {
NULL,
};
-static struct attribute_group bldev_attr_group = {
+static const struct attribute_group bldev_attr_group = {
.attrs = bldev_attrs,
};
@@ -720,6 +720,9 @@ static int acx565akm_probe(struct spi_device *spi)
dev_dbg(&spi->dev, "%s\n", __func__);
+ if (!spi->dev.of_node)
+ return -ENODEV;
+
spi->mode = SPI_MODE_3;
ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
index cbf4c67c4933..0a38a0e8c925 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
@@ -40,7 +40,7 @@ struct panel_drv_data {
struct spi_device *spi_dev;
};
-static struct videomode td028ttec1_panel_vm = {
+static const struct videomode td028ttec1_panel_vm = {
.hactive = 480,
.vactive = 640,
.pixelclock = 22153000,
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
index 20c6d8fe215a..ac4a6d4d134c 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
@@ -282,7 +282,7 @@ static struct attribute *tpo_td043_attrs[] = {
NULL,
};
-static struct attribute_group tpo_td043_attr_group = {
+static const struct attribute_group tpo_td043_attr_group = {
.attrs = tpo_td043_attrs,
};
diff --git a/drivers/gpu/drm/omapdrm/dss/Makefile b/drivers/gpu/drm/omapdrm/dss/Makefile
index 688195e448c5..142ce5a02542 100644
--- a/drivers/gpu/drm/omapdrm/dss/Makefile
+++ b/drivers/gpu/drm/omapdrm/dss/Makefile
@@ -5,7 +5,7 @@ omapdss-base-y := base.o display.o dss-of.o output.o
obj-$(CONFIG_OMAP2_DSS) += omapdss.o
# Core DSS files
-omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o \
+omapdss-y := core.o dss.o dispc.o dispc_coefs.o \
pll.o video-pll.o
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
diff --git a/drivers/gpu/drm/omapdrm/dss/core.c b/drivers/gpu/drm/omapdrm/dss/core.c
index bdce4bfdf6e0..197ddbc1512b 100644
--- a/drivers/gpu/drm/omapdrm/dss/core.c
+++ b/drivers/gpu/drm/omapdrm/dss/core.c
@@ -24,182 +24,10 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/err.h>
#include <linux/platform_device.h>
-#include <linux/seq_file.h>
-#include <linux/debugfs.h>
-#include <linux/io.h>
-#include <linux/device.h>
-#include <linux/regulator/consumer.h>
-#include <linux/suspend.h>
-#include <linux/slab.h>
#include "omapdss.h"
#include "dss.h"
-#include "dss_features.h"
-
-static struct {
- struct platform_device *pdev;
-} core;
-
-enum omapdss_version omapdss_get_version(void)
-{
- struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
- return pdata->version;
-}
-EXPORT_SYMBOL(omapdss_get_version);
-
-int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask)
-{
- struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
-
- if (!board_data->dsi_enable_pads)
- return -ENOENT;
-
- return board_data->dsi_enable_pads(dsi_id, lane_mask);
-}
-
-void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask)
-{
- struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
-
- if (!board_data->dsi_disable_pads)
- return;
-
- return board_data->dsi_disable_pads(dsi_id, lane_mask);
-}
-
-int dss_set_min_bus_tput(struct device *dev, unsigned long tput)
-{
- struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
-
- if (pdata->set_min_bus_tput)
- return pdata->set_min_bus_tput(dev, tput);
- else
- return 0;
-}
-
-#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
-static int dss_debug_show(struct seq_file *s, void *unused)
-{
- void (*func)(struct seq_file *) = s->private;
- func(s);
- return 0;
-}
-
-static int dss_debug_open(struct inode *inode, struct file *file)
-{
- return single_open(file, dss_debug_show, inode->i_private);
-}
-
-static const struct file_operations dss_debug_fops = {
- .open = dss_debug_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static struct dentry *dss_debugfs_dir;
-
-static int dss_initialize_debugfs(void)
-{
- dss_debugfs_dir = debugfs_create_dir("omapdss", NULL);
- if (IS_ERR(dss_debugfs_dir)) {
- int err = PTR_ERR(dss_debugfs_dir);
- dss_debugfs_dir = NULL;
- return err;
- }
-
- debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
- &dss_debug_dump_clocks, &dss_debug_fops);
-
- return 0;
-}
-
-static void dss_uninitialize_debugfs(void)
-{
- if (dss_debugfs_dir)
- debugfs_remove_recursive(dss_debugfs_dir);
-}
-
-int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
-{
- struct dentry *d;
-
- d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir,
- write, &dss_debug_fops);
-
- return PTR_ERR_OR_ZERO(d);
-}
-#else /* CONFIG_OMAP2_DSS_DEBUGFS */
-static inline int dss_initialize_debugfs(void)
-{
- return 0;
-}
-static inline void dss_uninitialize_debugfs(void)
-{
-}
-int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
-{
- return 0;
-}
-#endif /* CONFIG_OMAP2_DSS_DEBUGFS */
-
-/* PLATFORM DEVICE */
-
-static void dss_disable_all_devices(void)
-{
- struct omap_dss_device *dssdev = NULL;
-
- for_each_dss_dev(dssdev) {
- if (!dssdev->driver)
- continue;
-
- if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
- dssdev->driver->disable(dssdev);
- }
-}
-
-static int __init omap_dss_probe(struct platform_device *pdev)
-{
- int r;
-
- core.pdev = pdev;
-
- dss_features_init(omapdss_get_version());
-
- r = dss_initialize_debugfs();
- if (r)
- goto err_debugfs;
-
- return 0;
-
-err_debugfs:
-
- return r;
-}
-
-static int omap_dss_remove(struct platform_device *pdev)
-{
- dss_uninitialize_debugfs();
-
- return 0;
-}
-
-static void omap_dss_shutdown(struct platform_device *pdev)
-{
- DSSDBG("shutdown\n");
- dss_disable_all_devices();
-}
-
-static struct platform_driver omap_dss_driver = {
- .remove = omap_dss_remove,
- .shutdown = omap_dss_shutdown,
- .driver = {
- .name = "omapdss",
- },
-};
/* INIT */
static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
@@ -236,21 +64,25 @@ static void (*dss_output_drv_unreg_funcs[])(void) = {
dss_uninit_platform_driver,
};
+static struct platform_device *omap_drm_device;
+
static int __init omap_dss_init(void)
{
int r;
int i;
- r = platform_driver_probe(&omap_dss_driver, omap_dss_probe);
- if (r)
- return r;
-
for (i = 0; i < ARRAY_SIZE(dss_output_drv_reg_funcs); ++i) {
r = dss_output_drv_reg_funcs[i]();
if (r)
goto err_reg;
}
+ omap_drm_device = platform_device_register_simple("omapdrm", 0, NULL, 0);
+ if (IS_ERR(omap_drm_device)) {
+ r = PTR_ERR(omap_drm_device);
+ goto err_reg;
+ }
+
return 0;
err_reg:
@@ -259,8 +91,6 @@ err_reg:
++i)
dss_output_drv_unreg_funcs[i]();
- platform_driver_unregister(&omap_dss_driver);
-
return r;
}
@@ -268,10 +98,10 @@ static void __exit omap_dss_exit(void)
{
int i;
+ platform_device_unregister(omap_drm_device);
+
for (i = 0; i < ARRAY_SIZE(dss_output_drv_unreg_funcs); ++i)
dss_output_drv_unreg_funcs[i]();
-
- platform_driver_unregister(&omap_dss_driver);
}
module_init(omap_dss_init);
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c
index fd7504b37e3b..0f4fdb221498 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -39,13 +39,14 @@
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/component.h>
+#include <linux/sys_soc.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_blend.h>
#include "omapdss.h"
#include "dss.h"
-#include "dss_features.h"
#include "dispc.h"
/* DISPC */
@@ -63,6 +64,33 @@ enum omap_burst_size {
#define REG_FLD_MOD(idx, val, start, end) \
dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end))
+/* DISPC has feature id */
+enum dispc_feature_id {
+ FEAT_LCDENABLEPOL,
+ FEAT_LCDENABLESIGNAL,
+ FEAT_PCKFREEENABLE,
+ FEAT_FUNCGATED,
+ FEAT_MGR_LCD2,
+ FEAT_MGR_LCD3,
+ FEAT_LINEBUFFERSPLIT,
+ FEAT_ROWREPEATENABLE,
+ FEAT_RESIZECONF,
+ /* Independent core clk divider */
+ FEAT_CORE_CLK_DIV,
+ FEAT_HANDLE_UV_SEPARATE,
+ FEAT_ATTR2,
+ FEAT_CPR,
+ FEAT_PRELOAD,
+ FEAT_FIR_COEF_V,
+ FEAT_ALPHA_FIXED_ZORDER,
+ FEAT_ALPHA_FREE_ZORDER,
+ FEAT_FIFO_MERGE,
+ /* An unknown HW bug causing the normal FIFO thresholds not to work */
+ FEAT_OMAP3_DSI_FIFO_BUG,
+ FEAT_BURST_2D,
+ FEAT_MFLAG,
+};
+
struct dispc_features {
u8 sw_start;
u8 fp_start;
@@ -76,6 +104,9 @@ struct dispc_features {
u16 mgr_height_max;
unsigned long max_lcd_pclk;
unsigned long max_tv_pclk;
+ unsigned int max_downscale;
+ unsigned int max_line_width;
+ unsigned int min_pcd;
int (*calc_scaling) (unsigned long pclk, unsigned long lclk,
const struct videomode *vm,
u16 width, u16 height, u16 out_width, u16 out_height,
@@ -86,6 +117,16 @@ struct dispc_features {
u16 width, u16 height, u16 out_width, u16 out_height,
bool mem_to_mem);
u8 num_fifos;
+ const enum dispc_feature_id *features;
+ unsigned int num_features;
+ const struct dss_reg_field *reg_fields;
+ const unsigned int num_reg_fields;
+ const enum omap_overlay_caps *overlay_caps;
+ const u32 **supported_color_modes;
+ unsigned int num_mgrs;
+ unsigned int num_ovls;
+ unsigned int buffer_size_unit;
+ unsigned int burst_size_unit;
/* swap GFX & WB fifos */
bool gfx_fifo_workaround:1;
@@ -180,6 +221,17 @@ enum mgr_reg_fields {
DISPC_MGR_FLD_NUM,
};
+/* DISPC register field id */
+enum dispc_feat_reg_field {
+ FEAT_REG_FIRHINC,
+ FEAT_REG_FIRVINC,
+ FEAT_REG_FIFOHIGHTHRESHOLD,
+ FEAT_REG_FIFOLOWTHRESHOLD,
+ FEAT_REG_FIFOSIZE,
+ FEAT_REG_HORIZONTALACCU,
+ FEAT_REG_VERTICALACCU,
+};
+
struct dispc_reg_field {
u16 reg;
u8 high;
@@ -343,6 +395,38 @@ static void mgr_fld_write(enum omap_channel channel,
spin_unlock_irqrestore(&dispc.control_lock, flags);
}
+static int dispc_get_num_ovls(void)
+{
+ return dispc.feat->num_ovls;
+}
+
+static int dispc_get_num_mgrs(void)
+{
+ return dispc.feat->num_mgrs;
+}
+
+static void dispc_get_reg_field(enum dispc_feat_reg_field id,
+ u8 *start, u8 *end)
+{
+ if (id >= dispc.feat->num_reg_fields)
+ BUG();
+
+ *start = dispc.feat->reg_fields[id].start;
+ *end = dispc.feat->reg_fields[id].end;
+}
+
+static bool dispc_has_feature(enum dispc_feature_id id)
+{
+ unsigned int i;
+
+ for (i = 0; i < dispc.feat->num_features; i++) {
+ if (dispc.feat->features[i] == id)
+ return true;
+ }
+
+ return false;
+}
+
#define SR(reg) \
dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg)
#define RR(reg) \
@@ -358,19 +442,19 @@ static void dispc_save_context(void)
SR(CONTROL);
SR(CONFIG);
SR(LINE_NUMBER);
- if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
- dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
+ if (dispc_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
+ dispc_has_feature(FEAT_ALPHA_FREE_ZORDER))
SR(GLOBAL_ALPHA);
- if (dss_has_feature(FEAT_MGR_LCD2)) {
+ if (dispc_has_feature(FEAT_MGR_LCD2)) {
SR(CONTROL2);
SR(CONFIG2);
}
- if (dss_has_feature(FEAT_MGR_LCD3)) {
+ if (dispc_has_feature(FEAT_MGR_LCD3)) {
SR(CONTROL3);
SR(CONFIG3);
}
- for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
+ for (i = 0; i < dispc_get_num_mgrs(); i++) {
SR(DEFAULT_COLOR(i));
SR(TRANS_COLOR(i));
SR(SIZE_MGR(i));
@@ -385,14 +469,14 @@ static void dispc_save_context(void)
SR(DATA_CYCLE2(i));
SR(DATA_CYCLE3(i));
- if (dss_has_feature(FEAT_CPR)) {
+ if (dispc_has_feature(FEAT_CPR)) {
SR(CPR_COEF_R(i));
SR(CPR_COEF_G(i));
SR(CPR_COEF_B(i));
}
}
- for (i = 0; i < dss_feat_get_num_ovls(); i++) {
+ for (i = 0; i < dispc_get_num_ovls(); i++) {
SR(OVL_BA0(i));
SR(OVL_BA1(i));
SR(OVL_POSITION(i));
@@ -401,7 +485,7 @@ static void dispc_save_context(void)
SR(OVL_FIFO_THRESHOLD(i));
SR(OVL_ROW_INC(i));
SR(OVL_PIXEL_INC(i));
- if (dss_has_feature(FEAT_PRELOAD))
+ if (dispc_has_feature(FEAT_PRELOAD))
SR(OVL_PRELOAD(i));
if (i == OMAP_DSS_GFX) {
SR(OVL_WINDOW_SKIP(i));
@@ -422,12 +506,12 @@ static void dispc_save_context(void)
for (j = 0; j < 5; j++)
SR(OVL_CONV_COEF(i, j));
- if (dss_has_feature(FEAT_FIR_COEF_V)) {
+ if (dispc_has_feature(FEAT_FIR_COEF_V)) {
for (j = 0; j < 8; j++)
SR(OVL_FIR_COEF_V(i, j));
}
- if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
+ if (dispc_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
SR(OVL_BA0_UV(i));
SR(OVL_BA1_UV(i));
SR(OVL_FIR2(i));
@@ -443,11 +527,11 @@ static void dispc_save_context(void)
for (j = 0; j < 8; j++)
SR(OVL_FIR_COEF_V2(i, j));
}
- if (dss_has_feature(FEAT_ATTR2))
+ if (dispc_has_feature(FEAT_ATTR2))
SR(OVL_ATTRIBUTES2(i));
}
- if (dss_has_feature(FEAT_CORE_CLK_DIV))
+ if (dispc_has_feature(FEAT_CORE_CLK_DIV))
SR(DIVISOR);
dispc.ctx_valid = true;
@@ -468,15 +552,15 @@ static void dispc_restore_context(void)
/*RR(CONTROL);*/
RR(CONFIG);
RR(LINE_NUMBER);
- if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
- dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
+ if (dispc_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
+ dispc_has_feature(FEAT_ALPHA_FREE_ZORDER))
RR(GLOBAL_ALPHA);
- if (dss_has_feature(FEAT_MGR_LCD2))
+ if (dispc_has_feature(FEAT_MGR_LCD2))
RR(CONFIG2);
- if (dss_has_feature(FEAT_MGR_LCD3))
+ if (dispc_has_feature(FEAT_MGR_LCD3))
RR(CONFIG3);
- for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
+ for (i = 0; i < dispc_get_num_mgrs(); i++) {
RR(DEFAULT_COLOR(i));
RR(TRANS_COLOR(i));
RR(SIZE_MGR(i));
@@ -491,14 +575,14 @@ static void dispc_restore_context(void)
RR(DATA_CYCLE2(i));
RR(DATA_CYCLE3(i));
- if (dss_has_feature(FEAT_CPR)) {
+ if (dispc_has_feature(FEAT_CPR)) {
RR(CPR_COEF_R(i));
RR(CPR_COEF_G(i));
RR(CPR_COEF_B(i));
}
}
- for (i = 0; i < dss_feat_get_num_ovls(); i++) {
+ for (i = 0; i < dispc_get_num_ovls(); i++) {
RR(OVL_BA0(i));
RR(OVL_BA1(i));
RR(OVL_POSITION(i));
@@ -507,7 +591,7 @@ static void dispc_restore_context(void)
RR(OVL_FIFO_THRESHOLD(i));
RR(OVL_ROW_INC(i));
RR(OVL_PIXEL_INC(i));
- if (dss_has_feature(FEAT_PRELOAD))
+ if (dispc_has_feature(FEAT_PRELOAD))
RR(OVL_PRELOAD(i));
if (i == OMAP_DSS_GFX) {
RR(OVL_WINDOW_SKIP(i));
@@ -528,12 +612,12 @@ static void dispc_restore_context(void)
for (j = 0; j < 5; j++)
RR(OVL_CONV_COEF(i, j));
- if (dss_has_feature(FEAT_FIR_COEF_V)) {
+ if (dispc_has_feature(FEAT_FIR_COEF_V)) {
for (j = 0; j < 8; j++)
RR(OVL_FIR_COEF_V(i, j));
}
- if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
+ if (dispc_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
RR(OVL_BA0_UV(i));
RR(OVL_BA1_UV(i));
RR(OVL_FIR2(i));
@@ -549,18 +633,18 @@ static void dispc_restore_context(void)
for (j = 0; j < 8; j++)
RR(OVL_FIR_COEF_V2(i, j));
}
- if (dss_has_feature(FEAT_ATTR2))
+ if (dispc_has_feature(FEAT_ATTR2))
RR(OVL_ATTRIBUTES2(i));
}
- if (dss_has_feature(FEAT_CORE_CLK_DIV))
+ if (dispc_has_feature(FEAT_CORE_CLK_DIV))
RR(DIVISOR);
/* enable last, because LCD & DIGIT enable are here */
RR(CONTROL);
- if (dss_has_feature(FEAT_MGR_LCD2))
+ if (dispc_has_feature(FEAT_MGR_LCD2))
RR(CONTROL2);
- if (dss_has_feature(FEAT_MGR_LCD3))
+ if (dispc_has_feature(FEAT_MGR_LCD3))
RR(CONTROL3);
/* clear spurious SYNC_LOST_DIGIT interrupts */
dispc_clear_irqstatus(DISPC_IRQ_SYNC_LOST_DIGIT);
@@ -779,7 +863,7 @@ static void dispc_ovl_write_color_conv_coef(enum omap_plane_id plane,
static void dispc_setup_color_conv_coef(void)
{
int i;
- int num_ovl = dss_feat_get_num_ovls();
+ int num_ovl = dispc_get_num_ovls();
const struct color_conv_coef ctbl_bt601_5_ovl = {
/* YUV -> RGB */
298, 409, 0, 298, -208, -100, 298, 0, 517, 0,
@@ -868,10 +952,10 @@ static void dispc_ovl_enable_zorder_planes(void)
{
int i;
- if (!dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
+ if (!dispc_has_feature(FEAT_ALPHA_FREE_ZORDER))
return;
- for (i = 0; i < dss_feat_get_num_ovls(); i++)
+ for (i = 0; i < dispc_get_num_ovls(); i++)
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25);
}
@@ -994,7 +1078,7 @@ static bool format_is_yuv(u32 fourcc)
static void dispc_ovl_configure_burst_type(enum omap_plane_id plane,
enum omap_dss_rotation_type rotation_type)
{
- if (dss_has_feature(FEAT_BURST_2D) == 0)
+ if (dispc_has_feature(FEAT_BURST_2D) == 0)
return;
if (rotation_type == OMAP_DSS_ROT_TILER)
@@ -1025,7 +1109,7 @@ static void dispc_ovl_set_channel_out(enum omap_plane_id plane,
}
val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
- if (dss_has_feature(FEAT_MGR_LCD2)) {
+ if (dispc_has_feature(FEAT_MGR_LCD2)) {
switch (channel) {
case OMAP_DSS_CHANNEL_LCD:
chan = 0;
@@ -1040,7 +1124,7 @@ static void dispc_ovl_set_channel_out(enum omap_plane_id plane,
chan2 = 1;
break;
case OMAP_DSS_CHANNEL_LCD3:
- if (dss_has_feature(FEAT_MGR_LCD3)) {
+ if (dispc_has_feature(FEAT_MGR_LCD3)) {
chan = 0;
chan2 = 2;
} else {
@@ -1089,7 +1173,7 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane_id plane)
if (FLD_GET(val, shift, shift) == 1)
return OMAP_DSS_CHANNEL_DIGIT;
- if (!dss_has_feature(FEAT_MGR_LCD2))
+ if (!dispc_has_feature(FEAT_MGR_LCD2))
return OMAP_DSS_CHANNEL_LCD;
switch (FLD_GET(val, 31, 30)) {
@@ -1128,7 +1212,7 @@ static void dispc_configure_burst_sizes(void)
const int burst_size = BURST_SIZE_X8;
/* Configure burst size always to maximum size */
- for (i = 0; i < dss_feat_get_num_ovls(); ++i)
+ for (i = 0; i < dispc_get_num_ovls(); ++i)
dispc_ovl_set_burst_size(i, burst_size);
if (dispc.feat->has_writeback)
dispc_ovl_set_burst_size(OMAP_DSS_WB, burst_size);
@@ -1136,19 +1220,28 @@ static void dispc_configure_burst_sizes(void)
static u32 dispc_ovl_get_burst_size(enum omap_plane_id plane)
{
- unsigned unit = dss_feat_get_burst_size_unit();
/* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */
- return unit * 8;
+ return dispc.feat->burst_size_unit * 8;
}
-static const u32 *dispc_ovl_get_color_modes(enum omap_plane_id plane)
+static bool dispc_ovl_color_mode_supported(enum omap_plane_id plane, u32 fourcc)
{
- return dss_feat_get_supported_color_modes(plane);
+ const u32 *modes;
+ unsigned int i;
+
+ modes = dispc.feat->supported_color_modes[plane];
+
+ for (i = 0; modes[i]; ++i) {
+ if (modes[i] == fourcc)
+ return true;
+ }
+
+ return false;
}
-static int dispc_get_num_ovls(void)
+static const u32 *dispc_ovl_get_color_modes(enum omap_plane_id plane)
{
- return dss_feat_get_num_ovls();
+ return dispc.feat->supported_color_modes[plane];
}
static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
@@ -1223,9 +1316,9 @@ static void dispc_init_fifos(void)
u32 unit;
int i;
- unit = dss_feat_get_buffer_size_unit();
+ unit = dispc.feat->buffer_size_unit;
- dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
+ dispc_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
for (fifo = 0; fifo < dispc.feat->num_fifos; ++fifo) {
size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(fifo), start, end);
@@ -1265,7 +1358,7 @@ static void dispc_init_fifos(void)
/*
* Setup default fifo thresholds.
*/
- for (i = 0; i < dss_feat_get_num_ovls(); ++i) {
+ for (i = 0; i < dispc_get_num_ovls(); ++i) {
u32 low, high;
const bool use_fifomerge = false;
const bool manual_update = false;
@@ -1307,7 +1400,7 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane_id plane, u32 low,
u8 hi_start, hi_end, lo_start, lo_end;
u32 unit;
- unit = dss_feat_get_buffer_size_unit();
+ unit = dispc.feat->buffer_size_unit;
WARN_ON(low % unit != 0);
WARN_ON(high % unit != 0);
@@ -1315,8 +1408,8 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane_id plane, u32 low,
low /= unit;
high /= unit;
- dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end);
- dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end);
+ dispc_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end);
+ dispc_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end);
DSSDBG("fifo(%d) threshold (bytes), old %u/%u, new %u/%u\n",
plane,
@@ -1335,14 +1428,14 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane_id plane, u32 low,
* large for the preload field, set the threshold to the maximum value
* that can be held by the preload register
*/
- if (dss_has_feature(FEAT_PRELOAD) && dispc.feat->set_max_preload &&
+ if (dispc_has_feature(FEAT_PRELOAD) && dispc.feat->set_max_preload &&
plane != OMAP_DSS_WB)
dispc_write_reg(DISPC_OVL_PRELOAD(plane), min(high, 0xfffu));
}
void dispc_enable_fifomerge(bool enable)
{
- if (!dss_has_feature(FEAT_FIFO_MERGE)) {
+ if (!dispc_has_feature(FEAT_FIFO_MERGE)) {
WARN_ON(enable);
return;
}
@@ -1360,7 +1453,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane_id plane,
* buffer_units, and the fifo thresholds must be buffer_unit aligned.
*/
- unsigned buf_unit = dss_feat_get_buffer_size_unit();
+ unsigned buf_unit = dispc.feat->buffer_size_unit;
unsigned ovl_fifo_size, total_fifo_size, burst_size;
int i;
@@ -1369,7 +1462,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane_id plane,
if (use_fifomerge) {
total_fifo_size = 0;
- for (i = 0; i < dss_feat_get_num_ovls(); ++i)
+ for (i = 0; i < dispc_get_num_ovls(); ++i)
total_fifo_size += dispc_ovl_get_fifo_size(i);
} else {
total_fifo_size = ovl_fifo_size;
@@ -1381,7 +1474,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane_id plane,
* combined fifo size
*/
- if (manual_update && dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) {
+ if (manual_update && dispc_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) {
*fifo_low = ovl_fifo_size - burst_size * 2;
*fifo_high = total_fifo_size - burst_size;
} else if (plane == OMAP_DSS_WB) {
@@ -1435,9 +1528,9 @@ static void dispc_init_mflag(void)
(1 << 0) | /* MFLAG_CTRL = force always on */
(0 << 2)); /* MFLAG_START = disable */
- for (i = 0; i < dss_feat_get_num_ovls(); ++i) {
+ for (i = 0; i < dispc_get_num_ovls(); ++i) {
u32 size = dispc_ovl_get_fifo_size(i);
- u32 unit = dss_feat_get_buffer_size_unit();
+ u32 unit = dispc.feat->buffer_size_unit;
u32 low, high;
dispc_ovl_set_mflag(i, true);
@@ -1456,7 +1549,7 @@ static void dispc_init_mflag(void)
if (dispc.feat->has_writeback) {
u32 size = dispc_ovl_get_fifo_size(OMAP_DSS_WB);
- u32 unit = dss_feat_get_buffer_size_unit();
+ u32 unit = dispc.feat->buffer_size_unit;
u32 low, high;
dispc_ovl_set_mflag(OMAP_DSS_WB, true);
@@ -1483,10 +1576,8 @@ static void dispc_ovl_set_fir(enum omap_plane_id plane,
if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y) {
u8 hinc_start, hinc_end, vinc_start, vinc_end;
- dss_feat_get_reg_field(FEAT_REG_FIRHINC,
- &hinc_start, &hinc_end);
- dss_feat_get_reg_field(FEAT_REG_FIRVINC,
- &vinc_start, &vinc_end);
+ dispc_get_reg_field(FEAT_REG_FIRHINC, &hinc_start, &hinc_end);
+ dispc_get_reg_field(FEAT_REG_FIRVINC, &vinc_start, &vinc_end);
val = FLD_VAL(vinc, vinc_start, vinc_end) |
FLD_VAL(hinc, hinc_start, hinc_end);
@@ -1503,8 +1594,8 @@ static void dispc_ovl_set_vid_accu0(enum omap_plane_id plane, int haccu,
u32 val;
u8 hor_start, hor_end, vert_start, vert_end;
- dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
- dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
+ dispc_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
+ dispc_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
val = FLD_VAL(vaccu, vert_start, vert_end) |
FLD_VAL(haccu, hor_start, hor_end);
@@ -1518,8 +1609,8 @@ static void dispc_ovl_set_vid_accu1(enum omap_plane_id plane, int haccu,
u32 val;
u8 hor_start, hor_end, vert_start, vert_end;
- dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
- dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
+ dispc_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
+ dispc_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
val = FLD_VAL(vaccu, vert_start, vert_end) |
FLD_VAL(haccu, hor_start, hor_end);
@@ -1671,14 +1762,14 @@ static void dispc_ovl_set_scaling_common(enum omap_plane_id plane,
l |= five_taps ? (1 << 21) : 0;
/* VRESIZECONF and HRESIZECONF */
- if (dss_has_feature(FEAT_RESIZECONF)) {
+ if (dispc_has_feature(FEAT_RESIZECONF)) {
l &= ~(0x3 << 7);
l |= (orig_width <= out_width) ? 0 : (1 << 7);
l |= (orig_height <= out_height) ? 0 : (1 << 8);
}
/* LINEBUFFERSPLIT */
- if (dss_has_feature(FEAT_LINEBUFFERSPLIT)) {
+ if (dispc_has_feature(FEAT_LINEBUFFERSPLIT)) {
l &= ~(0x1 << 22);
l |= five_taps ? (1 << 22) : 0;
}
@@ -1713,7 +1804,7 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane_id plane,
int scale_y = out_height != orig_height;
bool chroma_upscale = plane != OMAP_DSS_WB;
- if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE))
+ if (!dispc_has_feature(FEAT_HANDLE_UV_SEPARATE))
return;
if (!format_is_yuv(fourcc)) {
@@ -1860,11 +1951,11 @@ static void dispc_ovl_set_rotation_attrs(enum omap_plane_id plane, u8 rotation,
vidrot = 1;
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), vidrot, 13, 12);
- if (dss_has_feature(FEAT_ROWREPEATENABLE))
+ if (dispc_has_feature(FEAT_ROWREPEATENABLE))
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane),
row_repeat ? 1 : 0, 18, 18);
- if (dss_feat_color_mode_supported(plane, DRM_FORMAT_NV12)) {
+ if (dispc_ovl_color_mode_supported(plane, DRM_FORMAT_NV12)) {
bool doublestride =
fourcc == DRM_FORMAT_NV12 &&
rotation_type == OMAP_DSS_ROT_TILER &&
@@ -2118,8 +2209,7 @@ static int dispc_ovl_calc_scaling_24xx(unsigned long pclk, unsigned long lclk,
int error;
u16 in_width, in_height;
int min_factor = min(*decim_x, *decim_y);
- const int maxsinglelinewidth =
- dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+ const int maxsinglelinewidth = dispc.feat->max_line_width;
*five_taps = false;
@@ -2163,8 +2253,7 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,
{
int error;
u16 in_width, in_height;
- const int maxsinglelinewidth =
- dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+ const int maxsinglelinewidth = dispc.feat->max_line_width;
do {
in_height = height / *decim_y;
@@ -2249,9 +2338,8 @@ static int dispc_ovl_calc_scaling_44xx(unsigned long pclk, unsigned long lclk,
u16 in_width, in_width_max;
int decim_x_min = *decim_x;
u16 in_height = height / *decim_y;
- const int maxsinglelinewidth =
- dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
- const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
+ const int maxsinglelinewidth = dispc.feat->max_line_width;
+ const int maxdownscale = dispc.feat->max_downscale;
if (mem_to_mem) {
in_width_max = out_width * maxdownscale;
@@ -2311,7 +2399,7 @@ static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk,
int *x_predecim, int *y_predecim, u16 pos_x,
enum omap_dss_rotation_type rotation_type, bool mem_to_mem)
{
- const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
+ const int maxdownscale = dispc.feat->max_downscale;
const int max_decim_limit = 16;
unsigned long core_clk = 0;
int decim_x, decim_y, ret;
@@ -2332,7 +2420,7 @@ static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk,
} else {
*x_predecim = max_decim_limit;
*y_predecim = (rotation_type == OMAP_DSS_ROT_TILER &&
- dss_has_feature(FEAT_BURST_2D)) ?
+ dispc_has_feature(FEAT_BURST_2D)) ?
2 : max_decim_limit;
}
@@ -2428,7 +2516,7 @@ static int dispc_ovl_setup_common(enum omap_plane_id plane,
out_height);
}
- if (!dss_feat_color_mode_supported(plane, fourcc))
+ if (!dispc_ovl_color_mode_supported(plane, fourcc))
return -EINVAL;
r = dispc_ovl_calc_scaling(pclk, lclk, caps, vm, in_width,
@@ -2549,7 +2637,7 @@ static int dispc_ovl_setup(enum omap_plane_id plane,
enum omap_channel channel)
{
int r;
- enum omap_overlay_caps caps = dss_feat_get_overlay_caps(plane);
+ enum omap_overlay_caps caps = dispc.feat->overlay_caps[plane];
const bool replication = true;
DSSDBG("dispc_ovl_setup %d, pa %pad, pa_uv %pad, sw %d, %d,%d, %dx%d ->"
@@ -2647,12 +2735,12 @@ static int dispc_ovl_enable(enum omap_plane_id plane, bool enable)
static enum omap_dss_output_id dispc_mgr_get_supported_outputs(enum omap_channel channel)
{
- return dss_feat_get_supported_outputs(channel);
+ return dss_get_supported_outputs(channel);
}
static void dispc_lcd_enable_signal_polarity(bool act_high)
{
- if (!dss_has_feature(FEAT_LCDENABLEPOL))
+ if (!dispc_has_feature(FEAT_LCDENABLEPOL))
return;
REG_FLD_MOD(DISPC_CONTROL, act_high ? 1 : 0, 29, 29);
@@ -2660,7 +2748,7 @@ static void dispc_lcd_enable_signal_polarity(bool act_high)
void dispc_lcd_enable_signal(bool enable)
{
- if (!dss_has_feature(FEAT_LCDENABLESIGNAL))
+ if (!dispc_has_feature(FEAT_LCDENABLESIGNAL))
return;
REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 28, 28);
@@ -2668,17 +2756,12 @@ void dispc_lcd_enable_signal(bool enable)
void dispc_pck_free_enable(bool enable)
{
- if (!dss_has_feature(FEAT_PCKFREEENABLE))
+ if (!dispc_has_feature(FEAT_PCKFREEENABLE))
return;
REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27);
}
-static int dispc_get_num_mgrs(void)
-{
- return dss_feat_get_num_mgrs();
-}
-
static void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable)
{
mgr_fld_write(channel, DISPC_MGR_FLD_FIFOHANDCHECK, enable);
@@ -2718,7 +2801,7 @@ static void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable)
static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch,
bool enable)
{
- if (!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER))
+ if (!dispc_has_feature(FEAT_ALPHA_FIXED_ZORDER))
return;
if (ch == OMAP_DSS_CHANNEL_LCD)
@@ -2735,7 +2818,7 @@ static void dispc_mgr_setup(enum omap_channel channel,
dispc_mgr_enable_trans_key(channel, info->trans_enabled);
dispc_mgr_enable_alpha_fixed_zorder(channel,
info->partial_alpha_enabled);
- if (dss_has_feature(FEAT_CPR)) {
+ if (dispc_has_feature(FEAT_CPR)) {
dispc_mgr_enable_cpr(channel, info->cpr_enable);
dispc_mgr_set_cpr_coef(channel, &info->cpr_coefs);
}
@@ -3013,7 +3096,7 @@ static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
dispc_write_reg(DISPC_DIVISORo(channel),
FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
- if (!dss_has_feature(FEAT_CORE_CLK_DIV) &&
+ if (!dispc_has_feature(FEAT_CORE_CLK_DIV) &&
channel == OMAP_DSS_CHANNEL_LCD)
dispc.core_clk_rate = dispc_fclk_rate() / lck_div;
}
@@ -3168,7 +3251,7 @@ void dispc_dump_clocks(struct seq_file *s)
seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
- if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
+ if (dispc_has_feature(FEAT_CORE_CLK_DIV)) {
seq_printf(s, "- DISPC-CORE-CLK -\n");
l = dispc_read_reg(DISPC_DIVISOR);
lcd = FLD_GET(l, 23, 16);
@@ -3179,9 +3262,9 @@ void dispc_dump_clocks(struct seq_file *s)
dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD);
- if (dss_has_feature(FEAT_MGR_LCD2))
+ if (dispc_has_feature(FEAT_MGR_LCD2))
dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD2);
- if (dss_has_feature(FEAT_MGR_LCD3))
+ if (dispc_has_feature(FEAT_MGR_LCD3))
dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD3);
dispc_runtime_put();
@@ -3221,18 +3304,18 @@ static void dispc_dump_regs(struct seq_file *s)
DUMPREG(DISPC_CAPABLE);
DUMPREG(DISPC_LINE_STATUS);
DUMPREG(DISPC_LINE_NUMBER);
- if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
- dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
+ if (dispc_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
+ dispc_has_feature(FEAT_ALPHA_FREE_ZORDER))
DUMPREG(DISPC_GLOBAL_ALPHA);
- if (dss_has_feature(FEAT_MGR_LCD2)) {
+ if (dispc_has_feature(FEAT_MGR_LCD2)) {
DUMPREG(DISPC_CONTROL2);
DUMPREG(DISPC_CONFIG2);
}
- if (dss_has_feature(FEAT_MGR_LCD3)) {
+ if (dispc_has_feature(FEAT_MGR_LCD3)) {
DUMPREG(DISPC_CONTROL3);
DUMPREG(DISPC_CONFIG3);
}
- if (dss_has_feature(FEAT_MFLAG))
+ if (dispc_has_feature(FEAT_MFLAG))
DUMPREG(DISPC_GLOBAL_MFLAG_ATTRIBUTE);
#undef DUMPREG
@@ -3245,7 +3328,7 @@ static void dispc_dump_regs(struct seq_file *s)
p_names = mgr_names;
/* DISPC channel specific registers */
- for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
+ for (i = 0; i < dispc_get_num_mgrs(); i++) {
DUMPREG(i, DISPC_DEFAULT_COLOR);
DUMPREG(i, DISPC_TRANS_COLOR);
DUMPREG(i, DISPC_SIZE_MGR);
@@ -3262,7 +3345,7 @@ static void dispc_dump_regs(struct seq_file *s)
DUMPREG(i, DISPC_DATA_CYCLE2);
DUMPREG(i, DISPC_DATA_CYCLE3);
- if (dss_has_feature(FEAT_CPR)) {
+ if (dispc_has_feature(FEAT_CPR)) {
DUMPREG(i, DISPC_CPR_COEF_R);
DUMPREG(i, DISPC_CPR_COEF_G);
DUMPREG(i, DISPC_CPR_COEF_B);
@@ -3271,7 +3354,7 @@ static void dispc_dump_regs(struct seq_file *s)
p_names = ovl_names;
- for (i = 0; i < dss_feat_get_num_ovls(); i++) {
+ for (i = 0; i < dispc_get_num_ovls(); i++) {
DUMPREG(i, DISPC_OVL_BA0);
DUMPREG(i, DISPC_OVL_BA1);
DUMPREG(i, DISPC_OVL_POSITION);
@@ -3282,9 +3365,9 @@ static void dispc_dump_regs(struct seq_file *s)
DUMPREG(i, DISPC_OVL_ROW_INC);
DUMPREG(i, DISPC_OVL_PIXEL_INC);
- if (dss_has_feature(FEAT_PRELOAD))
+ if (dispc_has_feature(FEAT_PRELOAD))
DUMPREG(i, DISPC_OVL_PRELOAD);
- if (dss_has_feature(FEAT_MFLAG))
+ if (dispc_has_feature(FEAT_MFLAG))
DUMPREG(i, DISPC_OVL_MFLAG_THRESHOLD);
if (i == OMAP_DSS_GFX) {
@@ -3297,14 +3380,14 @@ static void dispc_dump_regs(struct seq_file *s)
DUMPREG(i, DISPC_OVL_PICTURE_SIZE);
DUMPREG(i, DISPC_OVL_ACCU0);
DUMPREG(i, DISPC_OVL_ACCU1);
- if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
+ if (dispc_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
DUMPREG(i, DISPC_OVL_BA0_UV);
DUMPREG(i, DISPC_OVL_BA1_UV);
DUMPREG(i, DISPC_OVL_FIR2);
DUMPREG(i, DISPC_OVL_ACCU2_0);
DUMPREG(i, DISPC_OVL_ACCU2_1);
}
- if (dss_has_feature(FEAT_ATTR2))
+ if (dispc_has_feature(FEAT_ATTR2))
DUMPREG(i, DISPC_OVL_ATTRIBUTES2);
}
@@ -3319,21 +3402,21 @@ static void dispc_dump_regs(struct seq_file *s)
DUMPREG(i, DISPC_OVL_ROW_INC);
DUMPREG(i, DISPC_OVL_PIXEL_INC);
- if (dss_has_feature(FEAT_MFLAG))
+ if (dispc_has_feature(FEAT_MFLAG))
DUMPREG(i, DISPC_OVL_MFLAG_THRESHOLD);
DUMPREG(i, DISPC_OVL_FIR);
DUMPREG(i, DISPC_OVL_PICTURE_SIZE);
DUMPREG(i, DISPC_OVL_ACCU0);
DUMPREG(i, DISPC_OVL_ACCU1);
- if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
+ if (dispc_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
DUMPREG(i, DISPC_OVL_BA0_UV);
DUMPREG(i, DISPC_OVL_BA1_UV);
DUMPREG(i, DISPC_OVL_FIR2);
DUMPREG(i, DISPC_OVL_ACCU2_0);
DUMPREG(i, DISPC_OVL_ACCU2_1);
}
- if (dss_has_feature(FEAT_ATTR2))
+ if (dispc_has_feature(FEAT_ATTR2))
DUMPREG(i, DISPC_OVL_ATTRIBUTES2);
}
@@ -3349,7 +3432,7 @@ static void dispc_dump_regs(struct seq_file *s)
/* Video pipeline coefficient registers */
/* start from OMAP_DSS_VIDEO1 */
- for (i = 1; i < dss_feat_get_num_ovls(); i++) {
+ for (i = 1; i < dispc_get_num_ovls(); i++) {
for (j = 0; j < 8; j++)
DUMPREG(i, DISPC_OVL_FIR_COEF_H, j);
@@ -3359,12 +3442,12 @@ static void dispc_dump_regs(struct seq_file *s)
for (j = 0; j < 5; j++)
DUMPREG(i, DISPC_OVL_CONV_COEF, j);
- if (dss_has_feature(FEAT_FIR_COEF_V)) {
+ if (dispc_has_feature(FEAT_FIR_COEF_V)) {
for (j = 0; j < 8; j++)
DUMPREG(i, DISPC_OVL_FIR_COEF_V, j);
}
- if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
+ if (dispc_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
for (j = 0; j < 8; j++)
DUMPREG(i, DISPC_OVL_FIR_COEF_H2, j);
@@ -3397,7 +3480,7 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
return 0;
}
-bool dispc_div_calc(unsigned long dispc,
+bool dispc_div_calc(unsigned long dispc_freq,
unsigned long pck_min, unsigned long pck_max,
dispc_div_calc_func func, void *data)
{
@@ -3415,19 +3498,19 @@ bool dispc_div_calc(unsigned long dispc,
min_fck_per_pck = 0;
#endif
- pckd_hw_min = dss_feat_get_param_min(FEAT_PARAM_DSS_PCD);
- pckd_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_PCD);
+ pckd_hw_min = dispc.feat->min_pcd;
+ pckd_hw_max = 255;
- lck_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
+ lck_max = dss_get_max_fck_rate();
pck_min = pck_min ? pck_min : 1;
pck_max = pck_max ? pck_max : ULONG_MAX;
- lckd_start = max(DIV_ROUND_UP(dispc, lck_max), 1ul);
- lckd_stop = min(dispc / pck_min, 255ul);
+ lckd_start = max(DIV_ROUND_UP(dispc_freq, lck_max), 1ul);
+ lckd_stop = min(dispc_freq / pck_min, 255ul);
for (lckd = lckd_start; lckd <= lckd_stop; ++lckd) {
- lck = dispc / lckd;
+ lck = dispc_freq / lckd;
pckd_start = max(DIV_ROUND_UP(lck, pck_max), pckd_hw_min);
pckd_stop = min(lck / pck_min, pckd_hw_max);
@@ -3441,7 +3524,7 @@ bool dispc_div_calc(unsigned long dispc,
* also. Thus we need to use the calculated lck. For
* OMAP4+ the DISPC fclk is a separate clock.
*/
- if (dss_has_feature(FEAT_CORE_CLK_DIV))
+ if (dispc_has_feature(FEAT_CORE_CLK_DIV))
fck = dispc_core_clk_rate();
else
fck = lck;
@@ -3556,10 +3639,10 @@ static void dispc_restore_gamma_tables(void)
dispc_mgr_write_gamma_table(OMAP_DSS_CHANNEL_DIGIT);
- if (dss_has_feature(FEAT_MGR_LCD2))
+ if (dispc_has_feature(FEAT_MGR_LCD2))
dispc_mgr_write_gamma_table(OMAP_DSS_CHANNEL_LCD2);
- if (dss_has_feature(FEAT_MGR_LCD3))
+ if (dispc_has_feature(FEAT_MGR_LCD3))
dispc_mgr_write_gamma_table(OMAP_DSS_CHANNEL_LCD3);
}
@@ -3627,11 +3710,11 @@ static int dispc_init_gamma_tables(void)
u32 *gt;
if (channel == OMAP_DSS_CHANNEL_LCD2 &&
- !dss_has_feature(FEAT_MGR_LCD2))
+ !dispc_has_feature(FEAT_MGR_LCD2))
continue;
if (channel == OMAP_DSS_CHANNEL_LCD3 &&
- !dss_has_feature(FEAT_MGR_LCD3))
+ !dispc_has_feature(FEAT_MGR_LCD3))
continue;
gt = devm_kmalloc_array(&dispc.pdev->dev, gdesc->len,
@@ -3651,7 +3734,7 @@ static void _omap_dispc_initial_config(void)
u32 l;
/* Exclusively enable DISPC_CORE_CLK and set divider to 1 */
- if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
+ if (dispc_has_feature(FEAT_CORE_CLK_DIV)) {
l = dispc_read_reg(DISPC_DIVISOR);
/* Use DISPC_DIVISOR.LCD, instead of DISPC_DIVISOR1.LCD */
l = FLD_MOD(l, 1, 0, 0);
@@ -3669,7 +3752,7 @@ static void _omap_dispc_initial_config(void)
* func-clock auto-gating. For newer versions
* (dispc.feat->has_gamma_table) this enables tv-out gamma tables.
*/
- if (dss_has_feature(FEAT_FUNCGATED) || dispc.feat->has_gamma_table)
+ if (dispc_has_feature(FEAT_FUNCGATED) || dispc.feat->has_gamma_table)
REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
dispc_setup_color_conv_coef();
@@ -3685,10 +3768,272 @@ static void _omap_dispc_initial_config(void)
if (dispc.feat->mstandby_workaround)
REG_FLD_MOD(DISPC_MSTANDBY_CTRL, 1, 0, 0);
- if (dss_has_feature(FEAT_MFLAG))
+ if (dispc_has_feature(FEAT_MFLAG))
dispc_init_mflag();
}
+static const enum dispc_feature_id omap2_dispc_features_list[] = {
+ FEAT_LCDENABLEPOL,
+ FEAT_LCDENABLESIGNAL,
+ FEAT_PCKFREEENABLE,
+ FEAT_FUNCGATED,
+ FEAT_ROWREPEATENABLE,
+ FEAT_RESIZECONF,
+};
+
+static const enum dispc_feature_id omap3_dispc_features_list[] = {
+ FEAT_LCDENABLEPOL,
+ FEAT_LCDENABLESIGNAL,
+ FEAT_PCKFREEENABLE,
+ FEAT_FUNCGATED,
+ FEAT_LINEBUFFERSPLIT,
+ FEAT_ROWREPEATENABLE,
+ FEAT_RESIZECONF,
+ FEAT_CPR,
+ FEAT_PRELOAD,
+ FEAT_FIR_COEF_V,
+ FEAT_ALPHA_FIXED_ZORDER,
+ FEAT_FIFO_MERGE,
+ FEAT_OMAP3_DSI_FIFO_BUG,
+};
+
+static const enum dispc_feature_id am43xx_dispc_features_list[] = {
+ FEAT_LCDENABLEPOL,
+ FEAT_LCDENABLESIGNAL,
+ FEAT_PCKFREEENABLE,
+ FEAT_FUNCGATED,
+ FEAT_LINEBUFFERSPLIT,
+ FEAT_ROWREPEATENABLE,
+ FEAT_RESIZECONF,
+ FEAT_CPR,
+ FEAT_PRELOAD,
+ FEAT_FIR_COEF_V,
+ FEAT_ALPHA_FIXED_ZORDER,
+ FEAT_FIFO_MERGE,
+};
+
+static const enum dispc_feature_id omap4_dispc_features_list[] = {
+ FEAT_MGR_LCD2,
+ FEAT_CORE_CLK_DIV,
+ FEAT_HANDLE_UV_SEPARATE,
+ FEAT_ATTR2,
+ FEAT_CPR,
+ FEAT_PRELOAD,
+ FEAT_FIR_COEF_V,
+ FEAT_ALPHA_FREE_ZORDER,
+ FEAT_FIFO_MERGE,
+ FEAT_BURST_2D,
+};
+
+static const enum dispc_feature_id omap5_dispc_features_list[] = {
+ FEAT_MGR_LCD2,
+ FEAT_MGR_LCD3,
+ FEAT_CORE_CLK_DIV,
+ FEAT_HANDLE_UV_SEPARATE,
+ FEAT_ATTR2,
+ FEAT_CPR,
+ FEAT_PRELOAD,
+ FEAT_FIR_COEF_V,
+ FEAT_ALPHA_FREE_ZORDER,
+ FEAT_FIFO_MERGE,
+ FEAT_BURST_2D,
+ FEAT_MFLAG,
+};
+
+static const struct dss_reg_field omap2_dispc_reg_fields[] = {
+ [FEAT_REG_FIRHINC] = { 11, 0 },
+ [FEAT_REG_FIRVINC] = { 27, 16 },
+ [FEAT_REG_FIFOLOWTHRESHOLD] = { 8, 0 },
+ [FEAT_REG_FIFOHIGHTHRESHOLD] = { 24, 16 },
+ [FEAT_REG_FIFOSIZE] = { 8, 0 },
+ [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
+ [FEAT_REG_VERTICALACCU] = { 25, 16 },
+};
+
+static const struct dss_reg_field omap3_dispc_reg_fields[] = {
+ [FEAT_REG_FIRHINC] = { 12, 0 },
+ [FEAT_REG_FIRVINC] = { 28, 16 },
+ [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 },
+ [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 },
+ [FEAT_REG_FIFOSIZE] = { 10, 0 },
+ [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
+ [FEAT_REG_VERTICALACCU] = { 25, 16 },
+};
+
+static const struct dss_reg_field omap4_dispc_reg_fields[] = {
+ [FEAT_REG_FIRHINC] = { 12, 0 },
+ [FEAT_REG_FIRVINC] = { 28, 16 },
+ [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 },
+ [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 },
+ [FEAT_REG_FIFOSIZE] = { 15, 0 },
+ [FEAT_REG_HORIZONTALACCU] = { 10, 0 },
+ [FEAT_REG_VERTICALACCU] = { 26, 16 },
+};
+
+static const enum omap_overlay_caps omap2_dispc_overlay_caps[] = {
+ /* OMAP_DSS_GFX */
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO1 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO2 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
+};
+
+static const enum omap_overlay_caps omap3430_dispc_overlay_caps[] = {
+ /* OMAP_DSS_GFX */
+ OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO1 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO2 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
+};
+
+static const enum omap_overlay_caps omap3630_dispc_overlay_caps[] = {
+ /* OMAP_DSS_GFX */
+ OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO1 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO2 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
+};
+
+static const enum omap_overlay_caps omap4_dispc_overlay_caps[] = {
+ /* OMAP_DSS_GFX */
+ OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
+ OMAP_DSS_OVL_CAP_ZORDER | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO1 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO2 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
+
+ /* OMAP_DSS_VIDEO3 */
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
+};
+
+#define COLOR_ARRAY(arr...) (const u32[]) { arr, 0 }
+
+static const u32 *omap2_dispc_supported_color_modes[] = {
+
+ /* OMAP_DSS_GFX */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGBX4444, DRM_FORMAT_RGB565,
+ DRM_FORMAT_XRGB8888, DRM_FORMAT_RGB888),
+
+ /* OMAP_DSS_VIDEO1 */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_YUYV,
+ DRM_FORMAT_UYVY),
+
+ /* OMAP_DSS_VIDEO2 */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_YUYV,
+ DRM_FORMAT_UYVY),
+};
+
+static const u32 *omap3_dispc_supported_color_modes[] = {
+ /* OMAP_DSS_GFX */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGBX4444, DRM_FORMAT_ARGB4444,
+ DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_RGBA8888, DRM_FORMAT_RGBX8888),
+
+ /* OMAP_DSS_VIDEO1 */
+ COLOR_ARRAY(
+ DRM_FORMAT_XRGB8888, DRM_FORMAT_RGB888,
+ DRM_FORMAT_RGBX4444, DRM_FORMAT_RGB565,
+ DRM_FORMAT_YUYV, DRM_FORMAT_UYVY),
+
+ /* OMAP_DSS_VIDEO2 */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGBX4444, DRM_FORMAT_ARGB4444,
+ DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_YUYV,
+ DRM_FORMAT_UYVY, DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_RGBA8888, DRM_FORMAT_RGBX8888),
+};
+
+static const u32 *omap4_dispc_supported_color_modes[] = {
+ /* OMAP_DSS_GFX */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGBX4444, DRM_FORMAT_ARGB4444,
+ DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_RGBA8888, DRM_FORMAT_RGBX8888,
+ DRM_FORMAT_ARGB1555, DRM_FORMAT_XRGB4444,
+ DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB1555),
+
+ /* OMAP_DSS_VIDEO1 */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGB565, DRM_FORMAT_RGBX4444,
+ DRM_FORMAT_YUYV, DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_RGBA8888, DRM_FORMAT_NV12,
+ DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_UYVY,
+ DRM_FORMAT_ARGB4444, DRM_FORMAT_XRGB1555,
+ DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB4444,
+ DRM_FORMAT_RGBX8888),
+
+ /* OMAP_DSS_VIDEO2 */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGB565, DRM_FORMAT_RGBX4444,
+ DRM_FORMAT_YUYV, DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_RGBA8888, DRM_FORMAT_NV12,
+ DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_UYVY,
+ DRM_FORMAT_ARGB4444, DRM_FORMAT_XRGB1555,
+ DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB4444,
+ DRM_FORMAT_RGBX8888),
+
+ /* OMAP_DSS_VIDEO3 */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGB565, DRM_FORMAT_RGBX4444,
+ DRM_FORMAT_YUYV, DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_RGBA8888, DRM_FORMAT_NV12,
+ DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_UYVY,
+ DRM_FORMAT_ARGB4444, DRM_FORMAT_XRGB1555,
+ DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB4444,
+ DRM_FORMAT_RGBX8888),
+
+ /* OMAP_DSS_WB */
+ COLOR_ARRAY(
+ DRM_FORMAT_RGB565, DRM_FORMAT_RGBX4444,
+ DRM_FORMAT_YUYV, DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_RGBA8888, DRM_FORMAT_NV12,
+ DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_RGB888, DRM_FORMAT_UYVY,
+ DRM_FORMAT_ARGB4444, DRM_FORMAT_XRGB1555,
+ DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB4444,
+ DRM_FORMAT_RGBX8888),
+};
+
static const struct dispc_features omap24xx_dispc_feats = {
.sw_start = 5,
.fp_start = 15,
@@ -3701,9 +4046,26 @@ static const struct dispc_features omap24xx_dispc_feats = {
.mgr_width_max = 2048,
.mgr_height_max = 2048,
.max_lcd_pclk = 66500000,
+ .max_downscale = 2,
+ /*
+ * Assume the line width buffer to be 768 pixels as OMAP2 DISPC scaler
+ * cannot scale an image width larger than 768.
+ */
+ .max_line_width = 768,
+ .min_pcd = 2,
.calc_scaling = dispc_ovl_calc_scaling_24xx,
.calc_core_clk = calc_core_clk_24xx,
.num_fifos = 3,
+ .features = omap2_dispc_features_list,
+ .num_features = ARRAY_SIZE(omap2_dispc_features_list),
+ .reg_fields = omap2_dispc_reg_fields,
+ .num_reg_fields = ARRAY_SIZE(omap2_dispc_reg_fields),
+ .overlay_caps = omap2_dispc_overlay_caps,
+ .supported_color_modes = omap2_dispc_supported_color_modes,
+ .num_mgrs = 2,
+ .num_ovls = 3,
+ .buffer_size_unit = 1,
+ .burst_size_unit = 8,
.no_framedone_tv = true,
.set_max_preload = false,
.last_pixel_inc_missing = true,
@@ -3722,9 +4084,22 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats = {
.mgr_height_max = 2048,
.max_lcd_pclk = 173000000,
.max_tv_pclk = 59000000,
+ .max_downscale = 4,
+ .max_line_width = 1024,
+ .min_pcd = 1,
.calc_scaling = dispc_ovl_calc_scaling_34xx,
.calc_core_clk = calc_core_clk_34xx,
.num_fifos = 3,
+ .features = omap3_dispc_features_list,
+ .num_features = ARRAY_SIZE(omap3_dispc_features_list),
+ .reg_fields = omap3_dispc_reg_fields,
+ .num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields),
+ .overlay_caps = omap3430_dispc_overlay_caps,
+ .supported_color_modes = omap3_dispc_supported_color_modes,
+ .num_mgrs = 2,
+ .num_ovls = 3,
+ .buffer_size_unit = 1,
+ .burst_size_unit = 8,
.no_framedone_tv = true,
.set_max_preload = false,
.last_pixel_inc_missing = true,
@@ -3743,9 +4118,90 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats = {
.mgr_height_max = 2048,
.max_lcd_pclk = 173000000,
.max_tv_pclk = 59000000,
+ .max_downscale = 4,
+ .max_line_width = 1024,
+ .min_pcd = 1,
+ .calc_scaling = dispc_ovl_calc_scaling_34xx,
+ .calc_core_clk = calc_core_clk_34xx,
+ .num_fifos = 3,
+ .features = omap3_dispc_features_list,
+ .num_features = ARRAY_SIZE(omap3_dispc_features_list),
+ .reg_fields = omap3_dispc_reg_fields,
+ .num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields),
+ .overlay_caps = omap3430_dispc_overlay_caps,
+ .supported_color_modes = omap3_dispc_supported_color_modes,
+ .num_mgrs = 2,
+ .num_ovls = 3,
+ .buffer_size_unit = 1,
+ .burst_size_unit = 8,
+ .no_framedone_tv = true,
+ .set_max_preload = false,
+ .last_pixel_inc_missing = true,
+};
+
+static const struct dispc_features omap36xx_dispc_feats = {
+ .sw_start = 7,
+ .fp_start = 19,
+ .bp_start = 31,
+ .sw_max = 256,
+ .vp_max = 4095,
+ .hp_max = 4096,
+ .mgr_width_start = 10,
+ .mgr_height_start = 26,
+ .mgr_width_max = 2048,
+ .mgr_height_max = 2048,
+ .max_lcd_pclk = 173000000,
+ .max_tv_pclk = 59000000,
+ .max_downscale = 4,
+ .max_line_width = 1024,
+ .min_pcd = 1,
.calc_scaling = dispc_ovl_calc_scaling_34xx,
.calc_core_clk = calc_core_clk_34xx,
.num_fifos = 3,
+ .features = omap3_dispc_features_list,
+ .num_features = ARRAY_SIZE(omap3_dispc_features_list),
+ .reg_fields = omap3_dispc_reg_fields,
+ .num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields),
+ .overlay_caps = omap3630_dispc_overlay_caps,
+ .supported_color_modes = omap3_dispc_supported_color_modes,
+ .num_mgrs = 2,
+ .num_ovls = 3,
+ .buffer_size_unit = 1,
+ .burst_size_unit = 8,
+ .no_framedone_tv = true,
+ .set_max_preload = false,
+ .last_pixel_inc_missing = true,
+};
+
+static const struct dispc_features am43xx_dispc_feats = {
+ .sw_start = 7,
+ .fp_start = 19,
+ .bp_start = 31,
+ .sw_max = 256,
+ .vp_max = 4095,
+ .hp_max = 4096,
+ .mgr_width_start = 10,
+ .mgr_height_start = 26,
+ .mgr_width_max = 2048,
+ .mgr_height_max = 2048,
+ .max_lcd_pclk = 173000000,
+ .max_tv_pclk = 59000000,
+ .max_downscale = 4,
+ .max_line_width = 1024,
+ .min_pcd = 1,
+ .calc_scaling = dispc_ovl_calc_scaling_34xx,
+ .calc_core_clk = calc_core_clk_34xx,
+ .num_fifos = 3,
+ .features = am43xx_dispc_features_list,
+ .num_features = ARRAY_SIZE(am43xx_dispc_features_list),
+ .reg_fields = omap3_dispc_reg_fields,
+ .num_reg_fields = ARRAY_SIZE(omap3_dispc_reg_fields),
+ .overlay_caps = omap3430_dispc_overlay_caps,
+ .supported_color_modes = omap3_dispc_supported_color_modes,
+ .num_mgrs = 1,
+ .num_ovls = 3,
+ .buffer_size_unit = 1,
+ .burst_size_unit = 8,
.no_framedone_tv = true,
.set_max_preload = false,
.last_pixel_inc_missing = true,
@@ -3764,9 +4220,22 @@ static const struct dispc_features omap44xx_dispc_feats = {
.mgr_height_max = 2048,
.max_lcd_pclk = 170000000,
.max_tv_pclk = 185625000,
+ .max_downscale = 4,
+ .max_line_width = 2048,
+ .min_pcd = 1,
.calc_scaling = dispc_ovl_calc_scaling_44xx,
.calc_core_clk = calc_core_clk_44xx,
.num_fifos = 5,
+ .features = omap4_dispc_features_list,
+ .num_features = ARRAY_SIZE(omap4_dispc_features_list),
+ .reg_fields = omap4_dispc_reg_fields,
+ .num_reg_fields = ARRAY_SIZE(omap4_dispc_reg_fields),
+ .overlay_caps = omap4_dispc_overlay_caps,
+ .supported_color_modes = omap4_dispc_supported_color_modes,
+ .num_mgrs = 3,
+ .num_ovls = 4,
+ .buffer_size_unit = 16,
+ .burst_size_unit = 16,
.gfx_fifo_workaround = true,
.set_max_preload = true,
.supports_sync_align = true,
@@ -3790,9 +4259,22 @@ static const struct dispc_features omap54xx_dispc_feats = {
.mgr_height_max = 4096,
.max_lcd_pclk = 170000000,
.max_tv_pclk = 186000000,
+ .max_downscale = 4,
+ .max_line_width = 2048,
+ .min_pcd = 1,
.calc_scaling = dispc_ovl_calc_scaling_44xx,
.calc_core_clk = calc_core_clk_44xx,
.num_fifos = 5,
+ .features = omap5_dispc_features_list,
+ .num_features = ARRAY_SIZE(omap5_dispc_features_list),
+ .reg_fields = omap4_dispc_reg_fields,
+ .num_reg_fields = ARRAY_SIZE(omap4_dispc_reg_fields),
+ .overlay_caps = omap4_dispc_overlay_caps,
+ .supported_color_modes = omap4_dispc_supported_color_modes,
+ .num_mgrs = 4,
+ .num_ovls = 4,
+ .buffer_size_unit = 16,
+ .burst_size_unit = 16,
.gfx_fifo_workaround = true,
.mstandby_workaround = true,
.set_max_preload = true,
@@ -3804,54 +4286,6 @@ static const struct dispc_features omap54xx_dispc_feats = {
.has_gamma_i734_bug = true,
};
-static int dispc_init_features(struct platform_device *pdev)
-{
- const struct dispc_features *src;
- struct dispc_features *dst;
-
- dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
- if (!dst) {
- dev_err(&pdev->dev, "Failed to allocate DISPC Features\n");
- return -ENOMEM;
- }
-
- switch (omapdss_get_version()) {
- case OMAPDSS_VER_OMAP24xx:
- src = &omap24xx_dispc_feats;
- break;
-
- case OMAPDSS_VER_OMAP34xx_ES1:
- src = &omap34xx_rev1_0_dispc_feats;
- break;
-
- case OMAPDSS_VER_OMAP34xx_ES3:
- case OMAPDSS_VER_OMAP3630:
- case OMAPDSS_VER_AM35xx:
- case OMAPDSS_VER_AM43xx:
- src = &omap34xx_rev3_0_dispc_feats;
- break;
-
- case OMAPDSS_VER_OMAP4430_ES1:
- case OMAPDSS_VER_OMAP4430_ES2:
- case OMAPDSS_VER_OMAP4:
- src = &omap44xx_dispc_feats;
- break;
-
- case OMAPDSS_VER_OMAP5:
- case OMAPDSS_VER_DRA7xx:
- src = &omap54xx_dispc_feats;
- break;
-
- default:
- return -ENODEV;
- }
-
- memcpy(dst, src, sizeof(*dst));
- dispc.feat = dst;
-
- return 0;
-}
-
static irqreturn_t dispc_irq_handler(int irq, void *arg)
{
if (!dispc.is_enabled)
@@ -4083,9 +4517,28 @@ static const struct dispc_ops dispc_ops = {
};
/* DISPC HW IP initialisation */
+static const struct of_device_id dispc_of_match[] = {
+ { .compatible = "ti,omap2-dispc", .data = &omap24xx_dispc_feats },
+ { .compatible = "ti,omap3-dispc", .data = &omap36xx_dispc_feats },
+ { .compatible = "ti,omap4-dispc", .data = &omap44xx_dispc_feats },
+ { .compatible = "ti,omap5-dispc", .data = &omap54xx_dispc_feats },
+ { .compatible = "ti,dra7-dispc", .data = &omap54xx_dispc_feats },
+ {},
+};
+
+static const struct soc_device_attribute dispc_soc_devices[] = {
+ { .machine = "OMAP3[45]*",
+ .revision = "ES[12].?", .data = &omap34xx_rev1_0_dispc_feats },
+ { .machine = "OMAP3[45]*", .data = &omap34xx_rev3_0_dispc_feats },
+ { .machine = "AM35*", .data = &omap34xx_rev3_0_dispc_feats },
+ { .machine = "AM43*", .data = &am43xx_dispc_feats },
+ { /* sentinel */ }
+};
+
static int dispc_bind(struct device *dev, struct device *master, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
+ const struct soc_device_attribute *soc;
u32 rev;
int r = 0;
struct resource *dispc_mem;
@@ -4095,9 +4548,15 @@ static int dispc_bind(struct device *dev, struct device *master, void *data)
spin_lock_init(&dispc.control_lock);
- r = dispc_init_features(dispc.pdev);
- if (r)
- return r;
+ /*
+ * The OMAP3-based models can't be told apart using the compatible
+ * string, use SoC device matching.
+ */
+ soc = soc_device_match(dispc_soc_devices);
+ if (soc)
+ dispc.feat = soc->data;
+ else
+ dispc.feat = of_match_device(dispc_of_match, &pdev->dev)->data;
r = dispc_errata_i734_wa_init();
if (r)
@@ -4226,15 +4685,6 @@ static const struct dev_pm_ops dispc_pm_ops = {
.runtime_resume = dispc_runtime_resume,
};
-static const struct of_device_id dispc_of_match[] = {
- { .compatible = "ti,omap2-dispc", },
- { .compatible = "ti,omap3-dispc", },
- { .compatible = "ti,omap4-dispc", },
- { .compatible = "ti,omap5-dispc", },
- { .compatible = "ti,dra7-dispc", },
- {},
-};
-
static struct platform_driver omap_dispchw_driver = {
.probe = dispc_probe,
.remove = dispc_remove,
diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c
index 86dbb65a6c28..daf286fc8a40 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -32,13 +32,14 @@
#include <linux/string.h>
#include <linux/of.h>
#include <linux/clk.h>
+#include <linux/sys_soc.h>
#include "omapdss.h"
#include "dss.h"
-#include "dss_features.h"
struct dpi_data {
struct platform_device *pdev;
+ enum dss_model dss_model;
struct regulator *vdds_dsi_reg;
enum dss_clk_source clk_src;
@@ -99,25 +100,21 @@ static enum dss_clk_source dpi_get_clk_src_dra7xx(enum omap_channel channel)
return DSS_CLK_SRC_FCK;
}
-static enum dss_clk_source dpi_get_clk_src(enum omap_channel channel)
+static enum dss_clk_source dpi_get_clk_src(struct dpi_data *dpi)
{
+ enum omap_channel channel = dpi->output.dispc_channel;
+
/*
* XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL
* would also be used for DISPC fclk. Meaning, when the DPI output is
* disabled, DISPC clock will be disabled, and TV out will stop.
*/
- switch (omapdss_get_version()) {
- case OMAPDSS_VER_OMAP24xx:
- case OMAPDSS_VER_OMAP34xx_ES1:
- case OMAPDSS_VER_OMAP34xx_ES3:
- case OMAPDSS_VER_OMAP3630:
- case OMAPDSS_VER_AM35xx:
- case OMAPDSS_VER_AM43xx:
+ switch (dpi->dss_model) {
+ case DSS_MODEL_OMAP2:
+ case DSS_MODEL_OMAP3:
return DSS_CLK_SRC_FCK;
- case OMAPDSS_VER_OMAP4430_ES1:
- case OMAPDSS_VER_OMAP4430_ES2:
- case OMAPDSS_VER_OMAP4:
+ case DSS_MODEL_OMAP4:
switch (channel) {
case OMAP_DSS_CHANNEL_LCD:
return DSS_CLK_SRC_PLL1_1;
@@ -127,7 +124,7 @@ static enum dss_clk_source dpi_get_clk_src(enum omap_channel channel)
return DSS_CLK_SRC_FCK;
}
- case OMAPDSS_VER_OMAP5:
+ case DSS_MODEL_OMAP5:
switch (channel) {
case OMAP_DSS_CHANNEL_LCD:
return DSS_CLK_SRC_PLL1_1;
@@ -138,7 +135,7 @@ static enum dss_clk_source dpi_get_clk_src(enum omap_channel channel)
return DSS_CLK_SRC_FCK;
}
- case OMAPDSS_VER_DRA7xx:
+ case DSS_MODEL_DRA7:
return dpi_get_clk_src_dra7xx(channel);
default:
@@ -213,7 +210,7 @@ static bool dpi_calc_pll_cb(int n, int m, unsigned long fint,
ctx->pll_cinfo.clkdco = clkdco;
return dss_pll_hsdiv_calc_a(ctx->pll, clkdco,
- ctx->pck_min, dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
+ ctx->pck_min, dss_get_max_fck_rate(),
dpi_calc_hsdiv_cb, ctx);
}
@@ -403,19 +400,13 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
mutex_lock(&dpi->lock);
- if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi->vdds_dsi_reg) {
- DSSERR("no VDSS_DSI regulator\n");
- r = -ENODEV;
- goto err_no_reg;
- }
-
if (!out->dispc_channel_connected) {
DSSERR("failed to enable display: no output/manager\n");
r = -ENODEV;
goto err_no_out_mgr;
}
- if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) {
+ if (dpi->vdds_dsi_reg) {
r = regulator_enable(dpi->vdds_dsi_reg);
if (r)
goto err_reg_enable;
@@ -459,11 +450,10 @@ err_pll_init:
err_src_sel:
dispc_runtime_put();
err_get_dispc:
- if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
+ if (dpi->vdds_dsi_reg)
regulator_disable(dpi->vdds_dsi_reg);
err_reg_enable:
err_no_out_mgr:
-err_no_reg:
mutex_unlock(&dpi->lock);
return r;
}
@@ -484,7 +474,7 @@ static void dpi_display_disable(struct omap_dss_device *dssdev)
dispc_runtime_put();
- if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
+ if (dpi->vdds_dsi_reg)
regulator_disable(dpi->vdds_dsi_reg);
mutex_unlock(&dpi->lock);
@@ -575,11 +565,21 @@ static int dpi_verify_pll(struct dss_pll *pll)
return 0;
}
+static const struct soc_device_attribute dpi_soc_devices[] = {
+ { .family = "OMAP3[456]*" },
+ { .family = "[AD]M37*" },
+ { /* sentinel */ }
+};
+
static int dpi_init_regulator(struct dpi_data *dpi)
{
struct regulator *vdds_dsi;
- if (!dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
+ /*
+ * The DPI uses the DSI VDDS on OMAP34xx, OMAP35xx, OMAP36xx, AM37xx and
+ * DM37xx only.
+ */
+ if (!soc_device_match(dpi_soc_devices))
return 0;
if (dpi->vdds_dsi_reg)
@@ -604,7 +604,7 @@ static void dpi_init_pll(struct dpi_data *dpi)
if (dpi->pll)
return;
- dpi->clk_src = dpi_get_clk_src(dpi->output.dispc_channel);
+ dpi->clk_src = dpi_get_clk_src(dpi);
pll = dss_pll_find_by_src(dpi->clk_src);
if (!pll)
@@ -624,18 +624,14 @@ static void dpi_init_pll(struct dpi_data *dpi)
* the channel in some more dynamic manner, or get the channel as a user
* parameter.
*/
-static enum omap_channel dpi_get_channel(int port_num)
+static enum omap_channel dpi_get_channel(struct dpi_data *dpi, int port_num)
{
- switch (omapdss_get_version()) {
- case OMAPDSS_VER_OMAP24xx:
- case OMAPDSS_VER_OMAP34xx_ES1:
- case OMAPDSS_VER_OMAP34xx_ES3:
- case OMAPDSS_VER_OMAP3630:
- case OMAPDSS_VER_AM35xx:
- case OMAPDSS_VER_AM43xx:
+ switch (dpi->dss_model) {
+ case DSS_MODEL_OMAP2:
+ case DSS_MODEL_OMAP3:
return OMAP_DSS_CHANNEL_LCD;
- case OMAPDSS_VER_DRA7xx:
+ case DSS_MODEL_DRA7:
switch (port_num) {
case 2:
return OMAP_DSS_CHANNEL_LCD3;
@@ -646,12 +642,10 @@ static enum omap_channel dpi_get_channel(int port_num)
return OMAP_DSS_CHANNEL_LCD;
}
- case OMAPDSS_VER_OMAP4430_ES1:
- case OMAPDSS_VER_OMAP4430_ES2:
- case OMAPDSS_VER_OMAP4:
+ case DSS_MODEL_OMAP4:
return OMAP_DSS_CHANNEL_LCD2;
- case OMAPDSS_VER_OMAP5:
+ case DSS_MODEL_OMAP5:
return OMAP_DSS_CHANNEL_LCD3;
default:
@@ -716,10 +710,8 @@ static const struct omapdss_dpi_ops dpi_ops = {
.get_timings = dpi_get_timings,
};
-static void dpi_init_output_port(struct platform_device *pdev,
- struct device_node *port)
+static void dpi_init_output_port(struct dpi_data *dpi, struct device_node *port)
{
- struct dpi_data *dpi = port->data;
struct omap_dss_device *out = &dpi->output;
int r;
u32 port_num;
@@ -741,10 +733,10 @@ static void dpi_init_output_port(struct platform_device *pdev,
break;
}
- out->dev = &pdev->dev;
+ out->dev = &dpi->pdev->dev;
out->id = OMAP_DSS_OUTPUT_DPI;
out->output_type = OMAP_DISPLAY_TYPE_DPI;
- out->dispc_channel = dpi_get_channel(port_num);
+ out->dispc_channel = dpi_get_channel(dpi, port_num);
out->port_num = port_num;
out->ops.dpi = &dpi_ops;
out->owner = THIS_MODULE;
@@ -760,7 +752,8 @@ static void dpi_uninit_output_port(struct device_node *port)
omapdss_unregister_output(out);
}
-int dpi_init_port(struct platform_device *pdev, struct device_node *port)
+int dpi_init_port(struct platform_device *pdev, struct device_node *port,
+ enum dss_model dss_model)
{
struct dpi_data *dpi;
struct device_node *ep;
@@ -786,11 +779,12 @@ int dpi_init_port(struct platform_device *pdev, struct device_node *port)
of_node_put(ep);
dpi->pdev = pdev;
+ dpi->dss_model = dss_model;
port->data = dpi;
mutex_init(&dpi->lock);
- dpi_init_output_port(pdev, port);
+ dpi_init_output_port(dpi, port);
dpi->port_initialized = true;
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 835f49004bc3..b56a05730314 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -20,6 +20,8 @@
#define DSS_SUBSYS_NAME "DSI"
#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/device.h>
@@ -42,12 +44,12 @@
#include <linux/of_graph.h>
#include <linux/of_platform.h>
#include <linux/component.h>
+#include <linux/sys_soc.h>
#include <video/mipi_display.h>
#include "omapdss.h"
#include "dss.h"
-#include "dss_features.h"
#define DSI_CATCH_MISSING_TE
@@ -228,6 +230,12 @@ static int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel);
#define DSI_MAX_NR_ISRS 2
#define DSI_MAX_NR_LANES 5
+enum dsi_model {
+ DSI_MODEL_OMAP3,
+ DSI_MODEL_OMAP4,
+ DSI_MODEL_OMAP5,
+};
+
enum dsi_lane_function {
DSI_LANE_UNUSED = 0,
DSI_LANE_CLK,
@@ -299,12 +307,36 @@ struct dsi_lp_clock_info {
u16 lp_clk_div;
};
+struct dsi_module_id_data {
+ u32 address;
+ int id;
+};
+
+enum dsi_quirks {
+ DSI_QUIRK_PLL_PWR_BUG = (1 << 0), /* DSI-PLL power command 0x3 is not working */
+ DSI_QUIRK_DCS_CMD_CONFIG_VC = (1 << 1),
+ DSI_QUIRK_VC_OCP_WIDTH = (1 << 2),
+ DSI_QUIRK_REVERSE_TXCLKESC = (1 << 3),
+ DSI_QUIRK_GNQ = (1 << 4),
+ DSI_QUIRK_PHY_DCC = (1 << 5),
+};
+
+struct dsi_of_data {
+ enum dsi_model model;
+ const struct dss_pll_hw *pll_hw;
+ const struct dsi_module_id_data *modules;
+ unsigned int max_fck_freq;
+ unsigned int max_pll_lpdiv;
+ enum dsi_quirks quirks;
+};
+
struct dsi_data {
struct platform_device *pdev;
void __iomem *proto_base;
void __iomem *phy_base;
void __iomem *pll_base;
+ const struct dsi_of_data *data;
int module_id;
int irq;
@@ -312,6 +344,7 @@ struct dsi_data {
bool is_enabled;
struct clk *dss_clk;
+ struct regmap *syscon;
struct dispc_clock_info user_dispc_cinfo;
struct dss_pll_clock_info user_dsi_cinfo;
@@ -397,13 +430,6 @@ struct dsi_packet_sent_handler_data {
struct completion *completion;
};
-struct dsi_module_id_data {
- u32 address;
- int id;
-};
-
-static const struct of_device_id dsi_of_match[];
-
#ifdef DSI_PERF_MEASURE
static bool dsi_perf;
module_param(dsi_perf, bool, 0644);
@@ -1186,6 +1212,7 @@ static int dsi_regulator_init(struct platform_device *dsidev)
static void _dsi_print_reset_status(struct platform_device *dsidev)
{
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
u32 l;
int b0, b1, b2;
@@ -1194,7 +1221,7 @@ static void _dsi_print_reset_status(struct platform_device *dsidev)
* I/O. */
l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
- if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) {
+ if (dsi->data->quirks & DSI_QUIRK_REVERSE_TXCLKESC) {
b0 = 28;
b1 = 27;
b2 = 26;
@@ -1297,7 +1324,7 @@ static int dsi_set_lp_clk_divisor(struct platform_device *dsidev)
unsigned long dsi_fclk;
unsigned lp_clk_div;
unsigned long lp_clk;
- unsigned lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
+ unsigned lpdiv_max = dsi->data->max_pll_lpdiv;
lp_clk_div = dsi->user_lp_cinfo.lp_clk_div;
@@ -1349,11 +1376,12 @@ enum dsi_pll_power_state {
static int dsi_pll_power(struct platform_device *dsidev,
enum dsi_pll_power_state state)
{
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int t = 0;
/* DSI-PLL power command 0x3 is not working */
- if (dss_has_feature(FEAT_DSI_PLL_PWR_BUG) &&
- state == DSI_PLL_POWER_ON_DIV)
+ if ((dsi->data->quirks & DSI_QUIRK_PLL_PWR_BUG) &&
+ state == DSI_PLL_POWER_ON_DIV)
state = DSI_PLL_POWER_ON_ALL;
/* PLL_PWR_CMD */
@@ -1373,11 +1401,12 @@ static int dsi_pll_power(struct platform_device *dsidev,
}
-static void dsi_pll_calc_dsi_fck(struct dss_pll_clock_info *cinfo)
+static void dsi_pll_calc_dsi_fck(struct dsi_data *dsi,
+ struct dss_pll_clock_info *cinfo)
{
unsigned long max_dsi_fck;
- max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK);
+ max_dsi_fck = dsi->data->max_fck_freq;
cinfo->mX[HSDIV_DSI] = DIV_ROUND_UP(cinfo->clkdco, max_dsi_fck);
cinfo->clkout[HSDIV_DSI] = cinfo->clkdco / cinfo->mX[HSDIV_DSI];
@@ -1773,13 +1802,14 @@ static int dsi_cio_power(struct platform_device *dsidev,
static unsigned dsi_get_line_buf_size(struct platform_device *dsidev)
{
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int val;
/* line buffer on OMAP3 is 1024 x 24bits */
/* XXX: for some reason using full buffer size causes
* considerable TX slowdown with update sizes that fill the
* whole buffer */
- if (!dss_has_feature(FEAT_DSI_GNQ))
+ if (!(dsi->data->quirks & DSI_QUIRK_GNQ))
return 1023 * 3;
val = REG_GET(dsidev, DSI_GNQ, 14, 12); /* VP1_LINE_BUFFER_SIZE */
@@ -1872,6 +1902,7 @@ static inline unsigned ddr2ns(struct platform_device *dsidev, unsigned ddr)
static void dsi_cio_timings(struct platform_device *dsidev)
{
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
u32 r;
u32 ths_prepare, ths_prepare_ths_zero, ths_trail, ths_exit;
u32 tlpx_half, tclk_trail, tclk_zero;
@@ -1934,7 +1965,7 @@ static void dsi_cio_timings(struct platform_device *dsidev)
r = FLD_MOD(r, tclk_trail, 15, 8);
r = FLD_MOD(r, tclk_zero, 7, 0);
- if (dss_has_feature(FEAT_DSI_PHY_DCC)) {
+ if (dsi->data->quirks & DSI_QUIRK_PHY_DCC) {
r = FLD_MOD(r, 0, 21, 21); /* DCCEN = disable */
r = FLD_MOD(r, 1, 22, 22); /* CLKINP_DIVBY2EN = enable */
r = FLD_MOD(r, 1, 23, 23); /* CLKINP_SEL = enable */
@@ -2006,7 +2037,7 @@ static int dsi_cio_wait_tx_clk_esc_reset(struct platform_device *dsidev)
static const u8 offsets_new[] = { 24, 25, 26, 27, 28 };
const u8 *offsets;
- if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC))
+ if (dsi->data->quirks & DSI_QUIRK_REVERSE_TXCLKESC)
offsets = offsets_old;
else
offsets = offsets_new;
@@ -2060,6 +2091,83 @@ static unsigned dsi_get_lane_mask(struct platform_device *dsidev)
return mask;
}
+/* OMAP4 CONTROL_DSIPHY */
+#define OMAP4_DSIPHY_SYSCON_OFFSET 0x78
+
+#define OMAP4_DSI2_LANEENABLE_SHIFT 29
+#define OMAP4_DSI2_LANEENABLE_MASK (0x7 << 29)
+#define OMAP4_DSI1_LANEENABLE_SHIFT 24
+#define OMAP4_DSI1_LANEENABLE_MASK (0x1f << 24)
+#define OMAP4_DSI1_PIPD_SHIFT 19
+#define OMAP4_DSI1_PIPD_MASK (0x1f << 19)
+#define OMAP4_DSI2_PIPD_SHIFT 14
+#define OMAP4_DSI2_PIPD_MASK (0x1f << 14)
+
+static int dsi_omap4_mux_pads(struct dsi_data *dsi, unsigned int lanes)
+{
+ u32 enable_mask, enable_shift;
+ u32 pipd_mask, pipd_shift;
+
+ if (dsi->module_id == 0) {
+ enable_mask = OMAP4_DSI1_LANEENABLE_MASK;
+ enable_shift = OMAP4_DSI1_LANEENABLE_SHIFT;
+ pipd_mask = OMAP4_DSI1_PIPD_MASK;
+ pipd_shift = OMAP4_DSI1_PIPD_SHIFT;
+ } else if (dsi->module_id == 1) {
+ enable_mask = OMAP4_DSI2_LANEENABLE_MASK;
+ enable_shift = OMAP4_DSI2_LANEENABLE_SHIFT;
+ pipd_mask = OMAP4_DSI2_PIPD_MASK;
+ pipd_shift = OMAP4_DSI2_PIPD_SHIFT;
+ } else {
+ return -ENODEV;
+ }
+
+ return regmap_update_bits(dsi->syscon, OMAP4_DSIPHY_SYSCON_OFFSET,
+ enable_mask | pipd_mask,
+ (lanes << enable_shift) | (lanes << pipd_shift));
+}
+
+/* OMAP5 CONTROL_DSIPHY */
+
+#define OMAP5_DSIPHY_SYSCON_OFFSET 0x74
+
+#define OMAP5_DSI1_LANEENABLE_SHIFT 24
+#define OMAP5_DSI2_LANEENABLE_SHIFT 19
+#define OMAP5_DSI_LANEENABLE_MASK 0x1f
+
+static int dsi_omap5_mux_pads(struct dsi_data *dsi, unsigned int lanes)
+{
+ u32 enable_shift;
+
+ if (dsi->module_id == 0)
+ enable_shift = OMAP5_DSI1_LANEENABLE_SHIFT;
+ else if (dsi->module_id == 1)
+ enable_shift = OMAP5_DSI2_LANEENABLE_SHIFT;
+ else
+ return -ENODEV;
+
+ return regmap_update_bits(dsi->syscon, OMAP5_DSIPHY_SYSCON_OFFSET,
+ OMAP5_DSI_LANEENABLE_MASK << enable_shift,
+ lanes << enable_shift);
+}
+
+static int dsi_enable_pads(struct dsi_data *dsi, unsigned int lane_mask)
+{
+ if (dsi->data->model == DSI_MODEL_OMAP4)
+ return dsi_omap4_mux_pads(dsi, lane_mask);
+ if (dsi->data->model == DSI_MODEL_OMAP5)
+ return dsi_omap5_mux_pads(dsi, lane_mask);
+ return 0;
+}
+
+static void dsi_disable_pads(struct dsi_data *dsi)
+{
+ if (dsi->data->model == DSI_MODEL_OMAP4)
+ dsi_omap4_mux_pads(dsi, 0);
+ else if (dsi->data->model == DSI_MODEL_OMAP5)
+ dsi_omap5_mux_pads(dsi, 0);
+}
+
static int dsi_cio_init(struct platform_device *dsidev)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
@@ -2068,7 +2176,7 @@ static int dsi_cio_init(struct platform_device *dsidev)
DSSDBG("DSI CIO init starts");
- r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
+ r = dsi_enable_pads(dsi, dsi_get_lane_mask(dsidev));
if (r)
return r;
@@ -2178,7 +2286,7 @@ err_cio_pwr:
dsi_cio_disable_lane_override(dsidev);
err_scp_clk_dom:
dsi_disable_scp_clk(dsidev);
- dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
+ dsi_disable_pads(dsi);
return r;
}
@@ -2191,7 +2299,7 @@ static void dsi_cio_uninit(struct platform_device *dsidev)
dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF);
dsi_disable_scp_clk(dsidev);
- dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
+ dsi_disable_pads(dsi);
}
static void dsi_config_tx_fifo(struct platform_device *dsidev,
@@ -2439,7 +2547,7 @@ static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)
r = FLD_MOD(r, 1, 7, 7); /* CS_TX_EN */
r = FLD_MOD(r, 1, 8, 8); /* ECC_TX_EN */
r = FLD_MOD(r, 0, 9, 9); /* MODE_SPEED, high speed on/off */
- if (dss_has_feature(FEAT_DSI_VC_OCP_WIDTH))
+ if (dsi->data->quirks & DSI_QUIRK_VC_OCP_WIDTH)
r = FLD_MOD(r, 3, 11, 10); /* OCP_WIDTH = 32 bit */
r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */
@@ -2474,7 +2582,7 @@ static int dsi_vc_config_source(struct platform_device *dsidev, int channel,
REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), source, 1, 1);
/* DCS_CMD_ENABLE */
- if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) {
+ if (dsi->data->quirks & DSI_QUIRK_DCS_CMD_CONFIG_VC) {
bool enable = source == DSI_VC_SOURCE_VP;
REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), enable, 30, 30);
}
@@ -3607,7 +3715,7 @@ static int dsi_proto_config(struct platform_device *dsidev)
r = FLD_MOD(r, 0, 8, 8); /* VP_CLK_POL */
r = FLD_MOD(r, 1, 14, 14); /* TRIGGER_RESET_MODE */
r = FLD_MOD(r, 1, 19, 19); /* EOT_ENABLE */
- if (!dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) {
+ if (!(dsi->data->quirks & DSI_QUIRK_DCS_CMD_CONFIG_VC)) {
r = FLD_MOD(r, 1, 24, 24); /* DCS_CMD_ENABLE */
/* DCS_CMD_CODE, 1=start, 0=continue */
r = FLD_MOD(r, 0, 25, 25);
@@ -4450,6 +4558,7 @@ static bool dsi_cm_calc_pll_cb(int n, int m, unsigned long fint,
unsigned long clkdco, void *data)
{
struct dsi_clk_calc_ctx *ctx = data;
+ struct dsi_data *dsi = dsi_get_dsidrv_data(ctx->dsidev);
ctx->dsi_cinfo.n = n;
ctx->dsi_cinfo.m = m;
@@ -4457,7 +4566,7 @@ static bool dsi_cm_calc_pll_cb(int n, int m, unsigned long fint,
ctx->dsi_cinfo.clkdco = clkdco;
return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, ctx->req_pck_min,
- dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
+ dsi->data->max_fck_freq,
dsi_cm_calc_hsdiv_cb, ctx);
}
@@ -4749,6 +4858,7 @@ static bool dsi_vm_calc_pll_cb(int n, int m, unsigned long fint,
unsigned long clkdco, void *data)
{
struct dsi_clk_calc_ctx *ctx = data;
+ struct dsi_data *dsi = dsi_get_dsidrv_data(ctx->dsidev);
ctx->dsi_cinfo.n = n;
ctx->dsi_cinfo.m = m;
@@ -4756,7 +4866,7 @@ static bool dsi_vm_calc_pll_cb(int n, int m, unsigned long fint,
ctx->dsi_cinfo.clkdco = clkdco;
return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, ctx->req_pck_min,
- dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
+ dsi->data->max_fck_freq,
dsi_vm_calc_hsdiv_cb, ctx);
}
@@ -4827,7 +4937,7 @@ static int dsi_set_config(struct omap_dss_device *dssdev,
goto err;
}
- dsi_pll_calc_dsi_fck(&ctx.dsi_cinfo);
+ dsi_pll_calc_dsi_fck(dsi, &ctx.dsi_cinfo);
r = dsi_lp_clock_calc(ctx.dsi_cinfo.clkout[HSDIV_DSI],
config->lp_clk_min, config->lp_clk_max, &dsi->user_lp_cinfo);
@@ -4857,24 +4967,14 @@ err:
* the channel in some more dynamic manner, or get the channel as a user
* parameter.
*/
-static enum omap_channel dsi_get_channel(int module_id)
+static enum omap_channel dsi_get_channel(struct dsi_data *dsi)
{
- switch (omapdss_get_version()) {
- case OMAPDSS_VER_OMAP24xx:
- case OMAPDSS_VER_AM43xx:
- DSSWARN("DSI not supported\n");
+ switch (dsi->data->model) {
+ case DSI_MODEL_OMAP3:
return OMAP_DSS_CHANNEL_LCD;
- case OMAPDSS_VER_OMAP34xx_ES1:
- case OMAPDSS_VER_OMAP34xx_ES3:
- case OMAPDSS_VER_OMAP3630:
- case OMAPDSS_VER_AM35xx:
- return OMAP_DSS_CHANNEL_LCD;
-
- case OMAPDSS_VER_OMAP4430_ES1:
- case OMAPDSS_VER_OMAP4430_ES2:
- case OMAPDSS_VER_OMAP4:
- switch (module_id) {
+ case DSI_MODEL_OMAP4:
+ switch (dsi->module_id) {
case 0:
return OMAP_DSS_CHANNEL_LCD;
case 1:
@@ -4884,8 +4984,8 @@ static enum omap_channel dsi_get_channel(int module_id)
return OMAP_DSS_CHANNEL_LCD;
}
- case OMAPDSS_VER_OMAP5:
- switch (module_id) {
+ case DSI_MODEL_OMAP5:
+ switch (dsi->module_id) {
case 0:
return OMAP_DSS_CHANNEL_LCD;
case 1:
@@ -5065,7 +5165,7 @@ static void dsi_init_output(struct platform_device *dsidev)
out->output_type = OMAP_DISPLAY_TYPE_DSI;
out->name = dsi->module_id == 0 ? "dsi.0" : "dsi.1";
- out->dispc_channel = dsi_get_channel(dsi->module_id);
+ out->dispc_channel = dsi_get_channel(dsi);
out->ops.dsi = &dsi_ops;
out->owner = THIS_MODULE;
@@ -5240,29 +5340,7 @@ static int dsi_init_pll_data(struct platform_device *dsidev)
pll->id = dsi->module_id == 0 ? DSS_PLL_DSI1 : DSS_PLL_DSI2;
pll->clkin = clk;
pll->base = dsi->pll_base;
-
- switch (omapdss_get_version()) {
- case OMAPDSS_VER_OMAP34xx_ES1:
- case OMAPDSS_VER_OMAP34xx_ES3:
- case OMAPDSS_VER_OMAP3630:
- case OMAPDSS_VER_AM35xx:
- pll->hw = &dss_omap3_dsi_pll_hw;
- break;
-
- case OMAPDSS_VER_OMAP4430_ES1:
- case OMAPDSS_VER_OMAP4430_ES2:
- case OMAPDSS_VER_OMAP4:
- pll->hw = &dss_omap4_dsi_pll_hw;
- break;
-
- case OMAPDSS_VER_OMAP5:
- pll->hw = &dss_omap5_dsi_pll_hw;
- break;
-
- default:
- return -ENODEV;
- }
-
+ pll->hw = dsi->data->pll_hw;
pll->ops = &dsi_pll_ops;
r = dss_pll_register(pll);
@@ -5273,9 +5351,74 @@ static int dsi_init_pll_data(struct platform_device *dsidev)
}
/* DSI1 HW IP initialisation */
+static const struct dsi_of_data dsi_of_data_omap34xx = {
+ .model = DSI_MODEL_OMAP3,
+ .pll_hw = &dss_omap3_dsi_pll_hw,
+ .modules = (const struct dsi_module_id_data[]) {
+ { .address = 0x4804fc00, .id = 0, },
+ { },
+ },
+ .max_fck_freq = 173000000,
+ .max_pll_lpdiv = (1 << 13) - 1,
+ .quirks = DSI_QUIRK_REVERSE_TXCLKESC,
+};
+
+static const struct dsi_of_data dsi_of_data_omap36xx = {
+ .model = DSI_MODEL_OMAP3,
+ .pll_hw = &dss_omap3_dsi_pll_hw,
+ .modules = (const struct dsi_module_id_data[]) {
+ { .address = 0x4804fc00, .id = 0, },
+ { },
+ },
+ .max_fck_freq = 173000000,
+ .max_pll_lpdiv = (1 << 13) - 1,
+ .quirks = DSI_QUIRK_PLL_PWR_BUG,
+};
+
+static const struct dsi_of_data dsi_of_data_omap4 = {
+ .model = DSI_MODEL_OMAP4,
+ .pll_hw = &dss_omap4_dsi_pll_hw,
+ .modules = (const struct dsi_module_id_data[]) {
+ { .address = 0x58004000, .id = 0, },
+ { .address = 0x58005000, .id = 1, },
+ { },
+ },
+ .max_fck_freq = 170000000,
+ .max_pll_lpdiv = (1 << 13) - 1,
+ .quirks = DSI_QUIRK_DCS_CMD_CONFIG_VC | DSI_QUIRK_VC_OCP_WIDTH
+ | DSI_QUIRK_GNQ,
+};
+
+static const struct dsi_of_data dsi_of_data_omap5 = {
+ .model = DSI_MODEL_OMAP5,
+ .pll_hw = &dss_omap5_dsi_pll_hw,
+ .modules = (const struct dsi_module_id_data[]) {
+ { .address = 0x58004000, .id = 0, },
+ { .address = 0x58009000, .id = 1, },
+ { },
+ },
+ .max_fck_freq = 209250000,
+ .max_pll_lpdiv = (1 << 13) - 1,
+ .quirks = DSI_QUIRK_DCS_CMD_CONFIG_VC | DSI_QUIRK_VC_OCP_WIDTH
+ | DSI_QUIRK_GNQ | DSI_QUIRK_PHY_DCC,
+};
+
+static const struct of_device_id dsi_of_match[] = {
+ { .compatible = "ti,omap3-dsi", .data = &dsi_of_data_omap36xx, },
+ { .compatible = "ti,omap4-dsi", .data = &dsi_of_data_omap4, },
+ { .compatible = "ti,omap5-dsi", .data = &dsi_of_data_omap5, },
+ {},
+};
+
+static const struct soc_device_attribute dsi_soc_devices[] = {
+ { .machine = "OMAP3[45]*", .data = &dsi_of_data_omap34xx },
+ { .machine = "AM35*", .data = &dsi_of_data_omap34xx },
+ { /* sentinel */ }
+};
static int dsi_bind(struct device *dev, struct device *master, void *data)
{
struct platform_device *dsidev = to_platform_device(dev);
+ const struct soc_device_attribute *soc;
const struct dsi_module_id_data *d;
u32 rev;
int r, i;
@@ -5339,7 +5482,13 @@ static int dsi_bind(struct device *dev, struct device *master, void *data)
return r;
}
- d = of_match_node(dsi_of_match, dsidev->dev.of_node)->data;
+ soc = soc_device_match(dsi_soc_devices);
+ if (soc)
+ dsi->data = soc->data;
+ else
+ dsi->data = of_match_node(dsi_of_match, dev->of_node)->data;
+
+ d = dsi->data->modules;
while (d->address != 0 && d->address != dsi_mem->start)
d++;
@@ -5350,6 +5499,24 @@ static int dsi_bind(struct device *dev, struct device *master, void *data)
dsi->module_id = d->id;
+ if (dsi->data->model == DSI_MODEL_OMAP4 ||
+ dsi->data->model == DSI_MODEL_OMAP5) {
+ struct device_node *np;
+
+ /*
+ * The OMAP4/5 display DT bindings don't reference the padconf
+ * syscon. Our only option to retrieve it is to find it by name.
+ */
+ np = of_find_node_by_name(NULL,
+ dsi->data->model == DSI_MODEL_OMAP4 ?
+ "omap4_padconf_global" : "omap5_padconf_global");
+ if (!np)
+ return -ENODEV;
+
+ dsi->syscon = syscon_node_to_regmap(np);
+ of_node_put(np);
+ }
+
/* DSI VCs initialization */
for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {
dsi->vc[i].source = DSI_VC_SOURCE_L4;
@@ -5375,7 +5542,7 @@ static int dsi_bind(struct device *dev, struct device *master, void *data)
/* DSI on OMAP3 doesn't have register DSI_GNQ, set number
* of data to 3 by default */
- if (dss_has_feature(FEAT_DSI_GNQ))
+ if (dsi->data->quirks & DSI_QUIRK_GNQ)
/* NB_DATA_LANES */
dsi->num_lanes_supported = 1 + REG_GET(dsidev, DSI_GNQ, 11, 9);
else
@@ -5495,30 +5662,6 @@ static const struct dev_pm_ops dsi_pm_ops = {
.runtime_resume = dsi_runtime_resume,
};
-static const struct dsi_module_id_data dsi_of_data_omap3[] = {
- { .address = 0x4804fc00, .id = 0, },
- { },
-};
-
-static const struct dsi_module_id_data dsi_of_data_omap4[] = {
- { .address = 0x58004000, .id = 0, },
- { .address = 0x58005000, .id = 1, },
- { },
-};
-
-static const struct dsi_module_id_data dsi_of_data_omap5[] = {
- { .address = 0x58004000, .id = 0, },
- { .address = 0x58009000, .id = 1, },
- { },
-};
-
-static const struct of_device_id dsi_of_match[] = {
- { .compatible = "ti,omap3-dsi", .data = dsi_of_data_omap3, },
- { .compatible = "ti,omap4-dsi", .data = dsi_of_data_omap4, },
- { .compatible = "ti,omap5-dsi", .data = dsi_of_data_omap5, },
- {},
-};
-
static struct platform_driver omap_dsihw_driver = {
.probe = dsi_probe,
.remove = dsi_remove,
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c
index 99e22ca972c7..d1755f12236b 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -22,6 +22,7 @@
#define DSS_SUBSYS_NAME "DSS"
+#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/io.h>
@@ -38,14 +39,15 @@
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/of_graph.h>
#include <linux/regulator/consumer.h>
#include <linux/suspend.h>
#include <linux/component.h>
+#include <linux/sys_soc.h>
#include "omapdss.h"
#include "dss.h"
-#include "dss_features.h"
#define DSS_SZ_REGS SZ_512
@@ -69,15 +71,24 @@ struct dss_reg {
#define REG_FLD_MOD(idx, val, start, end) \
dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
+struct dss_ops {
+ int (*dpi_select_source)(int port, enum omap_channel channel);
+ int (*select_lcd_source)(enum omap_channel channel,
+ enum dss_clk_source clk_src);
+};
+
struct dss_features {
+ enum dss_model model;
u8 fck_div_max;
+ unsigned int fck_freq_max;
u8 dss_fck_multiplier;
const char *parent_clk_name;
const enum omap_display_type *ports;
int num_ports;
- int (*dpi_select_source)(int port, enum omap_channel channel);
- int (*select_lcd_source)(enum omap_channel channel,
- enum dss_clk_source clk_src);
+ const enum omap_dss_output_id *outputs;
+ const struct dss_ops *ops;
+ struct dss_reg_field dispc_clk_switch;
+ bool has_lcd_clk_src;
};
static struct {
@@ -139,8 +150,7 @@ static void dss_save_context(void)
SR(CONTROL);
- if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
- OMAP_DISPLAY_TYPE_SDI) {
+ if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
SR(SDI_CONTROL);
SR(PLL_CONTROL);
}
@@ -159,8 +169,7 @@ static void dss_restore_context(void)
RR(CONTROL);
- if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
- OMAP_DISPLAY_TYPE_SDI) {
+ if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
RR(SDI_CONTROL);
RR(PLL_CONTROL);
}
@@ -390,8 +399,7 @@ static void dss_dump_regs(struct seq_file *s)
DUMPREG(DSS_SYSSTATUS);
DUMPREG(DSS_CONTROL);
- if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
- OMAP_DISPLAY_TYPE_SDI) {
+ if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) {
DUMPREG(DSS_SDI_CONTROL);
DUMPREG(DSS_PLL_CONTROL);
DUMPREG(DSS_SDI_STATUS);
@@ -419,14 +427,12 @@ static int dss_get_channel_index(enum omap_channel channel)
static void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
{
int b;
- u8 start, end;
/*
* We always use PRCM clock as the DISPC func clock, except on DSS3,
* where we don't have separate DISPC and LCD clock sources.
*/
- if (WARN_ON(dss_has_feature(FEAT_LCD_CLK_SRC) &&
- clk_src != DSS_CLK_SRC_FCK))
+ if (WARN_ON(dss.feat->has_lcd_clk_src && clk_src != DSS_CLK_SRC_FCK))
return;
switch (clk_src) {
@@ -444,9 +450,9 @@ static void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
return;
}
- dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end);
-
- REG_FLD_MOD(DSS_CONTROL, b, start, end); /* DISPC_CLK_SWITCH */
+ REG_FLD_MOD(DSS_CONTROL, b, /* DISPC_CLK_SWITCH */
+ dss.feat->dispc_clk_switch.start,
+ dss.feat->dispc_clk_switch.end);
dss.dispc_clk_source = clk_src;
}
@@ -570,13 +576,13 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
int idx = dss_get_channel_index(channel);
int r;
- if (!dss_has_feature(FEAT_LCD_CLK_SRC)) {
+ if (!dss.feat->has_lcd_clk_src) {
dss_select_dispc_clk_source(clk_src);
dss.lcd_clk_source[idx] = clk_src;
return;
}
- r = dss.feat->select_lcd_source(channel, clk_src);
+ r = dss.feat->ops->select_lcd_source(channel, clk_src);
if (r)
return;
@@ -595,7 +601,7 @@ enum dss_clk_source dss_get_dsi_clk_source(int dsi_module)
enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
{
- if (dss_has_feature(FEAT_LCD_CLK_SRC)) {
+ if (dss.feat->has_lcd_clk_src) {
int idx = dss_get_channel_index(channel);
return dss.lcd_clk_source[idx];
} else {
@@ -615,7 +621,7 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min,
unsigned long prate;
unsigned m;
- fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
+ fck_hw_max = dss.feat->fck_freq_max;
if (dss.parent_clk == NULL) {
unsigned pckd;
@@ -673,6 +679,16 @@ unsigned long dss_get_dispc_clk_rate(void)
return dss.dss_clk_rate;
}
+unsigned long dss_get_max_fck_rate(void)
+{
+ return dss.feat->fck_freq_max;
+}
+
+enum omap_dss_output_id dss_get_supported_outputs(enum omap_channel channel)
+{
+ return dss.feat->outputs[channel];
+}
+
static int dss_setup_default_clock(void)
{
unsigned long max_dss_fck, prate;
@@ -680,7 +696,7 @@ static int dss_setup_default_clock(void)
unsigned fck_div;
int r;
- max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
+ max_dss_fck = dss.feat->fck_freq_max;
if (dss.parent_clk == NULL) {
fck = clk_round_rate(dss.dss_clk, max_dss_fck);
@@ -721,27 +737,29 @@ void dss_set_dac_pwrdn_bgz(bool enable)
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select src)
{
- enum omap_display_type dp;
- dp = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
+ enum omap_dss_output_id outputs;
+
+ outputs = dss.feat->outputs[OMAP_DSS_CHANNEL_DIGIT];
/* Complain about invalid selections */
- WARN_ON((src == DSS_VENC_TV_CLK) && !(dp & OMAP_DISPLAY_TYPE_VENC));
- WARN_ON((src == DSS_HDMI_M_PCLK) && !(dp & OMAP_DISPLAY_TYPE_HDMI));
+ WARN_ON((src == DSS_VENC_TV_CLK) && !(outputs & OMAP_DSS_OUTPUT_VENC));
+ WARN_ON((src == DSS_HDMI_M_PCLK) && !(outputs & OMAP_DSS_OUTPUT_HDMI));
/* Select only if we have options */
- if ((dp & OMAP_DISPLAY_TYPE_VENC) && (dp & OMAP_DISPLAY_TYPE_HDMI))
+ if ((outputs & OMAP_DSS_OUTPUT_VENC) &&
+ (outputs & OMAP_DSS_OUTPUT_HDMI))
REG_FLD_MOD(DSS_CONTROL, src, 15, 15); /* VENC_HDMI_SWITCH */
}
enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
{
- enum omap_display_type displays;
+ enum omap_dss_output_id outputs;
- displays = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
- if ((displays & OMAP_DISPLAY_TYPE_HDMI) == 0)
+ outputs = dss.feat->outputs[OMAP_DSS_CHANNEL_DIGIT];
+ if ((outputs & OMAP_DSS_OUTPUT_HDMI) == 0)
return DSS_VENC_TV_CLK;
- if ((displays & OMAP_DISPLAY_TYPE_VENC) == 0)
+ if ((outputs & OMAP_DSS_OUTPUT_VENC) == 0)
return DSS_HDMI_M_PCLK;
return REG_GET(DSS_CONTROL, 15, 15);
@@ -823,7 +841,7 @@ static int dss_dpi_select_source_dra7xx(int port, enum omap_channel channel)
int dss_dpi_select_source(int port, enum omap_channel channel)
{
- return dss.feat->dpi_select_source(port, channel);
+ return dss.feat->ops->dpi_select_source(port, channel);
}
static int dss_get_clocks(void)
@@ -882,7 +900,7 @@ void dss_runtime_put(void)
/* DEBUGFS */
#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
-void dss_debug_dump_clocks(struct seq_file *s)
+static void dss_debug_dump_clocks(struct seq_file *s)
{
dss_dump_clocks(s);
dispc_dump_clocks(s);
@@ -890,8 +908,88 @@ void dss_debug_dump_clocks(struct seq_file *s)
dsi_dump_clocks(s);
#endif
}
-#endif
+static int dss_debug_show(struct seq_file *s, void *unused)
+{
+ void (*func)(struct seq_file *) = s->private;
+
+ func(s);
+ return 0;
+}
+
+static int dss_debug_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dss_debug_show, inode->i_private);
+}
+
+static const struct file_operations dss_debug_fops = {
+ .open = dss_debug_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static struct dentry *dss_debugfs_dir;
+
+static int dss_initialize_debugfs(void)
+{
+ dss_debugfs_dir = debugfs_create_dir("omapdss", NULL);
+ if (IS_ERR(dss_debugfs_dir)) {
+ int err = PTR_ERR(dss_debugfs_dir);
+
+ dss_debugfs_dir = NULL;
+ return err;
+ }
+
+ debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
+ &dss_debug_dump_clocks, &dss_debug_fops);
+
+ return 0;
+}
+
+static void dss_uninitialize_debugfs(void)
+{
+ if (dss_debugfs_dir)
+ debugfs_remove_recursive(dss_debugfs_dir);
+}
+
+int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
+{
+ struct dentry *d;
+
+ d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir,
+ write, &dss_debug_fops);
+
+ return PTR_ERR_OR_ZERO(d);
+}
+#else /* CONFIG_OMAP2_DSS_DEBUGFS */
+static inline int dss_initialize_debugfs(void)
+{
+ return 0;
+}
+static inline void dss_uninitialize_debugfs(void)
+{
+}
+#endif /* CONFIG_OMAP2_DSS_DEBUGFS */
+
+static const struct dss_ops dss_ops_omap2_omap3 = {
+ .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
+};
+
+static const struct dss_ops dss_ops_omap4 = {
+ .dpi_select_source = &dss_dpi_select_source_omap4,
+ .select_lcd_source = &dss_lcd_clk_mux_omap4,
+};
+
+static const struct dss_ops dss_ops_omap5 = {
+ .dpi_select_source = &dss_dpi_select_source_omap5,
+ .select_lcd_source = &dss_lcd_clk_mux_omap5,
+};
+
+static const struct dss_ops dss_ops_dra7 = {
+ .dpi_select_source = &dss_dpi_select_source_dra7xx,
+ .select_lcd_source = &dss_lcd_clk_mux_dra7,
+};
static const enum omap_display_type omap2plus_ports[] = {
OMAP_DISPLAY_TYPE_DPI,
@@ -908,130 +1006,168 @@ static const enum omap_display_type dra7xx_ports[] = {
OMAP_DISPLAY_TYPE_DPI,
};
+static const enum omap_dss_output_id omap2_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id am43xx_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
+};
+
+static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DBI | OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI,
+
+ /* OMAP_DSS_CHANNEL_LCD2 */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI2,
+};
+
+static const enum omap_dss_output_id omap5_dss_supported_outputs[] = {
+ /* OMAP_DSS_CHANNEL_LCD */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI1 | OMAP_DSS_OUTPUT_DSI2,
+
+ /* OMAP_DSS_CHANNEL_DIGIT */
+ OMAP_DSS_OUTPUT_HDMI,
+
+ /* OMAP_DSS_CHANNEL_LCD2 */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI1,
+
+ /* OMAP_DSS_CHANNEL_LCD3 */
+ OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+ OMAP_DSS_OUTPUT_DSI2,
+};
+
static const struct dss_features omap24xx_dss_feats = {
+ .model = DSS_MODEL_OMAP2,
/*
* fck div max is really 16, but the divider range has gaps. The range
* from 1 to 6 has no gaps, so let's use that as a max.
*/
.fck_div_max = 6,
+ .fck_freq_max = 133000000,
.dss_fck_multiplier = 2,
.parent_clk_name = "core_ck",
- .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
.ports = omap2plus_ports,
.num_ports = ARRAY_SIZE(omap2plus_ports),
+ .outputs = omap2_dss_supported_outputs,
+ .ops = &dss_ops_omap2_omap3,
+ .dispc_clk_switch = { 0, 0 },
+ .has_lcd_clk_src = false,
};
static const struct dss_features omap34xx_dss_feats = {
+ .model = DSS_MODEL_OMAP3,
.fck_div_max = 16,
+ .fck_freq_max = 173000000,
.dss_fck_multiplier = 2,
.parent_clk_name = "dpll4_ck",
- .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
.ports = omap34xx_ports,
+ .outputs = omap3430_dss_supported_outputs,
.num_ports = ARRAY_SIZE(omap34xx_ports),
+ .ops = &dss_ops_omap2_omap3,
+ .dispc_clk_switch = { 0, 0 },
+ .has_lcd_clk_src = false,
};
static const struct dss_features omap3630_dss_feats = {
+ .model = DSS_MODEL_OMAP3,
.fck_div_max = 32,
+ .fck_freq_max = 173000000,
.dss_fck_multiplier = 1,
.parent_clk_name = "dpll4_ck",
- .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
.ports = omap2plus_ports,
.num_ports = ARRAY_SIZE(omap2plus_ports),
+ .outputs = omap3630_dss_supported_outputs,
+ .ops = &dss_ops_omap2_omap3,
+ .dispc_clk_switch = { 0, 0 },
+ .has_lcd_clk_src = false,
};
static const struct dss_features omap44xx_dss_feats = {
+ .model = DSS_MODEL_OMAP4,
.fck_div_max = 32,
+ .fck_freq_max = 186000000,
.dss_fck_multiplier = 1,
.parent_clk_name = "dpll_per_x2_ck",
- .dpi_select_source = &dss_dpi_select_source_omap4,
.ports = omap2plus_ports,
.num_ports = ARRAY_SIZE(omap2plus_ports),
- .select_lcd_source = &dss_lcd_clk_mux_omap4,
+ .outputs = omap4_dss_supported_outputs,
+ .ops = &dss_ops_omap4,
+ .dispc_clk_switch = { 9, 8 },
+ .has_lcd_clk_src = true,
};
static const struct dss_features omap54xx_dss_feats = {
+ .model = DSS_MODEL_OMAP5,
.fck_div_max = 64,
+ .fck_freq_max = 209250000,
.dss_fck_multiplier = 1,
.parent_clk_name = "dpll_per_x2_ck",
- .dpi_select_source = &dss_dpi_select_source_omap5,
.ports = omap2plus_ports,
.num_ports = ARRAY_SIZE(omap2plus_ports),
- .select_lcd_source = &dss_lcd_clk_mux_omap5,
+ .outputs = omap5_dss_supported_outputs,
+ .ops = &dss_ops_omap5,
+ .dispc_clk_switch = { 9, 7 },
+ .has_lcd_clk_src = true,
};
static const struct dss_features am43xx_dss_feats = {
+ .model = DSS_MODEL_OMAP3,
.fck_div_max = 0,
+ .fck_freq_max = 200000000,
.dss_fck_multiplier = 0,
.parent_clk_name = NULL,
- .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
.ports = omap2plus_ports,
.num_ports = ARRAY_SIZE(omap2plus_ports),
+ .outputs = am43xx_dss_supported_outputs,
+ .ops = &dss_ops_omap2_omap3,
+ .dispc_clk_switch = { 0, 0 },
+ .has_lcd_clk_src = true,
};
static const struct dss_features dra7xx_dss_feats = {
+ .model = DSS_MODEL_DRA7,
.fck_div_max = 64,
+ .fck_freq_max = 209250000,
.dss_fck_multiplier = 1,
.parent_clk_name = "dpll_per_x2_ck",
- .dpi_select_source = &dss_dpi_select_source_dra7xx,
.ports = dra7xx_ports,
.num_ports = ARRAY_SIZE(dra7xx_ports),
- .select_lcd_source = &dss_lcd_clk_mux_dra7,
+ .outputs = omap5_dss_supported_outputs,
+ .ops = &dss_ops_dra7,
+ .dispc_clk_switch = { 9, 7 },
+ .has_lcd_clk_src = true,
};
-static int dss_init_features(struct platform_device *pdev)
-{
- const struct dss_features *src;
- struct dss_features *dst;
-
- dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
- if (!dst) {
- dev_err(&pdev->dev, "Failed to allocate local DSS Features\n");
- return -ENOMEM;
- }
-
- switch (omapdss_get_version()) {
- case OMAPDSS_VER_OMAP24xx:
- src = &omap24xx_dss_feats;
- break;
-
- case OMAPDSS_VER_OMAP34xx_ES1:
- case OMAPDSS_VER_OMAP34xx_ES3:
- case OMAPDSS_VER_AM35xx:
- src = &omap34xx_dss_feats;
- break;
-
- case OMAPDSS_VER_OMAP3630:
- src = &omap3630_dss_feats;
- break;
-
- case OMAPDSS_VER_OMAP4430_ES1:
- case OMAPDSS_VER_OMAP4430_ES2:
- case OMAPDSS_VER_OMAP4:
- src = &omap44xx_dss_feats;
- break;
-
- case OMAPDSS_VER_OMAP5:
- src = &omap54xx_dss_feats;
- break;
-
- case OMAPDSS_VER_AM43xx:
- src = &am43xx_dss_feats;
- break;
-
- case OMAPDSS_VER_DRA7xx:
- src = &dra7xx_dss_feats;
- break;
-
- default:
- return -ENODEV;
- }
-
- memcpy(dst, src, sizeof(*dst));
- dss.feat = dst;
-
- return 0;
-}
-
static int dss_init_ports(struct platform_device *pdev)
{
struct device_node *parent = pdev->dev.of_node;
@@ -1045,7 +1181,7 @@ static int dss_init_ports(struct platform_device *pdev)
switch (dss.feat->ports[i]) {
case OMAP_DISPLAY_TYPE_DPI:
- dpi_init_port(pdev, port);
+ dpi_init_port(pdev, port, dss.feat->model);
break;
case OMAP_DISPLAY_TYPE_SDI:
sdi_init_port(pdev, port);
@@ -1144,6 +1280,23 @@ static int dss_video_pll_probe(struct platform_device *pdev)
}
/* DSS HW IP initialisation */
+static const struct of_device_id dss_of_match[] = {
+ { .compatible = "ti,omap2-dss", .data = &omap24xx_dss_feats },
+ { .compatible = "ti,omap3-dss", .data = &omap3630_dss_feats },
+ { .compatible = "ti,omap4-dss", .data = &omap44xx_dss_feats },
+ { .compatible = "ti,omap5-dss", .data = &omap54xx_dss_feats },
+ { .compatible = "ti,dra7-dss", .data = &dra7xx_dss_feats },
+ {},
+};
+MODULE_DEVICE_TABLE(of, dss_of_match);
+
+static const struct soc_device_attribute dss_soc_devices[] = {
+ { .machine = "OMAP3430/3530", .data = &omap34xx_dss_feats },
+ { .machine = "AM35??", .data = &omap34xx_dss_feats },
+ { .family = "AM43xx", .data = &am43xx_dss_feats },
+ { /* sentinel */ }
+};
+
static int dss_bind(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -1151,12 +1304,6 @@ static int dss_bind(struct device *dev)
u32 rev;
int r;
- dss.pdev = pdev;
-
- r = dss_init_features(dss.pdev);
- if (r)
- return r;
-
dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
dss.base = devm_ioremap_resource(&pdev->dev, dss_mem);
if (IS_ERR(dss.base))
@@ -1288,15 +1435,34 @@ static int dss_add_child_component(struct device *dev, void *data)
static int dss_probe(struct platform_device *pdev)
{
+ const struct soc_device_attribute *soc;
struct component_match *match = NULL;
int r;
+ dss.pdev = pdev;
+
+ /*
+ * The various OMAP3-based SoCs can't be told apart using the compatible
+ * string, use SoC device matching.
+ */
+ soc = soc_device_match(dss_soc_devices);
+ if (soc)
+ dss.feat = soc->data;
+ else
+ dss.feat = of_match_device(dss_of_match, &pdev->dev)->data;
+
+ r = dss_initialize_debugfs();
+ if (r)
+ return r;
+
/* add all the child devices as components */
device_for_each_child(&pdev->dev, &match, dss_add_child_component);
r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match);
- if (r)
+ if (r) {
+ dss_uninitialize_debugfs();
return r;
+ }
return 0;
}
@@ -1304,9 +1470,27 @@ static int dss_probe(struct platform_device *pdev)
static int dss_remove(struct platform_device *pdev)
{
component_master_del(&pdev->dev, &dss_component_ops);
+
+ dss_uninitialize_debugfs();
+
return 0;
}
+static void dss_shutdown(struct platform_device *pdev)
+{
+ struct omap_dss_device *dssdev = NULL;
+
+ DSSDBG("shutdown\n");
+
+ for_each_dss_dev(dssdev) {
+ if (!dssdev->driver)
+ continue;
+
+ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
+ dssdev->driver->disable(dssdev);
+ }
+}
+
static int dss_runtime_suspend(struct device *dev)
{
dss_save_context();
@@ -1343,20 +1527,10 @@ static const struct dev_pm_ops dss_pm_ops = {
.runtime_resume = dss_runtime_resume,
};
-static const struct of_device_id dss_of_match[] = {
- { .compatible = "ti,omap2-dss", },
- { .compatible = "ti,omap3-dss", },
- { .compatible = "ti,omap4-dss", },
- { .compatible = "ti,omap5-dss", },
- { .compatible = "ti,dra7-dss", },
- {},
-};
-
-MODULE_DEVICE_TABLE(of, dss_of_match);
-
static struct platform_driver omap_dsshw_driver = {
.probe = dss_probe,
.remove = dss_remove,
+ .shutdown = dss_shutdown,
.driver = {
.name = "omapdss_dss",
.pm = &dss_pm_ops,
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h
index 8dbf35f3ab23..ed465572491e 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -27,6 +27,9 @@
#include "omapdss.h"
+#define MAX_DSS_LCD_MANAGERS 3
+#define MAX_NUM_DSI 2
+
#ifdef pr_fmt
#undef pr_fmt
#endif
@@ -72,6 +75,14 @@
#define FLD_MOD(orig, val, start, end) \
(((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
+enum dss_model {
+ DSS_MODEL_OMAP2,
+ DSS_MODEL_OMAP3,
+ DSS_MODEL_OMAP4,
+ DSS_MODEL_OMAP5,
+ DSS_MODEL_DRA7,
+};
+
enum dss_io_pad_mode {
DSS_IO_PAD_MODE_RESET,
DSS_IO_PAD_MODE_RFBI,
@@ -174,6 +185,9 @@ struct dss_pll_hw {
bool has_freqsel;
bool has_selfreqdco;
bool has_refsel;
+
+ /* DRA7 errata i886: use high N & M to avoid jitter */
+ bool errata_i886;
};
struct dss_pll {
@@ -192,6 +206,11 @@ struct dss_pll {
struct dss_pll_clock_info cinfo;
};
+/* Defines a generic omap register field */
+struct dss_reg_field {
+ u8 start, end;
+};
+
struct dispc_clock_info {
/* rates that we get with dividers below */
unsigned long lck;
@@ -219,10 +238,11 @@ struct seq_file;
struct platform_device;
/* core */
-int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask);
-void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask);
-int dss_set_min_bus_tput(struct device *dev, unsigned long tput);
-int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *));
+static inline int dss_set_min_bus_tput(struct device *dev, unsigned long tput)
+{
+ /* To be implemented when the OMAP platform will provide this feature */
+ return 0;
+}
static inline bool dss_mgr_is_lcd(enum omap_channel id)
{
@@ -234,6 +254,16 @@ static inline bool dss_mgr_is_lcd(enum omap_channel id)
}
/* DSS */
+#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
+int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *));
+#else
+static inline int dss_debugfs_create_file(const char *name,
+ void (*write)(struct seq_file *))
+{
+ return 0;
+}
+#endif /* CONFIG_OMAP2_DSS_DEBUGFS */
+
int dss_init_platform_driver(void) __init;
void dss_uninit_platform_driver(void);
@@ -241,6 +271,8 @@ int dss_runtime_get(void);
void dss_runtime_put(void);
unsigned long dss_get_dispc_clk_rate(void);
+unsigned long dss_get_max_fck_rate(void);
+enum omap_dss_output_id dss_get_supported_outputs(enum omap_channel channel);
int dss_dpi_select_source(int port, enum omap_channel channel);
void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
@@ -252,10 +284,6 @@ struct dss_pll *dss_video_pll_init(struct platform_device *pdev, int id,
struct regulator *regulator);
void dss_video_pll_uninit(struct dss_pll *pll);
-#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
-void dss_debug_dump_clocks(struct seq_file *s);
-#endif
-
void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable);
void dss_sdi_init(int datapairs);
@@ -312,11 +340,12 @@ void dsi_irq_handler(void);
/* DPI */
#ifdef CONFIG_OMAP2_DSS_DPI
-int dpi_init_port(struct platform_device *pdev, struct device_node *port);
+int dpi_init_port(struct platform_device *pdev, struct device_node *port,
+ enum dss_model dss_model);
void dpi_uninit_port(struct device_node *port);
#else
static inline int dpi_init_port(struct platform_device *pdev,
- struct device_node *port)
+ struct device_node *port, enum dss_model dss_model)
{
return 0;
}
diff --git a/drivers/gpu/drm/omapdrm/dss/dss_features.c b/drivers/gpu/drm/omapdrm/dss/dss_features.c
deleted file mode 100644
index 0e599710dd95..000000000000
--- a/drivers/gpu/drm/omapdrm/dss/dss_features.c
+++ /dev/null
@@ -1,905 +0,0 @@
-/*
- * linux/drivers/video/omap2/dss/dss_features.c
- *
- * Copyright (C) 2010 Texas Instruments
- * Author: Archit Taneja <archit@ti.com>
- *
- * 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.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <drm/drm_fourcc.h>
-
-#include "omapdss.h"
-#include "dss.h"
-#include "dss_features.h"
-
-/* Defines a generic omap register field */
-struct dss_reg_field {
- u8 start, end;
-};
-
-struct dss_param_range {
- int min, max;
-};
-
-struct omap_dss_features {
- const struct dss_reg_field *reg_fields;
- const int num_reg_fields;
-
- const enum dss_feat_id *features;
- const int num_features;
-
- const int num_mgrs;
- const int num_ovls;
- const enum omap_display_type *supported_displays;
- const enum omap_dss_output_id *supported_outputs;
- const u32 **supported_color_modes;
- const enum omap_overlay_caps *overlay_caps;
- const struct dss_param_range *dss_params;
-
- const u32 buffer_size_unit;
- const u32 burst_size_unit;
-};
-
-/* This struct is assigned to one of the below during initialization */
-static const struct omap_dss_features *omap_current_dss_features;
-
-static const struct dss_reg_field omap2_dss_reg_fields[] = {
- [FEAT_REG_FIRHINC] = { 11, 0 },
- [FEAT_REG_FIRVINC] = { 27, 16 },
- [FEAT_REG_FIFOLOWTHRESHOLD] = { 8, 0 },
- [FEAT_REG_FIFOHIGHTHRESHOLD] = { 24, 16 },
- [FEAT_REG_FIFOSIZE] = { 8, 0 },
- [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
- [FEAT_REG_VERTICALACCU] = { 25, 16 },
- [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
-};
-
-static const struct dss_reg_field omap3_dss_reg_fields[] = {
- [FEAT_REG_FIRHINC] = { 12, 0 },
- [FEAT_REG_FIRVINC] = { 28, 16 },
- [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 },
- [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 },
- [FEAT_REG_FIFOSIZE] = { 10, 0 },
- [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
- [FEAT_REG_VERTICALACCU] = { 25, 16 },
- [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
-};
-
-static const struct dss_reg_field am43xx_dss_reg_fields[] = {
- [FEAT_REG_FIRHINC] = { 12, 0 },
- [FEAT_REG_FIRVINC] = { 28, 16 },
- [FEAT_REG_FIFOLOWTHRESHOLD] = { 11, 0 },
- [FEAT_REG_FIFOHIGHTHRESHOLD] = { 27, 16 },
- [FEAT_REG_FIFOSIZE] = { 10, 0 },
- [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
- [FEAT_REG_VERTICALACCU] = { 25, 16 },
- [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
-};
-
-static const struct dss_reg_field omap4_dss_reg_fields[] = {
- [FEAT_REG_FIRHINC] = { 12, 0 },
- [FEAT_REG_FIRVINC] = { 28, 16 },
- [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 },
- [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 },
- [FEAT_REG_FIFOSIZE] = { 15, 0 },
- [FEAT_REG_HORIZONTALACCU] = { 10, 0 },
- [FEAT_REG_VERTICALACCU] = { 26, 16 },
- [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 },
-};
-
-static const struct dss_reg_field omap5_dss_reg_fields[] = {
- [FEAT_REG_FIRHINC] = { 12, 0 },
- [FEAT_REG_FIRVINC] = { 28, 16 },
- [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 },
- [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 },
- [FEAT_REG_FIFOSIZE] = { 15, 0 },
- [FEAT_REG_HORIZONTALACCU] = { 10, 0 },
- [FEAT_REG_VERTICALACCU] = { 26, 16 },
- [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 7 },
-};
-
-static const enum omap_display_type omap2_dss_supported_displays[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DISPLAY_TYPE_VENC,
-};
-
-static const enum omap_display_type omap3430_dss_supported_displays[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
- OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DISPLAY_TYPE_VENC,
-};
-
-static const enum omap_display_type omap3630_dss_supported_displays[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
- OMAP_DISPLAY_TYPE_DSI,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DISPLAY_TYPE_VENC,
-};
-
-static const enum omap_display_type am43xx_dss_supported_displays[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI,
-};
-
-static const enum omap_display_type omap4_dss_supported_displays[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DISPLAY_TYPE_VENC | OMAP_DISPLAY_TYPE_HDMI,
-
- /* OMAP_DSS_CHANNEL_LCD2 */
- OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
- OMAP_DISPLAY_TYPE_DSI,
-};
-
-static const enum omap_display_type omap5_dss_supported_displays[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
- OMAP_DISPLAY_TYPE_DSI,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DISPLAY_TYPE_HDMI | OMAP_DISPLAY_TYPE_DPI,
-
- /* OMAP_DSS_CHANNEL_LCD2 */
- OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
- OMAP_DISPLAY_TYPE_DSI,
-};
-
-static const enum omap_dss_output_id omap2_dss_supported_outputs[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DSS_OUTPUT_VENC,
-};
-
-static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
- OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DSS_OUTPUT_VENC,
-};
-
-static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
- OMAP_DSS_OUTPUT_DSI1,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DSS_OUTPUT_VENC,
-};
-
-static const enum omap_dss_output_id am43xx_dss_supported_outputs[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
-};
-
-static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DSS_OUTPUT_DBI | OMAP_DSS_OUTPUT_DSI1,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI,
-
- /* OMAP_DSS_CHANNEL_LCD2 */
- OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
- OMAP_DSS_OUTPUT_DSI2,
-};
-
-static const enum omap_dss_output_id omap5_dss_supported_outputs[] = {
- /* OMAP_DSS_CHANNEL_LCD */
- OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
- OMAP_DSS_OUTPUT_DSI1 | OMAP_DSS_OUTPUT_DSI2,
-
- /* OMAP_DSS_CHANNEL_DIGIT */
- OMAP_DSS_OUTPUT_HDMI,
-
- /* OMAP_DSS_CHANNEL_LCD2 */
- OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
- OMAP_DSS_OUTPUT_DSI1,
-
- /* OMAP_DSS_CHANNEL_LCD3 */
- OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
- OMAP_DSS_OUTPUT_DSI2,
-};
-
-#define COLOR_ARRAY(arr...) (const u32[]) { arr, 0 }
-
-static const u32 *omap2_dss_supported_color_modes[] = {
-
- /* OMAP_DSS_GFX */
- COLOR_ARRAY(
- DRM_FORMAT_RGBX4444, DRM_FORMAT_RGB565,
- DRM_FORMAT_XRGB8888, DRM_FORMAT_RGB888),
-
- /* OMAP_DSS_VIDEO1 */
- COLOR_ARRAY(
- DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_YUYV,
- DRM_FORMAT_UYVY),
-
- /* OMAP_DSS_VIDEO2 */
- COLOR_ARRAY(
- DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_YUYV,
- DRM_FORMAT_UYVY),
-};
-
-static const u32 *omap3_dss_supported_color_modes[] = {
- /* OMAP_DSS_GFX */
- COLOR_ARRAY(
- DRM_FORMAT_RGBX4444, DRM_FORMAT_ARGB4444,
- DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_ARGB8888,
- DRM_FORMAT_RGBA8888, DRM_FORMAT_RGBX8888),
-
- /* OMAP_DSS_VIDEO1 */
- COLOR_ARRAY(
- DRM_FORMAT_XRGB8888, DRM_FORMAT_RGB888,
- DRM_FORMAT_RGBX4444, DRM_FORMAT_RGB565,
- DRM_FORMAT_YUYV, DRM_FORMAT_UYVY),
-
- /* OMAP_DSS_VIDEO2 */
- COLOR_ARRAY(
- DRM_FORMAT_RGBX4444, DRM_FORMAT_ARGB4444,
- DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_YUYV,
- DRM_FORMAT_UYVY, DRM_FORMAT_ARGB8888,
- DRM_FORMAT_RGBA8888, DRM_FORMAT_RGBX8888),
-};
-
-static const u32 *omap4_dss_supported_color_modes[] = {
- /* OMAP_DSS_GFX */
- COLOR_ARRAY(
- DRM_FORMAT_RGBX4444, DRM_FORMAT_ARGB4444,
- DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_ARGB8888,
- DRM_FORMAT_RGBA8888, DRM_FORMAT_RGBX8888,
- DRM_FORMAT_ARGB1555, DRM_FORMAT_XRGB4444,
- DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB1555),
-
- /* OMAP_DSS_VIDEO1 */
- COLOR_ARRAY(
- DRM_FORMAT_RGB565, DRM_FORMAT_RGBX4444,
- DRM_FORMAT_YUYV, DRM_FORMAT_ARGB1555,
- DRM_FORMAT_RGBA8888, DRM_FORMAT_NV12,
- DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_UYVY,
- DRM_FORMAT_ARGB4444, DRM_FORMAT_XRGB1555,
- DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB4444,
- DRM_FORMAT_RGBX8888),
-
- /* OMAP_DSS_VIDEO2 */
- COLOR_ARRAY(
- DRM_FORMAT_RGB565, DRM_FORMAT_RGBX4444,
- DRM_FORMAT_YUYV, DRM_FORMAT_ARGB1555,
- DRM_FORMAT_RGBA8888, DRM_FORMAT_NV12,
- DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_UYVY,
- DRM_FORMAT_ARGB4444, DRM_FORMAT_XRGB1555,
- DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB4444,
- DRM_FORMAT_RGBX8888),
-
- /* OMAP_DSS_VIDEO3 */
- COLOR_ARRAY(
- DRM_FORMAT_RGB565, DRM_FORMAT_RGBX4444,
- DRM_FORMAT_YUYV, DRM_FORMAT_ARGB1555,
- DRM_FORMAT_RGBA8888, DRM_FORMAT_NV12,
- DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_UYVY,
- DRM_FORMAT_ARGB4444, DRM_FORMAT_XRGB1555,
- DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB4444,
- DRM_FORMAT_RGBX8888),
-
- /* OMAP_DSS_WB */
- COLOR_ARRAY(
- DRM_FORMAT_RGB565, DRM_FORMAT_RGBX4444,
- DRM_FORMAT_YUYV, DRM_FORMAT_ARGB1555,
- DRM_FORMAT_RGBA8888, DRM_FORMAT_NV12,
- DRM_FORMAT_RGBA4444, DRM_FORMAT_XRGB8888,
- DRM_FORMAT_RGB888, DRM_FORMAT_UYVY,
- DRM_FORMAT_ARGB4444, DRM_FORMAT_XRGB1555,
- DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB4444,
- DRM_FORMAT_RGBX8888),
-};
-
-static const enum omap_overlay_caps omap2_dss_overlay_caps[] = {
- /* OMAP_DSS_GFX */
- OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO1 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
- OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO2 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
- OMAP_DSS_OVL_CAP_REPLICATION,
-};
-
-static const enum omap_overlay_caps omap3430_dss_overlay_caps[] = {
- /* OMAP_DSS_GFX */
- OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_POS |
- OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO1 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
- OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO2 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
-};
-
-static const enum omap_overlay_caps omap3630_dss_overlay_caps[] = {
- /* OMAP_DSS_GFX */
- OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
- OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO1 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
- OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO2 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_POS |
- OMAP_DSS_OVL_CAP_REPLICATION,
-};
-
-static const enum omap_overlay_caps omap4_dss_overlay_caps[] = {
- /* OMAP_DSS_GFX */
- OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
- OMAP_DSS_OVL_CAP_ZORDER | OMAP_DSS_OVL_CAP_POS |
- OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO1 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
- OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO2 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
- OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
-
- /* OMAP_DSS_VIDEO3 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
- OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
-};
-
-static const struct dss_param_range omap2_dss_param_range[] = {
- [FEAT_PARAM_DSS_FCK] = { 0, 133000000 },
- [FEAT_PARAM_DSS_PCD] = { 2, 255 },
- [FEAT_PARAM_DOWNSCALE] = { 1, 2 },
- /*
- * Assuming the line width buffer to be 768 pixels as OMAP2 DISPC
- * scaler cannot scale a image with width more than 768.
- */
- [FEAT_PARAM_LINEWIDTH] = { 1, 768 },
-};
-
-static const struct dss_param_range omap3_dss_param_range[] = {
- [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
- [FEAT_PARAM_DSS_PCD] = { 1, 255 },
- [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
- [FEAT_PARAM_DSI_FCK] = { 0, 173000000 },
- [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
- [FEAT_PARAM_LINEWIDTH] = { 1, 1024 },
-};
-
-static const struct dss_param_range am43xx_dss_param_range[] = {
- [FEAT_PARAM_DSS_FCK] = { 0, 200000000 },
- [FEAT_PARAM_DSS_PCD] = { 1, 255 },
- [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
- [FEAT_PARAM_LINEWIDTH] = { 1, 1024 },
-};
-
-static const struct dss_param_range omap4_dss_param_range[] = {
- [FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
- [FEAT_PARAM_DSS_PCD] = { 1, 255 },
- [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
- [FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
- [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
- [FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
-};
-
-static const struct dss_param_range omap5_dss_param_range[] = {
- [FEAT_PARAM_DSS_FCK] = { 0, 209250000 },
- [FEAT_PARAM_DSS_PCD] = { 1, 255 },
- [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
- [FEAT_PARAM_DSI_FCK] = { 0, 209250000 },
- [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
- [FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
-};
-
-static const enum dss_feat_id omap2_dss_feat_list[] = {
- FEAT_LCDENABLEPOL,
- FEAT_LCDENABLESIGNAL,
- FEAT_PCKFREEENABLE,
- FEAT_FUNCGATED,
- FEAT_ROWREPEATENABLE,
- FEAT_RESIZECONF,
-};
-
-static const enum dss_feat_id omap3430_dss_feat_list[] = {
- FEAT_LCDENABLEPOL,
- FEAT_LCDENABLESIGNAL,
- FEAT_PCKFREEENABLE,
- FEAT_FUNCGATED,
- FEAT_LINEBUFFERSPLIT,
- FEAT_ROWREPEATENABLE,
- FEAT_RESIZECONF,
- FEAT_DSI_REVERSE_TXCLKESC,
- FEAT_VENC_REQUIRES_TV_DAC_CLK,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FIXED_ZORDER,
- FEAT_FIFO_MERGE,
- FEAT_OMAP3_DSI_FIFO_BUG,
- FEAT_DPI_USES_VDDS_DSI,
-};
-
-static const enum dss_feat_id am35xx_dss_feat_list[] = {
- FEAT_LCDENABLEPOL,
- FEAT_LCDENABLESIGNAL,
- FEAT_PCKFREEENABLE,
- FEAT_FUNCGATED,
- FEAT_LINEBUFFERSPLIT,
- FEAT_ROWREPEATENABLE,
- FEAT_RESIZECONF,
- FEAT_DSI_REVERSE_TXCLKESC,
- FEAT_VENC_REQUIRES_TV_DAC_CLK,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FIXED_ZORDER,
- FEAT_FIFO_MERGE,
- FEAT_OMAP3_DSI_FIFO_BUG,
-};
-
-static const enum dss_feat_id am43xx_dss_feat_list[] = {
- FEAT_LCDENABLEPOL,
- FEAT_LCDENABLESIGNAL,
- FEAT_PCKFREEENABLE,
- FEAT_FUNCGATED,
- FEAT_LINEBUFFERSPLIT,
- FEAT_ROWREPEATENABLE,
- FEAT_RESIZECONF,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FIXED_ZORDER,
- FEAT_FIFO_MERGE,
-};
-
-static const enum dss_feat_id omap3630_dss_feat_list[] = {
- FEAT_LCDENABLEPOL,
- FEAT_LCDENABLESIGNAL,
- FEAT_PCKFREEENABLE,
- FEAT_FUNCGATED,
- FEAT_LINEBUFFERSPLIT,
- FEAT_ROWREPEATENABLE,
- FEAT_RESIZECONF,
- FEAT_DSI_PLL_PWR_BUG,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FIXED_ZORDER,
- FEAT_FIFO_MERGE,
- FEAT_OMAP3_DSI_FIFO_BUG,
- FEAT_DPI_USES_VDDS_DSI,
-};
-
-static const enum dss_feat_id omap4430_es1_0_dss_feat_list[] = {
- FEAT_MGR_LCD2,
- FEAT_CORE_CLK_DIV,
- FEAT_LCD_CLK_SRC,
- FEAT_DSI_DCS_CMD_CONFIG_VC,
- FEAT_DSI_VC_OCP_WIDTH,
- FEAT_DSI_GNQ,
- FEAT_HANDLE_UV_SEPARATE,
- FEAT_ATTR2,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FREE_ZORDER,
- FEAT_FIFO_MERGE,
- FEAT_BURST_2D,
-};
-
-static const enum dss_feat_id omap4430_es2_0_1_2_dss_feat_list[] = {
- FEAT_MGR_LCD2,
- FEAT_CORE_CLK_DIV,
- FEAT_LCD_CLK_SRC,
- FEAT_DSI_DCS_CMD_CONFIG_VC,
- FEAT_DSI_VC_OCP_WIDTH,
- FEAT_DSI_GNQ,
- FEAT_HDMI_CTS_SWMODE,
- FEAT_HANDLE_UV_SEPARATE,
- FEAT_ATTR2,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FREE_ZORDER,
- FEAT_FIFO_MERGE,
- FEAT_BURST_2D,
-};
-
-static const enum dss_feat_id omap4_dss_feat_list[] = {
- FEAT_MGR_LCD2,
- FEAT_CORE_CLK_DIV,
- FEAT_LCD_CLK_SRC,
- FEAT_DSI_DCS_CMD_CONFIG_VC,
- FEAT_DSI_VC_OCP_WIDTH,
- FEAT_DSI_GNQ,
- FEAT_HDMI_CTS_SWMODE,
- FEAT_HDMI_AUDIO_USE_MCLK,
- FEAT_HANDLE_UV_SEPARATE,
- FEAT_ATTR2,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FREE_ZORDER,
- FEAT_FIFO_MERGE,
- FEAT_BURST_2D,
-};
-
-static const enum dss_feat_id omap5_dss_feat_list[] = {
- FEAT_MGR_LCD2,
- FEAT_MGR_LCD3,
- FEAT_CORE_CLK_DIV,
- FEAT_LCD_CLK_SRC,
- FEAT_DSI_DCS_CMD_CONFIG_VC,
- FEAT_DSI_VC_OCP_WIDTH,
- FEAT_DSI_GNQ,
- FEAT_HDMI_CTS_SWMODE,
- FEAT_HDMI_AUDIO_USE_MCLK,
- FEAT_HANDLE_UV_SEPARATE,
- FEAT_ATTR2,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FREE_ZORDER,
- FEAT_FIFO_MERGE,
- FEAT_BURST_2D,
- FEAT_DSI_PHY_DCC,
- FEAT_MFLAG,
-};
-
-/* OMAP2 DSS Features */
-static const struct omap_dss_features omap2_dss_features = {
- .reg_fields = omap2_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap2_dss_reg_fields),
-
- .features = omap2_dss_feat_list,
- .num_features = ARRAY_SIZE(omap2_dss_feat_list),
-
- .num_mgrs = 2,
- .num_ovls = 3,
- .supported_displays = omap2_dss_supported_displays,
- .supported_outputs = omap2_dss_supported_outputs,
- .supported_color_modes = omap2_dss_supported_color_modes,
- .overlay_caps = omap2_dss_overlay_caps,
- .dss_params = omap2_dss_param_range,
- .buffer_size_unit = 1,
- .burst_size_unit = 8,
-};
-
-/* OMAP3 DSS Features */
-static const struct omap_dss_features omap3430_dss_features = {
- .reg_fields = omap3_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
-
- .features = omap3430_dss_feat_list,
- .num_features = ARRAY_SIZE(omap3430_dss_feat_list),
-
- .num_mgrs = 2,
- .num_ovls = 3,
- .supported_displays = omap3430_dss_supported_displays,
- .supported_outputs = omap3430_dss_supported_outputs,
- .supported_color_modes = omap3_dss_supported_color_modes,
- .overlay_caps = omap3430_dss_overlay_caps,
- .dss_params = omap3_dss_param_range,
- .buffer_size_unit = 1,
- .burst_size_unit = 8,
-};
-
-/*
- * AM35xx DSS Features. This is basically OMAP3 DSS Features without the
- * vdds_dsi regulator.
- */
-static const struct omap_dss_features am35xx_dss_features = {
- .reg_fields = omap3_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
-
- .features = am35xx_dss_feat_list,
- .num_features = ARRAY_SIZE(am35xx_dss_feat_list),
-
- .num_mgrs = 2,
- .num_ovls = 3,
- .supported_displays = omap3430_dss_supported_displays,
- .supported_outputs = omap3430_dss_supported_outputs,
- .supported_color_modes = omap3_dss_supported_color_modes,
- .overlay_caps = omap3430_dss_overlay_caps,
- .dss_params = omap3_dss_param_range,
- .buffer_size_unit = 1,
- .burst_size_unit = 8,
-};
-
-static const struct omap_dss_features am43xx_dss_features = {
- .reg_fields = am43xx_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(am43xx_dss_reg_fields),
-
- .features = am43xx_dss_feat_list,
- .num_features = ARRAY_SIZE(am43xx_dss_feat_list),
-
- .num_mgrs = 1,
- .num_ovls = 3,
- .supported_displays = am43xx_dss_supported_displays,
- .supported_outputs = am43xx_dss_supported_outputs,
- .supported_color_modes = omap3_dss_supported_color_modes,
- .overlay_caps = omap3430_dss_overlay_caps,
- .dss_params = am43xx_dss_param_range,
- .buffer_size_unit = 1,
- .burst_size_unit = 8,
-};
-
-static const struct omap_dss_features omap3630_dss_features = {
- .reg_fields = omap3_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
-
- .features = omap3630_dss_feat_list,
- .num_features = ARRAY_SIZE(omap3630_dss_feat_list),
-
- .num_mgrs = 2,
- .num_ovls = 3,
- .supported_displays = omap3630_dss_supported_displays,
- .supported_outputs = omap3630_dss_supported_outputs,
- .supported_color_modes = omap3_dss_supported_color_modes,
- .overlay_caps = omap3630_dss_overlay_caps,
- .dss_params = omap3_dss_param_range,
- .buffer_size_unit = 1,
- .burst_size_unit = 8,
-};
-
-/* OMAP4 DSS Features */
-/* For OMAP4430 ES 1.0 revision */
-static const struct omap_dss_features omap4430_es1_0_dss_features = {
- .reg_fields = omap4_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
-
- .features = omap4430_es1_0_dss_feat_list,
- .num_features = ARRAY_SIZE(omap4430_es1_0_dss_feat_list),
-
- .num_mgrs = 3,
- .num_ovls = 4,
- .supported_displays = omap4_dss_supported_displays,
- .supported_outputs = omap4_dss_supported_outputs,
- .supported_color_modes = omap4_dss_supported_color_modes,
- .overlay_caps = omap4_dss_overlay_caps,
- .dss_params = omap4_dss_param_range,
- .buffer_size_unit = 16,
- .burst_size_unit = 16,
-};
-
-/* For OMAP4430 ES 2.0, 2.1 and 2.2 revisions */
-static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
- .reg_fields = omap4_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
-
- .features = omap4430_es2_0_1_2_dss_feat_list,
- .num_features = ARRAY_SIZE(omap4430_es2_0_1_2_dss_feat_list),
-
- .num_mgrs = 3,
- .num_ovls = 4,
- .supported_displays = omap4_dss_supported_displays,
- .supported_outputs = omap4_dss_supported_outputs,
- .supported_color_modes = omap4_dss_supported_color_modes,
- .overlay_caps = omap4_dss_overlay_caps,
- .dss_params = omap4_dss_param_range,
- .buffer_size_unit = 16,
- .burst_size_unit = 16,
-};
-
-/* For all the other OMAP4 versions */
-static const struct omap_dss_features omap4_dss_features = {
- .reg_fields = omap4_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
-
- .features = omap4_dss_feat_list,
- .num_features = ARRAY_SIZE(omap4_dss_feat_list),
-
- .num_mgrs = 3,
- .num_ovls = 4,
- .supported_displays = omap4_dss_supported_displays,
- .supported_outputs = omap4_dss_supported_outputs,
- .supported_color_modes = omap4_dss_supported_color_modes,
- .overlay_caps = omap4_dss_overlay_caps,
- .dss_params = omap4_dss_param_range,
- .buffer_size_unit = 16,
- .burst_size_unit = 16,
-};
-
-/* OMAP5 DSS Features */
-static const struct omap_dss_features omap5_dss_features = {
- .reg_fields = omap5_dss_reg_fields,
- .num_reg_fields = ARRAY_SIZE(omap5_dss_reg_fields),
-
- .features = omap5_dss_feat_list,
- .num_features = ARRAY_SIZE(omap5_dss_feat_list),
-
- .num_mgrs = 4,
- .num_ovls = 4,
- .supported_displays = omap5_dss_supported_displays,
- .supported_outputs = omap5_dss_supported_outputs,
- .supported_color_modes = omap4_dss_supported_color_modes,
- .overlay_caps = omap4_dss_overlay_caps,
- .dss_params = omap5_dss_param_range,
- .buffer_size_unit = 16,
- .burst_size_unit = 16,
-};
-
-/* Functions returning values related to a DSS feature */
-int dss_feat_get_num_mgrs(void)
-{
- return omap_current_dss_features->num_mgrs;
-}
-
-int dss_feat_get_num_ovls(void)
-{
- return omap_current_dss_features->num_ovls;
-}
-
-unsigned long dss_feat_get_param_min(enum dss_range_param param)
-{
- return omap_current_dss_features->dss_params[param].min;
-}
-
-unsigned long dss_feat_get_param_max(enum dss_range_param param)
-{
- return omap_current_dss_features->dss_params[param].max;
-}
-
-enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel)
-{
- return omap_current_dss_features->supported_displays[channel];
-}
-
-enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel)
-{
- return omap_current_dss_features->supported_outputs[channel];
-}
-
-const u32 *dss_feat_get_supported_color_modes(enum omap_plane_id plane)
-{
- return omap_current_dss_features->supported_color_modes[plane];
-}
-
-enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane_id plane)
-{
- return omap_current_dss_features->overlay_caps[plane];
-}
-
-bool dss_feat_color_mode_supported(enum omap_plane_id plane, u32 fourcc)
-{
- const u32 *modes;
- unsigned int i;
-
- modes = omap_current_dss_features->supported_color_modes[plane];
-
- for (i = 0; modes[i]; ++i) {
- if (modes[i] == fourcc)
- return true;
- }
-
- return false;
-}
-
-u32 dss_feat_get_buffer_size_unit(void)
-{
- return omap_current_dss_features->buffer_size_unit;
-}
-
-u32 dss_feat_get_burst_size_unit(void)
-{
- return omap_current_dss_features->burst_size_unit;
-}
-
-/* DSS has_feature check */
-bool dss_has_feature(enum dss_feat_id id)
-{
- int i;
- const enum dss_feat_id *features = omap_current_dss_features->features;
- const int num_features = omap_current_dss_features->num_features;
-
- for (i = 0; i < num_features; i++) {
- if (features[i] == id)
- return true;
- }
-
- return false;
-}
-
-void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end)
-{
- if (id >= omap_current_dss_features->num_reg_fields)
- BUG();
-
- *start = omap_current_dss_features->reg_fields[id].start;
- *end = omap_current_dss_features->reg_fields[id].end;
-}
-
-void dss_features_init(enum omapdss_version version)
-{
- switch (version) {
- case OMAPDSS_VER_OMAP24xx:
- omap_current_dss_features = &omap2_dss_features;
- break;
-
- case OMAPDSS_VER_OMAP34xx_ES1:
- case OMAPDSS_VER_OMAP34xx_ES3:
- omap_current_dss_features = &omap3430_dss_features;
- break;
-
- case OMAPDSS_VER_OMAP3630:
- omap_current_dss_features = &omap3630_dss_features;
- break;
-
- case OMAPDSS_VER_OMAP4430_ES1:
- omap_current_dss_features = &omap4430_es1_0_dss_features;
- break;
-
- case OMAPDSS_VER_OMAP4430_ES2:
- omap_current_dss_features = &omap4430_es2_0_1_2_dss_features;
- break;
-
- case OMAPDSS_VER_OMAP4:
- omap_current_dss_features = &omap4_dss_features;
- break;
-
- case OMAPDSS_VER_OMAP5:
- case OMAPDSS_VER_DRA7xx:
- omap_current_dss_features = &omap5_dss_features;
- break;
-
- case OMAPDSS_VER_AM35xx:
- omap_current_dss_features = &am35xx_dss_features;
- break;
-
- case OMAPDSS_VER_AM43xx:
- omap_current_dss_features = &am43xx_dss_features;
- break;
-
- default:
- DSSWARN("Unsupported OMAP version");
- break;
- }
-}
diff --git a/drivers/gpu/drm/omapdrm/dss/dss_features.h b/drivers/gpu/drm/omapdrm/dss/dss_features.h
deleted file mode 100644
index c36436d27ff5..000000000000
--- a/drivers/gpu/drm/omapdrm/dss/dss_features.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * linux/drivers/video/omap2/dss/dss_features.h
- *
- * Copyright (C) 2010 Texas Instruments
- * Author: Archit Taneja <archit@ti.com>
- *
- * 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.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __OMAP2_DSS_FEATURES_H
-#define __OMAP2_DSS_FEATURES_H
-
-#define MAX_DSS_MANAGERS 4
-#define MAX_DSS_OVERLAYS 4
-#define MAX_DSS_LCD_MANAGERS 3
-#define MAX_NUM_DSI 2
-
-/* DSS has feature id */
-enum dss_feat_id {
- FEAT_LCDENABLEPOL,
- FEAT_LCDENABLESIGNAL,
- FEAT_PCKFREEENABLE,
- FEAT_FUNCGATED,
- FEAT_MGR_LCD2,
- FEAT_MGR_LCD3,
- FEAT_LINEBUFFERSPLIT,
- FEAT_ROWREPEATENABLE,
- FEAT_RESIZECONF,
- /* Independent core clk divider */
- FEAT_CORE_CLK_DIV,
- FEAT_LCD_CLK_SRC,
- /* DSI-PLL power command 0x3 is not working */
- FEAT_DSI_PLL_PWR_BUG,
- FEAT_DSI_DCS_CMD_CONFIG_VC,
- FEAT_DSI_VC_OCP_WIDTH,
- FEAT_DSI_REVERSE_TXCLKESC,
- FEAT_DSI_GNQ,
- FEAT_DPI_USES_VDDS_DSI,
- FEAT_HDMI_CTS_SWMODE,
- FEAT_HDMI_AUDIO_USE_MCLK,
- FEAT_HANDLE_UV_SEPARATE,
- FEAT_ATTR2,
- FEAT_VENC_REQUIRES_TV_DAC_CLK,
- FEAT_CPR,
- FEAT_PRELOAD,
- FEAT_FIR_COEF_V,
- FEAT_ALPHA_FIXED_ZORDER,
- FEAT_ALPHA_FREE_ZORDER,
- FEAT_FIFO_MERGE,
- /* An unknown HW bug causing the normal FIFO thresholds not to work */
- FEAT_OMAP3_DSI_FIFO_BUG,
- FEAT_BURST_2D,
- FEAT_DSI_PHY_DCC,
- FEAT_MFLAG,
-};
-
-/* DSS register field id */
-enum dss_feat_reg_field {
- FEAT_REG_FIRHINC,
- FEAT_REG_FIRVINC,
- FEAT_REG_FIFOHIGHTHRESHOLD,
- FEAT_REG_FIFOLOWTHRESHOLD,
- FEAT_REG_FIFOSIZE,
- FEAT_REG_HORIZONTALACCU,
- FEAT_REG_VERTICALACCU,
- FEAT_REG_DISPC_CLK_SWITCH,
-};
-
-enum dss_range_param {
- FEAT_PARAM_DSS_FCK,
- FEAT_PARAM_DSS_PCD,
- FEAT_PARAM_DSIPLL_LPDIV,
- FEAT_PARAM_DSI_FCK,
- FEAT_PARAM_DOWNSCALE,
- FEAT_PARAM_LINEWIDTH,
-};
-
-/* DSS Feature Functions */
-unsigned long dss_feat_get_param_min(enum dss_range_param param);
-unsigned long dss_feat_get_param_max(enum dss_range_param param);
-enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane_id plane);
-bool dss_feat_color_mode_supported(enum omap_plane_id plane,
- u32 fourcc);
-
-u32 dss_feat_get_buffer_size_unit(void); /* in bytes */
-u32 dss_feat_get_burst_size_unit(void); /* in bytes */
-
-bool dss_has_feature(enum dss_feat_id id);
-void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
-void dss_features_init(enum omapdss_version version);
-
-enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
-enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
-
-int dss_feat_get_num_mgrs(void);
-int dss_feat_get_num_ovls(void);
-const u32 *dss_feat_get_supported_color_modes(enum omap_plane_id plane);
-
-#endif
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi.h b/drivers/gpu/drm/omapdrm/dss/hdmi.h
index fb6cccd02374..a820b394af09 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi.h
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi.h
@@ -234,6 +234,7 @@ struct hdmi_core_audio_config {
struct hdmi_wp_data {
void __iomem *base;
phys_addr_t phys_base;
+ unsigned int version;
};
struct hdmi_pll_data {
@@ -245,15 +246,24 @@ struct hdmi_pll_data {
struct hdmi_wp_data *wp;
};
+struct hdmi_phy_features {
+ bool bist_ctrl;
+ bool ldo_voltage;
+ unsigned long max_phy;
+};
+
struct hdmi_phy_data {
void __iomem *base;
+ const struct hdmi_phy_features *features;
u8 lane_function[4];
u8 lane_polarity[4];
};
struct hdmi_core_data {
void __iomem *base;
+ bool cts_swmode;
+ bool audio_use_mclk;
};
static inline void hdmi_write_reg(void __iomem *base_addr, const u32 idx,
@@ -303,7 +313,8 @@ void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
struct videomode *vm);
void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
struct videomode *vm, struct hdmi_config *param);
-int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp);
+int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp,
+ unsigned int version);
phys_addr_t hdmi_wp_get_audio_dma_addr(struct hdmi_wp_data *wp);
/* HDMI PLL funcs */
@@ -316,7 +327,8 @@ void hdmi_pll_uninit(struct hdmi_pll_data *hpll);
int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk,
unsigned long lfbitclk);
void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s);
-int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy);
+int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy,
+ unsigned int version);
int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes);
/* HDMI common funcs */
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 284b4942b9ac..f169348da377 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -40,7 +40,6 @@
#include "omapdss.h"
#include "hdmi4_core.h"
#include "dss.h"
-#include "dss_features.h"
#include "hdmi.h"
static struct omap_hdmi hdmi;
@@ -668,7 +667,7 @@ static int hdmi_audio_register(struct device *dev)
{
struct omap_hdmi_audio_pdata pdata = {
.dev = dev,
- .dss_version = omapdss_get_version(),
+ .version = 4,
.audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
.ops = &hdmi_audio_ops,
};
@@ -700,7 +699,7 @@ static int hdmi4_bind(struct device *dev, struct device *master, void *data)
if (r)
return r;
- r = hdmi_wp_init(pdev, &hdmi.wp);
+ r = hdmi_wp_init(pdev, &hdmi.wp, 4);
if (r)
return r;
@@ -708,7 +707,7 @@ static int hdmi4_bind(struct device *dev, struct device *master, void *data)
if (r)
return r;
- r = hdmi_phy_init(pdev, &hdmi.phy);
+ r = hdmi_phy_init(pdev, &hdmi.phy, 4);
if (r)
goto err;
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c
index ed6001613405..365cf07daa01 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c
@@ -31,11 +31,11 @@
#include <linux/platform_device.h>
#include <linux/string.h>
#include <linux/seq_file.h>
+#include <linux/sys_soc.h>
#include <sound/asound.h>
#include <sound/asoundef.h>
#include "hdmi4_core.h"
-#include "dss_features.h"
#define HDMI_CORE_AV 0x500
@@ -757,10 +757,10 @@ int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
/* Audio clock regeneration settings */
acore.n = n;
acore.cts = cts;
- if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) {
+ if (core->cts_swmode) {
acore.aud_par_busclk = 0;
acore.cts_mode = HDMI_AUDIO_CTS_MODE_SW;
- acore.use_mclk = dss_has_feature(FEAT_HDMI_AUDIO_USE_MCLK);
+ acore.use_mclk = core->audio_use_mclk;
} else {
acore.aud_par_busclk = (((128 * 31) - 1) << 8);
acore.cts_mode = HDMI_AUDIO_CTS_MODE_HW;
@@ -884,10 +884,42 @@ void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp)
hdmi_wp_audio_core_req_enable(wp, false);
}
+struct hdmi4_features {
+ bool cts_swmode;
+ bool audio_use_mclk;
+};
+
+static const struct hdmi4_features hdmi4_es1_features = {
+ .cts_swmode = false,
+ .audio_use_mclk = false,
+};
+
+static const struct hdmi4_features hdmi4_es2_features = {
+ .cts_swmode = true,
+ .audio_use_mclk = false,
+};
+
+static const struct hdmi4_features hdmi4_es3_features = {
+ .cts_swmode = true,
+ .audio_use_mclk = true,
+};
+
+static const struct soc_device_attribute hdmi4_soc_devices[] = {
+ { .family = "OMAP4", .revision = "ES1.?", .data = &hdmi4_es1_features },
+ { .family = "OMAP4", .revision = "ES2.?", .data = &hdmi4_es2_features },
+ { .family = "OMAP4", .data = &hdmi4_es3_features },
+ { /* sentinel */ }
+};
+
int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core)
{
+ const struct hdmi4_features *features;
struct resource *res;
+ features = soc_device_match(hdmi4_soc_devices)->data;
+ core->cts_swmode = features->cts_swmode;
+ core->audio_use_mclk = features->audio_use_mclk;
+
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
core->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(core->base))
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index 441e1999d86a..b3221ca5bcd8 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -45,7 +45,6 @@
#include "omapdss.h"
#include "hdmi5_core.h"
#include "dss.h"
-#include "dss_features.h"
static struct omap_hdmi hdmi;
@@ -695,7 +694,7 @@ static int hdmi_audio_register(struct device *dev)
{
struct omap_hdmi_audio_pdata pdata = {
.dev = dev,
- .dss_version = omapdss_get_version(),
+ .version = 5,
.audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
.ops = &hdmi_audio_ops,
};
@@ -732,7 +731,7 @@ static int hdmi5_bind(struct device *dev, struct device *master, void *data)
if (r)
return r;
- r = hdmi_wp_init(pdev, &hdmi.wp);
+ r = hdmi_wp_init(pdev, &hdmi.wp, 5);
if (r)
return r;
@@ -740,7 +739,7 @@ static int hdmi5_bind(struct device *dev, struct device *master, void *data)
if (r)
return r;
- r = hdmi_phy_init(pdev, &hdmi.phy);
+ r = hdmi_phy_init(pdev, &hdmi.phy, 5);
if (r)
goto err;
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c b/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c
index fb5e4c724b4b..a156292b1820 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi_phy.c
@@ -19,14 +19,6 @@
#include "dss.h"
#include "hdmi.h"
-struct hdmi_phy_features {
- bool bist_ctrl;
- bool ldo_voltage;
- unsigned long max_phy;
-};
-
-static const struct hdmi_phy_features *phy_feat;
-
void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s)
{
#define DUMPPHY(r) seq_printf(s, "%-35s %08x\n", #r,\
@@ -36,7 +28,7 @@ void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s)
DUMPPHY(HDMI_TXPHY_DIGITAL_CTRL);
DUMPPHY(HDMI_TXPHY_POWER_CTRL);
DUMPPHY(HDMI_TXPHY_PAD_CFG_CTRL);
- if (phy_feat->bist_ctrl)
+ if (phy->features->bist_ctrl)
DUMPPHY(HDMI_TXPHY_BIST_CONTROL);
}
@@ -146,7 +138,7 @@ int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk,
* In OMAP5+, the HFBITCLK must be divided by 2 before issuing the
* HDMI_PHYPWRCMD_LDOON command.
*/
- if (phy_feat->bist_ctrl)
+ if (phy->features->bist_ctrl)
REG_FLD_MOD(phy->base, HDMI_TXPHY_BIST_CONTROL, 1, 11, 11);
/*
@@ -155,7 +147,7 @@ int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk,
*/
if (hfbitclk != lfbitclk)
freqout = 0;
- else if (hfbitclk / 10 < phy_feat->max_phy)
+ else if (hfbitclk / 10 < phy->features->max_phy)
freqout = 1;
else
freqout = 2;
@@ -170,7 +162,7 @@ int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk,
hdmi_write_reg(phy->base, HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
/* Setup max LDO voltage */
- if (phy_feat->ldo_voltage)
+ if (phy->features->ldo_voltage)
REG_FLD_MOD(phy->base, HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
hdmi_phy_configure_lanes(phy);
@@ -190,47 +182,15 @@ static const struct hdmi_phy_features omap54xx_phy_feats = {
.max_phy = 186000000,
};
-static int hdmi_phy_init_features(struct platform_device *pdev)
-{
- struct hdmi_phy_features *dst;
- const struct hdmi_phy_features *src;
-
- dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
- if (!dst) {
- dev_err(&pdev->dev, "Failed to allocate HDMI PHY Features\n");
- return -ENOMEM;
- }
-
- switch (omapdss_get_version()) {
- case OMAPDSS_VER_OMAP4430_ES1:
- case OMAPDSS_VER_OMAP4430_ES2:
- case OMAPDSS_VER_OMAP4:
- src = &omap44xx_phy_feats;
- break;
-
- case OMAPDSS_VER_OMAP5:
- case OMAPDSS_VER_DRA7xx:
- src = &omap54xx_phy_feats;
- break;
-
- default:
- return -ENODEV;
- }
-
- memcpy(dst, src, sizeof(*dst));
- phy_feat = dst;
-
- return 0;
-}
-
-int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy)
+int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy,
+ unsigned int version)
{
- int r;
struct resource *res;
- r = hdmi_phy_init_features(pdev);
- if (r)
- return r;
+ if (version == 4)
+ phy->features = &omap44xx_phy_feats;
+ else
+ phy->features = &omap54xx_phy_feats;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
phy->base = devm_ioremap_resource(&pdev->dev, res);
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c b/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c
index 46239358655a..55bee81f4dd5 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c
@@ -71,7 +71,7 @@ static void hdmi_pll_disable(struct dss_pll *dsspll)
WARN_ON(r < 0 && r != -ENOSYS);
}
-static const struct dss_pll_ops dsi_pll_ops = {
+static const struct dss_pll_ops hdmi_pll_ops = {
.enable = hdmi_pll_enable,
.disable = hdmi_pll_disable,
.set_config = dss_pll_write_config_type_b,
@@ -128,7 +128,8 @@ static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = {
.has_refsel = true,
};
-static int dsi_init_pll_data(struct platform_device *pdev, struct hdmi_pll_data *hpll)
+static int hdmi_init_pll_data(struct platform_device *pdev,
+ struct hdmi_pll_data *hpll)
{
struct dss_pll *pll = &hpll->pll;
struct clk *clk;
@@ -145,23 +146,12 @@ static int dsi_init_pll_data(struct platform_device *pdev, struct hdmi_pll_data
pll->base = hpll->base;
pll->clkin = clk;
- switch (omapdss_get_version()) {
- case OMAPDSS_VER_OMAP4430_ES1:
- case OMAPDSS_VER_OMAP4430_ES2:
- case OMAPDSS_VER_OMAP4:
+ if (hpll->wp->version == 4)
pll->hw = &dss_omap4_hdmi_pll_hw;
- break;
-
- case OMAPDSS_VER_OMAP5:
- case OMAPDSS_VER_DRA7xx:
+ else
pll->hw = &dss_omap5_hdmi_pll_hw;
- break;
-
- default:
- return -ENODEV;
- }
- pll->ops = &dsi_pll_ops;
+ pll->ops = &hdmi_pll_ops;
r = dss_pll_register(pll);
if (r)
@@ -184,7 +174,7 @@ int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
if (IS_ERR(pll->base))
return PTR_ERR(pll->base);
- r = dsi_init_pll_data(pdev, pll);
+ r = hdmi_init_pll_data(pdev, pll);
if (r) {
DSSERR("failed to init HDMI PLL\n");
return r;
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c b/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c
index ab129df2e310..88034fbe0e9f 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi_wp.c
@@ -178,9 +178,7 @@ void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
* However, we don't support OMAP5 ES1 at all, so we can just check for
* OMAP4 here.
*/
- if (omapdss_get_version() == OMAPDSS_VER_OMAP4430_ES1 ||
- omapdss_get_version() == OMAPDSS_VER_OMAP4430_ES2 ||
- omapdss_get_version() == OMAPDSS_VER_OMAP4)
+ if (wp->version == 4)
hsync_len_offset = 0;
timing_h |= FLD_VAL(vm->hback_porch, 31, 20);
@@ -235,9 +233,7 @@ void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp,
DSSDBG("Enter hdmi_wp_audio_config_format\n");
r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CFG);
- if (omapdss_get_version() == OMAPDSS_VER_OMAP4430_ES1 ||
- omapdss_get_version() == OMAPDSS_VER_OMAP4430_ES2 ||
- omapdss_get_version() == OMAPDSS_VER_OMAP4) {
+ if (wp->version == 4) {
r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24);
r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16);
}
@@ -282,7 +278,8 @@ int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable)
return 0;
}
-int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp)
+int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp,
+ unsigned int version)
{
struct resource *res;
@@ -292,6 +289,7 @@ int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp)
return PTR_ERR(wp->base);
wp->phys_base = res->start;
+ wp->version = version;
return 0;
}
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 85953a0bc7c2..47a331670963 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -25,6 +25,7 @@
#include <video/videomode.h>
#include <linux/platform_data/omapdss.h>
#include <uapi/drm/drm_mode.h>
+#include <drm/drm_crtc.h>
#define DISPC_IRQ_FRAMEDONE (1 << 0)
#define DISPC_IRQ_VSYNC (1 << 1)
@@ -241,13 +242,6 @@ struct omap_dss_dsi_config {
enum omap_dss_dsi_trans_mode trans_mode;
};
-/* Hardcoded videomodes for tv. Venc only uses these to
- * identify the mode, and does not actually use the configs
- * itself. However, the configs should be something that
- * a normal monitor can also show */
-extern const struct videomode omap_dss_pal_vm;
-extern const struct videomode omap_dss_ntsc_vm;
-
struct omap_dss_cpr_coefs {
s16 rr, rg, rb;
s16 gr, gg, gb;
@@ -403,6 +397,14 @@ struct omapdss_hdmi_ops {
int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
bool (*detect)(struct omap_dss_device *dssdev);
+ int (*register_hpd_cb)(struct omap_dss_device *dssdev,
+ void (*cb)(void *cb_data,
+ enum drm_connector_status status),
+ void *cb_data);
+ void (*unregister_hpd_cb)(struct omap_dss_device *dssdev);
+ void (*enable_hpd)(struct omap_dss_device *dssdev);
+ void (*disable_hpd)(struct omap_dss_device *dssdev);
+
int (*set_hdmi_mode)(struct omap_dss_device *dssdev, bool hdmi_mode);
int (*set_infoframe)(struct omap_dss_device *dssdev,
const struct hdmi_avi_infoframe *avi);
@@ -567,12 +569,19 @@ struct omap_dss_driver {
int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
bool (*detect)(struct omap_dss_device *dssdev);
+ int (*register_hpd_cb)(struct omap_dss_device *dssdev,
+ void (*cb)(void *cb_data,
+ enum drm_connector_status status),
+ void *cb_data);
+ void (*unregister_hpd_cb)(struct omap_dss_device *dssdev);
+ void (*enable_hpd)(struct omap_dss_device *dssdev);
+ void (*disable_hpd)(struct omap_dss_device *dssdev);
+
int (*set_hdmi_mode)(struct omap_dss_device *dssdev, bool hdmi_mode);
int (*set_hdmi_infoframe)(struct omap_dss_device *dssdev,
const struct hdmi_avi_infoframe *avi);
};
-enum omapdss_version omapdss_get_version(void);
bool omapdss_is_initialized(void);
int omap_dss_register_driver(struct omap_dss_driver *);
diff --git a/drivers/gpu/drm/omapdrm/dss/pll.c b/drivers/gpu/drm/omapdrm/dss/pll.c
index 5e221302768b..9d9d9d42009b 100644
--- a/drivers/gpu/drm/omapdrm/dss/pll.c
+++ b/drivers/gpu/drm/omapdrm/dss/pll.c
@@ -215,8 +215,8 @@ bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
dss_pll_calc_func func, void *data)
{
const struct dss_pll_hw *hw = pll->hw;
- int n, n_min, n_max;
- int m, m_min, m_max;
+ int n, n_start, n_stop, n_inc;
+ int m, m_start, m_stop, m_inc;
unsigned long fint, clkdco;
unsigned long pll_hw_max;
unsigned long fint_hw_min, fint_hw_max;
@@ -226,22 +226,33 @@ bool dss_pll_calc_a(const struct dss_pll *pll, unsigned long clkin,
fint_hw_min = hw->fint_min;
fint_hw_max = hw->fint_max;
- n_min = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul);
- n_max = min((unsigned)(clkin / fint_hw_min), hw->n_max);
+ n_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul);
+ n_stop = min((unsigned)(clkin / fint_hw_min), hw->n_max);
+ n_inc = 1;
+
+ if (hw->errata_i886) {
+ swap(n_start, n_stop);
+ n_inc = -1;
+ }
pll_max = pll_max ? pll_max : ULONG_MAX;
- /* Try to find high N & M to avoid jitter (DRA7 errata i886) */
- for (n = n_max; n >= n_min; --n) {
+ for (n = n_start; n != n_stop; n += n_inc) {
fint = clkin / n;
- m_min = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
+ m_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
1ul);
- m_max = min3((unsigned)(pll_max / fint / 2),
+ m_stop = min3((unsigned)(pll_max / fint / 2),
(unsigned)(pll_hw_max / fint / 2),
hw->m_max);
+ m_inc = 1;
+
+ if (hw->errata_i886) {
+ swap(m_start, m_stop);
+ m_inc = -1;
+ }
- for (m = m_max; m >= m_min; --m) {
+ for (m = m_start; m != m_stop; m += m_inc) {
clkdco = 2 * m * fint;
if (func(n, m, fint, clkdco, data))
diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c
index a6bfb3918b8d..d58da6f32693 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -37,10 +37,10 @@
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/component.h>
+#include <linux/sys_soc.h>
#include "omapdss.h"
#include "dss.h"
-#include "dss_features.h"
/* Venc registers */
#define VENC_REV_ID 0x00
@@ -263,7 +263,13 @@ static const struct venc_config venc_config_pal_bdghi = {
.fid_ext_start_y__fid_ext_offset_y = 0x01380005,
};
-const struct videomode omap_dss_pal_vm = {
+enum venc_videomode {
+ VENC_MODE_UNKNOWN,
+ VENC_MODE_PAL,
+ VENC_MODE_NTSC,
+};
+
+static const struct videomode omap_dss_pal_vm = {
.hactive = 720,
.vactive = 574,
.pixelclock = 13500000,
@@ -279,9 +285,8 @@ const struct videomode omap_dss_pal_vm = {
DISPLAY_FLAGS_PIXDATA_POSEDGE |
DISPLAY_FLAGS_SYNC_NEGEDGE,
};
-EXPORT_SYMBOL(omap_dss_pal_vm);
-const struct videomode omap_dss_ntsc_vm = {
+static const struct videomode omap_dss_ntsc_vm = {
.hactive = 720,
.vactive = 482,
.pixelclock = 13500000,
@@ -297,7 +302,24 @@ const struct videomode omap_dss_ntsc_vm = {
DISPLAY_FLAGS_PIXDATA_POSEDGE |
DISPLAY_FLAGS_SYNC_NEGEDGE,
};
-EXPORT_SYMBOL(omap_dss_ntsc_vm);
+
+static enum venc_videomode venc_get_videomode(const struct videomode *vm)
+{
+ if (!(vm->flags & DISPLAY_FLAGS_INTERLACED))
+ return VENC_MODE_UNKNOWN;
+
+ if (vm->pixelclock == omap_dss_pal_vm.pixelclock &&
+ vm->hactive == omap_dss_pal_vm.hactive &&
+ vm->vactive == omap_dss_pal_vm.vactive)
+ return VENC_MODE_PAL;
+
+ if (vm->pixelclock == omap_dss_ntsc_vm.pixelclock &&
+ vm->hactive == omap_dss_ntsc_vm.hactive &&
+ vm->vactive == omap_dss_ntsc_vm.vactive)
+ return VENC_MODE_NTSC;
+
+ return VENC_MODE_UNKNOWN;
+}
static struct {
struct platform_device *pdev;
@@ -311,6 +333,7 @@ static struct {
struct videomode vm;
enum omap_dss_venc_type type;
bool invert_polarity;
+ bool requires_tv_dac_clk;
struct omap_dss_device output;
} venc;
@@ -424,14 +447,14 @@ static void venc_runtime_put(void)
static const struct venc_config *venc_timings_to_config(struct videomode *vm)
{
- if (memcmp(&omap_dss_pal_vm, vm, sizeof(*vm)) == 0)
+ switch (venc_get_videomode(vm)) {
+ default:
+ WARN_ON_ONCE(1);
+ case VENC_MODE_PAL:
return &venc_config_pal_trm;
-
- if (memcmp(&omap_dss_ntsc_vm, vm, sizeof(*vm)) == 0)
+ case VENC_MODE_NTSC:
return &venc_config_ntsc_trm;
-
- BUG();
- return NULL;
+ }
}
static int venc_power_on(struct omap_dss_device *dssdev)
@@ -542,15 +565,28 @@ static void venc_display_disable(struct omap_dss_device *dssdev)
static void venc_set_timings(struct omap_dss_device *dssdev,
struct videomode *vm)
{
+ struct videomode actual_vm;
+
DSSDBG("venc_set_timings\n");
mutex_lock(&venc.venc_lock);
+ switch (venc_get_videomode(vm)) {
+ default:
+ WARN_ON_ONCE(1);
+ case VENC_MODE_PAL:
+ actual_vm = omap_dss_pal_vm;
+ break;
+ case VENC_MODE_NTSC:
+ actual_vm = omap_dss_ntsc_vm;
+ break;
+ }
+
/* Reset WSS data when the TV standard changes. */
- if (memcmp(&venc.vm, vm, sizeof(*vm)))
+ if (memcmp(&venc.vm, &actual_vm, sizeof(actual_vm)))
venc.wss_data = 0;
- venc.vm = *vm;
+ venc.vm = actual_vm;
dispc_set_tv_pclk(13500000);
@@ -562,13 +598,13 @@ static int venc_check_timings(struct omap_dss_device *dssdev,
{
DSSDBG("venc_check_timings\n");
- if (memcmp(&omap_dss_pal_vm, vm, sizeof(*vm)) == 0)
- return 0;
-
- if (memcmp(&omap_dss_ntsc_vm, vm, sizeof(*vm)) == 0)
+ switch (venc_get_videomode(vm)) {
+ case VENC_MODE_PAL:
+ case VENC_MODE_NTSC:
return 0;
-
- return -EINVAL;
+ default:
+ return -EINVAL;
+ }
}
static void venc_get_timings(struct omap_dss_device *dssdev,
@@ -693,7 +729,7 @@ static int venc_get_clocks(struct platform_device *pdev)
{
struct clk *clk;
- if (dss_has_feature(FEAT_VENC_REQUIRES_TV_DAC_CLK)) {
+ if (venc.requires_tv_dac_clk) {
clk = devm_clk_get(&pdev->dev, "tv_dac_clk");
if (IS_ERR(clk)) {
DSSERR("can't get tv_dac_clk\n");
@@ -828,6 +864,12 @@ err:
}
/* VENC HW IP initialisation */
+static const struct soc_device_attribute venc_soc_devices[] = {
+ { .machine = "OMAP3[45]*" },
+ { .machine = "AM35*" },
+ { /* sentinel */ }
+};
+
static int venc_bind(struct device *dev, struct device *master, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -837,6 +879,10 @@ static int venc_bind(struct device *dev, struct device *master, void *data)
venc.pdev = pdev;
+ /* The OMAP34xx, OMAP35xx and AM35xx VENC require the TV DAC clock. */
+ if (soc_device_match(venc_soc_devices))
+ venc.requires_tv_dac_clk = true;
+
mutex_init(&venc.venc_lock);
venc.wss_data = 0;
diff --git a/drivers/gpu/drm/omapdrm/dss/video-pll.c b/drivers/gpu/drm/omapdrm/dss/video-pll.c
index fbd1263a29a4..38a239cc5e04 100644
--- a/drivers/gpu/drm/omapdrm/dss/video-pll.c
+++ b/drivers/gpu/drm/omapdrm/dss/video-pll.c
@@ -19,7 +19,6 @@
#include "omapdss.h"
#include "dss.h"
-#include "dss_features.h"
struct dss_video_pll {
struct dss_pll pll;
@@ -131,6 +130,8 @@ static const struct dss_pll_hw dss_dra7_video_pll_hw = {
.mX_lsb[3] = 5,
.has_refsel = true,
+
+ .errata_i886 = true,
};
struct dss_pll *dss_video_pll_init(struct platform_device *pdev, int id,
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index c24b6b783e9a..aa5ba9ae2191 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -35,6 +35,23 @@ struct omap_connector {
bool hdmi_mode;
};
+static void omap_connector_hpd_cb(void *cb_data,
+ enum drm_connector_status status)
+{
+ struct omap_connector *omap_connector = cb_data;
+ struct drm_connector *connector = &omap_connector->base;
+ struct drm_device *dev = connector->dev;
+ enum drm_connector_status old_status;
+
+ mutex_lock(&dev->mode_config.mutex);
+ old_status = connector->status;
+ connector->status = status;
+ mutex_unlock(&dev->mode_config.mutex);
+
+ if (old_status != status)
+ drm_kms_helper_hotplug_event(dev);
+}
+
bool omap_connector_get_hdmi_mode(struct drm_connector *connector)
{
struct omap_connector *omap_connector = to_omap_connector(connector);
@@ -75,6 +92,10 @@ static void omap_connector_destroy(struct drm_connector *connector)
struct omap_dss_device *dssdev = omap_connector->dssdev;
DBG("%s", omap_connector->dssdev->name);
+ if (connector->polled == DRM_CONNECTOR_POLL_HPD &&
+ dssdev->driver->unregister_hpd_cb) {
+ dssdev->driver->unregister_hpd_cb(dssdev);
+ }
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(omap_connector);
@@ -195,7 +216,6 @@ static int omap_connector_mode_valid(struct drm_connector *connector,
}
static const struct drm_connector_funcs omap_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.detect = omap_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
@@ -216,6 +236,7 @@ struct drm_connector *omap_connector_init(struct drm_device *dev,
{
struct drm_connector *connector = NULL;
struct omap_connector *omap_connector;
+ bool hpd_supported = false;
DBG("%s", dssdev->name);
@@ -233,7 +254,20 @@ struct drm_connector *omap_connector_init(struct drm_device *dev,
connector_type);
drm_connector_helper_add(connector, &omap_connector_helper_funcs);
- if (dssdev->driver->detect)
+ if (dssdev->driver->register_hpd_cb) {
+ int ret = dssdev->driver->register_hpd_cb(dssdev,
+ omap_connector_hpd_cb,
+ omap_connector);
+ if (!ret)
+ hpd_supported = true;
+ else if (ret != -ENOTSUPP)
+ DBG("%s: Failed to register HPD callback (%d).",
+ dssdev->name, ret);
+ }
+
+ if (hpd_supported)
+ connector->polled = DRM_CONNECTOR_POLL_HPD;
+ else if (dssdev->driver->detect)
connector->polled = DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT;
else
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index dd0ef40ca469..cc85c16cbc2a 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -26,6 +26,16 @@
#include "omap_drv.h"
+#define to_omap_crtc_state(x) container_of(x, struct omap_crtc_state, base)
+
+struct omap_crtc_state {
+ /* Must be first. */
+ struct drm_crtc_state base;
+ /* Shadow values for legacy userspace support. */
+ unsigned int rotation;
+ unsigned int zpos;
+};
+
#define to_omap_crtc(x) container_of(x, struct omap_crtc, base)
struct omap_crtc {
@@ -356,7 +366,8 @@ static void omap_crtc_arm_event(struct drm_crtc *crtc)
}
}
-static void omap_crtc_enable(struct drm_crtc *crtc)
+static void omap_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
int ret;
@@ -372,7 +383,8 @@ static void omap_crtc_enable(struct drm_crtc *crtc)
spin_unlock_irq(&crtc->dev->event_lock);
}
-static void omap_crtc_disable(struct drm_crtc *crtc)
+static void omap_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
@@ -443,6 +455,8 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
static int omap_crtc_atomic_check(struct drm_crtc *crtc,
struct drm_crtc_state *state)
{
+ struct drm_plane_state *pri_state;
+
if (state->color_mgmt_changed && state->gamma_lut) {
uint length = state->gamma_lut->length /
sizeof(struct drm_color_lut);
@@ -451,6 +465,16 @@ static int omap_crtc_atomic_check(struct drm_crtc *crtc,
return -EINVAL;
}
+ pri_state = drm_atomic_get_new_plane_state(state->state, crtc->primary);
+ if (pri_state) {
+ struct omap_crtc_state *omap_crtc_state =
+ to_omap_crtc_state(state);
+
+ /* Mirror new values for zpos and rotation in omap_crtc_state */
+ omap_crtc_state->zpos = pri_state->zpos;
+ omap_crtc_state->rotation = pri_state->rotation;
+ }
+
return 0;
}
@@ -496,39 +520,32 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
spin_unlock_irq(&crtc->dev->event_lock);
}
-static bool omap_crtc_is_plane_prop(struct drm_crtc *crtc,
- struct drm_property *property)
-{
- struct drm_device *dev = crtc->dev;
- struct omap_drm_private *priv = dev->dev_private;
-
- return property == priv->zorder_prop ||
- property == crtc->primary->rotation_property;
-}
-
static int omap_crtc_atomic_set_property(struct drm_crtc *crtc,
struct drm_crtc_state *state,
struct drm_property *property,
uint64_t val)
{
- if (omap_crtc_is_plane_prop(crtc, property)) {
- struct drm_plane_state *plane_state;
- struct drm_plane *plane = crtc->primary;
-
- /*
- * Delegate property set to the primary plane. Get the plane
- * state and set the property directly.
- */
-
- plane_state = drm_atomic_get_plane_state(state->state, plane);
- if (IS_ERR(plane_state))
- return PTR_ERR(plane_state);
+ struct omap_drm_private *priv = crtc->dev->dev_private;
+ struct drm_plane_state *plane_state;
- return drm_atomic_plane_set_property(plane, plane_state,
- property, val);
- }
+ /*
+ * Delegate property set to the primary plane. Get the plane state and
+ * set the property directly, the shadow copy will be assigned in the
+ * omap_crtc_atomic_check callback. This way updates to plane state will
+ * always be mirrored in the crtc state correctly.
+ */
+ plane_state = drm_atomic_get_plane_state(state->state, crtc->primary);
+ if (IS_ERR(plane_state))
+ return PTR_ERR(plane_state);
+
+ if (property == crtc->primary->rotation_property)
+ plane_state->rotation = val;
+ else if (property == priv->zorder_prop)
+ plane_state->zpos = val;
+ else
+ return -EINVAL;
- return -EINVAL;
+ return 0;
}
static int omap_crtc_atomic_get_property(struct drm_crtc *crtc,
@@ -536,28 +553,60 @@ static int omap_crtc_atomic_get_property(struct drm_crtc *crtc,
struct drm_property *property,
uint64_t *val)
{
- if (omap_crtc_is_plane_prop(crtc, property)) {
- /*
- * Delegate property get to the primary plane. The
- * drm_atomic_plane_get_property() function isn't exported, but
- * can be called through drm_object_property_get_value() as that
- * will call drm_atomic_get_property() for atomic drivers.
- */
- return drm_object_property_get_value(&crtc->primary->base,
- property, val);
- }
+ struct omap_drm_private *priv = crtc->dev->dev_private;
+ struct omap_crtc_state *omap_state = to_omap_crtc_state(state);
+
+ if (property == crtc->primary->rotation_property)
+ *val = omap_state->rotation;
+ else if (property == priv->zorder_prop)
+ *val = omap_state->zpos;
+ else
+ return -EINVAL;
+
+ return 0;
+}
+
+static void omap_crtc_reset(struct drm_crtc *crtc)
+{
+ if (crtc->state)
+ __drm_atomic_helper_crtc_destroy_state(crtc->state);
+
+ kfree(crtc->state);
+ crtc->state = kzalloc(sizeof(struct omap_crtc_state), GFP_KERNEL);
+
+ if (crtc->state)
+ crtc->state->crtc = crtc;
+}
+
+static struct drm_crtc_state *
+omap_crtc_duplicate_state(struct drm_crtc *crtc)
+{
+ struct omap_crtc_state *state, *current_state;
+
+ if (WARN_ON(!crtc->state))
+ return NULL;
+
+ current_state = to_omap_crtc_state(crtc->state);
+
+ state = kmalloc(sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return NULL;
+
+ __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
+
+ state->zpos = current_state->zpos;
+ state->rotation = current_state->rotation;
- return -EINVAL;
+ return &state->base;
}
static const struct drm_crtc_funcs omap_crtc_funcs = {
- .reset = drm_atomic_helper_crtc_reset,
+ .reset = omap_crtc_reset,
.set_config = drm_atomic_helper_set_config,
.destroy = omap_crtc_destroy,
.page_flip = drm_atomic_helper_page_flip,
.gamma_set = drm_atomic_helper_legacy_gamma_set,
- .set_property = drm_atomic_helper_crtc_set_property,
- .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+ .atomic_duplicate_state = omap_crtc_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
.atomic_set_property = omap_crtc_atomic_set_property,
.atomic_get_property = omap_crtc_atomic_get_property,
@@ -567,11 +616,11 @@ static const struct drm_crtc_funcs omap_crtc_funcs = {
static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
.mode_set_nofb = omap_crtc_mode_set_nofb,
- .disable = omap_crtc_disable,
- .enable = omap_crtc_enable,
.atomic_check = omap_crtc_atomic_check,
.atomic_begin = omap_crtc_atomic_begin,
.atomic_flush = omap_crtc_atomic_flush,
+ .atomic_enable = omap_crtc_atomic_enable,
+ .atomic_disable = omap_crtc_atomic_disable,
};
/* -----------------------------------------------------------------------------
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 022029ea6972..cdf5b0601eba 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -57,13 +57,13 @@ static void omap_fb_output_poll_changed(struct drm_device *dev)
static void omap_atomic_wait_for_completion(struct drm_device *dev,
struct drm_atomic_state *old_state)
{
- struct drm_crtc_state *old_crtc_state;
+ struct drm_crtc_state *new_crtc_state;
struct drm_crtc *crtc;
unsigned int i;
int ret;
- for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
- if (!crtc->state->enable)
+ for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
+ if (!new_crtc_state->active)
continue;
ret = omap_crtc_wait_pending(crtc);
@@ -84,23 +84,36 @@ static void omap_atomic_commit_tail(struct drm_atomic_state *old_state)
/* Apply the atomic update. */
drm_atomic_helper_commit_modeset_disables(dev, old_state);
- /* With the current dss dispc implementation we have to enable
- * the new modeset before we can commit planes. The dispc ovl
- * configuration relies on the video mode configuration been
- * written into the HW when the ovl configuration is
- * calculated.
- *
- * This approach is not ideal because after a mode change the
- * plane update is executed only after the first vblank
- * interrupt. The dispc implementation should be fixed so that
- * it is able use uncommitted drm state information.
- */
- drm_atomic_helper_commit_modeset_enables(dev, old_state);
- omap_atomic_wait_for_completion(dev, old_state);
-
- drm_atomic_helper_commit_planes(dev, old_state, 0);
-
- drm_atomic_helper_commit_hw_done(old_state);
+ if (priv->omaprev != 0x3430) {
+ /* With the current dss dispc implementation we have to enable
+ * the new modeset before we can commit planes. The dispc ovl
+ * configuration relies on the video mode configuration been
+ * written into the HW when the ovl configuration is
+ * calculated.
+ *
+ * This approach is not ideal because after a mode change the
+ * plane update is executed only after the first vblank
+ * interrupt. The dispc implementation should be fixed so that
+ * it is able use uncommitted drm state information.
+ */
+ drm_atomic_helper_commit_modeset_enables(dev, old_state);
+ omap_atomic_wait_for_completion(dev, old_state);
+
+ drm_atomic_helper_commit_planes(dev, old_state, 0);
+
+ drm_atomic_helper_commit_hw_done(old_state);
+ } else {
+ /*
+ * OMAP3 DSS seems to have issues with the work-around above,
+ * resulting in endless sync losts if a crtc is enabled without
+ * a plane. For now, skip the WA for OMAP3.
+ */
+ drm_atomic_helper_commit_planes(dev, old_state, 0);
+
+ drm_atomic_helper_commit_modeset_enables(dev, old_state);
+
+ drm_atomic_helper_commit_hw_done(old_state);
+ }
/*
* Wait for completion of the page flips to ensure that old buffers
@@ -324,6 +337,32 @@ static int omap_modeset_init(struct drm_device *dev)
}
/*
+ * Enable the HPD in external components if supported
+ */
+static void omap_modeset_enable_external_hpd(void)
+{
+ struct omap_dss_device *dssdev = NULL;
+
+ for_each_dss_dev(dssdev) {
+ if (dssdev->driver->enable_hpd)
+ dssdev->driver->enable_hpd(dssdev);
+ }
+}
+
+/*
+ * Disable the HPD in external components if supported
+ */
+static void omap_modeset_disable_external_hpd(void)
+{
+ struct omap_dss_device *dssdev = NULL;
+
+ for_each_dss_dev(dssdev) {
+ if (dssdev->driver->disable_hpd)
+ dssdev->driver->disable_hpd(dssdev);
+ }
+}
+
+/*
* drm ioctl funcs
*/
@@ -438,44 +477,11 @@ static int dev_open(struct drm_device *dev, struct drm_file *file)
*/
static void dev_lastclose(struct drm_device *dev)
{
- int i;
-
- /* we don't support vga_switcheroo.. so just make sure the fbdev
- * mode is active
- */
struct omap_drm_private *priv = dev->dev_private;
int ret;
DBG("lastclose: dev=%p", dev);
- /* need to restore default rotation state.. not sure
- * if there is a cleaner way to restore properties to
- * default state? Maybe a flag that properties should
- * automatically be restored to default state on
- * lastclose?
- */
- for (i = 0; i < priv->num_crtcs; i++) {
- struct drm_crtc *crtc = priv->crtcs[i];
-
- if (!crtc->primary->rotation_property)
- continue;
-
- drm_object_property_set_value(&crtc->base,
- crtc->primary->rotation_property,
- DRM_MODE_ROTATE_0);
- }
-
- for (i = 0; i < priv->num_planes; i++) {
- struct drm_plane *plane = priv->planes[i];
-
- if (!plane->rotation_property)
- continue;
-
- drm_object_property_set_value(&plane->base,
- plane->rotation_property,
- DRM_MODE_ROTATE_0);
- }
-
if (priv->fbdev) {
ret = drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev);
if (ret)
@@ -517,7 +523,6 @@ static struct drm_driver omap_drm_driver = {
.gem_vm_ops = &omap_gem_vm_ops,
.dumb_create = omap_gem_dumb_create,
.dumb_map_offset = omap_gem_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.ioctls = ioctls,
.num_ioctls = DRM_OMAP_NUM_IOCTLS,
.fops = &omapdriver_fops,
@@ -550,6 +555,12 @@ static int pdev_probe(struct platform_device *pdev)
if (omapdss_is_initialized() == false)
return -EPROBE_DEFER;
+ ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to set the DMA mask\n");
+ return ret;
+ }
+
omap_crtc_pre_init();
ret = omap_connect_dssdevs();
@@ -603,6 +614,7 @@ static int pdev_probe(struct platform_device *pdev)
priv->fbdev = omap_fbdev_init(ddev);
drm_kms_helper_poll_init(ddev);
+ omap_modeset_enable_external_hpd();
/*
* Register the DRM device with the core and the connectors with
@@ -615,6 +627,7 @@ static int pdev_probe(struct platform_device *pdev)
return 0;
err_cleanup_helpers:
+ omap_modeset_disable_external_hpd();
drm_kms_helper_poll_fini(ddev);
if (priv->fbdev)
omap_fbdev_free(ddev);
@@ -643,6 +656,7 @@ static int pdev_remove(struct platform_device *pdev)
drm_dev_unregister(ddev);
+ omap_modeset_disable_external_hpd();
drm_kms_helper_poll_fini(ddev);
if (priv->fbdev)
@@ -734,7 +748,7 @@ static SIMPLE_DEV_PM_OPS(omapdrm_pm_ops, omap_drm_suspend, omap_drm_resume);
static struct platform_driver pdev = {
.driver = {
- .name = DRIVER_NAME,
+ .name = "omapdrm",
.pm = &omapdrm_pm_ops,
},
.probe = pdev_probe,
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 86c977b7189a..624f5b50b755 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -85,7 +85,8 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder,
if (hdmi_mode && dssdev->driver->set_hdmi_infoframe) {
struct hdmi_avi_infoframe avi;
- r = drm_hdmi_avi_infoframe_from_display_mode(&avi, adjusted_mode);
+ r = drm_hdmi_avi_infoframe_from_display_mode(&avi, adjusted_mode,
+ false);
if (r == 0)
dssdev->driver->set_hdmi_infoframe(dssdev, &avi);
}
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index ddf7a457951b..b1a762b70cbf 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -379,7 +379,7 @@ struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
return fb;
error:
- while (--i > 0)
+ while (--i >= 0)
drm_gem_object_unreference_unlocked(bos[i]);
return fb;
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index daf81a0a2899..9273118040b7 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -184,7 +184,6 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
helper->fb = fb;
fbi->par = helper;
- fbi->flags = FBINFO_DEFAULT;
fbi->fbops = &omap_fb_ops;
strcpy(fbi->fix.id, MODULE_NAME);
diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
index 863a881dd7cd..afdbad5c866a 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
@@ -144,7 +144,7 @@ static int omap_gem_dmabuf_mmap(struct dma_buf *buffer,
return omap_gem_mmap_obj(obj, vma);
}
-static struct dma_buf_ops omap_dmabuf_ops = {
+static const struct dma_buf_ops omap_dmabuf_ops = {
.map_dma_buf = omap_gem_map_dma_buf,
.unmap_dma_buf = omap_gem_unmap_dma_buf,
.release = drm_gem_dmabuf_release,
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 2160f64548e0..15e5d5d325c6 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -235,7 +235,6 @@ static const struct drm_plane_funcs omap_plane_funcs = {
.disable_plane = drm_atomic_helper_disable_plane,
.reset = omap_plane_reset,
.destroy = omap_plane_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
.atomic_set_property = omap_plane_atomic_set_property,
@@ -291,7 +290,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
ret = drm_universal_plane_init(dev, plane, possible_crtcs,
&omap_plane_funcs, formats,
- nformats, type, NULL);
+ nformats, NULL, type, NULL);
if (ret < 0)
goto error;
diff --git a/drivers/gpu/drm/panel/panel-lvds.c b/drivers/gpu/drm/panel/panel-lvds.c
index 3216aa9a88d6..e2d57c01200b 100644
--- a/drivers/gpu/drm/panel/panel-lvds.c
+++ b/drivers/gpu/drm/panel/panel-lvds.c
@@ -143,14 +143,14 @@ static int panel_lvds_parse_dt(struct panel_lvds *lvds)
ret = of_property_read_u32(np, "width-mm", &lvds->width);
if (ret < 0) {
- dev_err(lvds->dev, "%s: invalid or missing %s DT property\n",
- of_node_full_name(np), "width-mm");
+ dev_err(lvds->dev, "%pOF: invalid or missing %s DT property\n",
+ np, "width-mm");
return -ENODEV;
}
ret = of_property_read_u32(np, "height-mm", &lvds->height);
if (ret < 0) {
- dev_err(lvds->dev, "%s: invalid or missing %s DT property\n",
- of_node_full_name(np), "height-mm");
+ dev_err(lvds->dev, "%pOF: invalid or missing %s DT property\n",
+ np, "height-mm");
return -ENODEV;
}
@@ -158,8 +158,8 @@ static int panel_lvds_parse_dt(struct panel_lvds *lvds)
ret = of_property_read_string(np, "data-mapping", &mapping);
if (ret < 0) {
- dev_err(lvds->dev, "%s: invalid or missing %s DT property\n",
- of_node_full_name(np), "data-mapping");
+ dev_err(lvds->dev, "%pOF: invalid or missing %s DT property\n",
+ np, "data-mapping");
return -ENODEV;
}
@@ -170,8 +170,8 @@ static int panel_lvds_parse_dt(struct panel_lvds *lvds)
} else if (!strcmp(mapping, "vesa-24")) {
lvds->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG;
} else {
- dev_err(lvds->dev, "%s: invalid or missing %s DT property\n",
- of_node_full_name(np), "data-mapping");
+ dev_err(lvds->dev, "%pOF: invalid or missing %s DT property\n",
+ np, "data-mapping");
return -EINVAL;
}
diff --git a/drivers/gpu/drm/pl111/pl111_connector.c b/drivers/gpu/drm/pl111/pl111_connector.c
index 3f213d7e7692..d335f9a29ce4 100644
--- a/drivers/gpu/drm/pl111/pl111_connector.c
+++ b/drivers/gpu/drm/pl111/pl111_connector.c
@@ -69,7 +69,6 @@ const struct drm_connector_funcs connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = pl111_connector_destroy,
.detect = pl111_connector_detect,
- .dpms = drm_atomic_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
diff --git a/drivers/gpu/drm/pl111/pl111_display.c b/drivers/gpu/drm/pl111/pl111_display.c
index c6ca4f1bbd49..b58c988d9da0 100644
--- a/drivers/gpu/drm/pl111/pl111_display.c
+++ b/drivers/gpu/drm/pl111/pl111_display.c
@@ -23,6 +23,7 @@
#include <drm/drmP.h>
#include <drm/drm_panel.h>
#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include "pl111_drm.h"
@@ -274,7 +275,7 @@ void pl111_disable_vblank(struct drm_device *drm, unsigned int crtc)
static int pl111_display_prepare_fb(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *plane_state)
{
- return drm_fb_cma_prepare_fb(&pipe->plane, plane_state);
+ return drm_gem_fb_prepare_fb(&pipe->plane, plane_state);
}
static const struct drm_simple_display_pipe_funcs pl111_display_funcs = {
@@ -457,7 +458,7 @@ int pl111_display_init(struct drm_device *drm)
ret = drm_simple_display_pipe_init(drm, &priv->pipe,
&pl111_display_funcs,
formats, ARRAY_SIZE(formats),
- &priv->connector.connector);
+ NULL, &priv->connector.connector);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
index ac8771be70b0..581c452cede1 100644
--- a/drivers/gpu/drm/pl111/pl111_drv.c
+++ b/drivers/gpu/drm/pl111/pl111_drv.c
@@ -66,14 +66,15 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include "pl111_drm.h"
#define DRIVER_DESC "DRM module for PL111"
-static struct drm_mode_config_funcs mode_config_funcs = {
- .fb_create = drm_fb_cma_create,
+static const struct drm_mode_config_funcs mode_config_funcs = {
+ .fb_create = drm_gem_fb_create,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
};
@@ -159,9 +160,7 @@ static struct drm_driver pl111_drm_driver = {
.minor = 0,
.patchlevel = 0,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_destroy = drm_gem_dumb_destroy,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .gem_free_object = drm_gem_cma_free_object,
+ .gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.enable_vblank = pl111_enable_vblank,
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index 03fe182203ce..14c5613b4388 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -378,10 +378,6 @@ qxl_framebuffer_init(struct drm_device *dev,
return 0;
}
-static void qxl_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-}
-
static bool qxl_crtc_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -437,7 +433,7 @@ static void qxl_monitors_config_set(struct qxl_device *qdev,
}
-void qxl_mode_set_nofb(struct drm_crtc *crtc)
+static void qxl_mode_set_nofb(struct drm_crtc *crtc)
{
struct qxl_device *qdev = crtc->dev->dev_private;
struct qxl_crtc *qcrtc = to_qxl_crtc(crtc);
@@ -451,12 +447,14 @@ void qxl_mode_set_nofb(struct drm_crtc *crtc)
}
-static void qxl_crtc_commit(struct drm_crtc *crtc)
+static void qxl_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
DRM_DEBUG("\n");
}
-static void qxl_crtc_disable(struct drm_crtc *crtc)
+static void qxl_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct qxl_crtc *qcrtc = to_qxl_crtc(crtc);
struct qxl_device *qdev = crtc->dev->dev_private;
@@ -467,16 +465,15 @@ static void qxl_crtc_disable(struct drm_crtc *crtc)
}
static const struct drm_crtc_helper_funcs qxl_crtc_helper_funcs = {
- .dpms = qxl_crtc_dpms,
- .disable = qxl_crtc_disable,
.mode_fixup = qxl_crtc_mode_fixup,
.mode_set_nofb = qxl_mode_set_nofb,
- .commit = qxl_crtc_commit,
.atomic_flush = qxl_crtc_atomic_flush,
+ .atomic_enable = qxl_crtc_atomic_enable,
+ .atomic_disable = qxl_crtc_atomic_disable,
};
-int qxl_primary_atomic_check(struct drm_plane *plane,
- struct drm_plane_state *state)
+static int qxl_primary_atomic_check(struct drm_plane *plane,
+ struct drm_plane_state *state)
{
struct qxl_device *qdev = plane->dev->dev_private;
struct qxl_framebuffer *qfb;
@@ -547,8 +544,8 @@ static void qxl_primary_atomic_disable(struct drm_plane *plane,
}
}
-int qxl_plane_atomic_check(struct drm_plane *plane,
- struct drm_plane_state *state)
+static int qxl_plane_atomic_check(struct drm_plane *plane,
+ struct drm_plane_state *state)
{
return 0;
}
@@ -647,8 +644,8 @@ out_free_release:
}
-void qxl_cursor_atomic_disable(struct drm_plane *plane,
- struct drm_plane_state *old_state)
+static void qxl_cursor_atomic_disable(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
{
struct qxl_device *qdev = plane->dev->dev_private;
struct qxl_release *release;
@@ -675,8 +672,8 @@ void qxl_cursor_atomic_disable(struct drm_plane *plane,
qxl_release_fence_buffer_objects(release);
}
-int qxl_plane_prepare_fb(struct drm_plane *plane,
- struct drm_plane_state *new_state)
+static int qxl_plane_prepare_fb(struct drm_plane *plane,
+ struct drm_plane_state *new_state)
{
struct drm_gem_object *obj;
struct qxl_bo *user_bo;
@@ -787,7 +784,7 @@ static struct drm_plane *qxl_create_plane(struct qxl_device *qdev,
err = drm_universal_plane_init(&qdev->ddev, plane, possible_crtcs,
funcs, formats, num_formats,
- type, NULL);
+ NULL, type, NULL);
if (err)
goto free_plane;
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
index c2fc201d9e1b..2445e75cf7ea 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.c
+++ b/drivers/gpu/drm/qxl/qxl_drv.c
@@ -37,7 +37,6 @@
#include "qxl_drv.h"
#include "qxl_object.h"
-extern int qxl_max_ioctls;
static const struct pci_device_id pciidlist[] = {
{ 0x1b36, 0x100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8,
0xffff00, 0 },
@@ -262,11 +261,8 @@ static struct drm_driver qxl_driver = {
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
DRIVER_ATOMIC,
- .set_busid = drm_pci_set_busid,
-
.dumb_create = qxl_mode_dumb_create,
.dumb_map_offset = qxl_mode_dumb_mmap,
- .dumb_destroy = drm_gem_dumb_destroy,
#if defined(CONFIG_DEBUG_FS)
.debugfs_init = qxl_debugfs_init,
#endif
@@ -303,12 +299,12 @@ static int __init qxl_init(void)
if (qxl_modeset == 0)
return -EINVAL;
qxl_driver.num_ioctls = qxl_max_ioctls;
- return drm_pci_init(&qxl_driver, &qxl_pci_driver);
+ return pci_register_driver(&qxl_pci_driver);
}
static void __exit qxl_exit(void)
{
- drm_pci_exit(&qxl_driver, &qxl_pci_driver);
+ pci_unregister_driver(&qxl_pci_driver);
}
module_init(qxl_init);
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 3591d2330a09..3397a1907336 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
@@ -64,6 +64,7 @@
extern int qxl_log_level;
extern int qxl_num_crtc;
+extern int qxl_max_ioctls;
enum {
QXL_INFO_LEVEL = 1,
diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c
index 573e7e9a5f98..844c4a31ca13 100644
--- a/drivers/gpu/drm/qxl/qxl_fb.c
+++ b/drivers/gpu/drm/qxl/qxl_fb.c
@@ -275,7 +275,6 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev,
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
- info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT;
info->fbops = &qxlfb_ops;
/*
diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c
index 0b82a87916ae..31effed4a3c8 100644
--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
+++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
@@ -163,7 +163,7 @@ static int qxl_process_single_command(struct qxl_device *qdev,
return -EINVAL;
if (!access_ok(VERIFY_READ,
- (void *)(unsigned long)cmd->command,
+ u64_to_user_ptr(cmd->command),
cmd->command_size))
return -EFAULT;
@@ -183,7 +183,9 @@ static int qxl_process_single_command(struct qxl_device *qdev,
/* TODO copy slow path code from i915 */
fb_cmd = qxl_bo_kmap_atomic_page(qdev, cmd_bo, (release->release_offset & PAGE_SIZE));
- unwritten = __copy_from_user_inatomic_nocache(fb_cmd + sizeof(union qxl_release_info) + (release->release_offset & ~PAGE_SIZE), (void *)(unsigned long)cmd->command, cmd->command_size);
+ unwritten = __copy_from_user_inatomic_nocache
+ (fb_cmd + sizeof(union qxl_release_info) + (release->release_offset & ~PAGE_SIZE),
+ u64_to_user_ptr(cmd->command), cmd->command_size);
{
struct qxl_drawable *draw = fb_cmd;
@@ -201,10 +203,9 @@ static int qxl_process_single_command(struct qxl_device *qdev,
num_relocs = 0;
for (i = 0; i < cmd->relocs_num; ++i) {
struct drm_qxl_reloc reloc;
+ struct drm_qxl_reloc __user *u = u64_to_user_ptr(cmd->relocs);
- if (copy_from_user(&reloc,
- &((struct drm_qxl_reloc *)(uintptr_t)cmd->relocs)[i],
- sizeof(reloc))) {
+ if (copy_from_user(&reloc, u + i, sizeof(reloc))) {
ret = -EFAULT;
goto out_free_bos;
}
@@ -282,10 +283,10 @@ static int qxl_execbuffer_ioctl(struct drm_device *dev, void *data,
for (cmd_num = 0; cmd_num < execbuffer->commands_num; ++cmd_num) {
- struct drm_qxl_command *commands =
- (struct drm_qxl_command *)(uintptr_t)execbuffer->commands;
+ struct drm_qxl_command __user *commands =
+ u64_to_user_ptr(execbuffer->commands);
- if (copy_from_user(&user_cmd, &commands[cmd_num],
+ if (copy_from_user(&user_cmd, commands + cmd_num,
sizeof(user_cmd)))
return -EFAULT;
diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c
index 9a7eef7dd604..0a67ddf19c3d 100644
--- a/drivers/gpu/drm/qxl/qxl_object.c
+++ b/drivers/gpu/drm/qxl/qxl_object.c
@@ -221,7 +221,7 @@ struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo)
return bo;
}
-int __qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr)
+static int __qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr)
{
struct drm_device *ddev = bo->gem_base.dev;
int r;
@@ -244,7 +244,7 @@ int __qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr)
return r;
}
-int __qxl_bo_unpin(struct qxl_bo *bo)
+static int __qxl_bo_unpin(struct qxl_bo *bo)
{
struct drm_device *ddev = bo->gem_base.dev;
int r, i;
diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c
index 87fc1dbd0a2f..7ecf8a4b9fe6 100644
--- a/drivers/gpu/drm/qxl/qxl_ttm.c
+++ b/drivers/gpu/drm/qxl/qxl_ttm.c
@@ -187,7 +187,7 @@ static void qxl_evict_flags(struct ttm_buffer_object *bo,
struct ttm_placement *placement)
{
struct qxl_bo *qbo;
- static struct ttm_place placements = {
+ static const struct ttm_place placements = {
.fpfn = 0,
.lpfn = 0,
.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c
index a982be57d1ef..0d2b7e42b3a7 100644
--- a/drivers/gpu/drm/r128/r128_drv.c
+++ b/drivers/gpu/drm/r128/r128_drv.c
@@ -62,7 +62,6 @@ static struct drm_driver driver = {
.load = r128_driver_load,
.preclose = r128_driver_preclose,
.lastclose = r128_driver_lastclose,
- .set_busid = drm_pci_set_busid,
.get_vblank_counter = r128_get_vblank_counter,
.enable_vblank = r128_enable_vblank,
.disable_vblank = r128_disable_vblank,
@@ -96,12 +95,12 @@ static int __init r128_init(void)
{
driver.num_ioctls = r128_max_ioctl;
- return drm_pci_init(&driver, &r128_pci_driver);
+ return drm_legacy_pci_init(&driver, &r128_pci_driver);
}
static void __exit r128_exit(void)
{
- drm_pci_exit(&driver, &r128_pci_driver);
+ drm_legacy_pci_exit(&driver, &r128_pci_driver);
}
module_init(r128_init);
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 3c492a0aa6bd..02baaaf20e9d 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -2217,7 +2217,6 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
.mode_set_base_atomic = atombios_crtc_set_base_atomic,
.prepare = atombios_crtc_prepare,
.commit = atombios_crtc_commit,
- .load_lut = radeon_crtc_load_lut,
.disable = atombios_crtc_disable,
};
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 5008f3d4cccc..ec63bc5e9de7 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -464,7 +464,7 @@ struct radeon_bo_list {
struct radeon_bo *robj;
struct ttm_validate_buffer tv;
uint64_t gpu_offset;
- unsigned prefered_domains;
+ unsigned preferred_domains;
unsigned allowed_domains;
uint32_t tiling_flags;
};
@@ -2327,7 +2327,7 @@ struct radeon_device {
uint8_t *bios;
bool is_atom_bios;
uint16_t bios_header_start;
- struct radeon_bo *stollen_vga_memory;
+ struct radeon_bo *stolen_vga_memory;
/* Register mmio */
resource_size_t rmmio_base;
resource_size_t rmmio_size;
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
index 6efbd65c929e..8d3251a10cd4 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.c
+++ b/drivers/gpu/drm/radeon/radeon_acpi.c
@@ -351,7 +351,7 @@ out:
* handles it.
* Returns NOTIFY code
*/
-int radeon_atif_handler(struct radeon_device *rdev,
+static int radeon_atif_handler(struct radeon_device *rdev,
struct acpi_bus_event *event)
{
struct radeon_atif *atif = &rdev->atif;
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.h b/drivers/gpu/drm/radeon/radeon_acpi.h
index 7af1977c2c68..35202a453e66 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.h
+++ b/drivers/gpu/drm/radeon/radeon_acpi.h
@@ -27,9 +27,6 @@
struct radeon_device;
struct acpi_bus_event;
-int radeon_atif_handler(struct radeon_device *rdev,
- struct acpi_bus_event *event);
-
/* AMD hw uses four ACPI control methods:
* 1. ATIF
* ARG0: (ACPI_INTEGER) function code
diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c
index aaacac190d26..770e31f5fd1b 100644
--- a/drivers/gpu/drm/radeon/radeon_audio.c
+++ b/drivers/gpu/drm/radeon/radeon_audio.c
@@ -516,7 +516,7 @@ static int radeon_audio_set_avi_packet(struct drm_encoder *encoder,
if (!connector)
return -EINVAL;
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (err < 0) {
DRM_ERROR("failed to setup AVI infoframe: %d\n", err);
return err;
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 27affbde058c..2f642cbefd8e 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -773,12 +773,15 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct
if (connector->encoder->crtc) {
struct drm_crtc *crtc = connector->encoder->crtc;
- const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
radeon_crtc->output_csc = radeon_encoder->output_csc;
- (*crtc_funcs->load_lut)(crtc);
+ /*
+ * Our .gamma_set assumes the .gamma_store has been
+ * prefilled and don't care about its arguments.
+ */
+ crtc->funcs->gamma_set(crtc, NULL, NULL, NULL, 0, NULL);
}
}
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index 00b22af70f5c..1ae31dbc61c6 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -130,7 +130,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
p->rdev->family == CHIP_RS880)) {
/* TODO: is this still needed for NI+ ? */
- p->relocs[i].prefered_domains =
+ p->relocs[i].preferred_domains =
RADEON_GEM_DOMAIN_VRAM;
p->relocs[i].allowed_domains =
@@ -148,14 +148,14 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
return -EINVAL;
}
- p->relocs[i].prefered_domains = domain;
+ p->relocs[i].preferred_domains = domain;
if (domain == RADEON_GEM_DOMAIN_VRAM)
domain |= RADEON_GEM_DOMAIN_GTT;
p->relocs[i].allowed_domains = domain;
}
if (radeon_ttm_tt_has_userptr(p->relocs[i].robj->tbo.ttm)) {
- uint32_t domain = p->relocs[i].prefered_domains;
+ uint32_t domain = p->relocs[i].preferred_domains;
if (!(domain & RADEON_GEM_DOMAIN_GTT)) {
DRM_ERROR("Only RADEON_GEM_DOMAIN_GTT is "
"allowed for userptr BOs\n");
@@ -163,7 +163,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
}
need_mmap_lock = true;
domain = RADEON_GEM_DOMAIN_GTT;
- p->relocs[i].prefered_domains = domain;
+ p->relocs[i].preferred_domains = domain;
p->relocs[i].allowed_domains = domain;
}
@@ -437,7 +437,7 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bo
if (bo == NULL)
continue;
- drm_gem_object_unreference_unlocked(&bo->gem_base);
+ drm_gem_object_put_unlocked(&bo->gem_base);
}
}
kfree(parser->track);
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c
index 4a4f9533c53b..91952277557e 100644
--- a/drivers/gpu/drm/radeon/radeon_cursor.c
+++ b/drivers/gpu/drm/radeon/radeon_cursor.c
@@ -307,7 +307,7 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc,
robj = gem_to_radeon_bo(obj);
ret = radeon_bo_reserve(robj, false);
if (ret != 0) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
/* Only 27 bit offset for legacy cursor */
@@ -317,7 +317,7 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc,
radeon_bo_unreserve(robj);
if (ret) {
DRM_ERROR("Failed to pin new cursor BO (%d)\n", ret);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -352,7 +352,7 @@ unpin:
radeon_bo_unpin(robj);
radeon_bo_unreserve(robj);
}
- drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo);
+ drm_gem_object_put_unlocked(radeon_crtc->cursor_bo);
}
radeon_crtc->cursor_bo = obj;
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 17d3dafc8319..ddfe91efa61e 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -42,6 +42,7 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc)
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
@@ -60,11 +61,14 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc)
WREG32(AVIVO_DC_LUT_WRITE_EN_MASK, 0x0000003f);
WREG8(AVIVO_DC_LUT_RW_INDEX, 0);
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
for (i = 0; i < 256; i++) {
WREG32(AVIVO_DC_LUT_30_COLOR,
- (radeon_crtc->lut_r[i] << 20) |
- (radeon_crtc->lut_g[i] << 10) |
- (radeon_crtc->lut_b[i] << 0));
+ ((*r++ & 0xffc0) << 14) |
+ ((*g++ & 0xffc0) << 4) |
+ (*b++ >> 6));
}
/* Only change bit 0 of LUT_SEL, other bits are set elsewhere */
@@ -76,6 +80,7 @@ static void dce4_crtc_load_lut(struct drm_crtc *crtc)
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
@@ -93,11 +98,14 @@ static void dce4_crtc_load_lut(struct drm_crtc *crtc)
WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
for (i = 0; i < 256; i++) {
WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
- (radeon_crtc->lut_r[i] << 20) |
- (radeon_crtc->lut_g[i] << 10) |
- (radeon_crtc->lut_b[i] << 0));
+ ((*r++ & 0xffc0) << 14) |
+ ((*g++ & 0xffc0) << 4) |
+ (*b++ >> 6));
}
}
@@ -106,6 +114,7 @@ static void dce5_crtc_load_lut(struct drm_crtc *crtc)
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
@@ -135,11 +144,14 @@ static void dce5_crtc_load_lut(struct drm_crtc *crtc)
WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
for (i = 0; i < 256; i++) {
WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
- (radeon_crtc->lut_r[i] << 20) |
- (radeon_crtc->lut_g[i] << 10) |
- (radeon_crtc->lut_b[i] << 0));
+ ((*r++ & 0xffc0) << 14) |
+ ((*g++ & 0xffc0) << 4) |
+ (*b++ >> 6));
}
WREG32(NI_DEGAMMA_CONTROL + radeon_crtc->crtc_offset,
@@ -172,6 +184,7 @@ static void legacy_crtc_load_lut(struct drm_crtc *crtc)
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
+ u16 *r, *g, *b;
int i;
uint32_t dac2_cntl;
@@ -183,11 +196,14 @@ static void legacy_crtc_load_lut(struct drm_crtc *crtc)
WREG32(RADEON_DAC_CNTL2, dac2_cntl);
WREG8(RADEON_PALETTE_INDEX, 0);
+ r = crtc->gamma_store;
+ g = r + crtc->gamma_size;
+ b = g + crtc->gamma_size;
for (i = 0; i < 256; i++) {
WREG32(RADEON_PALETTE_30_DATA,
- (radeon_crtc->lut_r[i] << 20) |
- (radeon_crtc->lut_g[i] << 10) |
- (radeon_crtc->lut_b[i] << 0));
+ ((*r++ & 0xffc0) << 14) |
+ ((*g++ & 0xffc0) << 4) |
+ (*b++ >> 6));
}
}
@@ -209,41 +225,10 @@ void radeon_crtc_load_lut(struct drm_crtc *crtc)
legacy_crtc_load_lut(crtc);
}
-/** Sets the color ramps on behalf of fbcon */
-void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno)
-{
- struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
-
- radeon_crtc->lut_r[regno] = red >> 6;
- radeon_crtc->lut_g[regno] = green >> 6;
- radeon_crtc->lut_b[regno] = blue >> 6;
-}
-
-/** Gets the color ramps on behalf of fbcon */
-void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno)
-{
- struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
-
- *red = radeon_crtc->lut_r[regno] << 6;
- *green = radeon_crtc->lut_g[regno] << 6;
- *blue = radeon_crtc->lut_b[regno] << 6;
-}
-
static int radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, uint32_t size,
struct drm_modeset_acquire_ctx *ctx)
{
- struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
- int i;
-
- /* userspace palettes are always correct as is */
- for (i = 0; i < size; i++) {
- radeon_crtc->lut_r[i] = red[i] >> 6;
- radeon_crtc->lut_g[i] = green[i] >> 6;
- radeon_crtc->lut_b[i] = blue[i] >> 6;
- }
radeon_crtc_load_lut(crtc);
return 0;
@@ -282,7 +267,7 @@ static void radeon_unpin_work_func(struct work_struct *__work)
} else
DRM_ERROR("failed to reserve buffer after flip\n");
- drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
+ drm_gem_object_put_unlocked(&work->old_rbo->gem_base);
kfree(work);
}
@@ -519,7 +504,7 @@ static int radeon_crtc_page_flip_target(struct drm_crtc *crtc,
obj = old_radeon_fb->obj;
/* take a reference to the old object */
- drm_gem_object_reference(obj);
+ drm_gem_object_get(obj);
work->old_rbo = gem_to_radeon_bo(obj);
new_radeon_fb = to_radeon_framebuffer(fb);
@@ -618,7 +603,7 @@ pflip_cleanup:
radeon_bo_unreserve(new_rbo);
cleanup:
- drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
+ drm_gem_object_put_unlocked(&work->old_rbo->gem_base);
dma_fence_put(work->fence);
kfree(work);
return r;
@@ -1303,7 +1288,7 @@ static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
{
struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb);
- drm_gem_object_unreference_unlocked(radeon_fb->obj);
+ drm_gem_object_put_unlocked(radeon_fb->obj);
drm_framebuffer_cleanup(fb);
kfree(radeon_fb);
}
@@ -1363,14 +1348,14 @@ radeon_user_framebuffer_create(struct drm_device *dev,
radeon_fb = kzalloc(sizeof(*radeon_fb), GFP_KERNEL);
if (radeon_fb == NULL) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(-ENOMEM);
}
ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj);
if (ret) {
kfree(radeon_fb);
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ERR_PTR(ret);
}
@@ -1388,12 +1373,12 @@ static const struct drm_mode_config_funcs radeon_mode_funcs = {
.output_poll_changed = radeon_output_poll_changed
};
-static struct drm_prop_enum_list radeon_tmds_pll_enum_list[] =
+static const struct drm_prop_enum_list radeon_tmds_pll_enum_list[] =
{ { 0, "driver" },
{ 1, "bios" },
};
-static struct drm_prop_enum_list radeon_tv_std_enum_list[] =
+static const struct drm_prop_enum_list radeon_tv_std_enum_list[] =
{ { TV_STD_NTSC, "ntsc" },
{ TV_STD_PAL, "pal" },
{ TV_STD_PAL_M, "pal-m" },
@@ -1404,25 +1389,25 @@ static struct drm_prop_enum_list radeon_tv_std_enum_list[] =
{ TV_STD_SECAM, "secam" },
};
-static struct drm_prop_enum_list radeon_underscan_enum_list[] =
+static const struct drm_prop_enum_list radeon_underscan_enum_list[] =
{ { UNDERSCAN_OFF, "off" },
{ UNDERSCAN_ON, "on" },
{ UNDERSCAN_AUTO, "auto" },
};
-static struct drm_prop_enum_list radeon_audio_enum_list[] =
+static const struct drm_prop_enum_list radeon_audio_enum_list[] =
{ { RADEON_AUDIO_DISABLE, "off" },
{ RADEON_AUDIO_ENABLE, "on" },
{ RADEON_AUDIO_AUTO, "auto" },
};
/* XXX support different dither options? spatial, temporal, both, etc. */
-static struct drm_prop_enum_list radeon_dither_enum_list[] =
+static const struct drm_prop_enum_list radeon_dither_enum_list[] =
{ { RADEON_FMT_DITHER_DISABLE, "off" },
{ RADEON_FMT_DITHER_ENABLE, "on" },
};
-static struct drm_prop_enum_list radeon_output_csc_enum_list[] =
+static const struct drm_prop_enum_list radeon_output_csc_enum_list[] =
{ { RADEON_OUTPUT_CSC_BYPASS, "bypass" },
{ RADEON_OUTPUT_CSC_TVRGB, "tvrgb" },
{ RADEON_OUTPUT_CSC_YCBCR601, "ycbcr601" },
diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c
index 6598306dca9b..ebdf1b859cb6 100644
--- a/drivers/gpu/drm/radeon/radeon_dp_mst.c
+++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c
@@ -300,9 +300,7 @@ static void radeon_dp_register_mst_connector(struct drm_connector *connector)
struct drm_device *dev = connector->dev;
struct radeon_device *rdev = dev->dev_private;
- drm_modeset_lock_all(dev);
radeon_fb_add_connector(rdev, connector);
- drm_modeset_unlock_all(dev);
drm_connector_register(connector);
}
@@ -315,13 +313,8 @@ static void radeon_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
struct radeon_device *rdev = dev->dev_private;
drm_connector_unregister(connector);
- /* need to nuke the connector */
- drm_modeset_lock_all(dev);
- /* dpms off */
radeon_fb_remove_connector(rdev, connector);
-
drm_connector_cleanup(connector);
- drm_modeset_unlock_all(dev);
kfree(connector);
DRM_DEBUG_KMS("\n");
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 74abd161237b..f4becad0a78c 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -567,7 +567,6 @@ static struct drm_driver kms_driver = {
.open = radeon_driver_open_kms,
.postclose = radeon_driver_postclose_kms,
.lastclose = radeon_driver_lastclose_kms,
- .set_busid = drm_pci_set_busid,
.unload = radeon_driver_unload_kms,
.get_vblank_counter = radeon_get_vblank_counter_kms,
.enable_vblank = radeon_enable_vblank_kms,
@@ -584,7 +583,6 @@ static struct drm_driver kms_driver = {
.gem_close_object = radeon_gem_object_close,
.dumb_create = radeon_mode_dumb_create,
.dumb_map_offset = radeon_mode_dumb_mmap,
- .dumb_destroy = drm_gem_dumb_destroy,
.fops = &radeon_driver_kms_fops,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
@@ -642,14 +640,13 @@ static int __init radeon_init(void)
return -EINVAL;
}
- /* let modprobe override vga console setting */
- return drm_pci_init(driver, pdriver);
+ return pci_register_driver(pdriver);
}
static void __exit radeon_exit(void)
{
radeon_kfd_fini();
- drm_pci_exit(driver, pdriver);
+ pci_unregister_driver(pdriver);
radeon_unregister_atpx_handler();
}
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 356ad90a5238..fd25361ac681 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -118,7 +118,7 @@ static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj)
radeon_bo_unpin(rbo);
radeon_bo_unreserve(rbo);
}
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
}
static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
@@ -264,7 +264,6 @@ static int radeonfb_create(struct drm_fb_helper *helper,
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
- info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &radeonfb_ops;
tmp = radeon_bo_gpu_offset(rbo) - rdev->mc.vram_start;
@@ -300,7 +299,7 @@ out:
}
if (fb && ret) {
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
drm_framebuffer_unregister_private(fb);
drm_framebuffer_cleanup(fb);
kfree(fb);
@@ -332,8 +331,6 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb
}
static const struct drm_fb_helper_funcs radeon_fb_helper_funcs = {
- .gamma_set = radeon_crtc_fb_gamma_set,
- .gamma_get = radeon_crtc_fb_gamma_get,
.fb_probe = radeonfb_create,
};
@@ -347,9 +344,12 @@ int radeon_fbdev_init(struct radeon_device *rdev)
if (list_empty(&rdev->ddev->mode_config.connector_list))
return 0;
- /* select 8 bpp console on RN50 or 16MB cards */
- if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32*1024*1024))
+ /* select 8 bpp console on 8MB cards, or 16 bpp on RN50 or 32MB */
+ if (rdev->mc.real_vram_size <= (8*1024*1024))
bpp_sel = 8;
+ else if (ASIC_IS_RN50(rdev) ||
+ rdev->mc.real_vram_size <= (32*1024*1024))
+ bpp_sel = 16;
rfbdev = kzalloc(sizeof(struct radeon_fbdev), GFP_KERNEL);
if (!rfbdev)
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index 574bf7e6b118..3386452bd2f0 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -271,7 +271,7 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
}
r = drm_gem_handle_create(filp, gobj, &handle);
/* drop reference from allocate - handle holds it now */
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (r) {
up_read(&rdev->exclusive_lock);
r = radeon_gem_handle_lockup(rdev, r);
@@ -352,7 +352,7 @@ int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data,
r = drm_gem_handle_create(filp, gobj, &handle);
/* drop reference from allocate - handle holds it now */
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (r)
goto handle_lockup;
@@ -361,7 +361,7 @@ int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data,
return 0;
release_object:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
handle_lockup:
up_read(&rdev->exclusive_lock);
@@ -395,7 +395,7 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
up_read(&rdev->exclusive_lock);
r = radeon_gem_handle_lockup(robj->rdev, r);
return r;
@@ -414,11 +414,11 @@ int radeon_mode_dumb_mmap(struct drm_file *filp,
}
robj = gem_to_radeon_bo(gobj);
if (radeon_ttm_tt_has_userptr(robj->tbo.ttm)) {
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return -EPERM;
}
*offset_p = radeon_bo_mmap_offset(robj);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return 0;
}
@@ -453,7 +453,7 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
cur_placement = ACCESS_ONCE(robj->tbo.mem.mem_type);
args->domain = radeon_mem_type_to_domain(cur_placement);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -485,7 +485,7 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
if (rdev->asic->mmio_hdp_flush &&
radeon_mem_type_to_domain(cur_placement) == RADEON_GEM_DOMAIN_VRAM)
robj->rdev->asic->mmio_hdp_flush(rdev);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
r = radeon_gem_handle_lockup(rdev, r);
return r;
}
@@ -504,7 +504,7 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data,
return -ENOENT;
robj = gem_to_radeon_bo(gobj);
r = radeon_bo_set_tiling_flags(robj, args->tiling_flags, args->pitch);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -527,7 +527,7 @@ int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data,
radeon_bo_get_tiling_flags(rbo, &args->tiling_flags, &args->pitch);
radeon_bo_unreserve(rbo);
out:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -661,14 +661,14 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data,
r = radeon_bo_reserve(rbo, false);
if (r) {
args->operation = RADEON_VA_RESULT_ERROR;
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
bo_va = radeon_vm_bo_find(&fpriv->vm, rbo);
if (!bo_va) {
args->operation = RADEON_VA_RESULT_ERROR;
radeon_bo_unreserve(rbo);
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return -ENOENT;
}
@@ -695,7 +695,7 @@ int radeon_gem_va_ioctl(struct drm_device *dev, void *data,
args->operation = RADEON_VA_RESULT_ERROR;
}
out:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -736,7 +736,7 @@ int radeon_gem_op_ioctl(struct drm_device *dev, void *data,
radeon_bo_unreserve(robj);
out:
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
return r;
}
@@ -762,7 +762,7 @@ int radeon_mode_dumb_create(struct drm_file *file_priv,
r = drm_gem_handle_create(file_priv, gobj, &handle);
/* drop reference from allocate - handle holds it now */
- drm_gem_object_unreference_unlocked(gobj);
+ drm_gem_object_put_unlocked(gobj);
if (r) {
return r;
}
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index 7aacb44df201..afaf10db47cc 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -283,6 +283,10 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
int r = 0;
spin_lock_init(&rdev->irq.lock);
+
+ /* Disable vblank irqs aggressively for power-saving */
+ rdev->ddev->vblank_disable_immediate = true;
+
r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
if (r) {
return r;
@@ -324,7 +328,6 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
*/
void radeon_irq_kms_fini(struct radeon_device *rdev)
{
- drm_vblank_cleanup(rdev->ddev);
if (rdev->irq.installed) {
drm_irq_uninstall(rdev->ddev);
rdev->irq.installed = false;
diff --git a/drivers/gpu/drm/radeon/radeon_kfd.c b/drivers/gpu/drm/radeon/radeon_kfd.c
index 699fe7f9b8bf..f6578c96925c 100644
--- a/drivers/gpu/drm/radeon/radeon_kfd.c
+++ b/drivers/gpu/drm/radeon/radeon_kfd.c
@@ -75,12 +75,14 @@ static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
uint32_t hpd_size, uint64_t hpd_gpu_addr);
static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id);
static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
- uint32_t queue_id, uint32_t __user *wptr);
+ uint32_t queue_id, uint32_t __user *wptr,
+ uint32_t wptr_shift, uint32_t wptr_mask,
+ struct mm_struct *mm);
static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd);
static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
uint32_t pipe_id, uint32_t queue_id);
-static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
+static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd, uint32_t reset_type,
unsigned int timeout, uint32_t pipe_id,
uint32_t queue_id);
static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd);
@@ -184,7 +186,6 @@ void radeon_kfd_device_init(struct radeon_device *rdev)
if (rdev->kfd) {
struct kgd2kfd_shared_resources gpu_resources = {
.compute_vmid_bitmap = 0xFF00,
- .num_mec = 1,
.num_pipe_per_mec = 4,
.num_queue_per_pipe = 8
};
@@ -483,7 +484,9 @@ static inline struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd)
}
static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
- uint32_t queue_id, uint32_t __user *wptr)
+ uint32_t queue_id, uint32_t __user *wptr,
+ uint32_t wptr_shift, uint32_t wptr_mask,
+ struct mm_struct *mm)
{
uint32_t wptr_shadow, is_wptr_shadow_valid;
struct cik_mqd *m;
@@ -637,7 +640,7 @@ static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd)
return false;
}
-static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
+static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd, uint32_t reset_type,
unsigned int timeout, uint32_t pipe_id,
uint32_t queue_id)
{
@@ -786,7 +789,8 @@ static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd,
unsigned int watch_point_id,
unsigned int reg_offset)
{
- return watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX + reg_offset];
+ return watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX + reg_offset]
+ / 4;
}
static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd, uint8_t vmid)
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index ce6cb6666212..1f1856e0b1e0 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -1116,7 +1116,6 @@ static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
.mode_set_base_atomic = radeon_crtc_set_base_atomic,
.prepare = radeon_crtc_prepare,
.commit = radeon_crtc_commit,
- .load_lut = radeon_crtc_load_lut,
.disable = radeon_crtc_disable
};
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 00f5ec5c12c7..da44ac234f64 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -935,10 +935,6 @@ extern void
radeon_combios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc);
extern void
radeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on);
-extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno);
-extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno);
int radeon_framebuffer_init(struct drm_device *dev,
struct radeon_framebuffer *rfb,
const struct drm_mode_fb_cmd2 *mode_cmd,
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index 8b722297a05c..093594976126 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -445,7 +445,7 @@ void radeon_bo_force_delete(struct radeon_device *rdev)
list_del_init(&bo->list);
mutex_unlock(&bo->rdev->gem.mutex);
/* this should unref the ttm bo */
- drm_gem_object_unreference_unlocked(&bo->gem_base);
+ drm_gem_object_put_unlocked(&bo->gem_base);
}
}
@@ -546,7 +546,7 @@ int radeon_bo_list_validate(struct radeon_device *rdev,
list_for_each_entry(lobj, head, tv.head) {
struct radeon_bo *bo = lobj->robj;
if (!bo->pin_count) {
- u32 domain = lobj->prefered_domains;
+ u32 domain = lobj->preferred_domains;
u32 allowed = lobj->allowed_domains;
u32 current_domain =
radeon_mem_type_to_domain(bo->tbo.mem.mem_type);
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index faa021396da3..bf69bf9086bf 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -178,7 +178,7 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
static void radeon_evict_flags(struct ttm_buffer_object *bo,
struct ttm_placement *placement)
{
- static struct ttm_place placements = {
+ static const struct ttm_place placements = {
.fpfn = 0,
.lpfn = 0,
.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM
@@ -907,17 +907,17 @@ int radeon_ttm_init(struct radeon_device *rdev)
r = radeon_bo_create(rdev, 256 * 1024, PAGE_SIZE, true,
RADEON_GEM_DOMAIN_VRAM, 0, NULL,
- NULL, &rdev->stollen_vga_memory);
+ NULL, &rdev->stolen_vga_memory);
if (r) {
return r;
}
- r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
+ r = radeon_bo_reserve(rdev->stolen_vga_memory, false);
if (r)
return r;
- r = radeon_bo_pin(rdev->stollen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL);
- radeon_bo_unreserve(rdev->stollen_vga_memory);
+ r = radeon_bo_pin(rdev->stolen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL);
+ radeon_bo_unreserve(rdev->stolen_vga_memory);
if (r) {
- radeon_bo_unref(&rdev->stollen_vga_memory);
+ radeon_bo_unref(&rdev->stolen_vga_memory);
return r;
}
DRM_INFO("radeon: %uM of VRAM memory ready\n",
@@ -946,13 +946,13 @@ void radeon_ttm_fini(struct radeon_device *rdev)
if (!rdev->mman.initialized)
return;
radeon_ttm_debugfs_fini(rdev);
- if (rdev->stollen_vga_memory) {
- r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
+ if (rdev->stolen_vga_memory) {
+ r = radeon_bo_reserve(rdev->stolen_vga_memory, false);
if (r == 0) {
- radeon_bo_unpin(rdev->stollen_vga_memory);
- radeon_bo_unreserve(rdev->stollen_vga_memory);
+ radeon_bo_unpin(rdev->stolen_vga_memory);
+ radeon_bo_unreserve(rdev->stolen_vga_memory);
}
- radeon_bo_unref(&rdev->stollen_vga_memory);
+ radeon_bo_unref(&rdev->stolen_vga_memory);
}
ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_VRAM);
ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_TT);
@@ -1030,19 +1030,17 @@ int radeon_mmap(struct file *filp, struct vm_area_struct *vma)
static int radeon_mm_dump_table(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *)m->private;
- unsigned ttm_pl = *(int *)node->info_ent->data;
+ unsigned ttm_pl = *(int*)node->info_ent->data;
struct drm_device *dev = node->minor->dev;
struct radeon_device *rdev = dev->dev_private;
- struct drm_mm *mm = (struct drm_mm *)rdev->mman.bdev.man[ttm_pl].priv;
- struct ttm_bo_global *glob = rdev->mman.bdev.glob;
+ struct ttm_mem_type_manager *man = &rdev->mman.bdev.man[ttm_pl];
struct drm_printer p = drm_seq_file_printer(m);
- spin_lock(&glob->lru_lock);
- drm_mm_print(mm, &p);
- spin_unlock(&glob->lru_lock);
+ man->func->debug(man, &p);
return 0;
}
+
static int ttm_pl_vram = TTM_PL_VRAM;
static int ttm_pl_tt = TTM_PL_TT;
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c
index 5f68245579a3..5e82b408d522 100644
--- a/drivers/gpu/drm/radeon/radeon_vm.c
+++ b/drivers/gpu/drm/radeon/radeon_vm.c
@@ -139,7 +139,7 @@ struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev,
/* add the vm page table to the list */
list[0].robj = vm->page_directory;
- list[0].prefered_domains = RADEON_GEM_DOMAIN_VRAM;
+ list[0].preferred_domains = RADEON_GEM_DOMAIN_VRAM;
list[0].allowed_domains = RADEON_GEM_DOMAIN_VRAM;
list[0].tv.bo = &vm->page_directory->tbo;
list[0].tv.shared = true;
@@ -151,7 +151,7 @@ struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev,
continue;
list[idx].robj = vm->page_tables[i].bo;
- list[idx].prefered_domains = RADEON_GEM_DOMAIN_VRAM;
+ list[idx].preferred_domains = RADEON_GEM_DOMAIN_VRAM;
list[idx].allowed_domains = RADEON_GEM_DOMAIN_VRAM;
list[idx].tv.bo = &list[idx].robj->tbo;
list[idx].tv.shared = true;
diff --git a/drivers/gpu/drm/radeon/vce_v2_0.c b/drivers/gpu/drm/radeon/vce_v2_0.c
index fce214482e72..b0a43b68776d 100644
--- a/drivers/gpu/drm/radeon/vce_v2_0.c
+++ b/drivers/gpu/drm/radeon/vce_v2_0.c
@@ -104,6 +104,10 @@ static void vce_v2_0_disable_cg(struct radeon_device *rdev)
WREG32(VCE_CGTT_CLK_OVERRIDE, 7);
}
+/*
+ * Local variable sw_cg is used for debugging purposes, in case we
+ * ran into problems with dynamic clock gating. Don't remove it.
+ */
void vce_v2_0_enable_mgcg(struct radeon_device *rdev, bool enable)
{
bool sw_cg = false;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 345eff72f581..301ea1a8018e 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -13,6 +13,7 @@
#include <linux/clk.h>
#include <linux/mutex.h>
+#include <linux/sys_soc.h>
#include <drm/drmP.h>
#include <drm/drm_atomic.h>
@@ -129,10 +130,8 @@ static void rcar_du_dpll_divider(struct rcar_du_crtc *rcrtc,
for (fdpll = 1; fdpll < 32; fdpll++) {
unsigned long output;
- /* 1/2 (FRQSEL=1) for duty rate 50% */
output = input * (n + 1) / (m + 1)
- / (fdpll + 1) / 2;
-
+ / (fdpll + 1);
if (output >= 400000000)
continue;
@@ -158,6 +157,11 @@ done:
best_diff);
}
+static const struct soc_device_attribute rcar_du_r8a7795_es1[] = {
+ { .soc_id = "r8a7795", .revision = "ES1.*" },
+ { /* sentinel */ }
+};
+
static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
{
const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
@@ -168,7 +172,8 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
u32 escr;
u32 div;
- /* Compute the clock divisor and select the internal or external dot
+ /*
+ * Compute the clock divisor and select the internal or external dot
* clock based on the requested frequency.
*/
clk = clk_get_rate(rcrtc->clock);
@@ -185,7 +190,20 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
extclk = clk_get_rate(rcrtc->extclock);
if (rcdu->info->dpll_ch & (1 << rcrtc->index)) {
- rcar_du_dpll_divider(rcrtc, &dpll, extclk, mode_clock);
+ unsigned long target = mode_clock;
+
+ /*
+ * The H3 ES1.x exhibits dot clock duty cycle stability
+ * issues. We can work around them by configuring the
+ * DPLL to twice the desired frequency, coupled with a
+ * /2 post-divider. This isn't needed on other SoCs and
+ * breaks HDMI output on M3-W for a currently unknown
+ * reason, so restrict the workaround to H3 ES1.x.
+ */
+ if (soc_device_match(rcar_du_r8a7795_es1))
+ target *= 2;
+
+ rcar_du_dpll_divider(rcrtc, &dpll, extclk, target);
extclk = dpll.output;
}
@@ -197,8 +215,6 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
if (abs((long)extrate - (long)mode_clock) <
abs((long)rate - (long)mode_clock)) {
- dev_dbg(rcrtc->group->dev->dev,
- "crtc%u: using external clock\n", rcrtc->index);
if (rcdu->info->dpll_ch & (1 << rcrtc->index)) {
u32 dpllcr = DPLLCR_CODE | DPLLCR_CLKE
@@ -215,12 +231,14 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc)
rcar_du_group_write(rcrtc->group, DPLLCR,
dpllcr);
-
- escr = ESCR_DCLKSEL_DCLKIN | 1;
- } else {
- escr = ESCR_DCLKSEL_DCLKIN | extdiv;
}
+
+ escr = ESCR_DCLKSEL_DCLKIN | extdiv;
}
+
+ dev_dbg(rcrtc->group->dev->dev,
+ "mode clock %lu extrate %lu rate %lu ESCR 0x%08x\n",
+ mode_clock, extrate, rate, escr);
}
rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? ESCR2 : ESCR,
@@ -261,12 +279,14 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc,
struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
struct rcar_du_device *rcdu = rcrtc->group->dev;
- /* Store the route from the CRTC output to the DU output. The DU will be
+ /*
+ * Store the route from the CRTC output to the DU output. The DU will be
* configured when starting the CRTC.
*/
rcrtc->outputs |= BIT(output);
- /* Store RGB routing to DPAD0, the hardware will be configured when
+ /*
+ * Store RGB routing to DPAD0, the hardware will be configured when
* starting the CRTC.
*/
if (output == RCAR_DU_OUTPUT_DPAD0)
@@ -342,7 +362,8 @@ static void rcar_du_crtc_update_planes(struct rcar_du_crtc *rcrtc)
}
}
- /* Update the planes to display timing and dot clock generator
+ /*
+ * Update the planes to display timing and dot clock generator
* associations.
*
* Updating the DPTSR register requires restarting the CRTC group,
@@ -431,14 +452,8 @@ static void rcar_du_crtc_wait_page_flip(struct rcar_du_crtc *rcrtc)
* Start/Stop and Suspend/Resume
*/
-static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
+static void rcar_du_crtc_setup(struct rcar_du_crtc *rcrtc)
{
- struct drm_crtc *crtc = &rcrtc->crtc;
- bool interlaced;
-
- if (rcrtc->started)
- return;
-
/* Set display off and background to black */
rcar_du_crtc_write(rcrtc, DOOR, DOOR_RGB(0, 0, 0));
rcar_du_crtc_write(rcrtc, BPOR, BPOR_RGB(0, 0, 0));
@@ -450,7 +465,20 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
/* Start with all planes disabled. */
rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
- /* Select master sync mode. This enables display operation in master
+ /* Enable the VSP compositor. */
+ if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
+ rcar_du_vsp_enable(rcrtc);
+
+ /* Turn vertical blanking interrupt reporting on. */
+ drm_crtc_vblank_on(&rcrtc->crtc);
+}
+
+static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
+{
+ bool interlaced;
+
+ /*
+ * Select master sync mode. This enables display operation in master
* sync mode (with the HSYNC and VSYNC signals configured as outputs and
* actively driven).
*/
@@ -460,38 +488,56 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
DSYSR_TVM_MASTER);
rcar_du_group_start_stop(rcrtc->group, true);
+}
- /* Enable the VSP compositor. */
- if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
- rcar_du_vsp_enable(rcrtc);
+static void rcar_du_crtc_disable_planes(struct rcar_du_crtc *rcrtc)
+{
+ struct rcar_du_device *rcdu = rcrtc->group->dev;
+ struct drm_crtc *crtc = &rcrtc->crtc;
+ u32 status;
- /* Turn vertical blanking interrupt reporting back on. */
- drm_crtc_vblank_on(crtc);
+ /* Make sure vblank interrupts are enabled. */
+ drm_crtc_vblank_get(crtc);
- rcrtc->started = true;
+ /*
+ * Disable planes and calculate how many vertical blanking interrupts we
+ * have to wait for. If a vertical blanking interrupt has been triggered
+ * but not processed yet, we don't know whether it occurred before or
+ * after the planes got disabled. We thus have to wait for two vblank
+ * interrupts in that case.
+ */
+ spin_lock_irq(&rcrtc->vblank_lock);
+ rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
+ status = rcar_du_crtc_read(rcrtc, DSSR);
+ rcrtc->vblank_count = status & DSSR_VBK ? 2 : 1;
+ spin_unlock_irq(&rcrtc->vblank_lock);
+
+ if (!wait_event_timeout(rcrtc->vblank_wait, rcrtc->vblank_count == 0,
+ msecs_to_jiffies(100)))
+ dev_warn(rcdu->dev, "vertical blanking timeout\n");
+
+ drm_crtc_vblank_put(crtc);
}
static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
{
struct drm_crtc *crtc = &rcrtc->crtc;
- if (!rcrtc->started)
- return;
-
- /* Disable all planes and wait for the change to take effect. This is
- * required as the DSnPR registers are updated on vblank, and no vblank
- * will occur once the CRTC is stopped. Disabling planes when starting
- * the CRTC thus wouldn't be enough as it would start scanning out
- * immediately from old frame buffers until the next vblank.
+ /*
+ * Disable all planes and wait for the change to take effect. This is
+ * required as the plane enable registers are updated on vblank, and no
+ * vblank will occur once the CRTC is stopped. Disabling planes when
+ * starting the CRTC thus wouldn't be enough as it would start scanning
+ * out immediately from old frame buffers until the next vblank.
*
* This increases the CRTC stop delay, especially when multiple CRTCs
* are stopped in one operation as we now wait for one vblank per CRTC.
* Whether this can be improved needs to be researched.
*/
- rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
- drm_crtc_wait_one_vblank(crtc);
+ rcar_du_crtc_disable_planes(rcrtc);
- /* Disable vertical blanking interrupt reporting. We first need to wait
+ /*
+ * Disable vertical blanking interrupt reporting. We first need to wait
* for page flip completion before stopping the CRTC as userspace
* expects page flips to eventually complete.
*/
@@ -502,14 +548,13 @@ static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc)
if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
rcar_du_vsp_disable(rcrtc);
- /* Select switch sync mode. This stops display operation and configures
+ /*
+ * Select switch sync mode. This stops display operation and configures
* the HSYNC and VSYNC signals as inputs.
*/
rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH);
rcar_du_group_start_stop(rcrtc->group, false);
-
- rcrtc->started = false;
}
void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc)
@@ -529,12 +574,10 @@ void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc)
return;
rcar_du_crtc_get(rcrtc);
- rcar_du_crtc_start(rcrtc);
+ rcar_du_crtc_setup(rcrtc);
/* Commit the planes state. */
- if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE)) {
- rcar_du_vsp_enable(rcrtc);
- } else {
+ if (!rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE)) {
for (i = 0; i < rcrtc->group->num_planes; ++i) {
struct rcar_du_plane *plane = &rcrtc->group->planes[i];
@@ -546,21 +589,33 @@ void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc)
}
rcar_du_crtc_update_planes(rcrtc);
+ rcar_du_crtc_start(rcrtc);
}
/* -----------------------------------------------------------------------------
* CRTC Functions
*/
-static void rcar_du_crtc_enable(struct drm_crtc *crtc)
+static void rcar_du_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
- rcar_du_crtc_get(rcrtc);
+ /*
+ * If the CRTC has already been setup by the .atomic_begin() handler we
+ * can skip the setup stage.
+ */
+ if (!rcrtc->initialized) {
+ rcar_du_crtc_get(rcrtc);
+ rcar_du_crtc_setup(rcrtc);
+ rcrtc->initialized = true;
+ }
+
rcar_du_crtc_start(rcrtc);
}
-static void rcar_du_crtc_disable(struct drm_crtc *crtc)
+static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
@@ -574,6 +629,7 @@ static void rcar_du_crtc_disable(struct drm_crtc *crtc)
}
spin_unlock_irq(&crtc->dev->event_lock);
+ rcrtc->initialized = false;
rcrtc->outputs = 0;
}
@@ -582,6 +638,19 @@ static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc,
{
struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
+ WARN_ON(!crtc->state->enable);
+
+ /*
+ * If a mode set is in progress we can be called with the CRTC disabled.
+ * We then need to first setup the CRTC in order to configure planes.
+ * The .atomic_enable() handler will notice and skip the CRTC setup.
+ */
+ if (!rcrtc->initialized) {
+ rcar_du_crtc_get(rcrtc);
+ rcar_du_crtc_setup(rcrtc);
+ rcrtc->initialized = true;
+ }
+
if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE))
rcar_du_vsp_atomic_begin(rcrtc);
}
@@ -609,10 +678,10 @@ static void rcar_du_crtc_atomic_flush(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs crtc_helper_funcs = {
- .disable = rcar_du_crtc_disable,
- .enable = rcar_du_crtc_enable,
.atomic_begin = rcar_du_crtc_atomic_begin,
.atomic_flush = rcar_du_crtc_atomic_flush,
+ .atomic_enable = rcar_du_crtc_atomic_enable,
+ .atomic_disable = rcar_du_crtc_atomic_disable,
};
static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc)
@@ -621,6 +690,7 @@ static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc)
rcar_du_crtc_write(rcrtc, DSRCR, DSRCR_VBCL);
rcar_du_crtc_set(rcrtc, DIER, DIER_VBE);
+ rcrtc->vblank_enable = true;
return 0;
}
@@ -630,6 +700,7 @@ static void rcar_du_crtc_disable_vblank(struct drm_crtc *crtc)
struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
rcar_du_crtc_clr(rcrtc, DIER, DIER_VBE);
+ rcrtc->vblank_enable = false;
}
static const struct drm_crtc_funcs crtc_funcs = {
@@ -654,14 +725,30 @@ static irqreturn_t rcar_du_crtc_irq(int irq, void *arg)
irqreturn_t ret = IRQ_NONE;
u32 status;
+ spin_lock(&rcrtc->vblank_lock);
+
status = rcar_du_crtc_read(rcrtc, DSSR);
rcar_du_crtc_write(rcrtc, DSRCR, status & DSRCR_MASK);
- if (status & DSSR_FRM) {
- drm_crtc_handle_vblank(&rcrtc->crtc);
+ if (status & DSSR_VBK) {
+ /*
+ * Wake up the vblank wait if the counter reaches 0. This must
+ * be protected by the vblank_lock to avoid races in
+ * rcar_du_crtc_disable_planes().
+ */
+ if (rcrtc->vblank_count) {
+ if (--rcrtc->vblank_count == 0)
+ wake_up(&rcrtc->vblank_wait);
+ }
+ }
- if (rcdu->info->gen < 3)
+ spin_unlock(&rcrtc->vblank_lock);
+
+ if (status & DSSR_VBK) {
+ if (rcdu->info->gen < 3) {
+ drm_crtc_handle_vblank(&rcrtc->crtc);
rcar_du_crtc_finish_page_flip(rcrtc);
+ }
ret = IRQ_HANDLED;
}
@@ -715,13 +802,15 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index)
}
init_waitqueue_head(&rcrtc->flip_wait);
+ init_waitqueue_head(&rcrtc->vblank_wait);
+ spin_lock_init(&rcrtc->vblank_lock);
rcrtc->group = rgrp;
rcrtc->mmio_offset = mmio_offsets[index];
rcrtc->index = index;
if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
- primary = &rcrtc->vsp->planes[0].plane;
+ primary = &rcrtc->vsp->planes[rcrtc->vsp_pipe].plane;
else
primary = &rgrp->planes[index % 2].plane;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index b199ed5adf36..fdc2bf99bda1 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -15,6 +15,7 @@
#define __RCAR_DU_CRTC_H__
#include <linux/mutex.h>
+#include <linux/spinlock.h>
#include <linux/wait.h>
#include <drm/drmP.h>
@@ -30,11 +31,17 @@ struct rcar_du_vsp;
* @extclock: external pixel dot clock (optional)
* @mmio_offset: offset of the CRTC registers in the DU MMIO block
* @index: CRTC software and hardware index
- * @started: whether the CRTC has been started and is running
+ * @initialized: whether the CRTC has been initialized and clocks enabled
+ * @vblank_enable: whether vblank events are enabled on this CRTC
* @event: event to post when the pending page flip completes
* @flip_wait: wait queue used to signal page flip completion
+ * @vblank_lock: protects vblank_wait and vblank_count
+ * @vblank_wait: wait queue used to signal vertical blanking
+ * @vblank_count: number of vertical blanking interrupts to wait for
* @outputs: bitmask of the outputs (enum rcar_du_output) driven by this CRTC
* @group: CRTC group this CRTC belongs to
+ * @vsp: VSP feeding video to this CRTC
+ * @vsp_pipe: index of the VSP pipeline feeding video to this CRTC
*/
struct rcar_du_crtc {
struct drm_crtc crtc;
@@ -43,15 +50,21 @@ struct rcar_du_crtc {
struct clk *extclock;
unsigned int mmio_offset;
unsigned int index;
- bool started;
+ bool initialized;
+ bool vblank_enable;
struct drm_pending_vblank_event *event;
wait_queue_head_t flip_wait;
+ spinlock_t vblank_lock;
+ wait_queue_head_t vblank_wait;
+ unsigned int vblank_count;
+
unsigned int outputs;
struct rcar_du_group *group;
struct rcar_du_vsp *vsp;
+ unsigned int vsp_pipe;
};
#define to_rcar_crtc(c) container_of(c, struct rcar_du_crtc, crtc)
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index d6a0255181cc..d2f29e6b1112 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -39,7 +39,8 @@ static const struct rcar_du_device_info rcar_du_r8a7779_info = {
.features = 0,
.num_crtcs = 2,
.routes = {
- /* R8A7779 has two RGB outputs and one (currently unsupported)
+ /*
+ * R8A7779 has two RGB outputs and one (currently unsupported)
* TCON output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
@@ -61,7 +62,8 @@ static const struct rcar_du_device_info rcar_du_r8a7790_info = {
.quirks = RCAR_DU_QUIRK_ALIGN_128B | RCAR_DU_QUIRK_LVDS_LANES,
.num_crtcs = 3,
.routes = {
- /* R8A7790 has one RGB output, two LVDS outputs and one
+ /*
+ * R8A7790 has one RGB output, two LVDS outputs and one
* (currently unsupported) TCON output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
@@ -87,7 +89,8 @@ static const struct rcar_du_device_info rcar_du_r8a7791_info = {
| RCAR_DU_FEATURE_EXT_CTRL_REGS,
.num_crtcs = 2,
.routes = {
- /* R8A779[13] has one RGB output, one LVDS output and one
+ /*
+ * R8A779[13] has one RGB output, one LVDS output and one
* (currently unsupported) TCON output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
@@ -127,7 +130,8 @@ static const struct rcar_du_device_info rcar_du_r8a7794_info = {
| RCAR_DU_FEATURE_EXT_CTRL_REGS,
.num_crtcs = 2,
.routes = {
- /* R8A7794 has two RGB outputs and one (currently unsupported)
+ /*
+ * R8A7794 has two RGB outputs and one (currently unsupported)
* TCON output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
@@ -149,7 +153,8 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = {
| RCAR_DU_FEATURE_VSP1_SOURCE,
.num_crtcs = 4,
.routes = {
- /* R8A7795 has one RGB output, two HDMI outputs and one
+ /*
+ * R8A7795 has one RGB output, two HDMI outputs and one
* LVDS output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
@@ -180,19 +185,25 @@ static const struct rcar_du_device_info rcar_du_r8a7796_info = {
| RCAR_DU_FEATURE_VSP1_SOURCE,
.num_crtcs = 3,
.routes = {
- /* R8A7796 has one RGB output, one LVDS output and one
- * (currently unsupported) HDMI output.
+ /*
+ * R8A7796 has one RGB output, one LVDS output and one HDMI
+ * output.
*/
[RCAR_DU_OUTPUT_DPAD0] = {
.possible_crtcs = BIT(2),
.port = 0,
},
+ [RCAR_DU_OUTPUT_HDMI0] = {
+ .possible_crtcs = BIT(1),
+ .port = 1,
+ },
[RCAR_DU_OUTPUT_LVDS0] = {
.possible_crtcs = BIT(0),
.port = 2,
},
},
.num_lvds = 1,
+ .dpll_ch = BIT(1),
};
static const struct of_device_id rcar_du_of_table[] = {
@@ -238,8 +249,6 @@ static struct drm_driver rcar_du_driver = {
.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
.gem_prime_mmap = drm_gem_cma_prime_mmap,
.dumb_create = rcar_du_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.fops = &rcar_du_fops,
.name = "rcar-du",
.desc = "Renesas R-Car Display Unit",
@@ -341,7 +350,8 @@ static int rcar_du_probe(struct platform_device *pdev)
ddev->irq_enabled = 1;
- /* Register the DRM device with the core and the connectors with
+ /*
+ * Register the DRM device with the core and the connectors with
* sysfs.
*/
ret = drm_dev_register(ddev, 0);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
index 3e048dd98b64..ba8d2804c1d1 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
@@ -186,8 +186,8 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
}
if (enc_node) {
- dev_dbg(rcdu->dev, "initializing encoder %s for output %u\n",
- of_node_full_name(enc_node), output);
+ dev_dbg(rcdu->dev, "initializing encoder %pOF for output %u\n",
+ enc_node, output);
/* Locate the DRM bridge from the encoder DT node. */
bridge = of_drm_find_bridge(enc_node);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index 64738fca96d0..2f37ea901873 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -64,7 +64,8 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
if (rcdu->info->gen < 3) {
defr8 |= DEFR8_DEFE8;
- /* On Gen2 the DEFR8 register for the first group also controls
+ /*
+ * On Gen2 the DEFR8 register for the first group also controls
* RGB output routing to DPAD0 and VSPD1 routing to DU0/1/2 for
* DU instances that support it.
*/
@@ -75,7 +76,8 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
defr8 |= DEFR8_VSCS;
}
} else {
- /* On Gen3 VSPD routing can't be configured, but DPAD routing
+ /*
+ * On Gen3 VSPD routing can't be configured, but DPAD routing
* needs to be set despite having a single option available.
*/
u32 crtc = ffs(possible_crtcs) - 1;
@@ -124,7 +126,8 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
if (rcdu->info->gen >= 3)
rcar_du_group_write(rgrp, DEFR10, DEFR10_CODE | DEFR10_DEFE10);
- /* Use DS1PR and DS2PR to configure planes priorities and connects the
+ /*
+ * Use DS1PR and DS2PR to configure planes priorities and connects the
* superposition 0 to DU0 pins. DU1 pins will be configured dynamically.
*/
rcar_du_group_write(rgrp, DORCR, DORCR_PG1D_DS1 | DORCR_DPRS);
@@ -177,7 +180,8 @@ static void __rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
{
- /* Many of the configuration bits are only updated when the display
+ /*
+ * Many of the configuration bits are only updated when the display
* reset (DRES) bit in DSYSR is set to 1, disabling *both* CRTCs. Some
* of those bits could be pre-configured, but others (especially the
* bits related to plane assignment to display timing controllers) need
@@ -208,23 +212,32 @@ void rcar_du_group_restart(struct rcar_du_group *rgrp)
int rcar_du_set_dpad0_vsp1_routing(struct rcar_du_device *rcdu)
{
+ struct rcar_du_group *rgrp;
+ struct rcar_du_crtc *crtc;
+ unsigned int index;
int ret;
if (!rcar_du_has(rcdu, RCAR_DU_FEATURE_EXT_CTRL_REGS))
return 0;
- /* RGB output routing to DPAD0 and VSP1D routing to DU0/1/2 are
- * configured in the DEFR8 register of the first group. As this function
- * can be called with the DU0 and DU1 CRTCs disabled, we need to enable
- * the first group clock before accessing the register.
+ /*
+ * RGB output routing to DPAD0 and VSP1D routing to DU0/1/2 are
+ * configured in the DEFR8 register of the first group on Gen2 and the
+ * last group on Gen3. As this function can be called with the DU
+ * channels of the corresponding CRTCs disabled, we need to enable the
+ * group clock before accessing the register.
*/
- ret = clk_prepare_enable(rcdu->crtcs[0].clock);
+ index = rcdu->info->gen < 3 ? 0 : DIV_ROUND_UP(rcdu->num_crtcs, 2) - 1;
+ rgrp = &rcdu->groups[index];
+ crtc = &rcdu->crtcs[index * 2];
+
+ ret = clk_prepare_enable(crtc->clock);
if (ret < 0)
return ret;
- rcar_du_group_setup_defr8(&rcdu->groups[0]);
+ rcar_du_group_setup_defr8(rgrp);
- clk_disable_unprepare(rcdu->crtcs[0].clock);
+ clk_disable_unprepare(crtc->clock);
return 0;
}
@@ -236,7 +249,8 @@ int rcar_du_group_set_routing(struct rcar_du_group *rgrp)
dorcr &= ~(DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_MASK);
- /* Set the DPAD1 pins sources. Select CRTC 0 if explicitly requested and
+ /*
+ * Set the DPAD1 pins sources. Select CRTC 0 if explicitly requested and
* CRTC 1 in all other cases to avoid cloning CRTC 0 to DPAD0 and DPAD1
* by default.
*/
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index f4125c8ca902..7278b9703c15 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -96,7 +96,8 @@ static const struct rcar_du_format_info rcar_du_format_infos[] = {
.pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
.edf = PnDDCR4_EDF_NONE,
},
- /* The following formats are not supported on Gen2 and thus have no
+ /*
+ * The following formats are not supported on Gen2 and thus have no
* associated .pnmr or .edf settings.
*/
{
@@ -153,7 +154,8 @@ int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev,
unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
unsigned int align;
- /* The R8A7779 DU requires a 16 pixels pitch alignment as documented,
+ /*
+ * The R8A7779 DU requires a 16 pixels pitch alignment as documented,
* but the R8A7790 DU seems to require a 128 bytes pitch alignment.
*/
if (rcar_du_needs(rcdu, RCAR_DU_QUIRK_ALIGN_128B))
@@ -255,12 +257,12 @@ static void rcar_du_atomic_commit_tail(struct drm_atomic_state *old_state)
/* Apply the atomic update. */
drm_atomic_helper_commit_modeset_disables(dev, old_state);
- drm_atomic_helper_commit_modeset_enables(dev, old_state);
drm_atomic_helper_commit_planes(dev, old_state,
DRM_PLANE_COMMIT_ACTIVE_ONLY);
+ drm_atomic_helper_commit_modeset_enables(dev, old_state);
drm_atomic_helper_commit_hw_done(old_state);
- drm_atomic_helper_wait_for_vblanks(dev, old_state);
+ drm_atomic_helper_wait_for_flip_done(dev, old_state);
drm_atomic_helper_cleanup_planes(dev, old_state);
}
@@ -297,19 +299,19 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
*/
entity = of_graph_get_remote_port_parent(ep->local_node);
if (!entity) {
- dev_dbg(rcdu->dev, "unconnected endpoint %s, skipping\n",
- ep->local_node->full_name);
+ dev_dbg(rcdu->dev, "unconnected endpoint %pOF, skipping\n",
+ ep->local_node);
return -ENODEV;
}
if (!of_device_is_available(entity)) {
dev_dbg(rcdu->dev,
- "connected entity %s is disabled, skipping\n",
- entity->full_name);
+ "connected entity %pOF is disabled, skipping\n",
+ entity);
return -ENODEV;
}
- entity_ep_node = of_parse_phandle(ep->local_node, "remote-endpoint", 0);
+ entity_ep_node = of_graph_get_remote_endpoint(ep->local_node);
for_each_endpoint_of_node(entity, ep_node) {
if (ep_node == entity_ep_node)
@@ -325,8 +327,8 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
if (!connector) {
dev_warn(rcdu->dev,
- "no connector for encoder %s, skipping\n",
- encoder->full_name);
+ "no connector for encoder %pOF, skipping\n",
+ encoder);
of_node_put(entity_ep_node);
of_node_put(encoder);
return -ENODEV;
@@ -348,8 +350,8 @@ static int rcar_du_encoders_init_one(struct rcar_du_device *rcdu,
ret = rcar_du_encoder_init(rcdu, output, encoder, connector);
if (ret && ret != -EPROBE_DEFER)
dev_warn(rcdu->dev,
- "failed to initialize encoder %s on output %u (%d), skipping\n",
- of_node_full_name(encoder), output, ret);
+ "failed to initialize encoder %pOF on output %u (%d), skipping\n",
+ encoder, output, ret);
of_node_put(encoder);
of_node_put(connector);
@@ -419,7 +421,8 @@ static int rcar_du_properties_init(struct rcar_du_device *rcdu)
if (rcdu->props.alpha == NULL)
return -ENOMEM;
- /* The color key is expressed as an RGB888 triplet stored in a 32-bit
+ /*
+ * The color key is expressed as an RGB888 triplet stored in a 32-bit
* integer in XRGB8888 format. Bit 24 is used as a flag to disable (0)
* or enable source color keying (1).
*/
@@ -432,6 +435,81 @@ static int rcar_du_properties_init(struct rcar_du_device *rcdu)
return 0;
}
+static int rcar_du_vsps_init(struct rcar_du_device *rcdu)
+{
+ const struct device_node *np = rcdu->dev->of_node;
+ struct of_phandle_args args;
+ struct {
+ struct device_node *np;
+ unsigned int crtcs_mask;
+ } vsps[RCAR_DU_MAX_VSPS] = { { 0, }, };
+ unsigned int vsps_count = 0;
+ unsigned int cells;
+ unsigned int i;
+ int ret;
+
+ /*
+ * First parse the DT vsps property to populate the list of VSPs. Each
+ * entry contains a pointer to the VSP DT node and a bitmask of the
+ * connected DU CRTCs.
+ */
+ cells = of_property_count_u32_elems(np, "vsps") / rcdu->num_crtcs - 1;
+ if (cells > 1)
+ return -EINVAL;
+
+ for (i = 0; i < rcdu->num_crtcs; ++i) {
+ unsigned int j;
+
+ ret = of_parse_phandle_with_fixed_args(np, "vsps", cells, i,
+ &args);
+ if (ret < 0)
+ goto error;
+
+ /*
+ * Add the VSP to the list or update the corresponding existing
+ * entry if the VSP has already been added.
+ */
+ for (j = 0; j < vsps_count; ++j) {
+ if (vsps[j].np == args.np)
+ break;
+ }
+
+ if (j < vsps_count)
+ of_node_put(args.np);
+ else
+ vsps[vsps_count++].np = args.np;
+
+ vsps[j].crtcs_mask |= BIT(i);
+
+ /* Store the VSP pointer and pipe index in the CRTC. */
+ rcdu->crtcs[i].vsp = &rcdu->vsps[j];
+ rcdu->crtcs[i].vsp_pipe = cells >= 1 ? args.args[0] : 0;
+ }
+
+ /*
+ * Then initialize all the VSPs from the node pointers and CRTCs bitmask
+ * computed previously.
+ */
+ for (i = 0; i < vsps_count; ++i) {
+ struct rcar_du_vsp *vsp = &rcdu->vsps[i];
+
+ vsp->index = i;
+ vsp->dev = rcdu;
+
+ ret = rcar_du_vsp_init(vsp, vsps[i].np, vsps[i].crtcs_mask);
+ if (ret < 0)
+ goto error;
+ }
+
+ return 0;
+
+error:
+ for (i = 0; i < ARRAY_SIZE(vsps); ++i)
+ of_node_put(vsps[i].np);
+
+ return ret;
+}
+
int rcar_du_modeset_init(struct rcar_du_device *rcdu)
{
static const unsigned int mmio_offsets[] = {
@@ -461,7 +539,8 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
if (ret < 0)
return ret;
- /* Initialize vertical blanking interrupts handling. Start with vblank
+ /*
+ * Initialize vertical blanking interrupts handling. Start with vblank
* disabled for all CRTCs.
*/
ret = drm_vblank_init(dev, (1 << rcdu->info->num_crtcs) - 1);
@@ -481,7 +560,8 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
rgrp->index = i;
rgrp->num_crtcs = min(rcdu->num_crtcs - 2 * i, 2U);
- /* If we have more than one CRTCs in this group pre-associate
+ /*
+ * If we have more than one CRTCs in this group pre-associate
* the low-order planes with CRTC 0 and the high-order planes
* with CRTC 1 to minimize flicker occurring when the
* association is changed.
@@ -499,17 +579,9 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
/* Initialize the compositors. */
if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) {
- for (i = 0; i < rcdu->num_crtcs; ++i) {
- struct rcar_du_vsp *vsp = &rcdu->vsps[i];
-
- vsp->index = i;
- vsp->dev = rcdu;
- rcdu->crtcs[i].vsp = vsp;
-
- ret = rcar_du_vsp_init(vsp);
- if (ret < 0)
- return ret;
- }
+ ret = rcar_du_vsps_init(rcdu);
+ if (ret < 0)
+ return ret;
}
/* Create the CRTCs. */
@@ -537,7 +609,8 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
num_encoders = ret;
- /* Set the possible CRTCs and possible clones. There's always at least
+ /*
+ * Set the possible CRTCs and possible clones. There's always at least
* one way for all encoders to clone each other, set all bits in the
* possible clones field.
*/
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
index ee91481131ad..b373ad48ef5f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c
@@ -46,7 +46,6 @@ static void rcar_du_lvds_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = rcar_du_lvds_connector_destroy,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c
index 1661f6201210..12d22f3db1af 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c
@@ -59,7 +59,8 @@ static void rcar_du_lvdsenc_start_gen2(struct rcar_du_lvdsenc *lvds,
rcar_lvds_write(lvds, LVDPLLCR, pllcr);
- /* Select the input, hardcode mode 0, enable LVDS operation and turn
+ /*
+ * Select the input, hardcode mode 0, enable LVDS operation and turn
* bias circuitry on.
*/
lvdcr0 = (lvds->mode << LVDCR0_LVMD_SHIFT) | LVDCR0_BEN | LVDCR0_LVEN;
@@ -73,7 +74,8 @@ static void rcar_du_lvdsenc_start_gen2(struct rcar_du_lvdsenc *lvds,
LVDCR1_CHSTBY_GEN2(1) | LVDCR1_CHSTBY_GEN2(0) |
LVDCR1_CLKSTBY_GEN2);
- /* Turn the PLL on, wait for the startup delay, and turn the output
+ /*
+ * Turn the PLL on, wait for the startup delay, and turn the output
* on.
*/
lvdcr0 |= LVDCR0_PLLON;
@@ -140,7 +142,8 @@ static int rcar_du_lvdsenc_start(struct rcar_du_lvdsenc *lvds,
if (ret < 0)
return ret;
- /* Hardcode the channels and control signals routing for now.
+ /*
+ * Hardcode the channels and control signals routing for now.
*
* HSYNC -> CTRL0
* VSYNC -> CTRL1
@@ -202,7 +205,8 @@ void rcar_du_lvdsenc_atomic_check(struct rcar_du_lvdsenc *lvds,
{
struct rcar_du_device *rcdu = lvds->dev;
- /* The internal LVDS encoder has a restricted clock frequency operating
+ /*
+ * The internal LVDS encoder has a restricted clock frequency operating
* range (30MHz to 150MHz on Gen2, 25.175MHz to 148.5MHz on Gen3). Clamp
* the clock accordingly.
*/
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index dcde6288da6c..61833cc1c699 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -50,23 +50,21 @@
* automatically when the core swaps the old and new states.
*/
-static bool rcar_du_plane_needs_realloc(struct rcar_du_plane *plane,
- struct rcar_du_plane_state *new_state)
+static bool rcar_du_plane_needs_realloc(
+ const struct rcar_du_plane_state *old_state,
+ const struct rcar_du_plane_state *new_state)
{
- struct rcar_du_plane_state *cur_state;
-
- cur_state = to_rcar_plane_state(plane->plane.state);
-
- /* Lowering the number of planes doesn't strictly require reallocation
+ /*
+ * Lowering the number of planes doesn't strictly require reallocation
* as the extra hardware plane will be freed when committing, but doing
* so could lead to more fragmentation.
*/
- if (!cur_state->format ||
- cur_state->format->planes != new_state->format->planes)
+ if (!old_state->format ||
+ old_state->format->planes != new_state->format->planes)
return true;
/* Reallocate hardware planes if the source has changed. */
- if (cur_state->source != new_state->source)
+ if (old_state->source != new_state->source)
return true;
return false;
@@ -141,37 +139,43 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
unsigned int groups = 0;
unsigned int i;
struct drm_plane *drm_plane;
- struct drm_plane_state *drm_plane_state;
+ struct drm_plane_state *old_drm_plane_state;
+ struct drm_plane_state *new_drm_plane_state;
/* Check if hardware planes need to be reallocated. */
- for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
- struct rcar_du_plane_state *plane_state;
+ for_each_oldnew_plane_in_state(state, drm_plane, old_drm_plane_state,
+ new_drm_plane_state, i) {
+ struct rcar_du_plane_state *old_plane_state;
+ struct rcar_du_plane_state *new_plane_state;
struct rcar_du_plane *plane;
unsigned int index;
plane = to_rcar_plane(drm_plane);
- plane_state = to_rcar_plane_state(drm_plane_state);
+ old_plane_state = to_rcar_plane_state(old_drm_plane_state);
+ new_plane_state = to_rcar_plane_state(new_drm_plane_state);
dev_dbg(rcdu->dev, "%s: checking plane (%u,%tu)\n", __func__,
plane->group->index, plane - plane->group->planes);
- /* If the plane is being disabled we don't need to go through
+ /*
+ * If the plane is being disabled we don't need to go through
* the full reallocation procedure. Just mark the hardware
* plane(s) as freed.
*/
- if (!plane_state->format) {
+ if (!new_plane_state->format) {
dev_dbg(rcdu->dev, "%s: plane is being disabled\n",
__func__);
index = plane - plane->group->planes;
group_freed_planes[plane->group->index] |= 1 << index;
- plane_state->hwindex = -1;
+ new_plane_state->hwindex = -1;
continue;
}
- /* If the plane needs to be reallocated mark it as such, and
+ /*
+ * If the plane needs to be reallocated mark it as such, and
* mark the hardware plane(s) as free.
*/
- if (rcar_du_plane_needs_realloc(plane, plane_state)) {
+ if (rcar_du_plane_needs_realloc(old_plane_state, new_plane_state)) {
dev_dbg(rcdu->dev, "%s: plane needs reallocation\n",
__func__);
groups |= 1 << plane->group->index;
@@ -179,14 +183,15 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
index = plane - plane->group->planes;
group_freed_planes[plane->group->index] |= 1 << index;
- plane_state->hwindex = -1;
+ new_plane_state->hwindex = -1;
}
}
if (!needs_realloc)
return 0;
- /* Grab all plane states for the groups that need reallocation to ensure
+ /*
+ * Grab all plane states for the groups that need reallocation to ensure
* locking and avoid racy updates. This serializes the update operation,
* but there's not much we can do about it as that's the hardware
* design.
@@ -204,14 +209,15 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
for (i = 0; i < group->num_planes; ++i) {
struct rcar_du_plane *plane = &group->planes[i];
- struct rcar_du_plane_state *plane_state;
+ struct rcar_du_plane_state *new_plane_state;
struct drm_plane_state *s;
s = drm_atomic_get_plane_state(state, &plane->plane);
if (IS_ERR(s))
return PTR_ERR(s);
- /* If the plane has been freed in the above loop its
+ /*
+ * If the plane has been freed in the above loop its
* hardware planes must not be added to the used planes
* bitmask. However, the current state doesn't reflect
* the free state yet, as we've modified the new state
@@ -226,16 +232,16 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
continue;
}
- plane_state = to_rcar_plane_state(plane->plane.state);
- used_planes |= rcar_du_plane_hwmask(plane_state);
+ new_plane_state = to_rcar_plane_state(s);
+ used_planes |= rcar_du_plane_hwmask(new_plane_state);
dev_dbg(rcdu->dev,
"%s: plane (%u,%tu) uses %u hwplanes (index %d)\n",
__func__, plane->group->index,
plane - plane->group->planes,
- plane_state->format ?
- plane_state->format->planes : 0,
- plane_state->hwindex);
+ new_plane_state->format ?
+ new_plane_state->format->planes : 0,
+ new_plane_state->hwindex);
}
group_free_planes[index] = 0xff & ~used_planes;
@@ -246,40 +252,45 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
}
/* Reallocate hardware planes for each plane that needs it. */
- for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
- struct rcar_du_plane_state *plane_state;
+ for_each_oldnew_plane_in_state(state, drm_plane, old_drm_plane_state,
+ new_drm_plane_state, i) {
+ struct rcar_du_plane_state *old_plane_state;
+ struct rcar_du_plane_state *new_plane_state;
struct rcar_du_plane *plane;
unsigned int crtc_planes;
unsigned int free;
int idx;
plane = to_rcar_plane(drm_plane);
- plane_state = to_rcar_plane_state(drm_plane_state);
+ old_plane_state = to_rcar_plane_state(old_drm_plane_state);
+ new_plane_state = to_rcar_plane_state(new_drm_plane_state);
dev_dbg(rcdu->dev, "%s: allocating plane (%u,%tu)\n", __func__,
plane->group->index, plane - plane->group->planes);
- /* Skip planes that are being disabled or don't need to be
+ /*
+ * Skip planes that are being disabled or don't need to be
* reallocated.
*/
- if (!plane_state->format ||
- !rcar_du_plane_needs_realloc(plane, plane_state))
+ if (!new_plane_state->format ||
+ !rcar_du_plane_needs_realloc(old_plane_state, new_plane_state))
continue;
- /* Try to allocate the plane from the free planes currently
+ /*
+ * Try to allocate the plane from the free planes currently
* associated with the target CRTC to avoid restarting the CRTC
* group and thus minimize flicker. If it fails fall back to
* allocating from all free planes.
*/
- crtc_planes = to_rcar_crtc(plane_state->state.crtc)->index % 2
+ crtc_planes = to_rcar_crtc(new_plane_state->state.crtc)->index % 2
? plane->group->dptsr_planes
: ~plane->group->dptsr_planes;
free = group_free_planes[plane->group->index];
- idx = rcar_du_plane_hwalloc(plane, plane_state,
+ idx = rcar_du_plane_hwalloc(plane, new_plane_state,
free & crtc_planes);
if (idx < 0)
- idx = rcar_du_plane_hwalloc(plane, plane_state,
+ idx = rcar_du_plane_hwalloc(plane, new_plane_state,
free);
if (idx < 0) {
dev_dbg(rcdu->dev, "%s: no available hardware plane\n",
@@ -288,12 +299,12 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
}
dev_dbg(rcdu->dev, "%s: allocated %u hwplanes (index %u)\n",
- __func__, plane_state->format->planes, idx);
+ __func__, new_plane_state->format->planes, idx);
- plane_state->hwindex = idx;
+ new_plane_state->hwindex = idx;
group_free_planes[plane->group->index] &=
- ~rcar_du_plane_hwmask(plane_state);
+ ~rcar_du_plane_hwmask(new_plane_state);
dev_dbg(rcdu->dev, "%s: group %u free planes mask 0x%02x\n",
__func__, plane->group->index,
@@ -351,14 +362,16 @@ static void rcar_du_plane_setup_scanout(struct rcar_du_group *rgrp,
dma[1] = 0;
}
- /* Memory pitch (expressed in pixels). Must be doubled for interlaced
+ /*
+ * Memory pitch (expressed in pixels). Must be doubled for interlaced
* operation with 32bpp formats.
*/
rcar_du_plane_write(rgrp, index, PnMWR,
(interlaced && state->format->bpp == 32) ?
pitch * 2 : pitch);
- /* The Y position is expressed in raster line units and must be doubled
+ /*
+ * The Y position is expressed in raster line units and must be doubled
* for 32bpp formats, according to the R8A7790 datasheet. No mention of
* doubling the Y position is found in the R8A7779 datasheet, but the
* rule seems to apply there as well.
@@ -396,7 +409,8 @@ static void rcar_du_plane_setup_mode(struct rcar_du_group *rgrp,
u32 colorkey;
u32 pnmr;
- /* The PnALPHAR register controls alpha-blending in 16bpp formats
+ /*
+ * The PnALPHAR register controls alpha-blending in 16bpp formats
* (ARGB1555 and XRGB1555).
*
* For ARGB, set the alpha value to 0, and enable alpha-blending when
@@ -413,7 +427,8 @@ static void rcar_du_plane_setup_mode(struct rcar_du_group *rgrp,
pnmr = PnMR_BM_MD | state->format->pnmr;
- /* Disable color keying when requested. YUV formats have the
+ /*
+ * Disable color keying when requested. YUV formats have the
* PnMR_SPIM_TP_OFF bit set in their pnmr field, disabling color keying
* automatically.
*/
@@ -457,7 +472,8 @@ static void rcar_du_plane_setup_format_gen2(struct rcar_du_group *rgrp,
u32 ddcr2 = PnDDCR2_CODE;
u32 ddcr4;
- /* Data format
+ /*
+ * Data format
*
* The data format is selected by the DDDF field in PnMR and the EDF
* field in DDCR4.
@@ -589,7 +605,8 @@ static void rcar_du_plane_atomic_update(struct drm_plane *plane,
rcar_du_plane_setup(rplane);
- /* Check whether the source has changed from memory to live source or
+ /*
+ * Check whether the source has changed from memory to live source or
* from live source to memory. The source has been configured by the
* VSPS bit in the PnDDCR4 register. Although the datasheet states that
* the bit is updated during vertical blanking, it seems that updates
@@ -698,7 +715,6 @@ static const struct drm_plane_funcs rcar_du_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.reset = rcar_du_plane_reset,
- .set_property = drm_atomic_helper_plane_set_property,
.destroy = drm_plane_cleanup,
.atomic_duplicate_state = rcar_du_plane_atomic_duplicate_state,
.atomic_destroy_state = rcar_du_plane_atomic_destroy_state,
@@ -726,7 +742,8 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp)
unsigned int i;
int ret;
- /* Create one primary plane per CRTC in this group and seven overlay
+ /*
+ * Create one primary plane per CRTC in this group and seven overlay
* planes.
*/
rgrp->num_planes = rgrp->num_crtcs + 7;
@@ -743,8 +760,8 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp)
ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs,
&rcar_du_plane_funcs, formats,
- ARRAY_SIZE(formats), type,
- NULL);
+ ARRAY_SIZE(formats),
+ NULL, type, NULL);
if (ret < 0)
return ret;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
index 8b91dd3a46e4..f62e09f195de 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
@@ -20,7 +20,8 @@
struct rcar_du_format_info;
struct rcar_du_group;
-/* The RCAR DU has 8 hardware planes, shared between primary and overlay planes.
+/*
+ * The RCAR DU has 8 hardware planes, shared between primary and overlay planes.
* As using overlay planes requires at least one of the CRTCs being enabled, no
* more than 7 overlay planes can be available. We thus create 1 primary plane
* per CRTC and 7 overlay planes, for a total of up to 9 KMS planes.
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index f870445ebc8d..2c96147bc444 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -19,6 +19,7 @@
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_plane_helper.h>
+#include <linux/bitops.h>
#include <linux/dma-mapping.h>
#include <linux/of_platform.h>
#include <linux/scatterlist.h>
@@ -30,11 +31,15 @@
#include "rcar_du_kms.h"
#include "rcar_du_vsp.h"
-static void rcar_du_vsp_complete(void *private)
+static void rcar_du_vsp_complete(void *private, bool completed)
{
struct rcar_du_crtc *crtc = private;
- rcar_du_crtc_finish_page_flip(crtc);
+ if (crtc->vblank_enable)
+ drm_crtc_handle_vblank(&crtc->crtc);
+
+ if (completed)
+ rcar_du_crtc_finish_page_flip(crtc);
}
void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
@@ -73,7 +78,8 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
__rcar_du_plane_setup(crtc->group, &state);
- /* Ensure that the plane source configuration takes effect by requesting
+ /*
+ * Ensure that the plane source configuration takes effect by requesting
* a restart of the group. See rcar_du_plane_atomic_update() for a more
* detailed explanation.
*
@@ -81,22 +87,22 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
*/
crtc->group->need_restart = true;
- vsp1_du_setup_lif(crtc->vsp->vsp, &cfg);
+ vsp1_du_setup_lif(crtc->vsp->vsp, crtc->vsp_pipe, &cfg);
}
void rcar_du_vsp_disable(struct rcar_du_crtc *crtc)
{
- vsp1_du_setup_lif(crtc->vsp->vsp, NULL);
+ vsp1_du_setup_lif(crtc->vsp->vsp, crtc->vsp_pipe, NULL);
}
void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc)
{
- vsp1_du_atomic_begin(crtc->vsp->vsp);
+ vsp1_du_atomic_begin(crtc->vsp->vsp, crtc->vsp_pipe);
}
void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc)
{
- vsp1_du_atomic_flush(crtc->vsp->vsp);
+ vsp1_du_atomic_flush(crtc->vsp->vsp, crtc->vsp_pipe);
}
/* Keep the two tables in sync. */
@@ -162,6 +168,7 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
{
struct rcar_du_vsp_plane_state *state =
to_rcar_vsp_plane_state(plane->plane.state);
+ struct rcar_du_crtc *crtc = to_rcar_crtc(state->state.crtc);
struct drm_framebuffer *fb = plane->plane.state->fb;
struct vsp1_du_atomic_config cfg = {
.pixelformat = 0,
@@ -192,7 +199,8 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
}
}
- vsp1_du_atomic_update(plane->vsp->vsp, plane->index, &cfg);
+ vsp1_du_atomic_update(plane->vsp->vsp, crtc->vsp_pipe,
+ plane->index, &cfg);
}
static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
@@ -288,11 +296,13 @@ static void rcar_du_vsp_plane_atomic_update(struct drm_plane *plane,
struct drm_plane_state *old_state)
{
struct rcar_du_vsp_plane *rplane = to_rcar_vsp_plane(plane);
+ struct rcar_du_crtc *crtc = to_rcar_crtc(old_state->crtc);
if (plane->state->crtc)
rcar_du_vsp_plane_setup(rplane);
else
- vsp1_du_atomic_update(rplane->vsp->vsp, rplane->index, NULL);
+ vsp1_du_atomic_update(rplane->vsp->vsp, crtc->vsp_pipe,
+ rplane->index, NULL);
}
static const struct drm_plane_helper_funcs rcar_du_vsp_plane_helper_funcs = {
@@ -383,7 +393,6 @@ static const struct drm_plane_funcs rcar_du_vsp_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.reset = rcar_du_vsp_plane_reset,
- .set_property = drm_atomic_helper_plane_set_property,
.destroy = drm_plane_cleanup,
.atomic_duplicate_state = rcar_du_vsp_plane_atomic_duplicate_state,
.atomic_destroy_state = rcar_du_vsp_plane_atomic_destroy_state,
@@ -391,23 +400,17 @@ static const struct drm_plane_funcs rcar_du_vsp_plane_funcs = {
.atomic_get_property = rcar_du_vsp_plane_atomic_get_property,
};
-int rcar_du_vsp_init(struct rcar_du_vsp *vsp)
+int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
+ unsigned int crtcs)
{
struct rcar_du_device *rcdu = vsp->dev;
struct platform_device *pdev;
- struct device_node *np;
+ unsigned int num_crtcs = hweight32(crtcs);
unsigned int i;
int ret;
/* Find the VSP device and initialize it. */
- np = of_parse_phandle(rcdu->dev->of_node, "vsps", vsp->index);
- if (!np) {
- dev_err(rcdu->dev, "vsps node not found\n");
- return -ENXIO;
- }
-
pdev = of_find_device_by_node(np);
- of_node_put(np);
if (!pdev)
return -ENXIO;
@@ -417,7 +420,8 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp)
if (ret < 0)
return ret;
- /* The VSP2D (Gen3) has 5 RPFs, but the VSP1D (Gen2) is limited to
+ /*
+ * The VSP2D (Gen3) has 5 RPFs, but the VSP1D (Gen2) is limited to
* 4 RPFs.
*/
vsp->num_planes = rcdu->info->gen >= 3 ? 5 : 4;
@@ -428,19 +432,19 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp)
return -ENOMEM;
for (i = 0; i < vsp->num_planes; ++i) {
- enum drm_plane_type type = i ? DRM_PLANE_TYPE_OVERLAY
- : DRM_PLANE_TYPE_PRIMARY;
+ enum drm_plane_type type = i < num_crtcs
+ ? DRM_PLANE_TYPE_PRIMARY
+ : DRM_PLANE_TYPE_OVERLAY;
struct rcar_du_vsp_plane *plane = &vsp->planes[i];
plane->vsp = vsp;
plane->index = i;
- ret = drm_universal_plane_init(rcdu->ddev, &plane->plane,
- 1 << vsp->index,
+ ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs,
&rcar_du_vsp_plane_funcs,
formats_kms,
- ARRAY_SIZE(formats_kms), type,
- NULL);
+ ARRAY_SIZE(formats_kms),
+ NULL, type, NULL);
if (ret < 0)
return ret;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
index 8861661590ff..f876c512163c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
@@ -64,13 +64,19 @@ to_rcar_vsp_plane_state(struct drm_plane_state *state)
}
#ifdef CONFIG_DRM_RCAR_VSP
-int rcar_du_vsp_init(struct rcar_du_vsp *vsp);
+int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
+ unsigned int crtcs);
void rcar_du_vsp_enable(struct rcar_du_crtc *crtc);
void rcar_du_vsp_disable(struct rcar_du_crtc *crtc);
void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc);
void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc);
#else
-static inline int rcar_du_vsp_init(struct rcar_du_vsp *vsp) { return -ENXIO; };
+static inline int rcar_du_vsp_init(struct rcar_du_vsp *vsp,
+ struct device_node *np,
+ unsigned int crtcs)
+{
+ return -ENXIO;
+}
static inline void rcar_du_vsp_enable(struct rcar_du_crtc *crtc) { };
static inline void rcar_du_vsp_disable(struct rcar_du_crtc *crtc) { };
static inline void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc) { };
diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
index 7539626b8ebd..dc85b53d58ef 100644
--- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
+++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
@@ -45,7 +45,7 @@ static int rcar_hdmi_phy_configure(struct dw_hdmi *hdmi,
{
const struct rcar_hdmi_phy_params *params = rcar_hdmi_phy_params;
- for (; params && params->mpixelclock != ~0UL; ++params) {
+ for (; params->mpixelclock != ~0UL; ++params) {
if (mpixelclock <= params->mpixelclock)
break;
}
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 50c41c0a50ef..dcc539ba85d6 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -5,6 +5,10 @@ config DRM_ROCKCHIP
select DRM_KMS_HELPER
select DRM_PANEL
select VIDEOMODE_HELPERS
+ select DRM_ANALOGIX_DP if ROCKCHIP_ANALOGIX_DP
+ select DRM_DW_HDMI if ROCKCHIP_DW_HDMI
+ select DRM_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
+ select SND_SOC_HDMI_CODEC if ROCKCHIP_CDN_DP && SND_SOC
help
Choose this option if you have a Rockchip soc chipset.
This driver provides kernel mode setting and buffer
@@ -12,10 +16,10 @@ config DRM_ROCKCHIP
2D or 3D acceleration; acceleration is performed by other
IP found on the SoC.
+if DRM_ROCKCHIP
+
config ROCKCHIP_ANALOGIX_DP
bool "Rockchip specific extensions for Analogix DP driver"
- depends on DRM_ROCKCHIP
- select DRM_ANALOGIX_DP
help
This selects support for Rockchip SoC specific extensions
for the Analogix Core DP driver. If you want to enable DP
@@ -23,9 +27,7 @@ config ROCKCHIP_ANALOGIX_DP
config ROCKCHIP_CDN_DP
bool "Rockchip cdn DP"
- depends on DRM_ROCKCHIP
- depends on EXTCON
- select SND_SOC_HDMI_CODEC if SND_SOC
+ depends on EXTCON=y || (EXTCON=m && DRM_ROCKCHIP=m)
help
This selects support for Rockchip SoC specific extensions
for the cdn DP driver. If you want to enable Dp on
@@ -34,8 +36,6 @@ config ROCKCHIP_CDN_DP
config ROCKCHIP_DW_HDMI
bool "Rockchip specific extensions for Synopsys DW HDMI"
- depends on DRM_ROCKCHIP
- select DRM_DW_HDMI
help
This selects support for Rockchip SoC specific extensions
for the Synopsys DesignWare HDMI driver. If you want to
@@ -44,8 +44,6 @@ config ROCKCHIP_DW_HDMI
config ROCKCHIP_DW_MIPI_DSI
bool "Rockchip specific extensions for Synopsys DW MIPI DSI"
- depends on DRM_ROCKCHIP
- select DRM_MIPI_DSI
help
This selects support for Rockchip SoC specific extensions
for the Synopsys DesignWare HDMI driver. If you want to
@@ -54,8 +52,9 @@ config ROCKCHIP_DW_MIPI_DSI
config ROCKCHIP_INNO_HDMI
bool "Rockchip specific extensions for Innosilicon HDMI"
- depends on DRM_ROCKCHIP
help
This selects support for Rockchip SoC specific extensions
for the Innosilicon HDMI driver. If you want to enable
HDMI on RK3036 based SoC, you should select this option.
+
+endif
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 9b0b0588bbed..a57da051f516 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -254,7 +254,6 @@ static void cdn_dp_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs cdn_dp_atomic_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = cdn_dp_connector_detect,
.destroy = cdn_dp_connector_destroy,
.fill_modes = drm_helper_probe_single_connector_modes,
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 21b9737662ae..9a20b9dc27c8 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -1080,7 +1080,6 @@ static void dw_mipi_dsi_drm_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs dw_mipi_dsi_atomic_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = dw_mipi_dsi_drm_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index f8208489724e..ccd5d595ada7 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -7,10 +7,12 @@
* (at your option) any later version.
*/
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
+
#include <drm/drm_of.h>
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
@@ -20,13 +22,32 @@
#include "rockchip_drm_drv.h"
#include "rockchip_drm_vop.h"
-#define GRF_SOC_CON6 0x025c
-#define HDMI_SEL_VOP_LIT (1 << 4)
+#define RK3288_GRF_SOC_CON6 0x025C
+#define RK3288_HDMI_LCDC_SEL BIT(4)
+#define RK3399_GRF_SOC_CON20 0x6250
+#define RK3399_HDMI_LCDC_SEL BIT(6)
+
+#define HIWORD_UPDATE(val, mask) (val | (mask) << 16)
+
+/**
+ * struct rockchip_hdmi_chip_data - splite the grf setting of kind of chips
+ * @lcdsel_grf_reg: grf register offset of lcdc select
+ * @lcdsel_big: reg value of selecting vop big for HDMI
+ * @lcdsel_lit: reg value of selecting vop little for HDMI
+ */
+struct rockchip_hdmi_chip_data {
+ u32 lcdsel_grf_reg;
+ u32 lcdsel_big;
+ u32 lcdsel_lit;
+};
struct rockchip_hdmi {
struct device *dev;
struct regmap *regmap;
struct drm_encoder encoder;
+ const struct rockchip_hdmi_chip_data *chip_data;
+ struct clk *vpll_clk;
+ struct clk *grf_clk;
};
#define to_rockchip_hdmi(x) container_of(x, struct rockchip_hdmi, x)
@@ -143,6 +164,7 @@ static const struct dw_hdmi_phy_config rockchip_phy_config[] = {
static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
{
struct device_node *np = hdmi->dev->of_node;
+ int ret;
hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
if (IS_ERR(hdmi->regmap)) {
@@ -150,6 +172,32 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
return PTR_ERR(hdmi->regmap);
}
+ hdmi->vpll_clk = devm_clk_get(hdmi->dev, "vpll");
+ if (PTR_ERR(hdmi->vpll_clk) == -ENOENT) {
+ hdmi->vpll_clk = NULL;
+ } else if (PTR_ERR(hdmi->vpll_clk) == -EPROBE_DEFER) {
+ return -EPROBE_DEFER;
+ } else if (IS_ERR(hdmi->vpll_clk)) {
+ dev_err(hdmi->dev, "failed to get grf clock\n");
+ return PTR_ERR(hdmi->vpll_clk);
+ }
+
+ hdmi->grf_clk = devm_clk_get(hdmi->dev, "grf");
+ if (PTR_ERR(hdmi->grf_clk) == -ENOENT) {
+ hdmi->grf_clk = NULL;
+ } else if (PTR_ERR(hdmi->grf_clk) == -EPROBE_DEFER) {
+ return -EPROBE_DEFER;
+ } else if (IS_ERR(hdmi->grf_clk)) {
+ dev_err(hdmi->dev, "failed to get grf clock\n");
+ return PTR_ERR(hdmi->grf_clk);
+ }
+
+ ret = clk_prepare_enable(hdmi->vpll_clk);
+ if (ret) {
+ dev_err(hdmi->dev, "Failed to enable HDMI vpll: %d\n", ret);
+ return ret;
+ }
+
return 0;
}
@@ -192,23 +240,36 @@ static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adj_mode)
{
+ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
+
+ clk_set_rate(hdmi->vpll_clk, adj_mode->clock * 1000);
}
static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
{
struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
u32 val;
- int mux;
+ int ret;
- mux = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder);
- if (mux)
- val = HDMI_SEL_VOP_LIT | (HDMI_SEL_VOP_LIT << 16);
+ ret = drm_of_encoder_active_endpoint_id(hdmi->dev->of_node, encoder);
+ if (ret)
+ val = hdmi->chip_data->lcdsel_lit;
else
- val = HDMI_SEL_VOP_LIT << 16;
+ val = hdmi->chip_data->lcdsel_big;
- regmap_write(hdmi->regmap, GRF_SOC_CON6, val);
+ ret = clk_prepare_enable(hdmi->grf_clk);
+ if (ret < 0) {
+ dev_err(hdmi->dev, "failed to enable grfclk %d\n", ret);
+ return;
+ }
+
+ ret = regmap_write(hdmi->regmap, hdmi->chip_data->lcdsel_grf_reg, val);
+ if (ret != 0)
+ dev_err(hdmi->dev, "Could not write to GRF: %d\n", ret);
+
+ clk_disable_unprepare(hdmi->grf_clk);
dev_dbg(hdmi->dev, "vop %s output to hdmi\n",
- (mux) ? "LIT" : "BIG");
+ ret ? "LIT" : "BIG");
}
static int
@@ -232,16 +293,40 @@ static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_fun
.atomic_check = dw_hdmi_rockchip_encoder_atomic_check,
};
-static const struct dw_hdmi_plat_data rockchip_hdmi_drv_data = {
+static struct rockchip_hdmi_chip_data rk3288_chip_data = {
+ .lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
+ .lcdsel_big = HIWORD_UPDATE(0, RK3288_HDMI_LCDC_SEL),
+ .lcdsel_lit = HIWORD_UPDATE(RK3288_HDMI_LCDC_SEL, RK3288_HDMI_LCDC_SEL),
+};
+
+static const struct dw_hdmi_plat_data rk3288_hdmi_drv_data = {
.mode_valid = dw_hdmi_rockchip_mode_valid,
.mpll_cfg = rockchip_mpll_cfg,
.cur_ctr = rockchip_cur_ctr,
.phy_config = rockchip_phy_config,
+ .phy_data = &rk3288_chip_data,
+};
+
+static struct rockchip_hdmi_chip_data rk3399_chip_data = {
+ .lcdsel_grf_reg = RK3399_GRF_SOC_CON20,
+ .lcdsel_big = HIWORD_UPDATE(0, RK3399_HDMI_LCDC_SEL),
+ .lcdsel_lit = HIWORD_UPDATE(RK3399_HDMI_LCDC_SEL, RK3399_HDMI_LCDC_SEL),
+};
+
+static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = {
+ .mode_valid = dw_hdmi_rockchip_mode_valid,
+ .mpll_cfg = rockchip_mpll_cfg,
+ .cur_ctr = rockchip_cur_ctr,
+ .phy_config = rockchip_phy_config,
+ .phy_data = &rk3399_chip_data,
};
static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = {
{ .compatible = "rockchip,rk3288-dw-hdmi",
- .data = &rockchip_hdmi_drv_data
+ .data = &rk3288_hdmi_drv_data
+ },
+ { .compatible = "rockchip,rk3399-dw-hdmi",
+ .data = &rk3399_hdmi_drv_data
},
{},
};
@@ -268,6 +353,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
match = of_match_node(dw_hdmi_rockchip_dt_ids, pdev->dev.of_node);
plat_data = match->data;
hdmi->dev = &pdev->dev;
+ hdmi->chip_data = plat_data->phy_data;
encoder = &hdmi->encoder;
encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 7d9b75eb6c44..7a251a54e792 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -294,7 +294,7 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
union hdmi_infoframe frame;
int rc;
- rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode);
+ rc = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false);
if (hdmi->hdmi_data.enc_out_format == HDMI_COLORSPACE_YUV444)
frame.avi.colorspace = HDMI_COLORSPACE_YUV444;
@@ -592,8 +592,7 @@ static void inno_hdmi_connector_destroy(struct drm_connector *connector)
drm_connector_cleanup(connector);
}
-static struct drm_connector_funcs inno_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
+static const struct drm_connector_funcs inno_hdmi_connector_funcs = {
.fill_modes = inno_hdmi_probe_single_connector_modes,
.detect = inno_hdmi_connector_detect,
.destroy = inno_hdmi_connector_destroy,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index c6b1b7f3a2a3..c41f48ae7913 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -161,23 +161,21 @@ static int rockchip_drm_bind(struct device *dev)
*/
drm_dev->irq_enabled = true;
- /* init kms poll for handling hpd */
- drm_kms_helper_poll_init(drm_dev);
-
ret = rockchip_drm_fbdev_init(drm_dev);
if (ret)
- goto err_kms_helper_poll_fini;
+ goto err_unbind_all;
+
+ /* init kms poll for handling hpd */
+ drm_kms_helper_poll_init(drm_dev);
ret = drm_dev_register(drm_dev, 0);
if (ret)
- goto err_fbdev_fini;
+ goto err_kms_helper_poll_fini;
return 0;
-err_fbdev_fini:
- rockchip_drm_fbdev_fini(drm_dev);
err_kms_helper_poll_fini:
drm_kms_helper_poll_fini(drm_dev);
- drm_vblank_cleanup(drm_dev);
+ rockchip_drm_fbdev_fini(drm_dev);
err_unbind_all:
component_unbind_all(dev, drm_dev);
err_mode_config_cleanup:
@@ -200,7 +198,6 @@ static void rockchip_drm_unbind(struct device *dev)
drm_kms_helper_poll_fini(drm_dev);
drm_atomic_helper_shutdown(drm_dev);
- drm_vblank_cleanup(drm_dev);
component_unbind_all(dev, drm_dev);
drm_mode_config_cleanup(drm_dev);
rockchip_iommu_cleanup(drm_dev);
@@ -235,8 +232,6 @@ static struct drm_driver rockchip_drm_driver = {
.gem_vm_ops = &drm_gem_cma_vm_ops,
.gem_free_object_unlocked = rockchip_gem_free_object,
.dumb_create = rockchip_gem_dumb_create,
- .dumb_map_offset = rockchip_gem_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import = drm_gem_prime_import,
@@ -370,8 +365,8 @@ static int rockchip_drm_platform_of_probe(struct device *dev)
iommu = of_parse_phandle(port->parent, "iommus", 0);
if (!iommu || !of_device_is_available(iommu->parent)) {
- dev_dbg(dev, "no iommu attached for %s, using non-iommu buffers\n",
- port->parent->full_name);
+ dev_dbg(dev, "no iommu attached for %pOF, using non-iommu buffers\n",
+ port->parent);
/*
* if there is a crtc not support iommu, force set all
* crtc use non-iommu buffer.
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 81f9548672b0..70773041785b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -48,7 +48,7 @@ static void rockchip_drm_fb_destroy(struct drm_framebuffer *fb)
int i;
for (i = 0; i < ROCKCHIP_MAX_FB_BUFFER; i++)
- drm_gem_object_unreference_unlocked(rockchip_fb->obj[i]);
+ drm_gem_object_put_unlocked(rockchip_fb->obj[i]);
drm_framebuffer_cleanup(fb);
kfree(rockchip_fb);
@@ -144,7 +144,7 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
width * drm_format_plane_cpp(mode_cmd->pixel_format, i);
if (obj->size < min_size) {
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
ret = -EINVAL;
goto err_gem_object_unreference;
}
@@ -161,40 +161,19 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
err_gem_object_unreference:
for (i--; i >= 0; i--)
- drm_gem_object_unreference_unlocked(objs[i]);
+ drm_gem_object_put_unlocked(objs[i]);
return ERR_PTR(ret);
}
static void rockchip_drm_output_poll_changed(struct drm_device *dev)
{
struct rockchip_drm_private *private = dev->dev_private;
- struct drm_fb_helper *fb_helper = &private->fbdev_helper;
- if (fb_helper)
- drm_fb_helper_hotplug_event(fb_helper);
-}
-
-static void
-rockchip_atomic_commit_tail(struct drm_atomic_state *state)
-{
- struct drm_device *dev = state->dev;
-
- drm_atomic_helper_commit_modeset_disables(dev, state);
-
- drm_atomic_helper_commit_modeset_enables(dev, state);
-
- drm_atomic_helper_commit_planes(dev, state,
- DRM_PLANE_COMMIT_ACTIVE_ONLY);
-
- drm_atomic_helper_commit_hw_done(state);
-
- drm_atomic_helper_wait_for_vblanks(dev, state);
-
- drm_atomic_helper_cleanup_planes(dev, state);
+ drm_fb_helper_hotplug_event(&private->fbdev_helper);
}
static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers = {
- .atomic_commit_tail = rockchip_atomic_commit_tail,
+ .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
};
static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
index ce946b9c57a9..724579ebf947 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
@@ -173,7 +173,7 @@ void rockchip_drm_fbdev_fini(struct drm_device *dev)
drm_fb_helper_unregister_fbi(helper);
if (helper->fb)
- drm_framebuffer_unreference(helper->fb);
+ drm_framebuffer_put(helper->fb);
drm_fb_helper_fini(helper);
}
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index b74ac717e56a..1869c8bb76c8 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -383,7 +383,7 @@ rockchip_gem_create_with_handle(struct drm_file *file_priv,
goto err_handle_create;
/* drop reference from allocate - handle holds it now. */
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return rk_obj;
@@ -393,32 +393,6 @@ err_handle_create:
return ERR_PTR(ret);
}
-int rockchip_gem_dumb_map_offset(struct drm_file *file_priv,
- struct drm_device *dev, uint32_t handle,
- uint64_t *offset)
-{
- struct drm_gem_object *obj;
- int ret;
-
- obj = drm_gem_object_lookup(file_priv, handle);
- if (!obj) {
- DRM_ERROR("failed to lookup gem object.\n");
- return -EINVAL;
- }
-
- ret = drm_gem_create_mmap_offset(obj);
- if (ret)
- goto out;
-
- *offset = drm_vma_node_offset_addr(&obj->vma_node);
- DRM_DEBUG_KMS("offset = 0x%llx\n", *offset);
-
-out:
- drm_gem_object_unreference_unlocked(obj);
-
- return 0;
-}
-
/*
* rockchip_gem_dumb_create - (struct drm_driver)->dumb_create callback
* function
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.h b/drivers/gpu/drm/rockchip/rockchip_drm_gem.h
index 3f6ea4d18a5c..f237375582fb 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.h
@@ -57,7 +57,4 @@ void rockchip_gem_free_object(struct drm_gem_object *obj);
int rockchip_gem_dumb_create(struct drm_file *file_priv,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
-int rockchip_gem_dumb_map_offset(struct drm_file *file_priv,
- struct drm_device *dev, uint32_t handle,
- uint64_t *offset);
#endif /* _ROCKCHIP_DRM_GEM_H */
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 5d450332c2fd..bf9ed0e63973 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -42,33 +42,20 @@
#include "rockchip_drm_psr.h"
#include "rockchip_drm_vop.h"
-#define __REG_SET_RELAXED(x, off, mask, shift, v, write_mask) \
- vop_mask_write(x, off, mask, shift, v, write_mask, true)
-
-#define __REG_SET_NORMAL(x, off, mask, shift, v, write_mask) \
- vop_mask_write(x, off, mask, shift, v, write_mask, false)
-
-#define REG_SET(x, base, reg, v, mode) \
- __REG_SET_##mode(x, base + reg.offset, \
- reg.mask, reg.shift, v, reg.write_mask)
-#define REG_SET_MASK(x, base, reg, mask, v, mode) \
- __REG_SET_##mode(x, base + reg.offset, \
- mask, reg.shift, v, reg.write_mask)
-
#define VOP_WIN_SET(x, win, name, v) \
- REG_SET(x, win->base, win->phy->name, v, RELAXED)
+ vop_reg_set(vop, &win->phy->name, win->base, ~0, v, #name)
#define VOP_SCL_SET(x, win, name, v) \
- REG_SET(x, win->base, win->phy->scl->name, v, RELAXED)
+ vop_reg_set(vop, &win->phy->scl->name, win->base, ~0, v, #name)
#define VOP_SCL_SET_EXT(x, win, name, v) \
- REG_SET(x, win->base, win->phy->scl->ext->name, v, RELAXED)
-#define VOP_CTRL_SET(x, name, v) \
- REG_SET(x, 0, (x)->data->ctrl->name, v, NORMAL)
+ vop_reg_set(vop, &win->phy->scl->ext->name, \
+ win->base, ~0, v, #name)
+
+#define VOP_INTR_SET_MASK(vop, name, mask, v) \
+ vop_reg_set(vop, &vop->data->intr->name, 0, mask, v, #name)
-#define VOP_INTR_GET(vop, name) \
- vop_read_reg(vop, 0, &vop->data->ctrl->name)
+#define VOP_REG_SET(vop, group, name, v) \
+ vop_reg_set(vop, &vop->data->group->name, 0, ~0, v, #name)
-#define VOP_INTR_SET(vop, name, mask, v) \
- REG_SET_MASK(vop, 0, vop->data->intr->name, mask, v, NORMAL)
#define VOP_INTR_SET_TYPE(vop, name, type, v) \
do { \
int i, reg = 0, mask = 0; \
@@ -78,13 +65,13 @@
mask |= 1 << i; \
} \
} \
- VOP_INTR_SET(vop, name, mask, reg); \
+ VOP_INTR_SET_MASK(vop, name, mask, reg); \
} while (0)
#define VOP_INTR_GET_TYPE(vop, name, type) \
vop_get_intr_type(vop, &vop->data->intr->name, type)
#define VOP_WIN_GET(x, win, name) \
- vop_read_reg(x, win->base, &win->phy->name)
+ vop_read_reg(x, win->offset, win->phy->name)
#define VOP_WIN_GET_YRGBADDR(vop, win) \
vop_readl(vop, win->base + win->phy->yrgb_mst.offset)
@@ -166,14 +153,22 @@ static inline uint32_t vop_read_reg(struct vop *vop, uint32_t base,
return (vop_readl(vop, base + reg->offset) >> reg->shift) & reg->mask;
}
-static inline void vop_mask_write(struct vop *vop, uint32_t offset,
- uint32_t mask, uint32_t shift, uint32_t v,
- bool write_mask, bool relaxed)
+static void vop_reg_set(struct vop *vop, const struct vop_reg *reg,
+ uint32_t _offset, uint32_t _mask, uint32_t v,
+ const char *reg_name)
{
- if (!mask)
+ int offset, mask, shift;
+
+ if (!reg || !reg->mask) {
+ dev_dbg(vop->dev, "Warning: not support %s\n", reg_name);
return;
+ }
+
+ offset = reg->offset + _offset;
+ mask = reg->mask & _mask;
+ shift = reg->shift;
- if (write_mask) {
+ if (reg->write_mask) {
v = ((v << shift) & 0xffff) | (mask << (shift + 16));
} else {
uint32_t cached_val = vop->regsbak[offset >> 2];
@@ -182,7 +177,7 @@ static inline void vop_mask_write(struct vop *vop, uint32_t offset,
vop->regsbak[offset >> 2] = v;
}
- if (relaxed)
+ if (reg->relaxed)
writel_relaxed(v, vop->regs + offset);
else
writel(v, vop->regs + offset);
@@ -204,7 +199,7 @@ static inline uint32_t vop_get_intr_type(struct vop *vop,
static inline void vop_cfg_done(struct vop *vop)
{
- VOP_CTRL_SET(vop, cfg_done, 1);
+ VOP_REG_SET(vop, common, cfg_done, 1);
}
static bool has_rb_swapped(uint32_t format)
@@ -500,7 +495,7 @@ static void vop_line_flag_irq_disable(struct vop *vop)
static int vop_enable(struct drm_crtc *crtc)
{
struct vop *vop = to_vop(crtc);
- int ret;
+ int ret, i;
ret = pm_runtime_get_sync(vop->dev);
if (ret < 0) {
@@ -533,6 +528,20 @@ static int vop_enable(struct drm_crtc *crtc)
}
memcpy(vop->regs, vop->regsbak, vop->len);
+ /*
+ * We need to make sure that all windows are disabled before we
+ * enable the crtc. Otherwise we might try to scan from a destroyed
+ * buffer later.
+ */
+ for (i = 0; i < vop->data->win_size; i++) {
+ struct vop_win *vop_win = &vop->win[i];
+ const struct vop_win_data *win = vop_win->data;
+
+ spin_lock(&vop->reg_lock);
+ VOP_WIN_SET(vop, win, enable, 0);
+ spin_unlock(&vop->reg_lock);
+ }
+
vop_cfg_done(vop);
/*
@@ -542,7 +551,7 @@ static int vop_enable(struct drm_crtc *crtc)
spin_lock(&vop->reg_lock);
- VOP_CTRL_SET(vop, standby, 0);
+ VOP_REG_SET(vop, common, standby, 1);
spin_unlock(&vop->reg_lock);
@@ -563,31 +572,15 @@ err_put_pm_runtime:
return ret;
}
-static void vop_crtc_disable(struct drm_crtc *crtc)
+static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct vop *vop = to_vop(crtc);
- int i;
WARN_ON(vop->event);
rockchip_drm_psr_deactivate(&vop->crtc);
- /*
- * We need to make sure that all windows are disabled before we
- * disable that crtc. Otherwise we might try to scan from a destroyed
- * buffer later.
- */
- for (i = 0; i < vop->data->win_size; i++) {
- struct vop_win *vop_win = &vop->win[i];
- const struct vop_win_data *win = vop_win->data;
-
- spin_lock(&vop->reg_lock);
- VOP_WIN_SET(vop, win, enable, 0);
- spin_unlock(&vop->reg_lock);
- }
-
- vop_cfg_done(vop);
-
drm_crtc_vblank_off(crtc);
/*
@@ -602,7 +595,7 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
spin_lock(&vop->reg_lock);
- VOP_CTRL_SET(vop, standby, 1);
+ VOP_REG_SET(vop, common, standby, 1);
spin_unlock(&vop->reg_lock);
@@ -682,8 +675,10 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
* Src.x1 can be odd when do clip, but yuv plane start point
* need align with 2 pixel.
*/
- if (is_yuv_support(fb->format->format) && ((state->src.x1 >> 16) % 2))
+ if (is_yuv_support(fb->format->format) && ((state->src.x1 >> 16) % 2)) {
+ DRM_ERROR("Invalid Source: Yuv format not support odd xpos\n");
return -EINVAL;
+ }
return 0;
}
@@ -764,7 +759,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
spin_lock(&vop->reg_lock);
VOP_WIN_SET(vop, win, format, format);
- VOP_WIN_SET(vop, win, yrgb_vir, fb->pitches[0] >> 2);
+ VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4));
VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
if (is_yuv_support(fb->format->format)) {
int hsub = drm_format_horz_chroma_subsampling(fb->format->format);
@@ -778,7 +773,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
- VOP_WIN_SET(vop, win, uv_vir, fb->pitches[1] >> 2);
+ VOP_WIN_SET(vop, win, uv_vir, DIV_ROUND_UP(fb->pitches[1], 4));
VOP_WIN_SET(vop, win, uv_mst, dma_addr);
}
@@ -871,7 +866,8 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
return true;
}
-static void vop_crtc_enable(struct drm_crtc *crtc)
+static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct vop *vop = to_vop(crtc);
const struct vop_data *vop_data = vop->data;
@@ -898,70 +894,34 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
return;
}
- /*
- * If dclk rate is zero, mean that scanout is stop,
- * we don't need wait any more.
- */
- if (clk_get_rate(vop->dclk)) {
- /*
- * Rk3288 vop timing register is immediately, when configure
- * display timing on display time, may cause tearing.
- *
- * Vop standby will take effect at end of current frame,
- * if dsp hold valid irq happen, it means standby complete.
- *
- * mode set:
- * standby and wait complete --> |----
- * | display time
- * |----
- * |---> dsp hold irq
- * configure display timing --> |
- * standby exit |
- * | new frame start.
- */
-
- reinit_completion(&vop->dsp_hold_completion);
- vop_dsp_hold_valid_irq_enable(vop);
-
- spin_lock(&vop->reg_lock);
-
- VOP_CTRL_SET(vop, standby, 1);
-
- spin_unlock(&vop->reg_lock);
-
- wait_for_completion(&vop->dsp_hold_completion);
-
- vop_dsp_hold_valid_irq_disable(vop);
- }
-
pin_pol = BIT(DCLK_INVERT);
pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) ?
BIT(HSYNC_POSITIVE) : 0;
pin_pol |= (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) ?
BIT(VSYNC_POSITIVE) : 0;
- VOP_CTRL_SET(vop, pin_pol, pin_pol);
+ VOP_REG_SET(vop, output, pin_pol, pin_pol);
switch (s->output_type) {
case DRM_MODE_CONNECTOR_LVDS:
- VOP_CTRL_SET(vop, rgb_en, 1);
- VOP_CTRL_SET(vop, rgb_pin_pol, pin_pol);
+ VOP_REG_SET(vop, output, rgb_en, 1);
+ VOP_REG_SET(vop, output, rgb_pin_pol, pin_pol);
break;
case DRM_MODE_CONNECTOR_eDP:
- VOP_CTRL_SET(vop, edp_pin_pol, pin_pol);
- VOP_CTRL_SET(vop, edp_en, 1);
+ VOP_REG_SET(vop, output, edp_pin_pol, pin_pol);
+ VOP_REG_SET(vop, output, edp_en, 1);
break;
case DRM_MODE_CONNECTOR_HDMIA:
- VOP_CTRL_SET(vop, hdmi_pin_pol, pin_pol);
- VOP_CTRL_SET(vop, hdmi_en, 1);
+ VOP_REG_SET(vop, output, hdmi_pin_pol, pin_pol);
+ VOP_REG_SET(vop, output, hdmi_en, 1);
break;
case DRM_MODE_CONNECTOR_DSI:
- VOP_CTRL_SET(vop, mipi_pin_pol, pin_pol);
- VOP_CTRL_SET(vop, mipi_en, 1);
+ VOP_REG_SET(vop, output, mipi_pin_pol, pin_pol);
+ VOP_REG_SET(vop, output, mipi_en, 1);
break;
case DRM_MODE_CONNECTOR_DisplayPort:
pin_pol &= ~BIT(DCLK_INVERT);
- VOP_CTRL_SET(vop, dp_pin_pol, pin_pol);
- VOP_CTRL_SET(vop, dp_en, 1);
+ VOP_REG_SET(vop, output, dp_pin_pol, pin_pol);
+ VOP_REG_SET(vop, output, dp_en, 1);
break;
default:
DRM_DEV_ERROR(vop->dev, "unsupported connector_type [%d]\n",
@@ -974,25 +934,25 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
if (s->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
!(vop_data->feature & VOP_FEATURE_OUTPUT_RGB10))
s->output_mode = ROCKCHIP_OUT_MODE_P888;
- VOP_CTRL_SET(vop, out_mode, s->output_mode);
+ VOP_REG_SET(vop, common, out_mode, s->output_mode);
- VOP_CTRL_SET(vop, htotal_pw, (htotal << 16) | hsync_len);
+ VOP_REG_SET(vop, modeset, htotal_pw, (htotal << 16) | hsync_len);
val = hact_st << 16;
val |= hact_end;
- VOP_CTRL_SET(vop, hact_st_end, val);
- VOP_CTRL_SET(vop, hpost_st_end, val);
+ VOP_REG_SET(vop, modeset, hact_st_end, val);
+ VOP_REG_SET(vop, modeset, hpost_st_end, val);
- VOP_CTRL_SET(vop, vtotal_pw, (vtotal << 16) | vsync_len);
+ VOP_REG_SET(vop, modeset, vtotal_pw, (vtotal << 16) | vsync_len);
val = vact_st << 16;
val |= vact_end;
- VOP_CTRL_SET(vop, vact_st_end, val);
- VOP_CTRL_SET(vop, vpost_st_end, val);
+ VOP_REG_SET(vop, modeset, vact_st_end, val);
+ VOP_REG_SET(vop, modeset, vpost_st_end, val);
- VOP_CTRL_SET(vop, line_flag_num[0], vact_end);
+ VOP_REG_SET(vop, intr, line_flag_num[0], vact_end);
clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
- VOP_CTRL_SET(vop, standby, 0);
+ VOP_REG_SET(vop, common, standby, 0);
rockchip_drm_psr_activate(&vop->crtc);
}
@@ -1027,7 +987,7 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state)
{
struct drm_atomic_state *old_state = old_crtc_state->state;
- struct drm_plane_state *old_plane_state;
+ struct drm_plane_state *old_plane_state, *new_plane_state;
struct vop *vop = to_vop(crtc);
struct drm_plane *plane;
int i;
@@ -1058,14 +1018,15 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
}
spin_unlock_irq(&crtc->dev->event_lock);
- for_each_plane_in_state(old_state, plane, old_plane_state, i) {
+ for_each_oldnew_plane_in_state(old_state, plane, old_plane_state,
+ new_plane_state, i) {
if (!old_plane_state->fb)
continue;
- if (old_plane_state->fb == plane->state->fb)
+ if (old_plane_state->fb == new_plane_state->fb)
continue;
- drm_framebuffer_reference(old_plane_state->fb);
+ drm_framebuffer_get(old_plane_state->fb);
drm_flip_work_queue(&vop->fb_unref_work, old_plane_state->fb);
set_bit(VOP_PENDING_FB_UNREF, &vop->pending);
WARN_ON(drm_crtc_vblank_get(crtc) != 0);
@@ -1079,11 +1040,11 @@ static void vop_crtc_atomic_begin(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
- .enable = vop_crtc_enable,
- .disable = vop_crtc_disable,
.mode_fixup = vop_crtc_mode_fixup,
.atomic_flush = vop_crtc_atomic_flush,
.atomic_begin = vop_crtc_atomic_begin,
+ .atomic_enable = vop_crtc_atomic_enable,
+ .atomic_disable = vop_crtc_atomic_disable,
};
static void vop_crtc_destroy(struct drm_crtc *crtc)
@@ -1189,7 +1150,7 @@ static void vop_fb_unref_worker(struct drm_flip_work *work, void *val)
struct drm_framebuffer *fb = val;
drm_crtc_vblank_put(&vop->crtc);
- drm_framebuffer_unreference(fb);
+ drm_framebuffer_put(fb);
}
static void vop_handle_vblank(struct vop *vop)
@@ -1290,7 +1251,7 @@ static int vop_create_crtc(struct vop *vop)
0, &vop_plane_funcs,
win_data->phy->data_formats,
win_data->phy->nformats,
- win_data->type, NULL);
+ NULL, win_data->type, NULL);
if (ret) {
DRM_DEV_ERROR(vop->dev, "failed to init plane %d\n",
ret);
@@ -1329,7 +1290,7 @@ static int vop_create_crtc(struct vop *vop)
&vop_plane_funcs,
win_data->phy->data_formats,
win_data->phy->nformats,
- win_data->type, NULL);
+ NULL, win_data->type, NULL);
if (ret) {
DRM_DEV_ERROR(vop->dev, "failed to init overlay %d\n",
ret);
@@ -1340,8 +1301,8 @@ static int vop_create_crtc(struct vop *vop)
port = of_get_child_by_name(dev->of_node, "port");
if (!port) {
- DRM_DEV_ERROR(vop->dev, "no port node found in %s\n",
- dev->of_node->full_name);
+ DRM_DEV_ERROR(vop->dev, "no port node found in %pOF\n",
+ dev->of_node);
ret = -ENOENT;
goto err_cleanup_crtc;
}
@@ -1395,7 +1356,6 @@ static void vop_destroy_crtc(struct vop *vop)
static int vop_initial(struct vop *vop)
{
const struct vop_data *vop_data = vop->data;
- const struct vop_reg_data *init_table = vop_data->init_table;
struct reset_control *ahb_rst;
int i, ret;
@@ -1455,13 +1415,16 @@ static int vop_initial(struct vop *vop)
memcpy(vop->regsbak, vop->regs, vop->len);
- for (i = 0; i < vop_data->table_size; i++)
- vop_writel(vop, init_table[i].offset, init_table[i].value);
+ VOP_REG_SET(vop, misc, global_regdone_en, 1);
+ VOP_REG_SET(vop, common, dsp_blank, 0);
for (i = 0; i < vop_data->win_size; i++) {
const struct vop_win_data *win = &vop_data->win[i];
+ int channel = i * 2 + 1;
+ VOP_WIN_SET(vop, win, channel, (channel + 1) << 4 | channel);
VOP_WIN_SET(vop, win, enable, 0);
+ VOP_WIN_SET(vop, win, gate, 1);
}
vop_cfg_done(vop);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 9979fd0c2282..56bbd2e2a8ef 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -15,6 +15,14 @@
#ifndef _ROCKCHIP_DRM_VOP_H
#define _ROCKCHIP_DRM_VOP_H
+/*
+ * major: IP major version, used for IP structure
+ * minor: big feature change under same structure
+ */
+#define VOP_VERSION(major, minor) ((major) << 8 | (minor))
+#define VOP_MAJOR(version) ((version) >> 8)
+#define VOP_MINOR(version) ((version) & 0xff)
+
enum vop_data_format {
VOP_FMT_ARGB8888 = 0,
VOP_FMT_RGB888,
@@ -24,53 +32,58 @@ enum vop_data_format {
VOP_FMT_YUV444SP,
};
-struct vop_reg_data {
- uint32_t offset;
- uint32_t value;
-};
-
struct vop_reg {
- uint32_t offset;
- uint32_t shift;
uint32_t mask;
+ uint16_t offset;
+ uint8_t shift;
bool write_mask;
+ bool relaxed;
};
-struct vop_ctrl {
- struct vop_reg standby;
- struct vop_reg data_blank;
- struct vop_reg gate_en;
- struct vop_reg mmu_en;
- struct vop_reg rgb_en;
- struct vop_reg edp_en;
- struct vop_reg hdmi_en;
- struct vop_reg mipi_en;
- struct vop_reg dp_en;
- struct vop_reg out_mode;
- struct vop_reg dither_down;
- struct vop_reg dither_up;
- struct vop_reg pin_pol;
- struct vop_reg rgb_pin_pol;
- struct vop_reg hdmi_pin_pol;
- struct vop_reg edp_pin_pol;
- struct vop_reg mipi_pin_pol;
- struct vop_reg dp_pin_pol;
-
+struct vop_modeset {
struct vop_reg htotal_pw;
struct vop_reg hact_st_end;
+ struct vop_reg hpost_st_end;
struct vop_reg vtotal_pw;
struct vop_reg vact_st_end;
- struct vop_reg hpost_st_end;
struct vop_reg vpost_st_end;
+};
- struct vop_reg line_flag_num[2];
+struct vop_output {
+ struct vop_reg pin_pol;
+ struct vop_reg dp_pin_pol;
+ struct vop_reg edp_pin_pol;
+ struct vop_reg hdmi_pin_pol;
+ struct vop_reg mipi_pin_pol;
+ struct vop_reg rgb_pin_pol;
+ struct vop_reg dp_en;
+ struct vop_reg edp_en;
+ struct vop_reg hdmi_en;
+ struct vop_reg mipi_en;
+ struct vop_reg rgb_en;
+};
+struct vop_common {
struct vop_reg cfg_done;
+ struct vop_reg dsp_blank;
+ struct vop_reg data_blank;
+ struct vop_reg dither_down;
+ struct vop_reg dither_up;
+ struct vop_reg gate_en;
+ struct vop_reg mmu_en;
+ struct vop_reg out_mode;
+ struct vop_reg standby;
+};
+
+struct vop_misc {
+ struct vop_reg global_regdone_en;
};
struct vop_intr {
const int *intrs;
uint32_t nintrs;
+
+ struct vop_reg line_flag_num[2];
struct vop_reg enable;
struct vop_reg clear;
struct vop_reg status;
@@ -115,6 +128,7 @@ struct vop_win_phy {
uint32_t nformats;
struct vop_reg enable;
+ struct vop_reg gate;
struct vop_reg format;
struct vop_reg rb_swap;
struct vop_reg act_info;
@@ -127,6 +141,7 @@ struct vop_win_phy {
struct vop_reg dst_alpha_ctl;
struct vop_reg src_alpha_ctl;
+ struct vop_reg channel;
};
struct vop_win_data {
@@ -136,10 +151,12 @@ struct vop_win_data {
};
struct vop_data {
- const struct vop_reg_data *init_table;
- unsigned int table_size;
- const struct vop_ctrl *ctrl;
+ uint32_t version;
const struct vop_intr *intr;
+ const struct vop_common *common;
+ const struct vop_misc *misc;
+ const struct vop_modeset *modeset;
+ const struct vop_output *output;
const struct vop_win_data *win;
unsigned int win_size;
@@ -282,6 +299,9 @@ static inline uint16_t scl_get_bili_dn_vskip(int src_h, int dst_h,
act_height = (src_h + vskiplines - 1) / vskiplines;
+ if (act_height == dst_h)
+ return GET_SCL_FT_BILI_DN(src_h, dst_h) / vskiplines;
+
return GET_SCL_FT_BILI_DN(act_height, dst_h);
}
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index bafd698a28b1..94de7b9f6fde 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -20,17 +20,23 @@
#include "rockchip_drm_vop.h"
#include "rockchip_vop_reg.h"
-#define VOP_REG(off, _mask, s) \
- {.offset = off, \
+#define _VOP_REG(off, _mask, _shift, _write_mask, _relaxed) \
+ { \
+ .offset = off, \
.mask = _mask, \
- .shift = s, \
- .write_mask = false,}
+ .shift = _shift, \
+ .write_mask = _write_mask, \
+ .relaxed = _relaxed, \
+ }
-#define VOP_REG_MASK(off, _mask, s) \
- {.offset = off, \
- .mask = _mask, \
- .shift = s, \
- .write_mask = true,}
+#define VOP_REG(off, _mask, _shift) \
+ _VOP_REG(off, _mask, _shift, false, true)
+
+#define VOP_REG_SYNC(off, _mask, _shift) \
+ _VOP_REG(off, _mask, _shift, false, false)
+
+#define VOP_REG_MASK_SYNC(off, _mask, _shift) \
+ _VOP_REG(off, _mask, _shift, true, false)
static const uint32_t formats_win_full[] = {
DRM_FORMAT_XRGB8888,
@@ -110,32 +116,35 @@ static const int rk3036_vop_intrs[] = {
static const struct vop_intr rk3036_intr = {
.intrs = rk3036_vop_intrs,
.nintrs = ARRAY_SIZE(rk3036_vop_intrs),
- .status = VOP_REG(RK3036_INT_STATUS, 0xf, 0),
- .enable = VOP_REG(RK3036_INT_STATUS, 0xf, 4),
- .clear = VOP_REG(RK3036_INT_STATUS, 0xf, 8),
+ .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
+ .status = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 0),
+ .enable = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 4),
+ .clear = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 8),
};
-static const struct vop_ctrl rk3036_ctrl_data = {
- .standby = VOP_REG(RK3036_SYS_CTRL, 0x1, 30),
- .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
- .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
+static const struct vop_modeset rk3036_modeset = {
.htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
.hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
.vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
.vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
- .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
- .cfg_done = VOP_REG(RK3036_REG_CFG_DONE, 0x1, 0),
};
-static const struct vop_reg_data rk3036_vop_init_reg_table[] = {
- {RK3036_DSP_CTRL1, 0x00000000},
+static const struct vop_output rk3036_output = {
+ .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
+};
+
+static const struct vop_common rk3036_common = {
+ .standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30),
+ .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
+ .dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24),
+ .cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0),
};
static const struct vop_data rk3036_vop = {
- .init_table = rk3036_vop_init_reg_table,
- .table_size = ARRAY_SIZE(rk3036_vop_init_reg_table),
- .ctrl = &rk3036_ctrl_data,
.intr = &rk3036_intr,
+ .common = &rk3036_common,
+ .modeset = &rk3036_modeset,
+ .output = &rk3036_output,
.win = rk3036_vop_win_data,
.win_size = ARRAY_SIZE(rk3036_vop_win_data),
};
@@ -188,12 +197,14 @@ static const struct vop_win_phy rk3288_win01_data = {
.uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
.src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
.dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
+ .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
};
static const struct vop_win_phy rk3288_win23_data = {
.data_formats = formats_win_lite,
.nformats = ARRAY_SIZE(formats_win_lite),
- .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
+ .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
+ .gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
.format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
.rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12),
.dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0),
@@ -204,40 +215,33 @@ static const struct vop_win_phy rk3288_win23_data = {
.dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0),
};
-static const struct vop_ctrl rk3288_ctrl_data = {
- .standby = VOP_REG(RK3288_SYS_CTRL, 0x1, 22),
- .gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
- .mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
- .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
- .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
- .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
- .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
- .dither_down = VOP_REG(RK3288_DSP_CTRL1, 0xf, 1),
- .dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
- .data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
- .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
- .pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
+static const struct vop_modeset rk3288_modeset = {
.htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
.hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
.vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
.vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
.hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
- .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
- .cfg_done = VOP_REG(RK3288_REG_CFG_DONE, 0x1, 0),
};
-static const struct vop_reg_data rk3288_init_reg_table[] = {
- {RK3288_SYS_CTRL, 0x00c00000},
- {RK3288_DSP_CTRL0, 0x00000000},
- {RK3288_WIN0_CTRL0, 0x00000080},
- {RK3288_WIN1_CTRL0, 0x00000080},
- /* TODO: Win2/3 support multiple area function, but we haven't found
- * a suitable way to use it yet, so let's just use them as other windows
- * with only area 0 enabled.
- */
- {RK3288_WIN2_CTRL0, 0x00000010},
- {RK3288_WIN3_CTRL0, 0x00000010},
+static const struct vop_output rk3288_output = {
+ .pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
+ .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
+ .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
+ .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
+ .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
+};
+
+static const struct vop_common rk3288_common = {
+ .standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22),
+ .gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
+ .mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
+ .dither_down = VOP_REG(RK3288_DSP_CTRL1, 0xf, 1),
+ .dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
+ .data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
+ .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
+ .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
+ .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0),
};
/*
@@ -267,50 +271,24 @@ static const int rk3288_vop_intrs[] = {
static const struct vop_intr rk3288_vop_intr = {
.intrs = rk3288_vop_intrs,
.nintrs = ARRAY_SIZE(rk3288_vop_intrs),
+ .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
.status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0),
.enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4),
.clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8),
};
static const struct vop_data rk3288_vop = {
- .init_table = rk3288_init_reg_table,
- .table_size = ARRAY_SIZE(rk3288_init_reg_table),
+ .version = VOP_VERSION(3, 1),
.feature = VOP_FEATURE_OUTPUT_RGB10,
.intr = &rk3288_vop_intr,
- .ctrl = &rk3288_ctrl_data,
+ .common = &rk3288_common,
+ .modeset = &rk3288_modeset,
+ .output = &rk3288_output,
.win = rk3288_vop_win_data,
.win_size = ARRAY_SIZE(rk3288_vop_win_data),
};
-static const struct vop_ctrl rk3399_ctrl_data = {
- .standby = VOP_REG(RK3399_SYS_CTRL, 0x1, 22),
- .gate_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 23),
- .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
- .rgb_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 12),
- .hdmi_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 13),
- .edp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 14),
- .mipi_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 15),
- .dither_down = VOP_REG(RK3399_DSP_CTRL1, 0xf, 1),
- .dither_up = VOP_REG(RK3399_DSP_CTRL1, 0x1, 6),
- .data_blank = VOP_REG(RK3399_DSP_CTRL0, 0x1, 19),
- .out_mode = VOP_REG(RK3399_DSP_CTRL0, 0xf, 0),
- .rgb_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
- .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
- .hdmi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 20),
- .edp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 24),
- .mipi_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 28),
- .htotal_pw = VOP_REG(RK3399_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
- .hact_st_end = VOP_REG(RK3399_DSP_HACT_ST_END, 0x1fff1fff, 0),
- .vtotal_pw = VOP_REG(RK3399_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
- .vact_st_end = VOP_REG(RK3399_DSP_VACT_ST_END, 0x1fff1fff, 0),
- .hpost_st_end = VOP_REG(RK3399_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
- .vpost_st_end = VOP_REG(RK3399_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
- .line_flag_num[0] = VOP_REG(RK3399_LINE_FLAG, 0xffff, 0),
- .line_flag_num[1] = VOP_REG(RK3399_LINE_FLAG, 0xffff, 16),
- .cfg_done = VOP_REG_MASK(RK3399_REG_CFG_DONE, 0x1, 0),
-};
-
-static const int rk3399_vop_intrs[] = {
+static const int rk3368_vop_intrs[] = {
FS_INTR,
0, 0,
LINE_FLAG_INTR,
@@ -320,69 +298,232 @@ static const int rk3399_vop_intrs[] = {
DSP_HOLD_VALID_INTR,
};
-static const struct vop_intr rk3399_vop_intr = {
- .intrs = rk3399_vop_intrs,
- .nintrs = ARRAY_SIZE(rk3399_vop_intrs),
- .status = VOP_REG_MASK(RK3399_INTR_STATUS0, 0xffff, 0),
- .enable = VOP_REG_MASK(RK3399_INTR_EN0, 0xffff, 0),
- .clear = VOP_REG_MASK(RK3399_INTR_CLEAR0, 0xffff, 0),
+static const struct vop_intr rk3368_vop_intr = {
+ .intrs = rk3368_vop_intrs,
+ .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
+ .line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 0),
+ .line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 16),
+ .status = VOP_REG_MASK_SYNC(RK3368_INTR_STATUS, 0x3fff, 0),
+ .enable = VOP_REG_MASK_SYNC(RK3368_INTR_EN, 0x3fff, 0),
+ .clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0),
};
-static const struct vop_reg_data rk3399_init_reg_table[] = {
- {RK3399_SYS_CTRL, 0x2000f800},
- {RK3399_DSP_CTRL0, 0x00000000},
- {RK3399_WIN0_CTRL0, 0x00000080},
- {RK3399_WIN1_CTRL0, 0x00000080},
- /* TODO: Win2/3 support multiple area function, but we haven't found
- * a suitable way to use it yet, so let's just use them as other windows
- * with only area 0 enabled.
- */
- {RK3399_WIN2_CTRL0, 0x00000010},
- {RK3399_WIN3_CTRL0, 0x00000010},
+static const struct vop_win_phy rk3368_win23_data = {
+ .data_formats = formats_win_lite,
+ .nformats = ARRAY_SIZE(formats_win_lite),
+ .gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0),
+ .enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
+ .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
+ .rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20),
+ .dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0),
+ .dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0),
+ .yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0),
+ .yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0),
+ .src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
+ .dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xff, 0),
+};
+
+static const struct vop_win_data rk3368_vop_win_data[] = {
+ { .base = 0x00, .phy = &rk3288_win01_data,
+ .type = DRM_PLANE_TYPE_PRIMARY },
+ { .base = 0x40, .phy = &rk3288_win01_data,
+ .type = DRM_PLANE_TYPE_OVERLAY },
+ { .base = 0x00, .phy = &rk3368_win23_data,
+ .type = DRM_PLANE_TYPE_OVERLAY },
+ { .base = 0x50, .phy = &rk3368_win23_data,
+ .type = DRM_PLANE_TYPE_CURSOR },
+};
+
+static const struct vop_output rk3368_output = {
+ .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 16),
+ .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 20),
+ .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 24),
+ .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 28),
+ .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
+ .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
+ .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
+ .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
+};
+
+static const struct vop_misc rk3368_misc = {
+ .global_regdone_en = VOP_REG(RK3368_SYS_CTRL, 0x1, 11),
+};
+
+static const struct vop_data rk3368_vop = {
+ .version = VOP_VERSION(3, 2),
+ .intr = &rk3368_vop_intr,
+ .common = &rk3288_common,
+ .modeset = &rk3288_modeset,
+ .output = &rk3368_output,
+ .misc = &rk3368_misc,
+ .win = rk3368_vop_win_data,
+ .win_size = ARRAY_SIZE(rk3368_vop_win_data),
+};
+
+static const struct vop_intr rk3366_vop_intr = {
+ .intrs = rk3368_vop_intrs,
+ .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
+ .line_flag_num[0] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 0),
+ .line_flag_num[1] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 16),
+ .status = VOP_REG_MASK_SYNC(RK3366_INTR_STATUS0, 0xffff, 0),
+ .enable = VOP_REG_MASK_SYNC(RK3366_INTR_EN0, 0xffff, 0),
+ .clear = VOP_REG_MASK_SYNC(RK3366_INTR_CLEAR0, 0xffff, 0),
+};
+
+static const struct vop_data rk3366_vop = {
+ .version = VOP_VERSION(3, 4),
+ .intr = &rk3366_vop_intr,
+ .common = &rk3288_common,
+ .modeset = &rk3288_modeset,
+ .output = &rk3368_output,
+ .misc = &rk3368_misc,
+ .win = rk3368_vop_win_data,
+ .win_size = ARRAY_SIZE(rk3368_vop_win_data),
+};
+
+static const struct vop_output rk3399_output = {
+ .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
+ .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 16),
+ .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 20),
+ .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 24),
+ .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 28),
+ .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
+ .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
+ .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
+ .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
+ .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
};
static const struct vop_data rk3399_vop_big = {
- .init_table = rk3399_init_reg_table,
- .table_size = ARRAY_SIZE(rk3399_init_reg_table),
+ .version = VOP_VERSION(3, 5),
.feature = VOP_FEATURE_OUTPUT_RGB10,
- .intr = &rk3399_vop_intr,
- .ctrl = &rk3399_ctrl_data,
- /*
- * rk3399 vop big windows register layout is same as rk3288.
- */
- .win = rk3288_vop_win_data,
- .win_size = ARRAY_SIZE(rk3288_vop_win_data),
+ .intr = &rk3366_vop_intr,
+ .common = &rk3288_common,
+ .modeset = &rk3288_modeset,
+ .output = &rk3399_output,
+ .misc = &rk3368_misc,
+ .win = rk3368_vop_win_data,
+ .win_size = ARRAY_SIZE(rk3368_vop_win_data),
};
static const struct vop_win_data rk3399_vop_lit_win_data[] = {
{ .base = 0x00, .phy = &rk3288_win01_data,
.type = DRM_PLANE_TYPE_PRIMARY },
- { .base = 0x00, .phy = &rk3288_win23_data,
+ { .base = 0x00, .phy = &rk3368_win23_data,
.type = DRM_PLANE_TYPE_CURSOR},
};
static const struct vop_data rk3399_vop_lit = {
- .init_table = rk3399_init_reg_table,
- .table_size = ARRAY_SIZE(rk3399_init_reg_table),
- .intr = &rk3399_vop_intr,
- .ctrl = &rk3399_ctrl_data,
- /*
- * rk3399 vop lit windows register layout is same as rk3288,
- * but cut off the win1 and win3 windows.
- */
+ .version = VOP_VERSION(3, 6),
+ .intr = &rk3366_vop_intr,
+ .common = &rk3288_common,
+ .modeset = &rk3288_modeset,
+ .output = &rk3399_output,
+ .misc = &rk3368_misc,
.win = rk3399_vop_lit_win_data,
.win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
};
+static const struct vop_win_data rk3228_vop_win_data[] = {
+ { .base = 0x00, .phy = &rk3288_win01_data,
+ .type = DRM_PLANE_TYPE_PRIMARY },
+ { .base = 0x40, .phy = &rk3288_win01_data,
+ .type = DRM_PLANE_TYPE_CURSOR },
+};
+
+static const struct vop_data rk3228_vop = {
+ .version = VOP_VERSION(3, 7),
+ .feature = VOP_FEATURE_OUTPUT_RGB10,
+ .intr = &rk3366_vop_intr,
+ .common = &rk3288_common,
+ .modeset = &rk3288_modeset,
+ .output = &rk3399_output,
+ .misc = &rk3368_misc,
+ .win = rk3228_vop_win_data,
+ .win_size = ARRAY_SIZE(rk3228_vop_win_data),
+};
+
+static const struct vop_modeset rk3328_modeset = {
+ .htotal_pw = VOP_REG(RK3328_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
+ .hact_st_end = VOP_REG(RK3328_DSP_HACT_ST_END, 0x1fff1fff, 0),
+ .vtotal_pw = VOP_REG(RK3328_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
+ .vact_st_end = VOP_REG(RK3328_DSP_VACT_ST_END, 0x1fff1fff, 0),
+ .hpost_st_end = VOP_REG(RK3328_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
+ .vpost_st_end = VOP_REG(RK3328_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
+};
+
+static const struct vop_output rk3328_output = {
+ .rgb_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 12),
+ .hdmi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 13),
+ .edp_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 14),
+ .mipi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 15),
+ .rgb_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 16),
+ .hdmi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 20),
+ .edp_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 24),
+ .mipi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 28),
+};
+
+static const struct vop_misc rk3328_misc = {
+ .global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11),
+};
+
+static const struct vop_common rk3328_common = {
+ .standby = VOP_REG_SYNC(RK3328_SYS_CTRL, 0x1, 22),
+ .dither_down = VOP_REG(RK3328_DSP_CTRL1, 0xf, 1),
+ .dither_up = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6),
+ .dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18),
+ .out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0),
+ .cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0),
+};
+
+static const struct vop_intr rk3328_vop_intr = {
+ .intrs = rk3368_vop_intrs,
+ .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
+ .line_flag_num[0] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 0),
+ .line_flag_num[1] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 16),
+ .status = VOP_REG_MASK_SYNC(RK3328_INTR_STATUS0, 0xffff, 0),
+ .enable = VOP_REG_MASK_SYNC(RK3328_INTR_EN0, 0xffff, 0),
+ .clear = VOP_REG_MASK_SYNC(RK3328_INTR_CLEAR0, 0xffff, 0),
+};
+
+static const struct vop_win_data rk3328_vop_win_data[] = {
+ { .base = 0xd0, .phy = &rk3288_win01_data,
+ .type = DRM_PLANE_TYPE_PRIMARY },
+ { .base = 0x1d0, .phy = &rk3288_win01_data,
+ .type = DRM_PLANE_TYPE_OVERLAY },
+ { .base = 0x2d0, .phy = &rk3288_win01_data,
+ .type = DRM_PLANE_TYPE_CURSOR },
+};
+
+static const struct vop_data rk3328_vop = {
+ .version = VOP_VERSION(3, 8),
+ .feature = VOP_FEATURE_OUTPUT_RGB10,
+ .intr = &rk3328_vop_intr,
+ .common = &rk3328_common,
+ .modeset = &rk3328_modeset,
+ .output = &rk3328_output,
+ .misc = &rk3328_misc,
+ .win = rk3328_vop_win_data,
+ .win_size = ARRAY_SIZE(rk3328_vop_win_data),
+};
+
static const struct of_device_id vop_driver_dt_match[] = {
{ .compatible = "rockchip,rk3036-vop",
.data = &rk3036_vop },
{ .compatible = "rockchip,rk3288-vop",
.data = &rk3288_vop },
+ { .compatible = "rockchip,rk3368-vop",
+ .data = &rk3368_vop },
+ { .compatible = "rockchip,rk3366-vop",
+ .data = &rk3366_vop },
{ .compatible = "rockchip,rk3399-vop-big",
.data = &rk3399_vop_big },
{ .compatible = "rockchip,rk3399-vop-lit",
.data = &rk3399_vop_lit },
+ { .compatible = "rockchip,rk3228-vop",
+ .data = &rk3228_vop },
+ { .compatible = "rockchip,rk3328-vop",
+ .data = &rk3328_vop },
{},
};
MODULE_DEVICE_TABLE(of, vop_driver_dt_match);
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
index cd197260ece5..4a4799ff65de 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
@@ -41,6 +41,7 @@
#define RK3288_WIN0_SRC_ALPHA_CTRL 0x0060
#define RK3288_WIN0_DST_ALPHA_CTRL 0x0064
#define RK3288_WIN0_FADING_CTRL 0x0068
+#define RK3288_WIN0_CTRL2 0x006c
/* win1 register */
#define RK3288_WIN1_CTRL0 0x0070
@@ -122,6 +123,717 @@
#define RK3288_DSP_VACT_ST_END_F1 0x019c
/* register definition end */
+/* rk3368 register definition */
+#define RK3368_REG_CFG_DONE 0x0000
+#define RK3368_VERSION_INFO 0x0004
+#define RK3368_SYS_CTRL 0x0008
+#define RK3368_SYS_CTRL1 0x000c
+#define RK3368_DSP_CTRL0 0x0010
+#define RK3368_DSP_CTRL1 0x0014
+#define RK3368_DSP_BG 0x0018
+#define RK3368_MCU_CTRL 0x001c
+#define RK3368_LINE_FLAG 0x0020
+#define RK3368_INTR_EN 0x0024
+#define RK3368_INTR_CLEAR 0x0028
+#define RK3368_INTR_STATUS 0x002c
+#define RK3368_WIN0_CTRL0 0x0030
+#define RK3368_WIN0_CTRL1 0x0034
+#define RK3368_WIN0_COLOR_KEY 0x0038
+#define RK3368_WIN0_VIR 0x003c
+#define RK3368_WIN0_YRGB_MST 0x0040
+#define RK3368_WIN0_CBR_MST 0x0044
+#define RK3368_WIN0_ACT_INFO 0x0048
+#define RK3368_WIN0_DSP_INFO 0x004c
+#define RK3368_WIN0_DSP_ST 0x0050
+#define RK3368_WIN0_SCL_FACTOR_YRGB 0x0054
+#define RK3368_WIN0_SCL_FACTOR_CBR 0x0058
+#define RK3368_WIN0_SCL_OFFSET 0x005c
+#define RK3368_WIN0_SRC_ALPHA_CTRL 0x0060
+#define RK3368_WIN0_DST_ALPHA_CTRL 0x0064
+#define RK3368_WIN0_FADING_CTRL 0x0068
+#define RK3368_WIN0_CTRL2 0x006c
+#define RK3368_WIN1_CTRL0 0x0070
+#define RK3368_WIN1_CTRL1 0x0074
+#define RK3368_WIN1_COLOR_KEY 0x0078
+#define RK3368_WIN1_VIR 0x007c
+#define RK3368_WIN1_YRGB_MST 0x0080
+#define RK3368_WIN1_CBR_MST 0x0084
+#define RK3368_WIN1_ACT_INFO 0x0088
+#define RK3368_WIN1_DSP_INFO 0x008c
+#define RK3368_WIN1_DSP_ST 0x0090
+#define RK3368_WIN1_SCL_FACTOR_YRGB 0x0094
+#define RK3368_WIN1_SCL_FACTOR_CBR 0x0098
+#define RK3368_WIN1_SCL_OFFSET 0x009c
+#define RK3368_WIN1_SRC_ALPHA_CTRL 0x00a0
+#define RK3368_WIN1_DST_ALPHA_CTRL 0x00a4
+#define RK3368_WIN1_FADING_CTRL 0x00a8
+#define RK3368_WIN1_CTRL2 0x00ac
+#define RK3368_WIN2_CTRL0 0x00b0
+#define RK3368_WIN2_CTRL1 0x00b4
+#define RK3368_WIN2_VIR0_1 0x00b8
+#define RK3368_WIN2_VIR2_3 0x00bc
+#define RK3368_WIN2_MST0 0x00c0
+#define RK3368_WIN2_DSP_INFO0 0x00c4
+#define RK3368_WIN2_DSP_ST0 0x00c8
+#define RK3368_WIN2_COLOR_KEY 0x00cc
+#define RK3368_WIN2_MST1 0x00d0
+#define RK3368_WIN2_DSP_INFO1 0x00d4
+#define RK3368_WIN2_DSP_ST1 0x00d8
+#define RK3368_WIN2_SRC_ALPHA_CTRL 0x00dc
+#define RK3368_WIN2_MST2 0x00e0
+#define RK3368_WIN2_DSP_INFO2 0x00e4
+#define RK3368_WIN2_DSP_ST2 0x00e8
+#define RK3368_WIN2_DST_ALPHA_CTRL 0x00ec
+#define RK3368_WIN2_MST3 0x00f0
+#define RK3368_WIN2_DSP_INFO3 0x00f4
+#define RK3368_WIN2_DSP_ST3 0x00f8
+#define RK3368_WIN2_FADING_CTRL 0x00fc
+#define RK3368_WIN3_CTRL0 0x0100
+#define RK3368_WIN3_CTRL1 0x0104
+#define RK3368_WIN3_VIR0_1 0x0108
+#define RK3368_WIN3_VIR2_3 0x010c
+#define RK3368_WIN3_MST0 0x0110
+#define RK3368_WIN3_DSP_INFO0 0x0114
+#define RK3368_WIN3_DSP_ST0 0x0118
+#define RK3368_WIN3_COLOR_KEY 0x011c
+#define RK3368_WIN3_MST1 0x0120
+#define RK3368_WIN3_DSP_INFO1 0x0124
+#define RK3368_WIN3_DSP_ST1 0x0128
+#define RK3368_WIN3_SRC_ALPHA_CTRL 0x012c
+#define RK3368_WIN3_MST2 0x0130
+#define RK3368_WIN3_DSP_INFO2 0x0134
+#define RK3368_WIN3_DSP_ST2 0x0138
+#define RK3368_WIN3_DST_ALPHA_CTRL 0x013c
+#define RK3368_WIN3_MST3 0x0140
+#define RK3368_WIN3_DSP_INFO3 0x0144
+#define RK3368_WIN3_DSP_ST3 0x0148
+#define RK3368_WIN3_FADING_CTRL 0x014c
+#define RK3368_HWC_CTRL0 0x0150
+#define RK3368_HWC_CTRL1 0x0154
+#define RK3368_HWC_MST 0x0158
+#define RK3368_HWC_DSP_ST 0x015c
+#define RK3368_HWC_SRC_ALPHA_CTRL 0x0160
+#define RK3368_HWC_DST_ALPHA_CTRL 0x0164
+#define RK3368_HWC_FADING_CTRL 0x0168
+#define RK3368_HWC_RESERVED1 0x016c
+#define RK3368_POST_DSP_HACT_INFO 0x0170
+#define RK3368_POST_DSP_VACT_INFO 0x0174
+#define RK3368_POST_SCL_FACTOR_YRGB 0x0178
+#define RK3368_POST_RESERVED 0x017c
+#define RK3368_POST_SCL_CTRL 0x0180
+#define RK3368_POST_DSP_VACT_INFO_F1 0x0184
+#define RK3368_DSP_HTOTAL_HS_END 0x0188
+#define RK3368_DSP_HACT_ST_END 0x018c
+#define RK3368_DSP_VTOTAL_VS_END 0x0190
+#define RK3368_DSP_VACT_ST_END 0x0194
+#define RK3368_DSP_VS_ST_END_F1 0x0198
+#define RK3368_DSP_VACT_ST_END_F1 0x019c
+#define RK3368_PWM_CTRL 0x01a0
+#define RK3368_PWM_PERIOD_HPR 0x01a4
+#define RK3368_PWM_DUTY_LPR 0x01a8
+#define RK3368_PWM_CNT 0x01ac
+#define RK3368_BCSH_COLOR_BAR 0x01b0
+#define RK3368_BCSH_BCS 0x01b4
+#define RK3368_BCSH_H 0x01b8
+#define RK3368_BCSH_CTRL 0x01bc
+#define RK3368_CABC_CTRL0 0x01c0
+#define RK3368_CABC_CTRL1 0x01c4
+#define RK3368_CABC_CTRL2 0x01c8
+#define RK3368_CABC_CTRL3 0x01cc
+#define RK3368_CABC_GAUSS_LINE0_0 0x01d0
+#define RK3368_CABC_GAUSS_LINE0_1 0x01d4
+#define RK3368_CABC_GAUSS_LINE1_0 0x01d8
+#define RK3368_CABC_GAUSS_LINE1_1 0x01dc
+#define RK3368_CABC_GAUSS_LINE2_0 0x01e0
+#define RK3368_CABC_GAUSS_LINE2_1 0x01e4
+#define RK3368_FRC_LOWER01_0 0x01e8
+#define RK3368_FRC_LOWER01_1 0x01ec
+#define RK3368_FRC_LOWER10_0 0x01f0
+#define RK3368_FRC_LOWER10_1 0x01f4
+#define RK3368_FRC_LOWER11_0 0x01f8
+#define RK3368_FRC_LOWER11_1 0x01fc
+#define RK3368_IFBDC_CTRL 0x0200
+#define RK3368_IFBDC_TILES_NUM 0x0204
+#define RK3368_IFBDC_FRAME_RST_CYCLE 0x0208
+#define RK3368_IFBDC_BASE_ADDR 0x020c
+#define RK3368_IFBDC_MB_SIZE 0x0210
+#define RK3368_IFBDC_CMP_INDEX_INIT 0x0214
+#define RK3368_IFBDC_VIR 0x0220
+#define RK3368_IFBDC_DEBUG0 0x0230
+#define RK3368_IFBDC_DEBUG1 0x0234
+#define RK3368_LATENCY_CTRL0 0x0250
+#define RK3368_RD_MAX_LATENCY_NUM0 0x0254
+#define RK3368_RD_LATENCY_THR_NUM0 0x0258
+#define RK3368_RD_LATENCY_SAMP_NUM0 0x025c
+#define RK3368_WIN0_DSP_BG 0x0260
+#define RK3368_WIN1_DSP_BG 0x0264
+#define RK3368_WIN2_DSP_BG 0x0268
+#define RK3368_WIN3_DSP_BG 0x026c
+#define RK3368_SCAN_LINE_NUM 0x0270
+#define RK3368_CABC_DEBUG0 0x0274
+#define RK3368_CABC_DEBUG1 0x0278
+#define RK3368_CABC_DEBUG2 0x027c
+#define RK3368_DBG_REG_000 0x0280
+#define RK3368_DBG_REG_001 0x0284
+#define RK3368_DBG_REG_002 0x0288
+#define RK3368_DBG_REG_003 0x028c
+#define RK3368_DBG_REG_004 0x0290
+#define RK3368_DBG_REG_005 0x0294
+#define RK3368_DBG_REG_006 0x0298
+#define RK3368_DBG_REG_007 0x029c
+#define RK3368_DBG_REG_008 0x02a0
+#define RK3368_DBG_REG_016 0x02c0
+#define RK3368_DBG_REG_017 0x02c4
+#define RK3368_DBG_REG_018 0x02c8
+#define RK3368_DBG_REG_019 0x02cc
+#define RK3368_DBG_REG_020 0x02d0
+#define RK3368_DBG_REG_021 0x02d4
+#define RK3368_DBG_REG_022 0x02d8
+#define RK3368_DBG_REG_023 0x02dc
+#define RK3368_DBG_REG_028 0x02f0
+#define RK3368_MMU_DTE_ADDR 0x0300
+#define RK3368_MMU_STATUS 0x0304
+#define RK3368_MMU_COMMAND 0x0308
+#define RK3368_MMU_PAGE_FAULT_ADDR 0x030c
+#define RK3368_MMU_ZAP_ONE_LINE 0x0310
+#define RK3368_MMU_INT_RAWSTAT 0x0314
+#define RK3368_MMU_INT_CLEAR 0x0318
+#define RK3368_MMU_INT_MASK 0x031c
+#define RK3368_MMU_INT_STATUS 0x0320
+#define RK3368_MMU_AUTO_GATING 0x0324
+#define RK3368_WIN2_LUT_ADDR 0x0400
+#define RK3368_WIN3_LUT_ADDR 0x0800
+#define RK3368_HWC_LUT_ADDR 0x0c00
+#define RK3368_GAMMA_LUT_ADDR 0x1000
+#define RK3368_CABC_GAMMA_LUT_ADDR 0x1800
+#define RK3368_MCU_BYPASS_WPORT 0x2200
+#define RK3368_MCU_BYPASS_RPORT 0x2300
+/* rk3368 register definition end */
+
+#define RK3366_REG_CFG_DONE 0x0000
+#define RK3366_VERSION_INFO 0x0004
+#define RK3366_SYS_CTRL 0x0008
+#define RK3366_SYS_CTRL1 0x000c
+#define RK3366_DSP_CTRL0 0x0010
+#define RK3366_DSP_CTRL1 0x0014
+#define RK3366_DSP_BG 0x0018
+#define RK3366_MCU_CTRL 0x001c
+#define RK3366_WB_CTRL0 0x0020
+#define RK3366_WB_CTRL1 0x0024
+#define RK3366_WB_YRGB_MST 0x0028
+#define RK3366_WB_CBR_MST 0x002c
+#define RK3366_WIN0_CTRL0 0x0030
+#define RK3366_WIN0_CTRL1 0x0034
+#define RK3366_WIN0_COLOR_KEY 0x0038
+#define RK3366_WIN0_VIR 0x003c
+#define RK3366_WIN0_YRGB_MST 0x0040
+#define RK3366_WIN0_CBR_MST 0x0044
+#define RK3366_WIN0_ACT_INFO 0x0048
+#define RK3366_WIN0_DSP_INFO 0x004c
+#define RK3366_WIN0_DSP_ST 0x0050
+#define RK3366_WIN0_SCL_FACTOR_YRGB 0x0054
+#define RK3366_WIN0_SCL_FACTOR_CBR 0x0058
+#define RK3366_WIN0_SCL_OFFSET 0x005c
+#define RK3366_WIN0_SRC_ALPHA_CTRL 0x0060
+#define RK3366_WIN0_DST_ALPHA_CTRL 0x0064
+#define RK3366_WIN0_FADING_CTRL 0x0068
+#define RK3366_WIN0_CTRL2 0x006c
+#define RK3366_WIN1_CTRL0 0x0070
+#define RK3366_WIN1_CTRL1 0x0074
+#define RK3366_WIN1_COLOR_KEY 0x0078
+#define RK3366_WIN1_VIR 0x007c
+#define RK3366_WIN1_YRGB_MST 0x0080
+#define RK3366_WIN1_CBR_MST 0x0084
+#define RK3366_WIN1_ACT_INFO 0x0088
+#define RK3366_WIN1_DSP_INFO 0x008c
+#define RK3366_WIN1_DSP_ST 0x0090
+#define RK3366_WIN1_SCL_FACTOR_YRGB 0x0094
+#define RK3366_WIN1_SCL_FACTOR_CBR 0x0098
+#define RK3366_WIN1_SCL_OFFSET 0x009c
+#define RK3366_WIN1_SRC_ALPHA_CTRL 0x00a0
+#define RK3366_WIN1_DST_ALPHA_CTRL 0x00a4
+#define RK3366_WIN1_FADING_CTRL 0x00a8
+#define RK3366_WIN1_CTRL2 0x00ac
+#define RK3366_WIN2_CTRL0 0x00b0
+#define RK3366_WIN2_CTRL1 0x00b4
+#define RK3366_WIN2_VIR0_1 0x00b8
+#define RK3366_WIN2_VIR2_3 0x00bc
+#define RK3366_WIN2_MST0 0x00c0
+#define RK3366_WIN2_DSP_INFO0 0x00c4
+#define RK3366_WIN2_DSP_ST0 0x00c8
+#define RK3366_WIN2_COLOR_KEY 0x00cc
+#define RK3366_WIN2_MST1 0x00d0
+#define RK3366_WIN2_DSP_INFO1 0x00d4
+#define RK3366_WIN2_DSP_ST1 0x00d8
+#define RK3366_WIN2_SRC_ALPHA_CTRL 0x00dc
+#define RK3366_WIN2_MST2 0x00e0
+#define RK3366_WIN2_DSP_INFO2 0x00e4
+#define RK3366_WIN2_DSP_ST2 0x00e8
+#define RK3366_WIN2_DST_ALPHA_CTRL 0x00ec
+#define RK3366_WIN2_MST3 0x00f0
+#define RK3366_WIN2_DSP_INFO3 0x00f4
+#define RK3366_WIN2_DSP_ST3 0x00f8
+#define RK3366_WIN2_FADING_CTRL 0x00fc
+#define RK3366_WIN3_CTRL0 0x0100
+#define RK3366_WIN3_CTRL1 0x0104
+#define RK3366_WIN3_VIR0_1 0x0108
+#define RK3366_WIN3_VIR2_3 0x010c
+#define RK3366_WIN3_MST0 0x0110
+#define RK3366_WIN3_DSP_INFO0 0x0114
+#define RK3366_WIN3_DSP_ST0 0x0118
+#define RK3366_WIN3_COLOR_KEY 0x011c
+#define RK3366_WIN3_MST1 0x0120
+#define RK3366_WIN3_DSP_INFO1 0x0124
+#define RK3366_WIN3_DSP_ST1 0x0128
+#define RK3366_WIN3_SRC_ALPHA_CTRL 0x012c
+#define RK3366_WIN3_MST2 0x0130
+#define RK3366_WIN3_DSP_INFO2 0x0134
+#define RK3366_WIN3_DSP_ST2 0x0138
+#define RK3366_WIN3_DST_ALPHA_CTRL 0x013c
+#define RK3366_WIN3_MST3 0x0140
+#define RK3366_WIN3_DSP_INFO3 0x0144
+#define RK3366_WIN3_DSP_ST3 0x0148
+#define RK3366_WIN3_FADING_CTRL 0x014c
+#define RK3366_HWC_CTRL0 0x0150
+#define RK3366_HWC_CTRL1 0x0154
+#define RK3366_HWC_MST 0x0158
+#define RK3366_HWC_DSP_ST 0x015c
+#define RK3366_HWC_SRC_ALPHA_CTRL 0x0160
+#define RK3366_HWC_DST_ALPHA_CTRL 0x0164
+#define RK3366_HWC_FADING_CTRL 0x0168
+#define RK3366_HWC_RESERVED1 0x016c
+#define RK3366_POST_DSP_HACT_INFO 0x0170
+#define RK3366_POST_DSP_VACT_INFO 0x0174
+#define RK3366_POST_SCL_FACTOR_YRGB 0x0178
+#define RK3366_POST_RESERVED 0x017c
+#define RK3366_POST_SCL_CTRL 0x0180
+#define RK3366_POST_DSP_VACT_INFO_F1 0x0184
+#define RK3366_DSP_HTOTAL_HS_END 0x0188
+#define RK3366_DSP_HACT_ST_END 0x018c
+#define RK3366_DSP_VTOTAL_VS_END 0x0190
+#define RK3366_DSP_VACT_ST_END 0x0194
+#define RK3366_DSP_VS_ST_END_F1 0x0198
+#define RK3366_DSP_VACT_ST_END_F1 0x019c
+#define RK3366_PWM_CTRL 0x01a0
+#define RK3366_PWM_PERIOD_HPR 0x01a4
+#define RK3366_PWM_DUTY_LPR 0x01a8
+#define RK3366_PWM_CNT 0x01ac
+#define RK3366_BCSH_COLOR_BAR 0x01b0
+#define RK3366_BCSH_BCS 0x01b4
+#define RK3366_BCSH_H 0x01b8
+#define RK3366_BCSH_CTRL 0x01bc
+#define RK3366_CABC_CTRL0 0x01c0
+#define RK3366_CABC_CTRL1 0x01c4
+#define RK3366_CABC_CTRL2 0x01c8
+#define RK3366_CABC_CTRL3 0x01cc
+#define RK3366_CABC_GAUSS_LINE0_0 0x01d0
+#define RK3366_CABC_GAUSS_LINE0_1 0x01d4
+#define RK3366_CABC_GAUSS_LINE1_0 0x01d8
+#define RK3366_CABC_GAUSS_LINE1_1 0x01dc
+#define RK3366_CABC_GAUSS_LINE2_0 0x01e0
+#define RK3366_CABC_GAUSS_LINE2_1 0x01e4
+#define RK3366_FRC_LOWER01_0 0x01e8
+#define RK3366_FRC_LOWER01_1 0x01ec
+#define RK3366_FRC_LOWER10_0 0x01f0
+#define RK3366_FRC_LOWER10_1 0x01f4
+#define RK3366_FRC_LOWER11_0 0x01f8
+#define RK3366_FRC_LOWER11_1 0x01fc
+#define RK3366_INTR_EN0 0x0280
+#define RK3366_INTR_CLEAR0 0x0284
+#define RK3366_INTR_STATUS0 0x0288
+#define RK3366_INTR_RAW_STATUS0 0x028c
+#define RK3366_INTR_EN1 0x0290
+#define RK3366_INTR_CLEAR1 0x0294
+#define RK3366_INTR_STATUS1 0x0298
+#define RK3366_INTR_RAW_STATUS1 0x029c
+#define RK3366_LINE_FLAG 0x02a0
+#define RK3366_VOP_STATUS 0x02a4
+#define RK3366_BLANKING_VALUE 0x02a8
+#define RK3366_WIN0_DSP_BG 0x02b0
+#define RK3366_WIN1_DSP_BG 0x02b4
+#define RK3366_WIN2_DSP_BG 0x02b8
+#define RK3366_WIN3_DSP_BG 0x02bc
+#define RK3366_WIN2_LUT_ADDR 0x0400
+#define RK3366_WIN3_LUT_ADDR 0x0800
+#define RK3366_HWC_LUT_ADDR 0x0c00
+#define RK3366_GAMMA0_LUT_ADDR 0x1000
+#define RK3366_GAMMA1_LUT_ADDR 0x1400
+#define RK3366_CABC_GAMMA_LUT_ADDR 0x1800
+#define RK3366_MCU_BYPASS_WPORT 0x2200
+#define RK3366_MCU_BYPASS_RPORT 0x2300
+#define RK3366_MMU_DTE_ADDR 0x2400
+#define RK3366_MMU_STATUS 0x2404
+#define RK3366_MMU_COMMAND 0x2408
+#define RK3366_MMU_PAGE_FAULT_ADDR 0x240c
+#define RK3366_MMU_ZAP_ONE_LINE 0x2410
+#define RK3366_MMU_INT_RAWSTAT 0x2414
+#define RK3366_MMU_INT_CLEAR 0x2418
+#define RK3366_MMU_INT_MASK 0x241c
+#define RK3366_MMU_INT_STATUS 0x2420
+#define RK3366_MMU_AUTO_GATING 0x2424
+
+/* rk3399 register definition */
+#define RK3399_REG_CFG_DONE 0x0000
+#define RK3399_VERSION_INFO 0x0004
+#define RK3399_SYS_CTRL 0x0008
+#define RK3399_SYS_CTRL1 0x000c
+#define RK3399_DSP_CTRL0 0x0010
+#define RK3399_DSP_CTRL1 0x0014
+#define RK3399_DSP_BG 0x0018
+#define RK3399_MCU_CTRL 0x001c
+#define RK3399_WB_CTRL0 0x0020
+#define RK3399_WB_CTRL1 0x0024
+#define RK3399_WB_YRGB_MST 0x0028
+#define RK3399_WB_CBR_MST 0x002c
+#define RK3399_WIN0_CTRL0 0x0030
+#define RK3399_WIN0_CTRL1 0x0034
+#define RK3399_WIN0_COLOR_KEY 0x0038
+#define RK3399_WIN0_VIR 0x003c
+#define RK3399_WIN0_YRGB_MST 0x0040
+#define RK3399_WIN0_CBR_MST 0x0044
+#define RK3399_WIN0_ACT_INFO 0x0048
+#define RK3399_WIN0_DSP_INFO 0x004c
+#define RK3399_WIN0_DSP_ST 0x0050
+#define RK3399_WIN0_SCL_FACTOR_YRGB 0x0054
+#define RK3399_WIN0_SCL_FACTOR_CBR 0x0058
+#define RK3399_WIN0_SCL_OFFSET 0x005c
+#define RK3399_WIN0_SRC_ALPHA_CTRL 0x0060
+#define RK3399_WIN0_DST_ALPHA_CTRL 0x0064
+#define RK3399_WIN0_FADING_CTRL 0x0068
+#define RK3399_WIN0_CTRL2 0x006c
+#define RK3399_WIN1_CTRL0 0x0070
+#define RK3399_WIN1_CTRL1 0x0074
+#define RK3399_WIN1_COLOR_KEY 0x0078
+#define RK3399_WIN1_VIR 0x007c
+#define RK3399_WIN1_YRGB_MST 0x0080
+#define RK3399_WIN1_CBR_MST 0x0084
+#define RK3399_WIN1_ACT_INFO 0x0088
+#define RK3399_WIN1_DSP_INFO 0x008c
+#define RK3399_WIN1_DSP_ST 0x0090
+#define RK3399_WIN1_SCL_FACTOR_YRGB 0x0094
+#define RK3399_WIN1_SCL_FACTOR_CBR 0x0098
+#define RK3399_WIN1_SCL_OFFSET 0x009c
+#define RK3399_WIN1_SRC_ALPHA_CTRL 0x00a0
+#define RK3399_WIN1_DST_ALPHA_CTRL 0x00a4
+#define RK3399_WIN1_FADING_CTRL 0x00a8
+#define RK3399_WIN1_CTRL2 0x00ac
+#define RK3399_WIN2_CTRL0 0x00b0
+#define RK3399_WIN2_CTRL1 0x00b4
+#define RK3399_WIN2_VIR0_1 0x00b8
+#define RK3399_WIN2_VIR2_3 0x00bc
+#define RK3399_WIN2_MST0 0x00c0
+#define RK3399_WIN2_DSP_INFO0 0x00c4
+#define RK3399_WIN2_DSP_ST0 0x00c8
+#define RK3399_WIN2_COLOR_KEY 0x00cc
+#define RK3399_WIN2_MST1 0x00d0
+#define RK3399_WIN2_DSP_INFO1 0x00d4
+#define RK3399_WIN2_DSP_ST1 0x00d8
+#define RK3399_WIN2_SRC_ALPHA_CTRL 0x00dc
+#define RK3399_WIN2_MST2 0x00e0
+#define RK3399_WIN2_DSP_INFO2 0x00e4
+#define RK3399_WIN2_DSP_ST2 0x00e8
+#define RK3399_WIN2_DST_ALPHA_CTRL 0x00ec
+#define RK3399_WIN2_MST3 0x00f0
+#define RK3399_WIN2_DSP_INFO3 0x00f4
+#define RK3399_WIN2_DSP_ST3 0x00f8
+#define RK3399_WIN2_FADING_CTRL 0x00fc
+#define RK3399_WIN3_CTRL0 0x0100
+#define RK3399_WIN3_CTRL1 0x0104
+#define RK3399_WIN3_VIR0_1 0x0108
+#define RK3399_WIN3_VIR2_3 0x010c
+#define RK3399_WIN3_MST0 0x0110
+#define RK3399_WIN3_DSP_INFO0 0x0114
+#define RK3399_WIN3_DSP_ST0 0x0118
+#define RK3399_WIN3_COLOR_KEY 0x011c
+#define RK3399_WIN3_MST1 0x0120
+#define RK3399_WIN3_DSP_INFO1 0x0124
+#define RK3399_WIN3_DSP_ST1 0x0128
+#define RK3399_WIN3_SRC_ALPHA_CTRL 0x012c
+#define RK3399_WIN3_MST2 0x0130
+#define RK3399_WIN3_DSP_INFO2 0x0134
+#define RK3399_WIN3_DSP_ST2 0x0138
+#define RK3399_WIN3_DST_ALPHA_CTRL 0x013c
+#define RK3399_WIN3_MST3 0x0140
+#define RK3399_WIN3_DSP_INFO3 0x0144
+#define RK3399_WIN3_DSP_ST3 0x0148
+#define RK3399_WIN3_FADING_CTRL 0x014c
+#define RK3399_HWC_CTRL0 0x0150
+#define RK3399_HWC_CTRL1 0x0154
+#define RK3399_HWC_MST 0x0158
+#define RK3399_HWC_DSP_ST 0x015c
+#define RK3399_HWC_SRC_ALPHA_CTRL 0x0160
+#define RK3399_HWC_DST_ALPHA_CTRL 0x0164
+#define RK3399_HWC_FADING_CTRL 0x0168
+#define RK3399_HWC_RESERVED1 0x016c
+#define RK3399_POST_DSP_HACT_INFO 0x0170
+#define RK3399_POST_DSP_VACT_INFO 0x0174
+#define RK3399_POST_SCL_FACTOR_YRGB 0x0178
+#define RK3399_POST_RESERVED 0x017c
+#define RK3399_POST_SCL_CTRL 0x0180
+#define RK3399_POST_DSP_VACT_INFO_F1 0x0184
+#define RK3399_DSP_HTOTAL_HS_END 0x0188
+#define RK3399_DSP_HACT_ST_END 0x018c
+#define RK3399_DSP_VTOTAL_VS_END 0x0190
+#define RK3399_DSP_VACT_ST_END 0x0194
+#define RK3399_DSP_VS_ST_END_F1 0x0198
+#define RK3399_DSP_VACT_ST_END_F1 0x019c
+#define RK3399_PWM_CTRL 0x01a0
+#define RK3399_PWM_PERIOD_HPR 0x01a4
+#define RK3399_PWM_DUTY_LPR 0x01a8
+#define RK3399_PWM_CNT 0x01ac
+#define RK3399_BCSH_COLOR_BAR 0x01b0
+#define RK3399_BCSH_BCS 0x01b4
+#define RK3399_BCSH_H 0x01b8
+#define RK3399_BCSH_CTRL 0x01bc
+#define RK3399_CABC_CTRL0 0x01c0
+#define RK3399_CABC_CTRL1 0x01c4
+#define RK3399_CABC_CTRL2 0x01c8
+#define RK3399_CABC_CTRL3 0x01cc
+#define RK3399_CABC_GAUSS_LINE0_0 0x01d0
+#define RK3399_CABC_GAUSS_LINE0_1 0x01d4
+#define RK3399_CABC_GAUSS_LINE1_0 0x01d8
+#define RK3399_CABC_GAUSS_LINE1_1 0x01dc
+#define RK3399_CABC_GAUSS_LINE2_0 0x01e0
+#define RK3399_CABC_GAUSS_LINE2_1 0x01e4
+#define RK3399_FRC_LOWER01_0 0x01e8
+#define RK3399_FRC_LOWER01_1 0x01ec
+#define RK3399_FRC_LOWER10_0 0x01f0
+#define RK3399_FRC_LOWER10_1 0x01f4
+#define RK3399_FRC_LOWER11_0 0x01f8
+#define RK3399_FRC_LOWER11_1 0x01fc
+#define RK3399_AFBCD0_CTRL 0x0200
+#define RK3399_AFBCD0_HDR_PTR 0x0204
+#define RK3399_AFBCD0_PIC_SIZE 0x0208
+#define RK3399_AFBCD0_STATUS 0x020c
+#define RK3399_AFBCD1_CTRL 0x0220
+#define RK3399_AFBCD1_HDR_PTR 0x0224
+#define RK3399_AFBCD1_PIC_SIZE 0x0228
+#define RK3399_AFBCD1_STATUS 0x022c
+#define RK3399_AFBCD2_CTRL 0x0240
+#define RK3399_AFBCD2_HDR_PTR 0x0244
+#define RK3399_AFBCD2_PIC_SIZE 0x0248
+#define RK3399_AFBCD2_STATUS 0x024c
+#define RK3399_AFBCD3_CTRL 0x0260
+#define RK3399_AFBCD3_HDR_PTR 0x0264
+#define RK3399_AFBCD3_PIC_SIZE 0x0268
+#define RK3399_AFBCD3_STATUS 0x026c
+#define RK3399_INTR_EN0 0x0280
+#define RK3399_INTR_CLEAR0 0x0284
+#define RK3399_INTR_STATUS0 0x0288
+#define RK3399_INTR_RAW_STATUS0 0x028c
+#define RK3399_INTR_EN1 0x0290
+#define RK3399_INTR_CLEAR1 0x0294
+#define RK3399_INTR_STATUS1 0x0298
+#define RK3399_INTR_RAW_STATUS1 0x029c
+#define RK3399_LINE_FLAG 0x02a0
+#define RK3399_VOP_STATUS 0x02a4
+#define RK3399_BLANKING_VALUE 0x02a8
+#define RK3399_MCU_BYPASS_PORT 0x02ac
+#define RK3399_WIN0_DSP_BG 0x02b0
+#define RK3399_WIN1_DSP_BG 0x02b4
+#define RK3399_WIN2_DSP_BG 0x02b8
+#define RK3399_WIN3_DSP_BG 0x02bc
+#define RK3399_YUV2YUV_WIN 0x02c0
+#define RK3399_YUV2YUV_POST 0x02c4
+#define RK3399_AUTO_GATING_EN 0x02cc
+#define RK3399_WIN0_CSC_COE 0x03a0
+#define RK3399_WIN1_CSC_COE 0x03c0
+#define RK3399_WIN2_CSC_COE 0x03e0
+#define RK3399_WIN3_CSC_COE 0x0400
+#define RK3399_HWC_CSC_COE 0x0420
+#define RK3399_BCSH_R2Y_CSC_COE 0x0440
+#define RK3399_BCSH_Y2R_CSC_COE 0x0460
+#define RK3399_POST_YUV2YUV_Y2R_COE 0x0480
+#define RK3399_POST_YUV2YUV_3X3_COE 0x04a0
+#define RK3399_POST_YUV2YUV_R2Y_COE 0x04c0
+#define RK3399_WIN0_YUV2YUV_Y2R 0x04e0
+#define RK3399_WIN0_YUV2YUV_3X3 0x0500
+#define RK3399_WIN0_YUV2YUV_R2Y 0x0520
+#define RK3399_WIN1_YUV2YUV_Y2R 0x0540
+#define RK3399_WIN1_YUV2YUV_3X3 0x0560
+#define RK3399_WIN1_YUV2YUV_R2Y 0x0580
+#define RK3399_WIN2_YUV2YUV_Y2R 0x05a0
+#define RK3399_WIN2_YUV2YUV_3X3 0x05c0
+#define RK3399_WIN2_YUV2YUV_R2Y 0x05e0
+#define RK3399_WIN3_YUV2YUV_Y2R 0x0600
+#define RK3399_WIN3_YUV2YUV_3X3 0x0620
+#define RK3399_WIN3_YUV2YUV_R2Y 0x0640
+#define RK3399_WIN2_LUT_ADDR 0x1000
+#define RK3399_WIN3_LUT_ADDR 0x1400
+#define RK3399_HWC_LUT_ADDR 0x1800
+#define RK3399_CABC_GAMMA_LUT_ADDR 0x1c00
+#define RK3399_GAMMA_LUT_ADDR 0x2000
+/* rk3399 register definition end */
+
+/* rk3328 register definition end */
+#define RK3328_REG_CFG_DONE 0x00000000
+#define RK3328_VERSION_INFO 0x00000004
+#define RK3328_SYS_CTRL 0x00000008
+#define RK3328_SYS_CTRL1 0x0000000c
+#define RK3328_DSP_CTRL0 0x00000010
+#define RK3328_DSP_CTRL1 0x00000014
+#define RK3328_DSP_BG 0x00000018
+#define RK3328_AUTO_GATING_EN 0x0000003c
+#define RK3328_LINE_FLAG 0x00000040
+#define RK3328_VOP_STATUS 0x00000044
+#define RK3328_BLANKING_VALUE 0x00000048
+#define RK3328_WIN0_DSP_BG 0x00000050
+#define RK3328_WIN1_DSP_BG 0x00000054
+#define RK3328_DBG_PERF_LATENCY_CTRL0 0x000000c0
+#define RK3328_DBG_PERF_RD_MAX_LATENCY_NUM0 0x000000c4
+#define RK3328_DBG_PERF_RD_LATENCY_THR_NUM0 0x000000c8
+#define RK3328_DBG_PERF_RD_LATENCY_SAMP_NUM0 0x000000cc
+#define RK3328_INTR_EN0 0x000000e0
+#define RK3328_INTR_CLEAR0 0x000000e4
+#define RK3328_INTR_STATUS0 0x000000e8
+#define RK3328_INTR_RAW_STATUS0 0x000000ec
+#define RK3328_INTR_EN1 0x000000f0
+#define RK3328_INTR_CLEAR1 0x000000f4
+#define RK3328_INTR_STATUS1 0x000000f8
+#define RK3328_INTR_RAW_STATUS1 0x000000fc
+#define RK3328_WIN0_CTRL0 0x00000100
+#define RK3328_WIN0_CTRL1 0x00000104
+#define RK3328_WIN0_COLOR_KEY 0x00000108
+#define RK3328_WIN0_VIR 0x0000010c
+#define RK3328_WIN0_YRGB_MST 0x00000110
+#define RK3328_WIN0_CBR_MST 0x00000114
+#define RK3328_WIN0_ACT_INFO 0x00000118
+#define RK3328_WIN0_DSP_INFO 0x0000011c
+#define RK3328_WIN0_DSP_ST 0x00000120
+#define RK3328_WIN0_SCL_FACTOR_YRGB 0x00000124
+#define RK3328_WIN0_SCL_FACTOR_CBR 0x00000128
+#define RK3328_WIN0_SCL_OFFSET 0x0000012c
+#define RK3328_WIN0_SRC_ALPHA_CTRL 0x00000130
+#define RK3328_WIN0_DST_ALPHA_CTRL 0x00000134
+#define RK3328_WIN0_FADING_CTRL 0x00000138
+#define RK3328_WIN0_CTRL2 0x0000013c
+#define RK3328_DBG_WIN0_REG0 0x000001f0
+#define RK3328_DBG_WIN0_REG1 0x000001f4
+#define RK3328_DBG_WIN0_REG2 0x000001f8
+#define RK3328_DBG_WIN0_RESERVED 0x000001fc
+#define RK3328_WIN1_CTRL0 0x00000200
+#define RK3328_WIN1_CTRL1 0x00000204
+#define RK3328_WIN1_COLOR_KEY 0x00000208
+#define RK3328_WIN1_VIR 0x0000020c
+#define RK3328_WIN1_YRGB_MST 0x00000210
+#define RK3328_WIN1_CBR_MST 0x00000214
+#define RK3328_WIN1_ACT_INFO 0x00000218
+#define RK3328_WIN1_DSP_INFO 0x0000021c
+#define RK3328_WIN1_DSP_ST 0x00000220
+#define RK3328_WIN1_SCL_FACTOR_YRGB 0x00000224
+#define RK3328_WIN1_SCL_FACTOR_CBR 0x00000228
+#define RK3328_WIN1_SCL_OFFSET 0x0000022c
+#define RK3328_WIN1_SRC_ALPHA_CTRL 0x00000230
+#define RK3328_WIN1_DST_ALPHA_CTRL 0x00000234
+#define RK3328_WIN1_FADING_CTRL 0x00000238
+#define RK3328_WIN1_CTRL2 0x0000023c
+#define RK3328_DBG_WIN1_REG0 0x000002f0
+#define RK3328_DBG_WIN1_REG1 0x000002f4
+#define RK3328_DBG_WIN1_REG2 0x000002f8
+#define RK3328_DBG_WIN1_RESERVED 0x000002fc
+#define RK3328_WIN2_CTRL0 0x00000300
+#define RK3328_WIN2_CTRL1 0x00000304
+#define RK3328_WIN2_COLOR_KEY 0x00000308
+#define RK3328_WIN2_VIR 0x0000030c
+#define RK3328_WIN2_YRGB_MST 0x00000310
+#define RK3328_WIN2_CBR_MST 0x00000314
+#define RK3328_WIN2_ACT_INFO 0x00000318
+#define RK3328_WIN2_DSP_INFO 0x0000031c
+#define RK3328_WIN2_DSP_ST 0x00000320
+#define RK3328_WIN2_SCL_FACTOR_YRGB 0x00000324
+#define RK3328_WIN2_SCL_FACTOR_CBR 0x00000328
+#define RK3328_WIN2_SCL_OFFSET 0x0000032c
+#define RK3328_WIN2_SRC_ALPHA_CTRL 0x00000330
+#define RK3328_WIN2_DST_ALPHA_CTRL 0x00000334
+#define RK3328_WIN2_FADING_CTRL 0x00000338
+#define RK3328_WIN2_CTRL2 0x0000033c
+#define RK3328_DBG_WIN2_REG0 0x000003f0
+#define RK3328_DBG_WIN2_REG1 0x000003f4
+#define RK3328_DBG_WIN2_REG2 0x000003f8
+#define RK3328_DBG_WIN2_RESERVED 0x000003fc
+#define RK3328_WIN3_CTRL0 0x00000400
+#define RK3328_WIN3_CTRL1 0x00000404
+#define RK3328_WIN3_COLOR_KEY 0x00000408
+#define RK3328_WIN3_VIR 0x0000040c
+#define RK3328_WIN3_YRGB_MST 0x00000410
+#define RK3328_WIN3_CBR_MST 0x00000414
+#define RK3328_WIN3_ACT_INFO 0x00000418
+#define RK3328_WIN3_DSP_INFO 0x0000041c
+#define RK3328_WIN3_DSP_ST 0x00000420
+#define RK3328_WIN3_SCL_FACTOR_YRGB 0x00000424
+#define RK3328_WIN3_SCL_FACTOR_CBR 0x00000428
+#define RK3328_WIN3_SCL_OFFSET 0x0000042c
+#define RK3328_WIN3_SRC_ALPHA_CTRL 0x00000430
+#define RK3328_WIN3_DST_ALPHA_CTRL 0x00000434
+#define RK3328_WIN3_FADING_CTRL 0x00000438
+#define RK3328_WIN3_CTRL2 0x0000043c
+#define RK3328_DBG_WIN3_REG0 0x000004f0
+#define RK3328_DBG_WIN3_REG1 0x000004f4
+#define RK3328_DBG_WIN3_REG2 0x000004f8
+#define RK3328_DBG_WIN3_RESERVED 0x000004fc
+
+#define RK3328_HWC_CTRL0 0x00000500
+#define RK3328_HWC_CTRL1 0x00000504
+#define RK3328_HWC_MST 0x00000508
+#define RK3328_HWC_DSP_ST 0x0000050c
+#define RK3328_HWC_SRC_ALPHA_CTRL 0x00000510
+#define RK3328_HWC_DST_ALPHA_CTRL 0x00000514
+#define RK3328_HWC_FADING_CTRL 0x00000518
+#define RK3328_HWC_RESERVED1 0x0000051c
+#define RK3328_POST_DSP_HACT_INFO 0x00000600
+#define RK3328_POST_DSP_VACT_INFO 0x00000604
+#define RK3328_POST_SCL_FACTOR_YRGB 0x00000608
+#define RK3328_POST_RESERVED 0x0000060c
+#define RK3328_POST_SCL_CTRL 0x00000610
+#define RK3328_POST_DSP_VACT_INFO_F1 0x00000614
+#define RK3328_DSP_HTOTAL_HS_END 0x00000618
+#define RK3328_DSP_HACT_ST_END 0x0000061c
+#define RK3328_DSP_VTOTAL_VS_END 0x00000620
+#define RK3328_DSP_VACT_ST_END 0x00000624
+#define RK3328_DSP_VS_ST_END_F1 0x00000628
+#define RK3328_DSP_VACT_ST_END_F1 0x0000062c
+#define RK3328_BCSH_COLOR_BAR 0x00000640
+#define RK3328_BCSH_BCS 0x00000644
+#define RK3328_BCSH_H 0x00000648
+#define RK3328_BCSH_CTRL 0x0000064c
+#define RK3328_FRC_LOWER01_0 0x00000678
+#define RK3328_FRC_LOWER01_1 0x0000067c
+#define RK3328_FRC_LOWER10_0 0x00000680
+#define RK3328_FRC_LOWER10_1 0x00000684
+#define RK3328_FRC_LOWER11_0 0x00000688
+#define RK3328_FRC_LOWER11_1 0x0000068c
+#define RK3328_DBG_POST_REG0 0x000006e8
+#define RK3328_DBG_POST_RESERVED 0x000006ec
+#define RK3328_DBG_DATAO 0x000006f0
+#define RK3328_DBG_DATAO_2 0x000006f4
+
+/* sdr to hdr */
+#define RK3328_SDR2HDR_CTRL 0x00000700
+#define RK3328_EOTF_OETF_Y0 0x00000704
+#define RK3328_RESERVED0001 0x00000708
+#define RK3328_RESERVED0002 0x0000070c
+#define RK3328_EOTF_OETF_Y1 0x00000710
+#define RK3328_EOTF_OETF_Y64 0x0000080c
+#define RK3328_OETF_DX_DXPOW1 0x00000810
+#define RK3328_OETF_DX_DXPOW64 0x0000090c
+#define RK3328_OETF_XN1 0x00000910
+#define RK3328_OETF_XN63 0x00000a08
+
+/* hdr to sdr */
+#define RK3328_HDR2SDR_CTRL 0x00000a10
+#define RK3328_HDR2SDR_SRC_RANGE 0x00000a14
+#define RK3328_HDR2SDR_NORMFACEETF 0x00000a18
+#define RK3328_RESERVED0003 0x00000a1c
+#define RK3328_HDR2SDR_DST_RANGE 0x00000a20
+#define RK3328_HDR2SDR_NORMFACCGAMMA 0x00000a24
+#define RK3328_EETF_OETF_Y0 0x00000a28
+#define RK3328_SAT_Y0 0x00000a2c
+#define RK3328_EETF_OETF_Y1 0x00000a30
+#define RK3328_SAT_Y1 0x00000ab0
+#define RK3328_SAT_Y8 0x00000acc
+
+#define RK3328_HWC_LUT_ADDR 0x00000c00
+
/* rk3036 register definition */
#define RK3036_SYS_CTRL 0x00
#define RK3036_DSP_CTRL0 0x04
@@ -166,197 +878,4 @@
#define RK3036_HWC_LUT_ADDR 0x800
/* rk3036 register definition end */
-/* rk3399 register definition */
-#define RK3399_REG_CFG_DONE 0x00000
-#define RK3399_VERSION_INFO 0x00004
-#define RK3399_SYS_CTRL 0x00008
-#define RK3399_SYS_CTRL1 0x0000c
-#define RK3399_DSP_CTRL0 0x00010
-#define RK3399_DSP_CTRL1 0x00014
-#define RK3399_DSP_BG 0x00018
-#define RK3399_MCU_CTRL 0x0001c
-#define RK3399_WB_CTRL0 0x00020
-#define RK3399_WB_CTRL1 0x00024
-#define RK3399_WB_YRGB_MST 0x00028
-#define RK3399_WB_CBR_MST 0x0002c
-#define RK3399_WIN0_CTRL0 0x00030
-#define RK3399_WIN0_CTRL1 0x00034
-#define RK3399_WIN0_COLOR_KEY 0x00038
-#define RK3399_WIN0_VIR 0x0003c
-#define RK3399_WIN0_YRGB_MST 0x00040
-#define RK3399_WIN0_CBR_MST 0x00044
-#define RK3399_WIN0_ACT_INFO 0x00048
-#define RK3399_WIN0_DSP_INFO 0x0004c
-#define RK3399_WIN0_DSP_ST 0x00050
-#define RK3399_WIN0_SCL_FACTOR_YRGB 0x00054
-#define RK3399_WIN0_SCL_FACTOR_CBR 0x00058
-#define RK3399_WIN0_SCL_OFFSET 0x0005c
-#define RK3399_WIN0_SRC_ALPHA_CTRL 0x00060
-#define RK3399_WIN0_DST_ALPHA_CTRL 0x00064
-#define RK3399_WIN0_FADING_CTRL 0x00068
-#define RK3399_WIN0_CTRL2 0x0006c
-#define RK3399_WIN1_CTRL0 0x00070
-#define RK3399_WIN1_CTRL1 0x00074
-#define RK3399_WIN1_COLOR_KEY 0x00078
-#define RK3399_WIN1_VIR 0x0007c
-#define RK3399_WIN1_YRGB_MST 0x00080
-#define RK3399_WIN1_CBR_MST 0x00084
-#define RK3399_WIN1_ACT_INFO 0x00088
-#define RK3399_WIN1_DSP_INFO 0x0008c
-#define RK3399_WIN1_DSP_ST 0x00090
-#define RK3399_WIN1_SCL_FACTOR_YRGB 0x00094
-#define RK3399_WIN1_SCL_FACTOR_CBR 0x00098
-#define RK3399_WIN1_SCL_OFFSET 0x0009c
-#define RK3399_WIN1_SRC_ALPHA_CTRL 0x000a0
-#define RK3399_WIN1_DST_ALPHA_CTRL 0x000a4
-#define RK3399_WIN1_FADING_CTRL 0x000a8
-#define RK3399_WIN1_CTRL2 0x000ac
-#define RK3399_WIN2_CTRL0 0x000b0
-#define RK3399_WIN2_CTRL1 0x000b4
-#define RK3399_WIN2_VIR0_1 0x000b8
-#define RK3399_WIN2_VIR2_3 0x000bc
-#define RK3399_WIN2_MST0 0x000c0
-#define RK3399_WIN2_DSP_INFO0 0x000c4
-#define RK3399_WIN2_DSP_ST0 0x000c8
-#define RK3399_WIN2_COLOR_KEY 0x000cc
-#define RK3399_WIN2_MST1 0x000d0
-#define RK3399_WIN2_DSP_INFO1 0x000d4
-#define RK3399_WIN2_DSP_ST1 0x000d8
-#define RK3399_WIN2_SRC_ALPHA_CTRL 0x000dc
-#define RK3399_WIN2_MST2 0x000e0
-#define RK3399_WIN2_DSP_INFO2 0x000e4
-#define RK3399_WIN2_DSP_ST2 0x000e8
-#define RK3399_WIN2_DST_ALPHA_CTRL 0x000ec
-#define RK3399_WIN2_MST3 0x000f0
-#define RK3399_WIN2_DSP_INFO3 0x000f4
-#define RK3399_WIN2_DSP_ST3 0x000f8
-#define RK3399_WIN2_FADING_CTRL 0x000fc
-#define RK3399_WIN3_CTRL0 0x00100
-#define RK3399_WIN3_CTRL1 0x00104
-#define RK3399_WIN3_VIR0_1 0x00108
-#define RK3399_WIN3_VIR2_3 0x0010c
-#define RK3399_WIN3_MST0 0x00110
-#define RK3399_WIN3_DSP_INFO0 0x00114
-#define RK3399_WIN3_DSP_ST0 0x00118
-#define RK3399_WIN3_COLOR_KEY 0x0011c
-#define RK3399_WIN3_MST1 0x00120
-#define RK3399_WIN3_DSP_INFO1 0x00124
-#define RK3399_WIN3_DSP_ST1 0x00128
-#define RK3399_WIN3_SRC_ALPHA_CTRL 0x0012c
-#define RK3399_WIN3_MST2 0x00130
-#define RK3399_WIN3_DSP_INFO2 0x00134
-#define RK3399_WIN3_DSP_ST2 0x00138
-#define RK3399_WIN3_DST_ALPHA_CTRL 0x0013c
-#define RK3399_WIN3_MST3 0x00140
-#define RK3399_WIN3_DSP_INFO3 0x00144
-#define RK3399_WIN3_DSP_ST3 0x00148
-#define RK3399_WIN3_FADING_CTRL 0x0014c
-#define RK3399_HWC_CTRL0 0x00150
-#define RK3399_HWC_CTRL1 0x00154
-#define RK3399_HWC_MST 0x00158
-#define RK3399_HWC_DSP_ST 0x0015c
-#define RK3399_HWC_SRC_ALPHA_CTRL 0x00160
-#define RK3399_HWC_DST_ALPHA_CTRL 0x00164
-#define RK3399_HWC_FADING_CTRL 0x00168
-#define RK3399_HWC_RESERVED1 0x0016c
-#define RK3399_POST_DSP_HACT_INFO 0x00170
-#define RK3399_POST_DSP_VACT_INFO 0x00174
-#define RK3399_POST_SCL_FACTOR_YRGB 0x00178
-#define RK3399_POST_RESERVED 0x0017c
-#define RK3399_POST_SCL_CTRL 0x00180
-#define RK3399_POST_DSP_VACT_INFO_F1 0x00184
-#define RK3399_DSP_HTOTAL_HS_END 0x00188
-#define RK3399_DSP_HACT_ST_END 0x0018c
-#define RK3399_DSP_VTOTAL_VS_END 0x00190
-#define RK3399_DSP_VACT_ST_END 0x00194
-#define RK3399_DSP_VS_ST_END_F1 0x00198
-#define RK3399_DSP_VACT_ST_END_F1 0x0019c
-#define RK3399_PWM_CTRL 0x001a0
-#define RK3399_PWM_PERIOD_HPR 0x001a4
-#define RK3399_PWM_DUTY_LPR 0x001a8
-#define RK3399_PWM_CNT 0x001ac
-#define RK3399_BCSH_COLOR_BAR 0x001b0
-#define RK3399_BCSH_BCS 0x001b4
-#define RK3399_BCSH_H 0x001b8
-#define RK3399_BCSH_CTRL 0x001bc
-#define RK3399_CABC_CTRL0 0x001c0
-#define RK3399_CABC_CTRL1 0x001c4
-#define RK3399_CABC_CTRL2 0x001c8
-#define RK3399_CABC_CTRL3 0x001cc
-#define RK3399_CABC_GAUSS_LINE0_0 0x001d0
-#define RK3399_CABC_GAUSS_LINE0_1 0x001d4
-#define RK3399_CABC_GAUSS_LINE1_0 0x001d8
-#define RK3399_CABC_GAUSS_LINE1_1 0x001dc
-#define RK3399_CABC_GAUSS_LINE2_0 0x001e0
-#define RK3399_CABC_GAUSS_LINE2_1 0x001e4
-#define RK3399_FRC_LOWER01_0 0x001e8
-#define RK3399_FRC_LOWER01_1 0x001ec
-#define RK3399_FRC_LOWER10_0 0x001f0
-#define RK3399_FRC_LOWER10_1 0x001f4
-#define RK3399_FRC_LOWER11_0 0x001f8
-#define RK3399_FRC_LOWER11_1 0x001fc
-#define RK3399_AFBCD0_CTRL 0x00200
-#define RK3399_AFBCD0_HDR_PTR 0x00204
-#define RK3399_AFBCD0_PIC_SIZE 0x00208
-#define RK3399_AFBCD0_STATUS 0x0020c
-#define RK3399_AFBCD1_CTRL 0x00220
-#define RK3399_AFBCD1_HDR_PTR 0x00224
-#define RK3399_AFBCD1_PIC_SIZE 0x00228
-#define RK3399_AFBCD1_STATUS 0x0022c
-#define RK3399_AFBCD2_CTRL 0x00240
-#define RK3399_AFBCD2_HDR_PTR 0x00244
-#define RK3399_AFBCD2_PIC_SIZE 0x00248
-#define RK3399_AFBCD2_STATUS 0x0024c
-#define RK3399_AFBCD3_CTRL 0x00260
-#define RK3399_AFBCD3_HDR_PTR 0x00264
-#define RK3399_AFBCD3_PIC_SIZE 0x00268
-#define RK3399_AFBCD3_STATUS 0x0026c
-#define RK3399_INTR_EN0 0x00280
-#define RK3399_INTR_CLEAR0 0x00284
-#define RK3399_INTR_STATUS0 0x00288
-#define RK3399_INTR_RAW_STATUS0 0x0028c
-#define RK3399_INTR_EN1 0x00290
-#define RK3399_INTR_CLEAR1 0x00294
-#define RK3399_INTR_STATUS1 0x00298
-#define RK3399_INTR_RAW_STATUS1 0x0029c
-#define RK3399_LINE_FLAG 0x002a0
-#define RK3399_VOP_STATUS 0x002a4
-#define RK3399_BLANKING_VALUE 0x002a8
-#define RK3399_MCU_BYPASS_PORT 0x002ac
-#define RK3399_WIN0_DSP_BG 0x002b0
-#define RK3399_WIN1_DSP_BG 0x002b4
-#define RK3399_WIN2_DSP_BG 0x002b8
-#define RK3399_WIN3_DSP_BG 0x002bc
-#define RK3399_YUV2YUV_WIN 0x002c0
-#define RK3399_YUV2YUV_POST 0x002c4
-#define RK3399_AUTO_GATING_EN 0x002cc
-#define RK3399_WIN0_CSC_COE 0x003a0
-#define RK3399_WIN1_CSC_COE 0x003c0
-#define RK3399_WIN2_CSC_COE 0x003e0
-#define RK3399_WIN3_CSC_COE 0x00400
-#define RK3399_HWC_CSC_COE 0x00420
-#define RK3399_BCSH_R2Y_CSC_COE 0x00440
-#define RK3399_BCSH_Y2R_CSC_COE 0x00460
-#define RK3399_POST_YUV2YUV_Y2R_COE 0x00480
-#define RK3399_POST_YUV2YUV_3X3_COE 0x004a0
-#define RK3399_POST_YUV2YUV_R2Y_COE 0x004c0
-#define RK3399_WIN0_YUV2YUV_Y2R 0x004e0
-#define RK3399_WIN0_YUV2YUV_3X3 0x00500
-#define RK3399_WIN0_YUV2YUV_R2Y 0x00520
-#define RK3399_WIN1_YUV2YUV_Y2R 0x00540
-#define RK3399_WIN1_YUV2YUV_3X3 0x00560
-#define RK3399_WIN1_YUV2YUV_R2Y 0x00580
-#define RK3399_WIN2_YUV2YUV_Y2R 0x005a0
-#define RK3399_WIN2_YUV2YUV_3X3 0x005c0
-#define RK3399_WIN2_YUV2YUV_R2Y 0x005e0
-#define RK3399_WIN3_YUV2YUV_Y2R 0x00600
-#define RK3399_WIN3_YUV2YUV_3X3 0x00620
-#define RK3399_WIN3_YUV2YUV_R2Y 0x00640
-#define RK3399_WIN2_LUT_ADDR 0x01000
-#define RK3399_WIN3_LUT_ADDR 0x01400
-#define RK3399_HWC_LUT_ADDR 0x01800
-#define RK3399_CABC_GAMMA_LUT_ADDR 0x01c00
-#define RK3399_GAMMA_LUT_ADDR 0x02000
-/* rk3399 register definition end */
-
#endif /* _ROCKCHIP_VOP_REG_H */
diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c
index 78c6d8e9b42c..2bddeb8bf457 100644
--- a/drivers/gpu/drm/savage/savage_drv.c
+++ b/drivers/gpu/drm/savage/savage_drv.c
@@ -55,7 +55,6 @@ static struct drm_driver driver = {
.preclose = savage_reclaim_buffers,
.lastclose = savage_driver_lastclose,
.unload = savage_driver_unload,
- .set_busid = drm_pci_set_busid,
.ioctls = savage_ioctls,
.dma_ioctl = savage_bci_buffers,
.fops = &savage_driver_fops,
@@ -75,12 +74,12 @@ static struct pci_driver savage_pci_driver = {
static int __init savage_init(void)
{
driver.num_ioctls = savage_max_ioctl;
- return drm_pci_init(&driver, &savage_pci_driver);
+ return drm_legacy_pci_init(&driver, &savage_pci_driver);
}
static void __exit savage_exit(void)
{
- drm_pci_exit(&driver, &savage_pci_driver);
+ drm_legacy_pci_exit(&driver, &savage_pci_driver);
}
module_init(savage_init);
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
index 800d1d2c435d..592572554eb0 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
@@ -145,8 +145,6 @@ static struct drm_driver shmob_drm_driver = {
.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
.gem_prime_mmap = drm_gem_cma_prime_mmap,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.fops = &shmob_drm_fops,
.name = "shmob-drm",
.desc = "Renesas SH Mobile DRM",
@@ -277,7 +275,7 @@ static int shmob_drm_probe(struct platform_device *pdev)
ret = drm_irq_install(ddev, platform_get_irq(pdev, 0));
if (ret < 0) {
dev_err(&pdev->dev, "failed to install IRQ handler\n");
- goto err_vblank_cleanup;
+ goto err_modeset_cleanup;
}
/*
@@ -292,8 +290,6 @@ static int shmob_drm_probe(struct platform_device *pdev)
err_irq_uninstall:
drm_irq_uninstall(ddev);
-err_vblank_cleanup:
- drm_vblank_cleanup(ddev);
err_modeset_cleanup:
drm_kms_helper_poll_fini(ddev);
drm_mode_config_cleanup(ddev);
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c
index 7f05da13ea5e..e04a92658cd7 100644
--- a/drivers/gpu/drm/sis/sis_drv.c
+++ b/drivers/gpu/drm/sis/sis_drv.c
@@ -104,7 +104,6 @@ static struct drm_driver driver = {
.open = sis_driver_open,
.preclose = sis_reclaim_buffers_locked,
.postclose = sis_driver_postclose,
- .set_busid = drm_pci_set_busid,
.dma_quiescent = sis_idle,
.lastclose = sis_lastclose,
.ioctls = sis_ioctls,
@@ -125,12 +124,12 @@ static struct pci_driver sis_pci_driver = {
static int __init sis_init(void)
{
driver.num_ioctls = sis_max_ioctl;
- return drm_pci_init(&driver, &sis_pci_driver);
+ return drm_legacy_pci_init(&driver, &sis_pci_driver);
}
static void __exit sis_exit(void)
{
- drm_pci_exit(&driver, &sis_pci_driver);
+ drm_legacy_pci_exit(&driver, &sis_pci_driver);
}
module_init(sis_init);
diff --git a/drivers/gpu/drm/sti/sti_crtc.c b/drivers/gpu/drm/sti/sti_crtc.c
index d45a4335df5d..e8a4d48e985a 100644
--- a/drivers/gpu/drm/sti/sti_crtc.c
+++ b/drivers/gpu/drm/sti/sti_crtc.c
@@ -20,7 +20,8 @@
#include "sti_vid.h"
#include "sti_vtg.h"
-static void sti_crtc_enable(struct drm_crtc *crtc)
+static void sti_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct sti_mixer *mixer = to_sti_mixer(crtc);
@@ -31,7 +32,8 @@ static void sti_crtc_enable(struct drm_crtc *crtc)
drm_crtc_vblank_on(crtc);
}
-static void sti_crtc_disabling(struct drm_crtc *crtc)
+static void sti_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct sti_mixer *mixer = to_sti_mixer(crtc);
@@ -222,10 +224,10 @@ static void sti_crtc_atomic_flush(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = {
- .enable = sti_crtc_enable,
- .disable = sti_crtc_disabling,
.mode_set_nofb = sti_crtc_mode_set_nofb,
.atomic_flush = sti_crtc_atomic_flush,
+ .atomic_enable = sti_crtc_atomic_enable,
+ .atomic_disable = sti_crtc_atomic_disable,
};
static void sti_crtc_destroy(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/sti/sti_cursor.c b/drivers/gpu/drm/sti/sti_cursor.c
index 5b3a41f74f21..b709ebbec095 100644
--- a/drivers/gpu/drm/sti/sti_cursor.c
+++ b/drivers/gpu/drm/sti/sti_cursor.c
@@ -348,7 +348,6 @@ static const struct drm_plane_funcs sti_cursor_plane_helpers_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = sti_cursor_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
.reset = sti_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -392,7 +391,7 @@ struct drm_plane *sti_cursor_create(struct drm_device *drm_dev,
&sti_cursor_plane_helpers_funcs,
cursor_supported_formats,
ARRAY_SIZE(cursor_supported_formats),
- DRM_PLANE_TYPE_CURSOR, NULL);
+ NULL, DRM_PLANE_TYPE_CURSOR, NULL);
if (res) {
DRM_ERROR("Failed to initialize universal plane\n");
goto err_plane;
diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
index a4b574283269..1700c542cd93 100644
--- a/drivers/gpu/drm/sti/sti_drv.c
+++ b/drivers/gpu/drm/sti/sti_drv.c
@@ -175,8 +175,6 @@ static struct drm_driver sti_driver = {
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.fops = &sti_driver_fops,
.enable_vblank = sti_crtc_enable_vblank,
@@ -237,7 +235,6 @@ static void sti_cleanup(struct drm_device *ddev)
}
drm_kms_helper_poll_fini(ddev);
- drm_vblank_cleanup(ddev);
component_unbind_all(ddev->dev, ddev);
kfree(private);
ddev->dev_private = NULL;
diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
index 24ebc6b2f34d..852bf2293b05 100644
--- a/drivers/gpu/drm/sti/sti_dvo.c
+++ b/drivers/gpu/drm/sti/sti_dvo.c
@@ -412,7 +412,6 @@ static int sti_dvo_late_register(struct drm_connector *connector)
}
static const struct drm_connector_funcs sti_dvo_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = sti_dvo_connector_detect,
.destroy = drm_connector_cleanup,
@@ -582,7 +581,7 @@ static int sti_dvo_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id dvo_of_match[] = {
+static const struct of_device_id dvo_of_match[] = {
{ .compatible = "st,stih407-dvo", },
{ /* end node */ }
};
diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c
index 5ee0503945c8..b65eea4f2c97 100644
--- a/drivers/gpu/drm/sti/sti_gdp.c
+++ b/drivers/gpu/drm/sti/sti_gdp.c
@@ -895,7 +895,6 @@ static const struct drm_plane_funcs sti_gdp_plane_helpers_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = sti_gdp_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
.reset = sti_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -931,7 +930,7 @@ struct drm_plane *sti_gdp_create(struct drm_device *drm_dev,
&sti_gdp_plane_helpers_funcs,
gdp_supported_formats,
ARRAY_SIZE(gdp_supported_formats),
- type, NULL);
+ NULL, type, NULL);
if (res) {
DRM_ERROR("Failed to initialize universal plane\n");
goto err;
diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
index d6ed909d9d75..cf65e32b5090 100644
--- a/drivers/gpu/drm/sti/sti_hda.c
+++ b/drivers/gpu/drm/sti/sti_hda.c
@@ -647,7 +647,6 @@ static int sti_hda_late_register(struct drm_connector *connector)
}
static const struct drm_connector_funcs sti_hda_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index a59c95a8081b..30f02d2fdd03 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -434,7 +434,7 @@ static int hdmi_avi_infoframe_config(struct sti_hdmi *hdmi)
DRM_DEBUG_DRIVER("\n");
- ret = drm_hdmi_avi_infoframe_from_display_mode(&infoframe, mode);
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&infoframe, mode, false);
if (ret < 0) {
DRM_ERROR("failed to setup AVI infoframe: %d\n", ret);
return ret;
@@ -1113,12 +1113,10 @@ static int sti_hdmi_late_register(struct drm_connector *connector)
}
static const struct drm_connector_funcs sti_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = sti_hdmi_connector_detect,
.destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
- .set_property = drm_atomic_helper_connector_set_property,
.atomic_set_property = sti_hdmi_connector_set_property,
.atomic_get_property = sti_hdmi_connector_get_property,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c
index a1c161f77804..b19b3430b296 100644
--- a/drivers/gpu/drm/sti/sti_hqvdp.c
+++ b/drivers/gpu/drm/sti/sti_hqvdp.c
@@ -958,6 +958,7 @@ static void sti_hqvdp_start_xp70(struct sti_hqvdp *hqvdp)
}
if (i == POLL_MAX_ATTEMPT) {
DRM_ERROR("Could not reset\n");
+ clk_disable_unprepare(hqvdp->clk);
goto out;
}
@@ -994,6 +995,7 @@ static void sti_hqvdp_start_xp70(struct sti_hqvdp *hqvdp)
}
if (i == POLL_MAX_ATTEMPT) {
DRM_ERROR("Could not boot\n");
+ clk_disable_unprepare(hqvdp->clk);
goto out;
}
@@ -1081,6 +1083,7 @@ static int sti_hqvdp_atomic_check(struct drm_plane *drm_plane,
&hqvdp->vtg_nb,
crtc)) {
DRM_ERROR("Cannot register VTG notifier\n");
+ clk_disable_unprepare(hqvdp->clk_pix_main);
return -EINVAL;
}
hqvdp->vtg_registered = true;
@@ -1273,7 +1276,6 @@ static const struct drm_plane_funcs sti_hqvdp_plane_helpers_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = sti_hqvdp_destroy,
- .set_property = drm_atomic_helper_plane_set_property,
.reset = sti_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -1295,7 +1297,7 @@ static struct drm_plane *sti_hqvdp_create(struct drm_device *drm_dev,
&sti_hqvdp_plane_helpers_funcs,
hqvdp_supported_formats,
ARRAY_SIZE(hqvdp_supported_formats),
- DRM_PLANE_TYPE_OVERLAY, NULL);
+ NULL, DRM_PLANE_TYPE_OVERLAY, NULL);
if (res) {
DRM_ERROR("Failed to initialize universal plane\n");
return NULL;
@@ -1395,7 +1397,7 @@ static int sti_hqvdp_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id hqvdp_of_match[] = {
+static const struct of_device_id hqvdp_of_match[] = {
{ .compatible = "st,stih407-hqvdp", },
{ /* end node */ }
};
diff --git a/drivers/gpu/drm/stm/Kconfig b/drivers/gpu/drm/stm/Kconfig
index 2c4817fb0890..35367ada3bc1 100644
--- a/drivers/gpu/drm/stm/Kconfig
+++ b/drivers/gpu/drm/stm/Kconfig
@@ -4,13 +4,19 @@ config DRM_STM
select DRM_KMS_HELPER
select DRM_GEM_CMA_HELPER
select DRM_KMS_CMA_HELPER
- select DRM_PANEL
+ select DRM_PANEL_BRIDGE
select VIDEOMODE_HELPERS
select FB_PROVIDE_GET_FB_UNMAPPED_AREA
- default y
help
Enable support for the on-chip display controller on
STMicroelectronics STM32 MCUs.
To compile this driver as a module, choose M here: the module
will be called stm-drm.
+
+config DRM_STM_DSI
+ tristate "STMicroelectronics specific extensions for Synopsys MIPI DSI"
+ depends on DRM_STM
+ select DRM_DW_MIPI_DSI
+ help
+ Choose this option for MIPI DSI support on STMicroelectronics SoC.
diff --git a/drivers/gpu/drm/stm/Makefile b/drivers/gpu/drm/stm/Makefile
index a09ecf450218..d883adc365a2 100644
--- a/drivers/gpu/drm/stm/Makefile
+++ b/drivers/gpu/drm/stm/Makefile
@@ -2,4 +2,6 @@ stm-drm-y := \
drv.o \
ltdc.o
+obj-$(CONFIG_DRM_STM_DSI) += dw_mipi_dsi-stm.o
+
obj-$(CONFIG_DRM_STM) += stm-drm.o
diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
index 83ab48f1fd00..b333b37f3f89 100644
--- a/drivers/gpu/drm/stm/drv.c
+++ b/drivers/gpu/drm/stm/drv.c
@@ -20,13 +20,6 @@
#include "ltdc.h"
-#define DRIVER_NAME "stm"
-#define DRIVER_DESC "STMicroelectronics SoC DRM"
-#define DRIVER_DATE "20170330"
-#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 0
-#define DRIVER_PATCH_LEVEL 0
-
#define STM_MAX_FB_WIDTH 2048
#define STM_MAX_FB_HEIGHT 2048 /* same as width to handle orientation */
@@ -59,16 +52,14 @@ static struct drm_driver drv_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
DRIVER_ATOMIC,
.lastclose = drv_lastclose,
- .name = DRIVER_NAME,
- .desc = DRIVER_DESC,
- .date = DRIVER_DATE,
- .major = DRIVER_MAJOR,
- .minor = DRIVER_MINOR,
- .patchlevel = DRIVER_PATCH_LEVEL,
+ .name = "stm",
+ .desc = "STMicroelectronics SoC DRM",
+ .date = "20170330",
+ .major = 1,
+ .minor = 0,
+ .patchlevel = 0,
.fops = &drv_driver_fops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_free_object_unlocked = drm_gem_cma_free_object,
@@ -206,7 +197,7 @@ static struct platform_driver stm_drm_platform_driver = {
.probe = stm_drm_platform_probe,
.remove = stm_drm_platform_remove,
.driver = {
- .name = DRIVER_NAME,
+ .name = "stm32-display",
.of_match_table = drv_dt_ids,
},
};
diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
new file mode 100644
index 000000000000..568c5d0461ea
--- /dev/null
+++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2017
+ *
+ * Authors: Philippe Cornu <philippe.cornu@st.com>
+ * Yannick Fertre <yannick.fertre@st.com>
+ *
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <drm/drmP.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/bridge/dw_mipi_dsi.h>
+#include <video/mipi_display.h>
+
+/* DSI wrapper register & bit definitions */
+/* Note: registers are named as in the Reference Manual */
+#define DSI_WCFGR 0x0400 /* Wrapper ConFiGuration Reg */
+#define WCFGR_DSIM BIT(0) /* DSI Mode */
+#define WCFGR_COLMUX GENMASK(3, 1) /* COLor MUltipleXing */
+
+#define DSI_WCR 0x0404 /* Wrapper Control Reg */
+#define WCR_DSIEN BIT(3) /* DSI ENable */
+
+#define DSI_WISR 0x040C /* Wrapper Interrupt and Status Reg */
+#define WISR_PLLLS BIT(8) /* PLL Lock Status */
+#define WISR_RRS BIT(12) /* Regulator Ready Status */
+
+#define DSI_WPCR0 0x0418 /* Wrapper Phy Conf Reg 0 */
+#define WPCR0_UIX4 GENMASK(5, 0) /* Unit Interval X 4 */
+#define WPCR0_TDDL BIT(16) /* Turn Disable Data Lanes */
+
+#define DSI_WRPCR 0x0430 /* Wrapper Regulator & Pll Ctrl Reg */
+#define WRPCR_PLLEN BIT(0) /* PLL ENable */
+#define WRPCR_NDIV GENMASK(8, 2) /* pll loop DIVision Factor */
+#define WRPCR_IDF GENMASK(14, 11) /* pll Input Division Factor */
+#define WRPCR_ODF GENMASK(17, 16) /* pll Output Division Factor */
+#define WRPCR_REGEN BIT(24) /* REGulator ENable */
+#define WRPCR_BGREN BIT(28) /* BandGap Reference ENable */
+#define IDF_MIN 1
+#define IDF_MAX 7
+#define NDIV_MIN 10
+#define NDIV_MAX 125
+#define ODF_MIN 1
+#define ODF_MAX 8
+
+/* dsi color format coding according to the datasheet */
+enum dsi_color {
+ DSI_RGB565_CONF1,
+ DSI_RGB565_CONF2,
+ DSI_RGB565_CONF3,
+ DSI_RGB666_CONF1,
+ DSI_RGB666_CONF2,
+ DSI_RGB888,
+};
+
+#define LANE_MIN_KBPS 31250
+#define LANE_MAX_KBPS 500000
+
+/* Sleep & timeout for regulator on/off, pll lock/unlock & fifo empty */
+#define SLEEP_US 1000
+#define TIMEOUT_US 200000
+
+struct dw_mipi_dsi_stm {
+ void __iomem *base;
+ struct clk *pllref_clk;
+};
+
+static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 val)
+{
+ writel(val, dsi->base + reg);
+}
+
+static inline u32 dsi_read(struct dw_mipi_dsi_stm *dsi, u32 reg)
+{
+ return readl(dsi->base + reg);
+}
+
+static inline void dsi_set(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask)
+{
+ dsi_write(dsi, reg, dsi_read(dsi, reg) | mask);
+}
+
+static inline void dsi_clear(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask)
+{
+ dsi_write(dsi, reg, dsi_read(dsi, reg) & ~mask);
+}
+
+static inline void dsi_update_bits(struct dw_mipi_dsi_stm *dsi, u32 reg,
+ u32 mask, u32 val)
+{
+ dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val);
+}
+
+static enum dsi_color dsi_color_from_mipi(enum mipi_dsi_pixel_format fmt)
+{
+ switch (fmt) {
+ case MIPI_DSI_FMT_RGB888:
+ return DSI_RGB888;
+ case MIPI_DSI_FMT_RGB666:
+ return DSI_RGB666_CONF2;
+ case MIPI_DSI_FMT_RGB666_PACKED:
+ return DSI_RGB666_CONF1;
+ case MIPI_DSI_FMT_RGB565:
+ return DSI_RGB565_CONF1;
+ default:
+ DRM_DEBUG_DRIVER("MIPI color invalid, so we use rgb888\n");
+ }
+ return DSI_RGB888;
+}
+
+static int dsi_pll_get_clkout_khz(int clkin_khz, int idf, int ndiv, int odf)
+{
+ /* prevent from division by 0 */
+ if (idf * odf)
+ return DIV_ROUND_CLOSEST(clkin_khz * ndiv, idf * odf);
+
+ return 0;
+}
+
+static int dsi_pll_get_params(int clkin_khz, int clkout_khz,
+ int *idf, int *ndiv, int *odf)
+{
+ int i, o, n, n_min, n_max;
+ int fvco_min, fvco_max, delta, best_delta; /* all in khz */
+
+ /* Early checks preventing division by 0 & odd results */
+ if ((clkin_khz <= 0) || (clkout_khz <= 0))
+ return -EINVAL;
+
+ fvco_min = LANE_MIN_KBPS * 2 * ODF_MAX;
+ fvco_max = LANE_MAX_KBPS * 2 * ODF_MIN;
+
+ best_delta = 1000000; /* big started value (1000000khz) */
+
+ for (i = IDF_MIN; i <= IDF_MAX; i++) {
+ /* Compute ndiv range according to Fvco */
+ n_min = ((fvco_min * i) / (2 * clkin_khz)) + 1;
+ n_max = (fvco_max * i) / (2 * clkin_khz);
+
+ /* No need to continue idf loop if we reach ndiv max */
+ if (n_min >= NDIV_MAX)
+ break;
+
+ /* Clamp ndiv to valid values */
+ if (n_min < NDIV_MIN)
+ n_min = NDIV_MIN;
+ if (n_max > NDIV_MAX)
+ n_max = NDIV_MAX;
+
+ for (o = ODF_MIN; o <= ODF_MAX; o *= 2) {
+ n = DIV_ROUND_CLOSEST(i * o * clkout_khz, clkin_khz);
+ /* Check ndiv according to vco range */
+ if ((n < n_min) || (n > n_max))
+ continue;
+ /* Check if new delta is better & saves parameters */
+ delta = dsi_pll_get_clkout_khz(clkin_khz, i, n, o) -
+ clkout_khz;
+ if (delta < 0)
+ delta = -delta;
+ if (delta < best_delta) {
+ *idf = i;
+ *ndiv = n;
+ *odf = o;
+ best_delta = delta;
+ }
+ /* fast return in case of "perfect result" */
+ if (!delta)
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+static int dw_mipi_dsi_phy_init(void *priv_data)
+{
+ struct dw_mipi_dsi_stm *dsi = priv_data;
+ u32 val;
+ int ret;
+
+ /* Enable the regulator */
+ dsi_set(dsi, DSI_WRPCR, WRPCR_REGEN | WRPCR_BGREN);
+ ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_RRS,
+ SLEEP_US, TIMEOUT_US);
+ if (ret)
+ DRM_DEBUG_DRIVER("!TIMEOUT! waiting REGU, let's continue\n");
+
+ /* Enable the DSI PLL & wait for its lock */
+ dsi_set(dsi, DSI_WRPCR, WRPCR_PLLEN);
+ ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_PLLLS,
+ SLEEP_US, TIMEOUT_US);
+ if (ret)
+ DRM_DEBUG_DRIVER("!TIMEOUT! waiting PLL, let's continue\n");
+
+ /* Enable the DSI wrapper */
+ dsi_set(dsi, DSI_WCR, WCR_DSIEN);
+
+ return 0;
+}
+
+static int
+dw_mipi_dsi_get_lane_mbps(void *priv_data, struct drm_display_mode *mode,
+ unsigned long mode_flags, u32 lanes, u32 format,
+ unsigned int *lane_mbps)
+{
+ struct dw_mipi_dsi_stm *dsi = priv_data;
+ unsigned int idf, ndiv, odf, pll_in_khz, pll_out_khz;
+ int ret, bpp;
+ u32 val;
+
+ pll_in_khz = (unsigned int)(clk_get_rate(dsi->pllref_clk) / 1000);
+
+ /* Compute requested pll out */
+ bpp = mipi_dsi_pixel_format_to_bpp(format);
+ pll_out_khz = mode->clock * bpp / lanes;
+ /* Add 20% to pll out to be higher than pixel bw (burst mode only) */
+ pll_out_khz = (pll_out_khz * 12) / 10;
+ if (pll_out_khz > LANE_MAX_KBPS) {
+ pll_out_khz = LANE_MAX_KBPS;
+ DRM_WARN("Warning max phy mbps is used\n");
+ }
+ if (pll_out_khz < LANE_MIN_KBPS) {
+ pll_out_khz = LANE_MIN_KBPS;
+ DRM_WARN("Warning min phy mbps is used\n");
+ }
+
+ /* Compute best pll parameters */
+ idf = 0;
+ ndiv = 0;
+ odf = 0;
+ ret = dsi_pll_get_params(pll_in_khz, pll_out_khz, &idf, &ndiv, &odf);
+ if (ret)
+ DRM_WARN("Warning dsi_pll_get_params(): bad params\n");
+
+ /* Get the adjusted pll out value */
+ pll_out_khz = dsi_pll_get_clkout_khz(pll_in_khz, idf, ndiv, odf);
+
+ /* Set the PLL division factors */
+ dsi_update_bits(dsi, DSI_WRPCR, WRPCR_NDIV | WRPCR_IDF | WRPCR_ODF,
+ (ndiv << 2) | (idf << 11) | ((ffs(odf) - 1) << 16));
+
+ /* Compute uix4 & set the bit period in high-speed mode */
+ val = 4000000 / pll_out_khz;
+ dsi_update_bits(dsi, DSI_WPCR0, WPCR0_UIX4, val);
+
+ /* Select video mode by resetting DSIM bit */
+ dsi_clear(dsi, DSI_WCFGR, WCFGR_DSIM);
+
+ /* Select the color coding */
+ dsi_update_bits(dsi, DSI_WCFGR, WCFGR_COLMUX,
+ dsi_color_from_mipi(format) << 1);
+
+ *lane_mbps = pll_out_khz / 1000;
+
+ DRM_DEBUG_DRIVER("pll_in %ukHz pll_out %ukHz lane_mbps %uMHz\n",
+ pll_in_khz, pll_out_khz, *lane_mbps);
+
+ return 0;
+}
+
+static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_stm_phy_ops = {
+ .init = dw_mipi_dsi_phy_init,
+ .get_lane_mbps = dw_mipi_dsi_get_lane_mbps,
+};
+
+static struct dw_mipi_dsi_plat_data dw_mipi_dsi_stm_plat_data = {
+ .max_data_lanes = 2,
+ .phy_ops = &dw_mipi_dsi_stm_phy_ops,
+};
+
+static const struct of_device_id dw_mipi_dsi_stm_dt_ids[] = {
+ { .compatible = "st,stm32-dsi", .data = &dw_mipi_dsi_stm_plat_data, },
+ { },
+};
+MODULE_DEVICE_TABLE(of, dw_mipi_dsi_stm_dt_ids);
+
+static int dw_mipi_dsi_stm_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct dw_mipi_dsi_stm *dsi;
+ struct resource *res;
+ int ret;
+
+ dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
+ if (!dsi)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ DRM_ERROR("Unable to get resource\n");
+ return -ENODEV;
+ }
+
+ dsi->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(dsi->base)) {
+ DRM_ERROR("Unable to get dsi registers\n");
+ return PTR_ERR(dsi->base);
+ }
+
+ dsi->pllref_clk = devm_clk_get(dev, "ref");
+ if (IS_ERR(dsi->pllref_clk)) {
+ ret = PTR_ERR(dsi->pllref_clk);
+ dev_err(dev, "Unable to get pll reference clock: %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(dsi->pllref_clk);
+ if (ret) {
+ dev_err(dev, "%s: Failed to enable pllref_clk\n", __func__);
+ return ret;
+ }
+
+ dw_mipi_dsi_stm_plat_data.base = dsi->base;
+ dw_mipi_dsi_stm_plat_data.priv_data = dsi;
+
+ ret = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data);
+ if (ret) {
+ DRM_ERROR("Failed to initialize mipi dsi host\n");
+ clk_disable_unprepare(dsi->pllref_clk);
+ }
+
+ return ret;
+}
+
+static int dw_mipi_dsi_stm_remove(struct platform_device *pdev)
+{
+ struct dw_mipi_dsi_stm *dsi = dw_mipi_dsi_stm_plat_data.priv_data;
+
+ clk_disable_unprepare(dsi->pllref_clk);
+ dw_mipi_dsi_remove(pdev);
+
+ return 0;
+}
+
+static struct platform_driver dw_mipi_dsi_stm_driver = {
+ .probe = dw_mipi_dsi_stm_probe,
+ .remove = dw_mipi_dsi_stm_remove,
+ .driver = {
+ .of_match_table = dw_mipi_dsi_stm_dt_ids,
+ .name = "dw_mipi_dsi-stm",
+ },
+};
+
+module_platform_driver(dw_mipi_dsi_stm_driver);
+
+MODULE_AUTHOR("Philippe Cornu <philippe.cornu@st.com>");
+MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics DW MIPI DSI host controller driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index 1b9483d4f2a4..d394a03632c4 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -21,7 +21,7 @@
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_of.h>
-#include <drm/drm_panel.h>
+#include <drm/drm_bridge.h>
#include <drm/drm_plane_helper.h>
#include <video/videomode.h>
@@ -42,52 +42,52 @@
* an extra offset specified with reg_ofs.
*/
#define REG_OFS_NONE 0
-#define REG_OFS_4 4 /* Insertion of "Layer Configuration 2" reg */
+#define REG_OFS_4 4 /* Insertion of "Layer Conf. 2" reg */
#define REG_OFS (ldev->caps.reg_ofs)
-#define LAY_OFS 0x80 /* Register Offset between 2 layers */
+#define LAY_OFS 0x80 /* Register Offset between 2 layers */
/* Global register offsets */
-#define LTDC_IDR 0x0000 /* IDentification */
-#define LTDC_LCR 0x0004 /* Layer Count */
-#define LTDC_SSCR 0x0008 /* Synchronization Size Configuration */
-#define LTDC_BPCR 0x000C /* Back Porch Configuration */
-#define LTDC_AWCR 0x0010 /* Active Width Configuration */
-#define LTDC_TWCR 0x0014 /* Total Width Configuration */
-#define LTDC_GCR 0x0018 /* Global Control */
-#define LTDC_GC1R 0x001C /* Global Configuration 1 */
-#define LTDC_GC2R 0x0020 /* Global Configuration 2 */
-#define LTDC_SRCR 0x0024 /* Shadow Reload Configuration */
-#define LTDC_GACR 0x0028 /* GAmma Correction */
-#define LTDC_BCCR 0x002C /* Background Color Configuration */
-#define LTDC_IER 0x0034 /* Interrupt Enable */
-#define LTDC_ISR 0x0038 /* Interrupt Status */
-#define LTDC_ICR 0x003C /* Interrupt Clear */
-#define LTDC_LIPCR 0x0040 /* Line Interrupt Position Configuration */
-#define LTDC_CPSR 0x0044 /* Current Position Status */
-#define LTDC_CDSR 0x0048 /* Current Display Status */
+#define LTDC_IDR 0x0000 /* IDentification */
+#define LTDC_LCR 0x0004 /* Layer Count */
+#define LTDC_SSCR 0x0008 /* Synchronization Size Configuration */
+#define LTDC_BPCR 0x000C /* Back Porch Configuration */
+#define LTDC_AWCR 0x0010 /* Active Width Configuration */
+#define LTDC_TWCR 0x0014 /* Total Width Configuration */
+#define LTDC_GCR 0x0018 /* Global Control */
+#define LTDC_GC1R 0x001C /* Global Configuration 1 */
+#define LTDC_GC2R 0x0020 /* Global Configuration 2 */
+#define LTDC_SRCR 0x0024 /* Shadow Reload Configuration */
+#define LTDC_GACR 0x0028 /* GAmma Correction */
+#define LTDC_BCCR 0x002C /* Background Color Configuration */
+#define LTDC_IER 0x0034 /* Interrupt Enable */
+#define LTDC_ISR 0x0038 /* Interrupt Status */
+#define LTDC_ICR 0x003C /* Interrupt Clear */
+#define LTDC_LIPCR 0x0040 /* Line Interrupt Position Conf. */
+#define LTDC_CPSR 0x0044 /* Current Position Status */
+#define LTDC_CDSR 0x0048 /* Current Display Status */
/* Layer register offsets */
-#define LTDC_L1LC1R (0x0080) /* L1 Layer Configuration 1 */
-#define LTDC_L1LC2R (0x0084) /* L1 Layer Configuration 2 */
-#define LTDC_L1CR (0x0084 + REG_OFS) /* L1 Control */
-#define LTDC_L1WHPCR (0x0088 + REG_OFS) /* L1 Window Hor Position Config */
-#define LTDC_L1WVPCR (0x008C + REG_OFS) /* L1 Window Vert Position Config */
-#define LTDC_L1CKCR (0x0090 + REG_OFS) /* L1 Color Keying Configuration */
-#define LTDC_L1PFCR (0x0094 + REG_OFS) /* L1 Pixel Format Configuration */
-#define LTDC_L1CACR (0x0098 + REG_OFS) /* L1 Constant Alpha Config */
-#define LTDC_L1DCCR (0x009C + REG_OFS) /* L1 Default Color Configuration */
-#define LTDC_L1BFCR (0x00A0 + REG_OFS) /* L1 Blend Factors Configuration */
-#define LTDC_L1FBBCR (0x00A4 + REG_OFS) /* L1 FrameBuffer Bus Control */
-#define LTDC_L1AFBCR (0x00A8 + REG_OFS) /* L1 AuxFB Control */
-#define LTDC_L1CFBAR (0x00AC + REG_OFS) /* L1 Color FrameBuffer Address */
-#define LTDC_L1CFBLR (0x00B0 + REG_OFS) /* L1 Color FrameBuffer Length */
-#define LTDC_L1CFBLNR (0x00B4 + REG_OFS) /* L1 Color FrameBuffer Line Nb */
-#define LTDC_L1AFBAR (0x00B8 + REG_OFS) /* L1 AuxFB Address */
-#define LTDC_L1AFBLR (0x00BC + REG_OFS) /* L1 AuxFB Length */
-#define LTDC_L1AFBLNR (0x00C0 + REG_OFS) /* L1 AuxFB Line Number */
-#define LTDC_L1CLUTWR (0x00C4 + REG_OFS) /* L1 CLUT Write */
-#define LTDC_L1YS1R (0x00E0 + REG_OFS) /* L1 YCbCr Scale 1 */
-#define LTDC_L1YS2R (0x00E4 + REG_OFS) /* L1 YCbCr Scale 2 */
+#define LTDC_L1LC1R (0x80) /* L1 Layer Configuration 1 */
+#define LTDC_L1LC2R (0x84) /* L1 Layer Configuration 2 */
+#define LTDC_L1CR (0x84 + REG_OFS)/* L1 Control */
+#define LTDC_L1WHPCR (0x88 + REG_OFS)/* L1 Window Hor Position Config */
+#define LTDC_L1WVPCR (0x8C + REG_OFS)/* L1 Window Vert Position Config */
+#define LTDC_L1CKCR (0x90 + REG_OFS)/* L1 Color Keying Configuration */
+#define LTDC_L1PFCR (0x94 + REG_OFS)/* L1 Pixel Format Configuration */
+#define LTDC_L1CACR (0x98 + REG_OFS)/* L1 Constant Alpha Config */
+#define LTDC_L1DCCR (0x9C + REG_OFS)/* L1 Default Color Configuration */
+#define LTDC_L1BFCR (0xA0 + REG_OFS)/* L1 Blend Factors Configuration */
+#define LTDC_L1FBBCR (0xA4 + REG_OFS)/* L1 FrameBuffer Bus Control */
+#define LTDC_L1AFBCR (0xA8 + REG_OFS)/* L1 AuxFB Control */
+#define LTDC_L1CFBAR (0xAC + REG_OFS)/* L1 Color FrameBuffer Address */
+#define LTDC_L1CFBLR (0xB0 + REG_OFS)/* L1 Color FrameBuffer Length */
+#define LTDC_L1CFBLNR (0xB4 + REG_OFS)/* L1 Color FrameBuffer Line Nb */
+#define LTDC_L1AFBAR (0xB8 + REG_OFS)/* L1 AuxFB Address */
+#define LTDC_L1AFBLR (0xBC + REG_OFS)/* L1 AuxFB Length */
+#define LTDC_L1AFBLNR (0xC0 + REG_OFS)/* L1 AuxFB Line Number */
+#define LTDC_L1CLUTWR (0xC4 + REG_OFS)/* L1 CLUT Write */
+#define LTDC_L1YS1R (0xE0 + REG_OFS)/* L1 YCbCr Scale 1 */
+#define LTDC_L1YS2R (0xE4 + REG_OFS)/* L1 YCbCr Scale 2 */
/* Bit definitions */
#define SSCR_VSH GENMASK(10, 0) /* Vertical Synchronization Height */
@@ -104,10 +104,10 @@
#define GCR_LTDCEN BIT(0) /* LTDC ENable */
#define GCR_DEN BIT(16) /* Dither ENable */
-#define GCR_PCPOL BIT(28) /* Pixel Clock POLarity */
-#define GCR_DEPOL BIT(29) /* Data Enable POLarity */
-#define GCR_VSPOL BIT(30) /* Vertical Synchro POLarity */
-#define GCR_HSPOL BIT(31) /* Horizontal Synchro POLarity */
+#define GCR_PCPOL BIT(28) /* Pixel Clock POLarity-Inverted */
+#define GCR_DEPOL BIT(29) /* Data Enable POLarity-High */
+#define GCR_VSPOL BIT(30) /* Vertical Synchro POLarity-High */
+#define GCR_HSPOL BIT(31) /* Horizontal Synchro POLarity-High */
#define GC1R_WBCH GENMASK(3, 0) /* Width of Blue CHannel output */
#define GC1R_WGCH GENMASK(7, 4) /* Width of Green Channel output */
@@ -172,60 +172,52 @@
#define LXCFBLR_CFBLL GENMASK(12, 0) /* Color Frame Buffer Line Length */
#define LXCFBLR_CFBP GENMASK(28, 16) /* Color Frame Buffer Pitch in bytes */
-#define LXCFBLNR_CFBLN GENMASK(10, 0) /* Color Frame Buffer Line Number */
+#define LXCFBLNR_CFBLN GENMASK(10, 0) /* Color Frame Buffer Line Number */
-#define HSPOL_AL 0 /* Horizontal Sync POLarity Active Low */
-#define VSPOL_AL 0 /* Vertical Sync POLarity Active Low */
-#define DEPOL_AL 0 /* Data Enable POLarity Active Low */
-#define PCPOL_IPC 0 /* Input Pixel Clock */
-#define HSPOL_AH GCR_HSPOL /* Horizontal Sync POLarity Active High */
-#define VSPOL_AH GCR_VSPOL /* Vertical Sync POLarity Active High */
-#define DEPOL_AH GCR_DEPOL /* Data Enable POLarity Active High */
-#define PCPOL_IIPC GCR_PCPOL /* Inverted Input Pixel Clock */
-#define CONSTA_MAX 0xFF /* CONSTant Alpha MAX= 1.0 */
-#define BF1_PAXCA 0x600 /* Pixel Alpha x Constant Alpha */
-#define BF1_CA 0x400 /* Constant Alpha */
-#define BF2_1PAXCA 0x007 /* 1 - (Pixel Alpha x Constant Alpha) */
-#define BF2_1CA 0x005 /* 1 - Constant Alpha */
+#define CONSTA_MAX 0xFF /* CONSTant Alpha MAX= 1.0 */
+#define BF1_PAXCA 0x600 /* Pixel Alpha x Constant Alpha */
+#define BF1_CA 0x400 /* Constant Alpha */
+#define BF2_1PAXCA 0x007 /* 1 - (Pixel Alpha x Constant Alpha) */
+#define BF2_1CA 0x005 /* 1 - Constant Alpha */
-#define NB_PF 8 /* Max nb of HW pixel format */
+#define NB_PF 8 /* Max nb of HW pixel format */
enum ltdc_pix_fmt {
PF_NONE,
/* RGB formats */
- PF_ARGB8888, /* ARGB [32 bits] */
- PF_RGBA8888, /* RGBA [32 bits] */
- PF_RGB888, /* RGB [24 bits] */
- PF_RGB565, /* RGB [16 bits] */
- PF_ARGB1555, /* ARGB A:1 bit RGB:15 bits [16 bits] */
- PF_ARGB4444, /* ARGB A:4 bits R/G/B: 4 bits each [16 bits] */
+ PF_ARGB8888, /* ARGB [32 bits] */
+ PF_RGBA8888, /* RGBA [32 bits] */
+ PF_RGB888, /* RGB [24 bits] */
+ PF_RGB565, /* RGB [16 bits] */
+ PF_ARGB1555, /* ARGB A:1 bit RGB:15 bits [16 bits] */
+ PF_ARGB4444, /* ARGB A:4 bits R/G/B: 4 bits each [16 bits] */
/* Indexed formats */
- PF_L8, /* Indexed 8 bits [8 bits] */
- PF_AL44, /* Alpha:4 bits + indexed 4 bits [8 bits] */
- PF_AL88 /* Alpha:8 bits + indexed 8 bits [16 bits] */
+ PF_L8, /* Indexed 8 bits [8 bits] */
+ PF_AL44, /* Alpha:4 bits + indexed 4 bits [8 bits] */
+ PF_AL88 /* Alpha:8 bits + indexed 8 bits [16 bits] */
};
/* The index gives the encoding of the pixel format for an HW version */
static const enum ltdc_pix_fmt ltdc_pix_fmt_a0[NB_PF] = {
- PF_ARGB8888, /* 0x00 */
- PF_RGB888, /* 0x01 */
- PF_RGB565, /* 0x02 */
- PF_ARGB1555, /* 0x03 */
- PF_ARGB4444, /* 0x04 */
- PF_L8, /* 0x05 */
- PF_AL44, /* 0x06 */
- PF_AL88 /* 0x07 */
+ PF_ARGB8888, /* 0x00 */
+ PF_RGB888, /* 0x01 */
+ PF_RGB565, /* 0x02 */
+ PF_ARGB1555, /* 0x03 */
+ PF_ARGB4444, /* 0x04 */
+ PF_L8, /* 0x05 */
+ PF_AL44, /* 0x06 */
+ PF_AL88 /* 0x07 */
};
static const enum ltdc_pix_fmt ltdc_pix_fmt_a1[NB_PF] = {
- PF_ARGB8888, /* 0x00 */
- PF_RGB888, /* 0x01 */
- PF_RGB565, /* 0x02 */
- PF_RGBA8888, /* 0x03 */
- PF_AL44, /* 0x04 */
- PF_L8, /* 0x05 */
- PF_ARGB1555, /* 0x06 */
- PF_ARGB4444 /* 0x07 */
+ PF_ARGB8888, /* 0x00 */
+ PF_RGB888, /* 0x01 */
+ PF_RGB565, /* 0x02 */
+ PF_RGBA8888, /* 0x03 */
+ PF_AL44, /* 0x04 */
+ PF_L8, /* 0x05 */
+ PF_ARGB1555, /* 0x06 */
+ PF_ARGB4444 /* 0x07 */
};
static inline u32 reg_read(void __iomem *base, u32 reg)
@@ -269,11 +261,6 @@ static inline struct ltdc_device *encoder_to_ltdc(struct drm_encoder *enc)
return (struct ltdc_device *)enc->dev->dev_private;
}
-static inline struct ltdc_device *connector_to_ltdc(struct drm_connector *con)
-{
- return (struct ltdc_device *)con->dev->dev_private;
-}
-
static inline enum ltdc_pix_fmt to_ltdc_pixelformat(u32 drm_fmt)
{
enum ltdc_pix_fmt pf;
@@ -307,7 +294,7 @@ static inline enum ltdc_pix_fmt to_ltdc_pixelformat(u32 drm_fmt)
default:
pf = PF_NONE;
break;
- /* Note: There are no DRM_FORMAT for AL44 and AL88 */
+ /* Note: There are no DRM_FORMAT for AL44 and AL88 */
}
return pf;
@@ -330,8 +317,8 @@ static inline u32 to_drm_pixelformat(enum ltdc_pix_fmt pf)
return DRM_FORMAT_ARGB4444;
case PF_L8:
return DRM_FORMAT_C8;
- case PF_AL44: /* No DRM support */
- case PF_AL88: /* No DRM support */
+ case PF_AL44: /* No DRM support */
+ case PF_AL88: /* No DRM support */
case PF_NONE:
default:
return 0;
@@ -375,18 +362,8 @@ static irqreturn_t ltdc_irq(int irq, void *arg)
* DRM_CRTC
*/
-static void ltdc_crtc_load_lut(struct drm_crtc *crtc)
-{
- struct ltdc_device *ldev = crtc_to_ltdc(crtc);
- unsigned int i, lay;
-
- for (lay = 0; lay < ldev->caps.nb_layers; lay++)
- for (i = 0; i < 256; i++)
- reg_write(ldev->regs, LTDC_L1CLUTWR + lay * LAY_OFS,
- ldev->clut[i]);
-}
-
-static void ltdc_crtc_enable(struct drm_crtc *crtc)
+static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct ltdc_device *ldev = crtc_to_ltdc(crtc);
@@ -407,7 +384,8 @@ static void ltdc_crtc_enable(struct drm_crtc *crtc)
drm_crtc_vblank_on(crtc);
}
-static void ltdc_crtc_disable(struct drm_crtc *crtc)
+static void ltdc_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct ltdc_device *ldev = crtc_to_ltdc(crtc);
@@ -462,20 +440,20 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
clk_enable(ldev->pixel_clk);
- /* Configures the HS, VS, DE and PC polarities. */
- val = HSPOL_AL | VSPOL_AL | DEPOL_AL | PCPOL_IPC;
+ /* Configures the HS, VS, DE and PC polarities. Default Active Low */
+ val = 0;
if (vm.flags & DISPLAY_FLAGS_HSYNC_HIGH)
- val |= HSPOL_AH;
+ val |= GCR_HSPOL;
if (vm.flags & DISPLAY_FLAGS_VSYNC_HIGH)
- val |= VSPOL_AH;
+ val |= GCR_VSPOL;
if (vm.flags & DISPLAY_FLAGS_DE_HIGH)
- val |= DEPOL_AH;
+ val |= GCR_DEPOL;
if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
- val |= PCPOL_IIPC;
+ val |= GCR_PCPOL;
reg_update_bits(ldev->regs, LTDC_GCR,
GCR_HSPOL | GCR_VSPOL | GCR_DEPOL | GCR_PCPOL, val);
@@ -522,12 +500,11 @@ static void ltdc_crtc_atomic_flush(struct drm_crtc *crtc,
}
}
-static struct drm_crtc_helper_funcs ltdc_crtc_helper_funcs = {
- .load_lut = ltdc_crtc_load_lut,
- .enable = ltdc_crtc_enable,
- .disable = ltdc_crtc_disable,
+static const struct drm_crtc_helper_funcs ltdc_crtc_helper_funcs = {
.mode_set_nofb = ltdc_crtc_mode_set_nofb,
.atomic_flush = ltdc_crtc_atomic_flush,
+ .atomic_enable = ltdc_crtc_atomic_enable,
+ .atomic_disable = ltdc_crtc_atomic_disable,
};
int ltdc_crtc_enable_vblank(struct drm_device *ddev, unsigned int pipe)
@@ -548,7 +525,7 @@ void ltdc_crtc_disable_vblank(struct drm_device *ddev, unsigned int pipe)
reg_clear(ldev->regs, LTDC_IER, IER_LIE);
}
-static struct drm_crtc_funcs ltdc_crtc_funcs = {
+static const struct drm_crtc_funcs ltdc_crtc_funcs = {
.destroy = drm_crtc_cleanup,
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
@@ -613,11 +590,11 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
src_w = state->src_w >> 16;
src_h = state->src_h >> 16;
- DRM_DEBUG_DRIVER(
- "plane:%d fb:%d (%dx%d)@(%d,%d) -> (%dx%d)@(%d,%d)\n",
- plane->base.id, fb->base.id,
- src_w, src_h, src_x, src_y,
- state->crtc_w, state->crtc_h, state->crtc_x, state->crtc_y);
+ DRM_DEBUG_DRIVER("plane:%d fb:%d (%dx%d)@(%d,%d) -> (%dx%d)@(%d,%d)\n",
+ plane->base.id, fb->base.id,
+ src_w, src_h, src_x, src_y,
+ state->crtc_w, state->crtc_h,
+ state->crtc_x, state->crtc_y);
bpcr = reg_read(ldev->regs, LTDC_BPCR);
ahbp = (bpcr & BPCR_AHBP) >> 16;
@@ -642,7 +619,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
if (val == NB_PF) {
DRM_ERROR("Pixel format %.4s not supported\n",
(char *)&fb->format->format);
- val = 0; /* set by default ARGB 32 bits */
+ val = 0; /* set by default ARGB 32 bits */
}
reg_update_bits(ldev->regs, LTDC_L1PFCR + lofs, LXPFCR_PF, val);
@@ -656,8 +633,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
/* Specifies the constant alpha value */
val = CONSTA_MAX;
- reg_update_bits(ldev->regs, LTDC_L1CACR + lofs,
- LXCACR_CONSTA, val);
+ reg_update_bits(ldev->regs, LTDC_L1CACR + lofs, LXCACR_CONSTA, val);
/* Specifies the blending factors */
val = BF1_PAXCA | BF2_1PAXCA;
@@ -666,8 +642,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
/* Configures the frame buffer line number */
val = y1 - y0 + 1;
- reg_update_bits(ldev->regs, LTDC_L1CFBLNR + lofs,
- LXCFBLNR_CFBLN, val);
+ reg_update_bits(ldev->regs, LTDC_L1CFBLNR + lofs, LXCFBLNR_CFBLN, val);
/* Sets the FB address */
paddr = (u32)drm_fb_cma_get_gem_addr(fb, state, 0);
@@ -706,11 +681,10 @@ static void ltdc_plane_atomic_disable(struct drm_plane *plane,
oldstate->crtc->base.id, plane->base.id);
}
-static struct drm_plane_funcs ltdc_plane_funcs = {
+static const struct drm_plane_funcs ltdc_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = drm_plane_cleanup,
- .set_property = drm_atomic_helper_plane_set_property,
.reset = drm_atomic_helper_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -748,7 +722,7 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
ret = drm_universal_plane_init(ddev, plane, possible_crtcs,
&ltdc_plane_funcs, formats, nb_fmt,
- type, NULL);
+ NULL, type, NULL);
if (ret < 0)
return 0;
@@ -773,7 +747,7 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
struct ltdc_device *ldev = ddev->dev_private;
struct drm_plane *primary, *overlay;
unsigned int i;
- int res;
+ int ret;
primary = ltdc_plane_create(ddev, DRM_PLANE_TYPE_PRIMARY);
if (!primary) {
@@ -781,9 +755,9 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
return -EINVAL;
}
- res = drm_crtc_init_with_planes(ddev, crtc, primary, NULL,
+ ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL,
&ltdc_crtc_funcs, NULL);
- if (res) {
+ if (ret) {
DRM_ERROR("Can not initialize CRTC\n");
goto cleanup;
}
@@ -796,7 +770,7 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
for (i = 1; i < ldev->caps.nb_layers; i++) {
overlay = ltdc_plane_create(ddev, DRM_PLANE_TYPE_OVERLAY);
if (!overlay) {
- res = -ENOMEM;
+ ret = -ENOMEM;
DRM_ERROR("Can not create overlay plane %d\n", i);
goto cleanup;
}
@@ -806,137 +780,42 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
cleanup:
ltdc_plane_destroy_all(ddev);
- return res;
+ return ret;
}
/*
* DRM_ENCODER
*/
-static void ltdc_rgb_encoder_enable(struct drm_encoder *encoder)
-{
- struct ltdc_device *ldev = encoder_to_ltdc(encoder);
-
- DRM_DEBUG_DRIVER("\n");
-
- drm_panel_prepare(ldev->panel);
- drm_panel_enable(ldev->panel);
-}
-
-static void ltdc_rgb_encoder_disable(struct drm_encoder *encoder)
-{
- struct ltdc_device *ldev = encoder_to_ltdc(encoder);
-
- DRM_DEBUG_DRIVER("\n");
-
- drm_panel_disable(ldev->panel);
- drm_panel_unprepare(ldev->panel);
-}
-
-static const struct drm_encoder_helper_funcs ltdc_rgb_encoder_helper_funcs = {
- .enable = ltdc_rgb_encoder_enable,
- .disable = ltdc_rgb_encoder_disable,
-};
-
-static const struct drm_encoder_funcs ltdc_rgb_encoder_funcs = {
+static const struct drm_encoder_funcs ltdc_encoder_funcs = {
.destroy = drm_encoder_cleanup,
};
-static struct drm_encoder *ltdc_rgb_encoder_create(struct drm_device *ddev)
+static int ltdc_encoder_init(struct drm_device *ddev)
{
+ struct ltdc_device *ldev = ddev->dev_private;
struct drm_encoder *encoder;
+ int ret;
encoder = devm_kzalloc(ddev->dev, sizeof(*encoder), GFP_KERNEL);
if (!encoder)
- return NULL;
+ return -ENOMEM;
encoder->possible_crtcs = CRTC_MASK;
- encoder->possible_clones = 0; /* No cloning support */
+ encoder->possible_clones = 0; /* No cloning support */
- drm_encoder_init(ddev, encoder, &ltdc_rgb_encoder_funcs,
+ drm_encoder_init(ddev, encoder, &ltdc_encoder_funcs,
DRM_MODE_ENCODER_DPI, NULL);
- drm_encoder_helper_add(encoder, &ltdc_rgb_encoder_helper_funcs);
-
- DRM_DEBUG_DRIVER("RGB encoder:%d created\n", encoder->base.id);
-
- return encoder;
-}
-
-/*
- * DRM_CONNECTOR
- */
-
-static int ltdc_rgb_connector_get_modes(struct drm_connector *connector)
-{
- struct drm_device *ddev = connector->dev;
- struct ltdc_device *ldev = ddev->dev_private;
- int ret = 0;
-
- DRM_DEBUG_DRIVER("\n");
-
- if (ldev->panel)
- ret = drm_panel_get_modes(ldev->panel);
-
- return ret < 0 ? 0 : ret;
-}
-
-static struct drm_connector_helper_funcs ltdc_rgb_connector_helper_funcs = {
- .get_modes = ltdc_rgb_connector_get_modes,
-};
-
-static enum drm_connector_status
-ltdc_rgb_connector_detect(struct drm_connector *connector, bool force)
-{
- struct ltdc_device *ldev = connector_to_ltdc(connector);
-
- return ldev->panel ? connector_status_connected :
- connector_status_disconnected;
-}
-
-static void ltdc_rgb_connector_destroy(struct drm_connector *connector)
-{
- DRM_DEBUG_DRIVER("\n");
-
- drm_connector_unregister(connector);
- drm_connector_cleanup(connector);
-}
-
-static const struct drm_connector_funcs ltdc_rgb_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
- .fill_modes = drm_helper_probe_single_connector_modes,
- .detect = ltdc_rgb_connector_detect,
- .destroy = ltdc_rgb_connector_destroy,
- .reset = drm_atomic_helper_connector_reset,
- .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
- .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-struct drm_connector *ltdc_rgb_connector_create(struct drm_device *ddev)
-{
- struct drm_connector *connector;
- int err;
-
- connector = devm_kzalloc(ddev->dev, sizeof(*connector), GFP_KERNEL);
- if (!connector) {
- DRM_ERROR("Failed to allocate connector\n");
- return NULL;
- }
-
- connector->polled = DRM_CONNECTOR_POLL_HPD;
-
- err = drm_connector_init(ddev, connector, &ltdc_rgb_connector_funcs,
- DRM_MODE_CONNECTOR_DPI);
- if (err) {
- DRM_ERROR("Failed to initialize connector\n");
- return NULL;
+ ret = drm_bridge_attach(encoder, ldev->bridge, NULL);
+ if (ret) {
+ drm_encoder_cleanup(encoder);
+ return -EINVAL;
}
- drm_connector_helper_add(connector, &ltdc_rgb_connector_helper_funcs);
-
- DRM_DEBUG_DRIVER("RGB connector:%d created\n", connector->base.id);
+ DRM_DEBUG_DRIVER("Bridge encoder:%d created\n", encoder->base.id);
- return connector;
+ return 0;
}
static int ltdc_get_caps(struct drm_device *ddev)
@@ -972,61 +851,26 @@ static int ltdc_get_caps(struct drm_device *ddev)
return 0;
}
-static struct drm_panel *ltdc_get_panel(struct drm_device *ddev)
-{
- struct device *dev = ddev->dev;
- struct device_node *np = dev->of_node;
- struct device_node *entity, *port = NULL;
- struct drm_panel *panel = NULL;
-
- DRM_DEBUG_DRIVER("\n");
-
- /*
- * Parse ltdc node to get remote port and find RGB panel / HDMI slave
- * If a dsi or a bridge (hdmi, lvds...) is connected to ltdc,
- * a remote port & RGB panel will not be found.
- */
- for_each_endpoint_of_node(np, entity) {
- if (!of_device_is_available(entity))
- continue;
-
- port = of_graph_get_remote_port_parent(entity);
- if (port) {
- panel = of_drm_find_panel(port);
- of_node_put(port);
- if (panel) {
- DRM_DEBUG_DRIVER("remote panel %s\n",
- port->full_name);
- } else {
- DRM_DEBUG_DRIVER("panel missing\n");
- of_node_put(entity);
- }
- }
- }
-
- return panel;
-}
-
int ltdc_load(struct drm_device *ddev)
{
struct platform_device *pdev = to_platform_device(ddev->dev);
struct ltdc_device *ldev = ddev->dev_private;
struct device *dev = ddev->dev;
struct device_node *np = dev->of_node;
- struct drm_encoder *encoder;
- struct drm_connector *connector = NULL;
+ struct drm_bridge *bridge;
+ struct drm_panel *panel;
struct drm_crtc *crtc;
struct reset_control *rstc;
- struct resource res;
+ struct resource *res;
int irq, ret, i;
DRM_DEBUG_DRIVER("\n");
- ldev->panel = ltdc_get_panel(ddev);
- if (!ldev->panel)
- return -EPROBE_DEFER;
+ ret = drm_of_find_panel_or_bridge(np, 0, 0, &panel, &bridge);
+ if (ret)
+ return ret;
- rstc = of_reset_control_get(np, NULL);
+ rstc = devm_reset_control_get_exclusive(dev, NULL);
mutex_init(&ldev->err_lock);
@@ -1041,15 +885,18 @@ int ltdc_load(struct drm_device *ddev)
return -ENODEV;
}
- if (of_address_to_resource(np, 0, &res)) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
DRM_ERROR("Unable to get resource\n");
- return -ENODEV;
+ ret = -ENODEV;
+ goto err;
}
- ldev->regs = devm_ioremap_resource(dev, &res);
+ ldev->regs = devm_ioremap_resource(dev, res);
if (IS_ERR(ldev->regs)) {
DRM_ERROR("Unable to get ltdc registers\n");
- return PTR_ERR(ldev->regs);
+ ret = PTR_ERR(ldev->regs);
+ goto err;
}
for (i = 0; i < MAX_IRQ; i++) {
@@ -1062,7 +909,7 @@ int ltdc_load(struct drm_device *ddev)
dev_name(dev), ddev);
if (ret) {
DRM_ERROR("Failed to register LTDC interrupt\n");
- return ret;
+ goto err;
}
}
@@ -1077,33 +924,27 @@ int ltdc_load(struct drm_device *ddev)
if (ret) {
DRM_ERROR("hardware identifier (0x%08x) not supported!\n",
ldev->caps.hw_version);
- return ret;
+ goto err;
}
DRM_INFO("ltdc hw version 0x%08x - ready\n", ldev->caps.hw_version);
- if (ldev->panel) {
- encoder = ltdc_rgb_encoder_create(ddev);
- if (!encoder) {
- DRM_ERROR("Failed to create RGB encoder\n");
- ret = -EINVAL;
+ if (panel) {
+ bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DPI);
+ if (IS_ERR(bridge)) {
+ DRM_ERROR("Failed to create panel-bridge\n");
+ ret = PTR_ERR(bridge);
goto err;
}
+ ldev->is_panel_bridge = true;
+ }
- connector = ltdc_rgb_connector_create(ddev);
- if (!connector) {
- DRM_ERROR("Failed to create RGB connector\n");
- ret = -EINVAL;
- goto err;
- }
+ ldev->bridge = bridge;
- ret = drm_mode_connector_attach_encoder(connector, encoder);
- if (ret) {
- DRM_ERROR("Failed to attach connector to encoder\n");
- goto err;
- }
-
- drm_panel_attach(ldev->panel, connector);
+ ret = ltdc_encoder_init(ddev);
+ if (ret) {
+ DRM_ERROR("Failed to init encoder\n");
+ goto err;
}
crtc = devm_kzalloc(dev, sizeof(*crtc), GFP_KERNEL);
@@ -1129,9 +970,10 @@ int ltdc_load(struct drm_device *ddev)
ddev->irq_enabled = 1;
return 0;
+
err:
- if (ldev->panel)
- drm_panel_detach(ldev->panel);
+ if (ldev->is_panel_bridge)
+ drm_panel_bridge_remove(bridge);
clk_disable_unprepare(ldev->pixel_clk);
@@ -1144,8 +986,8 @@ void ltdc_unload(struct drm_device *ddev)
DRM_DEBUG_DRIVER("\n");
- if (ldev->panel)
- drm_panel_detach(ldev->panel);
+ if (ldev->is_panel_bridge)
+ drm_panel_bridge_remove(ldev->bridge);
clk_disable_unprepare(ldev->pixel_clk);
}
diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h
index d7a9c736ac1e..bc6d6f6419a9 100644
--- a/drivers/gpu/drm/stm/ltdc.h
+++ b/drivers/gpu/drm/stm/ltdc.h
@@ -24,10 +24,10 @@ struct ltdc_device {
struct drm_fbdev_cma *fbdev;
void __iomem *regs;
struct clk *pixel_clk; /* lcd pixel clock */
- struct drm_panel *panel;
+ struct drm_bridge *bridge;
+ bool is_panel_bridge;
struct mutex err_lock; /* protecting error_status */
struct ltdc_caps caps;
- u32 clut[256]; /* color look up table */
u32 error_status;
u32 irq_status;
};
diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c
index f8c70439d1e2..d097c6f93ad0 100644
--- a/drivers/gpu/drm/sun4i/sun4i_crtc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c
@@ -69,7 +69,8 @@ static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc,
}
}
-static void sun4i_crtc_disable(struct drm_crtc *crtc)
+static void sun4i_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
@@ -86,7 +87,8 @@ static void sun4i_crtc_disable(struct drm_crtc *crtc)
}
}
-static void sun4i_crtc_enable(struct drm_crtc *crtc)
+static void sun4i_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
@@ -98,8 +100,8 @@ static void sun4i_crtc_enable(struct drm_crtc *crtc)
static const struct drm_crtc_helper_funcs sun4i_crtc_helper_funcs = {
.atomic_begin = sun4i_crtc_atomic_begin,
.atomic_flush = sun4i_crtc_atomic_flush,
- .disable = sun4i_crtc_disable,
- .enable = sun4i_crtc_enable,
+ .atomic_enable = sun4i_crtc_atomic_enable,
+ .atomic_disable = sun4i_crtc_atomic_disable,
};
static int sun4i_crtc_enable_vblank(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index abc7d8fe06b4..d599206a1e86 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -40,8 +40,6 @@ static struct drm_driver sun4i_drv_driver = {
/* GEM Operations */
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_destroy = drm_gem_dumb_destroy,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
@@ -187,9 +185,9 @@ static bool sun4i_drv_node_is_tcon(struct device_node *node)
static int compare_of(struct device *dev, void *data)
{
- DRM_DEBUG_DRIVER("Comparing of node %s with %s\n",
- of_node_full_name(dev->of_node),
- of_node_full_name(data));
+ DRM_DEBUG_DRIVER("Comparing of node %pOF with %pOF\n",
+ dev->of_node,
+ data);
return dev->of_node == data;
}
@@ -219,8 +217,7 @@ static int sun4i_drv_add_endpoints(struct device *dev,
if (!sun4i_drv_node_is_frontend(node)) {
/* Add current component */
- DRM_DEBUG_DRIVER("Adding component %s\n",
- of_node_full_name(node));
+ DRM_DEBUG_DRIVER("Adding component %pOF\n", node);
drm_of_component_match_add(dev, match, compare_of, node);
count++;
}
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 863a51618819..9ea6cd5a1370 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -50,7 +50,7 @@ static int sun4i_hdmi_setup_avi_infoframes(struct sun4i_hdmi *hdmi,
u8 buffer[17];
int i, ret;
- ret = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (ret < 0) {
DRM_ERROR("Failed to get infoframes from mode\n");
return ret;
@@ -225,7 +225,6 @@ sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force)
}
static const struct drm_connector_funcs sun4i_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = sun4i_hdmi_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
index b0c1155891b4..7bddf12548d3 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -108,7 +108,7 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
ret = drm_universal_plane_init(drm, &layer->plane, 0,
&sun4i_backend_layer_funcs,
plane->formats, plane->nformats,
- plane->type, NULL);
+ NULL, plane->type, NULL);
if (ret) {
dev_err(drm->dev, "Couldn't initialize layer\n");
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c
index 76362c09c608..7cd7090ad63a 100644
--- a/drivers/gpu/drm/sun4i/sun4i_rgb.c
+++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c
@@ -119,8 +119,7 @@ sun4i_rgb_connector_destroy(struct drm_connector *connector)
drm_connector_cleanup(connector);
}
-static struct drm_connector_funcs sun4i_rgb_con_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
+static const struct drm_connector_funcs sun4i_rgb_con_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = sun4i_rgb_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index 73bfe7b1cd78..050cfd43c7a0 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -537,8 +537,7 @@ sun4i_tv_comp_connector_destroy(struct drm_connector *connector)
drm_connector_cleanup(connector);
}
-static struct drm_connector_funcs sun4i_tv_comp_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
+static const struct drm_connector_funcs sun4i_tv_comp_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = sun4i_tv_comp_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/sun4i/sun8i_layer.c b/drivers/gpu/drm/sun4i/sun8i_layer.c
index e627eeece658..23810ff72684 100644
--- a/drivers/gpu/drm/sun4i/sun8i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_layer.c
@@ -90,7 +90,7 @@ static struct sun8i_layer *sun8i_layer_init_one(struct drm_device *drm,
ret = drm_universal_plane_init(drm, &layer->plane, 0,
&sun8i_mixer_layer_funcs,
plane->formats, plane->nformats,
- plane->type, NULL);
+ NULL, plane->type, NULL);
if (ret) {
dev_err(drm->dev, "Couldn't initialize layer\n");
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c
index c54138c3a376..3a1476818c65 100644
--- a/drivers/gpu/drm/tdfx/tdfx_drv.c
+++ b/drivers/gpu/drm/tdfx/tdfx_drv.c
@@ -55,7 +55,6 @@ static const struct file_operations tdfx_driver_fops = {
static struct drm_driver driver = {
.driver_features = DRIVER_LEGACY,
- .set_busid = drm_pci_set_busid,
.fops = &tdfx_driver_fops,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
@@ -72,12 +71,12 @@ static struct pci_driver tdfx_pci_driver = {
static int __init tdfx_init(void)
{
- return drm_pci_init(&driver, &tdfx_pci_driver);
+ return drm_legacy_pci_init(&driver, &tdfx_pci_driver);
}
static void __exit tdfx_exit(void)
{
- drm_pci_exit(&driver, &tdfx_pci_driver);
+ drm_legacy_pci_exit(&driver, &tdfx_pci_driver);
}
module_init(tdfx_init);
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig
index 2db29d67193d..dc58ab140151 100644
--- a/drivers/gpu/drm/tegra/Kconfig
+++ b/drivers/gpu/drm/tegra/Kconfig
@@ -3,6 +3,7 @@ config DRM_TEGRA
depends on ARCH_TEGRA || (ARM && COMPILE_TEST)
depends on COMMON_CLK
depends on DRM
+ depends on OF
select DRM_KMS_HELPER
select DRM_MIPI_DSI
select DRM_PANEL
diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile
index 6af3a9ad6565..8927784396e8 100644
--- a/drivers/gpu/drm/tegra/Makefile
+++ b/drivers/gpu/drm/tegra/Makefile
@@ -17,4 +17,6 @@ tegra-drm-y := \
falcon.o \
vic.o
+tegra-drm-y += trace.o
+
obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index c875f11786b9..4df39112e38e 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -678,8 +678,8 @@ static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm,
err = drm_universal_plane_init(drm, &plane->base, possible_crtcs,
&tegra_primary_plane_funcs, formats,
- num_formats, DRM_PLANE_TYPE_PRIMARY,
- NULL);
+ num_formats, NULL,
+ DRM_PLANE_TYPE_PRIMARY, NULL);
if (err < 0) {
kfree(plane);
return ERR_PTR(err);
@@ -844,8 +844,8 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe,
&tegra_cursor_plane_funcs, formats,
- num_formats, DRM_PLANE_TYPE_CURSOR,
- NULL);
+ num_formats, NULL,
+ DRM_PLANE_TYPE_CURSOR, NULL);
if (err < 0) {
kfree(plane);
return ERR_PTR(err);
@@ -906,8 +906,8 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe,
&tegra_overlay_plane_funcs, formats,
- num_formats, DRM_PLANE_TYPE_OVERLAY,
- NULL);
+ num_formats, NULL,
+ DRM_PLANE_TYPE_OVERLAY, NULL);
if (err < 0) {
kfree(plane);
return ERR_PTR(err);
@@ -1199,7 +1199,8 @@ static int tegra_dc_wait_idle(struct tegra_dc *dc, unsigned long timeout)
return -ETIMEDOUT;
}
-static void tegra_crtc_disable(struct drm_crtc *crtc)
+static void tegra_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct tegra_dc *dc = to_tegra_dc(crtc);
u32 value;
@@ -1243,7 +1244,8 @@ static void tegra_crtc_disable(struct drm_crtc *crtc)
pm_runtime_put_sync(dc->dev);
}
-static void tegra_crtc_enable(struct drm_crtc *crtc)
+static void tegra_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
struct tegra_dc_state *state = to_dc_state(crtc->state);
@@ -1351,11 +1353,11 @@ static void tegra_crtc_atomic_flush(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
- .disable = tegra_crtc_disable,
- .enable = tegra_crtc_enable,
.atomic_check = tegra_crtc_atomic_check,
.atomic_begin = tegra_crtc_atomic_begin,
.atomic_flush = tegra_crtc_atomic_flush,
+ .atomic_enable = tegra_crtc_atomic_enable,
+ .atomic_disable = tegra_crtc_atomic_disable,
};
static irqreturn_t tegra_dc_irq(int irq, void *data)
diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index 2fde44c3a1b3..e4da041ba89b 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -25,6 +25,7 @@
#include "dpaux.h"
#include "drm.h"
+#include "trace.h"
static DEFINE_MUTEX(dpaux_lock);
static LIST_HEAD(dpaux_list);
@@ -65,14 +66,19 @@ static inline struct tegra_dpaux *work_to_dpaux(struct work_struct *work)
}
static inline u32 tegra_dpaux_readl(struct tegra_dpaux *dpaux,
- unsigned long offset)
+ unsigned int offset)
{
- return readl(dpaux->regs + (offset << 2));
+ u32 value = readl(dpaux->regs + (offset << 2));
+
+ trace_dpaux_readl(dpaux->dev, offset, value);
+
+ return value;
}
static inline void tegra_dpaux_writel(struct tegra_dpaux *dpaux,
- u32 value, unsigned long offset)
+ u32 value, unsigned int offset)
{
+ trace_dpaux_writel(dpaux->dev, offset, value);
writel(value, dpaux->regs + (offset << 2));
}
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 518f4b69ea53..597d563d636a 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -100,7 +100,12 @@ static int tegra_atomic_commit(struct drm_device *drm,
* the software side now.
*/
- drm_atomic_helper_swap_state(state, true);
+ err = drm_atomic_helper_swap_state(state, true);
+ if (err) {
+ mutex_unlock(&tegra->commit.lock);
+ drm_atomic_helper_cleanup_planes(drm, state);
+ return err;
+ }
drm_atomic_state_get(state);
if (nonblock)
@@ -214,12 +219,10 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
err = tegra_drm_fb_init(drm);
if (err < 0)
- goto vblank;
+ goto device;
return 0;
-vblank:
- drm_vblank_cleanup(drm);
device:
host1x_device_exit(device);
fbdev:
@@ -248,7 +251,6 @@ static void tegra_drm_unload(struct drm_device *drm)
drm_kms_helper_poll_fini(drm);
tegra_drm_fb_exit(drm);
drm_mode_config_cleanup(drm);
- drm_vblank_cleanup(drm);
err = host1x_device_exit(device);
if (err < 0)
@@ -304,8 +306,6 @@ host1x_bo_lookup(struct drm_file *file, u32 handle)
if (!gem)
return NULL;
- drm_gem_object_unreference_unlocked(gem);
-
bo = to_tegra_bo(gem);
return &bo->base;
}
@@ -394,8 +394,10 @@ int tegra_drm_submit(struct tegra_drm_context *context,
(void __user *)(uintptr_t)args->waitchks;
struct drm_tegra_syncpt syncpt;
struct host1x *host1x = dev_get_drvdata(drm->dev->parent);
+ struct drm_gem_object **refs;
struct host1x_syncpt *sp;
struct host1x_job *job;
+ unsigned int num_refs;
int err;
/* We don't yet support other than one syncpt_incr struct per submit */
@@ -417,6 +419,21 @@ int tegra_drm_submit(struct tegra_drm_context *context,
job->class = context->client->base.class;
job->serialize = true;
+ /*
+ * Track referenced BOs so that they can be unreferenced after the
+ * submission is complete.
+ */
+ num_refs = num_cmdbufs + num_relocs * 2 + num_waitchks;
+
+ refs = kmalloc_array(num_refs, sizeof(*refs), GFP_KERNEL);
+ if (!refs) {
+ err = -ENOMEM;
+ goto put;
+ }
+
+ /* reuse as an iterator later */
+ num_refs = 0;
+
while (num_cmdbufs) {
struct drm_tegra_cmdbuf cmdbuf;
struct host1x_bo *bo;
@@ -445,6 +462,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
offset = (u64)cmdbuf.offset + (u64)cmdbuf.words * sizeof(u32);
obj = host1x_to_tegra_bo(bo);
+ refs[num_refs++] = &obj->gem;
/*
* Gather buffer base address must be 4-bytes aligned,
@@ -474,6 +492,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
reloc = &job->relocarray[num_relocs];
obj = host1x_to_tegra_bo(reloc->cmdbuf.bo);
+ refs[num_refs++] = &obj->gem;
/*
* The unaligned cmdbuf offset will cause an unaligned write
@@ -487,6 +506,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
}
obj = host1x_to_tegra_bo(reloc->target.bo);
+ refs[num_refs++] = &obj->gem;
if (reloc->target.offset >= obj->gem.size) {
err = -EINVAL;
@@ -506,6 +526,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
goto fail;
obj = host1x_to_tegra_bo(wait->bo);
+ refs[num_refs++] = &obj->gem;
/*
* The unaligned offset will cause an unaligned write during
@@ -545,17 +566,20 @@ int tegra_drm_submit(struct tegra_drm_context *context,
goto fail;
err = host1x_job_submit(job);
- if (err)
- goto fail_submit;
+ if (err) {
+ host1x_job_unpin(job);
+ goto fail;
+ }
args->fence = job->syncpt_end;
- host1x_job_put(job);
- return 0;
-
-fail_submit:
- host1x_job_unpin(job);
fail:
+ while (num_refs--)
+ drm_gem_object_put_unlocked(refs[num_refs]);
+
+ kfree(refs);
+
+put:
host1x_job_put(job);
return err;
}
@@ -591,7 +615,7 @@ static int tegra_gem_mmap(struct drm_device *drm, void *data,
args->offset = drm_vma_node_offset_addr(&bo->gem.vma_node);
- drm_gem_object_unreference_unlocked(gem);
+ drm_gem_object_put_unlocked(gem);
return 0;
}
@@ -858,7 +882,7 @@ static int tegra_gem_set_tiling(struct drm_device *drm, void *data,
bo->tiling.mode = mode;
bo->tiling.value = value;
- drm_gem_object_unreference_unlocked(gem);
+ drm_gem_object_put_unlocked(gem);
return 0;
}
@@ -898,7 +922,7 @@ static int tegra_gem_get_tiling(struct drm_device *drm, void *data,
break;
}
- drm_gem_object_unreference_unlocked(gem);
+ drm_gem_object_put_unlocked(gem);
return err;
}
@@ -923,7 +947,7 @@ static int tegra_gem_set_flags(struct drm_device *drm, void *data,
if (args->flags & DRM_TEGRA_GEM_BOTTOM_UP)
bo->flags |= TEGRA_BO_BOTTOM_UP;
- drm_gem_object_unreference_unlocked(gem);
+ drm_gem_object_put_unlocked(gem);
return 0;
}
@@ -945,7 +969,7 @@ static int tegra_gem_get_flags(struct drm_device *drm, void *data,
if (bo->flags & TEGRA_BO_BOTTOM_UP)
args->flags |= DRM_TEGRA_GEM_BOTTOM_UP;
- drm_gem_object_unreference_unlocked(gem);
+ drm_gem_object_put_unlocked(gem);
return 0;
}
@@ -953,20 +977,34 @@ static int tegra_gem_get_flags(struct drm_device *drm, void *data,
static const struct drm_ioctl_desc tegra_drm_ioctls[] = {
#ifdef CONFIG_DRM_TEGRA_STAGING
- DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE, tegra_gem_create, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_GEM_MMAP, tegra_gem_mmap, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_READ, tegra_syncpt_read, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_INCR, tegra_syncpt_incr, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_WAIT, tegra_syncpt_wait, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_OPEN_CHANNEL, tegra_open_channel, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_CLOSE_CHANNEL, tegra_close_channel, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT, tegra_get_syncpt, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_SUBMIT, tegra_submit, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT_BASE, tegra_get_syncpt_base, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_TILING, tegra_gem_set_tiling, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_TILING, tegra_gem_get_tiling, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_FLAGS, tegra_gem_set_flags, 0),
- DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_FLAGS, tegra_gem_get_flags, 0),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE, tegra_gem_create,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_MMAP, tegra_gem_mmap,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_READ, tegra_syncpt_read,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_INCR, tegra_syncpt_incr,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_WAIT, tegra_syncpt_wait,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_OPEN_CHANNEL, tegra_open_channel,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_CLOSE_CHANNEL, tegra_close_channel,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT, tegra_get_syncpt,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_SUBMIT, tegra_submit,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT_BASE, tegra_get_syncpt_base,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_TILING, tegra_gem_set_tiling,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_TILING, tegra_gem_get_tiling,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_FLAGS, tegra_gem_set_flags,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_FLAGS, tegra_gem_get_flags,
+ DRM_UNLOCKED | DRM_RENDER_ALLOW),
#endif
};
@@ -1033,9 +1071,11 @@ static int tegra_debugfs_iova(struct seq_file *s, void *data)
struct tegra_drm *tegra = drm->dev_private;
struct drm_printer p = drm_seq_file_printer(s);
- mutex_lock(&tegra->mm_lock);
- drm_mm_print(&tegra->mm, &p);
- mutex_unlock(&tegra->mm_lock);
+ if (tegra->domain) {
+ mutex_lock(&tegra->mm_lock);
+ drm_mm_print(&tegra->mm, &p);
+ mutex_unlock(&tegra->mm_lock);
+ }
return 0;
}
@@ -1055,7 +1095,7 @@ static int tegra_debugfs_init(struct drm_minor *minor)
static struct drm_driver tegra_drm_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
- DRIVER_ATOMIC,
+ DRIVER_ATOMIC | DRIVER_RENDER,
.load = tegra_drm_load,
.unload = tegra_drm_unload,
.open = tegra_drm_open,
@@ -1075,8 +1115,6 @@ static struct drm_driver tegra_drm_driver = {
.gem_prime_import = tegra_gem_prime_import,
.dumb_create = tegra_bo_dumb_create,
- .dumb_map_offset = tegra_bo_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.ioctls = tegra_drm_ioctls,
.num_ioctls = ARRAY_SIZE(tegra_drm_ioctls),
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index 6d6da01282f3..063f5d397526 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -23,6 +23,7 @@
#include <drm/drm_fixed.h>
#include "gem.h"
+#include "trace.h"
struct reset_control;
@@ -172,14 +173,19 @@ static inline struct tegra_dc *to_tegra_dc(struct drm_crtc *crtc)
}
static inline void tegra_dc_writel(struct tegra_dc *dc, u32 value,
- unsigned long offset)
+ unsigned int offset)
{
+ trace_dc_writel(dc->dev, offset, value);
writel(value, dc->regs + (offset << 2));
}
-static inline u32 tegra_dc_readl(struct tegra_dc *dc, unsigned long offset)
+static inline u32 tegra_dc_readl(struct tegra_dc *dc, unsigned int offset)
{
- return readl(dc->regs + (offset << 2));
+ u32 value = readl(dc->regs + (offset << 2));
+
+ trace_dc_readl(dc->dev, offset, value);
+
+ return value;
}
struct tegra_dc_window {
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index 3dea1216bafd..046649ec9441 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -28,6 +28,7 @@
#include "drm.h"
#include "dsi.h"
#include "mipi-phy.h"
+#include "trace.h"
struct tegra_dsi_state {
struct drm_connector_state base;
@@ -105,15 +106,20 @@ static struct tegra_dsi_state *tegra_dsi_get_state(struct tegra_dsi *dsi)
return to_dsi_state(dsi->output.connector.state);
}
-static inline u32 tegra_dsi_readl(struct tegra_dsi *dsi, unsigned long reg)
+static inline u32 tegra_dsi_readl(struct tegra_dsi *dsi, unsigned int offset)
{
- return readl(dsi->regs + (reg << 2));
+ u32 value = readl(dsi->regs + (offset << 2));
+
+ trace_dsi_readl(dsi->dev, offset, value);
+
+ return value;
}
static inline void tegra_dsi_writel(struct tegra_dsi *dsi, u32 value,
- unsigned long reg)
+ unsigned int offset)
{
- writel(value, dsi->regs + (reg << 2));
+ trace_dsi_writel(dsi->dev, offset, value);
+ writel(value, dsi->regs + (offset << 2));
}
static int tegra_dsi_show_regs(struct seq_file *s, void *data)
@@ -815,7 +821,6 @@ tegra_dsi_connector_duplicate_state(struct drm_connector *connector)
}
static const struct drm_connector_funcs tegra_dsi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = tegra_dsi_connector_reset,
.detect = tegra_output_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
index 25acb73ee728..80540c1c66dc 100644
--- a/drivers/gpu/drm/tegra/fb.c
+++ b/drivers/gpu/drm/tegra/fb.c
@@ -88,7 +88,7 @@ static void tegra_fb_destroy(struct drm_framebuffer *framebuffer)
if (bo->pages)
vunmap(bo->vaddr);
- drm_gem_object_unreference_unlocked(&bo->gem);
+ drm_gem_object_put_unlocked(&bo->gem);
}
}
@@ -195,7 +195,7 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
unreference:
while (i--)
- drm_gem_object_unreference_unlocked(&planes[i]->gem);
+ drm_gem_object_put_unlocked(&planes[i]->gem);
return ERR_PTR(err);
}
@@ -242,7 +242,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,
info = drm_fb_helper_alloc_fbi(helper);
if (IS_ERR(info)) {
dev_err(drm->dev, "failed to allocate framebuffer info\n");
- drm_gem_object_unreference_unlocked(&bo->gem);
+ drm_gem_object_put_unlocked(&bo->gem);
return PTR_ERR(info);
}
@@ -251,7 +251,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper,
err = PTR_ERR(fbdev->fb);
dev_err(drm->dev, "failed to allocate DRM framebuffer: %d\n",
err);
- drm_gem_object_unreference_unlocked(&bo->gem);
+ drm_gem_object_put_unlocked(&bo->gem);
return PTR_ERR(fbdev->fb);
}
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 7a39a355678a..ab1e53d434e8 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -24,7 +24,7 @@ static void tegra_bo_put(struct host1x_bo *bo)
{
struct tegra_bo *obj = host1x_to_tegra_bo(bo);
- drm_gem_object_unreference_unlocked(&obj->gem);
+ drm_gem_object_put_unlocked(&obj->gem);
}
static dma_addr_t tegra_bo_pin(struct host1x_bo *bo, struct sg_table **sgt)
@@ -95,7 +95,7 @@ static struct host1x_bo *tegra_bo_get(struct host1x_bo *bo)
{
struct tegra_bo *obj = host1x_to_tegra_bo(bo);
- drm_gem_object_reference(&obj->gem);
+ drm_gem_object_get(&obj->gem);
return bo;
}
@@ -325,7 +325,7 @@ struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file,
return ERR_PTR(err);
}
- drm_gem_object_unreference_unlocked(&bo->gem);
+ drm_gem_object_put_unlocked(&bo->gem);
return bo;
}
@@ -423,27 +423,6 @@ int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm,
return 0;
}
-int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm,
- u32 handle, u64 *offset)
-{
- struct drm_gem_object *gem;
- struct tegra_bo *bo;
-
- gem = drm_gem_object_lookup(file, handle);
- if (!gem) {
- dev_err(drm->dev, "failed to lookup GEM object\n");
- return -EINVAL;
- }
-
- bo = to_tegra_bo(gem);
-
- *offset = drm_vma_node_offset_addr(&bo->gem.vma_node);
-
- drm_gem_object_unreference_unlocked(gem);
-
- return 0;
-}
-
static int tegra_bo_fault(struct vm_fault *vmf)
{
struct vm_area_struct *vma = vmf->vma;
@@ -481,30 +460,28 @@ const struct vm_operations_struct tegra_bo_vm_ops = {
.close = drm_gem_vm_close,
};
-int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma)
+static int tegra_gem_mmap(struct drm_gem_object *gem,
+ struct vm_area_struct *vma)
{
- struct drm_gem_object *gem;
- struct tegra_bo *bo;
- int ret;
-
- ret = drm_gem_mmap(file, vma);
- if (ret)
- return ret;
-
- gem = vma->vm_private_data;
- bo = to_tegra_bo(gem);
+ struct tegra_bo *bo = to_tegra_bo(gem);
if (!bo->pages) {
unsigned long vm_pgoff = vma->vm_pgoff;
+ int err;
+ /*
+ * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(),
+ * and set the vm_pgoff (used as a fake buffer offset by DRM)
+ * to 0 as we want to map the whole buffer.
+ */
vma->vm_flags &= ~VM_PFNMAP;
vma->vm_pgoff = 0;
- ret = dma_mmap_wc(gem->dev->dev, vma, bo->vaddr, bo->paddr,
+ err = dma_mmap_wc(gem->dev->dev, vma, bo->vaddr, bo->paddr,
gem->size);
- if (ret) {
+ if (err < 0) {
drm_gem_vm_close(vma);
- return ret;
+ return err;
}
vma->vm_pgoff = vm_pgoff;
@@ -520,6 +497,20 @@ int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma)
return 0;
}
+int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct drm_gem_object *gem;
+ int err;
+
+ err = drm_gem_mmap(file, vma);
+ if (err < 0)
+ return err;
+
+ gem = vma->vm_private_data;
+
+ return tegra_gem_mmap(gem, vma);
+}
+
static struct sg_table *
tegra_gem_prime_map_dma_buf(struct dma_buf_attachment *attach,
enum dma_data_direction dir)
@@ -603,7 +594,14 @@ static void tegra_gem_prime_kunmap(struct dma_buf *buf, unsigned long page,
static int tegra_gem_prime_mmap(struct dma_buf *buf, struct vm_area_struct *vma)
{
- return -EINVAL;
+ struct drm_gem_object *gem = buf->priv;
+ int err;
+
+ err = drm_gem_mmap_obj(gem, gem->size, vma);
+ if (err < 0)
+ return err;
+
+ return tegra_gem_mmap(gem, vma);
}
static void *tegra_gem_prime_vmap(struct dma_buf *buf)
@@ -654,7 +652,7 @@ struct drm_gem_object *tegra_gem_prime_import(struct drm_device *drm,
struct drm_gem_object *gem = buf->priv;
if (gem->dev == drm) {
- drm_gem_object_reference(gem);
+ drm_gem_object_get(gem);
return gem;
}
}
diff --git a/drivers/gpu/drm/tegra/gem.h b/drivers/gpu/drm/tegra/gem.h
index 8b32a6fd586d..8eb9fd24ef0e 100644
--- a/drivers/gpu/drm/tegra/gem.h
+++ b/drivers/gpu/drm/tegra/gem.h
@@ -67,8 +67,6 @@ struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file,
void tegra_bo_free_object(struct drm_gem_object *gem);
int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm,
struct drm_mode_create_dumb *args);
-int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm,
- u32 handle, u64 *offset);
int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma);
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index cda0491ed6bf..5b9d83b71943 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -24,6 +24,7 @@
#include "hdmi.h"
#include "drm.h"
#include "dc.h"
+#include "trace.h"
#define HDMI_ELD_BUFFER_SIZE 96
@@ -100,14 +101,19 @@ enum {
};
static inline u32 tegra_hdmi_readl(struct tegra_hdmi *hdmi,
- unsigned long offset)
+ unsigned int offset)
{
- return readl(hdmi->regs + (offset << 2));
+ u32 value = readl(hdmi->regs + (offset << 2));
+
+ trace_hdmi_readl(hdmi->dev, offset, value);
+
+ return value;
}
static inline void tegra_hdmi_writel(struct tegra_hdmi *hdmi, u32 value,
- unsigned long offset)
+ unsigned int offset)
{
+ trace_hdmi_writel(hdmi->dev, offset, value);
writel(value, hdmi->regs + (offset << 2));
}
@@ -734,7 +740,7 @@ static void tegra_hdmi_setup_avi_infoframe(struct tegra_hdmi *hdmi,
u8 buffer[17];
ssize_t err;
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (err < 0) {
dev_err(hdmi->dev, "failed to setup AVI infoframe: %zd\n", err);
return;
@@ -902,7 +908,6 @@ tegra_hdmi_connector_detect(struct drm_connector *connector, bool force)
}
static const struct drm_connector_funcs tegra_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.detect = tegra_hdmi_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
index a131b44e2d6f..78ec5193741d 100644
--- a/drivers/gpu/drm/tegra/rgb.c
+++ b/drivers/gpu/drm/tegra/rgb.c
@@ -88,7 +88,6 @@ static void tegra_dc_write_regs(struct tegra_dc *dc,
}
static const struct drm_connector_funcs tegra_rgb_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.detect = tegra_output_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index a8f528925009..7ab1d1dc7cd7 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -26,6 +26,7 @@
#include "dc.h"
#include "drm.h"
#include "sor.h"
+#include "trace.h"
#define SOR_REKEY 0x38
@@ -232,14 +233,19 @@ static inline struct tegra_sor *to_sor(struct tegra_output *output)
return container_of(output, struct tegra_sor, output);
}
-static inline u32 tegra_sor_readl(struct tegra_sor *sor, unsigned long offset)
+static inline u32 tegra_sor_readl(struct tegra_sor *sor, unsigned int offset)
{
- return readl(sor->regs + (offset << 2));
+ u32 value = readl(sor->regs + (offset << 2));
+
+ trace_sor_readl(sor->dev, offset, value);
+
+ return value;
}
static inline void tegra_sor_writel(struct tegra_sor *sor, u32 value,
- unsigned long offset)
+ unsigned int offset)
{
+ trace_sor_writel(sor->dev, offset, value);
writel(value, sor->regs + (offset << 2));
}
@@ -1340,7 +1346,6 @@ tegra_sor_connector_duplicate_state(struct drm_connector *connector)
}
static const struct drm_connector_funcs tegra_sor_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = tegra_sor_connector_reset,
.detect = tegra_sor_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
@@ -1904,7 +1909,7 @@ tegra_sor_hdmi_setup_avi_infoframe(struct tegra_sor *sor,
value &= ~INFOFRAME_CTRL_ENABLE;
tegra_sor_writel(sor, value, SOR_HDMI_AVI_INFOFRAME_CTRL);
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
if (err < 0) {
dev_err(sor->dev, "failed to setup AVI infoframe: %d\n", err);
return err;
diff --git a/drivers/gpu/drm/tegra/trace.c b/drivers/gpu/drm/tegra/trace.c
new file mode 100644
index 000000000000..006f65c72a34
--- /dev/null
+++ b/drivers/gpu/drm/tegra/trace.c
@@ -0,0 +1,2 @@
+#define CREATE_TRACE_POINTS
+#include "trace.h"
diff --git a/drivers/gpu/drm/tegra/trace.h b/drivers/gpu/drm/tegra/trace.h
new file mode 100644
index 000000000000..e9b7cdad5c4c
--- /dev/null
+++ b/drivers/gpu/drm/tegra/trace.h
@@ -0,0 +1,68 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM tegra
+
+#if !defined(DRM_TEGRA_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define DRM_TEGRA_TRACE_H 1
+
+#include <linux/device.h>
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(register_access,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value),
+ TP_STRUCT__entry(
+ __field(struct device *, dev)
+ __field(unsigned int, offset)
+ __field(u32, value)
+ ),
+ TP_fast_assign(
+ __entry->dev = dev;
+ __entry->offset = offset;
+ __entry->value = value;
+ ),
+ TP_printk("%s %04x %08x", dev_name(__entry->dev), __entry->offset,
+ __entry->value)
+);
+
+DEFINE_EVENT(register_access, dc_writel,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+DEFINE_EVENT(register_access, dc_readl,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+
+DEFINE_EVENT(register_access, hdmi_writel,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+DEFINE_EVENT(register_access, hdmi_readl,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+
+DEFINE_EVENT(register_access, dsi_writel,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+DEFINE_EVENT(register_access, dsi_readl,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+
+DEFINE_EVENT(register_access, dpaux_writel,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+DEFINE_EVENT(register_access, dpaux_readl,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+
+DEFINE_EVENT(register_access, sor_writel,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+DEFINE_EVENT(register_access, sor_readl,
+ TP_PROTO(struct device *dev, unsigned int offset, u32 value),
+ TP_ARGS(dev, offset, value));
+
+#endif /* DRM_TEGRA_TRACE_H */
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace
+#include <trace/define_trace.h>
diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c
index 47cb1aaa58b1..2448229fa653 100644
--- a/drivers/gpu/drm/tegra/vic.c
+++ b/drivers/gpu/drm/tegra/vic.c
@@ -258,12 +258,16 @@ static const struct tegra_drm_client_ops vic_ops = {
.submit = tegra_drm_submit,
};
+#define NVIDIA_TEGRA_124_VIC_FIRMWARE "nvidia/tegra124/vic03_ucode.bin"
+
static const struct vic_config vic_t124_config = {
- .firmware = "nvidia/tegra124/vic03_ucode.bin",
+ .firmware = NVIDIA_TEGRA_124_VIC_FIRMWARE,
};
+#define NVIDIA_TEGRA_210_VIC_FIRMWARE "nvidia/tegra210/vic04_ucode.bin"
+
static const struct vic_config vic_t210_config = {
- .firmware = "nvidia/tegra210/vic04_ucode.bin",
+ .firmware = NVIDIA_TEGRA_210_VIC_FIRMWARE,
};
static const struct of_device_id vic_match[] = {
@@ -394,3 +398,10 @@ struct platform_driver tegra_vic_driver = {
.probe = vic_probe,
.remove = vic_remove,
};
+
+#if IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC)
+MODULE_FIRMWARE(NVIDIA_TEGRA_124_VIC_FIRMWARE);
+#endif
+#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
+MODULE_FIRMWARE(NVIDIA_TEGRA_210_VIC_FIRMWARE);
+#endif
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index d524ed0d5146..406fe4544b83 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -504,6 +504,12 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc)
mutex_unlock(&tilcdc_crtc->enable_lock);
}
+static void tilcdc_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
+{
+ tilcdc_crtc_enable(crtc);
+}
+
static void tilcdc_crtc_off(struct drm_crtc *crtc, bool shutdown)
{
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
@@ -562,6 +568,12 @@ static void tilcdc_crtc_disable(struct drm_crtc *crtc)
tilcdc_crtc_off(crtc, false);
}
+static void tilcdc_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
+{
+ tilcdc_crtc_disable(crtc);
+}
+
void tilcdc_crtc_shutdown(struct drm_crtc *crtc)
{
tilcdc_crtc_off(crtc, true);
@@ -729,9 +741,9 @@ static const struct drm_crtc_funcs tilcdc_crtc_funcs = {
static const struct drm_crtc_helper_funcs tilcdc_crtc_helper_funcs = {
.mode_fixup = tilcdc_crtc_mode_fixup,
- .enable = tilcdc_crtc_enable,
- .disable = tilcdc_crtc_disable,
.atomic_check = tilcdc_crtc_atomic_check,
+ .atomic_enable = tilcdc_crtc_atomic_enable,
+ .atomic_disable = tilcdc_crtc_atomic_disable,
};
int tilcdc_crtc_max_width(struct drm_crtc *crtc)
@@ -1038,8 +1050,8 @@ int tilcdc_crtc_create(struct drm_device *dev)
if (priv->is_componentized) {
crtc->port = of_graph_get_port_by_id(dev->dev->of_node, 0);
if (!crtc->port) { /* This should never happen */
- dev_err(dev->dev, "Port node not found in %s\n",
- dev->dev->of_node->full_name);
+ dev_err(dev->dev, "Port node not found in %pOF\n",
+ dev->dev->of_node);
ret = -EINVAL;
goto fail;
}
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index d67e18983a7d..b0d70f943cec 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -108,7 +108,11 @@ static int tilcdc_commit(struct drm_device *dev,
if (ret)
return ret;
- drm_atomic_helper_swap_state(state, true);
+ ret = drm_atomic_helper_swap_state(state, true);
+ if (ret) {
+ drm_atomic_helper_cleanup_planes(dev, state);
+ return ret;
+ }
/*
* Everything below can be run asynchronously without the need to grab
@@ -538,8 +542,6 @@ static struct drm_driver tilcdc_driver = {
.gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
index 28c3e2f44f64..1813a3623ce6 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
@@ -189,7 +189,6 @@ static struct drm_encoder *panel_connector_best_encoder(
static const struct drm_connector_funcs panel_connector_funcs = {
.destroy = panel_connector_destroy,
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_plane.c b/drivers/gpu/drm/tilcdc/tilcdc_plane.c
index ba0d66c0d8ac..7667b038ae7f 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_plane.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_plane.c
@@ -28,7 +28,6 @@ static struct drm_plane_funcs tilcdc_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = drm_plane_cleanup,
- .set_property = drm_atomic_helper_plane_set_property,
.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/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
index aabfad882e23..1e2dfb1b1d6b 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
@@ -202,7 +202,6 @@ static struct drm_encoder *tfp410_connector_best_encoder(
static const struct drm_connector_funcs tfp410_connector_funcs = {
.destroy = tfp410_connector_destroy,
- .dpms = drm_atomic_helper_connector_dpms,
.detect = tfp410_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/tinydrm/Kconfig b/drivers/gpu/drm/tinydrm/Kconfig
index 3504c53846da..2e790e7dced5 100644
--- a/drivers/gpu/drm/tinydrm/Kconfig
+++ b/drivers/gpu/drm/tinydrm/Kconfig
@@ -19,3 +19,26 @@ config TINYDRM_MI0283QT
help
DRM driver for the Multi-Inno MI0283QT display panel
If M is selected the module will be called mi0283qt.
+
+config TINYDRM_REPAPER
+ tristate "DRM support for Pervasive Displays RePaper panels (V231)"
+ depends on DRM_TINYDRM && SPI
+ depends on THERMAL || !THERMAL
+ help
+ DRM driver for the following Pervasive Displays panels:
+ 1.44" TFT EPD Panel (E1144CS021)
+ 1.90" TFT EPD Panel (E1190CS021)
+ 2.00" TFT EPD Panel (E2200CS021)
+ 2.71" TFT EPD Panel (E2271CS021)
+
+ If M is selected the module will be called repaper.
+
+config TINYDRM_ST7586
+ tristate "DRM support for Sitronix ST7586 display panels"
+ depends on DRM_TINYDRM && SPI
+ select TINYDRM_MIPI_DBI
+ help
+ DRM driver for the following Sitronix ST7586 panels:
+ * LEGO MINDSTORMS EV3
+
+ If M is selected the module will be called st7586.
diff --git a/drivers/gpu/drm/tinydrm/Makefile b/drivers/gpu/drm/tinydrm/Makefile
index 7a3604cf4fc2..0c184bd1bb59 100644
--- a/drivers/gpu/drm/tinydrm/Makefile
+++ b/drivers/gpu/drm/tinydrm/Makefile
@@ -5,3 +5,5 @@ obj-$(CONFIG_TINYDRM_MIPI_DBI) += mipi-dbi.o
# Displays
obj-$(CONFIG_TINYDRM_MI0283QT) += mi0283qt.o
+obj-$(CONFIG_TINYDRM_REPAPER) += repaper.o
+obj-$(CONFIG_TINYDRM_ST7586) += st7586.o
diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c b/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
index d4cda3308ac7..bd6cce093a85 100644
--- a/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
+++ b/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
@@ -7,13 +7,15 @@
* (at your option) any later version.
*/
-#include <drm/tinydrm/tinydrm.h>
-#include <drm/tinydrm/tinydrm-helpers.h>
#include <linux/backlight.h>
+#include <linux/dma-buf.h>
#include <linux/pm.h>
#include <linux/spi/spi.h>
#include <linux/swab.h>
+#include <drm/tinydrm/tinydrm.h>
+#include <drm/tinydrm/tinydrm-helpers.h>
+
static unsigned int spi_max;
module_param(spi_max, uint, 0400);
MODULE_PARM_DESC(spi_max, "Set a lower SPI max transfer size");
@@ -181,6 +183,60 @@ void tinydrm_xrgb8888_to_rgb565(u16 *dst, void *vaddr,
EXPORT_SYMBOL(tinydrm_xrgb8888_to_rgb565);
/**
+ * tinydrm_xrgb8888_to_gray8 - Convert XRGB8888 to grayscale
+ * @dst: 8-bit grayscale destination buffer
+ * @vaddr: XRGB8888 source buffer
+ * @fb: DRM framebuffer
+ * @clip: Clip rectangle area to copy
+ *
+ * Drm doesn't have native monochrome or grayscale support.
+ * Such drivers can announce the commonly supported XR24 format to userspace
+ * and use this function to convert to the native format.
+ *
+ * Monochrome drivers will use the most significant bit,
+ * where 1 means foreground color and 0 background color.
+ *
+ * ITU BT.601 is used for the RGB -> luma (brightness) conversion.
+ */
+void tinydrm_xrgb8888_to_gray8(u8 *dst, void *vaddr, struct drm_framebuffer *fb,
+ struct drm_clip_rect *clip)
+{
+ unsigned int len = (clip->x2 - clip->x1) * sizeof(u32);
+ unsigned int x, y;
+ void *buf;
+ u32 *src;
+
+ if (WARN_ON(fb->format->format != DRM_FORMAT_XRGB8888))
+ return;
+ /*
+ * The cma memory is write-combined so reads are uncached.
+ * Speed up by fetching one line at a time.
+ */
+ buf = kmalloc(len, GFP_KERNEL);
+ if (!buf)
+ return;
+
+ for (y = clip->y1; y < clip->y2; y++) {
+ src = vaddr + (y * fb->pitches[0]);
+ src += clip->x1;
+ memcpy(buf, src, len);
+ src = buf;
+ for (x = clip->x1; x < clip->x2; x++) {
+ u8 r = (*src & 0x00ff0000) >> 16;
+ u8 g = (*src & 0x0000ff00) >> 8;
+ u8 b = *src & 0x000000ff;
+
+ /* ITU BT.601: Y = 0.299 R + 0.587 G + 0.114 B */
+ *dst++ = (3 * r + 6 * g + b) / 10;
+ src++;
+ }
+ }
+
+ kfree(buf);
+}
+EXPORT_SYMBOL(tinydrm_xrgb8888_to_gray8);
+
+/**
* tinydrm_of_find_backlight - Find backlight device in device-tree
* @dev: Device
*
diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c b/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c
index ec43fb7ad9e4..177e9d861001 100644
--- a/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c
+++ b/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c
@@ -56,7 +56,7 @@ static const struct drm_connector_helper_funcs tinydrm_connector_hfuncs = {
static enum drm_connector_status
tinydrm_connector_detect(struct drm_connector *connector, bool force)
{
- if (drm_device_is_unplugged(connector->dev))
+ if (drm_dev_is_unplugged(connector->dev))
return connector_status_disconnected;
return connector->status;
@@ -71,7 +71,6 @@ static void tinydrm_connector_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs tinydrm_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.reset = drm_atomic_helper_connector_reset,
.detect = tinydrm_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
@@ -225,7 +224,7 @@ tinydrm_display_pipe_init(struct tinydrm_device *tdev,
return PTR_ERR(connector);
ret = drm_simple_display_pipe_init(drm, &tdev->pipe, funcs, formats,
- format_count, connector);
+ format_count, NULL, connector);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/tinydrm/mi0283qt.c b/drivers/gpu/drm/tinydrm/mi0283qt.c
index 482ff1c3db61..7e5bb7d6f655 100644
--- a/drivers/gpu/drm/tinydrm/mi0283qt.c
+++ b/drivers/gpu/drm/tinydrm/mi0283qt.c
@@ -195,8 +195,12 @@ static int mi0283qt_probe(struct spi_device *spi)
device_property_read_u32(dev, "rotation", &rotation);
- ret = mipi_dbi_spi_init(spi, mipi, dc, &mi0283qt_pipe_funcs,
- &mi0283qt_driver, &mi0283qt_mode, rotation);
+ ret = mipi_dbi_spi_init(spi, mipi, dc);
+ if (ret)
+ return ret;
+
+ ret = mipi_dbi_init(&spi->dev, mipi, &mi0283qt_pipe_funcs,
+ &mi0283qt_driver, &mi0283qt_mode, rotation);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/tinydrm/mipi-dbi.c b/drivers/gpu/drm/tinydrm/mipi-dbi.c
index c83eeb7a34b0..2caeabcd3458 100644
--- a/drivers/gpu/drm/tinydrm/mipi-dbi.c
+++ b/drivers/gpu/drm/tinydrm/mipi-dbi.c
@@ -776,15 +776,12 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *mipi, u8 cmd,
/**
* mipi_dbi_spi_init - Initialize MIPI DBI SPI interfaced controller
* @spi: SPI device
- * @dc: D/C gpio (optional)
* @mipi: &mipi_dbi structure to initialize
- * @pipe_funcs: Display pipe functions
- * @driver: DRM driver
- * @mode: Display mode
- * @rotation: Initial rotation in degrees Counter Clock Wise
+ * @dc: D/C gpio (optional)
*
* This function sets &mipi_dbi->command, enables &mipi->read_commands for the
- * usual read commands and initializes @mipi using mipi_dbi_init().
+ * usual read commands. It should be followed by a call to mipi_dbi_init() or
+ * a driver-specific init.
*
* If @dc is set, a Type C Option 3 interface is assumed, if not
* Type C Option 1.
@@ -799,11 +796,7 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *mipi, u8 cmd,
* Zero on success, negative error code on failure.
*/
int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *mipi,
- struct gpio_desc *dc,
- const struct drm_simple_display_pipe_funcs *pipe_funcs,
- struct drm_driver *driver,
- const struct drm_display_mode *mode,
- unsigned int rotation)
+ struct gpio_desc *dc)
{
size_t tx_size = tinydrm_spi_max_transfer_size(spi, 0);
struct device *dev = &spi->dev;
@@ -849,7 +842,7 @@ int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *mipi,
return -ENOMEM;
}
- return mipi_dbi_init(dev, mipi, pipe_funcs, driver, mode, rotation);
+ return 0;
}
EXPORT_SYMBOL(mipi_dbi_spi_init);
diff --git a/drivers/gpu/drm/tinydrm/repaper.c b/drivers/gpu/drm/tinydrm/repaper.c
new file mode 100644
index 000000000000..30dc97b3ff21
--- /dev/null
+++ b/drivers/gpu/drm/tinydrm/repaper.c
@@ -0,0 +1,1117 @@
+/*
+ * DRM driver for Pervasive Displays RePaper branded e-ink panels
+ *
+ * Copyright 2013-2017 Pervasive Displays, Inc.
+ * Copyright 2017 Noralf Trønnes
+ *
+ * The driver supports:
+ * Material Film: Aurora Mb (V231)
+ * Driver IC: G2 (eTC)
+ *
+ * The controller code was taken from the userspace driver:
+ * https://github.com/repaper/gratis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/dma-buf.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/sched/clock.h>
+#include <linux/spi/spi.h>
+#include <linux/thermal.h>
+
+#include <drm/tinydrm/tinydrm.h>
+#include <drm/tinydrm/tinydrm-helpers.h>
+
+#define REPAPER_RID_G2_COG_ID 0x12
+
+enum repaper_model {
+ E1144CS021 = 1,
+ E1190CS021,
+ E2200CS021,
+ E2271CS021,
+};
+
+enum repaper_stage { /* Image pixel -> Display pixel */
+ REPAPER_COMPENSATE, /* B -> W, W -> B (Current Image) */
+ REPAPER_WHITE, /* B -> N, W -> W (Current Image) */
+ REPAPER_INVERSE, /* B -> N, W -> B (New Image) */
+ REPAPER_NORMAL /* B -> B, W -> W (New Image) */
+};
+
+enum repaper_epd_border_byte {
+ REPAPER_BORDER_BYTE_NONE,
+ REPAPER_BORDER_BYTE_ZERO,
+ REPAPER_BORDER_BYTE_SET,
+};
+
+struct repaper_epd {
+ struct tinydrm_device tinydrm;
+ struct spi_device *spi;
+
+ struct gpio_desc *panel_on;
+ struct gpio_desc *border;
+ struct gpio_desc *discharge;
+ struct gpio_desc *reset;
+ struct gpio_desc *busy;
+
+ struct thermal_zone_device *thermal;
+
+ unsigned int height;
+ unsigned int width;
+ unsigned int bytes_per_scan;
+ const u8 *channel_select;
+ unsigned int stage_time;
+ unsigned int factored_stage_time;
+ bool middle_scan;
+ bool pre_border_byte;
+ enum repaper_epd_border_byte border_byte;
+
+ u8 *line_buffer;
+ void *current_frame;
+
+ bool enabled;
+ bool cleared;
+ bool partial;
+};
+
+static inline struct repaper_epd *
+epd_from_tinydrm(struct tinydrm_device *tdev)
+{
+ return container_of(tdev, struct repaper_epd, tinydrm);
+}
+
+static int repaper_spi_transfer(struct spi_device *spi, u8 header,
+ const void *tx, void *rx, size_t len)
+{
+ void *txbuf = NULL, *rxbuf = NULL;
+ struct spi_transfer tr[2] = {};
+ u8 *headerbuf;
+ int ret;
+
+ headerbuf = kmalloc(1, GFP_KERNEL);
+ if (!headerbuf)
+ return -ENOMEM;
+
+ headerbuf[0] = header;
+ tr[0].tx_buf = headerbuf;
+ tr[0].len = 1;
+
+ /* Stack allocated tx? */
+ if (tx && len <= 32) {
+ txbuf = kmalloc(len, GFP_KERNEL);
+ if (!txbuf) {
+ ret = -ENOMEM;
+ goto out_free;
+ }
+ memcpy(txbuf, tx, len);
+ }
+
+ if (rx) {
+ rxbuf = kmalloc(len, GFP_KERNEL);
+ if (!rxbuf) {
+ ret = -ENOMEM;
+ goto out_free;
+ }
+ }
+
+ tr[1].tx_buf = txbuf ? txbuf : tx;
+ tr[1].rx_buf = rxbuf;
+ tr[1].len = len;
+
+ ndelay(80);
+ ret = spi_sync_transfer(spi, tr, 2);
+ if (rx && !ret)
+ memcpy(rx, rxbuf, len);
+
+out_free:
+ kfree(headerbuf);
+ kfree(txbuf);
+ kfree(rxbuf);
+
+ return ret;
+}
+
+static int repaper_write_buf(struct spi_device *spi, u8 reg,
+ const u8 *buf, size_t len)
+{
+ int ret;
+
+ ret = repaper_spi_transfer(spi, 0x70, &reg, NULL, 1);
+ if (ret)
+ return ret;
+
+ return repaper_spi_transfer(spi, 0x72, buf, NULL, len);
+}
+
+static int repaper_write_val(struct spi_device *spi, u8 reg, u8 val)
+{
+ return repaper_write_buf(spi, reg, &val, 1);
+}
+
+static int repaper_read_val(struct spi_device *spi, u8 reg)
+{
+ int ret;
+ u8 val;
+
+ ret = repaper_spi_transfer(spi, 0x70, &reg, NULL, 1);
+ if (ret)
+ return ret;
+
+ ret = repaper_spi_transfer(spi, 0x73, NULL, &val, 1);
+
+ return ret ? ret : val;
+}
+
+static int repaper_read_id(struct spi_device *spi)
+{
+ int ret;
+ u8 id;
+
+ ret = repaper_spi_transfer(spi, 0x71, NULL, &id, 1);
+
+ return ret ? ret : id;
+}
+
+static void repaper_spi_mosi_low(struct spi_device *spi)
+{
+ const u8 buf[1] = { 0 };
+
+ spi_write(spi, buf, 1);
+}
+
+/* pixels on display are numbered from 1 so even is actually bits 1,3,5,... */
+static void repaper_even_pixels(struct repaper_epd *epd, u8 **pp,
+ const u8 *data, u8 fixed_value, const u8 *mask,
+ enum repaper_stage stage)
+{
+ unsigned int b;
+
+ for (b = 0; b < (epd->width / 8); b++) {
+ if (data) {
+ u8 pixels = data[b] & 0xaa;
+ u8 pixel_mask = 0xff;
+ u8 p1, p2, p3, p4;
+
+ if (mask) {
+ pixel_mask = (mask[b] ^ pixels) & 0xaa;
+ pixel_mask |= pixel_mask >> 1;
+ }
+
+ switch (stage) {
+ case REPAPER_COMPENSATE: /* B -> W, W -> B (Current) */
+ pixels = 0xaa | ((pixels ^ 0xaa) >> 1);
+ break;
+ case REPAPER_WHITE: /* B -> N, W -> W (Current) */
+ pixels = 0x55 + ((pixels ^ 0xaa) >> 1);
+ break;
+ case REPAPER_INVERSE: /* B -> N, W -> B (New) */
+ pixels = 0x55 | (pixels ^ 0xaa);
+ break;
+ case REPAPER_NORMAL: /* B -> B, W -> W (New) */
+ pixels = 0xaa | (pixels >> 1);
+ break;
+ }
+
+ pixels = (pixels & pixel_mask) | (~pixel_mask & 0x55);
+ p1 = (pixels >> 6) & 0x03;
+ p2 = (pixels >> 4) & 0x03;
+ p3 = (pixels >> 2) & 0x03;
+ p4 = (pixels >> 0) & 0x03;
+ pixels = (p1 << 0) | (p2 << 2) | (p3 << 4) | (p4 << 6);
+ *(*pp)++ = pixels;
+ } else {
+ *(*pp)++ = fixed_value;
+ }
+ }
+}
+
+/* pixels on display are numbered from 1 so odd is actually bits 0,2,4,... */
+static void repaper_odd_pixels(struct repaper_epd *epd, u8 **pp,
+ const u8 *data, u8 fixed_value, const u8 *mask,
+ enum repaper_stage stage)
+{
+ unsigned int b;
+
+ for (b = epd->width / 8; b > 0; b--) {
+ if (data) {
+ u8 pixels = data[b - 1] & 0x55;
+ u8 pixel_mask = 0xff;
+
+ if (mask) {
+ pixel_mask = (mask[b - 1] ^ pixels) & 0x55;
+ pixel_mask |= pixel_mask << 1;
+ }
+
+ switch (stage) {
+ case REPAPER_COMPENSATE: /* B -> W, W -> B (Current) */
+ pixels = 0xaa | (pixels ^ 0x55);
+ break;
+ case REPAPER_WHITE: /* B -> N, W -> W (Current) */
+ pixels = 0x55 + (pixels ^ 0x55);
+ break;
+ case REPAPER_INVERSE: /* B -> N, W -> B (New) */
+ pixels = 0x55 | ((pixels ^ 0x55) << 1);
+ break;
+ case REPAPER_NORMAL: /* B -> B, W -> W (New) */
+ pixels = 0xaa | pixels;
+ break;
+ }
+
+ pixels = (pixels & pixel_mask) | (~pixel_mask & 0x55);
+ *(*pp)++ = pixels;
+ } else {
+ *(*pp)++ = fixed_value;
+ }
+ }
+}
+
+/* interleave bits: (byte)76543210 -> (16 bit).7.6.5.4.3.2.1 */
+static inline u16 repaper_interleave_bits(u16 value)
+{
+ value = (value | (value << 4)) & 0x0f0f;
+ value = (value | (value << 2)) & 0x3333;
+ value = (value | (value << 1)) & 0x5555;
+
+ return value;
+}
+
+/* pixels on display are numbered from 1 */
+static void repaper_all_pixels(struct repaper_epd *epd, u8 **pp,
+ const u8 *data, u8 fixed_value, const u8 *mask,
+ enum repaper_stage stage)
+{
+ unsigned int b;
+
+ for (b = epd->width / 8; b > 0; b--) {
+ if (data) {
+ u16 pixels = repaper_interleave_bits(data[b - 1]);
+ u16 pixel_mask = 0xffff;
+
+ if (mask) {
+ pixel_mask = repaper_interleave_bits(mask[b - 1]);
+
+ pixel_mask = (pixel_mask ^ pixels) & 0x5555;
+ pixel_mask |= pixel_mask << 1;
+ }
+
+ switch (stage) {
+ case REPAPER_COMPENSATE: /* B -> W, W -> B (Current) */
+ pixels = 0xaaaa | (pixels ^ 0x5555);
+ break;
+ case REPAPER_WHITE: /* B -> N, W -> W (Current) */
+ pixels = 0x5555 + (pixels ^ 0x5555);
+ break;
+ case REPAPER_INVERSE: /* B -> N, W -> B (New) */
+ pixels = 0x5555 | ((pixels ^ 0x5555) << 1);
+ break;
+ case REPAPER_NORMAL: /* B -> B, W -> W (New) */
+ pixels = 0xaaaa | pixels;
+ break;
+ }
+
+ pixels = (pixels & pixel_mask) | (~pixel_mask & 0x5555);
+ *(*pp)++ = pixels >> 8;
+ *(*pp)++ = pixels;
+ } else {
+ *(*pp)++ = fixed_value;
+ *(*pp)++ = fixed_value;
+ }
+ }
+}
+
+/* output one line of scan and data bytes to the display */
+static void repaper_one_line(struct repaper_epd *epd, unsigned int line,
+ const u8 *data, u8 fixed_value, const u8 *mask,
+ enum repaper_stage stage)
+{
+ u8 *p = epd->line_buffer;
+ unsigned int b;
+
+ repaper_spi_mosi_low(epd->spi);
+
+ if (epd->pre_border_byte)
+ *p++ = 0x00;
+
+ if (epd->middle_scan) {
+ /* data bytes */
+ repaper_odd_pixels(epd, &p, data, fixed_value, mask, stage);
+
+ /* scan line */
+ for (b = epd->bytes_per_scan; b > 0; b--) {
+ if (line / 4 == b - 1)
+ *p++ = 0x03 << (2 * (line & 0x03));
+ else
+ *p++ = 0x00;
+ }
+
+ /* data bytes */
+ repaper_even_pixels(epd, &p, data, fixed_value, mask, stage);
+ } else {
+ /*
+ * even scan line, but as lines on display are numbered from 1,
+ * line: 1,3,5,...
+ */
+ for (b = 0; b < epd->bytes_per_scan; b++) {
+ if (0 != (line & 0x01) && line / 8 == b)
+ *p++ = 0xc0 >> (line & 0x06);
+ else
+ *p++ = 0x00;
+ }
+
+ /* data bytes */
+ repaper_all_pixels(epd, &p, data, fixed_value, mask, stage);
+
+ /*
+ * odd scan line, but as lines on display are numbered from 1,
+ * line: 0,2,4,6,...
+ */
+ for (b = epd->bytes_per_scan; b > 0; b--) {
+ if (0 == (line & 0x01) && line / 8 == b - 1)
+ *p++ = 0x03 << (line & 0x06);
+ else
+ *p++ = 0x00;
+ }
+ }
+
+ switch (epd->border_byte) {
+ case REPAPER_BORDER_BYTE_NONE:
+ break;
+
+ case REPAPER_BORDER_BYTE_ZERO:
+ *p++ = 0x00;
+ break;
+
+ case REPAPER_BORDER_BYTE_SET:
+ switch (stage) {
+ case REPAPER_COMPENSATE:
+ case REPAPER_WHITE:
+ case REPAPER_INVERSE:
+ *p++ = 0x00;
+ break;
+ case REPAPER_NORMAL:
+ *p++ = 0xaa;
+ break;
+ }
+ break;
+ }
+
+ repaper_write_buf(epd->spi, 0x0a, epd->line_buffer,
+ p - epd->line_buffer);
+
+ /* Output data to panel */
+ repaper_write_val(epd->spi, 0x02, 0x07);
+
+ repaper_spi_mosi_low(epd->spi);
+}
+
+static void repaper_frame_fixed(struct repaper_epd *epd, u8 fixed_value,
+ enum repaper_stage stage)
+{
+ unsigned int line;
+
+ for (line = 0; line < epd->height; line++)
+ repaper_one_line(epd, line, NULL, fixed_value, NULL, stage);
+}
+
+static void repaper_frame_data(struct repaper_epd *epd, const u8 *image,
+ const u8 *mask, enum repaper_stage stage)
+{
+ unsigned int line;
+
+ if (!mask) {
+ for (line = 0; line < epd->height; line++) {
+ repaper_one_line(epd, line,
+ &image[line * (epd->width / 8)],
+ 0, NULL, stage);
+ }
+ } else {
+ for (line = 0; line < epd->height; line++) {
+ size_t n = line * epd->width / 8;
+
+ repaper_one_line(epd, line, &image[n], 0, &mask[n],
+ stage);
+ }
+ }
+}
+
+static void repaper_frame_fixed_repeat(struct repaper_epd *epd, u8 fixed_value,
+ enum repaper_stage stage)
+{
+ u64 start = local_clock();
+ u64 end = start + (epd->factored_stage_time * 1000 * 1000);
+
+ do {
+ repaper_frame_fixed(epd, fixed_value, stage);
+ } while (local_clock() < end);
+}
+
+static void repaper_frame_data_repeat(struct repaper_epd *epd, const u8 *image,
+ const u8 *mask, enum repaper_stage stage)
+{
+ u64 start = local_clock();
+ u64 end = start + (epd->factored_stage_time * 1000 * 1000);
+
+ do {
+ repaper_frame_data(epd, image, mask, stage);
+ } while (local_clock() < end);
+}
+
+static void repaper_get_temperature(struct repaper_epd *epd)
+{
+ int ret, temperature = 0;
+ unsigned int factor10x;
+
+ if (!epd->thermal)
+ return;
+
+ ret = thermal_zone_get_temp(epd->thermal, &temperature);
+ if (ret) {
+ dev_err(&epd->spi->dev, "Failed to get temperature (%d)\n",
+ ret);
+ return;
+ }
+
+ temperature /= 1000;
+
+ if (temperature <= -10)
+ factor10x = 170;
+ else if (temperature <= -5)
+ factor10x = 120;
+ else if (temperature <= 5)
+ factor10x = 80;
+ else if (temperature <= 10)
+ factor10x = 40;
+ else if (temperature <= 15)
+ factor10x = 30;
+ else if (temperature <= 20)
+ factor10x = 20;
+ else if (temperature <= 40)
+ factor10x = 10;
+ else
+ factor10x = 7;
+
+ epd->factored_stage_time = epd->stage_time * factor10x / 10;
+}
+
+static void repaper_gray8_to_mono_reversed(u8 *buf, u32 width, u32 height)
+{
+ u8 *gray8 = buf, *mono = buf;
+ int y, xb, i;
+
+ for (y = 0; y < height; y++)
+ for (xb = 0; xb < width / 8; xb++) {
+ u8 byte = 0x00;
+
+ for (i = 0; i < 8; i++) {
+ int x = xb * 8 + i;
+
+ byte >>= 1;
+ if (gray8[y * width + x] >> 7)
+ byte |= BIT(7);
+ }
+ *mono++ = byte;
+ }
+}
+
+static int repaper_fb_dirty(struct drm_framebuffer *fb,
+ struct drm_file *file_priv,
+ unsigned int flags, unsigned int color,
+ struct drm_clip_rect *clips,
+ unsigned int num_clips)
+{
+ struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
+ struct dma_buf_attachment *import_attach = cma_obj->base.import_attach;
+ struct tinydrm_device *tdev = fb->dev->dev_private;
+ struct repaper_epd *epd = epd_from_tinydrm(tdev);
+ struct drm_clip_rect clip;
+ u8 *buf = NULL;
+ int ret = 0;
+
+ /* repaper can't do partial updates */
+ clip.x1 = 0;
+ clip.x2 = fb->width;
+ clip.y1 = 0;
+ clip.y2 = fb->height;
+
+ mutex_lock(&tdev->dirty_lock);
+
+ if (!epd->enabled)
+ goto out_unlock;
+
+ /* fbdev can flush even when we're not interested */
+ if (tdev->pipe.plane.fb != fb)
+ goto out_unlock;
+
+ repaper_get_temperature(epd);
+
+ DRM_DEBUG("Flushing [FB:%d] st=%ums\n", fb->base.id,
+ epd->factored_stage_time);
+
+ buf = kmalloc(fb->width * fb->height, GFP_KERNEL);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto out_unlock;
+ }
+
+ if (import_attach) {
+ ret = dma_buf_begin_cpu_access(import_attach->dmabuf,
+ DMA_FROM_DEVICE);
+ if (ret)
+ goto out_unlock;
+ }
+
+ tinydrm_xrgb8888_to_gray8(buf, cma_obj->vaddr, fb, &clip);
+
+ if (import_attach) {
+ ret = dma_buf_end_cpu_access(import_attach->dmabuf,
+ DMA_FROM_DEVICE);
+ if (ret)
+ goto out_unlock;
+ }
+
+ repaper_gray8_to_mono_reversed(buf, fb->width, fb->height);
+
+ if (epd->partial) {
+ repaper_frame_data_repeat(epd, buf, epd->current_frame,
+ REPAPER_NORMAL);
+ } else if (epd->cleared) {
+ repaper_frame_data_repeat(epd, epd->current_frame, NULL,
+ REPAPER_COMPENSATE);
+ repaper_frame_data_repeat(epd, epd->current_frame, NULL,
+ REPAPER_WHITE);
+ repaper_frame_data_repeat(epd, buf, NULL, REPAPER_INVERSE);
+ repaper_frame_data_repeat(epd, buf, NULL, REPAPER_NORMAL);
+
+ epd->partial = true;
+ } else {
+ /* Clear display (anything -> white) */
+ repaper_frame_fixed_repeat(epd, 0xff, REPAPER_COMPENSATE);
+ repaper_frame_fixed_repeat(epd, 0xff, REPAPER_WHITE);
+ repaper_frame_fixed_repeat(epd, 0xaa, REPAPER_INVERSE);
+ repaper_frame_fixed_repeat(epd, 0xaa, REPAPER_NORMAL);
+
+ /* Assuming a clear (white) screen output an image */
+ repaper_frame_fixed_repeat(epd, 0xaa, REPAPER_COMPENSATE);
+ repaper_frame_fixed_repeat(epd, 0xaa, REPAPER_WHITE);
+ repaper_frame_data_repeat(epd, buf, NULL, REPAPER_INVERSE);
+ repaper_frame_data_repeat(epd, buf, NULL, REPAPER_NORMAL);
+
+ epd->cleared = true;
+ epd->partial = true;
+ }
+
+ memcpy(epd->current_frame, buf, fb->width * fb->height / 8);
+
+ /*
+ * An extra frame write is needed if pixels are set in the bottom line,
+ * or else grey lines rises up from the pixels
+ */
+ if (epd->pre_border_byte) {
+ unsigned int x;
+
+ for (x = 0; x < (fb->width / 8); x++)
+ if (buf[x + (fb->width * (fb->height - 1) / 8)]) {
+ repaper_frame_data_repeat(epd, buf,
+ epd->current_frame,
+ REPAPER_NORMAL);
+ break;
+ }
+ }
+
+out_unlock:
+ mutex_unlock(&tdev->dirty_lock);
+
+ if (ret)
+ dev_err(fb->dev->dev, "Failed to update display (%d)\n", ret);
+ kfree(buf);
+
+ return ret;
+}
+
+static const struct drm_framebuffer_funcs repaper_fb_funcs = {
+ .destroy = drm_fb_cma_destroy,
+ .create_handle = drm_fb_cma_create_handle,
+ .dirty = repaper_fb_dirty,
+};
+
+static void power_off(struct repaper_epd *epd)
+{
+ /* Turn off power and all signals */
+ gpiod_set_value_cansleep(epd->reset, 0);
+ gpiod_set_value_cansleep(epd->panel_on, 0);
+ if (epd->border)
+ gpiod_set_value_cansleep(epd->border, 0);
+
+ /* Ensure SPI MOSI and CLOCK are Low before CS Low */
+ repaper_spi_mosi_low(epd->spi);
+
+ /* Discharge pulse */
+ gpiod_set_value_cansleep(epd->discharge, 1);
+ msleep(150);
+ gpiod_set_value_cansleep(epd->discharge, 0);
+}
+
+static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
+ struct drm_crtc_state *crtc_state)
+{
+ struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
+ struct repaper_epd *epd = epd_from_tinydrm(tdev);
+ struct spi_device *spi = epd->spi;
+ struct device *dev = &spi->dev;
+ bool dc_ok = false;
+ int i, ret;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ /* Power up sequence */
+ gpiod_set_value_cansleep(epd->reset, 0);
+ gpiod_set_value_cansleep(epd->panel_on, 0);
+ gpiod_set_value_cansleep(epd->discharge, 0);
+ if (epd->border)
+ gpiod_set_value_cansleep(epd->border, 0);
+ repaper_spi_mosi_low(spi);
+ usleep_range(5000, 10000);
+
+ gpiod_set_value_cansleep(epd->panel_on, 1);
+ /*
+ * This delay comes from the repaper.org userspace driver, it's not
+ * mentioned in the datasheet.
+ */
+ usleep_range(10000, 15000);
+ gpiod_set_value_cansleep(epd->reset, 1);
+ if (epd->border)
+ gpiod_set_value_cansleep(epd->border, 1);
+ usleep_range(5000, 10000);
+ gpiod_set_value_cansleep(epd->reset, 0);
+ usleep_range(5000, 10000);
+ gpiod_set_value_cansleep(epd->reset, 1);
+ usleep_range(5000, 10000);
+
+ /* Wait for COG to become ready */
+ for (i = 100; i > 0; i--) {
+ if (!gpiod_get_value_cansleep(epd->busy))
+ break;
+
+ usleep_range(10, 100);
+ }
+
+ if (!i) {
+ dev_err(dev, "timeout waiting for panel to become ready.\n");
+ power_off(epd);
+ return;
+ }
+
+ repaper_read_id(spi);
+ ret = repaper_read_id(spi);
+ if (ret != REPAPER_RID_G2_COG_ID) {
+ if (ret < 0)
+ dev_err(dev, "failed to read chip (%d)\n", ret);
+ else
+ dev_err(dev, "wrong COG ID 0x%02x\n", ret);
+ power_off(epd);
+ return;
+ }
+
+ /* Disable OE */
+ repaper_write_val(spi, 0x02, 0x40);
+
+ ret = repaper_read_val(spi, 0x0f);
+ if (ret < 0 || !(ret & 0x80)) {
+ if (ret < 0)
+ dev_err(dev, "failed to read chip (%d)\n", ret);
+ else
+ dev_err(dev, "panel is reported broken\n");
+ power_off(epd);
+ return;
+ }
+
+ /* Power saving mode */
+ repaper_write_val(spi, 0x0b, 0x02);
+ /* Channel select */
+ repaper_write_buf(spi, 0x01, epd->channel_select, 8);
+ /* High power mode osc */
+ repaper_write_val(spi, 0x07, 0xd1);
+ /* Power setting */
+ repaper_write_val(spi, 0x08, 0x02);
+ /* Vcom level */
+ repaper_write_val(spi, 0x09, 0xc2);
+ /* Power setting */
+ repaper_write_val(spi, 0x04, 0x03);
+ /* Driver latch on */
+ repaper_write_val(spi, 0x03, 0x01);
+ /* Driver latch off */
+ repaper_write_val(spi, 0x03, 0x00);
+ usleep_range(5000, 10000);
+
+ /* Start chargepump */
+ for (i = 0; i < 4; ++i) {
+ /* Charge pump positive voltage on - VGH/VDL on */
+ repaper_write_val(spi, 0x05, 0x01);
+ msleep(240);
+
+ /* Charge pump negative voltage on - VGL/VDL on */
+ repaper_write_val(spi, 0x05, 0x03);
+ msleep(40);
+
+ /* Charge pump Vcom on - Vcom driver on */
+ repaper_write_val(spi, 0x05, 0x0f);
+ msleep(40);
+
+ /* check DC/DC */
+ ret = repaper_read_val(spi, 0x0f);
+ if (ret < 0) {
+ dev_err(dev, "failed to read chip (%d)\n", ret);
+ power_off(epd);
+ return;
+ }
+
+ if (ret & 0x40) {
+ dc_ok = true;
+ break;
+ }
+ }
+
+ if (!dc_ok) {
+ dev_err(dev, "dc/dc failed\n");
+ power_off(epd);
+ return;
+ }
+
+ /*
+ * Output enable to disable
+ * The userspace driver sets this to 0x04, but the datasheet says 0x06
+ */
+ repaper_write_val(spi, 0x02, 0x04);
+
+ epd->enabled = true;
+ epd->partial = false;
+}
+
+static void repaper_pipe_disable(struct drm_simple_display_pipe *pipe)
+{
+ struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
+ struct repaper_epd *epd = epd_from_tinydrm(tdev);
+ struct spi_device *spi = epd->spi;
+ unsigned int line;
+
+ DRM_DEBUG_DRIVER("\n");
+
+ mutex_lock(&tdev->dirty_lock);
+ epd->enabled = false;
+ mutex_unlock(&tdev->dirty_lock);
+
+ /* Nothing frame */
+ for (line = 0; line < epd->height; line++)
+ repaper_one_line(epd, 0x7fffu, NULL, 0x00, NULL,
+ REPAPER_COMPENSATE);
+
+ /* 2.7" */
+ if (epd->border) {
+ /* Dummy line */
+ repaper_one_line(epd, 0x7fffu, NULL, 0x00, NULL,
+ REPAPER_COMPENSATE);
+ msleep(25);
+ gpiod_set_value_cansleep(epd->border, 0);
+ msleep(200);
+ gpiod_set_value_cansleep(epd->border, 1);
+ } else {
+ /* Border dummy line */
+ repaper_one_line(epd, 0x7fffu, NULL, 0x00, NULL,
+ REPAPER_NORMAL);
+ msleep(200);
+ }
+
+ /* not described in datasheet */
+ repaper_write_val(spi, 0x0b, 0x00);
+ /* Latch reset turn on */
+ repaper_write_val(spi, 0x03, 0x01);
+ /* Power off charge pump Vcom */
+ repaper_write_val(spi, 0x05, 0x03);
+ /* Power off charge pump neg voltage */
+ repaper_write_val(spi, 0x05, 0x01);
+ msleep(120);
+ /* Discharge internal */
+ repaper_write_val(spi, 0x04, 0x80);
+ /* turn off all charge pumps */
+ repaper_write_val(spi, 0x05, 0x00);
+ /* Turn off osc */
+ repaper_write_val(spi, 0x07, 0x01);
+ msleep(50);
+
+ power_off(epd);
+}
+
+static const struct drm_simple_display_pipe_funcs repaper_pipe_funcs = {
+ .enable = repaper_pipe_enable,
+ .disable = repaper_pipe_disable,
+ .update = tinydrm_display_pipe_update,
+ .prepare_fb = tinydrm_display_pipe_prepare_fb,
+};
+
+static const uint32_t repaper_formats[] = {
+ DRM_FORMAT_XRGB8888,
+};
+
+static const struct drm_display_mode repaper_e1144cs021_mode = {
+ TINYDRM_MODE(128, 96, 29, 22),
+};
+
+static const u8 repaper_e1144cs021_cs[] = { 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0xff, 0x00 };
+
+static const struct drm_display_mode repaper_e1190cs021_mode = {
+ TINYDRM_MODE(144, 128, 36, 32),
+};
+
+static const u8 repaper_e1190cs021_cs[] = { 0x00, 0x00, 0x00, 0x03,
+ 0xfc, 0x00, 0x00, 0xff };
+
+static const struct drm_display_mode repaper_e2200cs021_mode = {
+ TINYDRM_MODE(200, 96, 46, 22),
+};
+
+static const u8 repaper_e2200cs021_cs[] = { 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0xff, 0xe0, 0x00 };
+
+static const struct drm_display_mode repaper_e2271cs021_mode = {
+ TINYDRM_MODE(264, 176, 57, 38),
+};
+
+static const u8 repaper_e2271cs021_cs[] = { 0x00, 0x00, 0x00, 0x7f,
+ 0xff, 0xfe, 0x00, 0x00 };
+
+DEFINE_DRM_GEM_CMA_FOPS(repaper_fops);
+
+static struct drm_driver repaper_driver = {
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
+ DRIVER_ATOMIC,
+ .fops = &repaper_fops,
+ TINYDRM_GEM_DRIVER_OPS,
+ .name = "repaper",
+ .desc = "Pervasive Displays RePaper e-ink panels",
+ .date = "20170405",
+ .major = 1,
+ .minor = 0,
+};
+
+static const struct of_device_id repaper_of_match[] = {
+ { .compatible = "pervasive,e1144cs021", .data = (void *)E1144CS021 },
+ { .compatible = "pervasive,e1190cs021", .data = (void *)E1190CS021 },
+ { .compatible = "pervasive,e2200cs021", .data = (void *)E2200CS021 },
+ { .compatible = "pervasive,e2271cs021", .data = (void *)E2271CS021 },
+ {},
+};
+MODULE_DEVICE_TABLE(of, repaper_of_match);
+
+static const struct spi_device_id repaper_id[] = {
+ { "e1144cs021", E1144CS021 },
+ { "e1190cs021", E1190CS021 },
+ { "e2200cs021", E2200CS021 },
+ { "e2271cs021", E2271CS021 },
+ { },
+};
+MODULE_DEVICE_TABLE(spi, repaper_id);
+
+static int repaper_probe(struct spi_device *spi)
+{
+ const struct drm_display_mode *mode;
+ const struct spi_device_id *spi_id;
+ const struct of_device_id *match;
+ struct device *dev = &spi->dev;
+ struct tinydrm_device *tdev;
+ enum repaper_model model;
+ const char *thermal_zone;
+ struct repaper_epd *epd;
+ size_t line_buffer_size;
+ int ret;
+
+ match = of_match_device(repaper_of_match, dev);
+ if (match) {
+ model = (enum repaper_model)match->data;
+ } else {
+ spi_id = spi_get_device_id(spi);
+ model = spi_id->driver_data;
+ }
+
+ /* The SPI device is used to allocate dma memory */
+ if (!dev->coherent_dma_mask) {
+ ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
+ if (ret) {
+ dev_warn(dev, "Failed to set dma mask %d\n", ret);
+ return ret;
+ }
+ }
+
+ epd = devm_kzalloc(dev, sizeof(*epd), GFP_KERNEL);
+ if (!epd)
+ return -ENOMEM;
+
+ epd->spi = spi;
+
+ epd->panel_on = devm_gpiod_get(dev, "panel-on", GPIOD_OUT_LOW);
+ if (IS_ERR(epd->panel_on)) {
+ ret = PTR_ERR(epd->panel_on);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get gpio 'panel-on'\n");
+ return ret;
+ }
+
+ epd->discharge = devm_gpiod_get(dev, "discharge", GPIOD_OUT_LOW);
+ if (IS_ERR(epd->discharge)) {
+ ret = PTR_ERR(epd->discharge);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get gpio 'discharge'\n");
+ return ret;
+ }
+
+ epd->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(epd->reset)) {
+ ret = PTR_ERR(epd->reset);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get gpio 'reset'\n");
+ return ret;
+ }
+
+ epd->busy = devm_gpiod_get(dev, "busy", GPIOD_IN);
+ if (IS_ERR(epd->busy)) {
+ ret = PTR_ERR(epd->busy);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get gpio 'busy'\n");
+ return ret;
+ }
+
+ if (!device_property_read_string(dev, "pervasive,thermal-zone",
+ &thermal_zone)) {
+ epd->thermal = thermal_zone_get_zone_by_name(thermal_zone);
+ if (IS_ERR(epd->thermal)) {
+ dev_err(dev, "Failed to get thermal zone: %s\n",
+ thermal_zone);
+ return PTR_ERR(epd->thermal);
+ }
+ }
+
+ switch (model) {
+ case E1144CS021:
+ mode = &repaper_e1144cs021_mode;
+ epd->channel_select = repaper_e1144cs021_cs;
+ epd->stage_time = 480;
+ epd->bytes_per_scan = 96 / 4;
+ epd->middle_scan = true; /* data-scan-data */
+ epd->pre_border_byte = false;
+ epd->border_byte = REPAPER_BORDER_BYTE_ZERO;
+ break;
+
+ case E1190CS021:
+ mode = &repaper_e1190cs021_mode;
+ epd->channel_select = repaper_e1190cs021_cs;
+ epd->stage_time = 480;
+ epd->bytes_per_scan = 128 / 4 / 2;
+ epd->middle_scan = false; /* scan-data-scan */
+ epd->pre_border_byte = false;
+ epd->border_byte = REPAPER_BORDER_BYTE_SET;
+ break;
+
+ case E2200CS021:
+ mode = &repaper_e2200cs021_mode;
+ epd->channel_select = repaper_e2200cs021_cs;
+ epd->stage_time = 480;
+ epd->bytes_per_scan = 96 / 4;
+ epd->middle_scan = true; /* data-scan-data */
+ epd->pre_border_byte = true;
+ epd->border_byte = REPAPER_BORDER_BYTE_NONE;
+ break;
+
+ case E2271CS021:
+ epd->border = devm_gpiod_get(dev, "border", GPIOD_OUT_LOW);
+ if (IS_ERR(epd->border)) {
+ ret = PTR_ERR(epd->border);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get gpio 'border'\n");
+ return ret;
+ }
+
+ mode = &repaper_e2271cs021_mode;
+ epd->channel_select = repaper_e2271cs021_cs;
+ epd->stage_time = 630;
+ epd->bytes_per_scan = 176 / 4;
+ epd->middle_scan = true; /* data-scan-data */
+ epd->pre_border_byte = true;
+ epd->border_byte = REPAPER_BORDER_BYTE_NONE;
+ break;
+
+ default:
+ return -ENODEV;
+ }
+
+ epd->width = mode->hdisplay;
+ epd->height = mode->vdisplay;
+ epd->factored_stage_time = epd->stage_time;
+
+ line_buffer_size = 2 * epd->width / 8 + epd->bytes_per_scan + 2;
+ epd->line_buffer = devm_kzalloc(dev, line_buffer_size, GFP_KERNEL);
+ if (!epd->line_buffer)
+ return -ENOMEM;
+
+ epd->current_frame = devm_kzalloc(dev, epd->width * epd->height / 8,
+ GFP_KERNEL);
+ if (!epd->current_frame)
+ return -ENOMEM;
+
+ tdev = &epd->tinydrm;
+
+ ret = devm_tinydrm_init(dev, tdev, &repaper_fb_funcs, &repaper_driver);
+ if (ret)
+ return ret;
+
+ ret = tinydrm_display_pipe_init(tdev, &repaper_pipe_funcs,
+ DRM_MODE_CONNECTOR_VIRTUAL,
+ repaper_formats,
+ ARRAY_SIZE(repaper_formats), mode, 0);
+ if (ret)
+ return ret;
+
+ drm_mode_config_reset(tdev->drm);
+
+ ret = devm_tinydrm_register(tdev);
+ if (ret)
+ return ret;
+
+ spi_set_drvdata(spi, tdev);
+
+ DRM_DEBUG_DRIVER("Initialized %s:%s @%uMHz on minor %d\n",
+ tdev->drm->driver->name, dev_name(dev),
+ spi->max_speed_hz / 1000000,
+ tdev->drm->primary->index);
+
+ return 0;
+}
+
+static void repaper_shutdown(struct spi_device *spi)
+{
+ struct tinydrm_device *tdev = spi_get_drvdata(spi);
+
+ tinydrm_shutdown(tdev);
+}
+
+static struct spi_driver repaper_spi_driver = {
+ .driver = {
+ .name = "repaper",
+ .owner = THIS_MODULE,
+ .of_match_table = repaper_of_match,
+ },
+ .id_table = repaper_id,
+ .probe = repaper_probe,
+ .shutdown = repaper_shutdown,
+};
+module_spi_driver(repaper_spi_driver);
+
+MODULE_DESCRIPTION("Pervasive Displays RePaper DRM driver");
+MODULE_AUTHOR("Noralf Trønnes");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tinydrm/st7586.c b/drivers/gpu/drm/tinydrm/st7586.c
new file mode 100644
index 000000000000..b439956a07f4
--- /dev/null
+++ b/drivers/gpu/drm/tinydrm/st7586.c
@@ -0,0 +1,428 @@
+/*
+ * DRM driver for Sitronix ST7586 panels
+ *
+ * Copyright 2017 David Lechner <david@lechnology.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/dma-buf.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/spi/spi.h>
+#include <video/mipi_display.h>
+
+#include <drm/tinydrm/mipi-dbi.h>
+#include <drm/tinydrm/tinydrm-helpers.h>
+
+/* controller-specific commands */
+#define ST7586_DISP_MODE_GRAY 0x38
+#define ST7586_DISP_MODE_MONO 0x39
+#define ST7586_ENABLE_DDRAM 0x3a
+#define ST7586_SET_DISP_DUTY 0xb0
+#define ST7586_SET_PART_DISP 0xb4
+#define ST7586_SET_NLINE_INV 0xb5
+#define ST7586_SET_VOP 0xc0
+#define ST7586_SET_BIAS_SYSTEM 0xc3
+#define ST7586_SET_BOOST_LEVEL 0xc4
+#define ST7586_SET_VOP_OFFSET 0xc7
+#define ST7586_ENABLE_ANALOG 0xd0
+#define ST7586_AUTO_READ_CTRL 0xd7
+#define ST7586_OTP_RW_CTRL 0xe0
+#define ST7586_OTP_CTRL_OUT 0xe1
+#define ST7586_OTP_READ 0xe3
+
+#define ST7586_DISP_CTRL_MX BIT(6)
+#define ST7586_DISP_CTRL_MY BIT(7)
+
+/*
+ * The ST7586 controller has an unusual pixel format where 2bpp grayscale is
+ * packed 3 pixels per byte with the first two pixels using 3 bits and the 3rd
+ * pixel using only 2 bits.
+ *
+ * | D7 | D6 | D5 || | || 2bpp |
+ * | (D4) | (D3) | (D2) || D1 | D0 || GRAY |
+ * +------+------+------++------+------++------+
+ * | 1 | 1 | 1 || 1 | 1 || 0 0 | black
+ * | 1 | 0 | 0 || 1 | 0 || 0 1 | dark gray
+ * | 0 | 1 | 0 || 0 | 1 || 1 0 | light gray
+ * | 0 | 0 | 0 || 0 | 0 || 1 1 | white
+ */
+
+static const u8 st7586_lookup[] = { 0x7, 0x4, 0x2, 0x0 };
+
+static void st7586_xrgb8888_to_gray332(u8 *dst, void *vaddr,
+ struct drm_framebuffer *fb,
+ struct drm_clip_rect *clip)
+{
+ size_t len = (clip->x2 - clip->x1) * (clip->y2 - clip->y1);
+ unsigned int x, y;
+ u8 *src, *buf, val;
+
+ buf = kmalloc(len, GFP_KERNEL);
+ if (!buf)
+ return;
+
+ tinydrm_xrgb8888_to_gray8(buf, vaddr, fb, clip);
+ src = buf;
+
+ for (y = clip->y1; y < clip->y2; y++) {
+ for (x = clip->x1; x < clip->x2; x += 3) {
+ val = st7586_lookup[*src++ >> 6] << 5;
+ val |= st7586_lookup[*src++ >> 6] << 2;
+ val |= st7586_lookup[*src++ >> 6] >> 1;
+ *dst++ = val;
+ }
+ }
+
+ kfree(buf);
+}
+
+static int st7586_buf_copy(void *dst, struct drm_framebuffer *fb,
+ struct drm_clip_rect *clip)
+{
+ struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
+ struct dma_buf_attachment *import_attach = cma_obj->base.import_attach;
+ void *src = cma_obj->vaddr;
+ int ret = 0;
+
+ if (import_attach) {
+ ret = dma_buf_begin_cpu_access(import_attach->dmabuf,
+ DMA_FROM_DEVICE);
+ if (ret)
+ return ret;
+ }
+
+ st7586_xrgb8888_to_gray332(dst, src, fb, clip);
+
+ if (import_attach)
+ ret = dma_buf_end_cpu_access(import_attach->dmabuf,
+ DMA_FROM_DEVICE);
+
+ return ret;
+}
+
+static int st7586_fb_dirty(struct drm_framebuffer *fb,
+ struct drm_file *file_priv, unsigned int flags,
+ unsigned int color, struct drm_clip_rect *clips,
+ unsigned int num_clips)
+{
+ struct tinydrm_device *tdev = fb->dev->dev_private;
+ struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
+ struct drm_clip_rect clip;
+ int start, end;
+ int ret = 0;
+
+ mutex_lock(&tdev->dirty_lock);
+
+ if (!mipi->enabled)
+ goto out_unlock;
+
+ /* fbdev can flush even when we're not interested */
+ if (tdev->pipe.plane.fb != fb)
+ goto out_unlock;
+
+ tinydrm_merge_clips(&clip, clips, num_clips, flags, fb->width,
+ fb->height);
+
+ /* 3 pixels per byte, so grow clip to nearest multiple of 3 */
+ clip.x1 = rounddown(clip.x1, 3);
+ clip.x2 = roundup(clip.x2, 3);
+
+ DRM_DEBUG("Flushing [FB:%d] x1=%u, x2=%u, y1=%u, y2=%u\n", fb->base.id,
+ clip.x1, clip.x2, clip.y1, clip.y2);
+
+ ret = st7586_buf_copy(mipi->tx_buf, fb, &clip);
+ if (ret)
+ goto out_unlock;
+
+ /* Pixels are packed 3 per byte */
+ start = clip.x1 / 3;
+ end = clip.x2 / 3;
+
+ mipi_dbi_command(mipi, MIPI_DCS_SET_COLUMN_ADDRESS,
+ (start >> 8) & 0xFF, start & 0xFF,
+ (end >> 8) & 0xFF, (end - 1) & 0xFF);
+ mipi_dbi_command(mipi, MIPI_DCS_SET_PAGE_ADDRESS,
+ (clip.y1 >> 8) & 0xFF, clip.y1 & 0xFF,
+ (clip.y2 >> 8) & 0xFF, (clip.y2 - 1) & 0xFF);
+
+ ret = mipi_dbi_command_buf(mipi, MIPI_DCS_WRITE_MEMORY_START,
+ (u8 *)mipi->tx_buf,
+ (end - start) * (clip.y2 - clip.y1));
+
+out_unlock:
+ mutex_unlock(&tdev->dirty_lock);
+
+ if (ret)
+ dev_err_once(fb->dev->dev, "Failed to update display %d\n",
+ ret);
+
+ return ret;
+}
+
+static const struct drm_framebuffer_funcs st7586_fb_funcs = {
+ .destroy = drm_fb_cma_destroy,
+ .create_handle = drm_fb_cma_create_handle,
+ .dirty = st7586_fb_dirty,
+};
+
+static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe,
+ struct drm_crtc_state *crtc_state)
+{
+ struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
+ struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
+ struct drm_framebuffer *fb = pipe->plane.fb;
+ struct device *dev = tdev->drm->dev;
+ int ret;
+ u8 addr_mode;
+
+ DRM_DEBUG_KMS("\n");
+
+ mipi_dbi_hw_reset(mipi);
+ ret = mipi_dbi_command(mipi, ST7586_AUTO_READ_CTRL, 0x9f);
+ if (ret) {
+ dev_err(dev, "Error sending command %d\n", ret);
+ return;
+ }
+
+ mipi_dbi_command(mipi, ST7586_OTP_RW_CTRL, 0x00);
+
+ msleep(10);
+
+ mipi_dbi_command(mipi, ST7586_OTP_READ);
+
+ msleep(20);
+
+ mipi_dbi_command(mipi, ST7586_OTP_CTRL_OUT);
+ mipi_dbi_command(mipi, MIPI_DCS_EXIT_SLEEP_MODE);
+ mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF);
+
+ msleep(50);
+
+ mipi_dbi_command(mipi, ST7586_SET_VOP_OFFSET, 0x00);
+ mipi_dbi_command(mipi, ST7586_SET_VOP, 0xe3, 0x00);
+ mipi_dbi_command(mipi, ST7586_SET_BIAS_SYSTEM, 0x02);
+ mipi_dbi_command(mipi, ST7586_SET_BOOST_LEVEL, 0x04);
+ mipi_dbi_command(mipi, ST7586_ENABLE_ANALOG, 0x1d);
+ mipi_dbi_command(mipi, ST7586_SET_NLINE_INV, 0x00);
+ mipi_dbi_command(mipi, ST7586_DISP_MODE_GRAY);
+ mipi_dbi_command(mipi, ST7586_ENABLE_DDRAM, 0x02);
+
+ switch (mipi->rotation) {
+ default:
+ addr_mode = 0x00;
+ break;
+ case 90:
+ addr_mode = ST7586_DISP_CTRL_MY;
+ break;
+ case 180:
+ addr_mode = ST7586_DISP_CTRL_MX | ST7586_DISP_CTRL_MY;
+ break;
+ case 270:
+ addr_mode = ST7586_DISP_CTRL_MX;
+ break;
+ }
+ mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
+
+ mipi_dbi_command(mipi, ST7586_SET_DISP_DUTY, 0x7f);
+ mipi_dbi_command(mipi, ST7586_SET_PART_DISP, 0xa0);
+ mipi_dbi_command(mipi, MIPI_DCS_SET_PARTIAL_AREA, 0x00, 0x00, 0x00, 0x77);
+ mipi_dbi_command(mipi, MIPI_DCS_EXIT_INVERT_MODE);
+
+ msleep(100);
+
+ mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON);
+
+ mipi->enabled = true;
+
+ if (fb)
+ fb->funcs->dirty(fb, NULL, 0, 0, NULL, 0);
+}
+
+static void st7586_pipe_disable(struct drm_simple_display_pipe *pipe)
+{
+ struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
+ struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
+
+ DRM_DEBUG_KMS("\n");
+
+ if (!mipi->enabled)
+ return;
+
+ mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF);
+ mipi->enabled = false;
+}
+
+static const u32 st7586_formats[] = {
+ DRM_FORMAT_XRGB8888,
+};
+
+static int st7586_init(struct device *dev, struct mipi_dbi *mipi,
+ const struct drm_simple_display_pipe_funcs *pipe_funcs,
+ struct drm_driver *driver, const struct drm_display_mode *mode,
+ unsigned int rotation)
+{
+ size_t bufsize = (mode->vdisplay + 2) / 3 * mode->hdisplay;
+ struct tinydrm_device *tdev = &mipi->tinydrm;
+ int ret;
+
+ mutex_init(&mipi->cmdlock);
+
+ mipi->tx_buf = devm_kmalloc(dev, bufsize, GFP_KERNEL);
+ if (!mipi->tx_buf)
+ return -ENOMEM;
+
+ ret = devm_tinydrm_init(dev, tdev, &st7586_fb_funcs, driver);
+ if (ret)
+ return ret;
+
+ ret = tinydrm_display_pipe_init(tdev, pipe_funcs,
+ DRM_MODE_CONNECTOR_VIRTUAL,
+ st7586_formats,
+ ARRAY_SIZE(st7586_formats),
+ mode, rotation);
+ if (ret)
+ return ret;
+
+ tdev->drm->mode_config.preferred_depth = 32;
+ mipi->rotation = rotation;
+
+ drm_mode_config_reset(tdev->drm);
+
+ DRM_DEBUG_KMS("preferred_depth=%u, rotation = %u\n",
+ tdev->drm->mode_config.preferred_depth, rotation);
+
+ return 0;
+}
+
+static const struct drm_simple_display_pipe_funcs st7586_pipe_funcs = {
+ .enable = st7586_pipe_enable,
+ .disable = st7586_pipe_disable,
+ .update = tinydrm_display_pipe_update,
+ .prepare_fb = tinydrm_display_pipe_prepare_fb,
+};
+
+static const struct drm_display_mode st7586_mode = {
+ TINYDRM_MODE(178, 128, 37, 27),
+};
+
+DEFINE_DRM_GEM_CMA_FOPS(st7586_fops);
+
+static struct drm_driver st7586_driver = {
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
+ DRIVER_ATOMIC,
+ .fops = &st7586_fops,
+ TINYDRM_GEM_DRIVER_OPS,
+ .lastclose = tinydrm_lastclose,
+ .debugfs_init = mipi_dbi_debugfs_init,
+ .name = "st7586",
+ .desc = "Sitronix ST7586",
+ .date = "20170801",
+ .major = 1,
+ .minor = 0,
+};
+
+static const struct of_device_id st7586_of_match[] = {
+ { .compatible = "lego,ev3-lcd" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, st7586_of_match);
+
+static const struct spi_device_id st7586_id[] = {
+ { "ev3-lcd", 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(spi, st7586_id);
+
+static int st7586_probe(struct spi_device *spi)
+{
+ struct device *dev = &spi->dev;
+ struct tinydrm_device *tdev;
+ struct mipi_dbi *mipi;
+ struct gpio_desc *a0;
+ u32 rotation = 0;
+ int ret;
+
+ mipi = devm_kzalloc(dev, sizeof(*mipi), GFP_KERNEL);
+ if (!mipi)
+ return -ENOMEM;
+
+ mipi->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(mipi->reset)) {
+ dev_err(dev, "Failed to get gpio 'reset'\n");
+ return PTR_ERR(mipi->reset);
+ }
+
+ a0 = devm_gpiod_get(dev, "a0", GPIOD_OUT_LOW);
+ if (IS_ERR(a0)) {
+ dev_err(dev, "Failed to get gpio 'a0'\n");
+ return PTR_ERR(a0);
+ }
+
+ device_property_read_u32(dev, "rotation", &rotation);
+
+ ret = mipi_dbi_spi_init(spi, mipi, a0);
+ if (ret)
+ return ret;
+
+ /* Cannot read from this controller via SPI */
+ mipi->read_commands = NULL;
+
+ /*
+ * we are using 8-bit data, so we are not actually swapping anything,
+ * but setting mipi->swap_bytes makes mipi_dbi_typec3_command() do the
+ * right thing and not use 16-bit transfers (which results in swapped
+ * bytes on little-endian systems and causes out of order data to be
+ * sent to the display).
+ */
+ mipi->swap_bytes = true;
+
+ ret = st7586_init(&spi->dev, mipi, &st7586_pipe_funcs, &st7586_driver,
+ &st7586_mode, rotation);
+ if (ret)
+ return ret;
+
+ tdev = &mipi->tinydrm;
+
+ ret = devm_tinydrm_register(tdev);
+ if (ret)
+ return ret;
+
+ spi_set_drvdata(spi, mipi);
+
+ DRM_DEBUG_DRIVER("Initialized %s:%s @%uMHz on minor %d\n",
+ tdev->drm->driver->name, dev_name(dev),
+ spi->max_speed_hz / 1000000,
+ tdev->drm->primary->index);
+
+ return 0;
+}
+
+static void st7586_shutdown(struct spi_device *spi)
+{
+ struct mipi_dbi *mipi = spi_get_drvdata(spi);
+
+ tinydrm_shutdown(&mipi->tinydrm);
+}
+
+static struct spi_driver st7586_spi_driver = {
+ .driver = {
+ .name = "st7586",
+ .owner = THIS_MODULE,
+ .of_match_table = st7586_of_match,
+ },
+ .id_table = st7586_id,
+ .probe = st7586_probe,
+ .shutdown = st7586_shutdown,
+};
+module_spi_driver(st7586_spi_driver);
+
+MODULE_DESCRIPTION("Sitronix ST7586 DRM driver");
+MODULE_AUTHOR("David Lechner <david@lechnology.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 22b57020790d..cba11f13d994 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -70,6 +70,7 @@ static inline int ttm_mem_type_from_place(const struct ttm_place *place,
static void ttm_mem_type_debug(struct ttm_bo_device *bdev, int mem_type)
{
struct ttm_mem_type_manager *man = &bdev->man[mem_type];
+ struct drm_printer p = drm_debug_printer(TTM_PFX);
pr_err(" has_type: %d\n", man->has_type);
pr_err(" use_type: %d\n", man->use_type);
@@ -79,7 +80,7 @@ static void ttm_mem_type_debug(struct ttm_bo_device *bdev, int mem_type)
pr_err(" available_caching: 0x%08X\n", man->available_caching);
pr_err(" default_caching: 0x%08X\n", man->default_caching);
if (mem_type != TTM_PL_SYSTEM)
- (*man->func->debug)(man, TTM_PFX);
+ (*man->func->debug)(man, &p);
}
static void ttm_bo_mem_space_debug(struct ttm_buffer_object *bo,
@@ -394,14 +395,33 @@ static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo)
ww_mutex_unlock (&bo->resv->lock);
}
+static int ttm_bo_individualize_resv(struct ttm_buffer_object *bo)
+{
+ int r;
+
+ if (bo->resv == &bo->ttm_resv)
+ return 0;
+
+ reservation_object_init(&bo->ttm_resv);
+ BUG_ON(!reservation_object_trylock(&bo->ttm_resv));
+
+ r = reservation_object_copy_fences(&bo->ttm_resv, bo->resv);
+ if (r) {
+ reservation_object_unlock(&bo->ttm_resv);
+ reservation_object_fini(&bo->ttm_resv);
+ }
+
+ return r;
+}
+
static void ttm_bo_flush_all_fences(struct ttm_buffer_object *bo)
{
struct reservation_object_list *fobj;
struct dma_fence *fence;
int i;
- fobj = reservation_object_get_list(bo->resv);
- fence = reservation_object_get_excl(bo->resv);
+ fobj = reservation_object_get_list(&bo->ttm_resv);
+ fence = reservation_object_get_excl(&bo->ttm_resv);
if (fence && !fence->ops->signaled)
dma_fence_enable_sw_signaling(fence);
@@ -430,8 +450,19 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
ttm_bo_cleanup_memtype_use(bo);
return;
- } else
- ttm_bo_flush_all_fences(bo);
+ }
+
+ ret = ttm_bo_individualize_resv(bo);
+ if (ret) {
+ /* Last resort, if we fail to allocate memory for the
+ * fences block for the BO to become idle and free it.
+ */
+ spin_unlock(&glob->lru_lock);
+ ttm_bo_wait(bo, true, true);
+ ttm_bo_cleanup_memtype_use(bo);
+ return;
+ }
+ ttm_bo_flush_all_fences(bo);
/*
* Make NO_EVICT bos immediately available to
@@ -443,6 +474,8 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
ttm_bo_add_to_lru(bo);
}
+ if (bo->resv != &bo->ttm_resv)
+ reservation_object_unlock(&bo->ttm_resv);
__ttm_bo_unreserve(bo);
}
@@ -471,17 +504,25 @@ static int ttm_bo_cleanup_refs_and_unlock(struct ttm_buffer_object *bo,
bool no_wait_gpu)
{
struct ttm_bo_global *glob = bo->glob;
+ struct reservation_object *resv;
int ret;
- ret = ttm_bo_wait(bo, false, true);
+ if (unlikely(list_empty(&bo->ddestroy)))
+ resv = bo->resv;
+ else
+ resv = &bo->ttm_resv;
+
+ if (reservation_object_test_signaled_rcu(resv, true))
+ ret = 0;
+ else
+ ret = -EBUSY;
if (ret && !no_wait_gpu) {
long lret;
ww_mutex_unlock(&bo->resv->lock);
spin_unlock(&glob->lru_lock);
- lret = reservation_object_wait_timeout_rcu(bo->resv,
- true,
+ lret = reservation_object_wait_timeout_rcu(resv, true,
interruptible,
30 * HZ);
@@ -505,13 +546,6 @@ static int ttm_bo_cleanup_refs_and_unlock(struct ttm_buffer_object *bo,
spin_unlock(&glob->lru_lock);
return 0;
}
-
- /*
- * remove sync_obj with ttm_bo_wait, the wait should be
- * finished, and no new wait object should have been added.
- */
- ret = ttm_bo_wait(bo, false, true);
- WARN_ON(ret);
}
if (ret || unlikely(list_empty(&bo->ddestroy))) {
diff --git a/drivers/gpu/drm/ttm/ttm_bo_manager.c b/drivers/gpu/drm/ttm/ttm_bo_manager.c
index 90a6c0b03afc..a7c232dc39cb 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_manager.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_manager.c
@@ -136,13 +136,12 @@ static int ttm_bo_man_takedown(struct ttm_mem_type_manager *man)
}
static void ttm_bo_man_debug(struct ttm_mem_type_manager *man,
- const char *prefix)
+ struct drm_printer *printer)
{
struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv;
- struct drm_printer p = drm_debug_printer(prefix);
spin_lock(&rman->lock);
- drm_mm_print(&rman->mm, &p);
+ drm_mm_print(&rman->mm, printer);
spin_unlock(&rman->lock);
}
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
index b442d12f2f7d..a01e5c90fd87 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
@@ -294,10 +294,87 @@ static void ttm_bo_vm_close(struct vm_area_struct *vma)
vma->vm_private_data = NULL;
}
+static int ttm_bo_vm_access_kmap(struct ttm_buffer_object *bo,
+ unsigned long offset,
+ void *buf, int len, int write)
+{
+ unsigned long page = offset >> PAGE_SHIFT;
+ unsigned long bytes_left = len;
+ int ret;
+
+ /* Copy a page at a time, that way no extra virtual address
+ * mapping is needed
+ */
+ offset -= page << PAGE_SHIFT;
+ do {
+ unsigned long bytes = min(bytes_left, PAGE_SIZE - offset);
+ struct ttm_bo_kmap_obj map;
+ void *ptr;
+ bool is_iomem;
+
+ ret = ttm_bo_kmap(bo, page, 1, &map);
+ if (ret)
+ return ret;
+
+ ptr = (uint8_t *)ttm_kmap_obj_virtual(&map, &is_iomem) + offset;
+ WARN_ON_ONCE(is_iomem);
+ if (write)
+ memcpy(ptr, buf, bytes);
+ else
+ memcpy(buf, ptr, bytes);
+ ttm_bo_kunmap(&map);
+
+ page++;
+ bytes_left -= bytes;
+ offset = 0;
+ } while (bytes_left);
+
+ return len;
+}
+
+static int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr,
+ void *buf, int len, int write)
+{
+ unsigned long offset = (addr) - vma->vm_start;
+ struct ttm_buffer_object *bo = vma->vm_private_data;
+ int ret;
+
+ if (len < 1 || (offset + len) >> PAGE_SHIFT > bo->num_pages)
+ return -EIO;
+
+ ret = ttm_bo_reserve(bo, true, false, NULL);
+ if (ret)
+ return ret;
+
+ switch (bo->mem.mem_type) {
+ case TTM_PL_SYSTEM:
+ if (unlikely(bo->ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) {
+ ret = ttm_tt_swapin(bo->ttm);
+ if (unlikely(ret != 0))
+ return ret;
+ }
+ /* fall through */
+ case TTM_PL_TT:
+ ret = ttm_bo_vm_access_kmap(bo, offset, buf, len, write);
+ break;
+ default:
+ if (bo->bdev->driver->access_memory)
+ ret = bo->bdev->driver->access_memory(
+ bo, offset, buf, len, write);
+ else
+ ret = -EIO;
+ }
+
+ ttm_bo_unreserve(bo);
+
+ return ret;
+}
+
static const struct vm_operations_struct ttm_bo_vm_ops = {
.fault = ttm_bo_vm_fault,
.open = ttm_bo_vm_open,
- .close = ttm_bo_vm_close
+ .close = ttm_bo_vm_close,
+ .access = ttm_bo_vm_access
};
static struct ttm_buffer_object *ttm_bo_vm_lookup(struct ttm_bo_device *bdev,
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
index eeddc1e48409..871599826773 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
@@ -615,7 +615,7 @@ static void ttm_page_pool_fill_locked(struct ttm_page_pool *pool,
} else {
pr_err("Failed to fill pool (%p)\n", pool);
/* If we have any pages left put them to the pool. */
- list_for_each_entry(p, &pool->list, lru) {
+ list_for_each_entry(p, &new_pages, lru) {
++cpages;
}
list_splice(&new_pages, &pool->list);
diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c
index d2f57c52f7db..9f9a49748d17 100644
--- a/drivers/gpu/drm/udl/udl_connector.c
+++ b/drivers/gpu/drm/udl/udl_connector.c
@@ -96,7 +96,7 @@ static int udl_mode_valid(struct drm_connector *connector,
static enum drm_connector_status
udl_detect(struct drm_connector *connector, bool force)
{
- if (drm_device_is_unplugged(connector->dev))
+ if (drm_dev_is_unplugged(connector->dev))
return connector_status_disconnected;
return connector_status_connected;
}
diff --git a/drivers/gpu/drm/udl/udl_dmabuf.c b/drivers/gpu/drm/udl/udl_dmabuf.c
index 2e031a894813..2867ed155ff6 100644
--- a/drivers/gpu/drm/udl/udl_dmabuf.c
+++ b/drivers/gpu/drm/udl/udl_dmabuf.c
@@ -186,7 +186,7 @@ static int udl_dmabuf_mmap(struct dma_buf *dma_buf,
return -EINVAL;
}
-static struct dma_buf_ops udl_dmabuf_ops = {
+static const struct dma_buf_ops udl_dmabuf_ops = {
.attach = udl_attach_dma_buf,
.detach = udl_detach_dma_buf,
.map_dma_buf = udl_map_dma_buf,
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index cd8b01727734..31421b6b586e 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -11,11 +11,6 @@
#include <drm/drm_crtc_helper.h>
#include "udl_drv.h"
-static int udl_driver_set_busid(struct drm_device *d, struct drm_master *m)
-{
- return 0;
-}
-
static int udl_usb_suspend(struct usb_interface *interface,
pm_message_t message)
{
@@ -52,7 +47,6 @@ static struct drm_driver driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
.load = udl_driver_load,
.unload = udl_driver_unload,
- .set_busid = udl_driver_set_busid,
/* gem hooks */
.gem_free_object = udl_gem_free_object,
@@ -60,7 +54,6 @@ static struct drm_driver driver = {
.dumb_create = udl_dumb_create,
.dumb_map_offset = udl_gem_mmap,
- .dumb_destroy = drm_gem_dumb_destroy,
.fops = &udl_driver_fops,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
@@ -108,7 +101,7 @@ static void udl_usb_disconnect(struct usb_interface *interface)
drm_kms_helper_poll_disable(dev);
udl_fbdev_unplug(dev);
udl_drop_usb(dev);
- drm_unplug_dev(dev);
+ drm_dev_unplug(dev);
}
/*
@@ -118,7 +111,7 @@ static void udl_usb_disconnect(struct usb_interface *interface)
* which is compatible with all known USB 2.0 era graphics chips and firmware,
* but allows DisplayLink to increment those for any future incompatible chips
*/
-static struct usb_device_id id_table[] = {
+static const struct usb_device_id id_table[] = {
{.idVendor = 0x17e9, .bInterfaceClass = 0xff,
.bInterfaceSubClass = 0x00,
.bInterfaceProtocol = 0x00,
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
index 4a6500362564..b7ca90db4e80 100644
--- a/drivers/gpu/drm/udl/udl_fb.c
+++ b/drivers/gpu/drm/udl/udl_fb.c
@@ -198,7 +198,7 @@ static int udl_fb_open(struct fb_info *info, int user)
struct udl_device *udl = dev->dev_private;
/* If the USB device is gone, we don't accept new opens */
- if (drm_device_is_unplugged(udl->ddev))
+ if (drm_dev_is_unplugged(udl->ddev))
return -ENODEV;
ufbdev->fb_count++;
@@ -309,7 +309,7 @@ static void udl_user_framebuffer_destroy(struct drm_framebuffer *fb)
struct udl_framebuffer *ufb = to_udl_fb(fb);
if (ufb->obj)
- drm_gem_object_unreference_unlocked(&ufb->obj->base);
+ drm_gem_object_put_unlocked(&ufb->obj->base);
drm_framebuffer_cleanup(fb);
kfree(ufb);
@@ -393,7 +393,6 @@ static int udlfb_create(struct drm_fb_helper *helper,
info->fix.smem_len = size;
info->fix.smem_start = (unsigned long)ufbdev->ufb.obj->vmapping;
- info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &udlfb_ops;
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
drm_fb_helper_fill_var(info, &ufbdev->helper, sizes->fb_width, sizes->fb_height);
@@ -404,7 +403,7 @@ static int udlfb_create(struct drm_fb_helper *helper,
return ret;
out_gfree:
- drm_gem_object_unreference_unlocked(&ufbdev->ufb.obj->base);
+ drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base);
out:
return ret;
}
@@ -420,7 +419,7 @@ static void udl_fbdev_destroy(struct drm_device *dev,
drm_fb_helper_fini(&ufbdev->helper);
drm_framebuffer_unregister_private(&ufbdev->ufb.base);
drm_framebuffer_cleanup(&ufbdev->ufb.base);
- drm_gem_object_unreference_unlocked(&ufbdev->ufb.obj->base);
+ drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base);
}
int udl_fbdev_init(struct drm_device *dev)
diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c
index db9ceceba30e..dee6bd9a3dd1 100644
--- a/drivers/gpu/drm/udl/udl_gem.c
+++ b/drivers/gpu/drm/udl/udl_gem.c
@@ -52,7 +52,7 @@ udl_gem_create(struct drm_file *file,
return ret;
}
- drm_gem_object_unreference_unlocked(&obj->base);
+ drm_gem_object_put_unlocked(&obj->base);
*handle_p = handle;
return 0;
}
@@ -234,7 +234,7 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev,
*offset = drm_vma_node_offset_addr(&gobj->base.vma_node);
out:
- drm_gem_object_unreference(&gobj->base);
+ drm_gem_object_put(&gobj->base);
unlock:
mutex_unlock(&dev->struct_mutex);
return ret;
diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index a9d93b871a15..0328b2c7b210 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -371,8 +371,6 @@ void udl_driver_unload(struct drm_device *dev)
{
struct udl_device *udl = dev->dev_private;
- drm_vblank_cleanup(dev);
-
if (udl->urbs.count)
udl_free_urb_list(dev);
diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig
index 4361bdcfd28a..fdae18aeab4f 100644
--- a/drivers/gpu/drm/vc4/Kconfig
+++ b/drivers/gpu/drm/vc4/Kconfig
@@ -19,3 +19,11 @@ config DRM_VC4
This driver requires that "avoid_warnings=2" be present in
the config.txt for the firmware, to keep it from smashing
our display setup.
+
+config DRM_VC4_HDMI_CEC
+ bool "Broadcom VC4 HDMI CEC Support"
+ depends on DRM_VC4
+ select CEC_CORE
+ help
+ Choose this option if you have a Broadcom VC4 GPU
+ and want to use CEC.
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 487f96412d35..3afdbf4bc10b 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -24,21 +24,35 @@
#include "vc4_drv.h"
#include "uapi/drm/vc4_drm.h"
+static const char * const bo_type_names[] = {
+ "kernel",
+ "V3D",
+ "V3D shader",
+ "dumb",
+ "binner",
+ "RCL",
+ "BCL",
+ "kernel BO cache",
+};
+
+static bool is_user_label(int label)
+{
+ return label >= VC4_BO_TYPE_COUNT;
+}
+
static void vc4_bo_stats_dump(struct vc4_dev *vc4)
{
- DRM_INFO("num bos allocated: %d\n",
- vc4->bo_stats.num_allocated);
- DRM_INFO("size bos allocated: %dkb\n",
- vc4->bo_stats.size_allocated / 1024);
- DRM_INFO("num bos used: %d\n",
- vc4->bo_stats.num_allocated - vc4->bo_stats.num_cached);
- DRM_INFO("size bos used: %dkb\n",
- (vc4->bo_stats.size_allocated -
- vc4->bo_stats.size_cached) / 1024);
- DRM_INFO("num bos cached: %d\n",
- vc4->bo_stats.num_cached);
- DRM_INFO("size bos cached: %dkb\n",
- vc4->bo_stats.size_cached / 1024);
+ int i;
+
+ for (i = 0; i < vc4->num_labels; i++) {
+ if (!vc4->bo_labels[i].num_allocated)
+ continue;
+
+ DRM_INFO("%30s: %6dkb BOs (%d)\n",
+ vc4->bo_labels[i].name,
+ vc4->bo_labels[i].size_allocated / 1024,
+ vc4->bo_labels[i].num_allocated);
+ }
}
#ifdef CONFIG_DEBUG_FS
@@ -47,64 +61,133 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *unused)
struct drm_info_node *node = (struct drm_info_node *)m->private;
struct drm_device *dev = node->minor->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
- struct vc4_bo_stats stats;
+ int i;
- /* Take a snapshot of the current stats with the lock held. */
mutex_lock(&vc4->bo_lock);
- stats = vc4->bo_stats;
+ for (i = 0; i < vc4->num_labels; i++) {
+ if (!vc4->bo_labels[i].num_allocated)
+ continue;
+
+ seq_printf(m, "%30s: %6dkb BOs (%d)\n",
+ vc4->bo_labels[i].name,
+ vc4->bo_labels[i].size_allocated / 1024,
+ vc4->bo_labels[i].num_allocated);
+ }
mutex_unlock(&vc4->bo_lock);
- seq_printf(m, "num bos allocated: %d\n",
- stats.num_allocated);
- seq_printf(m, "size bos allocated: %dkb\n",
- stats.size_allocated / 1024);
- seq_printf(m, "num bos used: %d\n",
- stats.num_allocated - stats.num_cached);
- seq_printf(m, "size bos used: %dkb\n",
- (stats.size_allocated - stats.size_cached) / 1024);
- seq_printf(m, "num bos cached: %d\n",
- stats.num_cached);
- seq_printf(m, "size bos cached: %dkb\n",
- stats.size_cached / 1024);
-
return 0;
}
#endif
+/* Takes ownership of *name and returns the appropriate slot for it in
+ * the bo_labels[] array, extending it as necessary.
+ *
+ * This is inefficient and could use a hash table instead of walking
+ * an array and strcmp()ing. However, the assumption is that user
+ * labeling will be infrequent (scanout buffers and other long-lived
+ * objects, or debug driver builds), so we can live with it for now.
+ */
+static int vc4_get_user_label(struct vc4_dev *vc4, const char *name)
+{
+ int i;
+ int free_slot = -1;
+
+ for (i = 0; i < vc4->num_labels; i++) {
+ if (!vc4->bo_labels[i].name) {
+ free_slot = i;
+ } else if (strcmp(vc4->bo_labels[i].name, name) == 0) {
+ kfree(name);
+ return i;
+ }
+ }
+
+ if (free_slot != -1) {
+ WARN_ON(vc4->bo_labels[free_slot].num_allocated != 0);
+ vc4->bo_labels[free_slot].name = name;
+ return free_slot;
+ } else {
+ u32 new_label_count = vc4->num_labels + 1;
+ struct vc4_label *new_labels =
+ krealloc(vc4->bo_labels,
+ new_label_count * sizeof(*new_labels),
+ GFP_KERNEL);
+
+ if (!new_labels) {
+ kfree(name);
+ return -1;
+ }
+
+ free_slot = vc4->num_labels;
+ vc4->bo_labels = new_labels;
+ vc4->num_labels = new_label_count;
+
+ vc4->bo_labels[free_slot].name = name;
+ vc4->bo_labels[free_slot].num_allocated = 0;
+ vc4->bo_labels[free_slot].size_allocated = 0;
+
+ return free_slot;
+ }
+}
+
+static void vc4_bo_set_label(struct drm_gem_object *gem_obj, int label)
+{
+ struct vc4_bo *bo = to_vc4_bo(gem_obj);
+ struct vc4_dev *vc4 = to_vc4_dev(gem_obj->dev);
+
+ lockdep_assert_held(&vc4->bo_lock);
+
+ if (label != -1) {
+ vc4->bo_labels[label].num_allocated++;
+ vc4->bo_labels[label].size_allocated += gem_obj->size;
+ }
+
+ vc4->bo_labels[bo->label].num_allocated--;
+ vc4->bo_labels[bo->label].size_allocated -= gem_obj->size;
+
+ if (vc4->bo_labels[bo->label].num_allocated == 0 &&
+ is_user_label(bo->label)) {
+ /* Free user BO label slots on last unreference.
+ * Slots are just where we track the stats for a given
+ * name, and once a name is unused we can reuse that
+ * slot.
+ */
+ kfree(vc4->bo_labels[bo->label].name);
+ vc4->bo_labels[bo->label].name = NULL;
+ }
+
+ bo->label = label;
+}
+
static uint32_t bo_page_index(size_t size)
{
return (size / PAGE_SIZE) - 1;
}
-/* Must be called with bo_lock held. */
static void vc4_bo_destroy(struct vc4_bo *bo)
{
struct drm_gem_object *obj = &bo->base.base;
struct vc4_dev *vc4 = to_vc4_dev(obj->dev);
+ lockdep_assert_held(&vc4->bo_lock);
+
+ vc4_bo_set_label(obj, -1);
+
if (bo->validated_shader) {
kfree(bo->validated_shader->texture_samples);
kfree(bo->validated_shader);
bo->validated_shader = NULL;
}
- vc4->bo_stats.num_allocated--;
- vc4->bo_stats.size_allocated -= obj->size;
-
reservation_object_fini(&bo->_resv);
drm_gem_cma_free_object(obj);
}
-/* Must be called with bo_lock held. */
static void vc4_bo_remove_from_cache(struct vc4_bo *bo)
{
- struct drm_gem_object *obj = &bo->base.base;
- struct vc4_dev *vc4 = to_vc4_dev(obj->dev);
-
- vc4->bo_stats.num_cached--;
- vc4->bo_stats.size_cached -= obj->size;
+ struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
+ lockdep_assert_held(&vc4->bo_lock);
list_del(&bo->unref_head);
list_del(&bo->size_head);
}
@@ -165,7 +248,8 @@ static void vc4_bo_cache_purge(struct drm_device *dev)
}
static struct vc4_bo *vc4_bo_get_from_cache(struct drm_device *dev,
- uint32_t size)
+ uint32_t size,
+ enum vc4_kernel_bo_type type)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
uint32_t page_index = bo_page_index(size);
@@ -186,6 +270,8 @@ static struct vc4_bo *vc4_bo_get_from_cache(struct drm_device *dev,
kref_init(&bo->base.base.refcount);
out:
+ if (bo)
+ vc4_bo_set_label(&bo->base.base, type);
mutex_unlock(&vc4->bo_lock);
return bo;
}
@@ -208,8 +294,9 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size)
return ERR_PTR(-ENOMEM);
mutex_lock(&vc4->bo_lock);
- vc4->bo_stats.num_allocated++;
- vc4->bo_stats.size_allocated += size;
+ bo->label = VC4_BO_TYPE_KERNEL;
+ vc4->bo_labels[VC4_BO_TYPE_KERNEL].num_allocated++;
+ vc4->bo_labels[VC4_BO_TYPE_KERNEL].size_allocated += size;
mutex_unlock(&vc4->bo_lock);
bo->resv = &bo->_resv;
reservation_object_init(bo->resv);
@@ -218,7 +305,7 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size)
}
struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size,
- bool allow_unzeroed)
+ bool allow_unzeroed, enum vc4_kernel_bo_type type)
{
size_t size = roundup(unaligned_size, PAGE_SIZE);
struct vc4_dev *vc4 = to_vc4_dev(dev);
@@ -229,7 +316,7 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size,
return ERR_PTR(-EINVAL);
/* First, try to get a vc4_bo from the kernel BO cache. */
- bo = vc4_bo_get_from_cache(dev, size);
+ bo = vc4_bo_get_from_cache(dev, size, type);
if (bo) {
if (!allow_unzeroed)
memset(bo->base.vaddr, 0, bo->base.base.size);
@@ -251,7 +338,13 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size,
return ERR_PTR(-ENOMEM);
}
}
- return to_vc4_bo(&cma_obj->base);
+ bo = to_vc4_bo(&cma_obj->base);
+
+ mutex_lock(&vc4->bo_lock);
+ vc4_bo_set_label(&cma_obj->base, type);
+ mutex_unlock(&vc4->bo_lock);
+
+ return bo;
}
int vc4_dumb_create(struct drm_file *file_priv,
@@ -268,22 +361,23 @@ int vc4_dumb_create(struct drm_file *file_priv,
if (args->size < args->pitch * args->height)
args->size = args->pitch * args->height;
- bo = vc4_bo_create(dev, args->size, false);
+ bo = vc4_bo_create(dev, args->size, false, VC4_BO_TYPE_DUMB);
if (IS_ERR(bo))
return PTR_ERR(bo);
ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
- drm_gem_object_unreference_unlocked(&bo->base.base);
+ drm_gem_object_put_unlocked(&bo->base.base);
return ret;
}
-/* Must be called with bo_lock held. */
static void vc4_bo_cache_free_old(struct drm_device *dev)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
unsigned long expire_time = jiffies - msecs_to_jiffies(1000);
+ lockdep_assert_held(&vc4->bo_lock);
+
while (!list_empty(&vc4->bo_cache.time_list)) {
struct vc4_bo *bo = list_last_entry(&vc4->bo_cache.time_list,
struct vc4_bo, unref_head);
@@ -348,8 +442,7 @@ void vc4_free_object(struct drm_gem_object *gem_bo)
list_add(&bo->size_head, cache_list);
list_add(&bo->unref_head, &vc4->bo_cache.time_list);
- vc4->bo_stats.num_cached++;
- vc4->bo_stats.size_cached += gem_bo->size;
+ vc4_bo_set_label(&bo->base.base, VC4_BO_TYPE_KERNEL_CACHE);
vc4_bo_cache_free_old(dev);
@@ -389,7 +482,7 @@ vc4_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags)
struct vc4_bo *bo = to_vc4_bo(obj);
if (bo->validated_shader) {
- DRM_ERROR("Attempting to export shader BO\n");
+ DRM_DEBUG("Attempting to export shader BO\n");
return ERR_PTR(-EINVAL);
}
@@ -410,7 +503,7 @@ int vc4_mmap(struct file *filp, struct vm_area_struct *vma)
bo = to_vc4_bo(gem_obj);
if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) {
- DRM_ERROR("mmaping of shader BOs for writing not allowed.\n");
+ DRM_DEBUG("mmaping of shader BOs for writing not allowed.\n");
return -EINVAL;
}
@@ -435,7 +528,7 @@ int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
struct vc4_bo *bo = to_vc4_bo(obj);
if (bo->validated_shader && (vma->vm_flags & VM_WRITE)) {
- DRM_ERROR("mmaping of shader BOs for writing not allowed.\n");
+ DRM_DEBUG("mmaping of shader BOs for writing not allowed.\n");
return -EINVAL;
}
@@ -447,7 +540,7 @@ void *vc4_prime_vmap(struct drm_gem_object *obj)
struct vc4_bo *bo = to_vc4_bo(obj);
if (bo->validated_shader) {
- DRM_ERROR("mmaping of shader BOs not allowed.\n");
+ DRM_DEBUG("mmaping of shader BOs not allowed.\n");
return ERR_PTR(-EINVAL);
}
@@ -483,12 +576,12 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
* We can't allocate from the BO cache, because the BOs don't
* get zeroed, and that might leak data between users.
*/
- bo = vc4_bo_create(dev, args->size, false);
+ bo = vc4_bo_create(dev, args->size, false, VC4_BO_TYPE_V3D);
if (IS_ERR(bo))
return PTR_ERR(bo);
ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
- drm_gem_object_unreference_unlocked(&bo->base.base);
+ drm_gem_object_put_unlocked(&bo->base.base);
return ret;
}
@@ -501,14 +594,14 @@ int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
gem_obj = drm_gem_object_lookup(file_priv, args->handle);
if (!gem_obj) {
- DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
+ DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle);
return -EINVAL;
}
/* The mmap offset was set up at BO allocation time. */
args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node);
- drm_gem_object_unreference_unlocked(gem_obj);
+ drm_gem_object_put_unlocked(gem_obj);
return 0;
}
@@ -536,7 +629,7 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
return -EINVAL;
}
- bo = vc4_bo_create(dev, args->size, true);
+ bo = vc4_bo_create(dev, args->size, true, VC4_BO_TYPE_V3D_SHADER);
if (IS_ERR(bo))
return PTR_ERR(bo);
@@ -564,7 +657,7 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
fail:
- drm_gem_object_unreference_unlocked(&bo->base.base);
+ drm_gem_object_put_unlocked(&bo->base.base);
return ret;
}
@@ -605,13 +698,13 @@ int vc4_set_tiling_ioctl(struct drm_device *dev, void *data,
gem_obj = drm_gem_object_lookup(file_priv, args->handle);
if (!gem_obj) {
- DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
+ DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle);
return -ENOENT;
}
bo = to_vc4_bo(gem_obj);
bo->t_format = t_format;
- drm_gem_object_unreference_unlocked(gem_obj);
+ drm_gem_object_put_unlocked(gem_obj);
return 0;
}
@@ -636,7 +729,7 @@ int vc4_get_tiling_ioctl(struct drm_device *dev, void *data,
gem_obj = drm_gem_object_lookup(file_priv, args->handle);
if (!gem_obj) {
- DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
+ DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle);
return -ENOENT;
}
bo = to_vc4_bo(gem_obj);
@@ -646,14 +739,29 @@ int vc4_get_tiling_ioctl(struct drm_device *dev, void *data,
else
args->modifier = DRM_FORMAT_MOD_NONE;
- drm_gem_object_unreference_unlocked(gem_obj);
+ drm_gem_object_put_unlocked(gem_obj);
return 0;
}
-void vc4_bo_cache_init(struct drm_device *dev)
+int vc4_bo_cache_init(struct drm_device *dev)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
+ int i;
+
+ /* Create the initial set of BO labels that the kernel will
+ * use. This lets us avoid a bunch of string reallocation in
+ * the kernel's draw and BO allocation paths.
+ */
+ vc4->bo_labels = kcalloc(VC4_BO_TYPE_COUNT, sizeof(*vc4->bo_labels),
+ GFP_KERNEL);
+ if (!vc4->bo_labels)
+ return -ENOMEM;
+ vc4->num_labels = VC4_BO_TYPE_COUNT;
+
+ BUILD_BUG_ON(ARRAY_SIZE(bo_type_names) != VC4_BO_TYPE_COUNT);
+ for (i = 0; i < VC4_BO_TYPE_COUNT; i++)
+ vc4->bo_labels[i].name = bo_type_names[i];
mutex_init(&vc4->bo_lock);
@@ -663,19 +771,66 @@ void vc4_bo_cache_init(struct drm_device *dev)
setup_timer(&vc4->bo_cache.time_timer,
vc4_bo_cache_time_timer,
(unsigned long)dev);
+
+ return 0;
}
void vc4_bo_cache_destroy(struct drm_device *dev)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
+ int i;
del_timer(&vc4->bo_cache.time_timer);
cancel_work_sync(&vc4->bo_cache.time_work);
vc4_bo_cache_purge(dev);
- if (vc4->bo_stats.num_allocated) {
- DRM_ERROR("Destroying BO cache while BOs still allocated:\n");
- vc4_bo_stats_dump(vc4);
+ for (i = 0; i < vc4->num_labels; i++) {
+ if (vc4->bo_labels[i].num_allocated) {
+ DRM_ERROR("Destroying BO cache with %d %s "
+ "BOs still allocated\n",
+ vc4->bo_labels[i].num_allocated,
+ vc4->bo_labels[i].name);
+ }
+
+ if (is_user_label(i))
+ kfree(vc4->bo_labels[i].name);
}
+ kfree(vc4->bo_labels);
+}
+
+int vc4_label_bo_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+ struct drm_vc4_label_bo *args = data;
+ char *name;
+ struct drm_gem_object *gem_obj;
+ int ret = 0, label;
+
+ if (!args->len)
+ return -EINVAL;
+
+ name = strndup_user(u64_to_user_ptr(args->name), args->len + 1);
+ if (IS_ERR(name))
+ return PTR_ERR(name);
+
+ gem_obj = drm_gem_object_lookup(file_priv, args->handle);
+ if (!gem_obj) {
+ DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
+ kfree(name);
+ return -ENOENT;
+ }
+
+ mutex_lock(&vc4->bo_lock);
+ label = vc4_get_user_label(vc4, name);
+ if (label != -1)
+ vc4_bo_set_label(gem_obj, label);
+ else
+ ret = -ENOMEM;
+ mutex_unlock(&vc4->bo_lock);
+
+ drm_gem_object_put_unlocked(gem_obj);
+
+ return ret;
}
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 403bbd5f99a9..ce1e3b9e14c9 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -479,7 +479,8 @@ static void require_hvs_enabled(struct drm_device *dev)
SCALER_DISPCTRL_ENABLE);
}
-static void vc4_crtc_disable(struct drm_crtc *crtc)
+static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct drm_device *dev = crtc->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
@@ -518,9 +519,51 @@ static void vc4_crtc_disable(struct drm_crtc *crtc)
WARN_ON_ONCE((HVS_READ(SCALER_DISPSTATX(chan)) &
(SCALER_DISPSTATX_FULL | SCALER_DISPSTATX_EMPTY)) !=
SCALER_DISPSTATX_EMPTY);
+
+ /*
+ * Make sure we issue a vblank event after disabling the CRTC if
+ * someone was waiting it.
+ */
+ if (crtc->state->event) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ crtc->state->event = NULL;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ }
+}
+
+static void vc4_crtc_update_dlist(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
+
+ if (crtc->state->event) {
+ unsigned long flags;
+
+ crtc->state->event->pipe = drm_crtc_index(crtc);
+
+ WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ vc4_crtc->event = crtc->state->event;
+ crtc->state->event = NULL;
+
+ HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
+ vc4_state->mm.start);
+
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ } else {
+ HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
+ vc4_state->mm.start);
+ }
}
-static void vc4_crtc_enable(struct drm_crtc *crtc)
+static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct drm_device *dev = crtc->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
@@ -530,6 +573,12 @@ static void vc4_crtc_enable(struct drm_crtc *crtc)
require_hvs_enabled(dev);
+ /* Enable vblank irq handling before crtc is started otherwise
+ * drm_crtc_get_vblank() fails in vc4_crtc_update_dlist().
+ */
+ drm_crtc_vblank_on(crtc);
+ vc4_crtc_update_dlist(crtc);
+
/* Turn on the scaler, which will wait for vstart to start
* compositing.
*/
@@ -541,23 +590,19 @@ static void vc4_crtc_enable(struct drm_crtc *crtc)
/* Turn on the pixel valve, which will emit the vstart signal. */
CRTC_WRITE(PV_V_CONTROL,
CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
-
- /* Enable vblank irq handling after crtc is started. */
- drm_crtc_vblank_on(crtc);
}
-static bool vc4_crtc_mode_fixup(struct drm_crtc *crtc,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode)
{
/* Do not allow doublescan modes from user space */
- if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) {
+ if (mode->flags & DRM_MODE_FLAG_DBLSCAN) {
DRM_DEBUG_KMS("[CRTC:%d] Doublescan mode rejected.\n",
crtc->base.id);
- return false;
+ return MODE_NO_DBLESCAN;
}
- return true;
+ return MODE_OK;
}
static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
@@ -598,7 +643,6 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
{
struct drm_device *dev = crtc->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
struct drm_plane *plane;
bool debug_dump_regs = false;
@@ -620,25 +664,15 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size);
- if (crtc->state->event) {
- unsigned long flags;
-
- crtc->state->event->pipe = drm_crtc_index(crtc);
-
- WARN_ON(drm_crtc_vblank_get(crtc) != 0);
-
- spin_lock_irqsave(&dev->event_lock, flags);
- vc4_crtc->event = crtc->state->event;
- crtc->state->event = NULL;
-
- HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
- vc4_state->mm.start);
-
- spin_unlock_irqrestore(&dev->event_lock, flags);
- } else {
- HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
- vc4_state->mm.start);
- }
+ /* Only update DISPLIST if the CRTC was already running and is not
+ * being disabled.
+ * vc4_crtc_enable() takes care of updating the dlist just after
+ * re-enabling VBLANK interrupts and before enabling the engine.
+ * If the CRTC is being disabled, there's no point in updating this
+ * information.
+ */
+ if (crtc->state->active && old_state->active)
+ vc4_crtc_update_dlist(crtc);
if (debug_dump_regs) {
DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc));
@@ -662,14 +696,6 @@ static void vc4_disable_vblank(struct drm_crtc *crtc)
CRTC_WRITE(PV_INTEN, 0);
}
-/* Must be called with the event lock held */
-bool vc4_event_pending(struct drm_crtc *crtc)
-{
- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
-
- return !!vc4_crtc->event;
-}
-
static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc)
{
struct drm_crtc *crtc = &vc4_crtc->base;
@@ -737,7 +763,7 @@ vc4_async_page_flip_complete(struct vc4_seqno_cb *cb)
}
drm_crtc_vblank_put(crtc);
- drm_framebuffer_unreference(flip_state->fb);
+ drm_framebuffer_put(flip_state->fb);
kfree(flip_state);
up(&vc4->async_modeset);
@@ -766,7 +792,7 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
if (!flip_state)
return -ENOMEM;
- drm_framebuffer_reference(fb);
+ drm_framebuffer_get(fb);
flip_state->fb = fb;
flip_state->crtc = crtc;
flip_state->event = event;
@@ -774,7 +800,7 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
/* Make sure all other async modesetes have landed. */
ret = down_interruptible(&vc4->async_modeset);
if (ret) {
- drm_framebuffer_unreference(fb);
+ drm_framebuffer_put(fb);
kfree(flip_state);
return ret;
}
@@ -865,11 +891,11 @@ static const struct drm_crtc_funcs vc4_crtc_funcs = {
static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = {
.mode_set_nofb = vc4_crtc_mode_set_nofb,
- .disable = vc4_crtc_disable,
- .enable = vc4_crtc_enable,
- .mode_fixup = vc4_crtc_mode_fixup,
+ .mode_valid = vc4_crtc_mode_valid,
.atomic_check = vc4_crtc_atomic_check,
.atomic_flush = vc4_crtc_atomic_flush,
+ .atomic_enable = vc4_crtc_atomic_enable,
+ .atomic_disable = vc4_crtc_atomic_disable,
};
static const struct vc4_crtc_data pv0_data = {
diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
index 2e0fe46aeb2e..519cefef800d 100644
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
@@ -224,20 +224,19 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder)
DRM_ERROR("Failed to set clock rate: %d\n", ret);
}
-static bool vc4_dpi_encoder_mode_fixup(struct drm_encoder *encoder,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+static enum drm_mode_status vc4_dpi_encoder_mode_valid(struct drm_encoder *encoder,
+ const struct drm_display_mode *mode)
{
- if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
- return false;
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ return MODE_NO_INTERLACE;
- return true;
+ return MODE_OK;
}
static const struct drm_encoder_helper_funcs vc4_dpi_encoder_helper_funcs = {
.disable = vc4_dpi_encoder_disable,
.enable = vc4_dpi_encoder_enable,
- .mode_fixup = vc4_dpi_encoder_mode_fixup,
+ .mode_valid = vc4_dpi_encoder_mode_valid,
};
static const struct of_device_id vc4_dpi_dt_match[] = {
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index c6b487c3d2b7..1c96edcb302b 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -99,6 +99,7 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data,
case DRM_VC4_PARAM_SUPPORTS_BRANCHES:
case DRM_VC4_PARAM_SUPPORTS_ETC1:
case DRM_VC4_PARAM_SUPPORTS_THREADED_FS:
+ case DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER:
args->value = true;
break;
default:
@@ -140,6 +141,7 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
DRM_IOCTL_DEF_DRV(VC4_GET_PARAM, vc4_get_param_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(VC4_SET_TILING, vc4_set_tiling_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(VC4_GET_TILING, vc4_get_tiling_ioctl, DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(VC4_LABEL_BO, vc4_label_bo_ioctl, DRM_RENDER_ALLOW),
};
static struct drm_driver vc4_drm_driver = {
@@ -178,8 +180,6 @@ static struct drm_driver vc4_drm_driver = {
.gem_prime_mmap = vc4_prime_mmap,
.dumb_create = vc4_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.ioctls = vc4_drm_ioctls,
.num_ioctls = ARRAY_SIZE(vc4_drm_ioctls),
@@ -257,7 +257,9 @@ static int vc4_drm_bind(struct device *dev)
vc4->dev = drm;
drm->dev_private = vc4;
- vc4_bo_cache_init(drm);
+ ret = vc4_bo_cache_init(drm);
+ if (ret)
+ goto dev_unref;
drm_mode_config_init(drm);
@@ -281,8 +283,9 @@ unbind_all:
component_unbind_all(dev, drm);
gem_destroy:
vc4_gem_destroy(drm);
- drm_dev_unref(drm);
vc4_bo_cache_destroy(drm);
+dev_unref:
+ drm_dev_unref(drm);
return ret;
}
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index df22698d62ee..87f2d8e5c134 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -11,6 +11,24 @@
#include <drm/drm_encoder.h>
#include <drm/drm_gem_cma_helper.h>
+/* Don't forget to update vc4_bo.c: bo_type_names[] when adding to
+ * this.
+ */
+enum vc4_kernel_bo_type {
+ /* Any kernel allocation (gem_create_object hook) before it
+ * gets another type set.
+ */
+ VC4_BO_TYPE_KERNEL,
+ VC4_BO_TYPE_V3D,
+ VC4_BO_TYPE_V3D_SHADER,
+ VC4_BO_TYPE_DUMB,
+ VC4_BO_TYPE_BIN,
+ VC4_BO_TYPE_RCL,
+ VC4_BO_TYPE_BCL,
+ VC4_BO_TYPE_KERNEL_CACHE,
+ VC4_BO_TYPE_COUNT
+};
+
struct vc4_dev {
struct drm_device *dev;
@@ -46,14 +64,14 @@ struct vc4_dev {
struct timer_list time_timer;
} bo_cache;
- struct vc4_bo_stats {
+ u32 num_labels;
+ struct vc4_label {
+ const char *name;
u32 num_allocated;
u32 size_allocated;
- u32 num_cached;
- u32 size_cached;
- } bo_stats;
+ } *bo_labels;
- /* Protects bo_cache and the BO stats. */
+ /* Protects bo_cache and bo_labels. */
struct mutex bo_lock;
uint64_t dma_fence_context;
@@ -169,6 +187,11 @@ struct vc4_bo {
/* normally (resv == &_resv) except for imported bo's */
struct reservation_object *resv;
struct reservation_object _resv;
+
+ /* One of enum vc4_kernel_bo_type, or VC4_BO_TYPE_COUNT + i
+ * for user-allocated labels.
+ */
+ int label;
};
static inline struct vc4_bo *
@@ -460,7 +483,7 @@ struct vc4_validated_shader_info {
struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size);
void vc4_free_object(struct drm_gem_object *gem_obj);
struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size,
- bool from_cache);
+ bool from_cache, enum vc4_kernel_bo_type type);
int vc4_dumb_create(struct drm_file *file_priv,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
@@ -478,6 +501,8 @@ int vc4_get_tiling_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+int vc4_label_bo_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
int vc4_mmap(struct file *filp, struct vm_area_struct *vma);
struct reservation_object *vc4_prime_res_obj(struct drm_gem_object *obj);
int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
@@ -485,13 +510,12 @@ struct drm_gem_object *vc4_prime_import_sg_table(struct drm_device *dev,
struct dma_buf_attachment *attach,
struct sg_table *sgt);
void *vc4_prime_vmap(struct drm_gem_object *obj);
-void vc4_bo_cache_init(struct drm_device *dev);
+int vc4_bo_cache_init(struct drm_device *dev);
void vc4_bo_cache_destroy(struct drm_device *dev);
int vc4_bo_stats_debugfs(struct seq_file *m, void *arg);
/* vc4_crtc.c */
extern struct platform_driver vc4_crtc_driver;
-bool vc4_event_pending(struct drm_crtc *crtc);
int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg);
bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id,
bool in_vblank_irq, int *vpos, int *hpos,
diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
index 5e8b81eaa168..d1e0dc908048 100644
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
@@ -736,18 +736,18 @@ static void vc4_dsi_latch_ulps(struct vc4_dsi *dsi, bool latch)
/* Enters or exits Ultra Low Power State. */
static void vc4_dsi_ulps(struct vc4_dsi *dsi, bool ulps)
{
- bool continuous = dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS;
- u32 phyc_ulps = ((continuous ? DSI_PORT_BIT(PHYC_CLANE_ULPS) : 0) |
+ bool non_continuous = dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS;
+ u32 phyc_ulps = ((non_continuous ? DSI_PORT_BIT(PHYC_CLANE_ULPS) : 0) |
DSI_PHYC_DLANE0_ULPS |
(dsi->lanes > 1 ? DSI_PHYC_DLANE1_ULPS : 0) |
(dsi->lanes > 2 ? DSI_PHYC_DLANE2_ULPS : 0) |
(dsi->lanes > 3 ? DSI_PHYC_DLANE3_ULPS : 0));
- u32 stat_ulps = ((continuous ? DSI1_STAT_PHY_CLOCK_ULPS : 0) |
+ u32 stat_ulps = ((non_continuous ? DSI1_STAT_PHY_CLOCK_ULPS : 0) |
DSI1_STAT_PHY_D0_ULPS |
(dsi->lanes > 1 ? DSI1_STAT_PHY_D1_ULPS : 0) |
(dsi->lanes > 2 ? DSI1_STAT_PHY_D2_ULPS : 0) |
(dsi->lanes > 3 ? DSI1_STAT_PHY_D3_ULPS : 0));
- u32 stat_stop = ((continuous ? DSI1_STAT_PHY_CLOCK_STOP : 0) |
+ u32 stat_stop = ((non_continuous ? DSI1_STAT_PHY_CLOCK_STOP : 0) |
DSI1_STAT_PHY_D0_STOP |
(dsi->lanes > 1 ? DSI1_STAT_PHY_D1_STOP : 0) |
(dsi->lanes > 2 ? DSI1_STAT_PHY_D2_STOP : 0) |
@@ -1035,7 +1035,17 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
DSI_HS_DLT4_TRAIL) |
VC4_SET_FIELD(0, DSI_HS_DLT4_ANLAT));
- DSI_PORT_WRITE(HS_DLT5, VC4_SET_FIELD(dsi_hs_timing(ui_ns, 1000, 5000),
+ /* T_INIT is how long STOP is driven after power-up to
+ * indicate to the slave (also coming out of power-up) that
+ * master init is complete, and should be greater than the
+ * maximum of two value: T_INIT,MASTER and T_INIT,SLAVE. The
+ * D-PHY spec gives a minimum 100us for T_INIT,MASTER and
+ * T_INIT,SLAVE, while allowing protocols on top of it to give
+ * greater minimums. The vc4 firmware uses an extremely
+ * conservative 5ms, and we maintain that here.
+ */
+ DSI_PORT_WRITE(HS_DLT5, VC4_SET_FIELD(dsi_hs_timing(ui_ns,
+ 5 * 1000 * 1000, 0),
DSI_HS_DLT5_INIT));
DSI_PORT_WRITE(HS_DLT6,
@@ -1626,14 +1636,10 @@ static void vc4_dsi_unbind(struct device *dev, struct device *master,
pm_runtime_disable(dev);
- drm_bridge_remove(dsi->bridge);
vc4_dsi_encoder_destroy(dsi->encoder);
mipi_dsi_host_unregister(&dsi->dsi_host);
- clk_disable_unprepare(dsi->pll_phy_clock);
- clk_disable_unprepare(dsi->escape_clock);
-
if (dsi->port == 1)
vc4->dsi1 = NULL;
}
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index d5b821ad06af..d0c6bfb68c4e 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -55,7 +55,7 @@ vc4_free_hang_state(struct drm_device *dev, struct vc4_hang_state *state)
unsigned int i;
for (i = 0; i < state->user_state.bo_count; i++)
- drm_gem_object_unreference_unlocked(state->bo[i]);
+ drm_gem_object_put_unlocked(state->bo[i]);
kfree(state);
}
@@ -119,7 +119,7 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
bo_state[i].size = vc4_bo->base.base.size;
}
- if (copy_to_user((void __user *)(uintptr_t)get_state->bo,
+ if (copy_to_user(u64_to_user_ptr(get_state->bo),
bo_state,
state->bo_count * sizeof(*bo_state)))
ret = -EFAULT;
@@ -188,12 +188,12 @@ vc4_save_hang_state(struct drm_device *dev)
continue;
for (j = 0; j < exec[i]->bo_count; j++) {
- drm_gem_object_reference(&exec[i]->bo[j]->base);
+ drm_gem_object_get(&exec[i]->bo[j]->base);
kernel_state->bo[j + prev_idx] = &exec[i]->bo[j]->base;
}
list_for_each_entry(bo, &exec[i]->unref_list, unref_head) {
- drm_gem_object_reference(&bo->base.base);
+ drm_gem_object_get(&bo->base.base);
kernel_state->bo[j + prev_idx] = &bo->base.base;
j++;
}
@@ -659,7 +659,7 @@ vc4_cl_lookup_bos(struct drm_device *dev,
/* See comment on bo_index for why we have to check
* this.
*/
- DRM_ERROR("Rendering requires BOs to validate\n");
+ DRM_DEBUG("Rendering requires BOs to validate\n");
return -EINVAL;
}
@@ -678,8 +678,7 @@ vc4_cl_lookup_bos(struct drm_device *dev,
goto fail;
}
- if (copy_from_user(handles,
- (void __user *)(uintptr_t)args->bo_handles,
+ if (copy_from_user(handles, u64_to_user_ptr(args->bo_handles),
exec->bo_count * sizeof(uint32_t))) {
ret = -EFAULT;
DRM_ERROR("Failed to copy in GEM handles\n");
@@ -691,13 +690,13 @@ vc4_cl_lookup_bos(struct drm_device *dev,
struct drm_gem_object *bo = idr_find(&file_priv->object_idr,
handles[i]);
if (!bo) {
- DRM_ERROR("Failed to look up GEM BO %d: %d\n",
+ DRM_DEBUG("Failed to look up GEM BO %d: %d\n",
i, handles[i]);
ret = -EINVAL;
spin_unlock(&file_priv->table_lock);
goto fail;
}
- drm_gem_object_reference(bo);
+ drm_gem_object_get(bo);
exec->bo[i] = (struct drm_gem_cma_object *)bo;
}
spin_unlock(&file_priv->table_lock);
@@ -729,7 +728,7 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
args->shader_rec_count >= (UINT_MAX /
sizeof(struct vc4_shader_state)) ||
temp_size < exec_size) {
- DRM_ERROR("overflow in exec arguments\n");
+ DRM_DEBUG("overflow in exec arguments\n");
ret = -EINVAL;
goto fail;
}
@@ -755,27 +754,27 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
exec->shader_state_size = args->shader_rec_count;
if (copy_from_user(bin,
- (void __user *)(uintptr_t)args->bin_cl,
+ u64_to_user_ptr(args->bin_cl),
args->bin_cl_size)) {
ret = -EFAULT;
goto fail;
}
if (copy_from_user(exec->shader_rec_u,
- (void __user *)(uintptr_t)args->shader_rec,
+ u64_to_user_ptr(args->shader_rec),
args->shader_rec_size)) {
ret = -EFAULT;
goto fail;
}
if (copy_from_user(exec->uniforms_u,
- (void __user *)(uintptr_t)args->uniforms,
+ u64_to_user_ptr(args->uniforms),
args->uniforms_size)) {
ret = -EFAULT;
goto fail;
}
- bo = vc4_bo_create(dev, exec_size, true);
+ bo = vc4_bo_create(dev, exec_size, true, VC4_BO_TYPE_BCL);
if (IS_ERR(bo)) {
DRM_ERROR("Couldn't allocate BO for binning\n");
ret = PTR_ERR(bo);
@@ -835,7 +834,7 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
if (exec->bo) {
for (i = 0; i < exec->bo_count; i++)
- drm_gem_object_unreference_unlocked(&exec->bo[i]->base);
+ drm_gem_object_put_unlocked(&exec->bo[i]->base);
kvfree(exec->bo);
}
@@ -843,7 +842,7 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
struct vc4_bo *bo = list_first_entry(&exec->unref_list,
struct vc4_bo, unref_head);
list_del(&bo->unref_head);
- drm_gem_object_unreference_unlocked(&bo->base.base);
+ drm_gem_object_put_unlocked(&bo->base.base);
}
/* Free up the allocation of any bin slots we used. */
@@ -974,7 +973,7 @@ vc4_wait_bo_ioctl(struct drm_device *dev, void *data,
gem_obj = drm_gem_object_lookup(file_priv, args->handle);
if (!gem_obj) {
- DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
+ DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle);
return -EINVAL;
}
bo = to_vc4_bo(gem_obj);
@@ -982,7 +981,7 @@ vc4_wait_bo_ioctl(struct drm_device *dev, void *data,
ret = vc4_wait_for_seqno_ioctl_helper(dev, bo->seqno,
&args->timeout_ns);
- drm_gem_object_unreference_unlocked(gem_obj);
+ drm_gem_object_put_unlocked(gem_obj);
return ret;
}
@@ -1008,8 +1007,11 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
struct ww_acquire_ctx acquire_ctx;
int ret = 0;
- if ((args->flags & ~VC4_SUBMIT_CL_USE_CLEAR_COLOR) != 0) {
- DRM_ERROR("Unknown flags: 0x%02x\n", args->flags);
+ if ((args->flags & ~(VC4_SUBMIT_CL_USE_CLEAR_COLOR |
+ VC4_SUBMIT_CL_FIXED_RCL_ORDER |
+ VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X |
+ VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y)) != 0) {
+ DRM_DEBUG("Unknown flags: 0x%02x\n", args->flags);
return -EINVAL;
}
@@ -1118,6 +1120,4 @@ vc4_gem_destroy(struct drm_device *dev)
if (vc4->hang_state)
vc4_free_hang_state(dev, vc4->hang_state);
-
- vc4_bo_cache_destroy(dev);
}
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index ed63d4e85762..937da8dd65b8 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -57,9 +57,14 @@
#include <sound/pcm_drm_eld.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
+#include "media/cec.h"
#include "vc4_drv.h"
#include "vc4_regs.h"
+#define HSM_CLOCK_FREQ 163682864
+#define CEC_CLOCK_FREQ 40000
+#define CEC_CLOCK_DIV (HSM_CLOCK_FREQ / CEC_CLOCK_FREQ)
+
/* HDMI audio information */
struct vc4_hdmi_audio {
struct snd_soc_card card;
@@ -85,6 +90,11 @@ struct vc4_hdmi {
int hpd_gpio;
bool hpd_active_low;
+ struct cec_adapter *cec_adap;
+ struct cec_msg cec_rx_msg;
+ bool cec_tx_ok;
+ bool cec_irq_was_rx;
+
struct clk *pixel_clock;
struct clk *hsm_clock;
};
@@ -149,6 +159,23 @@ static const struct {
HDMI_REG(VC4_HDMI_VERTB1),
HDMI_REG(VC4_HDMI_TX_PHY_RESET_CTL),
HDMI_REG(VC4_HDMI_TX_PHY_CTL0),
+
+ HDMI_REG(VC4_HDMI_CEC_CNTRL_1),
+ HDMI_REG(VC4_HDMI_CEC_CNTRL_2),
+ HDMI_REG(VC4_HDMI_CEC_CNTRL_3),
+ HDMI_REG(VC4_HDMI_CEC_CNTRL_4),
+ HDMI_REG(VC4_HDMI_CEC_CNTRL_5),
+ HDMI_REG(VC4_HDMI_CPU_STATUS),
+ HDMI_REG(VC4_HDMI_CPU_MASK_STATUS),
+
+ HDMI_REG(VC4_HDMI_CEC_RX_DATA_1),
+ HDMI_REG(VC4_HDMI_CEC_RX_DATA_2),
+ HDMI_REG(VC4_HDMI_CEC_RX_DATA_3),
+ HDMI_REG(VC4_HDMI_CEC_RX_DATA_4),
+ HDMI_REG(VC4_HDMI_CEC_TX_DATA_1),
+ HDMI_REG(VC4_HDMI_CEC_TX_DATA_2),
+ HDMI_REG(VC4_HDMI_CEC_TX_DATA_3),
+ HDMI_REG(VC4_HDMI_CEC_TX_DATA_4),
};
static const struct {
@@ -216,8 +243,8 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
if (gpio_get_value_cansleep(vc4->hdmi->hpd_gpio) ^
vc4->hdmi->hpd_active_low)
return connector_status_connected;
- else
- return connector_status_disconnected;
+ cec_phys_addr_invalidate(vc4->hdmi->cec_adap);
+ return connector_status_disconnected;
}
if (drm_probe_ddc(vc4->hdmi->ddc))
@@ -225,8 +252,8 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
if (HDMI_READ(VC4_HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
return connector_status_connected;
- else
- return connector_status_disconnected;
+ cec_phys_addr_invalidate(vc4->hdmi->cec_adap);
+ return connector_status_disconnected;
}
static void vc4_hdmi_connector_destroy(struct drm_connector *connector)
@@ -247,6 +274,7 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
struct edid *edid;
edid = drm_get_edid(connector, vc4->hdmi->ddc);
+ cec_s_phys_addr_from_edid(vc4->hdmi->cec_adap, edid);
if (!edid)
return -ENODEV;
@@ -260,12 +288,12 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
drm_mode_connector_update_edid_property(connector, edid);
ret = drm_add_edid_modes(connector, edid);
drm_edid_to_eld(connector, edid);
+ kfree(edid);
return ret;
}
static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = vc4_hdmi_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = vc4_hdmi_connector_destroy,
@@ -395,7 +423,7 @@ static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
union hdmi_infoframe frame;
int ret;
- ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode);
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false);
if (ret < 0) {
DRM_ERROR("couldn't fill AVI infoframe\n");
return;
@@ -463,11 +491,6 @@ static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder)
HD_WRITE(VC4_HD_VID_CTL,
HD_READ(VC4_HD_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
- HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_SW_RST);
- udelay(1);
- HD_WRITE(VC4_HD_M_CTL, 0);
-
- clk_disable_unprepare(hdmi->hsm_clock);
clk_disable_unprepare(hdmi->pixel_clock);
ret = pm_runtime_put(&hdmi->pdev->dev);
@@ -509,16 +532,6 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
return;
}
- /* This is the rate that is set by the firmware. The number
- * needs to be a bit higher than the pixel clock rate
- * (generally 148.5Mhz).
- */
- ret = clk_set_rate(hdmi->hsm_clock, 163682864);
- if (ret) {
- DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
- return;
- }
-
ret = clk_set_rate(hdmi->pixel_clock,
mode->clock * 1000 *
((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1));
@@ -533,20 +546,6 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
return;
}
- ret = clk_prepare_enable(hdmi->hsm_clock);
- if (ret) {
- DRM_ERROR("Failed to turn on HDMI state machine clock: %d\n",
- ret);
- clk_disable_unprepare(hdmi->pixel_clock);
- return;
- }
-
- HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_SW_RST);
- udelay(1);
- HD_WRITE(VC4_HD_M_CTL, 0);
-
- HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_ENABLE);
-
HDMI_WRITE(VC4_HDMI_SW_RESET_CONTROL,
VC4_HDMI_SW_RESET_HDMI |
VC4_HDMI_SW_RESET_FORMAT_DETECT);
@@ -1150,6 +1149,159 @@ static void vc4_hdmi_audio_cleanup(struct vc4_hdmi *hdmi)
snd_soc_unregister_codec(dev);
}
+#ifdef CONFIG_DRM_VC4_HDMI_CEC
+static irqreturn_t vc4_cec_irq_handler_thread(int irq, void *priv)
+{
+ struct vc4_dev *vc4 = priv;
+ struct vc4_hdmi *hdmi = vc4->hdmi;
+
+ if (hdmi->cec_irq_was_rx) {
+ if (hdmi->cec_rx_msg.len)
+ cec_received_msg(hdmi->cec_adap, &hdmi->cec_rx_msg);
+ } else if (hdmi->cec_tx_ok) {
+ cec_transmit_done(hdmi->cec_adap, CEC_TX_STATUS_OK,
+ 0, 0, 0, 0);
+ } else {
+ /*
+ * This CEC implementation makes 1 retry, so if we
+ * get a NACK, then that means it made 2 attempts.
+ */
+ cec_transmit_done(hdmi->cec_adap, CEC_TX_STATUS_NACK,
+ 0, 2, 0, 0);
+ }
+ return IRQ_HANDLED;
+}
+
+static void vc4_cec_read_msg(struct vc4_dev *vc4, u32 cntrl1)
+{
+ struct cec_msg *msg = &vc4->hdmi->cec_rx_msg;
+ unsigned int i;
+
+ msg->len = 1 + ((cntrl1 & VC4_HDMI_CEC_REC_WRD_CNT_MASK) >>
+ VC4_HDMI_CEC_REC_WRD_CNT_SHIFT);
+ for (i = 0; i < msg->len; i += 4) {
+ u32 val = HDMI_READ(VC4_HDMI_CEC_RX_DATA_1 + i);
+
+ msg->msg[i] = val & 0xff;
+ msg->msg[i + 1] = (val >> 8) & 0xff;
+ msg->msg[i + 2] = (val >> 16) & 0xff;
+ msg->msg[i + 3] = (val >> 24) & 0xff;
+ }
+}
+
+static irqreturn_t vc4_cec_irq_handler(int irq, void *priv)
+{
+ struct vc4_dev *vc4 = priv;
+ struct vc4_hdmi *hdmi = vc4->hdmi;
+ u32 stat = HDMI_READ(VC4_HDMI_CPU_STATUS);
+ u32 cntrl1, cntrl5;
+
+ if (!(stat & VC4_HDMI_CPU_CEC))
+ return IRQ_NONE;
+ hdmi->cec_rx_msg.len = 0;
+ cntrl1 = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
+ cntrl5 = HDMI_READ(VC4_HDMI_CEC_CNTRL_5);
+ hdmi->cec_irq_was_rx = cntrl5 & VC4_HDMI_CEC_RX_CEC_INT;
+ if (hdmi->cec_irq_was_rx) {
+ vc4_cec_read_msg(vc4, cntrl1);
+ cntrl1 |= VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, cntrl1);
+ cntrl1 &= ~VC4_HDMI_CEC_CLEAR_RECEIVE_OFF;
+ } else {
+ hdmi->cec_tx_ok = cntrl1 & VC4_HDMI_CEC_TX_STATUS_GOOD;
+ cntrl1 &= ~VC4_HDMI_CEC_START_XMIT_BEGIN;
+ }
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, cntrl1);
+ HDMI_WRITE(VC4_HDMI_CPU_CLEAR, VC4_HDMI_CPU_CEC);
+
+ return IRQ_WAKE_THREAD;
+}
+
+static int vc4_hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable)
+{
+ struct vc4_dev *vc4 = cec_get_drvdata(adap);
+ /* clock period in microseconds */
+ const u32 usecs = 1000000 / CEC_CLOCK_FREQ;
+ u32 val = HDMI_READ(VC4_HDMI_CEC_CNTRL_5);
+
+ val &= ~(VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET |
+ VC4_HDMI_CEC_CNT_TO_4700_US_MASK |
+ VC4_HDMI_CEC_CNT_TO_4500_US_MASK);
+ val |= ((4700 / usecs) << VC4_HDMI_CEC_CNT_TO_4700_US_SHIFT) |
+ ((4500 / usecs) << VC4_HDMI_CEC_CNT_TO_4500_US_SHIFT);
+
+ if (enable) {
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_5, val |
+ VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET);
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_5, val);
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_2,
+ ((1500 / usecs) << VC4_HDMI_CEC_CNT_TO_1500_US_SHIFT) |
+ ((1300 / usecs) << VC4_HDMI_CEC_CNT_TO_1300_US_SHIFT) |
+ ((800 / usecs) << VC4_HDMI_CEC_CNT_TO_800_US_SHIFT) |
+ ((600 / usecs) << VC4_HDMI_CEC_CNT_TO_600_US_SHIFT) |
+ ((400 / usecs) << VC4_HDMI_CEC_CNT_TO_400_US_SHIFT));
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_3,
+ ((2750 / usecs) << VC4_HDMI_CEC_CNT_TO_2750_US_SHIFT) |
+ ((2400 / usecs) << VC4_HDMI_CEC_CNT_TO_2400_US_SHIFT) |
+ ((2050 / usecs) << VC4_HDMI_CEC_CNT_TO_2050_US_SHIFT) |
+ ((1700 / usecs) << VC4_HDMI_CEC_CNT_TO_1700_US_SHIFT));
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_4,
+ ((4300 / usecs) << VC4_HDMI_CEC_CNT_TO_4300_US_SHIFT) |
+ ((3900 / usecs) << VC4_HDMI_CEC_CNT_TO_3900_US_SHIFT) |
+ ((3600 / usecs) << VC4_HDMI_CEC_CNT_TO_3600_US_SHIFT) |
+ ((3500 / usecs) << VC4_HDMI_CEC_CNT_TO_3500_US_SHIFT));
+
+ HDMI_WRITE(VC4_HDMI_CPU_MASK_CLEAR, VC4_HDMI_CPU_CEC);
+ } else {
+ HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, VC4_HDMI_CPU_CEC);
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_5, val |
+ VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET);
+ }
+ return 0;
+}
+
+static int vc4_hdmi_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
+{
+ struct vc4_dev *vc4 = cec_get_drvdata(adap);
+
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1,
+ (HDMI_READ(VC4_HDMI_CEC_CNTRL_1) & ~VC4_HDMI_CEC_ADDR_MASK) |
+ (log_addr & 0xf) << VC4_HDMI_CEC_ADDR_SHIFT);
+ return 0;
+}
+
+static int vc4_hdmi_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
+ u32 signal_free_time, struct cec_msg *msg)
+{
+ struct vc4_dev *vc4 = cec_get_drvdata(adap);
+ u32 val;
+ unsigned int i;
+
+ for (i = 0; i < msg->len; i += 4)
+ HDMI_WRITE(VC4_HDMI_CEC_TX_DATA_1 + i,
+ (msg->msg[i]) |
+ (msg->msg[i + 1] << 8) |
+ (msg->msg[i + 2] << 16) |
+ (msg->msg[i + 3] << 24));
+
+ val = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
+ val &= ~VC4_HDMI_CEC_START_XMIT_BEGIN;
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, val);
+ val &= ~VC4_HDMI_CEC_MESSAGE_LENGTH_MASK;
+ val |= (msg->len - 1) << VC4_HDMI_CEC_MESSAGE_LENGTH_SHIFT;
+ val |= VC4_HDMI_CEC_START_XMIT_BEGIN;
+
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, val);
+ return 0;
+}
+
+static const struct cec_adap_ops vc4_hdmi_cec_adap_ops = {
+ .adap_enable = vc4_hdmi_cec_adap_enable,
+ .adap_log_addr = vc4_hdmi_cec_adap_log_addr,
+ .adap_transmit = vc4_hdmi_cec_adap_transmit,
+};
+#endif
+
static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -1205,6 +1357,23 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
return -EPROBE_DEFER;
}
+ /* This is the rate that is set by the firmware. The number
+ * needs to be a bit higher than the pixel clock rate
+ * (generally 148.5Mhz).
+ */
+ ret = clk_set_rate(hdmi->hsm_clock, HSM_CLOCK_FREQ);
+ if (ret) {
+ DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
+ goto err_put_i2c;
+ }
+
+ ret = clk_prepare_enable(hdmi->hsm_clock);
+ if (ret) {
+ DRM_ERROR("Failed to turn on HDMI state machine clock: %d\n",
+ ret);
+ goto err_put_i2c;
+ }
+
/* Only use the GPIO HPD pin if present in the DT, otherwise
* we'll use the HDMI core's register.
*/
@@ -1216,7 +1385,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
&hpd_gpio_flags);
if (hdmi->hpd_gpio < 0) {
ret = hdmi->hpd_gpio;
- goto err_put_i2c;
+ goto err_unprepare_hsm;
}
hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW;
@@ -1224,6 +1393,14 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
vc4->hdmi = hdmi;
+ /* HDMI core must be enabled. */
+ if (!(HD_READ(VC4_HD_M_CTL) & VC4_HD_M_ENABLE)) {
+ HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_SW_RST);
+ udelay(1);
+ HD_WRITE(VC4_HD_M_CTL, 0);
+
+ HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_ENABLE);
+ }
pm_runtime_enable(dev);
drm_encoder_init(drm, hdmi->encoder, &vc4_hdmi_encoder_funcs,
@@ -1235,6 +1412,37 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
ret = PTR_ERR(hdmi->connector);
goto err_destroy_encoder;
}
+#ifdef CONFIG_DRM_VC4_HDMI_CEC
+ hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops,
+ vc4, "vc4",
+ CEC_CAP_TRANSMIT |
+ CEC_CAP_LOG_ADDRS |
+ CEC_CAP_PASSTHROUGH |
+ CEC_CAP_RC, 1);
+ ret = PTR_ERR_OR_ZERO(hdmi->cec_adap);
+ if (ret < 0)
+ goto err_destroy_conn;
+ HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, 0xffffffff);
+ value = HDMI_READ(VC4_HDMI_CEC_CNTRL_1);
+ value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
+ /*
+ * Set the logical address to Unregistered and set the clock
+ * divider: the hsm_clock rate and this divider setting will
+ * give a 40 kHz CEC clock.
+ */
+ value |= VC4_HDMI_CEC_ADDR_MASK |
+ (4091 << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT);
+ HDMI_WRITE(VC4_HDMI_CEC_CNTRL_1, value);
+ ret = devm_request_threaded_irq(dev, platform_get_irq(pdev, 0),
+ vc4_cec_irq_handler,
+ vc4_cec_irq_handler_thread, 0,
+ "vc4 hdmi cec", vc4);
+ if (ret)
+ goto err_delete_cec_adap;
+ ret = cec_register_adapter(hdmi->cec_adap, dev);
+ if (ret < 0)
+ goto err_delete_cec_adap;
+#endif
ret = vc4_hdmi_audio_init(hdmi);
if (ret)
@@ -1242,8 +1450,16 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
return 0;
+#ifdef CONFIG_DRM_VC4_HDMI_CEC
+err_delete_cec_adap:
+ cec_delete_adapter(hdmi->cec_adap);
+err_destroy_conn:
+ vc4_hdmi_connector_destroy(hdmi->connector);
+#endif
err_destroy_encoder:
vc4_hdmi_encoder_destroy(hdmi->encoder);
+err_unprepare_hsm:
+ clk_disable_unprepare(hdmi->hsm_clock);
pm_runtime_disable(dev);
err_put_i2c:
put_device(&hdmi->ddc->dev);
@@ -1259,10 +1475,11 @@ static void vc4_hdmi_unbind(struct device *dev, struct device *master,
struct vc4_hdmi *hdmi = vc4->hdmi;
vc4_hdmi_audio_cleanup(hdmi);
-
+ cec_unregister_adapter(hdmi->cec_adap);
vc4_hdmi_connector_destroy(hdmi->connector);
vc4_hdmi_encoder_destroy(hdmi->encoder);
+ clk_disable_unprepare(hdmi->hsm_clock);
pm_runtime_disable(dev);
put_device(&hdmi->ddc->dev);
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index bc6ecdc6f104..50c4959b5bd3 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -20,6 +20,7 @@
#include <drm/drm_crtc_helper.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_framebuffer_helper.h>
#include "vc4_drv.h"
static void vc4_output_poll_changed(struct drm_device *dev)
@@ -29,16 +30,9 @@ static void vc4_output_poll_changed(struct drm_device *dev)
drm_fbdev_cma_hotplug_event(vc4->fbdev);
}
-struct vc4_commit {
- struct drm_device *dev;
- struct drm_atomic_state *state;
- struct vc4_seqno_cb cb;
-};
-
static void
-vc4_atomic_complete_commit(struct vc4_commit *c)
+vc4_atomic_complete_commit(struct drm_atomic_state *state)
{
- struct drm_atomic_state *state = c->state;
struct drm_device *dev = state->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
@@ -72,28 +66,14 @@ vc4_atomic_complete_commit(struct vc4_commit *c)
drm_atomic_state_put(state);
up(&vc4->async_modeset);
-
- kfree(c);
}
-static void
-vc4_atomic_complete_commit_seqno_cb(struct vc4_seqno_cb *cb)
+static void commit_work(struct work_struct *work)
{
- struct vc4_commit *c = container_of(cb, struct vc4_commit, cb);
-
- vc4_atomic_complete_commit(c);
-}
-
-static struct vc4_commit *commit_init(struct drm_atomic_state *state)
-{
- struct vc4_commit *c = kzalloc(sizeof(*c), GFP_KERNEL);
-
- if (!c)
- return NULL;
- c->dev = state->dev;
- c->state = state;
-
- return c;
+ struct drm_atomic_state *state = container_of(work,
+ struct drm_atomic_state,
+ commit_work);
+ vc4_atomic_complete_commit(state);
}
/**
@@ -115,40 +95,29 @@ static int vc4_atomic_commit(struct drm_device *dev,
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
int ret;
- int i;
- uint64_t wait_seqno = 0;
- struct vc4_commit *c;
- struct drm_plane *plane;
- struct drm_plane_state *new_state;
-
- c = commit_init(state);
- if (!c)
- return -ENOMEM;
ret = drm_atomic_helper_setup_commit(state, nonblock);
if (ret)
return ret;
+ INIT_WORK(&state->commit_work, commit_work);
+
ret = down_interruptible(&vc4->async_modeset);
- if (ret) {
- kfree(c);
+ if (ret)
return ret;
- }
ret = drm_atomic_helper_prepare_planes(dev, state);
if (ret) {
- kfree(c);
up(&vc4->async_modeset);
return ret;
}
- for_each_plane_in_state(state, plane, new_state, i) {
- if ((plane->state->fb != new_state->fb) && new_state->fb) {
- struct drm_gem_cma_object *cma_bo =
- drm_fb_cma_get_gem_obj(new_state->fb, 0);
- struct vc4_bo *bo = to_vc4_bo(&cma_bo->base);
-
- wait_seqno = max(bo->seqno, wait_seqno);
+ if (!nonblock) {
+ ret = drm_atomic_helper_wait_for_fences(dev, state, true);
+ if (ret) {
+ drm_atomic_helper_cleanup_planes(dev, state);
+ up(&vc4->async_modeset);
+ return ret;
}
}
@@ -158,7 +127,7 @@ static int vc4_atomic_commit(struct drm_device *dev,
* the software side now.
*/
- drm_atomic_helper_swap_state(state, true);
+ BUG_ON(drm_atomic_helper_swap_state(state, false) < 0);
/*
* Everything below can be run asynchronously without the need to grab
@@ -177,13 +146,10 @@ static int vc4_atomic_commit(struct drm_device *dev,
*/
drm_atomic_state_get(state);
- if (nonblock) {
- vc4_queue_seqno_cb(dev, &c->cb, wait_seqno,
- vc4_atomic_complete_commit_seqno_cb);
- } else {
- vc4_wait_for_seqno(dev, wait_seqno, ~0ull, false);
- vc4_atomic_complete_commit(c);
- }
+ if (nonblock)
+ queue_work(system_unbound_wq, &state->commit_work);
+ else
+ vc4_atomic_complete_commit(state);
return 0;
}
@@ -204,7 +170,7 @@ static struct drm_framebuffer *vc4_fb_create(struct drm_device *dev,
gem_obj = drm_gem_object_lookup(file_priv,
mode_cmd->handles[0]);
if (!gem_obj) {
- DRM_ERROR("Failed to look up GEM BO %d\n",
+ DRM_DEBUG("Failed to look up GEM BO %d\n",
mode_cmd->handles[0]);
return ERR_PTR(-ENOENT);
}
@@ -219,12 +185,12 @@ static struct drm_framebuffer *vc4_fb_create(struct drm_device *dev,
mode_cmd_local.modifier[0] = DRM_FORMAT_MOD_NONE;
}
- drm_gem_object_unreference_unlocked(gem_obj);
+ drm_gem_object_put_unlocked(gem_obj);
mode_cmd = &mode_cmd_local;
}
- return drm_fb_cma_create(dev, file_priv, mode_cmd);
+ return drm_gem_fb_create(dev, file_priv, mode_cmd);
}
static const struct drm_mode_config_funcs vc4_mode_funcs = {
@@ -241,6 +207,9 @@ int vc4_kms_load(struct drm_device *dev)
sema_init(&vc4->async_modeset, 1);
+ /* Set support for vblank irq fast disable, before drm_vblank_init() */
+ dev->vblank_disable_immediate = true;
+
ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
if (ret < 0) {
dev_err(dev->dev, "failed to initialize vblank\n");
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index fa6809d8b0fe..2968b3ebb895 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -759,9 +759,26 @@ void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb)
vc4_state->dlist[vc4_state->ptr0_offset] = addr;
}
+static int vc4_prepare_fb(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ struct vc4_bo *bo;
+ struct dma_fence *fence;
+
+ if ((plane->state->fb == state->fb) || !state->fb)
+ return 0;
+
+ bo = to_vc4_bo(&drm_fb_cma_get_gem_obj(state->fb, 0)->base);
+ fence = reservation_object_get_excl_rcu(bo->resv);
+ drm_atomic_set_fence_for_plane(state, fence);
+
+ return 0;
+}
+
static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = {
.atomic_check = vc4_plane_atomic_check,
.atomic_update = vc4_plane_atomic_update,
+ .prepare_fb = vc4_prepare_fb,
};
static void vc4_plane_destroy(struct drm_plane *plane)
@@ -885,7 +902,7 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
ret = drm_universal_plane_init(dev, plane, 0,
&vc4_plane_funcs,
formats, num_formats,
- type, NULL);
+ NULL, type, NULL);
drm_plane_helper_add(plane, &vc4_plane_helper_funcs);
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index d382c34c1b9e..55677bd50f66 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -561,16 +561,129 @@
# define VC4_HDMI_VERTB_VBP_MASK VC4_MASK(8, 0)
# define VC4_HDMI_VERTB_VBP_SHIFT 0
+#define VC4_HDMI_CEC_CNTRL_1 0x0e8
+/* Set when the transmission has ended. */
+# define VC4_HDMI_CEC_TX_EOM BIT(31)
+/* If set, transmission was acked on the 1st or 2nd attempt (only one
+ * retry is attempted). If in continuous mode, this means TX needs to
+ * be filled if !TX_EOM.
+ */
+# define VC4_HDMI_CEC_TX_STATUS_GOOD BIT(30)
+# define VC4_HDMI_CEC_RX_EOM BIT(29)
+# define VC4_HDMI_CEC_RX_STATUS_GOOD BIT(28)
+/* Number of bytes received for the message. */
+# define VC4_HDMI_CEC_REC_WRD_CNT_MASK VC4_MASK(27, 24)
+# define VC4_HDMI_CEC_REC_WRD_CNT_SHIFT 24
+/* Sets continuous receive mode. Generates interrupt after each 8
+ * bytes to signal that RX_DATA should be consumed, and at RX_EOM.
+ *
+ * If disabled, maximum 16 bytes will be received (including header),
+ * and interrupt at RX_EOM. Later bytes will be acked but not put
+ * into the RX_DATA.
+ */
+# define VC4_HDMI_CEC_RX_CONTINUE BIT(23)
+# define VC4_HDMI_CEC_TX_CONTINUE BIT(22)
+/* Set this after a CEC interrupt. */
+# define VC4_HDMI_CEC_CLEAR_RECEIVE_OFF BIT(21)
+/* Starts a TX. Will wait for appropriate idel time before CEC
+ * activity. Must be cleared in between transmits.
+ */
+# define VC4_HDMI_CEC_START_XMIT_BEGIN BIT(20)
+# define VC4_HDMI_CEC_MESSAGE_LENGTH_MASK VC4_MASK(19, 16)
+# define VC4_HDMI_CEC_MESSAGE_LENGTH_SHIFT 16
+/* Device's CEC address */
+# define VC4_HDMI_CEC_ADDR_MASK VC4_MASK(15, 12)
+# define VC4_HDMI_CEC_ADDR_SHIFT 12
+/* Divides off of HSM clock to generate CEC bit clock. */
+/* With the current defaults the CEC bit clock is 40 kHz = 25 usec */
+# define VC4_HDMI_CEC_DIV_CLK_CNT_MASK VC4_MASK(11, 0)
+# define VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT 0
+
+/* Set these fields to how many bit clock cycles get to that many
+ * microseconds.
+ */
+#define VC4_HDMI_CEC_CNTRL_2 0x0ec
+# define VC4_HDMI_CEC_CNT_TO_1500_US_MASK VC4_MASK(30, 24)
+# define VC4_HDMI_CEC_CNT_TO_1500_US_SHIFT 24
+# define VC4_HDMI_CEC_CNT_TO_1300_US_MASK VC4_MASK(23, 17)
+# define VC4_HDMI_CEC_CNT_TO_1300_US_SHIFT 17
+# define VC4_HDMI_CEC_CNT_TO_800_US_MASK VC4_MASK(16, 11)
+# define VC4_HDMI_CEC_CNT_TO_800_US_SHIFT 11
+# define VC4_HDMI_CEC_CNT_TO_600_US_MASK VC4_MASK(10, 5)
+# define VC4_HDMI_CEC_CNT_TO_600_US_SHIFT 5
+# define VC4_HDMI_CEC_CNT_TO_400_US_MASK VC4_MASK(4, 0)
+# define VC4_HDMI_CEC_CNT_TO_400_US_SHIFT 0
+
+#define VC4_HDMI_CEC_CNTRL_3 0x0f0
+# define VC4_HDMI_CEC_CNT_TO_2750_US_MASK VC4_MASK(31, 24)
+# define VC4_HDMI_CEC_CNT_TO_2750_US_SHIFT 24
+# define VC4_HDMI_CEC_CNT_TO_2400_US_MASK VC4_MASK(23, 16)
+# define VC4_HDMI_CEC_CNT_TO_2400_US_SHIFT 16
+# define VC4_HDMI_CEC_CNT_TO_2050_US_MASK VC4_MASK(15, 8)
+# define VC4_HDMI_CEC_CNT_TO_2050_US_SHIFT 8
+# define VC4_HDMI_CEC_CNT_TO_1700_US_MASK VC4_MASK(7, 0)
+# define VC4_HDMI_CEC_CNT_TO_1700_US_SHIFT 0
+
+#define VC4_HDMI_CEC_CNTRL_4 0x0f4
+# define VC4_HDMI_CEC_CNT_TO_4300_US_MASK VC4_MASK(31, 24)
+# define VC4_HDMI_CEC_CNT_TO_4300_US_SHIFT 24
+# define VC4_HDMI_CEC_CNT_TO_3900_US_MASK VC4_MASK(23, 16)
+# define VC4_HDMI_CEC_CNT_TO_3900_US_SHIFT 16
+# define VC4_HDMI_CEC_CNT_TO_3600_US_MASK VC4_MASK(15, 8)
+# define VC4_HDMI_CEC_CNT_TO_3600_US_SHIFT 8
+# define VC4_HDMI_CEC_CNT_TO_3500_US_MASK VC4_MASK(7, 0)
+# define VC4_HDMI_CEC_CNT_TO_3500_US_SHIFT 0
+
+#define VC4_HDMI_CEC_CNTRL_5 0x0f8
+# define VC4_HDMI_CEC_TX_SW_RESET BIT(27)
+# define VC4_HDMI_CEC_RX_SW_RESET BIT(26)
+# define VC4_HDMI_CEC_PAD_SW_RESET BIT(25)
+# define VC4_HDMI_CEC_MUX_TP_OUT_CEC BIT(24)
+# define VC4_HDMI_CEC_RX_CEC_INT BIT(23)
+# define VC4_HDMI_CEC_CLK_PRELOAD_MASK VC4_MASK(22, 16)
+# define VC4_HDMI_CEC_CLK_PRELOAD_SHIFT 16
+# define VC4_HDMI_CEC_CNT_TO_4700_US_MASK VC4_MASK(15, 8)
+# define VC4_HDMI_CEC_CNT_TO_4700_US_SHIFT 8
+# define VC4_HDMI_CEC_CNT_TO_4500_US_MASK VC4_MASK(7, 0)
+# define VC4_HDMI_CEC_CNT_TO_4500_US_SHIFT 0
+
+/* Transmit data, first byte is low byte of the 32-bit reg. MSB of
+ * each byte transmitted first.
+ */
+#define VC4_HDMI_CEC_TX_DATA_1 0x0fc
+#define VC4_HDMI_CEC_TX_DATA_2 0x100
+#define VC4_HDMI_CEC_TX_DATA_3 0x104
+#define VC4_HDMI_CEC_TX_DATA_4 0x108
+#define VC4_HDMI_CEC_RX_DATA_1 0x10c
+#define VC4_HDMI_CEC_RX_DATA_2 0x110
+#define VC4_HDMI_CEC_RX_DATA_3 0x114
+#define VC4_HDMI_CEC_RX_DATA_4 0x118
+
#define VC4_HDMI_TX_PHY_RESET_CTL 0x2c0
#define VC4_HDMI_TX_PHY_CTL0 0x2c4
# define VC4_HDMI_TX_PHY_RNG_PWRDN BIT(25)
+/* Interrupt status bits */
+#define VC4_HDMI_CPU_STATUS 0x340
+#define VC4_HDMI_CPU_SET 0x344
+#define VC4_HDMI_CPU_CLEAR 0x348
+# define VC4_HDMI_CPU_CEC BIT(6)
+# define VC4_HDMI_CPU_HOTPLUG BIT(0)
+
+#define VC4_HDMI_CPU_MASK_STATUS 0x34c
+#define VC4_HDMI_CPU_MASK_SET 0x350
+#define VC4_HDMI_CPU_MASK_CLEAR 0x354
+
#define VC4_HDMI_GCP(x) (0x400 + ((x) * 0x4))
#define VC4_HDMI_RAM_PACKET(x) (0x400 + ((x) * 0x24))
#define VC4_HDMI_PACKET_STRIDE 0x24
#define VC4_HD_M_CTL 0x00c
+/* Debug: Current receive value on the CEC pad. */
+# define VC4_HD_CECRXD BIT(9)
+/* Debug: Override CEC output to 0. */
+# define VC4_HD_CECOVR BIT(8)
# define VC4_HD_M_REGISTER_FILE_STANDBY (3 << 6)
# define VC4_HD_M_RAM_STANDBY (3 << 4)
# define VC4_HD_M_SW_RST BIT(2)
diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c
index 5dc19429d4ae..273984f71ae2 100644
--- a/drivers/gpu/drm/vc4/vc4_render_cl.c
+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c
@@ -261,8 +261,17 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
uint8_t max_y_tile = args->max_y_tile;
uint8_t xtiles = max_x_tile - min_x_tile + 1;
uint8_t ytiles = max_y_tile - min_y_tile + 1;
- uint8_t x, y;
+ uint8_t xi, yi;
uint32_t size, loop_body_size;
+ bool positive_x = true;
+ bool positive_y = true;
+
+ if (args->flags & VC4_SUBMIT_CL_FIXED_RCL_ORDER) {
+ if (!(args->flags & VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X))
+ positive_x = false;
+ if (!(args->flags & VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y))
+ positive_y = false;
+ }
size = VC4_PACKET_TILE_RENDERING_MODE_CONFIG_SIZE;
loop_body_size = VC4_PACKET_TILE_COORDINATES_SIZE;
@@ -320,7 +329,7 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
size += xtiles * ytiles * loop_body_size;
- setup->rcl = &vc4_bo_create(dev, size, true)->base;
+ setup->rcl = &vc4_bo_create(dev, size, true, VC4_BO_TYPE_RCL)->base;
if (IS_ERR(setup->rcl))
return PTR_ERR(setup->rcl);
list_add_tail(&to_vc4_bo(&setup->rcl->base)->unref_head,
@@ -354,10 +363,12 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
rcl_u16(setup, args->height);
rcl_u16(setup, args->color_write.bits);
- for (y = min_y_tile; y <= max_y_tile; y++) {
- for (x = min_x_tile; x <= max_x_tile; x++) {
- bool first = (x == min_x_tile && y == min_y_tile);
- bool last = (x == max_x_tile && y == max_y_tile);
+ for (yi = 0; yi < ytiles; yi++) {
+ int y = positive_y ? min_y_tile + yi : max_y_tile - yi;
+ for (xi = 0; xi < xtiles; xi++) {
+ int x = positive_x ? min_x_tile + xi : max_x_tile - xi;
+ bool first = (xi == 0 && yi == 0);
+ bool last = (xi == xtiles - 1 && yi == ytiles - 1);
emit_tile(exec, setup, x, y, first, last);
}
@@ -378,14 +389,14 @@ static int vc4_full_res_bounds_check(struct vc4_exec_info *exec,
u32 render_tiles_stride = DIV_ROUND_UP(exec->args->width, 32);
if (surf->offset > obj->base.size) {
- DRM_ERROR("surface offset %d > BO size %zd\n",
+ DRM_DEBUG("surface offset %d > BO size %zd\n",
surf->offset, obj->base.size);
return -EINVAL;
}
if ((obj->base.size - surf->offset) / VC4_TILE_BUFFER_SIZE <
render_tiles_stride * args->max_y_tile + args->max_x_tile) {
- DRM_ERROR("MSAA tile %d, %d out of bounds "
+ DRM_DEBUG("MSAA tile %d, %d out of bounds "
"(bo size %zd, offset %d).\n",
args->max_x_tile, args->max_y_tile,
obj->base.size,
@@ -401,7 +412,7 @@ static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec,
struct drm_vc4_submit_rcl_surface *surf)
{
if (surf->flags != 0 || surf->bits != 0) {
- DRM_ERROR("MSAA surface had nonzero flags/bits\n");
+ DRM_DEBUG("MSAA surface had nonzero flags/bits\n");
return -EINVAL;
}
@@ -415,7 +426,7 @@ static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec,
exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj;
if (surf->offset & 0xf) {
- DRM_ERROR("MSAA write must be 16b aligned.\n");
+ DRM_DEBUG("MSAA write must be 16b aligned.\n");
return -EINVAL;
}
@@ -437,7 +448,7 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
int ret;
if (surf->flags & ~VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
- DRM_ERROR("Extra flags set\n");
+ DRM_DEBUG("Extra flags set\n");
return -EINVAL;
}
@@ -453,12 +464,12 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
if (surf == &exec->args->zs_write) {
- DRM_ERROR("general zs write may not be a full-res.\n");
+ DRM_DEBUG("general zs write may not be a full-res.\n");
return -EINVAL;
}
if (surf->bits != 0) {
- DRM_ERROR("load/store general bits set with "
+ DRM_DEBUG("load/store general bits set with "
"full res load/store.\n");
return -EINVAL;
}
@@ -473,19 +484,19 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
if (surf->bits & ~(VC4_LOADSTORE_TILE_BUFFER_TILING_MASK |
VC4_LOADSTORE_TILE_BUFFER_BUFFER_MASK |
VC4_LOADSTORE_TILE_BUFFER_FORMAT_MASK)) {
- DRM_ERROR("Unknown bits in load/store: 0x%04x\n",
+ DRM_DEBUG("Unknown bits in load/store: 0x%04x\n",
surf->bits);
return -EINVAL;
}
if (tiling > VC4_TILING_FORMAT_LT) {
- DRM_ERROR("Bad tiling format\n");
+ DRM_DEBUG("Bad tiling format\n");
return -EINVAL;
}
if (buffer == VC4_LOADSTORE_TILE_BUFFER_ZS) {
if (format != 0) {
- DRM_ERROR("No color format should be set for ZS\n");
+ DRM_DEBUG("No color format should be set for ZS\n");
return -EINVAL;
}
cpp = 4;
@@ -499,16 +510,16 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
cpp = 4;
break;
default:
- DRM_ERROR("Bad tile buffer format\n");
+ DRM_DEBUG("Bad tile buffer format\n");
return -EINVAL;
}
} else {
- DRM_ERROR("Bad load/store buffer %d.\n", buffer);
+ DRM_DEBUG("Bad load/store buffer %d.\n", buffer);
return -EINVAL;
}
if (surf->offset & 0xf) {
- DRM_ERROR("load/store buffer must be 16b aligned.\n");
+ DRM_DEBUG("load/store buffer must be 16b aligned.\n");
return -EINVAL;
}
@@ -533,7 +544,7 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec,
int cpp;
if (surf->flags != 0) {
- DRM_ERROR("No flags supported on render config.\n");
+ DRM_DEBUG("No flags supported on render config.\n");
return -EINVAL;
}
@@ -541,7 +552,7 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec,
VC4_RENDER_CONFIG_FORMAT_MASK |
VC4_RENDER_CONFIG_MS_MODE_4X |
VC4_RENDER_CONFIG_DECIMATE_MODE_4X)) {
- DRM_ERROR("Unknown bits in render config: 0x%04x\n",
+ DRM_DEBUG("Unknown bits in render config: 0x%04x\n",
surf->bits);
return -EINVAL;
}
@@ -556,7 +567,7 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec,
exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj;
if (tiling > VC4_TILING_FORMAT_LT) {
- DRM_ERROR("Bad tiling format\n");
+ DRM_DEBUG("Bad tiling format\n");
return -EINVAL;
}
@@ -569,7 +580,7 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec,
cpp = 4;
break;
default:
- DRM_ERROR("Bad tile buffer format\n");
+ DRM_DEBUG("Bad tile buffer format\n");
return -EINVAL;
}
@@ -590,7 +601,7 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec)
if (args->min_x_tile > args->max_x_tile ||
args->min_y_tile > args->max_y_tile) {
- DRM_ERROR("Bad render tile set (%d,%d)-(%d,%d)\n",
+ DRM_DEBUG("Bad render tile set (%d,%d)-(%d,%d)\n",
args->min_x_tile, args->min_y_tile,
args->max_x_tile, args->max_y_tile);
return -EINVAL;
@@ -599,7 +610,7 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec)
if (has_bin &&
(args->max_x_tile > exec->bin_tiles_x ||
args->max_y_tile > exec->bin_tiles_y)) {
- DRM_ERROR("Render tiles (%d,%d) outside of bin config "
+ DRM_DEBUG("Render tiles (%d,%d) outside of bin config "
"(%d,%d)\n",
args->max_x_tile, args->max_y_tile,
exec->bin_tiles_x, exec->bin_tiles_y);
@@ -642,7 +653,7 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec)
*/
if (!setup.color_write && !setup.zs_write &&
!setup.msaa_color_write && !setup.msaa_zs_write) {
- DRM_ERROR("RCL requires color or Z/S write\n");
+ DRM_DEBUG("RCL requires color or Z/S write\n");
return -EINVAL;
}
diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
index 8c723da71f66..622cd43840b8 100644
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -236,7 +236,8 @@ vc4_allocate_bin_bo(struct drm_device *drm)
INIT_LIST_HEAD(&list);
while (true) {
- struct vc4_bo *bo = vc4_bo_create(drm, size, true);
+ struct vc4_bo *bo = vc4_bo_create(drm, size, true,
+ VC4_BO_TYPE_BIN);
if (IS_ERR(bo)) {
ret = PTR_ERR(bo);
diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c
index 814b512c6b9a..2db485abb186 100644
--- a/drivers/gpu/drm/vc4/vc4_validate.c
+++ b/drivers/gpu/drm/vc4/vc4_validate.c
@@ -109,7 +109,7 @@ vc4_use_bo(struct vc4_exec_info *exec, uint32_t hindex)
struct vc4_bo *bo;
if (hindex >= exec->bo_count) {
- DRM_ERROR("BO index %d greater than BO count %d\n",
+ DRM_DEBUG("BO index %d greater than BO count %d\n",
hindex, exec->bo_count);
return NULL;
}
@@ -117,7 +117,7 @@ vc4_use_bo(struct vc4_exec_info *exec, uint32_t hindex)
bo = to_vc4_bo(&obj->base);
if (bo->validated_shader) {
- DRM_ERROR("Trying to use shader BO as something other than "
+ DRM_DEBUG("Trying to use shader BO as something other than "
"a shader\n");
return NULL;
}
@@ -172,7 +172,7 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo,
* our math.
*/
if (width > 4096 || height > 4096) {
- DRM_ERROR("Surface dimensions (%d,%d) too large",
+ DRM_DEBUG("Surface dimensions (%d,%d) too large",
width, height);
return false;
}
@@ -191,7 +191,7 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo,
aligned_height = round_up(height, utile_h);
break;
default:
- DRM_ERROR("buffer tiling %d unsupported\n", tiling_format);
+ DRM_DEBUG("buffer tiling %d unsupported\n", tiling_format);
return false;
}
@@ -200,7 +200,7 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo,
if (size + offset < size ||
size + offset > fbo->base.size) {
- DRM_ERROR("Overflow in %dx%d (%dx%d) fbo size (%d + %d > %zd)\n",
+ DRM_DEBUG("Overflow in %dx%d (%dx%d) fbo size (%d + %d > %zd)\n",
width, height,
aligned_width, aligned_height,
size, offset, fbo->base.size);
@@ -214,7 +214,7 @@ static int
validate_flush(VALIDATE_ARGS)
{
if (!validate_bin_pos(exec, untrusted, exec->args->bin_cl_size - 1)) {
- DRM_ERROR("Bin CL must end with VC4_PACKET_FLUSH\n");
+ DRM_DEBUG("Bin CL must end with VC4_PACKET_FLUSH\n");
return -EINVAL;
}
exec->found_flush = true;
@@ -226,13 +226,13 @@ static int
validate_start_tile_binning(VALIDATE_ARGS)
{
if (exec->found_start_tile_binning_packet) {
- DRM_ERROR("Duplicate VC4_PACKET_START_TILE_BINNING\n");
+ DRM_DEBUG("Duplicate VC4_PACKET_START_TILE_BINNING\n");
return -EINVAL;
}
exec->found_start_tile_binning_packet = true;
if (!exec->found_tile_binning_mode_config_packet) {
- DRM_ERROR("missing VC4_PACKET_TILE_BINNING_MODE_CONFIG\n");
+ DRM_DEBUG("missing VC4_PACKET_TILE_BINNING_MODE_CONFIG\n");
return -EINVAL;
}
@@ -243,7 +243,7 @@ static int
validate_increment_semaphore(VALIDATE_ARGS)
{
if (!validate_bin_pos(exec, untrusted, exec->args->bin_cl_size - 2)) {
- DRM_ERROR("Bin CL must end with "
+ DRM_DEBUG("Bin CL must end with "
"VC4_PACKET_INCREMENT_SEMAPHORE\n");
return -EINVAL;
}
@@ -264,7 +264,7 @@ validate_indexed_prim_list(VALIDATE_ARGS)
/* Check overflow condition */
if (exec->shader_state_count == 0) {
- DRM_ERROR("shader state must precede primitives\n");
+ DRM_DEBUG("shader state must precede primitives\n");
return -EINVAL;
}
shader_state = &exec->shader_state[exec->shader_state_count - 1];
@@ -281,7 +281,7 @@ validate_indexed_prim_list(VALIDATE_ARGS)
if (offset > ib->base.size ||
(ib->base.size - offset) / index_size < length) {
- DRM_ERROR("IB access overflow (%d + %d*%d > %zd)\n",
+ DRM_DEBUG("IB access overflow (%d + %d*%d > %zd)\n",
offset, length, index_size, ib->base.size);
return -EINVAL;
}
@@ -301,13 +301,13 @@ validate_gl_array_primitive(VALIDATE_ARGS)
/* Check overflow condition */
if (exec->shader_state_count == 0) {
- DRM_ERROR("shader state must precede primitives\n");
+ DRM_DEBUG("shader state must precede primitives\n");
return -EINVAL;
}
shader_state = &exec->shader_state[exec->shader_state_count - 1];
if (length + base_index < length) {
- DRM_ERROR("primitive vertex count overflow\n");
+ DRM_DEBUG("primitive vertex count overflow\n");
return -EINVAL;
}
max_index = length + base_index - 1;
@@ -324,7 +324,7 @@ validate_gl_shader_state(VALIDATE_ARGS)
uint32_t i = exec->shader_state_count++;
if (i >= exec->shader_state_size) {
- DRM_ERROR("More requests for shader states than declared\n");
+ DRM_DEBUG("More requests for shader states than declared\n");
return -EINVAL;
}
@@ -332,7 +332,7 @@ validate_gl_shader_state(VALIDATE_ARGS)
exec->shader_state[i].max_index = 0;
if (exec->shader_state[i].addr & ~0xf) {
- DRM_ERROR("high bits set in GL shader rec reference\n");
+ DRM_DEBUG("high bits set in GL shader rec reference\n");
return -EINVAL;
}
@@ -356,7 +356,7 @@ validate_tile_binning_config(VALIDATE_ARGS)
int bin_slot;
if (exec->found_tile_binning_mode_config_packet) {
- DRM_ERROR("Duplicate VC4_PACKET_TILE_BINNING_MODE_CONFIG\n");
+ DRM_DEBUG("Duplicate VC4_PACKET_TILE_BINNING_MODE_CONFIG\n");
return -EINVAL;
}
exec->found_tile_binning_mode_config_packet = true;
@@ -368,14 +368,14 @@ validate_tile_binning_config(VALIDATE_ARGS)
if (exec->bin_tiles_x == 0 ||
exec->bin_tiles_y == 0) {
- DRM_ERROR("Tile binning config of %dx%d too small\n",
+ DRM_DEBUG("Tile binning config of %dx%d too small\n",
exec->bin_tiles_x, exec->bin_tiles_y);
return -EINVAL;
}
if (flags & (VC4_BIN_CONFIG_DB_NON_MS |
VC4_BIN_CONFIG_TILE_BUFFER_64BIT)) {
- DRM_ERROR("unsupported binning config flags 0x%02x\n", flags);
+ DRM_DEBUG("unsupported binning config flags 0x%02x\n", flags);
return -EINVAL;
}
@@ -493,20 +493,20 @@ vc4_validate_bin_cl(struct drm_device *dev,
const struct cmd_info *info;
if (cmd >= ARRAY_SIZE(cmd_info)) {
- DRM_ERROR("0x%08x: packet %d out of bounds\n",
+ DRM_DEBUG("0x%08x: packet %d out of bounds\n",
src_offset, cmd);
return -EINVAL;
}
info = &cmd_info[cmd];
if (!info->name) {
- DRM_ERROR("0x%08x: packet %d invalid\n",
+ DRM_DEBUG("0x%08x: packet %d invalid\n",
src_offset, cmd);
return -EINVAL;
}
if (src_offset + info->len > len) {
- DRM_ERROR("0x%08x: packet %d (%s) length 0x%08x "
+ DRM_DEBUG("0x%08x: packet %d (%s) length 0x%08x "
"exceeds bounds (0x%08x)\n",
src_offset, cmd, info->name, info->len,
src_offset + len);
@@ -519,7 +519,7 @@ vc4_validate_bin_cl(struct drm_device *dev,
if (info->func && info->func(exec,
dst_pkt + 1,
src_pkt + 1)) {
- DRM_ERROR("0x%08x: packet %d (%s) failed to validate\n",
+ DRM_DEBUG("0x%08x: packet %d (%s) failed to validate\n",
src_offset, cmd, info->name);
return -EINVAL;
}
@@ -537,7 +537,7 @@ vc4_validate_bin_cl(struct drm_device *dev,
exec->ct0ea = exec->ct0ca + dst_offset;
if (!exec->found_start_tile_binning_packet) {
- DRM_ERROR("Bin CL missing VC4_PACKET_START_TILE_BINNING\n");
+ DRM_DEBUG("Bin CL missing VC4_PACKET_START_TILE_BINNING\n");
return -EINVAL;
}
@@ -549,7 +549,7 @@ vc4_validate_bin_cl(struct drm_device *dev,
* semaphore increment.
*/
if (!exec->found_increment_semaphore_packet || !exec->found_flush) {
- DRM_ERROR("Bin CL missing VC4_PACKET_INCREMENT_SEMAPHORE + "
+ DRM_DEBUG("Bin CL missing VC4_PACKET_INCREMENT_SEMAPHORE + "
"VC4_PACKET_FLUSH\n");
return -EINVAL;
}
@@ -588,11 +588,11 @@ reloc_tex(struct vc4_exec_info *exec,
uint32_t remaining_size = tex->base.size - p0;
if (p0 > tex->base.size - 4) {
- DRM_ERROR("UBO offset greater than UBO size\n");
+ DRM_DEBUG("UBO offset greater than UBO size\n");
goto fail;
}
if (p1 > remaining_size - 4) {
- DRM_ERROR("UBO clamp would allow reads "
+ DRM_DEBUG("UBO clamp would allow reads "
"outside of UBO\n");
goto fail;
}
@@ -612,14 +612,14 @@ reloc_tex(struct vc4_exec_info *exec,
if (VC4_GET_FIELD(p3, VC4_TEX_P2_PTYPE) ==
VC4_TEX_P2_PTYPE_CUBE_MAP_STRIDE) {
if (cube_map_stride) {
- DRM_ERROR("Cube map stride set twice\n");
+ DRM_DEBUG("Cube map stride set twice\n");
goto fail;
}
cube_map_stride = p3 & VC4_TEX_P2_CMST_MASK;
}
if (!cube_map_stride) {
- DRM_ERROR("Cube map stride not set\n");
+ DRM_DEBUG("Cube map stride not set\n");
goto fail;
}
}
@@ -660,7 +660,7 @@ reloc_tex(struct vc4_exec_info *exec,
case VC4_TEXTURE_TYPE_RGBA64:
case VC4_TEXTURE_TYPE_YUV422R:
default:
- DRM_ERROR("Texture format %d unsupported\n", type);
+ DRM_DEBUG("Texture format %d unsupported\n", type);
goto fail;
}
utile_w = utile_width(cpp);
@@ -713,7 +713,7 @@ reloc_tex(struct vc4_exec_info *exec,
level_size = aligned_width * cpp * aligned_height;
if (offset < level_size) {
- DRM_ERROR("Level %d (%dx%d -> %dx%d) size %db "
+ DRM_DEBUG("Level %d (%dx%d -> %dx%d) size %db "
"overflowed buffer bounds (offset %d)\n",
i, level_width, level_height,
aligned_width, aligned_height,
@@ -764,7 +764,7 @@ validate_gl_shader_rec(struct drm_device *dev,
nr_relocs = ARRAY_SIZE(shader_reloc_offsets) + nr_attributes;
if (nr_relocs * 4 > exec->shader_rec_size) {
- DRM_ERROR("overflowed shader recs reading %d handles "
+ DRM_DEBUG("overflowed shader recs reading %d handles "
"from %d bytes left\n",
nr_relocs, exec->shader_rec_size);
return -EINVAL;
@@ -774,7 +774,7 @@ validate_gl_shader_rec(struct drm_device *dev,
exec->shader_rec_size -= nr_relocs * 4;
if (packet_size > exec->shader_rec_size) {
- DRM_ERROR("overflowed shader recs copying %db packet "
+ DRM_DEBUG("overflowed shader recs copying %db packet "
"from %d bytes left\n",
packet_size, exec->shader_rec_size);
return -EINVAL;
@@ -794,7 +794,7 @@ validate_gl_shader_rec(struct drm_device *dev,
for (i = 0; i < shader_reloc_count; i++) {
if (src_handles[i] > exec->bo_count) {
- DRM_ERROR("Shader handle %d too big\n", src_handles[i]);
+ DRM_DEBUG("Shader handle %d too big\n", src_handles[i]);
return -EINVAL;
}
@@ -810,13 +810,13 @@ validate_gl_shader_rec(struct drm_device *dev,
if (((*(uint16_t *)pkt_u & VC4_SHADER_FLAG_FS_SINGLE_THREAD) == 0) !=
to_vc4_bo(&bo[0]->base)->validated_shader->is_threaded) {
- DRM_ERROR("Thread mode of CL and FS do not match\n");
+ DRM_DEBUG("Thread mode of CL and FS do not match\n");
return -EINVAL;
}
if (to_vc4_bo(&bo[1]->base)->validated_shader->is_threaded ||
to_vc4_bo(&bo[2]->base)->validated_shader->is_threaded) {
- DRM_ERROR("cs and vs cannot be threaded\n");
+ DRM_DEBUG("cs and vs cannot be threaded\n");
return -EINVAL;
}
@@ -831,7 +831,7 @@ validate_gl_shader_rec(struct drm_device *dev,
*(uint32_t *)(pkt_v + o) = bo[i]->paddr + src_offset;
if (src_offset != 0) {
- DRM_ERROR("Shaders must be at offset 0 of "
+ DRM_DEBUG("Shaders must be at offset 0 of "
"the BO.\n");
return -EINVAL;
}
@@ -842,7 +842,7 @@ validate_gl_shader_rec(struct drm_device *dev,
if (validated_shader->uniforms_src_size >
exec->uniforms_size) {
- DRM_ERROR("Uniforms src buffer overflow\n");
+ DRM_DEBUG("Uniforms src buffer overflow\n");
return -EINVAL;
}
@@ -900,7 +900,7 @@ validate_gl_shader_rec(struct drm_device *dev,
if (vbo->base.size < offset ||
vbo->base.size - offset < attr_size) {
- DRM_ERROR("BO offset overflow (%d + %d > %zu)\n",
+ DRM_DEBUG("BO offset overflow (%d + %d > %zu)\n",
offset, attr_size, vbo->base.size);
return -EINVAL;
}
@@ -909,7 +909,7 @@ validate_gl_shader_rec(struct drm_device *dev,
max_index = ((vbo->base.size - offset - attr_size) /
stride);
if (state->max_index > max_index) {
- DRM_ERROR("primitives use index %d out of "
+ DRM_DEBUG("primitives use index %d out of "
"supplied %d\n",
state->max_index, max_index);
return -EINVAL;
diff --git a/drivers/gpu/drm/vc4/vc4_validate_shaders.c b/drivers/gpu/drm/vc4/vc4_validate_shaders.c
index 0b2df5c6efb4..d3f15bf60900 100644
--- a/drivers/gpu/drm/vc4/vc4_validate_shaders.c
+++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c
@@ -200,7 +200,7 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader,
uint32_t clamp_reg, clamp_offset;
if (sig == QPU_SIG_SMALL_IMM) {
- DRM_ERROR("direct TMU read used small immediate\n");
+ DRM_DEBUG("direct TMU read used small immediate\n");
return false;
}
@@ -209,7 +209,7 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader,
*/
if (is_mul ||
QPU_GET_FIELD(inst, QPU_OP_ADD) != QPU_A_ADD) {
- DRM_ERROR("direct TMU load wasn't an add\n");
+ DRM_DEBUG("direct TMU load wasn't an add\n");
return false;
}
@@ -220,13 +220,13 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader,
*/
clamp_reg = raddr_add_a_to_live_reg_index(inst);
if (clamp_reg == ~0) {
- DRM_ERROR("direct TMU load wasn't clamped\n");
+ DRM_DEBUG("direct TMU load wasn't clamped\n");
return false;
}
clamp_offset = validation_state->live_min_clamp_offsets[clamp_reg];
if (clamp_offset == ~0) {
- DRM_ERROR("direct TMU load wasn't clamped\n");
+ DRM_DEBUG("direct TMU load wasn't clamped\n");
return false;
}
@@ -238,7 +238,7 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader,
if (!(add_b == QPU_MUX_A && raddr_a == QPU_R_UNIF) &&
!(add_b == QPU_MUX_B && raddr_b == QPU_R_UNIF)) {
- DRM_ERROR("direct TMU load didn't add to a uniform\n");
+ DRM_DEBUG("direct TMU load didn't add to a uniform\n");
return false;
}
@@ -246,14 +246,14 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader,
} else {
if (raddr_a == QPU_R_UNIF || (sig != QPU_SIG_SMALL_IMM &&
raddr_b == QPU_R_UNIF)) {
- DRM_ERROR("uniform read in the same instruction as "
+ DRM_DEBUG("uniform read in the same instruction as "
"texture setup.\n");
return false;
}
}
if (validation_state->tmu_write_count[tmu] >= 4) {
- DRM_ERROR("TMU%d got too many parameters before dispatch\n",
+ DRM_DEBUG("TMU%d got too many parameters before dispatch\n",
tmu);
return false;
}
@@ -265,7 +265,7 @@ check_tmu_write(struct vc4_validated_shader_info *validated_shader,
*/
if (!is_direct) {
if (validation_state->needs_uniform_address_update) {
- DRM_ERROR("Texturing with undefined uniform address\n");
+ DRM_DEBUG("Texturing with undefined uniform address\n");
return false;
}
@@ -336,35 +336,35 @@ validate_uniform_address_write(struct vc4_validated_shader_info *validated_shade
case QPU_SIG_LOAD_TMU1:
break;
default:
- DRM_ERROR("uniforms address change must be "
+ DRM_DEBUG("uniforms address change must be "
"normal math\n");
return false;
}
if (is_mul || QPU_GET_FIELD(inst, QPU_OP_ADD) != QPU_A_ADD) {
- DRM_ERROR("Uniform address reset must be an ADD.\n");
+ DRM_DEBUG("Uniform address reset must be an ADD.\n");
return false;
}
if (QPU_GET_FIELD(inst, QPU_COND_ADD) != QPU_COND_ALWAYS) {
- DRM_ERROR("Uniform address reset must be unconditional.\n");
+ DRM_DEBUG("Uniform address reset must be unconditional.\n");
return false;
}
if (QPU_GET_FIELD(inst, QPU_PACK) != QPU_PACK_A_NOP &&
!(inst & QPU_PM)) {
- DRM_ERROR("No packing allowed on uniforms reset\n");
+ DRM_DEBUG("No packing allowed on uniforms reset\n");
return false;
}
if (add_lri == -1) {
- DRM_ERROR("First argument of uniform address write must be "
+ DRM_DEBUG("First argument of uniform address write must be "
"an immediate value.\n");
return false;
}
if (validation_state->live_immediates[add_lri] != expected_offset) {
- DRM_ERROR("Resetting uniforms with offset %db instead of %db\n",
+ DRM_DEBUG("Resetting uniforms with offset %db instead of %db\n",
validation_state->live_immediates[add_lri],
expected_offset);
return false;
@@ -372,7 +372,7 @@ validate_uniform_address_write(struct vc4_validated_shader_info *validated_shade
if (!(add_b == QPU_MUX_A && raddr_a == QPU_R_UNIF) &&
!(add_b == QPU_MUX_B && raddr_b == QPU_R_UNIF)) {
- DRM_ERROR("Second argument of uniform address write must be "
+ DRM_DEBUG("Second argument of uniform address write must be "
"a uniform.\n");
return false;
}
@@ -417,7 +417,7 @@ check_reg_write(struct vc4_validated_shader_info *validated_shader,
switch (waddr) {
case QPU_W_UNIFORMS_ADDRESS:
if (is_b) {
- DRM_ERROR("relative uniforms address change "
+ DRM_DEBUG("relative uniforms address change "
"unsupported\n");
return false;
}
@@ -452,11 +452,11 @@ check_reg_write(struct vc4_validated_shader_info *validated_shader,
/* XXX: I haven't thought about these, so don't support them
* for now.
*/
- DRM_ERROR("Unsupported waddr %d\n", waddr);
+ DRM_DEBUG("Unsupported waddr %d\n", waddr);
return false;
case QPU_W_VPM_ADDR:
- DRM_ERROR("General VPM DMA unsupported\n");
+ DRM_DEBUG("General VPM DMA unsupported\n");
return false;
case QPU_W_VPM:
@@ -559,7 +559,7 @@ check_instruction_writes(struct vc4_validated_shader_info *validated_shader,
bool ok;
if (is_tmu_write(waddr_add) && is_tmu_write(waddr_mul)) {
- DRM_ERROR("ADD and MUL both set up textures\n");
+ DRM_DEBUG("ADD and MUL both set up textures\n");
return false;
}
@@ -588,7 +588,7 @@ check_branch(uint64_t inst,
* there's no need for it.
*/
if (waddr_add != QPU_W_NOP || waddr_mul != QPU_W_NOP) {
- DRM_ERROR("branch instruction at %d wrote a register.\n",
+ DRM_DEBUG("branch instruction at %d wrote a register.\n",
validation_state->ip);
return false;
}
@@ -614,7 +614,7 @@ check_instruction_reads(struct vc4_validated_shader_info *validated_shader,
validated_shader->uniforms_size += 4;
if (validation_state->needs_uniform_address_update) {
- DRM_ERROR("Uniform read with undefined uniform "
+ DRM_DEBUG("Uniform read with undefined uniform "
"address\n");
return false;
}
@@ -660,19 +660,19 @@ vc4_validate_branches(struct vc4_shader_validation_state *validation_state)
continue;
if (ip - last_branch < 4) {
- DRM_ERROR("Branch at %d during delay slots\n", ip);
+ DRM_DEBUG("Branch at %d during delay slots\n", ip);
return false;
}
last_branch = ip;
if (inst & QPU_BRANCH_REG) {
- DRM_ERROR("branching from register relative "
+ DRM_DEBUG("branching from register relative "
"not supported\n");
return false;
}
if (!(inst & QPU_BRANCH_REL)) {
- DRM_ERROR("relative branching required\n");
+ DRM_DEBUG("relative branching required\n");
return false;
}
@@ -682,13 +682,13 @@ vc4_validate_branches(struct vc4_shader_validation_state *validation_state)
* end of the shader object.
*/
if (branch_imm % sizeof(inst) != 0) {
- DRM_ERROR("branch target not aligned\n");
+ DRM_DEBUG("branch target not aligned\n");
return false;
}
branch_target_ip = after_delay_ip + (branch_imm >> 3);
if (branch_target_ip >= validation_state->max_ip) {
- DRM_ERROR("Branch at %d outside of shader (ip %d/%d)\n",
+ DRM_DEBUG("Branch at %d outside of shader (ip %d/%d)\n",
ip, branch_target_ip,
validation_state->max_ip);
return false;
@@ -699,7 +699,7 @@ vc4_validate_branches(struct vc4_shader_validation_state *validation_state)
* the shader.
*/
if (after_delay_ip >= validation_state->max_ip) {
- DRM_ERROR("Branch at %d continues past shader end "
+ DRM_DEBUG("Branch at %d continues past shader end "
"(%d/%d)\n",
ip, after_delay_ip, validation_state->max_ip);
return false;
@@ -709,7 +709,7 @@ vc4_validate_branches(struct vc4_shader_validation_state *validation_state)
}
if (max_branch_target > validation_state->max_ip - 3) {
- DRM_ERROR("Branch landed after QPU_SIG_PROG_END");
+ DRM_DEBUG("Branch landed after QPU_SIG_PROG_END");
return false;
}
@@ -750,7 +750,7 @@ vc4_handle_branch_target(struct vc4_shader_validation_state *validation_state)
return true;
if (texturing_in_progress(validation_state)) {
- DRM_ERROR("Branch target landed during TMU setup\n");
+ DRM_DEBUG("Branch target landed during TMU setup\n");
return false;
}
@@ -837,7 +837,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
case QPU_SIG_LAST_THREAD_SWITCH:
if (!check_instruction_writes(validated_shader,
&validation_state)) {
- DRM_ERROR("Bad write at ip %d\n", ip);
+ DRM_DEBUG("Bad write at ip %d\n", ip);
goto fail;
}
@@ -855,7 +855,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
validated_shader->is_threaded = true;
if (ip < last_thread_switch_ip + 3) {
- DRM_ERROR("Thread switch too soon after "
+ DRM_DEBUG("Thread switch too soon after "
"last switch at ip %d\n", ip);
goto fail;
}
@@ -867,7 +867,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
case QPU_SIG_LOAD_IMM:
if (!check_instruction_writes(validated_shader,
&validation_state)) {
- DRM_ERROR("Bad LOAD_IMM write at ip %d\n", ip);
+ DRM_DEBUG("Bad LOAD_IMM write at ip %d\n", ip);
goto fail;
}
break;
@@ -878,14 +878,14 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
goto fail;
if (ip < last_thread_switch_ip + 3) {
- DRM_ERROR("Branch in thread switch at ip %d",
+ DRM_DEBUG("Branch in thread switch at ip %d",
ip);
goto fail;
}
break;
default:
- DRM_ERROR("Unsupported QPU signal %d at "
+ DRM_DEBUG("Unsupported QPU signal %d at "
"instruction %d\n", sig, ip);
goto fail;
}
@@ -898,7 +898,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
}
if (ip == validation_state.max_ip) {
- DRM_ERROR("shader failed to terminate before "
+ DRM_DEBUG("shader failed to terminate before "
"shader BO end at %zd\n",
shader_obj->base.size);
goto fail;
@@ -907,7 +907,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
/* Might corrupt other thread */
if (validated_shader->is_threaded &&
validation_state.all_registers_used) {
- DRM_ERROR("Shader uses threading, but uses the upper "
+ DRM_DEBUG("Shader uses threading, but uses the upper "
"half of the registers, too\n");
goto fail;
}
diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 09c1e05765fa..3a9a302247a2 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -366,10 +366,8 @@ static int vc4_vec_connector_get_modes(struct drm_connector *connector)
}
static const struct drm_connector_funcs vc4_vec_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = vc4_vec_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
- .set_property = drm_atomic_helper_connector_set_property,
.destroy = vc4_vec_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
index 18f401b442c2..2524ff116f00 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.c
+++ b/drivers/gpu/drm/vgem/vgem_drv.c
@@ -52,6 +52,7 @@ static void vgem_gem_free_object(struct drm_gem_object *obj)
struct drm_vgem_gem_object *vgem_obj = to_vgem_bo(obj);
kvfree(vgem_obj->pages);
+ mutex_destroy(&vgem_obj->pages_lock);
if (obj->import_attach)
drm_prime_gem_destroy(obj, vgem_obj->table);
@@ -76,11 +77,15 @@ static int vgem_gem_fault(struct vm_fault *vmf)
if (page_offset > num_pages)
return VM_FAULT_SIGBUS;
+ ret = -ENOENT;
+ mutex_lock(&obj->pages_lock);
if (obj->pages) {
get_page(obj->pages[page_offset]);
vmf->page = obj->pages[page_offset];
ret = 0;
- } else {
+ }
+ mutex_unlock(&obj->pages_lock);
+ if (ret) {
struct page *page;
page = shmem_read_mapping_page(
@@ -161,6 +166,8 @@ static struct drm_vgem_gem_object *__vgem_gem_create(struct drm_device *dev,
return ERR_PTR(ret);
}
+ mutex_init(&obj->pages_lock);
+
return obj;
}
@@ -183,7 +190,7 @@ static struct drm_gem_object *vgem_gem_create(struct drm_device *dev,
return ERR_CAST(obj);
ret = drm_gem_handle_create(file, &obj->base, handle);
- drm_gem_object_unreference_unlocked(&obj->base);
+ drm_gem_object_put_unlocked(&obj->base);
if (ret)
goto err;
@@ -238,7 +245,7 @@ static int vgem_gem_dumb_map(struct drm_file *file, struct drm_device *dev,
*offset = drm_vma_node_offset_addr(&obj->vma_node);
unref:
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
@@ -271,40 +278,70 @@ static const struct file_operations vgem_driver_fops = {
.poll = drm_poll,
.read = drm_read,
.unlocked_ioctl = drm_ioctl,
+ .compat_ioctl = drm_compat_ioctl,
.release = drm_release,
};
+static struct page **vgem_pin_pages(struct drm_vgem_gem_object *bo)
+{
+ mutex_lock(&bo->pages_lock);
+ if (bo->pages_pin_count++ == 0) {
+ struct page **pages;
+
+ pages = drm_gem_get_pages(&bo->base);
+ if (IS_ERR(pages)) {
+ bo->pages_pin_count--;
+ mutex_unlock(&bo->pages_lock);
+ return pages;
+ }
+
+ bo->pages = pages;
+ }
+ mutex_unlock(&bo->pages_lock);
+
+ return bo->pages;
+}
+
+static void vgem_unpin_pages(struct drm_vgem_gem_object *bo)
+{
+ mutex_lock(&bo->pages_lock);
+ if (--bo->pages_pin_count == 0) {
+ drm_gem_put_pages(&bo->base, bo->pages, true, true);
+ bo->pages = NULL;
+ }
+ mutex_unlock(&bo->pages_lock);
+}
+
static int vgem_prime_pin(struct drm_gem_object *obj)
{
+ struct drm_vgem_gem_object *bo = to_vgem_bo(obj);
long n_pages = obj->size >> PAGE_SHIFT;
struct page **pages;
- /* Flush the object from the CPU cache so that importers can rely
- * on coherent indirect access via the exported dma-address.
- */
- pages = drm_gem_get_pages(obj);
+ pages = vgem_pin_pages(bo);
if (IS_ERR(pages))
return PTR_ERR(pages);
+ /* Flush the object from the CPU cache so that importers can rely
+ * on coherent indirect access via the exported dma-address.
+ */
drm_clflush_pages(pages, n_pages);
- drm_gem_put_pages(obj, pages, true, false);
return 0;
}
-static struct sg_table *vgem_prime_get_sg_table(struct drm_gem_object *obj)
+static void vgem_prime_unpin(struct drm_gem_object *obj)
{
- struct sg_table *st;
- struct page **pages;
+ struct drm_vgem_gem_object *bo = to_vgem_bo(obj);
- pages = drm_gem_get_pages(obj);
- if (IS_ERR(pages))
- return ERR_CAST(pages);
+ vgem_unpin_pages(bo);
+}
- st = drm_prime_pages_to_sg(pages, obj->size >> PAGE_SHIFT);
- drm_gem_put_pages(obj, pages, false, false);
+static struct sg_table *vgem_prime_get_sg_table(struct drm_gem_object *obj)
+{
+ struct drm_vgem_gem_object *bo = to_vgem_bo(obj);
- return st;
+ return drm_prime_pages_to_sg(bo->pages, bo->base.size >> PAGE_SHIFT);
}
static struct drm_gem_object* vgem_prime_import(struct drm_device *dev,
@@ -333,6 +370,8 @@ static struct drm_gem_object *vgem_prime_import_sg_table(struct drm_device *dev,
__vgem_gem_destroy(obj);
return ERR_PTR(-ENOMEM);
}
+
+ obj->pages_pin_count++; /* perma-pinned */
drm_prime_sg_to_page_addr_arrays(obj->table, obj->pages, NULL,
npages);
return &obj->base;
@@ -340,23 +379,23 @@ static struct drm_gem_object *vgem_prime_import_sg_table(struct drm_device *dev,
static void *vgem_prime_vmap(struct drm_gem_object *obj)
{
+ struct drm_vgem_gem_object *bo = to_vgem_bo(obj);
long n_pages = obj->size >> PAGE_SHIFT;
struct page **pages;
- void *addr;
- pages = drm_gem_get_pages(obj);
+ pages = vgem_pin_pages(bo);
if (IS_ERR(pages))
return NULL;
- addr = vmap(pages, n_pages, 0, pgprot_writecombine(PAGE_KERNEL));
- drm_gem_put_pages(obj, pages, false, false);
-
- return addr;
+ return vmap(pages, n_pages, 0, pgprot_writecombine(PAGE_KERNEL));
}
static void vgem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
{
+ struct drm_vgem_gem_object *bo = to_vgem_bo(obj);
+
vunmap(vaddr);
+ vgem_unpin_pages(bo);
}
static int vgem_prime_mmap(struct drm_gem_object *obj,
@@ -409,6 +448,7 @@ static struct drm_driver vgem_driver = {
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_pin = vgem_prime_pin,
+ .gem_prime_unpin = vgem_prime_unpin,
.gem_prime_import = vgem_prime_import,
.gem_prime_export = drm_gem_prime_export,
.gem_prime_import_sg_table = vgem_prime_import_sg_table,
diff --git a/drivers/gpu/drm/vgem/vgem_drv.h b/drivers/gpu/drm/vgem/vgem_drv.h
index 1aae01419112..5c8f6d619ff3 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.h
+++ b/drivers/gpu/drm/vgem/vgem_drv.h
@@ -43,7 +43,11 @@ struct vgem_file {
#define to_vgem_bo(x) container_of(x, struct drm_vgem_gem_object, base)
struct drm_vgem_gem_object {
struct drm_gem_object base;
+
struct page **pages;
+ unsigned int pages_pin_count;
+ struct mutex pages_lock;
+
struct sg_table *table;
};
diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c
index 3109c8308eb5..8fd52f211e9d 100644
--- a/drivers/gpu/drm/vgem/vgem_fence.c
+++ b/drivers/gpu/drm/vgem/vgem_fence.c
@@ -213,7 +213,7 @@ err_fence:
dma_fence_put(fence);
}
err:
- drm_gem_object_unreference_unlocked(obj);
+ drm_gem_object_put_unlocked(obj);
return ret;
}
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c
index 9e0e5392b6ec..aaf766f7cca2 100644
--- a/drivers/gpu/drm/via/via_drv.c
+++ b/drivers/gpu/drm/via/via_drv.c
@@ -77,7 +77,6 @@ static struct drm_driver driver = {
.open = via_driver_open,
.preclose = via_reclaim_buffers_locked,
.postclose = via_driver_postclose,
- .set_busid = drm_pci_set_busid,
.context_dtor = via_final_context,
.get_vblank_counter = via_get_vblank_counter,
.enable_vblank = via_enable_vblank,
@@ -107,12 +106,12 @@ static int __init via_init(void)
{
driver.num_ioctls = via_max_ioctl;
via_init_command_verifier();
- return drm_pci_init(&driver, &via_pci_driver);
+ return drm_legacy_pci_init(&driver, &via_pci_driver);
}
static void __exit via_exit(void)
{
- drm_pci_exit(&driver, &via_pci_driver);
+ drm_legacy_pci_exit(&driver, &via_pci_driver);
}
module_init(via_init);
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index d51bd4521f17..b6d52055a11f 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -113,11 +113,13 @@ static void virtio_gpu_crtc_mode_set_nofb(struct drm_crtc *crtc)
crtc->mode.vdisplay, 0, 0);
}
-static void virtio_gpu_crtc_enable(struct drm_crtc *crtc)
+static void virtio_gpu_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
}
-static void virtio_gpu_crtc_disable(struct drm_crtc *crtc)
+static void virtio_gpu_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct drm_device *dev = crtc->dev;
struct virtio_gpu_device *vgdev = dev->dev_private;
@@ -145,11 +147,11 @@ static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs virtio_gpu_crtc_helper_funcs = {
- .enable = virtio_gpu_crtc_enable,
- .disable = virtio_gpu_crtc_disable,
.mode_set_nofb = virtio_gpu_crtc_mode_set_nofb,
.atomic_check = virtio_gpu_crtc_atomic_check,
.atomic_flush = virtio_gpu_crtc_atomic_flush,
+ .atomic_enable = virtio_gpu_crtc_atomic_enable,
+ .atomic_disable = virtio_gpu_crtc_atomic_disable,
};
static void virtio_gpu_enc_mode_set(struct drm_encoder *encoder,
@@ -250,7 +252,6 @@ static void virtio_gpu_conn_destroy(struct drm_connector *connector)
}
static const struct drm_connector_funcs virtio_gpu_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.detect = virtio_gpu_conn_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = virtio_gpu_conn_destroy,
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
index 63d35c7e416c..49a3d8d5a249 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -122,7 +122,6 @@ static struct drm_driver driver = {
.dumb_create = virtio_gpu_mode_dumb_create,
.dumb_map_offset = virtio_gpu_mode_dumb_mmap,
- .dumb_destroy = virtio_gpu_mode_dumb_destroy,
#if defined(CONFIG_DEBUG_FS)
.debugfs_init = virtio_gpu_debugfs_init,
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 3a66abb8fd50..da2fb585fea4 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -236,9 +236,6 @@ struct virtio_gpu_object *virtio_gpu_alloc_object(struct drm_device *dev,
int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
-int virtio_gpu_mode_dumb_destroy(struct drm_file *file_priv,
- struct drm_device *dev,
- uint32_t handle);
int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv,
struct drm_device *dev,
uint32_t handle, uint64_t *offset_p);
diff --git a/drivers/gpu/drm/virtio/virtgpu_fb.c b/drivers/gpu/drm/virtio/virtgpu_fb.c
index 33df067b11c1..15d18fd0c64b 100644
--- a/drivers/gpu/drm/virtio/virtgpu_fb.c
+++ b/drivers/gpu/drm/virtio/virtgpu_fb.c
@@ -273,7 +273,6 @@ static int virtio_gpufb_create(struct drm_fb_helper *helper,
vfbdev->helper.fb = fb;
strcpy(info->fix.id, "virtiodrmfb");
- info->flags = FBINFO_DEFAULT;
info->fbops = &virtio_gpufb_ops;
info->pixmap.flags = FB_PIXMAP_SYSTEM;
@@ -309,7 +308,7 @@ static int virtio_gpu_fbdev_destroy(struct drm_device *dev,
return 0;
}
-static struct drm_fb_helper_funcs virtio_gpu_fb_helper_funcs = {
+static const struct drm_fb_helper_funcs virtio_gpu_fb_helper_funcs = {
.fb_probe = virtio_gpufb_create,
};
diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c
index cc025d8fbe19..72ad7b103448 100644
--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
+++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
@@ -118,13 +118,6 @@ fail:
return ret;
}
-int virtio_gpu_mode_dumb_destroy(struct drm_file *file_priv,
- struct drm_device *dev,
- uint32_t handle)
-{
- return drm_gem_handle_delete(file_priv, handle);
-}
-
int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv,
struct drm_device *dev,
uint32_t handle, uint64_t *offset_p)
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c
index adcdbd0abef6..71ba455af915 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -298,7 +298,7 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev,
ret = drm_universal_plane_init(dev, plane, 1 << index,
&virtio_gpu_plane_funcs,
formats, nformats,
- type, NULL);
+ NULL, type, NULL);
if (ret)
goto err_plane_init;
diff --git a/drivers/gpu/drm/virtio/virtgpu_ttm.c b/drivers/gpu/drm/virtio/virtgpu_ttm.c
index c1f2af4ca4ca..cd389c5eaef5 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ttm.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ttm.c
@@ -192,7 +192,7 @@ static int ttm_bo_man_takedown(struct ttm_mem_type_manager *man)
}
static void ttm_bo_man_debug(struct ttm_mem_type_manager *man,
- const char *prefix)
+ struct drm_printer *printer)
{
}
@@ -234,7 +234,7 @@ static int virtio_gpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
static void virtio_gpu_evict_flags(struct ttm_buffer_object *bo,
struct ttm_placement *placement)
{
- static struct ttm_place placements = {
+ static const struct ttm_place placements = {
.fpfn = 0,
.lpfn = 0,
.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
index 35bf781e418e..c7056322211c 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
@@ -30,49 +30,49 @@
#include <drm/ttm/ttm_placement.h>
#include <drm/ttm/ttm_page_alloc.h>
-static struct ttm_place vram_placement_flags = {
+static const struct ttm_place vram_placement_flags = {
.fpfn = 0,
.lpfn = 0,
.flags = TTM_PL_FLAG_VRAM | TTM_PL_FLAG_CACHED
};
-static struct ttm_place vram_ne_placement_flags = {
+static const struct ttm_place vram_ne_placement_flags = {
.fpfn = 0,
.lpfn = 0,
.flags = TTM_PL_FLAG_VRAM | TTM_PL_FLAG_CACHED | TTM_PL_FLAG_NO_EVICT
};
-static struct ttm_place sys_placement_flags = {
+static const struct ttm_place sys_placement_flags = {
.fpfn = 0,
.lpfn = 0,
.flags = TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED
};
-static struct ttm_place sys_ne_placement_flags = {
+static const struct ttm_place sys_ne_placement_flags = {
.fpfn = 0,
.lpfn = 0,
.flags = TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED | TTM_PL_FLAG_NO_EVICT
};
-static struct ttm_place gmr_placement_flags = {
+static const struct ttm_place gmr_placement_flags = {
.fpfn = 0,
.lpfn = 0,
.flags = VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED
};
-static struct ttm_place gmr_ne_placement_flags = {
+static const struct ttm_place gmr_ne_placement_flags = {
.fpfn = 0,
.lpfn = 0,
.flags = VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED | TTM_PL_FLAG_NO_EVICT
};
-static struct ttm_place mob_placement_flags = {
+static const struct ttm_place mob_placement_flags = {
.fpfn = 0,
.lpfn = 0,
.flags = VMW_PL_FLAG_MOB | TTM_PL_FLAG_CACHED
};
-static struct ttm_place mob_ne_placement_flags = {
+static const struct ttm_place mob_ne_placement_flags = {
.fpfn = 0,
.lpfn = 0,
.flags = VMW_PL_FLAG_MOB | TTM_PL_FLAG_CACHED | TTM_PL_FLAG_NO_EVICT
@@ -85,7 +85,7 @@ struct ttm_placement vmw_vram_placement = {
.busy_placement = &vram_placement_flags
};
-static struct ttm_place vram_gmr_placement_flags[] = {
+static const struct ttm_place vram_gmr_placement_flags[] = {
{
.fpfn = 0,
.lpfn = 0,
@@ -97,7 +97,7 @@ static struct ttm_place vram_gmr_placement_flags[] = {
}
};
-static struct ttm_place gmr_vram_placement_flags[] = {
+static const struct ttm_place gmr_vram_placement_flags[] = {
{
.fpfn = 0,
.lpfn = 0,
@@ -116,7 +116,7 @@ struct ttm_placement vmw_vram_gmr_placement = {
.busy_placement = &gmr_placement_flags
};
-static struct ttm_place vram_gmr_ne_placement_flags[] = {
+static const struct ttm_place vram_gmr_ne_placement_flags[] = {
{
.fpfn = 0,
.lpfn = 0,
@@ -165,7 +165,7 @@ struct ttm_placement vmw_sys_ne_placement = {
.busy_placement = &sys_ne_placement_flags
};
-static struct ttm_place evictable_placement_flags[] = {
+static const struct ttm_place evictable_placement_flags[] = {
{
.fpfn = 0,
.lpfn = 0,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
index 99a7f4ab7d97..86178796de6c 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
@@ -779,8 +779,8 @@ static int vmw_cmdbuf_space_pool(struct vmw_cmdbuf_man *man,
if (ret)
return ret;
- header->cb_header = dma_pool_alloc(man->headers, GFP_KERNEL,
- &header->handle);
+ header->cb_header = dma_pool_zalloc(man->headers, GFP_KERNEL,
+ &header->handle);
if (!header->cb_header) {
ret = -ENOMEM;
goto out_no_cb_header;
@@ -790,7 +790,6 @@ static int vmw_cmdbuf_space_pool(struct vmw_cmdbuf_man *man,
cb_hdr = header->cb_header;
offset = header->node.start << PAGE_SHIFT;
header->cmd = man->map + offset;
- memset(cb_hdr, 0, sizeof(*cb_hdr));
if (man->using_mob) {
cb_hdr->flags = SVGA_CB_FLAG_MOB;
cb_hdr->ptr.mob.mobid = man->cmd_space->mem.start;
@@ -827,8 +826,8 @@ static int vmw_cmdbuf_space_inline(struct vmw_cmdbuf_man *man,
if (WARN_ON_ONCE(size > VMW_CMDBUF_INLINE_SIZE))
return -ENOMEM;
- dheader = dma_pool_alloc(man->dheaders, GFP_KERNEL,
- &header->handle);
+ dheader = dma_pool_zalloc(man->dheaders, GFP_KERNEL,
+ &header->handle);
if (!dheader)
return -ENOMEM;
@@ -837,7 +836,6 @@ static int vmw_cmdbuf_space_inline(struct vmw_cmdbuf_man *man,
cb_hdr = &dheader->cb_header;
header->cb_header = cb_hdr;
header->cmd = dheader->cmd;
- memset(dheader, 0, sizeof(*dheader));
cb_hdr->status = SVGA_CB_STATUS_NONE;
cb_hdr->flags = SVGA_CB_FLAG_NONE;
cb_hdr->ptr.pa = (u64)header->handle +
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
index 1f013d45c9e9..36c7b6c839c0 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c
@@ -205,7 +205,7 @@ int vmw_cmdbuf_res_add(struct vmw_cmdbuf_res_manager *man,
int ret;
cres = kzalloc(sizeof(*cres), GFP_KERNEL);
- if (unlikely(cres == NULL))
+ if (unlikely(!cres))
return -ENOMEM;
cres->hash.key = user_key | (res_type << 24);
@@ -291,7 +291,7 @@ vmw_cmdbuf_res_man_create(struct vmw_private *dev_priv)
int ret;
man = kzalloc(sizeof(*man), GFP_KERNEL);
- if (man == NULL)
+ if (!man)
return ERR_PTR(-ENOMEM);
man->dev_priv = dev_priv;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c
index bcc6d4136c87..4212b3e673bc 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c
@@ -210,8 +210,8 @@ static int vmw_gb_context_init(struct vmw_private *dev_priv,
for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) {
uctx->cotables[i] = vmw_cotable_alloc(dev_priv,
&uctx->res, i);
- if (unlikely(uctx->cotables[i] == NULL)) {
- ret = -ENOMEM;
+ if (unlikely(IS_ERR(uctx->cotables[i]))) {
+ ret = PTR_ERR(uctx->cotables[i]);
goto out_cotables;
}
}
@@ -777,7 +777,7 @@ static int vmw_context_define(struct drm_device *dev, void *data,
}
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (unlikely(ctx == NULL)) {
+ if (unlikely(!ctx)) {
ttm_mem_global_free(vmw_mem_glob(dev_priv),
vmw_user_context_size);
ret = -ENOMEM;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c
index 6c026d75c180..d87861bbe971 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c
@@ -584,7 +584,7 @@ struct vmw_resource *vmw_cotable_alloc(struct vmw_private *dev_priv,
return ERR_PTR(ret);
vcotbl = kzalloc(sizeof(*vcotbl), GFP_KERNEL);
- if (unlikely(vcotbl == NULL)) {
+ if (unlikely(!vcotbl)) {
ret = -ENOMEM;
goto out_no_alloc;
}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 4a641555b960..8be26509a9aa 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -227,7 +227,7 @@ static const struct drm_ioctl_desc vmw_ioctls[] = {
DRM_AUTH | DRM_RENDER_ALLOW),
};
-static struct pci_device_id vmw_pci_id_list[] = {
+static const struct pci_device_id vmw_pci_id_list[] = {
{0x15ad, 0x0405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VMWGFX_CHIP_SVGAII},
{0, 0, 0}
};
@@ -630,7 +630,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
char host_log[100] = {0};
dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
- if (unlikely(dev_priv == NULL)) {
+ if (unlikely(!dev_priv)) {
DRM_ERROR("Failed allocating a device private struct.\n");
return -ENOMEM;
}
@@ -1035,7 +1035,7 @@ static int vmw_driver_open(struct drm_device *dev, struct drm_file *file_priv)
int ret = -ENOMEM;
vmw_fp = kzalloc(sizeof(*vmw_fp), GFP_KERNEL);
- if (unlikely(vmw_fp == NULL))
+ if (unlikely(!vmw_fp))
return ret;
vmw_fp->tfile = ttm_object_file_init(dev_priv->tdev, 10);
@@ -1196,7 +1196,7 @@ static int vmw_master_create(struct drm_device *dev,
struct vmw_master *vmaster;
vmaster = kzalloc(sizeof(*vmaster), GFP_KERNEL);
- if (unlikely(vmaster == NULL))
+ if (unlikely(!vmaster))
return -ENOMEM;
vmw_master_init(vmaster);
@@ -1531,7 +1531,6 @@ static struct drm_driver driver = {
.master_drop = vmw_master_drop,
.open = vmw_driver_open,
.postclose = vmw_postclose,
- .set_busid = drm_pci_set_busid,
.dumb_create = vmw_dumb_create,
.dumb_map_offset = vmw_dumb_map_offset,
@@ -1571,7 +1570,7 @@ static int __init vmwgfx_init(void)
if (vgacon_text_force())
return -EINVAL;
- ret = drm_pci_init(&driver, &vmw_pci_driver);
+ ret = pci_register_driver(&vmw_pci_driver);
if (ret)
DRM_ERROR("Failed initializing DRM.\n");
return ret;
@@ -1579,7 +1578,7 @@ static int __init vmwgfx_init(void)
static void __exit vmwgfx_exit(void)
{
- drm_pci_exit(&driver, &vmw_pci_driver);
+ pci_unregister_driver(&vmw_pci_driver);
}
module_init(vmwgfx_init);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index c7b53d987f06..2cfb3c93f42a 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -264,7 +264,7 @@ static int vmw_resource_val_add(struct vmw_sw_context *sw_context,
}
node = kzalloc(sizeof(*node), GFP_KERNEL);
- if (unlikely(node == NULL)) {
+ if (unlikely(!node)) {
DRM_ERROR("Failed to allocate a resource validation "
"entry.\n");
return -ENOMEM;
@@ -452,7 +452,7 @@ static int vmw_resource_relocation_add(struct list_head *list,
struct vmw_resource_relocation *rel;
rel = kmalloc(sizeof(*rel), GFP_KERNEL);
- if (unlikely(rel == NULL)) {
+ if (unlikely(!rel)) {
DRM_ERROR("Failed to allocate a resource relocation.\n");
return -ENOMEM;
}
@@ -519,7 +519,7 @@ static int vmw_cmd_invalid(struct vmw_private *dev_priv,
struct vmw_sw_context *sw_context,
SVGA3dCmdHeader *header)
{
- return capable(CAP_SYS_ADMIN) ? : -EINVAL;
+ return -EINVAL;
}
static int vmw_cmd_ok(struct vmw_private *dev_priv,
@@ -2584,7 +2584,7 @@ static int vmw_cmd_dx_set_vertex_buffers(struct vmw_private *dev_priv,
/**
* vmw_cmd_dx_ia_set_vertex_buffers - Validate an
- * SVGA_3D_CMD_DX_IA_SET_VERTEX_BUFFERS command.
+ * SVGA_3D_CMD_DX_IA_SET_INDEX_BUFFER command.
*
* @dev_priv: Pointer to a device private struct.
* @sw_context: The software context being used for this batch.
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
index 6f4cb4678cbc..d23a18aae476 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
@@ -779,7 +779,6 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
info->screen_base = (char __iomem *)par->vmalloc;
info->screen_size = fb_size;
- info->flags = FBINFO_DEFAULT;
info->fbops = &vmw_fb_ops;
/* 24 depth per default */
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
index 6b2708b4eafe..b8bc5bc7de7e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
@@ -284,7 +284,7 @@ struct vmw_fence_manager *vmw_fence_manager_init(struct vmw_private *dev_priv)
{
struct vmw_fence_manager *fman = kzalloc(sizeof(*fman), GFP_KERNEL);
- if (unlikely(fman == NULL))
+ if (unlikely(!fman))
return NULL;
fman->dev_priv = dev_priv;
@@ -541,7 +541,7 @@ int vmw_fence_create(struct vmw_fence_manager *fman,
int ret;
fence = kzalloc(sizeof(*fence), GFP_KERNEL);
- if (unlikely(fence == NULL))
+ if (unlikely(!fence))
return -ENOMEM;
ret = vmw_fence_obj_init(fman, fence, seqno,
@@ -606,7 +606,7 @@ int vmw_user_fence_create(struct drm_file *file_priv,
return ret;
ufence = kzalloc(sizeof(*ufence), GFP_KERNEL);
- if (unlikely(ufence == NULL)) {
+ if (unlikely(!ufence)) {
ret = -ENOMEM;
goto out_no_object;
}
@@ -966,7 +966,7 @@ int vmw_event_fence_action_queue(struct drm_file *file_priv,
struct vmw_fence_manager *fman = fman_from_fence(fence);
eaction = kzalloc(sizeof(*eaction), GFP_KERNEL);
- if (unlikely(eaction == NULL))
+ if (unlikely(!eaction))
return -ENOMEM;
eaction->event = event;
@@ -1002,7 +1002,7 @@ static int vmw_event_fence_action_create(struct drm_file *file_priv,
int ret;
event = kzalloc(sizeof(*event), GFP_KERNEL);
- if (unlikely(event == NULL)) {
+ if (unlikely(!event)) {
DRM_ERROR("Failed to allocate an event.\n");
ret = -ENOMEM;
goto out_no_space;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
index c1900f4390a4..f2f9d88131f2 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
@@ -121,7 +121,7 @@ static int vmw_gmrid_man_init(struct ttm_mem_type_manager *man,
struct vmwgfx_gmrid_man *gman =
kzalloc(sizeof(*gman), GFP_KERNEL);
- if (unlikely(gman == NULL))
+ if (unlikely(!gman))
return -ENOMEM;
spin_lock_init(&gman->lock);
@@ -157,9 +157,9 @@ static int vmw_gmrid_man_takedown(struct ttm_mem_type_manager *man)
}
static void vmw_gmrid_man_debug(struct ttm_mem_type_manager *man,
- const char *prefix)
+ struct drm_printer *printer)
{
- pr_info("%s: No debug info available for the GMR id manager\n", prefix);
+ drm_printf(printer, "No debug info available for the GMR id manager\n");
}
const struct ttm_mem_type_manager_func vmw_gmrid_manager_func = {
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 3d94ea67a825..36dd7930bf5f 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -384,6 +384,12 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,
hotspot_x = du->hotspot_x;
hotspot_y = du->hotspot_y;
+
+ if (plane->fb) {
+ hotspot_x += plane->fb->hot_x;
+ hotspot_y += plane->fb->hot_y;
+ }
+
du->cursor_surface = vps->surf;
du->cursor_dmabuf = vps->dmabuf;
@@ -411,6 +417,9 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,
vmw_cursor_update_position(dev_priv, true,
du->cursor_x + hotspot_x,
du->cursor_y + hotspot_y);
+
+ du->core_hotspot_x = hotspot_x - du->hotspot_x;
+ du->core_hotspot_y = hotspot_y - du->hotspot_y;
} else {
DRM_ERROR("Failed to update cursor image\n");
}
@@ -1527,7 +1536,7 @@ err_out:
* RETURNS
* Zero for success or -errno
*/
-int
+static int
vmw_kms_atomic_check_modeset(struct drm_device *dev,
struct drm_atomic_state *state)
{
@@ -1536,8 +1545,7 @@ vmw_kms_atomic_check_modeset(struct drm_device *dev,
struct vmw_private *dev_priv = vmw_priv(dev);
int i;
-
- for_each_crtc_in_state(state, crtc, crtc_state, i) {
+ for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
unsigned long requested_bb_mem = 0;
if (dev_priv->active_display_unit == vmw_du_screen_target) {
@@ -1658,7 +1666,7 @@ int vmw_kms_init(struct vmw_private *dev_priv)
int vmw_kms_close(struct vmw_private *dev_priv)
{
- int ret;
+ int ret = 0;
/*
* Docs says we should take the lock before calling this function
@@ -1666,11 +1674,7 @@ int vmw_kms_close(struct vmw_private *dev_priv)
* drm_encoder_cleanup which takes the lock we deadlock.
*/
drm_mode_config_cleanup(dev_priv->dev);
- if (dev_priv->active_display_unit == vmw_du_screen_object)
- ret = vmw_kms_sou_close_display(dev_priv);
- else if (dev_priv->active_display_unit == vmw_du_screen_target)
- ret = vmw_kms_stdu_close_display(dev_priv);
- else
+ if (dev_priv->active_display_unit == vmw_du_legacy)
ret = vmw_kms_ldu_close_display(dev_priv);
return ret;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index 5f8d678ae675..ff9c8389ff21 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -390,7 +390,6 @@ int vmw_kms_update_proxy(struct vmw_resource *res,
* Screen Objects display functions - vmwgfx_scrn.c
*/
int vmw_kms_sou_init_display(struct vmw_private *dev_priv);
-int vmw_kms_sou_close_display(struct vmw_private *dev_priv);
int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
struct vmw_framebuffer *framebuffer,
struct drm_clip_rect *clips,
@@ -418,7 +417,6 @@ int vmw_kms_sou_readback(struct vmw_private *dev_priv,
* Screen Target Display Unit functions - vmwgfx_stdu.c
*/
int vmw_kms_stdu_init_display(struct vmw_private *dev_priv);
-int vmw_kms_stdu_close_display(struct vmw_private *dev_priv);
int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
struct vmw_framebuffer *framebuffer,
struct drm_clip_rect *clips,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
index d3987bcf53f8..b8a09807c5de 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
@@ -203,19 +203,7 @@ static void vmw_ldu_crtc_mode_set_nofb(struct drm_crtc *crtc)
}
/**
- * vmw_ldu_crtc_helper_prepare - Noop
- *
- * @crtc: CRTC associated with the new screen
- *
- * Prepares the CRTC for a mode set, but we don't need to do anything here.
- *
- */
-static void vmw_ldu_crtc_helper_prepare(struct drm_crtc *crtc)
-{
-}
-
-/**
- * vmw_ldu_crtc_helper_commit - Noop
+ * vmw_ldu_crtc_atomic_enable - Noop
*
* @crtc: CRTC associated with the new screen
*
@@ -224,16 +212,18 @@ static void vmw_ldu_crtc_helper_prepare(struct drm_crtc *crtc)
* but since for LDU the display plane is closely tied to the
* CRTC, it makes more sense to do those at plane update time.
*/
-static void vmw_ldu_crtc_helper_commit(struct drm_crtc *crtc)
+static void vmw_ldu_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
}
/**
- * vmw_ldu_crtc_helper_disable - Turns off CRTC
+ * vmw_ldu_crtc_atomic_disable - Turns off CRTC
*
* @crtc: CRTC to be turned off
*/
-static void vmw_ldu_crtc_helper_disable(struct drm_crtc *crtc)
+static void vmw_ldu_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
}
@@ -388,13 +378,12 @@ drm_plane_helper_funcs vmw_ldu_primary_plane_helper_funcs = {
};
static const struct drm_crtc_helper_funcs vmw_ldu_crtc_helper_funcs = {
- .prepare = vmw_ldu_crtc_helper_prepare,
- .commit = vmw_ldu_crtc_helper_commit,
- .disable = vmw_ldu_crtc_helper_disable,
.mode_set_nofb = vmw_ldu_crtc_mode_set_nofb,
.atomic_check = vmw_du_crtc_atomic_check,
.atomic_begin = vmw_du_crtc_atomic_begin,
.atomic_flush = vmw_du_crtc_atomic_flush,
+ .atomic_enable = vmw_ldu_crtc_atomic_enable,
+ .atomic_disable = vmw_ldu_crtc_atomic_disable,
};
@@ -439,7 +428,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_ldu_plane_funcs,
vmw_primary_plane_formats,
ARRAY_SIZE(vmw_primary_plane_formats),
- DRM_PLANE_TYPE_PRIMARY, NULL);
+ NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) {
DRM_ERROR("Failed to initialize primary plane");
goto err_free;
@@ -454,7 +443,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_ldu_cursor_funcs,
vmw_cursor_plane_formats,
ARRAY_SIZE(vmw_cursor_plane_formats),
- DRM_PLANE_TYPE_CURSOR, NULL);
+ NULL, DRM_PLANE_TYPE_CURSOR, NULL);
if (ret) {
DRM_ERROR("Failed to initialize cursor plane");
drm_plane_cleanup(&ldu->base.primary);
@@ -582,13 +571,9 @@ err_free:
int vmw_kms_ldu_close_display(struct vmw_private *dev_priv)
{
- struct drm_device *dev = dev_priv->dev;
-
if (!dev_priv->ldu_priv)
return -ENOSYS;
- drm_vblank_cleanup(dev);
-
BUG_ON(!list_empty(&dev_priv->ldu_priv->active));
kfree(dev_priv->ldu_priv);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c
index 941bcfd131ff..b17f08fc50d3 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c
@@ -320,14 +320,14 @@ int vmw_otables_setup(struct vmw_private *dev_priv)
if (dev_priv->has_dx) {
*otables = kmemdup(dx_tables, sizeof(dx_tables), GFP_KERNEL);
- if (*otables == NULL)
+ if (!(*otables))
return -ENOMEM;
dev_priv->otable_batch.num_otables = ARRAY_SIZE(dx_tables);
} else {
*otables = kmemdup(pre_dx_tables, sizeof(pre_dx_tables),
GFP_KERNEL);
- if (*otables == NULL)
+ if (!(*otables))
return -ENOMEM;
dev_priv->otable_batch.num_otables = ARRAY_SIZE(pre_dx_tables);
@@ -407,7 +407,7 @@ struct vmw_mob *vmw_mob_create(unsigned long data_pages)
{
struct vmw_mob *mob = kzalloc(sizeof(*mob), GFP_KERNEL);
- if (unlikely(mob == NULL))
+ if (unlikely(!mob))
return NULL;
mob->num_pages = vmw_mob_calculate_pt_pages(data_pages);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
index 6063c9636d4a..97000996b8dc 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
@@ -244,7 +244,7 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
reply_len = ebx;
reply = kzalloc(reply_len + 1, GFP_KERNEL);
- if (reply == NULL) {
+ if (!reply) {
DRM_ERROR("Cannot allocate memory for reply\n");
return -ENOMEM;
}
@@ -340,7 +340,7 @@ int vmw_host_get_guestinfo(const char *guest_info_param,
msg_len = strlen(guest_info_param) + strlen("info-get ") + 1;
msg = kzalloc(msg_len, GFP_KERNEL);
- if (msg == NULL) {
+ if (!msg) {
DRM_ERROR("Cannot allocate memory to get %s", guest_info_param);
return -ENOMEM;
}
@@ -400,7 +400,7 @@ int vmw_host_log(const char *log)
msg_len = strlen(log) + strlen("log ") + 1;
msg = kzalloc(msg_len, GFP_KERNEL);
- if (msg == NULL) {
+ if (!msg) {
DRM_ERROR("Cannot allocate memory for log message\n");
return -ENOMEM;
}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index 7d591f653dfa..a96f90f017d1 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -446,7 +446,7 @@ int vmw_user_dmabuf_alloc(struct vmw_private *dev_priv,
int ret;
user_bo = kzalloc(sizeof(*user_bo), GFP_KERNEL);
- if (unlikely(user_bo == NULL)) {
+ if (unlikely(!user_bo)) {
DRM_ERROR("Failed to allocate a buffer.\n");
return -ENOMEM;
}
@@ -836,7 +836,7 @@ static int vmw_resource_buf_alloc(struct vmw_resource *res,
}
backup = kzalloc(sizeof(*backup), GFP_KERNEL);
- if (unlikely(backup == NULL))
+ if (unlikely(!backup))
return -ENOMEM;
ret = vmw_dmabuf_init(res->dev_priv, backup, res->backup_size,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
index 8d7dc9def7c2..d1552d3e0652 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
@@ -270,22 +270,24 @@ static void vmw_sou_crtc_helper_prepare(struct drm_crtc *crtc)
}
/**
- * vmw_sou_crtc_helper_commit - Noop
+ * vmw_sou_crtc_atomic_enable - Noop
*
* @crtc: CRTC associated with the new screen
*
* This is called after a mode set has been completed.
*/
-static void vmw_sou_crtc_helper_commit(struct drm_crtc *crtc)
+static void vmw_sou_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
}
/**
- * vmw_sou_crtc_helper_disable - Turns off CRTC
+ * vmw_sou_crtc_atomic_disable - Turns off CRTC
*
* @crtc: CRTC to be turned off
*/
-static void vmw_sou_crtc_helper_disable(struct drm_crtc *crtc)
+static void vmw_sou_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct vmw_private *dev_priv;
struct vmw_screen_object_unit *sou;
@@ -573,12 +575,12 @@ drm_plane_helper_funcs vmw_sou_primary_plane_helper_funcs = {
static const struct drm_crtc_helper_funcs vmw_sou_crtc_helper_funcs = {
.prepare = vmw_sou_crtc_helper_prepare,
- .commit = vmw_sou_crtc_helper_commit,
- .disable = vmw_sou_crtc_helper_disable,
.mode_set_nofb = vmw_sou_crtc_mode_set_nofb,
.atomic_check = vmw_du_crtc_atomic_check,
.atomic_begin = vmw_du_crtc_atomic_begin,
.atomic_flush = vmw_du_crtc_atomic_flush,
+ .atomic_enable = vmw_sou_crtc_atomic_enable,
+ .atomic_disable = vmw_sou_crtc_atomic_disable,
};
@@ -622,7 +624,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_sou_plane_funcs,
vmw_primary_plane_formats,
ARRAY_SIZE(vmw_primary_plane_formats),
- DRM_PLANE_TYPE_PRIMARY, NULL);
+ NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) {
DRM_ERROR("Failed to initialize primary plane");
goto err_free;
@@ -637,7 +639,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_sou_cursor_funcs,
vmw_cursor_plane_formats,
ARRAY_SIZE(vmw_cursor_plane_formats),
- DRM_PLANE_TYPE_CURSOR, NULL);
+ NULL, DRM_PLANE_TYPE_CURSOR, NULL);
if (ret) {
DRM_ERROR("Failed to initialize cursor plane");
drm_plane_cleanup(&sou->base.primary);
@@ -746,15 +748,6 @@ int vmw_kms_sou_init_display(struct vmw_private *dev_priv)
return 0;
}
-int vmw_kms_sou_close_display(struct vmw_private *dev_priv)
-{
- struct drm_device *dev = dev_priv->dev;
-
- drm_vblank_cleanup(dev);
-
- return 0;
-}
-
static int do_dmabuf_define_gmrfb(struct vmw_private *dev_priv,
struct vmw_framebuffer *framebuffer)
{
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
index 68f135c5b0d8..9b832f136813 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
@@ -751,7 +751,7 @@ static int vmw_user_shader_alloc(struct vmw_private *dev_priv,
}
ushader = kzalloc(sizeof(*ushader), GFP_KERNEL);
- if (unlikely(ushader == NULL)) {
+ if (unlikely(!ushader)) {
ttm_mem_global_free(vmw_mem_glob(dev_priv),
vmw_user_shader_size);
ret = -ENOMEM;
@@ -821,7 +821,7 @@ static struct vmw_resource *vmw_shader_alloc(struct vmw_private *dev_priv,
}
shader = kzalloc(sizeof(*shader), GFP_KERNEL);
- if (unlikely(shader == NULL)) {
+ if (unlikely(!shader)) {
ttm_mem_global_free(vmw_mem_glob(dev_priv),
vmw_shader_size);
ret = -ENOMEM;
@@ -981,7 +981,7 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv,
/* Allocate and pin a DMA buffer */
buf = kzalloc(sizeof(*buf), GFP_KERNEL);
- if (unlikely(buf == NULL))
+ if (unlikely(!buf))
return -ENOMEM;
ret = vmw_dmabuf_init(dev_priv, buf, size, &vmw_sys_ne_placement,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
index 50be1f034f9e..ca3afae2db1f 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
@@ -412,7 +412,8 @@ static void vmw_stdu_crtc_helper_prepare(struct drm_crtc *crtc)
}
-static void vmw_stdu_crtc_helper_commit(struct drm_crtc *crtc)
+static void vmw_stdu_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct vmw_private *dev_priv;
struct vmw_screen_target_display_unit *stdu;
@@ -432,7 +433,8 @@ static void vmw_stdu_crtc_helper_commit(struct drm_crtc *crtc)
vmw_kms_del_active(dev_priv, &stdu->base);
}
-static void vmw_stdu_crtc_helper_disable(struct drm_crtc *crtc)
+static void vmw_stdu_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct vmw_private *dev_priv;
struct vmw_screen_target_display_unit *stdu;
@@ -1415,12 +1417,12 @@ drm_plane_helper_funcs vmw_stdu_primary_plane_helper_funcs = {
static const struct drm_crtc_helper_funcs vmw_stdu_crtc_helper_funcs = {
.prepare = vmw_stdu_crtc_helper_prepare,
- .commit = vmw_stdu_crtc_helper_commit,
- .disable = vmw_stdu_crtc_helper_disable,
.mode_set_nofb = vmw_stdu_crtc_mode_set_nofb,
.atomic_check = vmw_du_crtc_atomic_check,
.atomic_begin = vmw_du_crtc_atomic_begin,
.atomic_flush = vmw_du_crtc_atomic_flush,
+ .atomic_enable = vmw_stdu_crtc_atomic_enable,
+ .atomic_disable = vmw_stdu_crtc_atomic_disable,
};
@@ -1473,7 +1475,7 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_stdu_plane_funcs,
vmw_primary_plane_formats,
ARRAY_SIZE(vmw_primary_plane_formats),
- DRM_PLANE_TYPE_PRIMARY, NULL);
+ NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) {
DRM_ERROR("Failed to initialize primary plane");
goto err_free;
@@ -1488,7 +1490,7 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_stdu_cursor_funcs,
vmw_cursor_plane_formats,
ARRAY_SIZE(vmw_cursor_plane_formats),
- DRM_PLANE_TYPE_CURSOR, NULL);
+ NULL, DRM_PLANE_TYPE_CURSOR, NULL);
if (ret) {
DRM_ERROR("Failed to initialize cursor plane");
drm_plane_cleanup(&stdu->base.primary);
@@ -1640,8 +1642,8 @@ int vmw_kms_stdu_init_display(struct vmw_private *dev_priv)
* something arbitrarily large and we will reject any layout
* that doesn't fit prim_bb_mem later
*/
- dev->mode_config.max_width = 16384;
- dev->mode_config.max_height = 16384;
+ dev->mode_config.max_width = 8192;
+ dev->mode_config.max_height = 8192;
}
vmw_kms_create_implicit_placement_property(dev_priv, false);
@@ -1651,36 +1653,11 @@ int vmw_kms_stdu_init_display(struct vmw_private *dev_priv)
if (unlikely(ret != 0)) {
DRM_ERROR("Failed to initialize STDU %d", i);
- goto err_vblank_cleanup;
+ return ret;
}
}
DRM_INFO("Screen Target Display device initialized\n");
return 0;
-
-err_vblank_cleanup:
- drm_vblank_cleanup(dev);
- return ret;
-}
-
-
-
-/**
- * vmw_kms_stdu_close_display - Cleans up after vmw_kms_stdu_init_display
- *
- * @dev_priv: VMW DRM device
- *
- * Frees up any resources allocated by vmw_kms_stdu_init_display
- *
- * RETURNS:
- * 0 on success
- */
-int vmw_kms_stdu_close_display(struct vmw_private *dev_priv)
-{
- struct drm_device *dev = dev_priv->dev;
-
- drm_vblank_cleanup(dev);
-
- return 0;
}
diff --git a/drivers/gpu/drm/zte/zx_drm_drv.c b/drivers/gpu/drm/zte/zx_drm_drv.c
index f46c855d274b..45244828fc1f 100644
--- a/drivers/gpu/drm/zte/zx_drm_drv.c
+++ b/drivers/gpu/drm/zte/zx_drm_drv.c
@@ -59,11 +59,9 @@ static struct drm_driver zx_drm_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
DRIVER_ATOMIC,
.lastclose = zx_drm_lastclose,
- .gem_free_object = drm_gem_cma_free_object,
+ .gem_free_object_unlocked = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
- .dumb_map_offset = drm_gem_cma_dumb_map_offset,
- .dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_export = drm_gem_prime_export,
@@ -149,7 +147,6 @@ out_fbdev_fini:
out_poll_fini:
drm_kms_helper_poll_fini(drm);
drm_mode_config_cleanup(drm);
- drm_vblank_cleanup(drm);
out_unbind:
component_unbind_all(dev, drm);
out_unregister:
@@ -171,7 +168,6 @@ static void zx_drm_unbind(struct device *dev)
}
drm_kms_helper_poll_fini(drm);
drm_mode_config_cleanup(drm);
- drm_vblank_cleanup(drm);
component_unbind_all(dev, drm);
dev_set_drvdata(dev, NULL);
drm->dev_private = NULL;
diff --git a/drivers/gpu/drm/zte/zx_hdmi.c b/drivers/gpu/drm/zte/zx_hdmi.c
index 0df7366e594b..b8abb1b496ff 100644
--- a/drivers/gpu/drm/zte/zx_hdmi.c
+++ b/drivers/gpu/drm/zte/zx_hdmi.c
@@ -124,7 +124,7 @@ static int zx_hdmi_config_video_avi(struct zx_hdmi *hdmi,
union hdmi_infoframe frame;
int ret;
- ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode);
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode, false);
if (ret) {
DRM_DEV_ERROR(hdmi->dev, "failed to get avi infoframe: %d\n",
ret);
@@ -300,7 +300,6 @@ zx_hdmi_connector_detect(struct drm_connector *connector, bool force)
}
static const struct drm_connector_funcs zx_hdmi_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = zx_hdmi_connector_detect,
.destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c
index 4a6252720c10..18e763493264 100644
--- a/drivers/gpu/drm/zte/zx_plane.c
+++ b/drivers/gpu/drm/zte/zx_plane.c
@@ -540,7 +540,7 @@ int zx_plane_init(struct drm_device *drm, struct zx_plane *zplane,
ret = drm_universal_plane_init(drm, plane, VOU_CRTC_MASK,
&zx_plane_funcs, formats, format_count,
- type, NULL);
+ NULL, type, NULL);
if (ret) {
DRM_DEV_ERROR(dev, "failed to init universal plane: %d\n", ret);
return ret;
diff --git a/drivers/gpu/drm/zte/zx_tvenc.c b/drivers/gpu/drm/zte/zx_tvenc.c
index b56dc69843fc..0de1a71ca4e0 100644
--- a/drivers/gpu/drm/zte/zx_tvenc.c
+++ b/drivers/gpu/drm/zte/zx_tvenc.c
@@ -269,7 +269,6 @@ static struct drm_connector_helper_funcs zx_tvenc_connector_helper_funcs = {
};
static const struct drm_connector_funcs zx_tvenc_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
diff --git a/drivers/gpu/drm/zte/zx_vga.c b/drivers/gpu/drm/zte/zx_vga.c
index 1e0811f775cb..3e7e33cd3dfa 100644
--- a/drivers/gpu/drm/zte/zx_vga.c
+++ b/drivers/gpu/drm/zte/zx_vga.c
@@ -138,7 +138,6 @@ zx_vga_connector_detect(struct drm_connector *connector, bool force)
}
static const struct drm_connector_funcs zx_vga_connector_funcs = {
- .dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.detect = zx_vga_connector_detect,
.destroy = drm_connector_cleanup,
diff --git a/drivers/gpu/drm/zte/zx_vou.c b/drivers/gpu/drm/zte/zx_vou.c
index 5fbd10b60ee5..7491813131f3 100644
--- a/drivers/gpu/drm/zte/zx_vou.c
+++ b/drivers/gpu/drm/zte/zx_vou.c
@@ -350,7 +350,8 @@ static inline void vou_chn_set_update(struct zx_crtc *zcrtc)
zx_writel(zcrtc->chnreg + CHN_UPDATE, 1);
}
-static void zx_crtc_enable(struct drm_crtc *crtc)
+static void zx_crtc_atomic_enable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
@@ -454,7 +455,8 @@ static void zx_crtc_enable(struct drm_crtc *crtc)
DRM_DEV_ERROR(vou->dev, "failed to enable pixclk: %d\n", ret);
}
-static void zx_crtc_disable(struct drm_crtc *crtc)
+static void zx_crtc_atomic_disable(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_state)
{
struct zx_crtc *zcrtc = to_zx_crtc(crtc);
const struct zx_crtc_bits *bits = zcrtc->bits;
@@ -490,9 +492,9 @@ static void zx_crtc_atomic_flush(struct drm_crtc *crtc,
}
static const struct drm_crtc_helper_funcs zx_crtc_helper_funcs = {
- .enable = zx_crtc_enable,
- .disable = zx_crtc_disable,
.atomic_flush = zx_crtc_atomic_flush,
+ .atomic_enable = zx_crtc_atomic_enable,
+ .atomic_disable = zx_crtc_atomic_disable,
};
static int zx_vou_enable_vblank(struct drm_crtc *crtc)
diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c
index a048e3ac523d..f9cde03030fd 100644
--- a/drivers/gpu/host1x/bus.c
+++ b/drivers/gpu/host1x/bus.c
@@ -41,13 +41,15 @@ struct host1x_subdev {
/**
* host1x_subdev_add() - add a new subdevice with an associated device node
* @device: host1x device to add the subdevice to
- * @driver: host1x driver
* @np: device node
*/
static int host1x_subdev_add(struct host1x_device *device,
+ struct host1x_driver *driver,
struct device_node *np)
{
struct host1x_subdev *subdev;
+ struct device_node *child;
+ int err;
subdev = kzalloc(sizeof(*subdev), GFP_KERNEL);
if (!subdev)
@@ -60,6 +62,19 @@ static int host1x_subdev_add(struct host1x_device *device,
list_add_tail(&subdev->list, &device->subdevs);
mutex_unlock(&device->subdevs_lock);
+ /* recursively add children */
+ for_each_child_of_node(np, child) {
+ if (of_match_node(driver->subdevs, child) &&
+ of_device_is_available(child)) {
+ err = host1x_subdev_add(device, driver, child);
+ if (err < 0) {
+ /* XXX cleanup? */
+ of_node_put(child);
+ return err;
+ }
+ }
+ }
+
return 0;
}
@@ -88,7 +103,7 @@ static int host1x_device_parse_dt(struct host1x_device *device,
for_each_child_of_node(device->dev.parent->of_node, np) {
if (of_match_node(driver->subdevs, np) &&
of_device_is_available(np)) {
- err = host1x_subdev_add(device, np);
+ err = host1x_subdev_add(device, driver, np);
if (err < 0) {
of_node_put(np);
return err;
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 2c58a390123a..7f22c5c37660 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -134,8 +134,8 @@ static int host1x_probe(struct platform_device *pdev)
syncpt_irq = platform_get_irq(pdev, 0);
if (syncpt_irq < 0) {
- dev_err(&pdev->dev, "failed to get IRQ\n");
- return -ENXIO;
+ dev_err(&pdev->dev, "failed to get IRQ: %d\n", syncpt_irq);
+ return syncpt_irq;
}
host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
@@ -186,8 +186,13 @@ static int host1x_probe(struct platform_device *pdev)
return -ENOMEM;
err = iommu_attach_device(host->domain, &pdev->dev);
- if (err)
+ if (err == -ENODEV) {
+ iommu_domain_free(host->domain);
+ host->domain = NULL;
+ goto skip_iommu;
+ } else if (err) {
goto fail_free_domain;
+ }
geometry = &host->domain->geometry;
@@ -198,6 +203,7 @@ static int host1x_probe(struct platform_device *pdev)
host->iova_end = geometry->aperture_end;
}
+skip_iommu:
err = host1x_channel_list_init(&host->channel_list,
host->info->nb_channels);
if (err) {
diff --git a/drivers/gpu/host1x/hw/intr_hw.c b/drivers/gpu/host1x/hw/intr_hw.c
index dacb8009a605..37ebb51703fa 100644
--- a/drivers/gpu/host1x/hw/intr_hw.c
+++ b/drivers/gpu/host1x/hw/intr_hw.c
@@ -33,10 +33,10 @@ static void host1x_intr_syncpt_handle(struct host1x_syncpt *syncpt)
unsigned int id = syncpt->id;
struct host1x *host = syncpt->host;
- host1x_sync_writel(host, BIT_MASK(id),
- HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(BIT_WORD(id)));
- host1x_sync_writel(host, BIT_MASK(id),
- HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(BIT_WORD(id)));
+ host1x_sync_writel(host, BIT(id % 32),
+ HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(id / 32));
+ host1x_sync_writel(host, BIT(id % 32),
+ HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(id / 32));
schedule_work(&syncpt->intr.work);
}
@@ -50,9 +50,9 @@ static irqreturn_t syncpt_thresh_isr(int irq, void *dev_id)
for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); i++) {
reg = host1x_sync_readl(host,
HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(i));
- for_each_set_bit(id, &reg, BITS_PER_LONG) {
+ for_each_set_bit(id, &reg, 32) {
struct host1x_syncpt *syncpt =
- host->syncpt + (i * BITS_PER_LONG + id);
+ host->syncpt + (i * 32 + id);
host1x_intr_syncpt_handle(syncpt);
}
}
@@ -117,17 +117,17 @@ static void _host1x_intr_set_syncpt_threshold(struct host1x *host,
static void _host1x_intr_enable_syncpt_intr(struct host1x *host,
unsigned int id)
{
- host1x_sync_writel(host, BIT_MASK(id),
- HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(BIT_WORD(id)));
+ host1x_sync_writel(host, BIT(id % 32),
+ HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(id / 32));
}
static void _host1x_intr_disable_syncpt_intr(struct host1x *host,
unsigned int id)
{
- host1x_sync_writel(host, BIT_MASK(id),
- HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(BIT_WORD(id)));
- host1x_sync_writel(host, BIT_MASK(id),
- HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(BIT_WORD(id)));
+ host1x_sync_writel(host, BIT(id % 32),
+ HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(id / 32));
+ host1x_sync_writel(host, BIT(id % 32),
+ HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(id / 32));
}
static int _host1x_free_syncpt_irq(struct host1x *host)
diff --git a/drivers/gpu/host1x/hw/syncpt_hw.c b/drivers/gpu/host1x/hw/syncpt_hw.c
index c93f74fcce72..7b0270d60742 100644
--- a/drivers/gpu/host1x/hw/syncpt_hw.c
+++ b/drivers/gpu/host1x/hw/syncpt_hw.c
@@ -89,7 +89,7 @@ static int syncpt_cpu_incr(struct host1x_syncpt *sp)
host1x_syncpt_idle(sp))
return -EINVAL;
- host1x_sync_writel(host, BIT_MASK(sp->id),
+ host1x_sync_writel(host, BIT(sp->id % 32),
HOST1X_SYNC_SYNCPT_CPU_INCR(reg_offset));
wmb();
diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
index bee504406cfc..db509ab8874e 100644
--- a/drivers/gpu/host1x/job.c
+++ b/drivers/gpu/host1x/job.c
@@ -197,10 +197,6 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
}
phys_addr = host1x_bo_pin(reloc->target.bo, &sgt);
- if (!phys_addr) {
- err = -EINVAL;
- goto unpin;
- }
job->addr_phys[job->num_unpins] = phys_addr;
job->unpins[job->num_unpins].bo = reloc->target.bo;
@@ -225,10 +221,6 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
}
phys_addr = host1x_bo_pin(g->bo, &sgt);
- if (!phys_addr) {
- err = -EINVAL;
- goto unpin;
- }
if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && host->domain) {
for_each_sg(sgt->sgl, sg, sgt->nents, j)
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c
index 960d816ad7f7..6a573d21d3cc 100644
--- a/drivers/gpu/ipu-v3/ipu-common.c
+++ b/drivers/gpu/ipu-v3/ipu-common.c
@@ -1217,8 +1217,8 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base)
of_node = of_graph_get_port_by_id(dev->of_node, i);
if (!of_node) {
dev_info(dev,
- "no port@%d node in %s, not using %s%d\n",
- i, dev->of_node->full_name,
+ "no port@%d node in %pOF, not using %s%d\n",
+ i, dev->of_node,
(i / 2) ? "DI" : "CSI", i % 2);
continue;
}
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 6fd01a692197..9017dcc14502 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2216,6 +2216,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
#if IS_ENABLED(CONFIG_HID_ORTEK)
{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
#endif
#if IS_ENABLED(CONFIG_HID_PANTHERLORD)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 3d911bfd91cf..c9ba4c6db74c 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -824,6 +824,7 @@
#define USB_VENDOR_ID_ORTEK 0x05a4
#define USB_DEVICE_ID_ORTEK_PKB1700 0x1700
#define USB_DEVICE_ID_ORTEK_WKB2000 0x2000
+#define USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S 0x8003
#define USB_VENDOR_ID_PLANTRONICS 0x047f
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 41b39464ded8..501e16a9227d 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -2732,6 +2732,9 @@ static int hidpp_initialize_battery(struct hidpp_device *hidpp)
hidpp_battery_props,
sizeof(hidpp_battery_props),
GFP_KERNEL);
+ if (!battery_props)
+ return -ENOMEM;
+
num_battery_props = ARRAY_SIZE(hidpp_battery_props) - 2;
if (hidpp->capabilities & HIDPP_CAPABILITY_BATTERY_MILEAGE)
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index f3e35e7a189d..aff20f4b6d97 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -620,16 +620,6 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
return 0;
}
-static int mt_touch_input_mapped(struct hid_device *hdev, struct hid_input *hi,
- struct hid_field *field, struct hid_usage *usage,
- unsigned long **bit, int *max)
-{
- if (usage->type == EV_KEY || usage->type == EV_ABS)
- set_bit(usage->type, hi->input->evbit);
-
- return -1;
-}
-
static int mt_compute_slot(struct mt_device *td, struct input_dev *input)
{
__s32 quirks = td->mtclass.quirks;
@@ -969,8 +959,10 @@ static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
return 0;
if (field->application == HID_DG_TOUCHSCREEN ||
- field->application == HID_DG_TOUCHPAD)
- return mt_touch_input_mapped(hdev, hi, field, usage, bit, max);
+ field->application == HID_DG_TOUCHPAD) {
+ /* We own these mappings, tell hid-input to ignore them */
+ return -1;
+ }
/* let hid-core decide for the others */
return 0;
diff --git a/drivers/hid/hid-ortek.c b/drivers/hid/hid-ortek.c
index 6620f15fec22..8783a064cdcf 100644
--- a/drivers/hid/hid-ortek.c
+++ b/drivers/hid/hid-ortek.c
@@ -5,6 +5,7 @@
*
* Ortek PKB-1700
* Ortek WKB-2000
+ * iHome IMAC-A210S
* Skycable wireless presenter
*
* Copyright (c) 2010 Johnathon Harris <jmharris@gmail.com>
@@ -28,10 +29,10 @@ static __u8 *ortek_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize)
{
if (*rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x01) {
- hid_info(hdev, "Fixing up logical minimum in report descriptor (Ortek)\n");
+ hid_info(hdev, "Fixing up logical maximum in report descriptor (Ortek)\n");
rdesc[55] = 0x92;
} else if (*rsize >= 54 && rdesc[52] == 0x25 && rdesc[53] == 0x01) {
- hid_info(hdev, "Fixing up logical minimum in report descriptor (Skycable)\n");
+ hid_info(hdev, "Fixing up logical maximum in report descriptor (Skycable)\n");
rdesc[53] = 0x65;
}
return rdesc;
@@ -40,6 +41,7 @@ static __u8 *ortek_report_fixup(struct hid_device *hdev, __u8 *rdesc,
static const struct hid_device_id ortek_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
{ }
};
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 76013eb5cb7f..c008847e0b20 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -680,18 +680,21 @@ static int usbhid_open(struct hid_device *hid)
struct usbhid_device *usbhid = hid->driver_data;
int res;
+ set_bit(HID_OPENED, &usbhid->iofl);
+
if (hid->quirks & HID_QUIRK_ALWAYS_POLL)
return 0;
res = usb_autopm_get_interface(usbhid->intf);
/* the device must be awake to reliably request remote wakeup */
- if (res < 0)
+ if (res < 0) {
+ clear_bit(HID_OPENED, &usbhid->iofl);
return -EIO;
+ }
usbhid->intf->needs_remote_wakeup = 1;
set_bit(HID_RESUME_RUNNING, &usbhid->iofl);
- set_bit(HID_OPENED, &usbhid->iofl);
set_bit(HID_IN_POLLING, &usbhid->iofl);
res = hid_start_in(hid);
@@ -727,19 +730,20 @@ static void usbhid_close(struct hid_device *hid)
{
struct usbhid_device *usbhid = hid->driver_data;
- if (hid->quirks & HID_QUIRK_ALWAYS_POLL)
- return;
-
/*
* Make sure we don't restart data acquisition due to
* a resumption we no longer care about by avoiding racing
* with hid_start_in().
*/
spin_lock_irq(&usbhid->lock);
- clear_bit(HID_IN_POLLING, &usbhid->iofl);
clear_bit(HID_OPENED, &usbhid->iofl);
+ if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL))
+ clear_bit(HID_IN_POLLING, &usbhid->iofl);
spin_unlock_irq(&usbhid->lock);
+ if (hid->quirks & HID_QUIRK_ALWAYS_POLL)
+ return;
+
hid_cancel_delayed_stuff(usbhid);
usb_kill_urb(usbhid->urbin);
usbhid->intf->needs_remote_wakeup = 0;
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index e9bf0bb87ac4..e57cc40cb768 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -606,6 +606,8 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
get_order(channel->ringbuffer_pagecount * PAGE_SIZE));
out:
+ /* re-enable tasklet for use on re-open */
+ tasklet_enable(&channel->callback_event);
return ret;
}
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 0af7fd311979..76c34f4fde13 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -566,6 +566,8 @@ static int applesmc_init_smcreg_try(void)
if (ret)
return ret;
s->fan_count = tmp[0];
+ if (s->fan_count > 10)
+ s->fan_count = 10;
ret = applesmc_get_lower_bound(&s->temp_begin, "T");
if (ret)
@@ -811,7 +813,8 @@ static ssize_t applesmc_show_fan_speed(struct device *dev,
char newkey[5];
u8 buffer[2];
- sprintf(newkey, fan_speed_fmt[to_option(attr)], to_index(attr));
+ scnprintf(newkey, sizeof(newkey), fan_speed_fmt[to_option(attr)],
+ to_index(attr));
ret = applesmc_read_key(newkey, buffer, 2);
speed = ((buffer[0] << 8 | buffer[1]) >> 2);
@@ -834,7 +837,8 @@ static ssize_t applesmc_store_fan_speed(struct device *dev,
if (kstrtoul(sysfsbuf, 10, &speed) < 0 || speed >= 0x4000)
return -EINVAL; /* Bigger than a 14-bit value */
- sprintf(newkey, fan_speed_fmt[to_option(attr)], to_index(attr));
+ scnprintf(newkey, sizeof(newkey), fan_speed_fmt[to_option(attr)],
+ to_index(attr));
buffer[0] = (speed >> 6) & 0xff;
buffer[1] = (speed << 2) & 0xff;
@@ -903,7 +907,7 @@ static ssize_t applesmc_show_fan_position(struct device *dev,
char newkey[5];
u8 buffer[17];
- sprintf(newkey, FAN_ID_FMT, to_index(attr));
+ scnprintf(newkey, sizeof(newkey), FAN_ID_FMT, to_index(attr));
ret = applesmc_read_key(newkey, buffer, 16);
buffer[16] = 0;
@@ -1116,7 +1120,8 @@ static int applesmc_create_nodes(struct applesmc_node_group *groups, int num)
}
for (i = 0; i < num; i++) {
node = &grp->nodes[i];
- sprintf(node->name, grp->format, i + 1);
+ scnprintf(node->name, sizeof(node->name), grp->format,
+ i + 1);
node->sda.index = (grp->option << 16) | (i & 0xffff);
node->sda.dev_attr.show = grp->show;
node->sda.dev_attr.store = grp->store;
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 1006b230b236..65fa29591d21 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -983,7 +983,7 @@ config I2C_UNIPHIER_F
config I2C_VERSATILE
tristate "ARM Versatile/Realview I2C bus support"
- depends on ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS || COMPILE_TEST
+ depends on ARCH_MPS2 || ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS || COMPILE_TEST
select I2C_ALGOBIT
help
Say yes if you want to support the I2C serial bus on ARMs Versatile
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 2ea6d0d25a01..143a8fd582b4 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -298,6 +298,9 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
}
acpi_speed = i2c_acpi_find_bus_speed(&pdev->dev);
+ /* Some broken DSTDs use 1MiHz instead of 1MHz */
+ if (acpi_speed == 1048576)
+ acpi_speed = 1000000;
/*
* Find bus speed from the "clock-frequency" device property, ACPI
* or by using fast mode if neither is set.
@@ -319,7 +322,8 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
if (dev->clk_freq != 100000 && dev->clk_freq != 400000
&& dev->clk_freq != 1000000 && dev->clk_freq != 3400000) {
dev_err(&pdev->dev,
- "Only 100kHz, 400kHz, 1MHz and 3.4MHz supported");
+ "%d Hz is unsupported, only 100kHz, 400kHz, 1MHz and 3.4MHz are supported\n",
+ dev->clk_freq);
ret = -EINVAL;
goto exit_reset;
}
diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
index 4842ec3a5451..a9126b3cda61 100644
--- a/drivers/i2c/i2c-core-acpi.c
+++ b/drivers/i2c/i2c-core-acpi.c
@@ -230,6 +230,16 @@ void i2c_acpi_register_devices(struct i2c_adapter *adap)
dev_warn(&adap->dev, "failed to enumerate I2C slaves\n");
}
+const struct acpi_device_id *
+i2c_acpi_match_device(const struct acpi_device_id *matches,
+ struct i2c_client *client)
+{
+ if (!(client && matches))
+ return NULL;
+
+ return acpi_match_device(matches, &client->dev);
+}
+
static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level,
void *data, void **return_value)
{
@@ -289,7 +299,7 @@ u32 i2c_acpi_find_bus_speed(struct device *dev)
}
EXPORT_SYMBOL_GPL(i2c_acpi_find_bus_speed);
-static int i2c_acpi_match_adapter(struct device *dev, void *data)
+static int i2c_acpi_find_match_adapter(struct device *dev, void *data)
{
struct i2c_adapter *adapter = i2c_verify_adapter(dev);
@@ -299,7 +309,7 @@ static int i2c_acpi_match_adapter(struct device *dev, void *data)
return ACPI_HANDLE(dev) == (acpi_handle)data;
}
-static int i2c_acpi_match_device(struct device *dev, void *data)
+static int i2c_acpi_find_match_device(struct device *dev, void *data)
{
return ACPI_COMPANION(dev) == data;
}
@@ -309,7 +319,7 @@ static struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle)
struct device *dev;
dev = bus_find_device(&i2c_bus_type, NULL, handle,
- i2c_acpi_match_adapter);
+ i2c_acpi_find_match_adapter);
return dev ? i2c_verify_adapter(dev) : NULL;
}
@@ -317,7 +327,8 @@ static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev)
{
struct device *dev;
- dev = bus_find_device(&i2c_bus_type, NULL, adev, i2c_acpi_match_device);
+ dev = bus_find_device(&i2c_bus_type, NULL, adev,
+ i2c_acpi_find_match_device);
return dev ? i2c_verify_client(dev) : NULL;
}
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index c89dac7fd2e7..12822a4b8f8f 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -357,6 +357,7 @@ static int i2c_device_probe(struct device *dev)
* Tree match table entry is supplied for the probing device.
*/
if (!driver->id_table &&
+ !i2c_acpi_match_device(dev->driver->acpi_match_table, client) &&
!i2c_of_match_device(dev->driver->of_match_table, client))
return -ENODEV;
diff --git a/drivers/i2c/i2c-core.h b/drivers/i2c/i2c-core.h
index 3b63f5e5b89c..3d3d9bf02101 100644
--- a/drivers/i2c/i2c-core.h
+++ b/drivers/i2c/i2c-core.h
@@ -31,9 +31,18 @@ int i2c_check_addr_validity(unsigned addr, unsigned short flags);
int i2c_check_7bit_addr_validity_strict(unsigned short addr);
#ifdef CONFIG_ACPI
+const struct acpi_device_id *
+i2c_acpi_match_device(const struct acpi_device_id *matches,
+ struct i2c_client *client);
void i2c_acpi_register_devices(struct i2c_adapter *adap);
#else /* CONFIG_ACPI */
static inline void i2c_acpi_register_devices(struct i2c_adapter *adap) { }
+static inline const struct acpi_device_id *
+i2c_acpi_match_device(const struct acpi_device_id *matches,
+ struct i2c_client *client)
+{
+ return NULL;
+}
#endif /* CONFIG_ACPI */
extern struct notifier_block i2c_acpi_notifier;
diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig
index 2c64d0e0740f..17121329bb79 100644
--- a/drivers/i2c/muxes/Kconfig
+++ b/drivers/i2c/muxes/Kconfig
@@ -83,7 +83,7 @@ config I2C_MUX_PINCTRL
different sets of pins at run-time.
This driver can also be built as a module. If so, the module will be
- called pinctrl-i2cmux.
+ called i2c-mux-pinctrl.
config I2C_MUX_REG
tristate "Register-based I2C multiplexer"
diff --git a/drivers/ide/ide-timings.c b/drivers/ide/ide-timings.c
index 0e05f75934c9..1858e3ce3993 100644
--- a/drivers/ide/ide-timings.c
+++ b/drivers/ide/ide-timings.c
@@ -104,19 +104,19 @@ u16 ide_pio_cycle_time(ide_drive_t *drive, u8 pio)
EXPORT_SYMBOL_GPL(ide_pio_cycle_time);
#define ENOUGH(v, unit) (((v) - 1) / (unit) + 1)
-#define EZ(v, unit) ((v) ? ENOUGH(v, unit) : 0)
+#define EZ(v, unit) ((v) ? ENOUGH((v) * 1000, unit) : 0)
static void ide_timing_quantize(struct ide_timing *t, struct ide_timing *q,
int T, int UT)
{
- q->setup = EZ(t->setup * 1000, T);
- q->act8b = EZ(t->act8b * 1000, T);
- q->rec8b = EZ(t->rec8b * 1000, T);
- q->cyc8b = EZ(t->cyc8b * 1000, T);
- q->active = EZ(t->active * 1000, T);
- q->recover = EZ(t->recover * 1000, T);
- q->cycle = EZ(t->cycle * 1000, T);
- q->udma = EZ(t->udma * 1000, UT);
+ q->setup = EZ(t->setup, T);
+ q->act8b = EZ(t->act8b, T);
+ q->rec8b = EZ(t->rec8b, T);
+ q->cyc8b = EZ(t->cyc8b, T);
+ q->active = EZ(t->active, T);
+ q->recover = EZ(t->recover, T);
+ q->cycle = EZ(t->cycle, T);
+ q->udma = EZ(t->udma, UT);
}
void ide_timing_merge(struct ide_timing *a, struct ide_timing *b,
diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c
index 6b5d3be283c4..807299dd45eb 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -193,7 +193,6 @@ struct bmc150_accel_data {
struct regmap *regmap;
int irq;
struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
- atomic_t active_intr;
struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
struct mutex mutex;
u8 fifo_mode, watermark;
@@ -493,11 +492,6 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
goto out_fix_power_state;
}
- if (state)
- atomic_inc(&data->active_intr);
- else
- atomic_dec(&data->active_intr);
-
return 0;
out_fix_power_state:
@@ -1710,8 +1704,7 @@ static int bmc150_accel_resume(struct device *dev)
struct bmc150_accel_data *data = iio_priv(indio_dev);
mutex_lock(&data->mutex);
- if (atomic_read(&data->active_intr))
- bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
+ bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
bmc150_accel_fifo_set_mode(data);
mutex_unlock(&data->mutex);
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
index 07d1489cd457..e44f62bf9caa 100644
--- a/drivers/iio/accel/st_accel_core.c
+++ b/drivers/iio/accel/st_accel_core.c
@@ -166,6 +166,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.mask_ihl = 0x02,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
},
+ .sim = {
+ .addr = 0x23,
+ .value = BIT(0),
+ },
.multi_read_bit = true,
.bootime = 2,
},
@@ -234,6 +238,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.mask_od = 0x40,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
},
+ .sim = {
+ .addr = 0x23,
+ .value = BIT(0),
+ },
.multi_read_bit = true,
.bootime = 2,
},
@@ -316,6 +324,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.en_mask = 0x08,
},
},
+ .sim = {
+ .addr = 0x24,
+ .value = BIT(0),
+ },
.multi_read_bit = false,
.bootime = 2,
},
@@ -379,6 +391,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.mask_int1 = 0x04,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
},
+ .sim = {
+ .addr = 0x21,
+ .value = BIT(1),
+ },
.multi_read_bit = true,
.bootime = 2, /* guess */
},
@@ -437,6 +453,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.mask_od = 0x40,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
},
+ .sim = {
+ .addr = 0x21,
+ .value = BIT(7),
+ },
.multi_read_bit = false,
.bootime = 2, /* guess */
},
@@ -499,6 +519,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.addr_ihl = 0x22,
.mask_ihl = 0x80,
},
+ .sim = {
+ .addr = 0x23,
+ .value = BIT(0),
+ },
.multi_read_bit = true,
.bootime = 2,
},
@@ -547,6 +571,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.mask_int1 = 0x04,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
},
+ .sim = {
+ .addr = 0x21,
+ .value = BIT(1),
+ },
.multi_read_bit = false,
.bootime = 2,
},
@@ -614,6 +642,10 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.mask_ihl = 0x02,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
},
+ .sim = {
+ .addr = 0x23,
+ .value = BIT(0),
+ },
.multi_read_bit = true,
.bootime = 2,
},
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index e0ea411a0b2d..c02b23d675cb 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -22,6 +22,7 @@
#include <linux/iio/iio.h>
#include <linux/iio/driver.h>
+#include <linux/iopoll.h>
#define ASPEED_RESOLUTION_BITS 10
#define ASPEED_CLOCKS_PER_SAMPLE 12
@@ -38,11 +39,17 @@
#define ASPEED_ENGINE_ENABLE BIT(0)
+#define ASPEED_ADC_CTRL_INIT_RDY BIT(8)
+
+#define ASPEED_ADC_INIT_POLLING_TIME 500
+#define ASPEED_ADC_INIT_TIMEOUT 500000
+
struct aspeed_adc_model_data {
const char *model_name;
unsigned int min_sampling_rate; // Hz
unsigned int max_sampling_rate; // Hz
unsigned int vref_voltage; // mV
+ bool wait_init_sequence;
};
struct aspeed_adc_data {
@@ -211,6 +218,24 @@ static int aspeed_adc_probe(struct platform_device *pdev)
goto scaler_error;
}
+ model_data = of_device_get_match_data(&pdev->dev);
+
+ if (model_data->wait_init_sequence) {
+ /* Enable engine in normal mode. */
+ writel(ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE,
+ data->base + ASPEED_REG_ENGINE_CONTROL);
+
+ /* Wait for initial sequence complete. */
+ ret = readl_poll_timeout(data->base + ASPEED_REG_ENGINE_CONTROL,
+ adc_engine_control_reg_val,
+ adc_engine_control_reg_val &
+ ASPEED_ADC_CTRL_INIT_RDY,
+ ASPEED_ADC_INIT_POLLING_TIME,
+ ASPEED_ADC_INIT_TIMEOUT);
+ if (ret)
+ goto scaler_error;
+ }
+
/* Start all channels in normal mode. */
ret = clk_prepare_enable(data->clk_scaler->clk);
if (ret)
@@ -274,6 +299,7 @@ static const struct aspeed_adc_model_data ast2500_model_data = {
.vref_voltage = 1800, // mV
.min_sampling_rate = 1,
.max_sampling_rate = 1000000,
+ .wait_init_sequence = true,
};
static const struct of_device_id aspeed_adc_matches[] = {
diff --git a/drivers/iio/adc/axp288_adc.c b/drivers/iio/adc/axp288_adc.c
index 64799ad7ebad..462a99c13e7a 100644
--- a/drivers/iio/adc/axp288_adc.c
+++ b/drivers/iio/adc/axp288_adc.c
@@ -28,6 +28,8 @@
#include <linux/iio/driver.h>
#define AXP288_ADC_EN_MASK 0xF1
+#define AXP288_ADC_TS_PIN_GPADC 0xF2
+#define AXP288_ADC_TS_PIN_ON 0xF3
enum axp288_adc_id {
AXP288_ADC_TS,
@@ -121,6 +123,26 @@ static int axp288_adc_read_channel(int *val, unsigned long address,
return IIO_VAL_INT;
}
+static int axp288_adc_set_ts(struct regmap *regmap, unsigned int mode,
+ unsigned long address)
+{
+ int ret;
+
+ /* channels other than GPADC do not need to switch TS pin */
+ if (address != AXP288_GP_ADC_H)
+ return 0;
+
+ ret = regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, mode);
+ if (ret)
+ return ret;
+
+ /* When switching to the GPADC pin give things some time to settle */
+ if (mode == AXP288_ADC_TS_PIN_GPADC)
+ usleep_range(6000, 10000);
+
+ return 0;
+}
+
static int axp288_adc_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
@@ -131,7 +153,16 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
mutex_lock(&indio_dev->mlock);
switch (mask) {
case IIO_CHAN_INFO_RAW:
+ if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_GPADC,
+ chan->address)) {
+ dev_err(&indio_dev->dev, "GPADC mode\n");
+ ret = -EINVAL;
+ break;
+ }
ret = axp288_adc_read_channel(val, chan->address, info->regmap);
+ if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_ON,
+ chan->address))
+ dev_err(&indio_dev->dev, "TS pin restore\n");
break;
default:
ret = -EINVAL;
@@ -141,6 +172,15 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
return ret;
}
+static int axp288_adc_set_state(struct regmap *regmap)
+{
+ /* ADC should be always enabled for internal FG to function */
+ if (regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, AXP288_ADC_TS_PIN_ON))
+ return -EIO;
+
+ return regmap_write(regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK);
+}
+
static const struct iio_info axp288_adc_iio_info = {
.read_raw = &axp288_adc_read_raw,
.driver_module = THIS_MODULE,
@@ -169,7 +209,7 @@ static int axp288_adc_probe(struct platform_device *pdev)
* Set ADC to enabled state at all time, including system suspend.
* otherwise internal fuel gauge functionality may be affected.
*/
- ret = regmap_write(info->regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK);
+ ret = axp288_adc_set_state(axp20x->regmap);
if (ret) {
dev_err(&pdev->dev, "unable to enable ADC device\n");
return ret;
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
index 81d4c39e414a..137f577d9432 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -256,6 +256,7 @@ static int sun4i_gpadc_read(struct iio_dev *indio_dev, int channel, int *val,
err:
pm_runtime_put_autosuspend(indio_dev->dev.parent);
+ disable_irq(irq);
mutex_unlock(&info->mutex);
return ret;
@@ -365,7 +366,6 @@ static irqreturn_t sun4i_gpadc_temp_data_irq_handler(int irq, void *dev_id)
complete(&info->completion);
out:
- disable_irq_nosync(info->temp_data_irq);
return IRQ_HANDLED;
}
@@ -380,7 +380,6 @@ static irqreturn_t sun4i_gpadc_fifo_data_irq_handler(int irq, void *dev_id)
complete(&info->completion);
out:
- disable_irq_nosync(info->fifo_data_irq);
return IRQ_HANDLED;
}
diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
index 01fc76f7d660..c168e0db329a 100644
--- a/drivers/iio/adc/vf610_adc.c
+++ b/drivers/iio/adc/vf610_adc.c
@@ -77,7 +77,7 @@
#define VF610_ADC_ADSTS_MASK 0x300
#define VF610_ADC_ADLPC_EN 0x80
#define VF610_ADC_ADHSC_EN 0x400
-#define VF610_ADC_REFSEL_VALT 0x100
+#define VF610_ADC_REFSEL_VALT 0x800
#define VF610_ADC_REFSEL_VBG 0x1000
#define VF610_ADC_ADTRG_HARD 0x2000
#define VF610_ADC_AVGS_8 0x4000
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
index 79c8c7cd70d5..6e6a1ecc99dd 100644
--- a/drivers/iio/common/st_sensors/st_sensors_core.c
+++ b/drivers/iio/common/st_sensors/st_sensors_core.c
@@ -550,6 +550,31 @@ out:
}
EXPORT_SYMBOL(st_sensors_read_info_raw);
+static int st_sensors_init_interface_mode(struct iio_dev *indio_dev,
+ const struct st_sensor_settings *sensor_settings)
+{
+ struct st_sensor_data *sdata = iio_priv(indio_dev);
+ struct device_node *np = sdata->dev->of_node;
+ struct st_sensors_platform_data *pdata;
+
+ pdata = (struct st_sensors_platform_data *)sdata->dev->platform_data;
+ if (((np && of_property_read_bool(np, "spi-3wire")) ||
+ (pdata && pdata->spi_3wire)) && sensor_settings->sim.addr) {
+ int err;
+
+ err = sdata->tf->write_byte(&sdata->tb, sdata->dev,
+ sensor_settings->sim.addr,
+ sensor_settings->sim.value);
+ if (err < 0) {
+ dev_err(&indio_dev->dev,
+ "failed to init interface mode\n");
+ return err;
+ }
+ }
+
+ return 0;
+}
+
int st_sensors_check_device_support(struct iio_dev *indio_dev,
int num_sensors_list,
const struct st_sensor_settings *sensor_settings)
@@ -574,6 +599,10 @@ int st_sensors_check_device_support(struct iio_dev *indio_dev,
return -ENODEV;
}
+ err = st_sensors_init_interface_mode(indio_dev, &sensor_settings[i]);
+ if (err < 0)
+ return err;
+
if (sensor_settings[i].wai_addr) {
err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
sensor_settings[i].wai_addr, &wai);
diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c
index e7d4ea75e007..7599693f7fe9 100644
--- a/drivers/iio/light/tsl2563.c
+++ b/drivers/iio/light/tsl2563.c
@@ -626,7 +626,7 @@ static irqreturn_t tsl2563_event_handler(int irq, void *private)
struct tsl2563_chip *chip = iio_priv(dev_info);
iio_push_event(dev_info,
- IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
+ IIO_UNMOD_EVENT_CODE(IIO_INTENSITY,
0,
IIO_EV_TYPE_THRESH,
IIO_EV_DIR_EITHER),
diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c
index aa61ec15c139..f1bce05ffa13 100644
--- a/drivers/iio/pressure/st_pressure_core.c
+++ b/drivers/iio/pressure/st_pressure_core.c
@@ -456,7 +456,7 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
.mask_od = 0x40,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
},
- .multi_read_bit = true,
+ .multi_read_bit = false,
.bootime = 2,
},
};
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index a6cb379a4ebc..437522ca97b4 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -61,6 +61,7 @@ struct addr_req {
void (*callback)(int status, struct sockaddr *src_addr,
struct rdma_dev_addr *addr, void *context);
unsigned long timeout;
+ struct delayed_work work;
int status;
u32 seq;
};
@@ -268,6 +269,7 @@ int rdma_translate_ip(const struct sockaddr *addr,
return ret;
ret = rdma_copy_addr(dev_addr, dev, NULL);
+ dev_addr->bound_dev_if = dev->ifindex;
if (vlan_id)
*vlan_id = rdma_vlan_dev_vlan_id(dev);
dev_put(dev);
@@ -280,6 +282,7 @@ int rdma_translate_ip(const struct sockaddr *addr,
&((const struct sockaddr_in6 *)addr)->sin6_addr,
dev, 1)) {
ret = rdma_copy_addr(dev_addr, dev, NULL);
+ dev_addr->bound_dev_if = dev->ifindex;
if (vlan_id)
*vlan_id = rdma_vlan_dev_vlan_id(dev);
break;
@@ -293,7 +296,7 @@ int rdma_translate_ip(const struct sockaddr *addr,
}
EXPORT_SYMBOL(rdma_translate_ip);
-static void set_timeout(unsigned long time)
+static void set_timeout(struct delayed_work *delayed_work, unsigned long time)
{
unsigned long delay;
@@ -301,7 +304,7 @@ static void set_timeout(unsigned long time)
if ((long)delay < 0)
delay = 0;
- mod_delayed_work(addr_wq, &work, delay);
+ mod_delayed_work(addr_wq, delayed_work, delay);
}
static void queue_req(struct addr_req *req)
@@ -316,8 +319,7 @@ static void queue_req(struct addr_req *req)
list_add(&req->list, &temp_req->list);
- if (req_list.next == &req->list)
- set_timeout(req->timeout);
+ set_timeout(&req->work, req->timeout);
mutex_unlock(&lock);
}
@@ -405,10 +407,10 @@ static int addr4_resolve(struct sockaddr_in *src_in,
fl4.saddr = src_ip;
fl4.flowi4_oif = addr->bound_dev_if;
rt = ip_route_output_key(addr->net, &fl4);
- if (IS_ERR(rt)) {
- ret = PTR_ERR(rt);
- goto out;
- }
+ ret = PTR_ERR_OR_ZERO(rt);
+ if (ret)
+ return ret;
+
src_in->sin_family = AF_INET;
src_in->sin_addr.s_addr = fl4.saddr;
@@ -423,8 +425,6 @@ static int addr4_resolve(struct sockaddr_in *src_in,
*prt = rt;
return 0;
-out:
- return ret;
}
#if IS_ENABLED(CONFIG_IPV6)
@@ -509,6 +509,11 @@ static int addr_resolve(struct sockaddr *src_in,
struct dst_entry *dst;
int ret;
+ if (!addr->net) {
+ pr_warn_ratelimited("%s: missing namespace\n", __func__);
+ return -EINVAL;
+ }
+
if (src_in->sa_family == AF_INET) {
struct rtable *rt = NULL;
const struct sockaddr_in *dst_in4 =
@@ -522,8 +527,12 @@ static int addr_resolve(struct sockaddr *src_in,
if (resolve_neigh)
ret = addr_resolve_neigh(&rt->dst, dst_in, addr, seq);
- ndev = rt->dst.dev;
- dev_hold(ndev);
+ if (addr->bound_dev_if) {
+ ndev = dev_get_by_index(addr->net, addr->bound_dev_if);
+ } else {
+ ndev = rt->dst.dev;
+ dev_hold(ndev);
+ }
ip_rt_put(rt);
} else {
@@ -539,19 +548,63 @@ static int addr_resolve(struct sockaddr *src_in,
if (resolve_neigh)
ret = addr_resolve_neigh(dst, dst_in, addr, seq);
- ndev = dst->dev;
- dev_hold(ndev);
+ if (addr->bound_dev_if) {
+ ndev = dev_get_by_index(addr->net, addr->bound_dev_if);
+ } else {
+ ndev = dst->dev;
+ dev_hold(ndev);
+ }
dst_release(dst);
}
- addr->bound_dev_if = ndev->ifindex;
- addr->net = dev_net(ndev);
+ if (ndev->flags & IFF_LOOPBACK) {
+ ret = rdma_translate_ip(dst_in, addr, NULL);
+ /*
+ * Put the loopback device and get the translated
+ * device instead.
+ */
+ dev_put(ndev);
+ ndev = dev_get_by_index(addr->net, addr->bound_dev_if);
+ } else {
+ addr->bound_dev_if = ndev->ifindex;
+ }
dev_put(ndev);
return ret;
}
+static void process_one_req(struct work_struct *_work)
+{
+ struct addr_req *req;
+ struct sockaddr *src_in, *dst_in;
+
+ mutex_lock(&lock);
+ req = container_of(_work, struct addr_req, work.work);
+
+ if (req->status == -ENODATA) {
+ src_in = (struct sockaddr *)&req->src_addr;
+ dst_in = (struct sockaddr *)&req->dst_addr;
+ req->status = addr_resolve(src_in, dst_in, req->addr,
+ true, req->seq);
+ if (req->status && time_after_eq(jiffies, req->timeout)) {
+ req->status = -ETIMEDOUT;
+ } else if (req->status == -ENODATA) {
+ /* requeue the work for retrying again */
+ set_timeout(&req->work, req->timeout);
+ mutex_unlock(&lock);
+ return;
+ }
+ }
+ list_del(&req->list);
+ mutex_unlock(&lock);
+
+ req->callback(req->status, (struct sockaddr *)&req->src_addr,
+ req->addr, req->context);
+ put_client(req->client);
+ kfree(req);
+}
+
static void process_req(struct work_struct *work)
{
struct addr_req *req, *temp_req;
@@ -569,20 +622,23 @@ static void process_req(struct work_struct *work)
true, req->seq);
if (req->status && time_after_eq(jiffies, req->timeout))
req->status = -ETIMEDOUT;
- else if (req->status == -ENODATA)
+ else if (req->status == -ENODATA) {
+ set_timeout(&req->work, req->timeout);
continue;
+ }
}
list_move_tail(&req->list, &done_list);
}
- if (!list_empty(&req_list)) {
- req = list_entry(req_list.next, struct addr_req, list);
- set_timeout(req->timeout);
- }
mutex_unlock(&lock);
list_for_each_entry_safe(req, temp_req, &done_list, list) {
list_del(&req->list);
+ /* It is safe to cancel other work items from this work item
+ * because at a time there can be only one work item running
+ * with this single threaded work queue.
+ */
+ cancel_delayed_work(&req->work);
req->callback(req->status, (struct sockaddr *) &req->src_addr,
req->addr, req->context);
put_client(req->client);
@@ -625,6 +681,7 @@ int rdma_resolve_ip(struct rdma_addr_client *client,
req->context = context;
req->client = client;
atomic_inc(&client->refcount);
+ INIT_DELAYED_WORK(&req->work, process_one_req);
req->seq = (u32)atomic_inc_return(&ib_nl_addr_request_seq);
req->status = addr_resolve(src_in, dst_in, addr, true, req->seq);
@@ -679,7 +736,7 @@ void rdma_addr_cancel(struct rdma_dev_addr *addr)
req->status = -ECANCELED;
req->timeout = jiffies;
list_move(&req->list, &req_list);
- set_timeout(req->timeout);
+ set_timeout(&req->work, req->timeout);
break;
}
}
@@ -785,9 +842,8 @@ static int netevent_callback(struct notifier_block *self, unsigned long event,
if (event == NETEVENT_NEIGH_UPDATE) {
struct neighbour *neigh = ctx;
- if (neigh->nud_state & NUD_VALID) {
- set_timeout(jiffies);
- }
+ if (neigh->nud_state & NUD_VALID)
+ set_timeout(&work, jiffies);
}
return 0;
}
@@ -798,7 +854,7 @@ static struct notifier_block nb = {
int addr_init(void)
{
- addr_wq = alloc_workqueue("ib_addr", WQ_MEM_RECLAIM, 0);
+ addr_wq = alloc_ordered_workqueue("ib_addr", WQ_MEM_RECLAIM);
if (!addr_wq)
return -ENOMEM;
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 31bb82d8ecd7..0eb393237ba2 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -623,22 +623,11 @@ static inline int cma_validate_port(struct ib_device *device, u8 port,
if ((dev_type != ARPHRD_INFINIBAND) && rdma_protocol_ib(device, port))
return ret;
- if (dev_type == ARPHRD_ETHER && rdma_protocol_roce(device, port)) {
+ if (dev_type == ARPHRD_ETHER && rdma_protocol_roce(device, port))
ndev = dev_get_by_index(&init_net, bound_if_index);
- if (ndev && ndev->flags & IFF_LOOPBACK) {
- pr_info("detected loopback device\n");
- dev_put(ndev);
-
- if (!device->get_netdev)
- return -EOPNOTSUPP;
-
- ndev = device->get_netdev(device, port);
- if (!ndev)
- return -ENODEV;
- }
- } else {
+ else
gid_type = IB_GID_TYPE_IB;
- }
+
ret = ib_find_cached_gid_by_port(device, gid, gid_type, port,
ndev, NULL);
@@ -1044,6 +1033,8 @@ int rdma_init_qp_attr(struct rdma_cm_id *id, struct ib_qp_attr *qp_attr,
} else
ret = iw_cm_init_qp_attr(id_priv->cm_id.iw, qp_attr,
qp_attr_mask);
+ qp_attr->port_num = id_priv->id.port_num;
+ *qp_attr_mask |= IB_QP_PORT;
} else
ret = -ENOSYS;
@@ -2569,21 +2560,6 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
goto err2;
}
- if (ndev->flags & IFF_LOOPBACK) {
- dev_put(ndev);
- if (!id_priv->id.device->get_netdev) {
- ret = -EOPNOTSUPP;
- goto err2;
- }
-
- ndev = id_priv->id.device->get_netdev(id_priv->id.device,
- id_priv->id.port_num);
- if (!ndev) {
- ret = -ENODEV;
- goto err2;
- }
- }
-
supported_gids = roce_gid_type_mask_support(id_priv->id.device,
id_priv->id.port_num);
gid_type = cma_route_gid_type(addr->dev_addr.network,
diff --git a/drivers/infiniband/core/roce_gid_mgmt.c b/drivers/infiniband/core/roce_gid_mgmt.c
index db958d3207ef..94a9eefb3cfc 100644
--- a/drivers/infiniband/core/roce_gid_mgmt.c
+++ b/drivers/infiniband/core/roce_gid_mgmt.c
@@ -42,6 +42,8 @@
#include <rdma/ib_cache.h>
#include <rdma/ib_addr.h>
+static struct workqueue_struct *gid_cache_wq;
+
enum gid_op_type {
GID_DEL = 0,
GID_ADD
@@ -560,7 +562,7 @@ static int netdevice_queue_work(struct netdev_event_work_cmd *cmds,
}
INIT_WORK(&ndev_work->work, netdevice_event_work_handler);
- queue_work(ib_wq, &ndev_work->work);
+ queue_work(gid_cache_wq, &ndev_work->work);
return NOTIFY_DONE;
}
@@ -693,7 +695,7 @@ static int addr_event(struct notifier_block *this, unsigned long event,
dev_hold(ndev);
work->gid_attr.ndev = ndev;
- queue_work(ib_wq, &work->work);
+ queue_work(gid_cache_wq, &work->work);
return NOTIFY_DONE;
}
@@ -740,6 +742,10 @@ static struct notifier_block nb_inet6addr = {
int __init roce_gid_mgmt_init(void)
{
+ gid_cache_wq = alloc_ordered_workqueue("gid-cache-wq", 0);
+ if (!gid_cache_wq)
+ return -ENOMEM;
+
register_inetaddr_notifier(&nb_inetaddr);
if (IS_ENABLED(CONFIG_IPV6))
register_inet6addr_notifier(&nb_inet6addr);
@@ -764,4 +770,5 @@ void __exit roce_gid_mgmt_cleanup(void)
* ib-core is removed, all physical devices have been removed,
* so no issue with remaining hardware contexts.
*/
+ destroy_workqueue(gid_cache_wq);
}
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 8ba9bfb073d1..c551d2b275fd 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -1153,7 +1153,7 @@ ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file,
int out_len)
{
struct ib_uverbs_resize_cq cmd;
- struct ib_uverbs_resize_cq_resp resp;
+ struct ib_uverbs_resize_cq_resp resp = {};
struct ib_udata udata;
struct ib_cq *cq;
int ret = -EINVAL;
@@ -1296,7 +1296,6 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
struct ib_uobject *uobj;
struct ib_cq *cq;
struct ib_ucq_object *obj;
- struct ib_uverbs_event_queue *ev_queue;
int ret = -EINVAL;
if (copy_from_user(&cmd, buf, sizeof cmd))
@@ -1313,7 +1312,6 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
*/
uverbs_uobject_get(uobj);
cq = uobj->object;
- ev_queue = cq->cq_context;
obj = container_of(cq->uobject, struct ib_ucq_object, uobject);
memset(&resp, 0, sizeof(resp));
@@ -1935,7 +1933,8 @@ static int modify_qp(struct ib_uverbs_file *file,
goto out;
}
- if (!rdma_is_port_valid(qp->device, cmd->base.port_num)) {
+ if ((cmd->base.attr_mask & IB_QP_PORT) &&
+ !rdma_is_port_valid(qp->device, cmd->base.port_num)) {
ret = -EINVAL;
goto release_qp;
}
@@ -2005,28 +2004,13 @@ static int modify_qp(struct ib_uverbs_file *file,
rdma_ah_set_port_num(&attr->alt_ah_attr,
cmd->base.alt_dest.port_num);
- if (qp->real_qp == qp) {
- if (cmd->base.attr_mask & IB_QP_AV) {
- ret = ib_resolve_eth_dmac(qp->device, &attr->ah_attr);
- if (ret)
- goto release_qp;
- }
- ret = ib_security_modify_qp(qp,
- attr,
- modify_qp_mask(qp->qp_type,
- cmd->base.attr_mask),
- udata);
- } else {
- ret = ib_security_modify_qp(qp,
- attr,
- modify_qp_mask(qp->qp_type,
- cmd->base.attr_mask),
- NULL);
- }
+ ret = ib_modify_qp_with_udata(qp, attr,
+ modify_qp_mask(qp->qp_type,
+ cmd->base.attr_mask),
+ udata);
release_qp:
uobj_put_obj_read(qp);
-
out:
kfree(attr);
@@ -2103,7 +2087,6 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
struct ib_uverbs_destroy_qp cmd;
struct ib_uverbs_destroy_qp_resp resp;
struct ib_uobject *uobj;
- struct ib_qp *qp;
struct ib_uqp_object *obj;
int ret = -EINVAL;
@@ -2117,7 +2100,6 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
if (IS_ERR(uobj))
return PTR_ERR(uobj);
- qp = uobj->object;
obj = container_of(uobj, struct ib_uqp_object, uevent.uobject);
/*
* Make sure we don't free the memory in remove_commit as we still
@@ -3019,7 +3001,6 @@ int ib_uverbs_ex_destroy_wq(struct ib_uverbs_file *file,
{
struct ib_uverbs_ex_destroy_wq cmd = {};
struct ib_uverbs_ex_destroy_wq_resp resp = {};
- struct ib_wq *wq;
struct ib_uobject *uobj;
struct ib_uwq_object *obj;
size_t required_cmd_sz;
@@ -3053,7 +3034,6 @@ int ib_uverbs_ex_destroy_wq(struct ib_uverbs_file *file,
if (IS_ERR(uobj))
return PTR_ERR(uobj);
- wq = uobj->object;
obj = container_of(uobj, struct ib_uwq_object, uevent.uobject);
/*
* Make sure we don't free the memory in remove_commit as we still
@@ -3743,10 +3723,8 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
struct ib_uverbs_destroy_srq cmd;
struct ib_uverbs_destroy_srq_resp resp;
struct ib_uobject *uobj;
- struct ib_srq *srq;
struct ib_uevent_object *obj;
int ret = -EINVAL;
- enum ib_srq_type srq_type;
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
@@ -3756,9 +3734,7 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
if (IS_ERR(uobj))
return PTR_ERR(uobj);
- srq = uobj->object;
obj = container_of(uobj, struct ib_uevent_object, uobject);
- srq_type = srq->srq_type;
/*
* Make sure we don't free the memory in remove_commit as we still
* needs the uobject memory to create the response.
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 3d2609608f58..c023e2c81b8f 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -250,6 +250,7 @@ void ib_uverbs_release_file(struct kref *ref)
if (atomic_dec_and_test(&file->device->refcount))
ib_uverbs_comp_dev(file->device);
+ kobject_put(&file->device->kobj);
kfree(file);
}
@@ -917,7 +918,6 @@ err:
static int ib_uverbs_close(struct inode *inode, struct file *filp)
{
struct ib_uverbs_file *file = filp->private_data;
- struct ib_uverbs_device *dev = file->device;
mutex_lock(&file->cleanup_mutex);
if (file->ucontext) {
@@ -939,7 +939,6 @@ static int ib_uverbs_close(struct inode *inode, struct file *filp)
ib_uverbs_release_async_event_file);
kref_put(&file->ref, ib_uverbs_release_file);
- kobject_put(&dev->kobj);
return 0;
}
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index c973a83c898b..7f8fe443df46 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -452,6 +452,19 @@ int ib_get_gids_from_rdma_hdr(const union rdma_network_hdr *hdr,
}
EXPORT_SYMBOL(ib_get_gids_from_rdma_hdr);
+/*
+ * This function creates ah from the incoming packet.
+ * Incoming packet has dgid of the receiver node on which this code is
+ * getting executed and, sgid contains the GID of the sender.
+ *
+ * When resolving mac address of destination, the arrived dgid is used
+ * as sgid and, sgid is used as dgid because sgid contains destinations
+ * GID whom to respond to.
+ *
+ * This is why when calling rdma_addr_find_l2_eth_by_grh() function, the
+ * position of arguments dgid and sgid do not match the order of the
+ * parameters.
+ */
int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
const struct ib_wc *wc, const struct ib_grh *grh,
struct rdma_ah_attr *ah_attr)
@@ -507,11 +520,6 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
}
resolved_dev = dev_get_by_index(&init_net, if_index);
- if (resolved_dev->flags & IFF_LOOPBACK) {
- dev_put(resolved_dev);
- resolved_dev = idev;
- dev_hold(resolved_dev);
- }
rcu_read_lock();
if (resolved_dev != idev && !rdma_is_upper_dev_rcu(idev,
resolved_dev))
@@ -1268,20 +1276,36 @@ out:
}
EXPORT_SYMBOL(ib_resolve_eth_dmac);
-int ib_modify_qp(struct ib_qp *qp,
- struct ib_qp_attr *qp_attr,
- int qp_attr_mask)
+/**
+ * ib_modify_qp_with_udata - Modifies the attributes for the specified QP.
+ * @qp: The QP to modify.
+ * @attr: On input, specifies the QP attributes to modify. On output,
+ * the current values of selected QP attributes are returned.
+ * @attr_mask: A bit-mask used to specify which attributes of the QP
+ * are being modified.
+ * @udata: pointer to user's input output buffer information
+ * are being modified.
+ * It returns 0 on success and returns appropriate error code on error.
+ */
+int ib_modify_qp_with_udata(struct ib_qp *qp, struct ib_qp_attr *attr,
+ int attr_mask, struct ib_udata *udata)
{
+ int ret;
- if (qp_attr_mask & IB_QP_AV) {
- int ret;
-
- ret = ib_resolve_eth_dmac(qp->device, &qp_attr->ah_attr);
+ if (attr_mask & IB_QP_AV) {
+ ret = ib_resolve_eth_dmac(qp->device, &attr->ah_attr);
if (ret)
return ret;
}
+ return ib_security_modify_qp(qp, attr, attr_mask, udata);
+}
+EXPORT_SYMBOL(ib_modify_qp_with_udata);
- return ib_security_modify_qp(qp->real_qp, qp_attr, qp_attr_mask, NULL);
+int ib_modify_qp(struct ib_qp *qp,
+ struct ib_qp_attr *qp_attr,
+ int qp_attr_mask)
+{
+ return ib_modify_qp_with_udata(qp, qp_attr, qp_attr_mask, NULL);
}
EXPORT_SYMBOL(ib_modify_qp);
diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
index 08772836fded..85527532c49d 100644
--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
+++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
@@ -51,6 +51,8 @@
#define BNXT_RE_PAGE_SIZE_8M BIT(23)
#define BNXT_RE_PAGE_SIZE_1G BIT(30)
+#define BNXT_RE_MAX_MR_SIZE BIT(30)
+
#define BNXT_RE_MAX_QPC_COUNT (64 * 1024)
#define BNXT_RE_MAX_MRW_COUNT (64 * 1024)
#define BNXT_RE_MAX_SRQC_COUNT (64 * 1024)
@@ -60,6 +62,13 @@
#define BNXT_RE_RQ_WQE_THRESHOLD 32
+/*
+ * Setting the default ack delay value to 16, which means
+ * the default timeout is approx. 260ms(4 usec * 2 ^(timeout))
+ */
+
+#define BNXT_RE_DEFAULT_ACK_DELAY 16
+
struct bnxt_re_work {
struct work_struct work;
unsigned long event;
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index c7bd68311d0c..f0e01b3ac711 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -145,10 +145,8 @@ int bnxt_re_query_device(struct ib_device *ibdev,
ib_attr->fw_ver = (u64)(unsigned long)(dev_attr->fw_ver);
bnxt_qplib_get_guid(rdev->netdev->dev_addr,
(u8 *)&ib_attr->sys_image_guid);
- ib_attr->max_mr_size = ~0ull;
- ib_attr->page_size_cap = BNXT_RE_PAGE_SIZE_4K | BNXT_RE_PAGE_SIZE_8K |
- BNXT_RE_PAGE_SIZE_64K | BNXT_RE_PAGE_SIZE_2M |
- BNXT_RE_PAGE_SIZE_8M | BNXT_RE_PAGE_SIZE_1G;
+ ib_attr->max_mr_size = BNXT_RE_MAX_MR_SIZE;
+ ib_attr->page_size_cap = BNXT_RE_PAGE_SIZE_4K;
ib_attr->vendor_id = rdev->en_dev->pdev->vendor;
ib_attr->vendor_part_id = rdev->en_dev->pdev->device;
@@ -174,9 +172,11 @@ int bnxt_re_query_device(struct ib_device *ibdev,
ib_attr->max_mr = dev_attr->max_mr;
ib_attr->max_pd = dev_attr->max_pd;
ib_attr->max_qp_rd_atom = dev_attr->max_qp_rd_atom;
- ib_attr->max_qp_init_rd_atom = dev_attr->max_qp_rd_atom;
- ib_attr->atomic_cap = IB_ATOMIC_HCA;
- ib_attr->masked_atomic_cap = IB_ATOMIC_HCA;
+ ib_attr->max_qp_init_rd_atom = dev_attr->max_qp_init_rd_atom;
+ if (dev_attr->is_atomic) {
+ ib_attr->atomic_cap = IB_ATOMIC_HCA;
+ ib_attr->masked_atomic_cap = IB_ATOMIC_HCA;
+ }
ib_attr->max_ee_rd_atom = 0;
ib_attr->max_res_rd_atom = 0;
@@ -201,7 +201,7 @@ int bnxt_re_query_device(struct ib_device *ibdev,
ib_attr->max_fast_reg_page_list_len = MAX_PBL_LVL_1_PGS;
ib_attr->max_pkeys = 1;
- ib_attr->local_ca_ack_delay = 0;
+ ib_attr->local_ca_ack_delay = BNXT_RE_DEFAULT_ACK_DELAY;
return 0;
}
@@ -390,15 +390,17 @@ int bnxt_re_del_gid(struct ib_device *ibdev, u8 port_num,
return -EINVAL;
ctx->refcnt--;
if (!ctx->refcnt) {
- rc = bnxt_qplib_del_sgid
- (sgid_tbl,
- &sgid_tbl->tbl[ctx->idx], true);
- if (rc)
+ rc = bnxt_qplib_del_sgid(sgid_tbl,
+ &sgid_tbl->tbl[ctx->idx],
+ true);
+ if (rc) {
dev_err(rdev_to_dev(rdev),
"Failed to remove GID: %#x", rc);
- ctx_tbl = sgid_tbl->ctx;
- ctx_tbl[ctx->idx] = NULL;
- kfree(ctx);
+ } else {
+ ctx_tbl = sgid_tbl->ctx;
+ ctx_tbl[ctx->idx] = NULL;
+ kfree(ctx);
+ }
}
} else {
return -EINVAL;
@@ -588,10 +590,10 @@ static int bnxt_re_create_fence_mr(struct bnxt_re_pd *pd)
/* Create a fence MW only for kernel consumers */
mw = bnxt_re_alloc_mw(&pd->ib_pd, IB_MW_TYPE_1, NULL);
- if (!mw) {
+ if (IS_ERR(mw)) {
dev_err(rdev_to_dev(rdev),
"Failed to create fence-MW for PD: %p\n", pd);
- rc = -EINVAL;
+ rc = PTR_ERR(mw);
goto fail;
}
fence->mw = mw;
@@ -612,30 +614,13 @@ int bnxt_re_dealloc_pd(struct ib_pd *ib_pd)
int rc;
bnxt_re_destroy_fence_mr(pd);
- if (ib_pd->uobject && pd->dpi.dbr) {
- struct ib_ucontext *ib_uctx = ib_pd->uobject->context;
- struct bnxt_re_ucontext *ucntx;
- /* Free DPI only if this is the first PD allocated by the
- * application and mark the context dpi as NULL
- */
- ucntx = container_of(ib_uctx, struct bnxt_re_ucontext, ib_uctx);
-
- rc = bnxt_qplib_dealloc_dpi(&rdev->qplib_res,
- &rdev->qplib_res.dpi_tbl,
- &pd->dpi);
+ if (pd->qplib_pd.id) {
+ rc = bnxt_qplib_dealloc_pd(&rdev->qplib_res,
+ &rdev->qplib_res.pd_tbl,
+ &pd->qplib_pd);
if (rc)
- dev_err(rdev_to_dev(rdev), "Failed to deallocate HW DPI");
- /* Don't fail, continue*/
- ucntx->dpi = NULL;
- }
-
- rc = bnxt_qplib_dealloc_pd(&rdev->qplib_res,
- &rdev->qplib_res.pd_tbl,
- &pd->qplib_pd);
- if (rc) {
- dev_err(rdev_to_dev(rdev), "Failed to deallocate HW PD");
- return rc;
+ dev_err(rdev_to_dev(rdev), "Failed to deallocate HW PD");
}
kfree(pd);
@@ -667,23 +652,22 @@ struct ib_pd *bnxt_re_alloc_pd(struct ib_device *ibdev,
if (udata) {
struct bnxt_re_pd_resp resp;
- if (!ucntx->dpi) {
+ if (!ucntx->dpi.dbr) {
/* Allocate DPI in alloc_pd to avoid failing of
* ibv_devinfo and family of application when DPIs
* are depleted.
*/
if (bnxt_qplib_alloc_dpi(&rdev->qplib_res.dpi_tbl,
- &pd->dpi, ucntx)) {
+ &ucntx->dpi, ucntx)) {
rc = -ENOMEM;
goto dbfail;
}
- ucntx->dpi = &pd->dpi;
}
resp.pdid = pd->qplib_pd.id;
/* Still allow mapping this DBR to the new user PD. */
- resp.dpi = ucntx->dpi->dpi;
- resp.dbr = (u64)ucntx->dpi->umdbr;
+ resp.dpi = ucntx->dpi.dpi;
+ resp.dbr = (u64)ucntx->dpi.umdbr;
rc = ib_copy_to_udata(udata, &resp, sizeof(resp));
if (rc) {
@@ -960,7 +944,7 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
qplib_qp->rq.nmap = umem->nmap;
}
- qplib_qp->dpi = cntx->dpi;
+ qplib_qp->dpi = &cntx->dpi;
return 0;
rqfail:
ib_umem_release(qp->sumem);
@@ -1530,13 +1514,24 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
if (qp_attr_mask & IB_QP_MAX_QP_RD_ATOMIC) {
qp->qplib_qp.modify_flags |=
CMDQ_MODIFY_QP_MODIFY_MASK_MAX_RD_ATOMIC;
- qp->qplib_qp.max_rd_atomic = qp_attr->max_rd_atomic;
+ /* Cap the max_rd_atomic to device max */
+ qp->qplib_qp.max_rd_atomic = min_t(u32, qp_attr->max_rd_atomic,
+ dev_attr->max_qp_rd_atom);
}
if (qp_attr_mask & IB_QP_SQ_PSN) {
qp->qplib_qp.modify_flags |= CMDQ_MODIFY_QP_MODIFY_MASK_SQ_PSN;
qp->qplib_qp.sq.psn = qp_attr->sq_psn;
}
if (qp_attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) {
+ if (qp_attr->max_dest_rd_atomic >
+ dev_attr->max_qp_init_rd_atom) {
+ dev_err(rdev_to_dev(rdev),
+ "max_dest_rd_atomic requested%d is > dev_max%d",
+ qp_attr->max_dest_rd_atomic,
+ dev_attr->max_qp_init_rd_atom);
+ return -EINVAL;
+ }
+
qp->qplib_qp.modify_flags |=
CMDQ_MODIFY_QP_MODIFY_MASK_MAX_DEST_RD_ATOMIC;
qp->qplib_qp.max_dest_rd_atomic = qp_attr->max_dest_rd_atomic;
@@ -2403,7 +2398,7 @@ struct ib_cq *bnxt_re_create_cq(struct ib_device *ibdev,
}
cq->qplib_cq.sghead = cq->umem->sg_head.sgl;
cq->qplib_cq.nmap = cq->umem->nmap;
- cq->qplib_cq.dpi = uctx->dpi;
+ cq->qplib_cq.dpi = &uctx->dpi;
} else {
cq->max_cql = min_t(u32, entries, MAX_CQL_PER_POLL);
cq->cql = kcalloc(cq->max_cql, sizeof(struct bnxt_qplib_cqe),
@@ -2905,6 +2900,7 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc)
spin_lock_irqsave(&cq->cq_lock, flags);
budget = min_t(u32, num_entries, cq->max_cql);
+ num_entries = budget;
if (!cq->cql) {
dev_err(rdev_to_dev(cq->rdev), "POLL CQ : no CQL to use");
goto exit;
@@ -3031,6 +3027,11 @@ int bnxt_re_req_notify_cq(struct ib_cq *ib_cq,
else if (ib_cqn_flags & IB_CQ_SOLICITED)
type = DBR_DBR_TYPE_CQ_ARMSE;
+ /* Poll to see if there are missed events */
+ if ((ib_cqn_flags & IB_CQ_REPORT_MISSED_EVENTS) &&
+ !(bnxt_qplib_is_cq_empty(&cq->qplib_cq)))
+ return 1;
+
bnxt_qplib_req_notify_cq(&cq->qplib_cq, type);
return 0;
@@ -3245,6 +3246,12 @@ struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *ib_pd, u64 start, u64 length,
struct scatterlist *sg;
int entry;
+ if (length > BNXT_RE_MAX_MR_SIZE) {
+ dev_err(rdev_to_dev(rdev), "MR Size: %lld > Max supported:%ld\n",
+ length, BNXT_RE_MAX_MR_SIZE);
+ return ERR_PTR(-ENOMEM);
+ }
+
mr = kzalloc(sizeof(*mr), GFP_KERNEL);
if (!mr)
return ERR_PTR(-ENOMEM);
@@ -3388,8 +3395,26 @@ int bnxt_re_dealloc_ucontext(struct ib_ucontext *ib_uctx)
struct bnxt_re_ucontext *uctx = container_of(ib_uctx,
struct bnxt_re_ucontext,
ib_uctx);
+
+ struct bnxt_re_dev *rdev = uctx->rdev;
+ int rc = 0;
+
if (uctx->shpg)
free_page((unsigned long)uctx->shpg);
+
+ if (uctx->dpi.dbr) {
+ /* Free DPI only if this is the first PD allocated by the
+ * application and mark the context dpi as NULL
+ */
+ rc = bnxt_qplib_dealloc_dpi(&rdev->qplib_res,
+ &rdev->qplib_res.dpi_tbl,
+ &uctx->dpi);
+ if (rc)
+ dev_err(rdev_to_dev(rdev), "Deallocte HW DPI failed!");
+ /* Don't fail, continue*/
+ uctx->dpi.dbr = NULL;
+ }
+
kfree(uctx);
return 0;
}
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
index 6c160f6a5398..a0bb7e33d7ca 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
@@ -59,7 +59,6 @@ struct bnxt_re_pd {
struct bnxt_re_dev *rdev;
struct ib_pd ib_pd;
struct bnxt_qplib_pd qplib_pd;
- struct bnxt_qplib_dpi dpi;
struct bnxt_re_fence_data fence;
};
@@ -127,7 +126,7 @@ struct bnxt_re_mw {
struct bnxt_re_ucontext {
struct bnxt_re_dev *rdev;
struct ib_ucontext ib_uctx;
- struct bnxt_qplib_dpi *dpi;
+ struct bnxt_qplib_dpi dpi;
void *shpg;
spinlock_t sh_lock; /* protect shpg */
};
diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
index 1fce5e73216b..ceae2d92fb08 100644
--- a/drivers/infiniband/hw/bnxt_re/main.c
+++ b/drivers/infiniband/hw/bnxt_re/main.c
@@ -333,6 +333,7 @@ static int bnxt_re_net_stats_ctx_alloc(struct bnxt_re_dev *rdev,
bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_STAT_CTX_ALLOC, -1, -1);
req.update_period_ms = cpu_to_le32(1000);
req.stats_dma_addr = cpu_to_le64(dma_map);
+ req.stat_ctx_flags = STAT_CTX_ALLOC_REQ_STAT_CTX_FLAGS_ROCE;
bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp,
sizeof(resp), DFLT_HWRM_CMD_TIMEOUT);
rc = en_dev->en_ops->bnxt_send_fw_msg(en_dev, BNXT_ROCE_ULP, &fw_msg);
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
index f05500bcdcf1..9af1514e5944 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
@@ -1128,6 +1128,11 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp,
}
/* Each SGE entry = 1 WQE size16 */
wqe_size16 = wqe->num_sge;
+ /* HW requires wqe size has room for atleast one SGE even if
+ * none was supplied by ULP
+ */
+ if (!wqe->num_sge)
+ wqe_size16++;
}
/* Specifics */
@@ -1364,6 +1369,11 @@ int bnxt_qplib_post_recv(struct bnxt_qplib_qp *qp,
rqe->flags = wqe->flags;
rqe->wqe_size = wqe->num_sge +
((offsetof(typeof(*rqe), data) + 15) >> 4);
+ /* HW requires wqe size has room for atleast one SGE even if none
+ * was supplied by ULP
+ */
+ if (!wqe->num_sge)
+ rqe->wqe_size++;
/* Supply the rqe->wr_id index to the wr_id_tbl for now */
rqe->wr_id[0] = cpu_to_le32(sw_prod);
@@ -1885,6 +1895,25 @@ flush_rq:
return rc;
}
+bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq)
+{
+ struct cq_base *hw_cqe, **hw_cqe_ptr;
+ unsigned long flags;
+ u32 sw_cons, raw_cons;
+ bool rc = true;
+
+ spin_lock_irqsave(&cq->hwq.lock, flags);
+ raw_cons = cq->hwq.cons;
+ sw_cons = HWQ_CMP(raw_cons, &cq->hwq);
+ hw_cqe_ptr = (struct cq_base **)cq->hwq.pbl_ptr;
+ hw_cqe = &hw_cqe_ptr[CQE_PG(sw_cons)][CQE_IDX(sw_cons)];
+
+ /* Check for Valid bit. If the CQE is valid, return false */
+ rc = !CQE_CMP_VALID(hw_cqe, raw_cons, cq->hwq.max_elements);
+ spin_unlock_irqrestore(&cq->hwq.lock, flags);
+ return rc;
+}
+
static int bnxt_qplib_cq_process_res_raweth_qp1(struct bnxt_qplib_cq *cq,
struct cq_res_raweth_qp1 *hwcqe,
struct bnxt_qplib_cqe **pcqe,
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
index 36b7b7db0e3f..19176e06c98a 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h
@@ -449,6 +449,7 @@ int bnxt_qplib_create_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq);
int bnxt_qplib_destroy_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq);
int bnxt_qplib_poll_cq(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe,
int num, struct bnxt_qplib_qp **qp);
+bool bnxt_qplib_is_cq_empty(struct bnxt_qplib_cq *cq);
void bnxt_qplib_req_notify_cq(struct bnxt_qplib_cq *cq, u32 arm_type);
void bnxt_qplib_free_nq(struct bnxt_qplib_nq *nq);
int bnxt_qplib_alloc_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq);
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
index fde18cf0e406..ef91ab786dd4 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
@@ -51,6 +51,19 @@ const struct bnxt_qplib_gid bnxt_qplib_gid_zero = {{ 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 } };
/* Device */
+
+static bool bnxt_qplib_is_atomic_cap(struct bnxt_qplib_rcfw *rcfw)
+{
+ int rc;
+ u16 pcie_ctl2;
+
+ rc = pcie_capability_read_word(rcfw->pdev, PCI_EXP_DEVCTL2,
+ &pcie_ctl2);
+ if (rc)
+ return false;
+ return !!(pcie_ctl2 & PCI_EXP_DEVCTL2_ATOMIC_REQ);
+}
+
int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
struct bnxt_qplib_dev_attr *attr)
{
@@ -81,6 +94,8 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
/* Extract the context from the side buffer */
attr->max_qp = le32_to_cpu(sb->max_qp);
+ /* max_qp value reported by FW for PF doesn't include the QP1 for PF */
+ attr->max_qp += 1;
attr->max_qp_rd_atom =
sb->max_qp_rd_atom > BNXT_QPLIB_MAX_OUT_RD_ATOM ?
BNXT_QPLIB_MAX_OUT_RD_ATOM : sb->max_qp_rd_atom;
@@ -129,6 +144,7 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
attr->tqm_alloc_reqs[i * 4 + 3] = *(++tqm_alloc);
}
+ attr->is_atomic = bnxt_qplib_is_atomic_cap(rcfw);
bail:
bnxt_qplib_rcfw_free_sbuf(rcfw, sbuf);
return rc;
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.h b/drivers/infiniband/hw/bnxt_re/qplib_sp.h
index a543f959098b..2ce7e2a32cf0 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.h
@@ -42,6 +42,8 @@
#define BNXT_QPLIB_RESERVED_QP_WRS 128
+#define PCI_EXP_DEVCTL2_ATOMIC_REQ 0x0040
+
struct bnxt_qplib_dev_attr {
char fw_ver[32];
u16 max_sgid;
@@ -70,6 +72,7 @@ struct bnxt_qplib_dev_attr {
u32 max_inline_data;
u32 l2_db_size;
u8 tqm_alloc_reqs[MAX_TQM_ALLOC_REQ];
+ bool is_atomic;
};
struct bnxt_qplib_pd {
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index 29d30744d6c9..0cd0c1fa27d4 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -718,7 +718,7 @@ static struct ib_mr *iwch_alloc_mr(struct ib_pd *pd,
struct iwch_mr *mhp;
u32 mmid;
u32 stag = 0;
- int ret = 0;
+ int ret = -ENOMEM;
if (mr_type != IB_MR_TYPE_MEM_REG ||
max_num_sg > T3_MAX_FASTREG_DEPTH)
@@ -731,10 +731,8 @@ static struct ib_mr *iwch_alloc_mr(struct ib_pd *pd,
goto err;
mhp->pages = kcalloc(max_num_sg, sizeof(u64), GFP_KERNEL);
- if (!mhp->pages) {
- ret = -ENOMEM;
+ if (!mhp->pages)
goto pl_err;
- }
mhp->rhp = rhp;
ret = iwch_alloc_pbl(mhp, max_num_sg);
@@ -751,7 +749,8 @@ static struct ib_mr *iwch_alloc_mr(struct ib_pd *pd,
mhp->attr.state = 1;
mmid = (stag) >> 8;
mhp->ibmr.rkey = mhp->ibmr.lkey = stag;
- if (insert_handle(rhp, &rhp->mmidr, mhp, mmid))
+ ret = insert_handle(rhp, &rhp->mmidr, mhp, mmid);
+ if (ret)
goto err3;
pr_debug("%s mmid 0x%x mhp %p stag 0x%x\n", __func__, mmid, mhp, stag);
diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c
index e16fcaf6b5a3..be07da1997e6 100644
--- a/drivers/infiniband/hw/cxgb4/cq.c
+++ b/drivers/infiniband/hw/cxgb4/cq.c
@@ -963,6 +963,7 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev,
goto err3;
if (ucontext) {
+ ret = -ENOMEM;
mm = kmalloc(sizeof *mm, GFP_KERNEL);
if (!mm)
goto err4;
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
index bfc77596acbe..cb7fc0d35d1d 100644
--- a/drivers/infiniband/hw/cxgb4/qp.c
+++ b/drivers/infiniband/hw/cxgb4/qp.c
@@ -569,7 +569,7 @@ static int build_rdma_read(union t4_wr *wqe, struct ib_send_wr *wr, u8 *len16)
{
if (wr->num_sge > 1)
return -EINVAL;
- if (wr->num_sge) {
+ if (wr->num_sge && wr->sg_list[0].length) {
wqe->read.stag_src = cpu_to_be32(rdma_wr(wr)->rkey);
wqe->read.to_src_hi = cpu_to_be32((u32)(rdma_wr(wr)->remote_addr
>> 32));
diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c
index 2ba00b89df6a..94b54850ec75 100644
--- a/drivers/infiniband/hw/hfi1/chip.c
+++ b/drivers/infiniband/hw/hfi1/chip.c
@@ -12847,7 +12847,12 @@ static void remap_intr(struct hfi1_devdata *dd, int isrc, int msix_intr)
/* clear from the handled mask of the general interrupt */
m = isrc / 64;
n = isrc % 64;
- dd->gi_mask[m] &= ~((u64)1 << n);
+ if (likely(m < CCE_NUM_INT_CSRS)) {
+ dd->gi_mask[m] &= ~((u64)1 << n);
+ } else {
+ dd_dev_err(dd, "remap interrupt err\n");
+ return;
+ }
/* direct the chip source to the given MSI-X interrupt */
m = isrc / 8;
diff --git a/drivers/infiniband/hw/hfi1/qp.c b/drivers/infiniband/hw/hfi1/qp.c
index 650305cc0373..1a7af9f60c13 100644
--- a/drivers/infiniband/hw/hfi1/qp.c
+++ b/drivers/infiniband/hw/hfi1/qp.c
@@ -647,18 +647,17 @@ void qp_iter_print(struct seq_file *s, struct qp_iter *iter)
qp->pid);
}
-void *qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp,
- gfp_t gfp)
+void *qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp)
{
struct hfi1_qp_priv *priv;
- priv = kzalloc_node(sizeof(*priv), gfp, rdi->dparms.node);
+ priv = kzalloc_node(sizeof(*priv), GFP_KERNEL, rdi->dparms.node);
if (!priv)
return ERR_PTR(-ENOMEM);
priv->owner = qp;
- priv->s_ahg = kzalloc_node(sizeof(*priv->s_ahg), gfp,
+ priv->s_ahg = kzalloc_node(sizeof(*priv->s_ahg), GFP_KERNEL,
rdi->dparms.node);
if (!priv->s_ahg) {
kfree(priv);
diff --git a/drivers/infiniband/hw/hfi1/qp.h b/drivers/infiniband/hw/hfi1/qp.h
index 1eb9cd7b8c19..6fe542b6a927 100644
--- a/drivers/infiniband/hw/hfi1/qp.h
+++ b/drivers/infiniband/hw/hfi1/qp.h
@@ -123,8 +123,7 @@ void hfi1_migrate_qp(struct rvt_qp *qp);
/*
* Functions provided by hfi1 driver for rdmavt to use
*/
-void *qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp,
- gfp_t gfp);
+void *qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp);
void qp_priv_free(struct rvt_dev_info *rdi, struct rvt_qp *qp);
unsigned free_all_qps(struct rvt_dev_info *rdi);
void notify_qp_reset(struct rvt_qp *qp);
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index 37d5d29597a4..2540b65e242c 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -228,14 +228,14 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
switch (wr->opcode) {
case IB_WR_RDMA_READ:
ps_opcode = HNS_ROCE_WQE_OPCODE_RDMA_READ;
- set_raddr_seg(wqe, atomic_wr(wr)->remote_addr,
- atomic_wr(wr)->rkey);
+ set_raddr_seg(wqe, rdma_wr(wr)->remote_addr,
+ rdma_wr(wr)->rkey);
break;
case IB_WR_RDMA_WRITE:
case IB_WR_RDMA_WRITE_WITH_IMM:
ps_opcode = HNS_ROCE_WQE_OPCODE_RDMA_WRITE;
- set_raddr_seg(wqe, atomic_wr(wr)->remote_addr,
- atomic_wr(wr)->rkey);
+ set_raddr_seg(wqe, rdma_wr(wr)->remote_addr,
+ rdma_wr(wr)->rkey);
break;
case IB_WR_SEND:
case IB_WR_SEND_WITH_INV:
@@ -661,9 +661,11 @@ static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev)
union ib_gid dgid;
u64 subnet_prefix;
int attr_mask = 0;
- int i;
+ int i, j;
int ret;
+ u8 queue_en[HNS_ROCE_V1_RESV_QP] = { 0 };
u8 phy_port;
+ u8 port = 0;
u8 sl;
priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
@@ -709,27 +711,35 @@ static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev)
attr.rnr_retry = 7;
attr.timeout = 0x12;
attr.path_mtu = IB_MTU_256;
+ attr.ah_attr.type = RDMA_AH_ATTR_TYPE_ROCE;
rdma_ah_set_grh(&attr.ah_attr, NULL, 0, 0, 1, 0);
rdma_ah_set_static_rate(&attr.ah_attr, 3);
subnet_prefix = cpu_to_be64(0xfe80000000000000LL);
for (i = 0; i < HNS_ROCE_V1_RESV_QP; i++) {
+ phy_port = (i >= HNS_ROCE_MAX_PORTS) ? (i - 2) :
+ (i % HNS_ROCE_MAX_PORTS);
+ sl = i / HNS_ROCE_MAX_PORTS;
+
+ for (j = 0; j < caps->num_ports; j++) {
+ if (hr_dev->iboe.phy_port[j] == phy_port) {
+ queue_en[i] = 1;
+ port = j;
+ break;
+ }
+ }
+
+ if (!queue_en[i])
+ continue;
+
free_mr->mr_free_qp[i] = hns_roce_v1_create_lp_qp(hr_dev, pd);
- if (IS_ERR(free_mr->mr_free_qp[i])) {
+ if (!free_mr->mr_free_qp[i]) {
dev_err(dev, "Create loop qp failed!\n");
goto create_lp_qp_failed;
}
hr_qp = free_mr->mr_free_qp[i];
- sl = i / caps->num_ports;
-
- if (caps->num_ports == HNS_ROCE_MAX_PORTS)
- phy_port = (i >= HNS_ROCE_MAX_PORTS) ? (i - 2) :
- (i % caps->num_ports);
- else
- phy_port = i % caps->num_ports;
-
- hr_qp->port = phy_port + 1;
+ hr_qp->port = port;
hr_qp->phy_port = phy_port;
hr_qp->ibqp.qp_type = IB_QPT_RC;
hr_qp->ibqp.device = &hr_dev->ib_dev;
@@ -739,23 +749,22 @@ static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev)
hr_qp->ibqp.recv_cq = cq;
hr_qp->ibqp.send_cq = cq;
- rdma_ah_set_port_num(&attr.ah_attr, phy_port + 1);
- rdma_ah_set_sl(&attr.ah_attr, phy_port + 1);
- attr.port_num = phy_port + 1;
+ rdma_ah_set_port_num(&attr.ah_attr, port + 1);
+ rdma_ah_set_sl(&attr.ah_attr, sl);
+ attr.port_num = port + 1;
attr.dest_qp_num = hr_qp->qpn;
memcpy(rdma_ah_retrieve_dmac(&attr.ah_attr),
- hr_dev->dev_addr[phy_port],
+ hr_dev->dev_addr[port],
MAC_ADDR_OCTET_NUM);
memcpy(&dgid.raw, &subnet_prefix, sizeof(u64));
- memcpy(&dgid.raw[8], hr_dev->dev_addr[phy_port], 3);
- memcpy(&dgid.raw[13], hr_dev->dev_addr[phy_port] + 3, 3);
+ memcpy(&dgid.raw[8], hr_dev->dev_addr[port], 3);
+ memcpy(&dgid.raw[13], hr_dev->dev_addr[port] + 3, 3);
dgid.raw[11] = 0xff;
dgid.raw[12] = 0xfe;
dgid.raw[8] ^= 2;
rdma_ah_set_dgid_raw(&attr.ah_attr, dgid.raw);
- attr_mask |= IB_QP_PORT;
ret = hr_dev->hw->modify_qp(&hr_qp->ibqp, &attr, attr_mask,
IB_QPS_RESET, IB_QPS_INIT);
@@ -812,6 +821,9 @@ static void hns_roce_v1_release_lp_qp(struct hns_roce_dev *hr_dev)
for (i = 0; i < HNS_ROCE_V1_RESV_QP; i++) {
hr_qp = free_mr->mr_free_qp[i];
+ if (!hr_qp)
+ continue;
+
ret = hns_roce_v1_destroy_qp(&hr_qp->ibqp);
if (ret)
dev_err(dev, "Destroy qp %d for mr free failed(%d)!\n",
@@ -963,7 +975,7 @@ static void hns_roce_v1_mr_free_work_fn(struct work_struct *work)
msecs_to_jiffies(HNS_ROCE_V1_FREE_MR_TIMEOUT_MSECS) + jiffies;
int i;
int ret;
- int ne;
+ int ne = 0;
mr_work = container_of(work, struct hns_roce_mr_free_work, work);
hr_mr = (struct hns_roce_mr *)mr_work->mr;
@@ -976,6 +988,10 @@ static void hns_roce_v1_mr_free_work_fn(struct work_struct *work)
for (i = 0; i < HNS_ROCE_V1_RESV_QP; i++) {
hr_qp = free_mr->mr_free_qp[i];
+ if (!hr_qp)
+ continue;
+ ne++;
+
ret = hns_roce_v1_send_lp_wqe(hr_qp);
if (ret) {
dev_err(dev,
@@ -985,7 +1001,6 @@ static void hns_roce_v1_mr_free_work_fn(struct work_struct *work)
}
}
- ne = HNS_ROCE_V1_RESV_QP;
do {
ret = hns_roce_v1_poll_cq(&mr_free_cq->ib_cq, ne, wc);
if (ret < 0) {
@@ -995,7 +1010,8 @@ static void hns_roce_v1_mr_free_work_fn(struct work_struct *work)
goto free_work;
}
ne -= ret;
- msleep(HNS_ROCE_V1_FREE_MR_WAIT_VALUE);
+ usleep_range(HNS_ROCE_V1_FREE_MR_WAIT_VALUE * 1000,
+ (1 + HNS_ROCE_V1_FREE_MR_WAIT_VALUE) * 1000);
} while (ne && time_before_eq(jiffies, end));
if (ne != 0)
@@ -2181,7 +2197,7 @@ static int hns_roce_v1_poll_one(struct hns_roce_cq *hr_cq,
}
wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)];
++wq->tail;
- } else {
+ } else {
/* RQ conrespond to CQE */
wc->byte_len = le32_to_cpu(cqe->byte_cnt);
opcode = roce_get_field(cqe->cqe_byte_4,
@@ -3533,10 +3549,12 @@ static int check_qp_db_process_status(struct hns_roce_dev *hr_dev,
old_cnt = roce_get_field(old_send,
ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S);
- if (cur_cnt - old_cnt > SDB_ST_CMP_VAL)
+ if (cur_cnt - old_cnt >
+ SDB_ST_CMP_VAL) {
success_flags = 1;
- else {
- send_ptr = roce_get_field(old_send,
+ } else {
+ send_ptr =
+ roce_get_field(old_send,
ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_M,
ROCEE_SDB_SEND_PTR_SDB_SEND_PTR_S) +
roce_get_field(sdb_retry_cnt,
@@ -3641,6 +3659,7 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work)
struct hns_roce_dev *hr_dev;
struct hns_roce_qp *hr_qp;
struct device *dev;
+ unsigned long qpn;
int ret;
qp_work_entry = container_of(work, struct hns_roce_qp_work, work);
@@ -3648,8 +3667,9 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work)
dev = &hr_dev->pdev->dev;
priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
hr_qp = qp_work_entry->qp;
+ qpn = hr_qp->qpn;
- dev_dbg(dev, "Schedule destroy QP(0x%lx) work.\n", hr_qp->qpn);
+ dev_dbg(dev, "Schedule destroy QP(0x%lx) work.\n", qpn);
qp_work_entry->sche_cnt++;
@@ -3660,7 +3680,7 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work)
&qp_work_entry->db_wait_stage);
if (ret) {
dev_err(dev, "Check QP(0x%lx) db process status failed!\n",
- hr_qp->qpn);
+ qpn);
return;
}
@@ -3674,7 +3694,7 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work)
ret = hns_roce_v1_modify_qp(&hr_qp->ibqp, NULL, 0, hr_qp->state,
IB_QPS_RESET);
if (ret) {
- dev_err(dev, "Modify QP(0x%lx) to RST failed!\n", hr_qp->qpn);
+ dev_err(dev, "Modify QP(0x%lx) to RST failed!\n", qpn);
return;
}
@@ -3683,14 +3703,14 @@ static void hns_roce_v1_destroy_qp_work_fn(struct work_struct *work)
if (hr_qp->ibqp.qp_type == IB_QPT_RC) {
/* RC QP, release QPN */
- hns_roce_release_range_qp(hr_dev, hr_qp->qpn, 1);
+ hns_roce_release_range_qp(hr_dev, qpn, 1);
kfree(hr_qp);
} else
kfree(hr_to_hr_sqp(hr_qp));
kfree(qp_work_entry);
- dev_dbg(dev, "Accomplished destroy QP(0x%lx) work.\n", hr_qp->qpn);
+ dev_dbg(dev, "Accomplished destroy QP(0x%lx) work.\n", qpn);
}
int hns_roce_v1_destroy_qp(struct ib_qp *ibqp)
diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c
index c3b41f95e70a..d9777b662eba 100644
--- a/drivers/infiniband/hw/hns/hns_roce_main.c
+++ b/drivers/infiniband/hw/hns/hns_roce_main.c
@@ -125,8 +125,6 @@ static int handle_en_event(struct hns_roce_dev *hr_dev, u8 port,
return -ENODEV;
}
- spin_lock_bh(&hr_dev->iboe.lock);
-
switch (event) {
case NETDEV_UP:
case NETDEV_CHANGE:
@@ -144,7 +142,6 @@ static int handle_en_event(struct hns_roce_dev *hr_dev, u8 port,
break;
}
- spin_unlock_bh(&hr_dev->iboe.lock);
return 0;
}
diff --git a/drivers/infiniband/hw/i40iw/i40iw.h b/drivers/infiniband/hw/i40iw/i40iw.h
index da2eb5a281fa..9b1566468744 100644
--- a/drivers/infiniband/hw/i40iw/i40iw.h
+++ b/drivers/infiniband/hw/i40iw/i40iw.h
@@ -527,6 +527,7 @@ enum i40iw_status_code i40iw_add_mac_addr(struct i40iw_device *iwdev,
int i40iw_modify_qp(struct ib_qp *, struct ib_qp_attr *, int, struct ib_udata *);
void i40iw_cq_wq_destroy(struct i40iw_device *iwdev, struct i40iw_sc_cq *cq);
+void i40iw_cleanup_pending_cqp_op(struct i40iw_device *iwdev);
void i40iw_rem_pdusecount(struct i40iw_pd *iwpd, struct i40iw_device *iwdev);
void i40iw_add_pdusecount(struct i40iw_pd *iwpd);
void i40iw_rem_devusecount(struct i40iw_device *iwdev);
diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.c b/drivers/infiniband/hw/i40iw/i40iw_cm.c
index 6ae98aa7f74e..5a2fa743676c 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_cm.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_cm.c
@@ -3487,7 +3487,8 @@ static void i40iw_cm_disconn_true(struct i40iw_qp *iwqp)
if (((original_hw_tcp_state == I40IW_TCP_STATE_CLOSED) ||
(original_hw_tcp_state == I40IW_TCP_STATE_TIME_WAIT) ||
(last_ae == I40IW_AE_RDMAP_ROE_BAD_LLP_CLOSE) ||
- (last_ae == I40IW_AE_LLP_CONNECTION_RESET))) {
+ (last_ae == I40IW_AE_LLP_CONNECTION_RESET) ||
+ iwdev->reset)) {
issue_close = 1;
iwqp->cm_id = NULL;
if (!iwqp->flush_issued) {
@@ -4265,6 +4266,8 @@ void i40iw_cm_disconnect_all(struct i40iw_device *iwdev)
cm_node = container_of(list_node, struct i40iw_cm_node, connected_entry);
attr.qp_state = IB_QPS_ERR;
i40iw_modify_qp(&cm_node->iwqp->ibqp, &attr, IB_QP_STATE, NULL);
+ if (iwdev->reset)
+ i40iw_cm_disconn(cm_node->iwqp);
i40iw_rem_ref_cm_node(cm_node);
}
}
diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c
index a027e2072477..9ec1ae9a82c9 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c
@@ -1970,6 +1970,8 @@ static enum i40iw_status_code i40iw_sc_ccq_destroy(struct i40iw_sc_cq *ccq,
ret_code = i40iw_cqp_poll_registers(cqp, tail, 1000);
}
+ cqp->process_cqp_sds = i40iw_update_sds_noccq;
+
return ret_code;
}
diff --git a/drivers/infiniband/hw/i40iw/i40iw_main.c b/drivers/infiniband/hw/i40iw/i40iw_main.c
index e0f47cc2effc..ae8463ff59a7 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_main.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_main.c
@@ -243,6 +243,8 @@ static void i40iw_destroy_cqp(struct i40iw_device *iwdev, bool free_hwcqp)
if (free_hwcqp)
dev->cqp_ops->cqp_destroy(dev->cqp);
+ i40iw_cleanup_pending_cqp_op(iwdev);
+
i40iw_free_dma_mem(dev->hw, &cqp->sq);
kfree(cqp->scratch_array);
iwdev->cqp.scratch_array = NULL;
@@ -274,13 +276,12 @@ static void i40iw_disable_irq(struct i40iw_sc_dev *dev,
/**
* i40iw_destroy_aeq - destroy aeq
* @iwdev: iwarp device
- * @reset: true if called before reset
*
* Issue a destroy aeq request and
* free the resources associated with the aeq
* The function is called during driver unload
*/
-static void i40iw_destroy_aeq(struct i40iw_device *iwdev, bool reset)
+static void i40iw_destroy_aeq(struct i40iw_device *iwdev)
{
enum i40iw_status_code status = I40IW_ERR_NOT_READY;
struct i40iw_sc_dev *dev = &iwdev->sc_dev;
@@ -288,7 +289,7 @@ static void i40iw_destroy_aeq(struct i40iw_device *iwdev, bool reset)
if (!iwdev->msix_shared)
i40iw_disable_irq(dev, iwdev->iw_msixtbl, (void *)iwdev);
- if (reset)
+ if (iwdev->reset)
goto exit;
if (!dev->aeq_ops->aeq_destroy(&aeq->sc_aeq, 0, 1))
@@ -304,19 +305,17 @@ exit:
* i40iw_destroy_ceq - destroy ceq
* @iwdev: iwarp device
* @iwceq: ceq to be destroyed
- * @reset: true if called before reset
*
* Issue a destroy ceq request and
* free the resources associated with the ceq
*/
static void i40iw_destroy_ceq(struct i40iw_device *iwdev,
- struct i40iw_ceq *iwceq,
- bool reset)
+ struct i40iw_ceq *iwceq)
{
enum i40iw_status_code status;
struct i40iw_sc_dev *dev = &iwdev->sc_dev;
- if (reset)
+ if (iwdev->reset)
goto exit;
status = dev->ceq_ops->ceq_destroy(&iwceq->sc_ceq, 0, 1);
@@ -335,12 +334,11 @@ exit:
/**
* i40iw_dele_ceqs - destroy all ceq's
* @iwdev: iwarp device
- * @reset: true if called before reset
*
* Go through all of the device ceq's and for each ceq
* disable the ceq interrupt and destroy the ceq
*/
-static void i40iw_dele_ceqs(struct i40iw_device *iwdev, bool reset)
+static void i40iw_dele_ceqs(struct i40iw_device *iwdev)
{
u32 i = 0;
struct i40iw_sc_dev *dev = &iwdev->sc_dev;
@@ -349,32 +347,31 @@ static void i40iw_dele_ceqs(struct i40iw_device *iwdev, bool reset)
if (iwdev->msix_shared) {
i40iw_disable_irq(dev, msix_vec, (void *)iwdev);
- i40iw_destroy_ceq(iwdev, iwceq, reset);
+ i40iw_destroy_ceq(iwdev, iwceq);
iwceq++;
i++;
}
for (msix_vec++; i < iwdev->ceqs_count; i++, msix_vec++, iwceq++) {
i40iw_disable_irq(dev, msix_vec, (void *)iwceq);
- i40iw_destroy_ceq(iwdev, iwceq, reset);
+ i40iw_destroy_ceq(iwdev, iwceq);
}
}
/**
* i40iw_destroy_ccq - destroy control cq
* @iwdev: iwarp device
- * @reset: true if called before reset
*
* Issue destroy ccq request and
* free the resources associated with the ccq
*/
-static void i40iw_destroy_ccq(struct i40iw_device *iwdev, bool reset)
+static void i40iw_destroy_ccq(struct i40iw_device *iwdev)
{
struct i40iw_sc_dev *dev = &iwdev->sc_dev;
struct i40iw_ccq *ccq = &iwdev->ccq;
enum i40iw_status_code status = 0;
- if (!reset)
+ if (!iwdev->reset)
status = dev->ccq_ops->ccq_destroy(dev->ccq, 0, true);
if (status)
i40iw_pr_err("ccq destroy failed %d\n", status);
@@ -810,7 +807,7 @@ static enum i40iw_status_code i40iw_setup_ceqs(struct i40iw_device *iwdev,
iwceq->msix_idx = msix_vec->idx;
status = i40iw_configure_ceq_vector(iwdev, iwceq, ceq_id, msix_vec);
if (status) {
- i40iw_destroy_ceq(iwdev, iwceq, false);
+ i40iw_destroy_ceq(iwdev, iwceq);
break;
}
i40iw_enable_intr(&iwdev->sc_dev, msix_vec->idx);
@@ -912,7 +909,7 @@ static enum i40iw_status_code i40iw_setup_aeq(struct i40iw_device *iwdev)
status = i40iw_configure_aeq_vector(iwdev);
if (status) {
- i40iw_destroy_aeq(iwdev, false);
+ i40iw_destroy_aeq(iwdev);
return status;
}
@@ -1442,12 +1439,11 @@ static enum i40iw_status_code i40iw_save_msix_info(struct i40iw_device *iwdev,
/**
* i40iw_deinit_device - clean up the device resources
* @iwdev: iwarp device
- * @reset: true if called before reset
*
* Destroy the ib device interface, remove the mac ip entry and ipv4/ipv6 addresses,
* destroy the device queues and free the pble and the hmc objects
*/
-static void i40iw_deinit_device(struct i40iw_device *iwdev, bool reset)
+static void i40iw_deinit_device(struct i40iw_device *iwdev)
{
struct i40e_info *ldev = iwdev->ldev;
@@ -1464,7 +1460,7 @@ static void i40iw_deinit_device(struct i40iw_device *iwdev, bool reset)
i40iw_destroy_rdma_device(iwdev->iwibdev);
/* fallthrough */
case IP_ADDR_REGISTERED:
- if (!reset)
+ if (!iwdev->reset)
i40iw_del_macip_entry(iwdev, (u8)iwdev->mac_ip_table_idx);
/* fallthrough */
case INET_NOTIFIER:
@@ -1474,26 +1470,26 @@ static void i40iw_deinit_device(struct i40iw_device *iwdev, bool reset)
unregister_inet6addr_notifier(&i40iw_inetaddr6_notifier);
}
/* fallthrough */
+ case PBLE_CHUNK_MEM:
+ i40iw_destroy_pble_pool(dev, iwdev->pble_rsrc);
+ /* fallthrough */
case CEQ_CREATED:
- i40iw_dele_ceqs(iwdev, reset);
+ i40iw_dele_ceqs(iwdev);
/* fallthrough */
case AEQ_CREATED:
- i40iw_destroy_aeq(iwdev, reset);
+ i40iw_destroy_aeq(iwdev);
/* fallthrough */
case IEQ_CREATED:
- i40iw_puda_dele_resources(&iwdev->vsi, I40IW_PUDA_RSRC_TYPE_IEQ, reset);
+ i40iw_puda_dele_resources(&iwdev->vsi, I40IW_PUDA_RSRC_TYPE_IEQ, iwdev->reset);
/* fallthrough */
case ILQ_CREATED:
- i40iw_puda_dele_resources(&iwdev->vsi, I40IW_PUDA_RSRC_TYPE_ILQ, reset);
+ i40iw_puda_dele_resources(&iwdev->vsi, I40IW_PUDA_RSRC_TYPE_ILQ, iwdev->reset);
/* fallthrough */
case CCQ_CREATED:
- i40iw_destroy_ccq(iwdev, reset);
- /* fallthrough */
- case PBLE_CHUNK_MEM:
- i40iw_destroy_pble_pool(dev, iwdev->pble_rsrc);
+ i40iw_destroy_ccq(iwdev);
/* fallthrough */
case HMC_OBJS_CREATED:
- i40iw_del_hmc_objects(dev, dev->hmc_info, true, reset);
+ i40iw_del_hmc_objects(dev, dev->hmc_info, true, iwdev->reset);
/* fallthrough */
case CQP_CREATED:
i40iw_destroy_cqp(iwdev, true);
@@ -1670,6 +1666,7 @@ static int i40iw_open(struct i40e_info *ldev, struct i40e_client *client)
status = i40iw_hmc_init_pble(&iwdev->sc_dev, iwdev->pble_rsrc);
if (status)
break;
+ iwdev->init_state = PBLE_CHUNK_MEM;
iwdev->virtchnl_wq = alloc_ordered_workqueue("iwvch", WQ_MEM_RECLAIM);
i40iw_register_notifiers();
iwdev->init_state = INET_NOTIFIER;
@@ -1693,7 +1690,7 @@ static int i40iw_open(struct i40e_info *ldev, struct i40e_client *client)
} while (0);
i40iw_pr_err("status = %d last completion = %d\n", status, iwdev->init_state);
- i40iw_deinit_device(iwdev, false);
+ i40iw_deinit_device(iwdev);
return -ERESTART;
}
@@ -1774,9 +1771,12 @@ static void i40iw_close(struct i40e_info *ldev, struct i40e_client *client, bool
iwdev = &hdl->device;
iwdev->closing = true;
+ if (reset)
+ iwdev->reset = true;
+
i40iw_cm_disconnect_all(iwdev);
destroy_workqueue(iwdev->virtchnl_wq);
- i40iw_deinit_device(iwdev, reset);
+ i40iw_deinit_device(iwdev);
}
/**
diff --git a/drivers/infiniband/hw/i40iw/i40iw_puda.c b/drivers/infiniband/hw/i40iw/i40iw_puda.c
index db41ab40da9c..71050c5d29a0 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_puda.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_puda.c
@@ -408,6 +408,9 @@ enum i40iw_status_code i40iw_puda_send(struct i40iw_sc_qp *qp,
set_64bit_val(wqe, 0, info->paddr);
set_64bit_val(wqe, 8, LS_64(info->len, I40IWQPSQ_FRAG_LEN));
set_64bit_val(wqe, 16, header[0]);
+
+ /* Ensure all data is written before writing valid bit */
+ wmb();
set_64bit_val(wqe, 24, header[1]);
i40iw_debug_buf(qp->dev, I40IW_DEBUG_PUDA, "PUDA SEND WQE", wqe, 32);
@@ -1411,10 +1414,10 @@ static void i40iw_ieq_handle_exception(struct i40iw_puda_rsrc *ieq,
if (!list_empty(rxlist)) {
tmpbuf = (struct i40iw_puda_buf *)rxlist->next;
- plist = &tmpbuf->list;
while ((struct list_head *)tmpbuf != rxlist) {
if ((int)(buf->seqnum - tmpbuf->seqnum) < 0)
break;
+ plist = &tmpbuf->list;
tmpbuf = (struct i40iw_puda_buf *)plist->next;
}
/* Insert buf before tmpbuf */
diff --git a/drivers/infiniband/hw/i40iw/i40iw_utils.c b/drivers/infiniband/hw/i40iw/i40iw_utils.c
index 56d986924a4c..e311ec559f4e 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_utils.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_utils.c
@@ -337,6 +337,7 @@ struct i40iw_cqp_request *i40iw_get_cqp_request(struct i40iw_cqp *cqp, bool wait
*/
void i40iw_free_cqp_request(struct i40iw_cqp *cqp, struct i40iw_cqp_request *cqp_request)
{
+ struct i40iw_device *iwdev = container_of(cqp, struct i40iw_device, cqp);
unsigned long flags;
if (cqp_request->dynamic) {
@@ -350,6 +351,7 @@ void i40iw_free_cqp_request(struct i40iw_cqp *cqp, struct i40iw_cqp_request *cqp
list_add_tail(&cqp_request->list, &cqp->cqp_avail_reqs);
spin_unlock_irqrestore(&cqp->req_lock, flags);
}
+ wake_up(&iwdev->close_wq);
}
/**
@@ -365,6 +367,56 @@ void i40iw_put_cqp_request(struct i40iw_cqp *cqp,
}
/**
+ * i40iw_free_pending_cqp_request -free pending cqp request objs
+ * @cqp: cqp ptr
+ * @cqp_request: to be put back in cqp list
+ */
+static void i40iw_free_pending_cqp_request(struct i40iw_cqp *cqp,
+ struct i40iw_cqp_request *cqp_request)
+{
+ struct i40iw_device *iwdev = container_of(cqp, struct i40iw_device, cqp);
+
+ if (cqp_request->waiting) {
+ cqp_request->compl_info.error = true;
+ cqp_request->request_done = true;
+ wake_up(&cqp_request->waitq);
+ }
+ i40iw_put_cqp_request(cqp, cqp_request);
+ wait_event_timeout(iwdev->close_wq,
+ !atomic_read(&cqp_request->refcount),
+ 1000);
+}
+
+/**
+ * i40iw_cleanup_pending_cqp_op - clean-up cqp with no completions
+ * @iwdev: iwarp device
+ */
+void i40iw_cleanup_pending_cqp_op(struct i40iw_device *iwdev)
+{
+ struct i40iw_sc_dev *dev = &iwdev->sc_dev;
+ struct i40iw_cqp *cqp = &iwdev->cqp;
+ struct i40iw_cqp_request *cqp_request = NULL;
+ struct cqp_commands_info *pcmdinfo = NULL;
+ u32 i, pending_work, wqe_idx;
+
+ pending_work = I40IW_RING_WORK_AVAILABLE(cqp->sc_cqp.sq_ring);
+ wqe_idx = I40IW_RING_GETCURRENT_TAIL(cqp->sc_cqp.sq_ring);
+ for (i = 0; i < pending_work; i++) {
+ cqp_request = (struct i40iw_cqp_request *)(unsigned long)cqp->scratch_array[wqe_idx];
+ if (cqp_request)
+ i40iw_free_pending_cqp_request(cqp, cqp_request);
+ wqe_idx = (wqe_idx + 1) % I40IW_RING_GETSIZE(cqp->sc_cqp.sq_ring);
+ }
+
+ while (!list_empty(&dev->cqp_cmd_head)) {
+ pcmdinfo = (struct cqp_commands_info *)i40iw_remove_head(&dev->cqp_cmd_head);
+ cqp_request = container_of(pcmdinfo, struct i40iw_cqp_request, info);
+ if (cqp_request)
+ i40iw_free_pending_cqp_request(cqp, cqp_request);
+ }
+}
+
+/**
* i40iw_free_qp - callback after destroy cqp completes
* @cqp_request: cqp request for destroy qp
* @num: not used
@@ -546,8 +598,12 @@ void i40iw_rem_ref(struct ib_qp *ibqp)
cqp_info->in.u.qp_destroy.scratch = (uintptr_t)cqp_request;
cqp_info->in.u.qp_destroy.remove_hash_idx = true;
status = i40iw_handle_cqp_op(iwdev, cqp_request);
- if (status)
- i40iw_pr_err("CQP-OP Destroy QP fail");
+ if (!status)
+ return;
+
+ i40iw_rem_pdusecount(iwqp->iwpd, iwdev);
+ i40iw_free_qp_resources(iwdev, iwqp, qp_num);
+ i40iw_rem_devusecount(iwdev);
}
/**
diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.c b/drivers/infiniband/hw/i40iw/i40iw_verbs.c
index 4dbe61ec7a77..02d871db7ca5 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_verbs.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.c
@@ -426,9 +426,13 @@ void i40iw_free_qp_resources(struct i40iw_device *iwdev,
struct i40iw_qp *iwqp,
u32 qp_num)
{
+ struct i40iw_pbl *iwpbl = &iwqp->iwpbl;
+
i40iw_dealloc_push_page(iwdev, &iwqp->sc_qp);
if (qp_num)
i40iw_free_resource(iwdev, iwdev->allocated_qps, qp_num);
+ if (iwpbl->pbl_allocated)
+ i40iw_free_pble(iwdev->pble_rsrc, &iwpbl->pble_alloc);
i40iw_free_dma_mem(iwdev->sc_dev.hw, &iwqp->q2_ctx_mem);
i40iw_free_dma_mem(iwdev->sc_dev.hw, &iwqp->kqp.dma_mem);
kfree(iwqp->kqp.wrid_mem);
@@ -483,7 +487,7 @@ static int i40iw_setup_virt_qp(struct i40iw_device *iwdev,
struct i40iw_qp *iwqp,
struct i40iw_qp_init_info *init_info)
{
- struct i40iw_pbl *iwpbl = iwqp->iwpbl;
+ struct i40iw_pbl *iwpbl = &iwqp->iwpbl;
struct i40iw_qp_mr *qpmr = &iwpbl->qp_mr;
iwqp->page = qpmr->sq_page;
@@ -688,19 +692,22 @@ static struct ib_qp *i40iw_create_qp(struct ib_pd *ibpd,
ucontext = to_ucontext(ibpd->uobject->context);
if (req.user_wqe_buffers) {
+ struct i40iw_pbl *iwpbl;
+
spin_lock_irqsave(
&ucontext->qp_reg_mem_list_lock, flags);
- iwqp->iwpbl = i40iw_get_pbl(
+ iwpbl = i40iw_get_pbl(
(unsigned long)req.user_wqe_buffers,
&ucontext->qp_reg_mem_list);
spin_unlock_irqrestore(
&ucontext->qp_reg_mem_list_lock, flags);
- if (!iwqp->iwpbl) {
+ if (!iwpbl) {
err_code = -ENODATA;
i40iw_pr_err("no pbl info\n");
goto error;
}
+ memcpy(&iwqp->iwpbl, iwpbl, sizeof(iwqp->iwpbl));
}
}
err_code = i40iw_setup_virt_qp(iwdev, iwqp, &init_info);
@@ -1161,8 +1168,10 @@ static struct ib_cq *i40iw_create_cq(struct ib_device *ibdev,
memset(&req, 0, sizeof(req));
iwcq->user_mode = true;
ucontext = to_ucontext(context);
- if (ib_copy_from_udata(&req, udata, sizeof(struct i40iw_create_cq_req)))
+ if (ib_copy_from_udata(&req, udata, sizeof(struct i40iw_create_cq_req))) {
+ err_code = -EFAULT;
goto cq_free_resources;
+ }
spin_lock_irqsave(&ucontext->cq_reg_mem_list_lock, flags);
iwpbl = i40iw_get_pbl((unsigned long)req.user_cq_buffer,
@@ -2063,7 +2072,7 @@ static int i40iw_dereg_mr(struct ib_mr *ib_mr)
ucontext = to_ucontext(ibpd->uobject->context);
i40iw_del_memlist(iwmr, ucontext);
}
- if (iwpbl->pbl_allocated)
+ if (iwpbl->pbl_allocated && iwmr->type != IW_MEMREG_TYPE_QP)
i40iw_free_pble(iwdev->pble_rsrc, palloc);
kfree(iwmr);
return 0;
diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.h b/drivers/infiniband/hw/i40iw/i40iw_verbs.h
index 07c3fec77de6..9067443cd311 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_verbs.h
+++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.h
@@ -170,7 +170,7 @@ struct i40iw_qp {
struct i40iw_qp_kmode kqp;
struct i40iw_dma_mem host_ctx;
struct timer_list terminate_timer;
- struct i40iw_pbl *iwpbl;
+ struct i40iw_pbl iwpbl;
struct i40iw_dma_mem q2_ctx_mem;
struct i40iw_dma_mem ietf_mem;
struct completion sq_drained;
diff --git a/drivers/infiniband/hw/mlx4/cm.c b/drivers/infiniband/hw/mlx4/cm.c
index 1e6c526450d9..fedaf8260105 100644
--- a/drivers/infiniband/hw/mlx4/cm.c
+++ b/drivers/infiniband/hw/mlx4/cm.c
@@ -323,6 +323,9 @@ int mlx4_ib_multiplex_cm_handler(struct ib_device *ibdev, int port, int slave_id
mad->mad_hdr.attr_id == CM_REP_ATTR_ID ||
mad->mad_hdr.attr_id == CM_SIDR_REQ_ATTR_ID) {
sl_cm_id = get_local_comm_id(mad);
+ id = id_map_get(ibdev, &pv_cm_id, slave_id, sl_cm_id);
+ if (id)
+ goto cont;
id = id_map_alloc(ibdev, slave_id, sl_cm_id);
if (IS_ERR(id)) {
mlx4_ib_warn(ibdev, "%s: id{slave: %d, sl_cm_id: 0x%x} Failed to id_map_alloc\n",
@@ -343,6 +346,7 @@ int mlx4_ib_multiplex_cm_handler(struct ib_device *ibdev, int port, int slave_id
return -EINVAL;
}
+cont:
set_local_comm_id(mad, id->pv_cm_id);
if (mad->mad_hdr.attr_id == CM_DREQ_ATTR_ID)
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index 4f5a143fc0a7..ff931c580557 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -102,7 +102,7 @@ static int mlx4_ib_alloc_cq_buf(struct mlx4_ib_dev *dev, struct mlx4_ib_cq_buf *
int err;
err = mlx4_buf_alloc(dev->dev, nent * dev->dev->caps.cqe_size,
- PAGE_SIZE * 2, &buf->buf, GFP_KERNEL);
+ PAGE_SIZE * 2, &buf->buf);
if (err)
goto out;
@@ -113,7 +113,7 @@ static int mlx4_ib_alloc_cq_buf(struct mlx4_ib_dev *dev, struct mlx4_ib_cq_buf *
if (err)
goto err_buf;
- err = mlx4_buf_write_mtt(dev->dev, &buf->mtt, &buf->buf, GFP_KERNEL);
+ err = mlx4_buf_write_mtt(dev->dev, &buf->mtt, &buf->buf);
if (err)
goto err_mtt;
@@ -219,7 +219,7 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev,
uar = &to_mucontext(context)->uar;
} else {
- err = mlx4_db_alloc(dev->dev, &cq->db, 1, GFP_KERNEL);
+ err = mlx4_db_alloc(dev->dev, &cq->db, 1);
if (err)
goto err_cq;
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 75b2f7d4cd95..d1b43cbbfea7 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -1155,7 +1155,7 @@ static void mlx4_ib_disassociate_ucontext(struct ib_ucontext *ibcontext)
* call to mlx4_ib_vma_close.
*/
put_task_struct(owning_process);
- msleep(1);
+ usleep_range(1000, 2000);
owning_process = get_pid_task(ibcontext->tgid,
PIDTYPE_PID);
if (!owning_process ||
diff --git a/drivers/infiniband/hw/mlx4/mcg.c b/drivers/infiniband/hw/mlx4/mcg.c
index 3405e947dc1e..b73f89700ef9 100644
--- a/drivers/infiniband/hw/mlx4/mcg.c
+++ b/drivers/infiniband/hw/mlx4/mcg.c
@@ -1091,7 +1091,7 @@ static void _mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy
if (!count)
break;
- msleep(1);
+ usleep_range(1000, 2000);
} while (time_after(end, jiffies));
flush_workqueue(ctx->mcg_wq);
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index c2b9cbf4da05..9db82e67e959 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -185,7 +185,6 @@ enum mlx4_ib_qp_flags {
MLX4_IB_QP_LSO = IB_QP_CREATE_IPOIB_UD_LSO,
MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK = IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK,
MLX4_IB_QP_NETIF = IB_QP_CREATE_NETIF_QP,
- MLX4_IB_QP_CREATE_USE_GFP_NOIO = IB_QP_CREATE_USE_GFP_NOIO,
/* Mellanox specific flags start from IB_QP_CREATE_RESERVED_START */
MLX4_IB_ROCE_V2_GSI_QP = MLX4_IB_QP_CREATE_ROCE_V2_GSI,
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 996e9058e515..75c0e6c5dd56 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -634,8 +634,8 @@ static void mlx4_ib_free_qp_counter(struct mlx4_ib_dev *dev,
static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
struct ib_qp_init_attr *init_attr,
- struct ib_udata *udata, int sqpn, struct mlx4_ib_qp **caller_qp,
- gfp_t gfp)
+ struct ib_udata *udata, int sqpn,
+ struct mlx4_ib_qp **caller_qp)
{
int qpn;
int err;
@@ -691,14 +691,14 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
if (qp_type == MLX4_IB_QPT_SMI || qp_type == MLX4_IB_QPT_GSI ||
(qp_type & (MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_SMI_OWNER |
MLX4_IB_QPT_PROXY_GSI | MLX4_IB_QPT_TUN_SMI_OWNER))) {
- sqp = kzalloc(sizeof (struct mlx4_ib_sqp), gfp);
+ sqp = kzalloc(sizeof(struct mlx4_ib_sqp), GFP_KERNEL);
if (!sqp)
return -ENOMEM;
qp = &sqp->qp;
qp->pri.vid = 0xFFFF;
qp->alt.vid = 0xFFFF;
} else {
- qp = kzalloc(sizeof (struct mlx4_ib_qp), gfp);
+ qp = kzalloc(sizeof(struct mlx4_ib_qp), GFP_KERNEL);
if (!qp)
return -ENOMEM;
qp->pri.vid = 0xFFFF;
@@ -780,7 +780,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
goto err;
if (qp_has_rq(init_attr)) {
- err = mlx4_db_alloc(dev->dev, &qp->db, 0, gfp);
+ err = mlx4_db_alloc(dev->dev, &qp->db, 0);
if (err)
goto err;
@@ -788,7 +788,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
}
if (mlx4_buf_alloc(dev->dev, qp->buf_size, qp->buf_size,
- &qp->buf, gfp)) {
+ &qp->buf)) {
memcpy(&init_attr->cap, &backup_cap,
sizeof(backup_cap));
err = set_kernel_sq_size(dev, &init_attr->cap, qp_type,
@@ -797,7 +797,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
goto err_db;
if (mlx4_buf_alloc(dev->dev, qp->buf_size,
- PAGE_SIZE * 2, &qp->buf, gfp)) {
+ PAGE_SIZE * 2, &qp->buf)) {
err = -ENOMEM;
goto err_db;
}
@@ -808,20 +808,20 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
if (err)
goto err_buf;
- err = mlx4_buf_write_mtt(dev->dev, &qp->mtt, &qp->buf, gfp);
+ err = mlx4_buf_write_mtt(dev->dev, &qp->mtt, &qp->buf);
if (err)
goto err_mtt;
qp->sq.wrid = kmalloc_array(qp->sq.wqe_cnt, sizeof(u64),
- gfp | __GFP_NOWARN);
+ GFP_KERNEL | __GFP_NOWARN);
if (!qp->sq.wrid)
qp->sq.wrid = __vmalloc(qp->sq.wqe_cnt * sizeof(u64),
- gfp, PAGE_KERNEL);
+ GFP_KERNEL, PAGE_KERNEL);
qp->rq.wrid = kmalloc_array(qp->rq.wqe_cnt, sizeof(u64),
- gfp | __GFP_NOWARN);
+ GFP_KERNEL | __GFP_NOWARN);
if (!qp->rq.wrid)
qp->rq.wrid = __vmalloc(qp->rq.wqe_cnt * sizeof(u64),
- gfp, PAGE_KERNEL);
+ GFP_KERNEL, PAGE_KERNEL);
if (!qp->sq.wrid || !qp->rq.wrid) {
err = -ENOMEM;
goto err_wrid;
@@ -859,7 +859,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
if (init_attr->create_flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK)
qp->flags |= MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK;
- err = mlx4_qp_alloc(dev->dev, qpn, &qp->mqp, gfp);
+ err = mlx4_qp_alloc(dev->dev, qpn, &qp->mqp);
if (err)
goto err_qpn;
@@ -1127,10 +1127,7 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
int err;
int sup_u_create_flags = MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK;
u16 xrcdn = 0;
- gfp_t gfp;
- gfp = (init_attr->create_flags & MLX4_IB_QP_CREATE_USE_GFP_NOIO) ?
- GFP_NOIO : GFP_KERNEL;
/*
* We only support LSO, vendor flag1, and multicast loopback blocking,
* and only for kernel UD QPs.
@@ -1140,8 +1137,7 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
MLX4_IB_SRIOV_TUNNEL_QP |
MLX4_IB_SRIOV_SQP |
MLX4_IB_QP_NETIF |
- MLX4_IB_QP_CREATE_ROCE_V2_GSI |
- MLX4_IB_QP_CREATE_USE_GFP_NOIO))
+ MLX4_IB_QP_CREATE_ROCE_V2_GSI))
return ERR_PTR(-EINVAL);
if (init_attr->create_flags & IB_QP_CREATE_NETIF_QP) {
@@ -1154,7 +1150,6 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
return ERR_PTR(-EINVAL);
if ((init_attr->create_flags & ~(MLX4_IB_SRIOV_SQP |
- MLX4_IB_QP_CREATE_USE_GFP_NOIO |
MLX4_IB_QP_CREATE_ROCE_V2_GSI |
MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK) &&
init_attr->qp_type != IB_QPT_UD) ||
@@ -1179,7 +1174,7 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
case IB_QPT_RC:
case IB_QPT_UC:
case IB_QPT_RAW_PACKET:
- qp = kzalloc(sizeof *qp, gfp);
+ qp = kzalloc(sizeof(*qp), GFP_KERNEL);
if (!qp)
return ERR_PTR(-ENOMEM);
qp->pri.vid = 0xFFFF;
@@ -1188,7 +1183,7 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
case IB_QPT_UD:
{
err = create_qp_common(to_mdev(pd->device), pd, init_attr,
- udata, 0, &qp, gfp);
+ udata, 0, &qp);
if (err) {
kfree(qp);
return ERR_PTR(err);
@@ -1217,8 +1212,7 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
}
err = create_qp_common(to_mdev(pd->device), pd, init_attr, udata,
- sqpn,
- &qp, gfp);
+ sqpn, &qp);
if (err)
return ERR_PTR(err);
diff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c
index e32dd58937a8..0facaf5f6d23 100644
--- a/drivers/infiniband/hw/mlx4/srq.c
+++ b/drivers/infiniband/hw/mlx4/srq.c
@@ -135,14 +135,14 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
if (err)
goto err_mtt;
} else {
- err = mlx4_db_alloc(dev->dev, &srq->db, 0, GFP_KERNEL);
+ err = mlx4_db_alloc(dev->dev, &srq->db, 0);
if (err)
goto err_srq;
*srq->db.db = 0;
- if (mlx4_buf_alloc(dev->dev, buf_size, PAGE_SIZE * 2, &srq->buf,
- GFP_KERNEL)) {
+ if (mlx4_buf_alloc(dev->dev, buf_size, PAGE_SIZE * 2,
+ &srq->buf)) {
err = -ENOMEM;
goto err_db;
}
@@ -167,7 +167,7 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
if (err)
goto err_buf;
- err = mlx4_buf_write_mtt(dev->dev, &srq->mtt, &srq->buf, GFP_KERNEL);
+ err = mlx4_buf_write_mtt(dev->dev, &srq->mtt, &srq->buf);
if (err)
goto err_mtt;
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index 763bb5b36144..2c40a2e989d2 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -582,6 +582,15 @@ static void clean_keys(struct mlx5_ib_dev *dev, int c)
}
}
+static void mlx5_mr_cache_debugfs_cleanup(struct mlx5_ib_dev *dev)
+{
+ if (!mlx5_debugfs_root)
+ return;
+
+ debugfs_remove_recursive(dev->cache.root);
+ dev->cache.root = NULL;
+}
+
static int mlx5_mr_cache_debugfs_init(struct mlx5_ib_dev *dev)
{
struct mlx5_mr_cache *cache = &dev->cache;
@@ -600,38 +609,34 @@ static int mlx5_mr_cache_debugfs_init(struct mlx5_ib_dev *dev)
sprintf(ent->name, "%d", ent->order);
ent->dir = debugfs_create_dir(ent->name, cache->root);
if (!ent->dir)
- return -ENOMEM;
+ goto err;
ent->fsize = debugfs_create_file("size", 0600, ent->dir, ent,
&size_fops);
if (!ent->fsize)
- return -ENOMEM;
+ goto err;
ent->flimit = debugfs_create_file("limit", 0600, ent->dir, ent,
&limit_fops);
if (!ent->flimit)
- return -ENOMEM;
+ goto err;
ent->fcur = debugfs_create_u32("cur", 0400, ent->dir,
&ent->cur);
if (!ent->fcur)
- return -ENOMEM;
+ goto err;
ent->fmiss = debugfs_create_u32("miss", 0600, ent->dir,
&ent->miss);
if (!ent->fmiss)
- return -ENOMEM;
+ goto err;
}
return 0;
-}
-
-static void mlx5_mr_cache_debugfs_cleanup(struct mlx5_ib_dev *dev)
-{
- if (!mlx5_debugfs_root)
- return;
+err:
+ mlx5_mr_cache_debugfs_cleanup(dev);
- debugfs_remove_recursive(dev->cache.root);
+ return -ENOMEM;
}
static void delay_time_func(unsigned long ctx)
@@ -692,6 +697,11 @@ int mlx5_mr_cache_init(struct mlx5_ib_dev *dev)
if (err)
mlx5_ib_warn(dev, "cache debugfs failure\n");
+ /*
+ * We don't want to fail driver if debugfs failed to initialize,
+ * so we are not forwarding error to the user.
+ */
+
return 0;
}
@@ -825,7 +835,7 @@ static int mr_umem_get(struct ib_pd *pd, u64 start, u64 length,
access_flags, 0);
err = PTR_ERR_OR_ZERO(*umem);
if (err < 0) {
- mlx5_ib_err(dev, "umem get failed (%ld)\n", PTR_ERR(umem));
+ mlx5_ib_err(dev, "umem get failed (%d)\n", err);
return err;
}
@@ -1779,7 +1789,7 @@ mlx5_ib_sg_to_klms(struct mlx5_ib_mr *mr,
mr->ndescs = sg_nents;
for_each_sg(sgl, sg, sg_nents, i) {
- if (unlikely(i > mr->max_descs))
+ if (unlikely(i >= mr->max_descs))
break;
klms[i].va = cpu_to_be64(sg_dma_address(sg) + sg_offset);
klms[i].bcount = cpu_to_be32(sg_dma_len(sg) - sg_offset);
diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c
index ae0746754008..3d701c7a4c91 100644
--- a/drivers/infiniband/hw/mlx5/odp.c
+++ b/drivers/infiniband/hw/mlx5/odp.c
@@ -939,7 +939,7 @@ static int mlx5_ib_mr_initiator_pfault_handler(
if (qp->ibqp.qp_type != IB_QPT_RC) {
av = *wqe;
- if (av->dqp_dct & be32_to_cpu(MLX5_WQE_AV_EXT))
+ if (av->dqp_dct & cpu_to_be32(MLX5_EXTENDED_UD_AV))
*wqe += sizeof(struct mlx5_av);
else
*wqe += sizeof(struct mlx5_base_av);
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index 8f9d8b4ad583..b0adf65e4bdb 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -551,7 +551,7 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
if ((0x0F000100 == (pcs_control_status0 & 0x0F000100))
|| (0x0F000100 == (pcs_control_status1 & 0x0F000100)))
int_cnt++;
- msleep(1);
+ usleep_range(1000, 2000);
}
if (int_cnt > 1) {
spin_lock_irqsave(&nesadapter->phy_lock, flags);
@@ -592,7 +592,7 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
break;
}
}
- msleep(1);
+ usleep_range(1000, 2000);
}
}
}
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
index 2f30bda8457a..27d5e8d9f08d 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
@@ -744,7 +744,8 @@ err:
if (is_uctx_pd) {
ocrdma_release_ucontext_pd(uctx);
} else {
- status = _ocrdma_dealloc_pd(dev, pd);
+ if (_ocrdma_dealloc_pd(dev, pd))
+ pr_err("%s: _ocrdma_dealloc_pd() failed\n", __func__);
}
exit:
return ERR_PTR(status);
@@ -1901,6 +1902,7 @@ struct ib_srq *ocrdma_create_srq(struct ib_pd *ibpd,
goto err;
if (udata == NULL) {
+ status = -ENOMEM;
srq->rqe_wr_id_tbl = kzalloc(sizeof(u64) * srq->rq.max_cnt,
GFP_KERNEL);
if (srq->rqe_wr_id_tbl == NULL)
diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c
index 548e4d1e998f..2ae71b8f1ba8 100644
--- a/drivers/infiniband/hw/qedr/verbs.c
+++ b/drivers/infiniband/hw/qedr/verbs.c
@@ -53,6 +53,14 @@
#define DB_ADDR_SHIFT(addr) ((addr) << DB_PWM_ADDR_OFFSET_SHIFT)
+static inline int qedr_ib_copy_to_udata(struct ib_udata *udata, void *src,
+ size_t len)
+{
+ size_t min_len = min_t(size_t, len, udata->outlen);
+
+ return ib_copy_to_udata(udata, src, min_len);
+}
+
int qedr_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey)
{
if (index > QEDR_ROCE_PKEY_TABLE_LEN)
@@ -378,7 +386,7 @@ struct ib_ucontext *qedr_alloc_ucontext(struct ib_device *ibdev,
uresp.sges_per_srq_wr = dev->attr.max_srq_sge;
uresp.max_cqes = QEDR_MAX_CQES;
- rc = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
+ rc = qedr_ib_copy_to_udata(udata, &uresp, sizeof(uresp));
if (rc)
goto err;
@@ -499,7 +507,7 @@ struct ib_pd *qedr_alloc_pd(struct ib_device *ibdev,
uresp.pd_id = pd_id;
- rc = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
+ rc = qedr_ib_copy_to_udata(udata, &uresp, sizeof(uresp));
if (rc) {
DP_ERR(dev, "copy error pd_id=0x%x.\n", pd_id);
dev->ops->rdma_dealloc_pd(dev->rdma_ctx, pd_id);
@@ -729,7 +737,7 @@ static int qedr_copy_cq_uresp(struct qedr_dev *dev,
uresp.db_offset = DB_ADDR_SHIFT(DQ_PWM_OFFSET_UCM_RDMA_CQ_CONS_32BIT);
uresp.icid = cq->icid;
- rc = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
+ rc = qedr_ib_copy_to_udata(udata, &uresp, sizeof(uresp));
if (rc)
DP_ERR(dev, "copy error cqid=0x%x.\n", cq->icid);
@@ -1238,7 +1246,7 @@ static int qedr_copy_qp_uresp(struct qedr_dev *dev,
uresp.atomic_supported = dev->atomic_cap != IB_ATOMIC_NONE;
uresp.qp_id = qp->qp_id;
- rc = ib_copy_to_udata(udata, &uresp, sizeof(uresp));
+ rc = qedr_ib_copy_to_udata(udata, &uresp, sizeof(uresp));
if (rc)
DP_ERR(dev,
"create qp: failed a copy to user space with qp icid=0x%x.\n",
diff --git a/drivers/infiniband/hw/qib/qib_qp.c b/drivers/infiniband/hw/qib/qib_qp.c
index 5984981e7dd4..a343e3b5d4cb 100644
--- a/drivers/infiniband/hw/qib/qib_qp.c
+++ b/drivers/infiniband/hw/qib/qib_qp.c
@@ -104,10 +104,9 @@ const struct rvt_operation_params qib_post_parms[RVT_OPERATION_MAX] = {
};
-static void get_map_page(struct rvt_qpn_table *qpt, struct rvt_qpn_map *map,
- gfp_t gfp)
+static void get_map_page(struct rvt_qpn_table *qpt, struct rvt_qpn_map *map)
{
- unsigned long page = get_zeroed_page(gfp);
+ unsigned long page = get_zeroed_page(GFP_KERNEL);
/*
* Free the page if someone raced with us installing it.
@@ -126,7 +125,7 @@ static void get_map_page(struct rvt_qpn_table *qpt, struct rvt_qpn_map *map,
* zero/one for QP type IB_QPT_SMI/IB_QPT_GSI.
*/
int qib_alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
- enum ib_qp_type type, u8 port, gfp_t gfp)
+ enum ib_qp_type type, u8 port)
{
u32 i, offset, max_scan, qpn;
struct rvt_qpn_map *map;
@@ -160,7 +159,7 @@ int qib_alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
max_scan = qpt->nmaps - !offset;
for (i = 0;;) {
if (unlikely(!map->page)) {
- get_map_page(qpt, map, gfp);
+ get_map_page(qpt, map);
if (unlikely(!map->page))
break;
}
@@ -317,16 +316,16 @@ u32 qib_mtu_from_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp, u32 pmtu)
return ib_mtu_enum_to_int(pmtu);
}
-void *qib_qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp, gfp_t gfp)
+void *qib_qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp)
{
struct qib_qp_priv *priv;
- priv = kzalloc(sizeof(*priv), gfp);
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return ERR_PTR(-ENOMEM);
priv->owner = qp;
- priv->s_hdr = kzalloc(sizeof(*priv->s_hdr), gfp);
+ priv->s_hdr = kzalloc(sizeof(*priv->s_hdr), GFP_KERNEL);
if (!priv->s_hdr) {
kfree(priv);
return ERR_PTR(-ENOMEM);
diff --git a/drivers/infiniband/hw/qib/qib_verbs.h b/drivers/infiniband/hw/qib/qib_verbs.h
index da0db5485ddc..a52fc67b40d7 100644
--- a/drivers/infiniband/hw/qib/qib_verbs.h
+++ b/drivers/infiniband/hw/qib/qib_verbs.h
@@ -274,11 +274,11 @@ int qib_get_counters(struct qib_pportdata *ppd,
* Functions provided by qib driver for rdmavt to use
*/
unsigned qib_free_all_qps(struct rvt_dev_info *rdi);
-void *qib_qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp, gfp_t gfp);
+void *qib_qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp);
void qib_qp_priv_free(struct rvt_dev_info *rdi, struct rvt_qp *qp);
void qib_notify_qp_reset(struct rvt_qp *qp);
int qib_alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
- enum ib_qp_type type, u8 port, gfp_t gfp);
+ enum ib_qp_type type, u8 port);
void qib_restart_rc(struct rvt_qp *qp, u32 psn, int wait);
#ifdef CONFIG_DEBUG_FS
diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c
index 727e81cc2c8f..8876ee7bc326 100644
--- a/drivers/infiniband/sw/rdmavt/qp.c
+++ b/drivers/infiniband/sw/rdmavt/qp.c
@@ -118,10 +118,9 @@ const int ib_rvt_state_ops[IB_QPS_ERR + 1] = {
EXPORT_SYMBOL(ib_rvt_state_ops);
static void get_map_page(struct rvt_qpn_table *qpt,
- struct rvt_qpn_map *map,
- gfp_t gfp)
+ struct rvt_qpn_map *map)
{
- unsigned long page = get_zeroed_page(gfp);
+ unsigned long page = get_zeroed_page(GFP_KERNEL);
/*
* Free the page if someone raced with us installing it.
@@ -173,7 +172,7 @@ static int init_qpn_table(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt)
rdi->dparms.qpn_res_start, rdi->dparms.qpn_res_end);
for (i = rdi->dparms.qpn_res_start; i <= rdi->dparms.qpn_res_end; i++) {
if (!map->page) {
- get_map_page(qpt, map, GFP_KERNEL);
+ get_map_page(qpt, map);
if (!map->page) {
ret = -ENOMEM;
break;
@@ -342,14 +341,14 @@ static inline unsigned mk_qpn(struct rvt_qpn_table *qpt,
* Return: The queue pair number
*/
static int alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
- enum ib_qp_type type, u8 port_num, gfp_t gfp)
+ enum ib_qp_type type, u8 port_num)
{
u32 i, offset, max_scan, qpn;
struct rvt_qpn_map *map;
u32 ret;
if (rdi->driver_f.alloc_qpn)
- return rdi->driver_f.alloc_qpn(rdi, qpt, type, port_num, gfp);
+ return rdi->driver_f.alloc_qpn(rdi, qpt, type, port_num);
if (type == IB_QPT_SMI || type == IB_QPT_GSI) {
unsigned n;
@@ -374,7 +373,7 @@ static int alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
max_scan = qpt->nmaps - !offset;
for (i = 0;;) {
if (unlikely(!map->page)) {
- get_map_page(qpt, map, gfp);
+ get_map_page(qpt, map);
if (unlikely(!map->page))
break;
}
@@ -672,7 +671,6 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
struct ib_qp *ret = ERR_PTR(-ENOMEM);
struct rvt_dev_info *rdi = ib_to_rvt(ibpd->device);
void *priv = NULL;
- gfp_t gfp;
size_t sqsize;
if (!rdi)
@@ -680,18 +678,9 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
if (init_attr->cap.max_send_sge > rdi->dparms.props.max_sge ||
init_attr->cap.max_send_wr > rdi->dparms.props.max_qp_wr ||
- init_attr->create_flags & ~(IB_QP_CREATE_USE_GFP_NOIO))
+ init_attr->create_flags)
return ERR_PTR(-EINVAL);
- /* GFP_NOIO is applicable to RC QP's only */
-
- if (init_attr->create_flags & IB_QP_CREATE_USE_GFP_NOIO &&
- init_attr->qp_type != IB_QPT_RC)
- return ERR_PTR(-EINVAL);
-
- gfp = init_attr->create_flags & IB_QP_CREATE_USE_GFP_NOIO ?
- GFP_NOIO : GFP_KERNEL;
-
/* Check receive queue parameters if no SRQ is specified. */
if (!init_attr->srq) {
if (init_attr->cap.max_recv_sge > rdi->dparms.props.max_sge ||
@@ -719,14 +708,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
sz = sizeof(struct rvt_sge) *
init_attr->cap.max_send_sge +
sizeof(struct rvt_swqe);
- if (gfp == GFP_NOIO)
- swq = __vmalloc(
- sqsize * sz,
- gfp | __GFP_ZERO, PAGE_KERNEL);
- else
- swq = vzalloc_node(
- sqsize * sz,
- rdi->dparms.node);
+ swq = vzalloc_node(sqsize * sz, rdi->dparms.node);
if (!swq)
return ERR_PTR(-ENOMEM);
@@ -741,7 +723,8 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
} else if (init_attr->cap.max_recv_sge > 1)
sg_list_sz = sizeof(*qp->r_sg_list) *
(init_attr->cap.max_recv_sge - 1);
- qp = kzalloc_node(sz + sg_list_sz, gfp, rdi->dparms.node);
+ qp = kzalloc_node(sz + sg_list_sz, GFP_KERNEL,
+ rdi->dparms.node);
if (!qp)
goto bail_swq;
@@ -751,7 +734,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
kzalloc_node(
sizeof(*qp->s_ack_queue) *
rvt_max_atomic(rdi),
- gfp,
+ GFP_KERNEL,
rdi->dparms.node);
if (!qp->s_ack_queue)
goto bail_qp;
@@ -766,7 +749,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
* Driver needs to set up it's private QP structure and do any
* initialization that is needed.
*/
- priv = rdi->driver_f.qp_priv_alloc(rdi, qp, gfp);
+ priv = rdi->driver_f.qp_priv_alloc(rdi, qp);
if (IS_ERR(priv)) {
ret = priv;
goto bail_qp;
@@ -786,11 +769,6 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
qp->r_rq.wq = vmalloc_user(
sizeof(struct rvt_rwq) +
qp->r_rq.size * sz);
- else if (gfp == GFP_NOIO)
- qp->r_rq.wq = __vmalloc(
- sizeof(struct rvt_rwq) +
- qp->r_rq.size * sz,
- gfp | __GFP_ZERO, PAGE_KERNEL);
else
qp->r_rq.wq = vzalloc_node(
sizeof(struct rvt_rwq) +
@@ -824,7 +802,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
err = alloc_qpn(rdi, &rdi->qp_dev->qpn_table,
init_attr->qp_type,
- init_attr->port_num, gfp);
+ init_attr->port_num);
if (err < 0) {
ret = ERR_PTR(err);
goto bail_rq_wq;
@@ -1280,9 +1258,7 @@ int rvt_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
if (attr_mask & IB_QP_TIMEOUT) {
qp->timeout = attr->timeout;
- qp->timeout_jiffies =
- usecs_to_jiffies((4096UL * (1UL << qp->timeout)) /
- 1000UL);
+ qp->timeout_jiffies = rvt_timeout_to_jiffies(qp->timeout);
}
if (attr_mask & IB_QP_QKEY)
diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c
index c3a140ed4df2..08f3f90d2912 100644
--- a/drivers/infiniband/sw/rxe/rxe_net.c
+++ b/drivers/infiniband/sw/rxe/rxe_net.c
@@ -441,6 +441,8 @@ static void rxe_skb_tx_dtor(struct sk_buff *skb)
if (unlikely(qp->need_req_skb &&
skb_out < RXE_INFLIGHT_SKBS_PER_QP_LOW))
rxe_run_task(&qp->req.task, 1);
+
+ rxe_drop_ref(qp);
}
int rxe_send(struct rxe_dev *rxe, struct rxe_pkt_info *pkt, struct sk_buff *skb)
@@ -473,6 +475,7 @@ int rxe_send(struct rxe_dev *rxe, struct rxe_pkt_info *pkt, struct sk_buff *skb)
return -EAGAIN;
}
+ rxe_add_ref(pkt->qp);
atomic_inc(&pkt->qp->skb_out);
kfree_skb(skb);
diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
index be944d5aa9af..a958ee918a49 100644
--- a/drivers/infiniband/sw/rxe/rxe_resp.c
+++ b/drivers/infiniband/sw/rxe/rxe_resp.c
@@ -1219,6 +1219,9 @@ void rxe_drain_req_pkts(struct rxe_qp *qp, bool notify)
kfree_skb(skb);
}
+ if (notify)
+ return;
+
while (!qp->srq && qp->rq.queue && queue_head(qp->rq.queue))
advance_consumer(qp->rq.queue);
}
diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
index 073e66783f1d..af90a7d42b96 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
@@ -914,6 +914,9 @@ static int rxe_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
spin_unlock_irqrestore(&rq->producer_lock, flags);
+ if (qp->resp.state == QP_STATE_ERROR)
+ rxe_run_task(&qp->resp.task, 1);
+
err1:
return err;
}
@@ -1240,6 +1243,8 @@ int rxe_register_device(struct rxe_dev *rxe)
addrconf_addr_eui48((unsigned char *)&dev->node_guid,
rxe->ndev->dev_addr);
dev->dev.dma_ops = &dma_virt_ops;
+ dma_coerce_mask_and_coherent(&dev->dev,
+ dma_get_required_mask(dev->dev.parent));
dev->uverbs_abi_ver = RXE_UVERBS_ABI_VERSION;
dev->uverbs_cmd_mask = BIT_ULL(IB_USER_VERBS_CMD_GET_CONTEXT)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index ff50a7bd66d8..7ac25059c40f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -336,6 +336,7 @@ struct ipoib_dev_priv {
unsigned long flags;
struct rw_semaphore vlan_rwsem;
+ struct mutex mcast_mutex;
struct rb_root path_tree;
struct list_head path_list;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 7cbcfdac6529..d69410c2ed97 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -39,6 +39,7 @@
#include <linux/vmalloc.h>
#include <linux/moduleparam.h>
#include <linux/sched/signal.h>
+#include <linux/sched/mm.h>
#include "ipoib.h"
@@ -510,7 +511,6 @@ static int ipoib_cm_rx_handler(struct ib_cm_id *cm_id,
case IB_CM_REQ_RECEIVED:
return ipoib_cm_req_handler(cm_id, event);
case IB_CM_DREQ_RECEIVED:
- p = cm_id->context;
ib_send_cm_drep(cm_id, NULL, 0);
/* Fall through */
case IB_CM_REJ_RECEIVED:
@@ -954,7 +954,7 @@ void ipoib_cm_dev_stop(struct net_device *dev)
break;
}
spin_unlock_irq(&priv->lock);
- msleep(1);
+ usleep_range(1000, 2000);
ipoib_drain_cq(dev);
spin_lock_irq(&priv->lock);
}
@@ -1047,9 +1047,8 @@ static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_
.sq_sig_type = IB_SIGNAL_ALL_WR,
.qp_type = IB_QPT_RC,
.qp_context = tx,
- .create_flags = IB_QP_CREATE_USE_GFP_NOIO
+ .create_flags = 0
};
-
struct ib_qp *tx_qp;
if (dev->features & NETIF_F_SG)
@@ -1057,10 +1056,6 @@ static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_
min_t(u32, priv->ca->attrs.max_sge, MAX_SKB_FRAGS + 1);
tx_qp = ib_create_qp(priv->pd, &attr);
- if (PTR_ERR(tx_qp) == -EINVAL) {
- attr.create_flags &= ~IB_QP_CREATE_USE_GFP_NOIO;
- tx_qp = ib_create_qp(priv->pd, &attr);
- }
tx->max_send_sge = attr.cap.max_send_sge;
return tx_qp;
}
@@ -1131,10 +1126,11 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn,
struct sa_path_rec *pathrec)
{
struct ipoib_dev_priv *priv = ipoib_priv(p->dev);
+ unsigned int noio_flag;
int ret;
- p->tx_ring = __vmalloc(ipoib_sendq_size * sizeof *p->tx_ring,
- GFP_NOIO, PAGE_KERNEL);
+ noio_flag = memalloc_noio_save();
+ p->tx_ring = vzalloc(ipoib_sendq_size * sizeof(*p->tx_ring));
if (!p->tx_ring) {
ret = -ENOMEM;
goto err_tx;
@@ -1142,9 +1138,10 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn,
memset(p->tx_ring, 0, ipoib_sendq_size * sizeof *p->tx_ring);
p->qp = ipoib_cm_create_tx_qp(p->dev, p);
+ memalloc_noio_restore(noio_flag);
if (IS_ERR(p->qp)) {
ret = PTR_ERR(p->qp);
- ipoib_warn(priv, "failed to allocate tx qp: %d\n", ret);
+ ipoib_warn(priv, "failed to create tx qp: %d\n", ret);
goto err_qp;
}
@@ -1206,7 +1203,7 @@ static void ipoib_cm_tx_destroy(struct ipoib_cm_tx *p)
goto timeout;
}
- msleep(1);
+ usleep_range(1000, 2000);
}
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
index 7871379342f4..184a22f48027 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
@@ -52,7 +52,8 @@ static const struct ipoib_stats ipoib_gstrings_stats[] = {
IPOIB_NETDEV_STAT(tx_bytes),
IPOIB_NETDEV_STAT(tx_errors),
IPOIB_NETDEV_STAT(rx_dropped),
- IPOIB_NETDEV_STAT(tx_dropped)
+ IPOIB_NETDEV_STAT(tx_dropped),
+ IPOIB_NETDEV_STAT(multicast),
};
#define IPOIB_GLOBAL_STATS_LEN ARRAY_SIZE(ipoib_gstrings_stats)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index efe7402f4885..2e075377242e 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -256,6 +256,8 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
++dev->stats.rx_packets;
dev->stats.rx_bytes += skb->len;
+ if (skb->pkt_type == PACKET_MULTICAST)
+ dev->stats.multicast++;
skb->dev = dev;
if ((dev->features & NETIF_F_RXCSUM) &&
@@ -709,6 +711,27 @@ static int recvs_pending(struct net_device *dev)
return pending;
}
+static void check_qp_movement_and_print(struct ipoib_dev_priv *priv,
+ struct ib_qp *qp,
+ enum ib_qp_state new_state)
+{
+ struct ib_qp_attr qp_attr;
+ struct ib_qp_init_attr query_init_attr;
+ int ret;
+
+ ret = ib_query_qp(qp, &qp_attr, IB_QP_STATE, &query_init_attr);
+ if (ret) {
+ ipoib_warn(priv, "%s: Failed to query QP\n", __func__);
+ return;
+ }
+ /* print according to the new-state and the previous state.*/
+ if (new_state == IB_QPS_ERR && qp_attr.qp_state == IB_QPS_RESET)
+ ipoib_dbg(priv, "Failed modify QP, IB_QPS_RESET to IB_QPS_ERR, acceptable\n");
+ else
+ ipoib_warn(priv, "Failed to modify QP to state: %d from state: %d\n",
+ new_state, qp_attr.qp_state);
+}
+
int ipoib_ib_dev_stop_default(struct net_device *dev)
{
struct ipoib_dev_priv *priv = ipoib_priv(dev);
@@ -728,7 +751,7 @@ int ipoib_ib_dev_stop_default(struct net_device *dev)
*/
qp_attr.qp_state = IB_QPS_ERR;
if (ib_modify_qp(priv->qp, &qp_attr, IB_QP_STATE))
- ipoib_warn(priv, "Failed to modify QP to ERROR state\n");
+ check_qp_movement_and_print(priv, priv->qp, IB_QPS_ERR);
/* Wait for all sends and receives to complete */
begin = jiffies;
@@ -770,7 +793,7 @@ int ipoib_ib_dev_stop_default(struct net_device *dev)
ipoib_drain_cq(dev);
- msleep(1);
+ usleep_range(1000, 2000);
}
ipoib_dbg(priv, "All sends and receives done.\n");
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 6e86eeee370e..6c77df34869d 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -233,6 +233,7 @@ static netdev_features_t ipoib_fix_features(struct net_device *dev, netdev_featu
static int ipoib_change_mtu(struct net_device *dev, int new_mtu)
{
struct ipoib_dev_priv *priv = ipoib_priv(dev);
+ int ret = 0;
/* dev->mtu > 2K ==> connected mode */
if (ipoib_cm_admin_enabled(dev)) {
@@ -256,9 +257,34 @@ static int ipoib_change_mtu(struct net_device *dev, int new_mtu)
ipoib_dbg(priv, "MTU must be smaller than the underlying "
"link layer MTU - 4 (%u)\n", priv->mcast_mtu);
- dev->mtu = min(priv->mcast_mtu, priv->admin_mtu);
+ new_mtu = min(priv->mcast_mtu, priv->admin_mtu);
- return 0;
+ if (priv->rn_ops->ndo_change_mtu) {
+ bool carrier_status = netif_carrier_ok(dev);
+
+ netif_carrier_off(dev);
+
+ /* notify lower level on the real mtu */
+ ret = priv->rn_ops->ndo_change_mtu(dev, new_mtu);
+
+ if (carrier_status)
+ netif_carrier_on(dev);
+ } else {
+ dev->mtu = new_mtu;
+ }
+
+ return ret;
+}
+
+static void ipoib_get_stats(struct net_device *dev,
+ struct rtnl_link_stats64 *stats)
+{
+ struct ipoib_dev_priv *priv = ipoib_priv(dev);
+
+ if (priv->rn_ops->ndo_get_stats64)
+ priv->rn_ops->ndo_get_stats64(dev, stats);
+ else
+ netdev_stats_to_stats64(stats, &dev->stats);
}
/* Called with an RCU read lock taken */
@@ -1534,6 +1560,7 @@ static void ipoib_flush_neighs(struct ipoib_dev_priv *priv)
int i, wait_flushed = 0;
init_completion(&priv->ntbl.flushed);
+ set_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags);
spin_lock_irqsave(&priv->lock, flags);
@@ -1578,7 +1605,6 @@ static void ipoib_neigh_hash_uninit(struct net_device *dev)
ipoib_dbg(priv, "ipoib_neigh_hash_uninit\n");
init_completion(&priv->ntbl.deleted);
- set_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags);
/* Stop GC if called at init fail need to cancel work */
stopped = test_and_set_bit(IPOIB_STOP_NEIGH_GC, &priv->flags);
@@ -1808,6 +1834,7 @@ static const struct net_device_ops ipoib_netdev_ops_pf = {
.ndo_get_vf_stats = ipoib_get_vf_stats,
.ndo_set_vf_guid = ipoib_set_vf_guid,
.ndo_set_mac_address = ipoib_set_mac,
+ .ndo_get_stats64 = ipoib_get_stats,
};
static const struct net_device_ops ipoib_netdev_ops_vf = {
@@ -1820,6 +1847,7 @@ static const struct net_device_ops ipoib_netdev_ops_vf = {
.ndo_tx_timeout = ipoib_timeout,
.ndo_set_rx_mode = ipoib_set_mcast_list,
.ndo_get_iflink = ipoib_get_iflink,
+ .ndo_get_stats64 = ipoib_get_stats,
};
void ipoib_setup_common(struct net_device *dev)
@@ -1850,6 +1878,7 @@ static void ipoib_build_priv(struct net_device *dev)
priv->dev = dev;
spin_lock_init(&priv->lock);
init_rwsem(&priv->vlan_rwsem);
+ mutex_init(&priv->mcast_mutex);
INIT_LIST_HEAD(&priv->path_list);
INIT_LIST_HEAD(&priv->child_intfs);
@@ -2146,14 +2175,14 @@ static struct net_device *ipoib_add_port(const char *format,
priv->dev->dev_id = port - 1;
result = ib_query_port(hca, port, &attr);
- if (!result)
- priv->max_ib_mtu = ib_mtu_enum_to_int(attr.max_mtu);
- else {
+ if (result) {
printk(KERN_WARNING "%s: ib_query_port %d failed\n",
hca->name, port);
goto device_init_failed;
}
+ priv->max_ib_mtu = ib_mtu_enum_to_int(attr.max_mtu);
+
/* MTU will be reset when mcast join happens */
priv->dev->mtu = IPOIB_UD_MTU(priv->max_ib_mtu);
priv->mcast_mtu = priv->admin_mtu = priv->dev->mtu;
@@ -2184,12 +2213,14 @@ static struct net_device *ipoib_add_port(const char *format,
printk(KERN_WARNING "%s: ib_query_gid port %d failed (ret = %d)\n",
hca->name, port, result);
goto device_init_failed;
- } else
- memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw, sizeof (union ib_gid));
+ }
+
+ memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw,
+ sizeof(union ib_gid));
set_bit(IPOIB_FLAG_DEV_ADDR_SET, &priv->flags);
result = ipoib_dev_init(priv->dev, hca, port);
- if (result < 0) {
+ if (result) {
printk(KERN_WARNING "%s: failed to initialize port %d (ret = %d)\n",
hca->name, port, result);
goto device_init_failed;
@@ -2212,6 +2243,7 @@ static struct net_device *ipoib_add_port(const char *format,
goto register_failed;
}
+ result = -ENOMEM;
if (ipoib_cm_add_mode_attr(priv->dev))
goto sysfs_failed;
if (ipoib_add_pkey_attr(priv->dev))
@@ -2337,6 +2369,7 @@ static int __init ipoib_init_module(void)
ipoib_sendq_size = max3(ipoib_sendq_size, 2 * MAX_SEND_CQE, IPOIB_MIN_QUEUE_SIZE);
#ifdef CONFIG_INFINIBAND_IPOIB_CM
ipoib_max_conn_qp = min(ipoib_max_conn_qp, IPOIB_CM_MAX_CONN_QP);
+ ipoib_max_conn_qp = max(ipoib_max_conn_qp, 0);
#endif
/*
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 057f58e6afca..93e149efc1f5 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -684,15 +684,10 @@ void ipoib_mcast_start_thread(struct net_device *dev)
int ipoib_mcast_stop_thread(struct net_device *dev)
{
struct ipoib_dev_priv *priv = ipoib_priv(dev);
- unsigned long flags;
ipoib_dbg_mcast(priv, "stopping multicast thread\n");
- spin_lock_irqsave(&priv->lock, flags);
- cancel_delayed_work(&priv->mcast_task);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- flush_workqueue(priv->wq);
+ cancel_delayed_work_sync(&priv->mcast_task);
return 0;
}
@@ -748,6 +743,14 @@ void ipoib_mcast_remove_list(struct list_head *remove_list)
{
struct ipoib_mcast *mcast, *tmcast;
+ /*
+ * make sure the in-flight joins have finished before we attempt
+ * to leave
+ */
+ list_for_each_entry_safe(mcast, tmcast, remove_list, list)
+ if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags))
+ wait_for_completion(&mcast->done);
+
list_for_each_entry_safe(mcast, tmcast, remove_list, list) {
ipoib_mcast_leave(mcast->dev, mcast);
ipoib_mcast_free(mcast);
@@ -838,6 +841,7 @@ void ipoib_mcast_dev_flush(struct net_device *dev)
struct ipoib_mcast *mcast, *tmcast;
unsigned long flags;
+ mutex_lock(&priv->mcast_mutex);
ipoib_dbg_mcast(priv, "flushing multicast list\n");
spin_lock_irqsave(&priv->lock, flags);
@@ -856,15 +860,8 @@ void ipoib_mcast_dev_flush(struct net_device *dev)
spin_unlock_irqrestore(&priv->lock, flags);
- /*
- * make sure the in-flight joins have finished before we attempt
- * to leave
- */
- list_for_each_entry_safe(mcast, tmcast, &remove_list, list)
- if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags))
- wait_for_completion(&mcast->done);
-
ipoib_mcast_remove_list(&remove_list);
+ mutex_unlock(&priv->mcast_mutex);
}
static int ipoib_mcast_addr_is_valid(const u8 *addr, const u8 *broadcast)
@@ -982,14 +979,6 @@ void ipoib_mcast_restart_task(struct work_struct *work)
netif_addr_unlock(dev);
local_irq_restore(flags);
- /*
- * make sure the in-flight joins have finished before we attempt
- * to leave
- */
- list_for_each_entry_safe(mcast, tmcast, &remove_list, list)
- if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags))
- wait_for_completion(&mcast->done);
-
ipoib_mcast_remove_list(&remove_list);
/*
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 5a887efb4bdf..37b33d708c2d 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -83,6 +83,7 @@ static struct scsi_host_template iscsi_iser_sht;
static struct iscsi_transport iscsi_iser_transport;
static struct scsi_transport_template *iscsi_iser_scsi_transport;
static struct workqueue_struct *release_wq;
+static DEFINE_MUTEX(unbind_iser_conn_mutex);
struct iser_global ig;
int iser_debug_level = 0;
@@ -550,12 +551,14 @@ iscsi_iser_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
*/
if (iser_conn) {
mutex_lock(&iser_conn->state_mutex);
+ mutex_lock(&unbind_iser_conn_mutex);
iser_conn_terminate(iser_conn);
iscsi_conn_stop(cls_conn, flag);
/* unbind */
iser_conn->iscsi_conn = NULL;
conn->dd_data = NULL;
+ mutex_unlock(&unbind_iser_conn_mutex);
complete(&iser_conn->stop_completion);
mutex_unlock(&iser_conn->state_mutex);
@@ -977,13 +980,21 @@ static int iscsi_iser_slave_alloc(struct scsi_device *sdev)
struct iser_conn *iser_conn;
struct ib_device *ib_dev;
+ mutex_lock(&unbind_iser_conn_mutex);
+
session = starget_to_session(scsi_target(sdev))->dd_data;
iser_conn = session->leadconn->dd_data;
+ if (!iser_conn) {
+ mutex_unlock(&unbind_iser_conn_mutex);
+ return -ENOTCONN;
+ }
ib_dev = iser_conn->ib_conn.device->ib_device;
if (!(ib_dev->attrs.device_cap_flags & IB_DEVICE_SG_GAPS_REG))
blk_queue_virt_boundary(sdev->request_queue, ~MASK_4K);
+ mutex_unlock(&unbind_iser_conn_mutex);
+
return 0;
}
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index 12ed62ce9ff7..2a07692007bd 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -137,8 +137,10 @@ iser_prepare_write_cmd(struct iscsi_task *task,
if (unsol_sz < edtl) {
hdr->flags |= ISER_WSV;
- hdr->write_stag = cpu_to_be32(mem_reg->rkey);
- hdr->write_va = cpu_to_be64(mem_reg->sge.addr + unsol_sz);
+ if (buf_out->data_len > imm_sz) {
+ hdr->write_stag = cpu_to_be32(mem_reg->rkey);
+ hdr->write_va = cpu_to_be64(mem_reg->sge.addr + unsol_sz);
+ }
iser_dbg("Cmd itt:%d, WRITE tags, RKEY:%#.4X "
"VA:%#llX + unsol:%d\n",
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index c538a38c91ce..26a004e97ae0 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -708,8 +708,14 @@ iser_calc_scsi_params(struct iser_conn *iser_conn,
unsigned short sg_tablesize, sup_sg_tablesize;
sg_tablesize = DIV_ROUND_UP(max_sectors * 512, SIZE_4K);
- sup_sg_tablesize = min_t(unsigned, ISCSI_ISER_MAX_SG_TABLESIZE,
- device->ib_device->attrs.max_fast_reg_page_list_len);
+ if (device->ib_device->attrs.device_cap_flags &
+ IB_DEVICE_MEM_MGT_EXTENSIONS)
+ sup_sg_tablesize =
+ min_t(
+ uint, ISCSI_ISER_MAX_SG_TABLESIZE,
+ device->ib_device->attrs.max_fast_reg_page_list_len);
+ else
+ sup_sg_tablesize = ISCSI_ISER_MAX_SG_TABLESIZE;
iser_conn->scsi_sg_tablesize = min(sg_tablesize, sup_sg_tablesize);
}
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 688e77576e5a..354cbd6392cd 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -4452,6 +4452,7 @@ static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info)
/* Setting */
irte->hi.fields.ga_root_ptr = (pi_data->base >> 12);
irte->hi.fields.vector = vcpu_pi_info->vector;
+ irte->lo.fields_vapic.ga_log_intr = 1;
irte->lo.fields_vapic.guest_mode = 1;
irte->lo.fields_vapic.ga_tag = pi_data->ga_tag;
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 5cc597b383c7..372303700566 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -2440,11 +2440,11 @@ static int __init state_next(void)
break;
case IOMMU_ACPI_FINISHED:
early_enable_iommus();
- register_syscore_ops(&amd_iommu_syscore_ops);
x86_platform.iommu_shutdown = disable_iommus;
init_state = IOMMU_ENABLED;
break;
case IOMMU_ENABLED:
+ register_syscore_ops(&amd_iommu_syscore_ops);
ret = amd_iommu_init_pci();
init_state = ret ? IOMMU_INIT_ERROR : IOMMU_PCI_INIT;
enable_iommus_v2();
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index bc89b4d6c043..2d80fa8a0634 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -400,6 +400,8 @@ struct arm_smmu_device {
u32 cavium_id_base; /* Specific to Cavium */
+ spinlock_t global_sync_lock;
+
/* IOMMU core code handle */
struct iommu_device iommu;
};
@@ -436,7 +438,7 @@ struct arm_smmu_domain {
struct arm_smmu_cfg cfg;
enum arm_smmu_domain_stage stage;
struct mutex init_mutex; /* Protects smmu pointer */
- spinlock_t cb_lock; /* Serialises ATS1* ops */
+ spinlock_t cb_lock; /* Serialises ATS1* ops and TLB syncs */
struct iommu_domain domain;
};
@@ -602,9 +604,12 @@ static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu,
static void arm_smmu_tlb_sync_global(struct arm_smmu_device *smmu)
{
void __iomem *base = ARM_SMMU_GR0(smmu);
+ unsigned long flags;
+ spin_lock_irqsave(&smmu->global_sync_lock, flags);
__arm_smmu_tlb_sync(smmu, base + ARM_SMMU_GR0_sTLBGSYNC,
base + ARM_SMMU_GR0_sTLBGSTATUS);
+ spin_unlock_irqrestore(&smmu->global_sync_lock, flags);
}
static void arm_smmu_tlb_sync_context(void *cookie)
@@ -612,9 +617,12 @@ static void arm_smmu_tlb_sync_context(void *cookie)
struct arm_smmu_domain *smmu_domain = cookie;
struct arm_smmu_device *smmu = smmu_domain->smmu;
void __iomem *base = ARM_SMMU_CB(smmu, smmu_domain->cfg.cbndx);
+ unsigned long flags;
+ spin_lock_irqsave(&smmu_domain->cb_lock, flags);
__arm_smmu_tlb_sync(smmu, base + ARM_SMMU_CB_TLBSYNC,
base + ARM_SMMU_CB_TLBSTATUS);
+ spin_unlock_irqrestore(&smmu_domain->cb_lock, flags);
}
static void arm_smmu_tlb_sync_vmid(void *cookie)
@@ -1511,6 +1519,12 @@ static int arm_smmu_add_device(struct device *dev)
if (using_legacy_binding) {
ret = arm_smmu_register_legacy_master(dev, &smmu);
+
+ /*
+ * If dev->iommu_fwspec is initally NULL, arm_smmu_register_legacy_master()
+ * will allocate/initialise a new one. Thus we need to update fwspec for
+ * later use.
+ */
fwspec = dev->iommu_fwspec;
if (ret)
goto out_free;
@@ -1550,15 +1564,15 @@ static int arm_smmu_add_device(struct device *dev)
ret = arm_smmu_master_alloc_smes(dev);
if (ret)
- goto out_free;
+ goto out_cfg_free;
iommu_device_link(&smmu->iommu, dev);
return 0;
+out_cfg_free:
+ kfree(cfg);
out_free:
- if (fwspec)
- kfree(fwspec->iommu_priv);
iommu_fwspec_free(dev);
return ret;
}
@@ -1925,6 +1939,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
smmu->num_mapping_groups = size;
mutex_init(&smmu->stream_map_mutex);
+ spin_lock_init(&smmu->global_sync_lock);
if (smmu->version < ARM_SMMU_V2 || !(id & ID0_PTFS_NO_AARCH32)) {
smmu->features |= ARM_SMMU_FEAT_FMT_AARCH32_L;
diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c
index af330f513653..d665d0dc16e8 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -479,6 +479,9 @@ static int arm_v7s_map(struct io_pgtable_ops *ops, unsigned long iova,
if (!(prot & (IOMMU_READ | IOMMU_WRITE)))
return 0;
+ if (WARN_ON(upper_32_bits(iova) || upper_32_bits(paddr)))
+ return -ERANGE;
+
ret = __arm_v7s_map(data, iova, paddr, size, prot, 1, data->pgd);
/*
* Synchronise all PTE updates for the new mapping before there's
@@ -659,6 +662,9 @@ static int arm_v7s_unmap(struct io_pgtable_ops *ops, unsigned long iova,
struct arm_v7s_io_pgtable *data = io_pgtable_ops_to_data(ops);
size_t unmapped;
+ if (WARN_ON(upper_32_bits(iova)))
+ return 0;
+
unmapped = __arm_v7s_unmap(data, iova, size, 1, data->pgd);
if (unmapped)
io_pgtable_tlb_sync(&data->iop);
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index b182039862c5..e8018a308868 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -452,6 +452,10 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova,
if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
return 0;
+ if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias) ||
+ paddr >= (1ULL << data->iop.cfg.oas)))
+ return -ERANGE;
+
prot = arm_lpae_prot_to_pte(data, iommu_prot);
ret = __arm_lpae_map(data, iova, paddr, size, prot, lvl, ptep);
/*
@@ -610,6 +614,9 @@ static int arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova,
arm_lpae_iopte *ptep = data->pgd;
int lvl = ARM_LPAE_START_LVL(data);
+ if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias)))
+ return 0;
+
unmapped = __arm_lpae_unmap(data, iova, size, lvl, ptep);
if (unmapped)
io_pgtable_tlb_sync(&data->iop);
diff --git a/drivers/iommu/io-pgtable.h b/drivers/iommu/io-pgtable.h
index 524263a7ae6f..a3e667077b14 100644
--- a/drivers/iommu/io-pgtable.h
+++ b/drivers/iommu/io-pgtable.h
@@ -158,14 +158,12 @@ void free_io_pgtable_ops(struct io_pgtable_ops *ops);
* @fmt: The page table format.
* @cookie: An opaque token provided by the IOMMU driver and passed back to
* any callback routines.
- * @tlb_sync_pending: Private flag for optimising out redundant syncs.
* @cfg: A copy of the page table configuration.
* @ops: The page table operations in use for this set of page tables.
*/
struct io_pgtable {
enum io_pgtable_fmt fmt;
void *cookie;
- bool tlb_sync_pending;
struct io_pgtable_cfg cfg;
struct io_pgtable_ops ops;
};
@@ -175,22 +173,17 @@ struct io_pgtable {
static inline void io_pgtable_tlb_flush_all(struct io_pgtable *iop)
{
iop->cfg.tlb->tlb_flush_all(iop->cookie);
- iop->tlb_sync_pending = true;
}
static inline void io_pgtable_tlb_add_flush(struct io_pgtable *iop,
unsigned long iova, size_t size, size_t granule, bool leaf)
{
iop->cfg.tlb->tlb_add_flush(iova, size, granule, leaf, iop->cookie);
- iop->tlb_sync_pending = true;
}
static inline void io_pgtable_tlb_sync(struct io_pgtable *iop)
{
- if (iop->tlb_sync_pending) {
- iop->cfg.tlb->tlb_sync(iop->cookie);
- iop->tlb_sync_pending = false;
- }
+ iop->cfg.tlb->tlb_sync(iop->cookie);
}
/**
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 5d14cd15198d..91c6d367ab35 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -129,6 +129,7 @@ static void mtk_iommu_tlb_add_flush_nosync(unsigned long iova, size_t size,
writel_relaxed(iova, data->base + REG_MMU_INVLD_START_A);
writel_relaxed(iova + size - 1, data->base + REG_MMU_INVLD_END_A);
writel_relaxed(F_MMU_INV_RANGE, data->base + REG_MMU_INVALIDATE);
+ data->tlb_flush_active = true;
}
static void mtk_iommu_tlb_sync(void *cookie)
@@ -137,6 +138,10 @@ static void mtk_iommu_tlb_sync(void *cookie)
int ret;
u32 tmp;
+ /* Avoid timing out if there's nothing to wait for */
+ if (!data->tlb_flush_active)
+ return;
+
ret = readl_poll_timeout_atomic(data->base + REG_MMU_CPE_DONE, tmp,
tmp != 0, 10, 100000);
if (ret) {
@@ -146,6 +151,7 @@ static void mtk_iommu_tlb_sync(void *cookie)
}
/* Clear the CPE status */
writel_relaxed(0, data->base + REG_MMU_CPE_DONE);
+ data->tlb_flush_active = false;
}
static const struct iommu_gather_ops mtk_iommu_gather_ops = {
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 2a28eadeea0e..c06cc91b5d9a 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -47,6 +47,7 @@ struct mtk_iommu_data {
struct iommu_group *m4u_group;
struct mtk_smi_iommu smi_imu; /* SMI larb iommu info */
bool enable_4GB;
+ bool tlb_flush_active;
struct iommu_device iommu;
};
diff --git a/drivers/irqchip/irq-digicolor.c b/drivers/irqchip/irq-digicolor.c
index dad85e74c37c..3aae015469a5 100644
--- a/drivers/irqchip/irq-digicolor.c
+++ b/drivers/irqchip/irq-digicolor.c
@@ -71,7 +71,7 @@ static void __init digicolor_set_gc(void __iomem *reg_base, unsigned irq_base,
static int __init digicolor_of_init(struct device_node *node,
struct device_node *parent)
{
- static void __iomem *reg_base;
+ void __iomem *reg_base;
unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
struct regmap *ucregs;
int ret;
diff --git a/drivers/irqchip/irq-gic-realview.c b/drivers/irqchip/irq-gic-realview.c
index 54c296401525..18d58d2b4ffe 100644
--- a/drivers/irqchip/irq-gic-realview.c
+++ b/drivers/irqchip/irq-gic-realview.c
@@ -43,7 +43,7 @@ static const struct of_device_id syscon_pldset_of_match[] = {
static int __init
realview_gic_of_init(struct device_node *node, struct device_node *parent)
{
- static struct regmap *map;
+ struct regmap *map;
struct device_node *np;
const struct of_device_id *gic_id;
u32 pld1_ctrl;
diff --git a/drivers/irqchip/irq-mips-cpu.c b/drivers/irqchip/irq-mips-cpu.c
index 0a8ed1c05518..14461cbfab2f 100644
--- a/drivers/irqchip/irq-mips-cpu.c
+++ b/drivers/irqchip/irq-mips-cpu.c
@@ -154,7 +154,7 @@ asmlinkage void __weak plat_irq_dispatch(void)
static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hw)
{
- static struct irq_chip *chip;
+ struct irq_chip *chip;
if (hw < 2 && cpu_has_mipsmt) {
/* Software interrupts are used for MT/CMT IPI */
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 832ebf4062f7..6ab1d3afec02 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -950,7 +950,6 @@ static void __init __gic_init(unsigned long gic_base_addr,
&gic_irq_domain_ops, NULL);
if (!gic_irq_domain)
panic("Failed to add GIC IRQ domain");
- gic_irq_domain->name = "mips-gic-irq";
gic_ipi_domain = irq_domain_add_hierarchy(gic_irq_domain,
IRQ_DOMAIN_FLAG_IPI_PER_CPU,
@@ -959,7 +958,6 @@ static void __init __gic_init(unsigned long gic_base_addr,
if (!gic_ipi_domain)
panic("Failed to add GIC IPI domain");
- gic_ipi_domain->name = "mips-gic-ipi";
irq_domain_update_bus_token(gic_ipi_domain, DOMAIN_BUS_IPI);
if (node &&
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c
index 060d357f107f..6f423bc49d0d 100644
--- a/drivers/isdn/divert/isdn_divert.c
+++ b/drivers/isdn/divert/isdn_divert.c
@@ -485,18 +485,19 @@ static int isdn_divert_icall(isdn_ctrl *ic)
cs->deflect_dest[0] = '\0';
retval = 4; /* only proceed */
}
- sprintf(cs->info, "%d 0x%lx %s %s %s %s 0x%x 0x%x %d %d %s\n",
- cs->akt_state,
- cs->divert_id,
- divert_if.drv_to_name(cs->ics.driver),
- (ic->command == ISDN_STAT_ICALLW) ? "1" : "0",
- cs->ics.parm.setup.phone,
- cs->ics.parm.setup.eazmsn,
- cs->ics.parm.setup.si1,
- cs->ics.parm.setup.si2,
- cs->ics.parm.setup.screen,
- dv->rule.waittime,
- cs->deflect_dest);
+ snprintf(cs->info, sizeof(cs->info),
+ "%d 0x%lx %s %s %s %s 0x%x 0x%x %d %d %s\n",
+ cs->akt_state,
+ cs->divert_id,
+ divert_if.drv_to_name(cs->ics.driver),
+ (ic->command == ISDN_STAT_ICALLW) ? "1" : "0",
+ cs->ics.parm.setup.phone,
+ cs->ics.parm.setup.eazmsn,
+ cs->ics.parm.setup.si1,
+ cs->ics.parm.setup.si2,
+ cs->ics.parm.setup.screen,
+ dv->rule.waittime,
+ cs->deflect_dest);
if ((dv->rule.action == DEFLECT_REPORT) ||
(dv->rule.action == DEFLECT_REJECT)) {
put_info_buffer(cs->info);
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c
index 40c7e2cf423b..034cabac699d 100644
--- a/drivers/isdn/hardware/avm/c4.c
+++ b/drivers/isdn/hardware/avm/c4.c
@@ -42,7 +42,7 @@ static char *revision = "$Revision: 1.1.2.2 $";
static bool suppress_pollack;
-static struct pci_device_id c4_pci_tbl[] = {
+static const struct pci_device_id c4_pci_tbl[] = {
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C4, 0, 0, (unsigned long)4 },
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C2, 0, 0, (unsigned long)2 },
{ } /* Terminating entry */
diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c
index 8b7ad4f1ab01..b2023e08dcd2 100644
--- a/drivers/isdn/hardware/eicon/divasmain.c
+++ b/drivers/isdn/hardware/eicon/divasmain.c
@@ -110,7 +110,7 @@ typedef struct _diva_os_thread_dpc {
/*
This table should be sorted by PCI device ID
*/
-static struct pci_device_id divas_pci_tbl[] = {
+static const struct pci_device_id divas_pci_tbl[] = {
/* Diva Server BRI-2M PCI 0xE010 */
{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRA),
CARDTYPE_MAESTRA_PCI },
diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c
index e3fa1cd64470..dce6632daae1 100644
--- a/drivers/isdn/hardware/mISDN/avmfritz.c
+++ b/drivers/isdn/hardware/mISDN/avmfritz.c
@@ -1142,7 +1142,7 @@ fritz_remove_pci(struct pci_dev *pdev)
pr_info("%s: drvdata already removed\n", __func__);
}
-static struct pci_device_id fcpci_ids[] = {
+static const struct pci_device_id fcpci_ids[] = {
{ PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1, PCI_ANY_ID, PCI_ANY_ID,
0, 0, (unsigned long) "Fritz!Card PCI"},
{ PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1_V2, PCI_ANY_ID, PCI_ANY_ID,
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index aea0c9616ea5..3cf07b8ced1c 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -5348,7 +5348,7 @@ static const struct hm_map hfcm_map[] = {
#undef H
#define H(x) ((unsigned long)&hfcm_map[x])
-static struct pci_device_id hfmultipci_ids[] = {
+static const struct pci_device_id hfmultipci_ids[] = {
/* Cards with HFC-4S Chip */
{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index 5dc246d71c16..d2e401a8090e 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -2161,7 +2161,7 @@ static const struct _hfc_map hfc_map[] =
{},
};
-static struct pci_device_id hfc_ids[] =
+static const struct pci_device_id hfc_ids[] =
{
{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_2BD0),
(unsigned long) &hfc_map[0] },
diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c
index afde4edef9ae..6a6d848bd18e 100644
--- a/drivers/isdn/hardware/mISDN/netjet.c
+++ b/drivers/isdn/hardware/mISDN/netjet.c
@@ -1137,7 +1137,7 @@ static void nj_remove(struct pci_dev *pdev)
/* We cannot select cards with PCI_SUB... IDs, since here are cards with
* SUB IDs set to PCI_ANY_ID, so we need to match all and reject
* known other cards which not work with this driver - see probe function */
-static struct pci_device_id nj_pci_ids[] = {
+static const struct pci_device_id nj_pci_ids[] = {
{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_300,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ }
diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c
index 3052c836b89f..d80072fef434 100644
--- a/drivers/isdn/hardware/mISDN/w6692.c
+++ b/drivers/isdn/hardware/mISDN/w6692.c
@@ -1398,7 +1398,7 @@ w6692_remove_pci(struct pci_dev *pdev)
pr_notice("%s: drvdata already removed\n", __func__);
}
-static struct pci_device_id w6692_ids[] = {
+static const struct pci_device_id w6692_ids[] = {
{ PCI_VENDOR_ID_DYNALINK, PCI_DEVICE_ID_DYNALINK_IS64PH,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, (ulong)&w6692_map[0]},
{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692,
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index c7d68675b028..7108bdb8742e 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -1909,7 +1909,7 @@ static void EChannel_proc_rcv(struct hisax_d_if *d_if)
#ifdef CONFIG_PCI
#include <linux/pci.h>
-static struct pci_device_id hisax_pci_tbl[] __used = {
+static const struct pci_device_id hisax_pci_tbl[] __used = {
#ifdef CONFIG_HISAX_FRITZPCI
{PCI_VDEVICE(AVM, PCI_DEVICE_ID_AVM_A1) },
#endif
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
index 90f051ce0259..9090cc1e1f29 100644
--- a/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -86,7 +86,7 @@ typedef struct {
char *device_name;
} hfc4s8s_param;
-static struct pci_device_id hfc4s8s_ids[] = {
+static const struct pci_device_id hfc4s8s_ids[] = {
{.vendor = PCI_VENDOR_ID_CCD,
.device = PCI_DEVICE_ID_4S,
.subvendor = 0x1397,
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
index 5a9f39ed1d5d..e4f7573ba9bf 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -52,7 +52,7 @@ module_param(debug, int, 0);
MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Karsten Keil <kkeil@suse.de>");
MODULE_DESCRIPTION("AVM Fritz!PCI/PnP ISDN driver");
-static struct pci_device_id fcpci_ids[] = {
+static const struct pci_device_id fcpci_ids[] = {
{ .vendor = PCI_VENDOR_ID_AVM,
.device = PCI_DEVICE_ID_AVM_A1,
.subvendor = PCI_ANY_ID,
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 7b5fd8fb1761..aaca0b3d662e 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -44,7 +44,6 @@ struct procdata {
char log_name[15]; /* log filename */
struct log_data *log_head, *log_tail; /* head and tail for queue */
int if_used; /* open count for interface */
- int volatile del_lock; /* lock for delete operations */
unsigned char logtmp[LOG_MAX_LINELEN];
wait_queue_head_t rd_queue;
};
@@ -102,7 +101,6 @@ put_log_buffer(hysdn_card *card, char *cp)
{
struct log_data *ib;
struct procdata *pd = card->proclog;
- int i;
unsigned long flags;
if (!pd)
@@ -126,21 +124,21 @@ put_log_buffer(hysdn_card *card, char *cp)
else
pd->log_tail->next = ib; /* follows existing messages */
pd->log_tail = ib; /* new tail */
- i = pd->del_lock++; /* get lock state */
- spin_unlock_irqrestore(&card->hysdn_lock, flags);
/* delete old entrys */
- if (!i)
- while (pd->log_head->next) {
- if ((pd->log_head->usage_cnt <= 0) &&
- (pd->log_head->next->usage_cnt <= 0)) {
- ib = pd->log_head;
- pd->log_head = pd->log_head->next;
- kfree(ib);
- } else
- break;
- } /* pd->log_head->next */
- pd->del_lock--; /* release lock level */
+ while (pd->log_head->next) {
+ if ((pd->log_head->usage_cnt <= 0) &&
+ (pd->log_head->next->usage_cnt <= 0)) {
+ ib = pd->log_head;
+ pd->log_head = pd->log_head->next;
+ kfree(ib);
+ } else {
+ break;
+ }
+ } /* pd->log_head->next */
+
+ spin_unlock_irqrestore(&card->hysdn_lock, flags);
+
wake_up_interruptible(&(pd->rd_queue)); /* announce new entry */
} /* put_log_buffer */
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 89b09c51ab7c..38a5bb764c7b 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -1376,6 +1376,7 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
if (arg) {
if (copy_from_user(bname, argp, sizeof(bname) - 1))
return -EFAULT;
+ bname[sizeof(bname)-1] = 0;
} else
return -EINVAL;
ret = mutex_lock_interruptible(&dev->mtx);
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index c151c6daa67e..f63a110b7bcb 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -2611,10 +2611,9 @@ isdn_net_newslave(char *parm)
char newname[10];
if (p) {
- /* Slave-Name MUST not be empty */
- if (!strlen(p + 1))
+ /* Slave-Name MUST not be empty or overflow 'newname' */
+ if (strscpy(newname, p + 1, sizeof(newname)) <= 0)
return NULL;
- strcpy(newname, p + 1);
*p = 0;
/* Master must already exist */
if (!(n = isdn_net_findif(parm)))
diff --git a/drivers/lightnvm/pblk-rb.c b/drivers/lightnvm/pblk-rb.c
index 5ecc154f6831..9bc32578a766 100644
--- a/drivers/lightnvm/pblk-rb.c
+++ b/drivers/lightnvm/pblk-rb.c
@@ -657,7 +657,7 @@ try:
* be directed to disk.
*/
int pblk_rb_copy_to_bio(struct pblk_rb *rb, struct bio *bio, sector_t lba,
- struct ppa_addr ppa, int bio_iter)
+ struct ppa_addr ppa, int bio_iter, bool advanced_bio)
{
struct pblk *pblk = container_of(rb, struct pblk, rwb);
struct pblk_rb_entry *entry;
@@ -694,7 +694,7 @@ int pblk_rb_copy_to_bio(struct pblk_rb *rb, struct bio *bio, sector_t lba,
* filled with data from the cache). If part of the data resides on the
* media, we will read later on
*/
- if (unlikely(!bio->bi_iter.bi_idx))
+ if (unlikely(!advanced_bio))
bio_advance(bio, bio_iter * PBLK_EXPOSED_PAGE_SIZE);
data = bio_data(bio);
diff --git a/drivers/lightnvm/pblk-read.c b/drivers/lightnvm/pblk-read.c
index 4e5c48f3de62..d682e89e6493 100644
--- a/drivers/lightnvm/pblk-read.c
+++ b/drivers/lightnvm/pblk-read.c
@@ -26,7 +26,7 @@
*/
static int pblk_read_from_cache(struct pblk *pblk, struct bio *bio,
sector_t lba, struct ppa_addr ppa,
- int bio_iter)
+ int bio_iter, bool advanced_bio)
{
#ifdef CONFIG_NVM_DEBUG
/* Callers must ensure that the ppa points to a cache address */
@@ -34,7 +34,8 @@ static int pblk_read_from_cache(struct pblk *pblk, struct bio *bio,
BUG_ON(!pblk_addr_in_cache(ppa));
#endif
- return pblk_rb_copy_to_bio(&pblk->rwb, bio, lba, ppa, bio_iter);
+ return pblk_rb_copy_to_bio(&pblk->rwb, bio, lba, ppa,
+ bio_iter, advanced_bio);
}
static void pblk_read_ppalist_rq(struct pblk *pblk, struct nvm_rq *rqd,
@@ -44,7 +45,7 @@ static void pblk_read_ppalist_rq(struct pblk *pblk, struct nvm_rq *rqd,
struct ppa_addr ppas[PBLK_MAX_REQ_ADDRS];
sector_t blba = pblk_get_lba(bio);
int nr_secs = rqd->nr_ppas;
- int advanced_bio = 0;
+ bool advanced_bio = false;
int i, j = 0;
/* logic error: lba out-of-bounds. Ignore read request */
@@ -62,19 +63,26 @@ static void pblk_read_ppalist_rq(struct pblk *pblk, struct nvm_rq *rqd,
retry:
if (pblk_ppa_empty(p)) {
WARN_ON(test_and_set_bit(i, read_bitmap));
- continue;
+
+ if (unlikely(!advanced_bio)) {
+ bio_advance(bio, (i) * PBLK_EXPOSED_PAGE_SIZE);
+ advanced_bio = true;
+ }
+
+ goto next;
}
/* Try to read from write buffer. The address is later checked
* on the write buffer to prevent retrieving overwritten data.
*/
if (pblk_addr_in_cache(p)) {
- if (!pblk_read_from_cache(pblk, bio, lba, p, i)) {
+ if (!pblk_read_from_cache(pblk, bio, lba, p, i,
+ advanced_bio)) {
pblk_lookup_l2p_seq(pblk, &p, lba, 1);
goto retry;
}
WARN_ON(test_and_set_bit(i, read_bitmap));
- advanced_bio = 1;
+ advanced_bio = true;
#ifdef CONFIG_NVM_DEBUG
atomic_long_inc(&pblk->cache_reads);
#endif
@@ -83,6 +91,7 @@ retry:
rqd->ppa_list[j++] = p;
}
+next:
if (advanced_bio)
bio_advance(bio, PBLK_EXPOSED_PAGE_SIZE);
}
@@ -282,7 +291,7 @@ retry:
* write buffer to prevent retrieving overwritten data.
*/
if (pblk_addr_in_cache(ppa)) {
- if (!pblk_read_from_cache(pblk, bio, lba, ppa, 0)) {
+ if (!pblk_read_from_cache(pblk, bio, lba, ppa, 0, 1)) {
pblk_lookup_l2p_seq(pblk, &ppa, lba, 1);
goto retry;
}
diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
index 0c5692cc2f60..67e623bd5c2d 100644
--- a/drivers/lightnvm/pblk.h
+++ b/drivers/lightnvm/pblk.h
@@ -670,7 +670,7 @@ unsigned int pblk_rb_read_to_bio_list(struct pblk_rb *rb, struct bio *bio,
struct list_head *list,
unsigned int max);
int pblk_rb_copy_to_bio(struct pblk_rb *rb, struct bio *bio, sector_t lba,
- struct ppa_addr ppa, int bio_iter);
+ struct ppa_addr ppa, int bio_iter, bool advanced_bio);
unsigned int pblk_rb_read_commit(struct pblk_rb *rb, unsigned int entries);
unsigned int pblk_rb_sync_init(struct pblk_rb *rb, unsigned long *flags);
diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
index ac91fd0d62c6..cbca5e51b975 100644
--- a/drivers/mailbox/pcc.c
+++ b/drivers/mailbox/pcc.c
@@ -92,7 +92,7 @@ static struct mbox_controller pcc_mbox_ctrl = {};
*/
static struct mbox_chan *get_pcc_channel(int id)
{
- if (id < 0 || id > pcc_mbox_ctrl.num_chans)
+ if (id < 0 || id >= pcc_mbox_ctrl.num_chans)
return ERR_PTR(-ENOENT);
return &pcc_mbox_channels[id];
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index f4eace5ea184..40f3cd7eab0f 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -156,7 +156,8 @@ static int read_sb_page(struct mddev *mddev, loff_t offset,
rdev_for_each(rdev, mddev) {
if (! test_bit(In_sync, &rdev->flags)
- || test_bit(Faulty, &rdev->flags))
+ || test_bit(Faulty, &rdev->flags)
+ || test_bit(Bitmap_sync, &rdev->flags))
continue;
target = offset + index * (PAGE_SIZE/512);
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
index 850ff6c67994..44f4a8ac95bd 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -1258,8 +1258,7 @@ EXPORT_SYMBOL_GPL(dm_bufio_write_dirty_buffers_async);
*/
int dm_bufio_write_dirty_buffers(struct dm_bufio_client *c)
{
- blk_status_t a;
- int f;
+ int a, f;
unsigned long buffers_processed = 0;
struct dm_buffer *b, *tmp;
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
index 1b224aa9cf15..3acce09bba35 100644
--- a/drivers/md/dm-integrity.c
+++ b/drivers/md/dm-integrity.c
@@ -1587,16 +1587,18 @@ retry:
if (likely(ic->mode == 'J')) {
if (dio->write) {
unsigned next_entry, i, pos;
- unsigned ws, we;
+ unsigned ws, we, range_sectors;
- dio->range.n_sectors = min(dio->range.n_sectors, ic->free_sectors);
+ dio->range.n_sectors = min(dio->range.n_sectors,
+ ic->free_sectors << ic->sb->log2_sectors_per_block);
if (unlikely(!dio->range.n_sectors))
goto sleep;
- ic->free_sectors -= dio->range.n_sectors;
+ range_sectors = dio->range.n_sectors >> ic->sb->log2_sectors_per_block;
+ ic->free_sectors -= range_sectors;
journal_section = ic->free_section;
journal_entry = ic->free_section_entry;
- next_entry = ic->free_section_entry + dio->range.n_sectors;
+ next_entry = ic->free_section_entry + range_sectors;
ic->free_section_entry = next_entry % ic->journal_section_entries;
ic->free_section += next_entry / ic->journal_section_entries;
ic->n_uncommitted_sections += next_entry / ic->journal_section_entries;
@@ -1727,6 +1729,8 @@ static void pad_uncommitted(struct dm_integrity_c *ic)
wraparound_section(ic, &ic->free_section);
ic->n_uncommitted_sections++;
}
+ WARN_ON(ic->journal_sections * ic->journal_section_entries !=
+ (ic->n_uncommitted_sections + ic->n_committed_sections) * ic->journal_section_entries + ic->free_sectors);
}
static void integrity_commit(struct work_struct *w)
@@ -1821,6 +1825,9 @@ static void do_journal_write(struct dm_integrity_c *ic, unsigned write_start,
{
unsigned i, j, n;
struct journal_completion comp;
+ struct blk_plug plug;
+
+ blk_start_plug(&plug);
comp.ic = ic;
comp.in_flight = (atomic_t)ATOMIC_INIT(1);
@@ -1945,6 +1952,8 @@ skip_io:
dm_bufio_write_dirty_buffers_async(ic->bufio);
+ blk_finish_plug(&plug);
+
complete_journal_op(&comp);
wait_for_completion_io(&comp.comp);
@@ -3019,6 +3028,11 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv)
ti->error = "Block size doesn't match the information in superblock";
goto bad;
}
+ if (!le32_to_cpu(ic->sb->journal_sections)) {
+ r = -EINVAL;
+ ti->error = "Corrupted superblock, journal_sections is 0";
+ goto bad;
+ }
/* make sure that ti->max_io_len doesn't overflow */
if (ic->sb->log2_interleave_sectors < MIN_LOG2_INTERLEAVE_SECTORS ||
ic->sb->log2_interleave_sectors > MAX_LOG2_INTERLEAVE_SECTORS) {
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 2e10c2f13a34..5bfe285ea9d1 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -208,6 +208,7 @@ struct raid_dev {
#define RT_FLAG_RS_BITMAP_LOADED 2
#define RT_FLAG_UPDATE_SBS 3
#define RT_FLAG_RESHAPE_RS 4
+#define RT_FLAG_RS_SUSPENDED 5
/* Array elements of 64 bit needed for rebuild/failed disk bits */
#define DISKS_ARRAY_ELEMS ((MAX_RAID_DEVICES + (sizeof(uint64_t) * 8 - 1)) / sizeof(uint64_t) / 8)
@@ -564,9 +565,10 @@ static const char *raid10_md_layout_to_format(int layout)
if (__raid10_near_copies(layout) > 1)
return "near";
- WARN_ON(__raid10_far_copies(layout) < 2);
+ if (__raid10_far_copies(layout) > 1)
+ return "far";
- return "far";
+ return "unknown";
}
/* Return md raid10 algorithm for @name */
@@ -2540,11 +2542,6 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
if (!freshest)
return 0;
- if (validate_raid_redundancy(rs)) {
- rs->ti->error = "Insufficient redundancy to activate array";
- return -EINVAL;
- }
-
/*
* Validation of the freshest device provides the source of
* validation for the remaining devices.
@@ -2553,6 +2550,11 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
if (super_validate(rs, freshest))
return -EINVAL;
+ if (validate_raid_redundancy(rs)) {
+ rs->ti->error = "Insufficient redundancy to activate array";
+ return -EINVAL;
+ }
+
rdev_for_each(rdev, mddev)
if (!test_bit(Journal, &rdev->flags) &&
rdev != freshest &&
@@ -3168,6 +3170,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
}
mddev_suspend(&rs->md);
+ set_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags);
/* Try to adjust the raid4/5/6 stripe cache size to the stripe size */
if (rs_is_raid456(rs)) {
@@ -3625,7 +3628,7 @@ static void raid_postsuspend(struct dm_target *ti)
{
struct raid_set *rs = ti->private;
- if (!rs->md.suspended)
+ if (!test_and_set_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags))
mddev_suspend(&rs->md);
rs->md.ro = 1;
@@ -3759,7 +3762,7 @@ static int rs_start_reshape(struct raid_set *rs)
return r;
/* Need to be resumed to be able to start reshape, recovery is frozen until raid_resume() though */
- if (mddev->suspended)
+ if (test_and_clear_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags))
mddev_resume(mddev);
/*
@@ -3786,8 +3789,8 @@ static int rs_start_reshape(struct raid_set *rs)
}
/* Suspend because a resume will happen in raid_resume() */
- if (!mddev->suspended)
- mddev_suspend(mddev);
+ set_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags);
+ mddev_suspend(mddev);
/*
* Now reshape got set up, update superblocks to
@@ -3883,13 +3886,13 @@ static void raid_resume(struct dm_target *ti)
if (!(rs->ctr_flags & RESUME_STAY_FROZEN_FLAGS))
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
- if (mddev->suspended)
+ if (test_and_clear_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags))
mddev_resume(mddev);
}
static struct target_type raid_target = {
.name = "raid",
- .version = {1, 11, 1},
+ .version = {1, 12, 1},
.module = THIS_MODULE,
.ctr = raid_ctr,
.dtr = raid_dtr,
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index a39bcd9b982a..28a4071cdf85 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -20,6 +20,7 @@
#include <linux/atomic.h>
#include <linux/blk-mq.h>
#include <linux/mount.h>
+#include <linux/dax.h>
#define DM_MSG_PREFIX "table"
@@ -1630,6 +1631,37 @@ static bool dm_table_supports_flush(struct dm_table *t, unsigned long flush)
return false;
}
+static int device_dax_write_cache_enabled(struct dm_target *ti,
+ struct dm_dev *dev, sector_t start,
+ sector_t len, void *data)
+{
+ struct dax_device *dax_dev = dev->dax_dev;
+
+ if (!dax_dev)
+ return false;
+
+ if (dax_write_cache_enabled(dax_dev))
+ return true;
+ return false;
+}
+
+static int dm_table_supports_dax_write_cache(struct dm_table *t)
+{
+ struct dm_target *ti;
+ unsigned i;
+
+ for (i = 0; i < dm_table_get_num_targets(t); i++) {
+ ti = dm_table_get_target(t, i);
+
+ if (ti->type->iterate_devices &&
+ ti->type->iterate_devices(ti,
+ device_dax_write_cache_enabled, NULL))
+ return true;
+ }
+
+ return false;
+}
+
static int device_is_nonrot(struct dm_target *ti, struct dm_dev *dev,
sector_t start, sector_t len, void *data)
{
@@ -1785,6 +1817,9 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
}
blk_queue_write_cache(q, wc, fua);
+ if (dm_table_supports_dax_write_cache(t))
+ dax_write_cache(t->md->dax_dev, true);
+
/* Ensure that all underlying devices are non-rotational. */
if (dm_table_all_devices_attribute(t, device_is_nonrot))
queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c
index 504ba3fa328b..e13f90832b6b 100644
--- a/drivers/md/dm-verity-fec.c
+++ b/drivers/md/dm-verity-fec.c
@@ -308,19 +308,14 @@ static int fec_alloc_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio)
{
unsigned n;
- if (!fio->rs) {
- fio->rs = mempool_alloc(v->fec->rs_pool, 0);
- if (unlikely(!fio->rs)) {
- DMERR("failed to allocate RS");
- return -ENOMEM;
- }
- }
+ if (!fio->rs)
+ fio->rs = mempool_alloc(v->fec->rs_pool, GFP_NOIO);
fec_for_each_prealloc_buffer(n) {
if (fio->bufs[n])
continue;
- fio->bufs[n] = mempool_alloc(v->fec->prealloc_pool, GFP_NOIO);
+ fio->bufs[n] = mempool_alloc(v->fec->prealloc_pool, GFP_NOWAIT);
if (unlikely(!fio->bufs[n])) {
DMERR("failed to allocate FEC buffer");
return -ENOMEM;
@@ -332,22 +327,16 @@ static int fec_alloc_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio)
if (fio->bufs[n])
continue;
- fio->bufs[n] = mempool_alloc(v->fec->extra_pool, GFP_NOIO);
+ fio->bufs[n] = mempool_alloc(v->fec->extra_pool, GFP_NOWAIT);
/* we can manage with even one buffer if necessary */
if (unlikely(!fio->bufs[n]))
break;
}
fio->nbufs = n;
- if (!fio->output) {
+ if (!fio->output)
fio->output = mempool_alloc(v->fec->output_pool, GFP_NOIO);
- if (!fio->output) {
- DMERR("failed to allocate FEC page");
- return -ENOMEM;
- }
- }
-
return 0;
}
diff --git a/drivers/md/dm-zoned-metadata.c b/drivers/md/dm-zoned-metadata.c
index 884ff7c170a0..a4fa2ada6883 100644
--- a/drivers/md/dm-zoned-metadata.c
+++ b/drivers/md/dm-zoned-metadata.c
@@ -624,7 +624,7 @@ static int dmz_write_sb(struct dmz_metadata *zmd, unsigned int set)
ret = dmz_rdwr_block(zmd, REQ_OP_WRITE, block, mblk->page);
if (ret == 0)
- ret = blkdev_issue_flush(zmd->dev->bdev, GFP_KERNEL, NULL);
+ ret = blkdev_issue_flush(zmd->dev->bdev, GFP_NOIO, NULL);
return ret;
}
@@ -658,7 +658,7 @@ static int dmz_write_dirty_mblocks(struct dmz_metadata *zmd,
/* Flush drive cache (this will also sync data) */
if (ret == 0)
- ret = blkdev_issue_flush(zmd->dev->bdev, GFP_KERNEL, NULL);
+ ret = blkdev_issue_flush(zmd->dev->bdev, GFP_NOIO, NULL);
return ret;
}
@@ -722,7 +722,7 @@ int dmz_flush_metadata(struct dmz_metadata *zmd)
/* If there are no dirty metadata blocks, just flush the device cache */
if (list_empty(&write_list)) {
- ret = blkdev_issue_flush(zmd->dev->bdev, GFP_KERNEL, NULL);
+ ret = blkdev_issue_flush(zmd->dev->bdev, GFP_NOIO, NULL);
goto out;
}
@@ -927,7 +927,7 @@ static int dmz_recover_mblocks(struct dmz_metadata *zmd, unsigned int dst_set)
(zmd->nr_meta_zones << zmd->dev->zone_nr_blocks_shift);
}
- page = alloc_page(GFP_KERNEL);
+ page = alloc_page(GFP_NOIO);
if (!page)
return -ENOMEM;
@@ -1183,7 +1183,7 @@ static int dmz_update_zone(struct dmz_metadata *zmd, struct dm_zone *zone)
/* Get zone information from disk */
ret = blkdev_report_zones(zmd->dev->bdev, dmz_start_sect(zmd, zone),
- &blkz, &nr_blkz, GFP_KERNEL);
+ &blkz, &nr_blkz, GFP_NOIO);
if (ret) {
dmz_dev_err(zmd->dev, "Get zone %u report failed",
dmz_id(zmd, zone));
@@ -1257,7 +1257,7 @@ static int dmz_reset_zone(struct dmz_metadata *zmd, struct dm_zone *zone)
ret = blkdev_reset_zones(dev->bdev,
dmz_start_sect(zmd, zone),
- dev->zone_nr_sectors, GFP_KERNEL);
+ dev->zone_nr_sectors, GFP_NOIO);
if (ret) {
dmz_dev_err(dev, "Reset zone %u failed %d",
dmz_id(zmd, zone), ret);
diff --git a/drivers/md/dm-zoned-reclaim.c b/drivers/md/dm-zoned-reclaim.c
index 05c0a126f5c8..44a119e12f1a 100644
--- a/drivers/md/dm-zoned-reclaim.c
+++ b/drivers/md/dm-zoned-reclaim.c
@@ -75,7 +75,7 @@ static int dmz_reclaim_align_wp(struct dmz_reclaim *zrc, struct dm_zone *zone,
nr_blocks = block - wp_block;
ret = blkdev_issue_zeroout(zrc->dev->bdev,
dmz_start_sect(zmd, zone) + dmz_blk2sect(wp_block),
- dmz_blk2sect(nr_blocks), GFP_NOFS, false);
+ dmz_blk2sect(nr_blocks), GFP_NOIO, 0);
if (ret) {
dmz_dev_err(zrc->dev,
"Align zone %u wp %llu to %llu (wp+%u) blocks failed %d",
diff --git a/drivers/md/dm-zoned-target.c b/drivers/md/dm-zoned-target.c
index 2b538fa817f4..b08bbbd4d902 100644
--- a/drivers/md/dm-zoned-target.c
+++ b/drivers/md/dm-zoned-target.c
@@ -541,7 +541,7 @@ static void dmz_queue_chunk_work(struct dmz_target *dmz, struct bio *bio)
int ret;
/* Create a new chunk work */
- cw = kmalloc(sizeof(struct dm_chunk_work), GFP_NOFS);
+ cw = kmalloc(sizeof(struct dm_chunk_work), GFP_NOIO);
if (!cw)
goto out;
@@ -588,7 +588,7 @@ static int dmz_map(struct dm_target *ti, struct bio *bio)
bio->bi_bdev = dev->bdev;
- if (!nr_sectors && (bio_op(bio) != REQ_OP_FLUSH) && (bio_op(bio) != REQ_OP_WRITE))
+ if (!nr_sectors && bio_op(bio) != REQ_OP_WRITE)
return DM_MAPIO_REMAPPED;
/* The BIO should be block aligned */
@@ -603,7 +603,7 @@ static int dmz_map(struct dm_target *ti, struct bio *bio)
bioctx->status = BLK_STS_OK;
/* Set the BIO pending in the flush list */
- if (bio_op(bio) == REQ_OP_FLUSH || (!nr_sectors && bio_op(bio) == REQ_OP_WRITE)) {
+ if (!nr_sectors && bio_op(bio) == REQ_OP_WRITE) {
spin_lock(&dmz->flush_lock);
bio_list_add(&dmz->flush_list, bio);
spin_unlock(&dmz->flush_lock);
@@ -785,7 +785,7 @@ static int dmz_ctr(struct dm_target *ti, unsigned int argc, char **argv)
/* Chunk BIO work */
mutex_init(&dmz->chunk_lock);
- INIT_RADIX_TREE(&dmz->chunk_rxtree, GFP_NOFS);
+ INIT_RADIX_TREE(&dmz->chunk_rxtree, GFP_KERNEL);
dmz->chunk_wq = alloc_workqueue("dmz_cwq_%s", WQ_MEM_RECLAIM | WQ_UNBOUND,
0, dev->name);
if (!dmz->chunk_wq) {
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 8cdca0296749..c99634612fc4 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2287,7 +2287,7 @@ static void export_array(struct mddev *mddev)
static bool set_in_sync(struct mddev *mddev)
{
- WARN_ON_ONCE(!spin_is_locked(&mddev->lock));
+ WARN_ON_ONCE(NR_CPUS != 1 && !spin_is_locked(&mddev->lock));
if (!mddev->in_sync) {
mddev->sync_checkers++;
spin_unlock(&mddev->lock);
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 991f0fe2dcc6..09db03455801 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -134,7 +134,9 @@ enum flag_bits {
Faulty, /* device is known to have a fault */
In_sync, /* device is in_sync with rest of array */
Bitmap_sync, /* ..actually, not quite In_sync. Need a
- * bitmap-based recovery to get fully in sync
+ * bitmap-based recovery to get fully in sync.
+ * The bit is only meaningful before device
+ * has been passed to pers->hot_add_disk.
*/
WriteMostly, /* Avoid reading if at all possible */
AutoDetected, /* added by auto-detect */
@@ -729,58 +731,4 @@ static inline void mddev_check_write_zeroes(struct mddev *mddev, struct bio *bio
!bdev_get_queue(bio->bi_bdev)->limits.max_write_zeroes_sectors)
mddev->queue->limits.max_write_zeroes_sectors = 0;
}
-
-/* Maximum size of each resync request */
-#define RESYNC_BLOCK_SIZE (64*1024)
-#define RESYNC_PAGES ((RESYNC_BLOCK_SIZE + PAGE_SIZE-1) / PAGE_SIZE)
-
-/* for managing resync I/O pages */
-struct resync_pages {
- unsigned idx; /* for get/put page from the pool */
- void *raid_bio;
- struct page *pages[RESYNC_PAGES];
-};
-
-static inline int resync_alloc_pages(struct resync_pages *rp,
- gfp_t gfp_flags)
-{
- int i;
-
- for (i = 0; i < RESYNC_PAGES; i++) {
- rp->pages[i] = alloc_page(gfp_flags);
- if (!rp->pages[i])
- goto out_free;
- }
-
- return 0;
-
-out_free:
- while (--i >= 0)
- put_page(rp->pages[i]);
- return -ENOMEM;
-}
-
-static inline void resync_free_pages(struct resync_pages *rp)
-{
- int i;
-
- for (i = 0; i < RESYNC_PAGES; i++)
- put_page(rp->pages[i]);
-}
-
-static inline void resync_get_all_pages(struct resync_pages *rp)
-{
- int i;
-
- for (i = 0; i < RESYNC_PAGES; i++)
- get_page(rp->pages[i]);
-}
-
-static inline struct page *resync_fetch_page(struct resync_pages *rp,
- unsigned idx)
-{
- if (WARN_ON_ONCE(idx >= RESYNC_PAGES))
- return NULL;
- return rp->pages[idx];
-}
#endif /* _MD_MD_H */
diff --git a/drivers/md/raid1-10.c b/drivers/md/raid1-10.c
new file mode 100644
index 000000000000..9f2670b45f31
--- /dev/null
+++ b/drivers/md/raid1-10.c
@@ -0,0 +1,81 @@
+/* Maximum size of each resync request */
+#define RESYNC_BLOCK_SIZE (64*1024)
+#define RESYNC_PAGES ((RESYNC_BLOCK_SIZE + PAGE_SIZE-1) / PAGE_SIZE)
+
+/* for managing resync I/O pages */
+struct resync_pages {
+ void *raid_bio;
+ struct page *pages[RESYNC_PAGES];
+};
+
+static inline int resync_alloc_pages(struct resync_pages *rp,
+ gfp_t gfp_flags)
+{
+ int i;
+
+ for (i = 0; i < RESYNC_PAGES; i++) {
+ rp->pages[i] = alloc_page(gfp_flags);
+ if (!rp->pages[i])
+ goto out_free;
+ }
+
+ return 0;
+
+out_free:
+ while (--i >= 0)
+ put_page(rp->pages[i]);
+ return -ENOMEM;
+}
+
+static inline void resync_free_pages(struct resync_pages *rp)
+{
+ int i;
+
+ for (i = 0; i < RESYNC_PAGES; i++)
+ put_page(rp->pages[i]);
+}
+
+static inline void resync_get_all_pages(struct resync_pages *rp)
+{
+ int i;
+
+ for (i = 0; i < RESYNC_PAGES; i++)
+ get_page(rp->pages[i]);
+}
+
+static inline struct page *resync_fetch_page(struct resync_pages *rp,
+ unsigned idx)
+{
+ if (WARN_ON_ONCE(idx >= RESYNC_PAGES))
+ return NULL;
+ return rp->pages[idx];
+}
+
+/*
+ * 'strct resync_pages' stores actual pages used for doing the resync
+ * IO, and it is per-bio, so make .bi_private points to it.
+ */
+static inline struct resync_pages *get_resync_pages(struct bio *bio)
+{
+ return bio->bi_private;
+}
+
+/* generally called after bio_reset() for reseting bvec */
+static void md_bio_reset_resync_pages(struct bio *bio, struct resync_pages *rp,
+ int size)
+{
+ int idx = 0;
+
+ /* initialize bvec table again */
+ do {
+ struct page *page = resync_fetch_page(rp, idx);
+ int len = min_t(int, size, PAGE_SIZE);
+
+ /*
+ * won't fail because the vec table is big
+ * enough to hold all these pages
+ */
+ bio_add_page(bio, page, len, 0);
+ size -= len;
+ } while (idx++ < RESYNC_PAGES && size > 0);
+}
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 3febfc8391fb..f50958ded9f0 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -81,14 +81,7 @@ static void lower_barrier(struct r1conf *conf, sector_t sector_nr);
#define raid1_log(md, fmt, args...) \
do { if ((md)->queue) blk_add_trace_msg((md)->queue, "raid1 " fmt, ##args); } while (0)
-/*
- * 'strct resync_pages' stores actual pages used for doing the resync
- * IO, and it is per-bio, so make .bi_private points to it.
- */
-static inline struct resync_pages *get_resync_pages(struct bio *bio)
-{
- return bio->bi_private;
-}
+#include "raid1-10.c"
/*
* for resync bio, r1bio pointer can be retrieved from the per-bio
@@ -170,7 +163,6 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)
resync_get_all_pages(rp);
}
- rp->idx = 0;
rp->raid_bio = r1_bio;
bio->bi_private = rp;
}
@@ -492,10 +484,6 @@ static void raid1_end_write_request(struct bio *bio)
}
if (behind) {
- /* we release behind master bio when all write are done */
- if (r1_bio->behind_master_bio == bio)
- to_put = NULL;
-
if (test_bit(WriteMostly, &rdev->flags))
atomic_dec(&r1_bio->behind_remaining);
@@ -802,8 +790,7 @@ static void flush_bio_list(struct r1conf *conf, struct bio *bio)
bio->bi_next = NULL;
bio->bi_bdev = rdev->bdev;
if (test_bit(Faulty, &rdev->flags)) {
- bio->bi_status = BLK_STS_IOERR;
- bio_endio(bio);
+ bio_io_error(bio);
} else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
!blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
/* Just ignore it */
@@ -1088,7 +1075,7 @@ static void unfreeze_array(struct r1conf *conf)
wake_up(&conf->wait_barrier);
}
-static struct bio *alloc_behind_master_bio(struct r1bio *r1_bio,
+static void alloc_behind_master_bio(struct r1bio *r1_bio,
struct bio *bio)
{
int size = bio->bi_iter.bi_size;
@@ -1098,11 +1085,13 @@ static struct bio *alloc_behind_master_bio(struct r1bio *r1_bio,
behind_bio = bio_alloc_mddev(GFP_NOIO, vcnt, r1_bio->mddev);
if (!behind_bio)
- goto fail;
+ return;
/* discard op, we don't support writezero/writesame yet */
- if (!bio_has_data(bio))
+ if (!bio_has_data(bio)) {
+ behind_bio->bi_iter.bi_size = size;
goto skip_copy;
+ }
while (i < vcnt && size) {
struct page *page;
@@ -1123,14 +1112,13 @@ skip_copy:
r1_bio->behind_master_bio = behind_bio;;
set_bit(R1BIO_BehindIO, &r1_bio->state);
- return behind_bio;
+ return;
free_pages:
pr_debug("%dB behind alloc failed, doing sync I/O\n",
bio->bi_iter.bi_size);
bio_free_pages(behind_bio);
-fail:
- return behind_bio;
+ bio_put(behind_bio);
}
struct raid1_plug_cb {
@@ -1483,7 +1471,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
(atomic_read(&bitmap->behind_writes)
< mddev->bitmap_info.max_write_behind) &&
!waitqueue_active(&bitmap->behind_wait)) {
- mbio = alloc_behind_master_bio(r1_bio, bio);
+ alloc_behind_master_bio(r1_bio, bio);
}
bitmap_startwrite(bitmap, r1_bio->sector,
@@ -1493,14 +1481,11 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
first_clone = 0;
}
- if (!mbio) {
- if (r1_bio->behind_master_bio)
- mbio = bio_clone_fast(r1_bio->behind_master_bio,
- GFP_NOIO,
- mddev->bio_set);
- else
- mbio = bio_clone_fast(bio, GFP_NOIO, mddev->bio_set);
- }
+ if (r1_bio->behind_master_bio)
+ mbio = bio_clone_fast(r1_bio->behind_master_bio,
+ GFP_NOIO, mddev->bio_set);
+ else
+ mbio = bio_clone_fast(bio, GFP_NOIO, mddev->bio_set);
if (r1_bio->behind_master_bio) {
if (test_bit(WriteMostly, &conf->mirrors[i].rdev->flags))
@@ -2086,10 +2071,7 @@ static void process_checks(struct r1bio *r1_bio)
/* Fix variable parts of all bios */
vcnt = (r1_bio->sectors + PAGE_SIZE / 512 - 1) >> (PAGE_SHIFT - 9);
for (i = 0; i < conf->raid_disks * 2; i++) {
- int j;
- int size;
blk_status_t status;
- struct bio_vec *bi;
struct bio *b = r1_bio->bios[i];
struct resync_pages *rp = get_resync_pages(b);
if (b->bi_end_io != end_sync_read)
@@ -2098,8 +2080,6 @@ static void process_checks(struct r1bio *r1_bio)
status = b->bi_status;
bio_reset(b);
b->bi_status = status;
- b->bi_vcnt = vcnt;
- b->bi_iter.bi_size = r1_bio->sectors << 9;
b->bi_iter.bi_sector = r1_bio->sector +
conf->mirrors[i].rdev->data_offset;
b->bi_bdev = conf->mirrors[i].rdev->bdev;
@@ -2107,15 +2087,8 @@ static void process_checks(struct r1bio *r1_bio)
rp->raid_bio = r1_bio;
b->bi_private = rp;
- size = b->bi_iter.bi_size;
- bio_for_each_segment_all(bi, b, j) {
- bi->bv_offset = 0;
- if (size > PAGE_SIZE)
- bi->bv_len = PAGE_SIZE;
- else
- bi->bv_len = size;
- size -= PAGE_SIZE;
- }
+ /* initialize bvec table again */
+ md_bio_reset_resync_pages(b, rp, r1_bio->sectors << 9);
}
for (primary = 0; primary < conf->raid_disks * 2; primary++)
if (r1_bio->bios[primary]->bi_end_io == end_sync_read &&
@@ -2366,8 +2339,6 @@ static int narrow_write_error(struct r1bio *r1_bio, int i)
wbio = bio_clone_fast(r1_bio->behind_master_bio,
GFP_NOIO,
mddev->bio_set);
- /* We really need a _all clone */
- wbio->bi_iter = (struct bvec_iter){ 0 };
} else {
wbio = bio_clone_fast(r1_bio->master_bio, GFP_NOIO,
mddev->bio_set);
@@ -2619,6 +2590,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
int good_sectors = RESYNC_SECTORS;
int min_bad = 0; /* number of sectors that are bad in all devices */
int idx = sector_to_idx(sector_nr);
+ int page_idx = 0;
if (!conf->r1buf_pool)
if (init_resync(conf))
@@ -2846,7 +2818,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
bio = r1_bio->bios[i];
rp = get_resync_pages(bio);
if (bio->bi_end_io) {
- page = resync_fetch_page(rp, rp->idx++);
+ page = resync_fetch_page(rp, page_idx);
/*
* won't fail because the vec table is big
@@ -2858,7 +2830,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
nr_sectors += len>>9;
sector_nr += len>>9;
sync_blocks -= (len>>9);
- } while (get_resync_pages(r1_bio->bios[disk]->bi_private)->idx < RESYNC_PAGES);
+ } while (++page_idx < RESYNC_PAGES);
r1_bio->sectors = nr_sectors;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 5026e7ad51d3..f55d4cc085f6 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -110,14 +110,7 @@ static void end_reshape(struct r10conf *conf);
#define raid10_log(md, fmt, args...) \
do { if ((md)->queue) blk_add_trace_msg((md)->queue, "raid10 " fmt, ##args); } while (0)
-/*
- * 'strct resync_pages' stores actual pages used for doing the resync
- * IO, and it is per-bio, so make .bi_private points to it.
- */
-static inline struct resync_pages *get_resync_pages(struct bio *bio)
-{
- return bio->bi_private;
-}
+#include "raid1-10.c"
/*
* for resync bio, r10bio pointer can be retrieved from the per-bio
@@ -221,7 +214,6 @@ static void * r10buf_pool_alloc(gfp_t gfp_flags, void *data)
resync_get_all_pages(rp);
}
- rp->idx = 0;
rp->raid_bio = r10_bio;
bio->bi_private = rp;
if (rbio) {
@@ -913,8 +905,7 @@ static void flush_pending_writes(struct r10conf *conf)
bio->bi_next = NULL;
bio->bi_bdev = rdev->bdev;
if (test_bit(Faulty, &rdev->flags)) {
- bio->bi_status = BLK_STS_IOERR;
- bio_endio(bio);
+ bio_io_error(bio);
} else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
!blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
/* Just ignore it */
@@ -1098,8 +1089,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
bio->bi_next = NULL;
bio->bi_bdev = rdev->bdev;
if (test_bit(Faulty, &rdev->flags)) {
- bio->bi_status = BLK_STS_IOERR;
- bio_endio(bio);
+ bio_io_error(bio);
} else if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
!blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
/* Just ignore it */
@@ -2087,8 +2077,8 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
rp = get_resync_pages(tbio);
bio_reset(tbio);
- tbio->bi_vcnt = vcnt;
- tbio->bi_iter.bi_size = fbio->bi_iter.bi_size;
+ md_bio_reset_resync_pages(tbio, rp, fbio->bi_iter.bi_size);
+
rp->raid_bio = r10_bio;
tbio->bi_private = rp;
tbio->bi_iter.bi_sector = r10_bio->devs[i].addr;
@@ -2853,6 +2843,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
sector_t sectors_skipped = 0;
int chunks_skipped = 0;
sector_t chunk_mask = conf->geo.chunk_mask;
+ int page_idx = 0;
if (!conf->r10buf_pool)
if (init_resync(conf))
@@ -3355,7 +3346,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
break;
for (bio= biolist ; bio ; bio=bio->bi_next) {
struct resync_pages *rp = get_resync_pages(bio);
- page = resync_fetch_page(rp, rp->idx++);
+ page = resync_fetch_page(rp, page_idx);
/*
* won't fail because the vec table is big enough
* to hold all these pages
@@ -3364,7 +3355,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
}
nr_sectors += len>>9;
sector_nr += len>>9;
- } while (get_resync_pages(biolist)->idx < RESYNC_PAGES);
+ } while (++page_idx < RESYNC_PAGES);
r10_bio->sectors = nr_sectors;
while (biolist) {
diff --git a/drivers/md/raid5-ppl.c b/drivers/md/raid5-ppl.c
index 77cce3573aa8..44ad5baf3206 100644
--- a/drivers/md/raid5-ppl.c
+++ b/drivers/md/raid5-ppl.c
@@ -1150,7 +1150,7 @@ int ppl_init_log(struct r5conf *conf)
goto err;
}
- ppl_conf->bs = bioset_create(conf->raid_disks, 0, 0);
+ ppl_conf->bs = bioset_create(conf->raid_disks, 0, BIOSET_NEED_BVECS);
if (!ppl_conf->bs) {
ret = -ENOMEM;
goto err;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 2ceb338b094b..0fc2748aaf95 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3381,9 +3381,8 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh,
sh->dev[i].sector + STRIPE_SECTORS) {
struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector);
- bi->bi_status = BLK_STS_IOERR;
md_write_end(conf->mddev);
- bio_endio(bi);
+ bio_io_error(bi);
bi = nextbi;
}
if (bitmap_end)
@@ -3403,9 +3402,8 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh,
sh->dev[i].sector + STRIPE_SECTORS) {
struct bio *bi2 = r5_next_bio(bi, sh->dev[i].sector);
- bi->bi_status = BLK_STS_IOERR;
md_write_end(conf->mddev);
- bio_endio(bi);
+ bio_io_error(bi);
bi = bi2;
}
@@ -3429,8 +3427,7 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh,
struct bio *nextbi =
r5_next_bio(bi, sh->dev[i].sector);
- bi->bi_status = BLK_STS_IOERR;
- bio_endio(bi);
+ bio_io_error(bi);
bi = nextbi;
}
}
@@ -6237,6 +6234,8 @@ static void raid5_do_work(struct work_struct *work)
pr_debug("%d stripes handled\n", handled);
spin_unlock_irq(&conf->device_lock);
+
+ async_tx_issue_pending_all();
blk_finish_plug(&plug);
pr_debug("--- raid5worker inactive\n");
@@ -7951,12 +7950,10 @@ static void end_reshape(struct r5conf *conf)
{
if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {
- struct md_rdev *rdev;
spin_lock_irq(&conf->device_lock);
conf->previous_raid_disks = conf->raid_disks;
- rdev_for_each(rdev, conf->mddev)
- rdev->data_offset = rdev->new_data_offset;
+ md_finish_reshape(conf->mddev);
smp_wmb();
conf->reshape_progress = MaxSector;
conf->mddev->reshape_position = MaxSector;
diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
index bf45977b2823..d596b601ff42 100644
--- a/drivers/media/cec/cec-adap.c
+++ b/drivers/media/cec/cec-adap.c
@@ -559,7 +559,7 @@ EXPORT_SYMBOL_GPL(cec_transmit_done);
void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status)
{
- switch (status) {
+ switch (status & ~CEC_TX_STATUS_MAX_RETRIES) {
case CEC_TX_STATUS_OK:
cec_transmit_done(adap, status, 0, 0, 0, 0);
return;
diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
index 74dc1c32080e..08b619d0ea1e 100644
--- a/drivers/media/cec/cec-notifier.c
+++ b/drivers/media/cec/cec-notifier.c
@@ -87,6 +87,9 @@ EXPORT_SYMBOL_GPL(cec_notifier_put);
void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa)
{
+ if (n == NULL)
+ return;
+
mutex_lock(&n->lock);
n->phys_addr = pa;
if (n->callback)
@@ -100,6 +103,9 @@ void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n,
{
u16 pa = CEC_PHYS_ADDR_INVALID;
+ if (n == NULL)
+ return;
+
if (edid && edid->extensions)
pa = cec_get_edid_phys_addr((const u8 *)edid,
EDID_LENGTH * (edid->extensions + 1), NULL);
diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c
index af694f2066a2..17970cdd55fa 100644
--- a/drivers/media/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb-core/dvb_ca_en50221.c
@@ -349,7 +349,8 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot)
/* read the buffer size from the CAM */
if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN | CMDREG_SR)) != 0)
return ret;
- if ((ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_DA, HZ / 10)) != 0)
+ ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_DA, HZ);
+ if (ret != 0)
return ret;
if ((ret = dvb_ca_en50221_read_data(ca, slot, buf, 2)) != 2)
return -EIO;
@@ -644,72 +645,101 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot,
}
buf_free = dvb_ringbuffer_free(&ca->slot_info[slot].rx_buffer);
- if (buf_free < (ca->slot_info[slot].link_buf_size + DVB_RINGBUFFER_PKTHDRSIZE)) {
+ if (buf_free < (ca->slot_info[slot].link_buf_size +
+ DVB_RINGBUFFER_PKTHDRSIZE)) {
status = -EAGAIN;
goto exit;
}
}
- /* check if there is data available */
- if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
- goto exit;
- if (!(status & STATUSREG_DA)) {
- /* no data */
- status = 0;
- goto exit;
- }
-
- /* read the amount of data */
- if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH)) < 0)
- goto exit;
- bytes_read = status << 8;
- if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW)) < 0)
- goto exit;
- bytes_read |= status;
+ if (ca->pub->read_data &&
+ (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_LINKINIT)) {
+ if (ebuf == NULL)
+ status = ca->pub->read_data(ca->pub, slot, buf,
+ sizeof(buf));
+ else
+ status = ca->pub->read_data(ca->pub, slot, buf, ecount);
+ if (status < 0)
+ return status;
+ bytes_read = status;
+ if (status == 0)
+ goto exit;
+ } else {
- /* check it will fit */
- if (ebuf == NULL) {
- if (bytes_read > ca->slot_info[slot].link_buf_size) {
- pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n",
- ca->dvbdev->adapter->num, bytes_read,
- ca->slot_info[slot].link_buf_size);
- ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
- status = -EIO;
+ /* check if there is data available */
+ status = ca->pub->read_cam_control(ca->pub, slot,
+ CTRLIF_STATUS);
+ if (status < 0)
goto exit;
- }
- if (bytes_read < 2) {
- pr_err("dvb_ca adapter %d: CAM sent a buffer that was less than 2 bytes!\n",
- ca->dvbdev->adapter->num);
- ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
- status = -EIO;
+ if (!(status & STATUSREG_DA)) {
+ /* no data */
+ status = 0;
goto exit;
}
- } else {
- if (bytes_read > ecount) {
- pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the ecount size!\n",
- ca->dvbdev->adapter->num);
- status = -EIO;
+
+ /* read the amount of data */
+ status = ca->pub->read_cam_control(ca->pub, slot,
+ CTRLIF_SIZE_HIGH);
+ if (status < 0)
+ goto exit;
+ bytes_read = status << 8;
+ status = ca->pub->read_cam_control(ca->pub, slot,
+ CTRLIF_SIZE_LOW);
+ if (status < 0)
goto exit;
+ bytes_read |= status;
+
+ /* check it will fit */
+ if (ebuf == NULL) {
+ if (bytes_read > ca->slot_info[slot].link_buf_size) {
+ pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n",
+ ca->dvbdev->adapter->num, bytes_read,
+ ca->slot_info[slot].link_buf_size);
+ ca->slot_info[slot].slot_state =
+ DVB_CA_SLOTSTATE_LINKINIT;
+ status = -EIO;
+ goto exit;
+ }
+ if (bytes_read < 2) {
+ pr_err("dvb_ca adapter %d: CAM sent a buffer that was less than 2 bytes!\n",
+ ca->dvbdev->adapter->num);
+ ca->slot_info[slot].slot_state =
+ DVB_CA_SLOTSTATE_LINKINIT;
+ status = -EIO;
+ goto exit;
+ }
+ } else {
+ if (bytes_read > ecount) {
+ pr_err("dvb_ca adapter %d: CAM tried to send a buffer larger than the ecount size!\n",
+ ca->dvbdev->adapter->num);
+ status = -EIO;
+ goto exit;
+ }
}
- }
- /* fill the buffer */
- for (i = 0; i < bytes_read; i++) {
- /* read byte and check */
- if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_DATA)) < 0)
- goto exit;
+ /* fill the buffer */
+ for (i = 0; i < bytes_read; i++) {
+ /* read byte and check */
+ status = ca->pub->read_cam_control(ca->pub, slot,
+ CTRLIF_DATA);
+ if (status < 0)
+ goto exit;
- /* OK, store it in the buffer */
- buf[i] = status;
- }
+ /* OK, store it in the buffer */
+ buf[i] = status;
+ }
- /* check for read error (RE should now be 0) */
- if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0)
- goto exit;
- if (status & STATUSREG_RE) {
- ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT;
- status = -EIO;
- goto exit;
+ /* check for read error (RE should now be 0) */
+ status = ca->pub->read_cam_control(ca->pub, slot,
+ CTRLIF_STATUS);
+ if (status < 0)
+ goto exit;
+ if (status & STATUSREG_RE) {
+ ca->slot_info[slot].slot_state =
+ DVB_CA_SLOTSTATE_LINKINIT;
+ status = -EIO;
+ goto exit;
+ }
}
/* OK, add it to the receive buffer, or copy into external buffer if supplied */
@@ -762,6 +792,10 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
if (bytes_write > ca->slot_info[slot].link_buf_size)
return -EINVAL;
+ if (ca->pub->write_data &&
+ (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_LINKINIT))
+ return ca->pub->write_data(ca->pub, slot, buf, bytes_write);
+
/* it is possible we are dealing with a single buffer implementation,
thus if there is data available for read or if there is even a read
already in progress, we do nothing but awake the kernel thread to
@@ -1176,7 +1210,8 @@ static int dvb_ca_en50221_thread(void *data)
pr_err("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n",
ca->dvbdev->adapter->num);
- ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
+ ca->slot_info[slot].slot_state =
+ DVB_CA_SLOTSTATE_UNINITIALISED;
dvb_ca_en50221_thread_update_delay(ca);
break;
}
diff --git a/drivers/media/dvb-core/dvb_ca_en50221.h b/drivers/media/dvb-core/dvb_ca_en50221.h
index 1e4bbbd34d91..82617bac0875 100644
--- a/drivers/media/dvb-core/dvb_ca_en50221.h
+++ b/drivers/media/dvb-core/dvb_ca_en50221.h
@@ -41,6 +41,8 @@
* @write_attribute_mem: function for writing attribute memory on the CAM
* @read_cam_control: function for reading the control interface on the CAM
* @write_cam_control: function for reading the control interface on the CAM
+ * @read_data: function for reading data (block mode)
+ * @write_data: function for writing data (block mode)
* @slot_reset: function to reset the CAM slot
* @slot_shutdown: function to shutdown a CAM slot
* @slot_ts_enable: function to enable the Transport Stream on a CAM slot
@@ -66,6 +68,11 @@ struct dvb_ca_en50221 {
int (*write_cam_control)(struct dvb_ca_en50221 *ca,
int slot, u8 address, u8 value);
+ int (*read_data)(struct dvb_ca_en50221 *ca,
+ int slot, u8 *ebuf, int ecount);
+ int (*write_data)(struct dvb_ca_en50221 *ca,
+ int slot, u8 *ebuf, int ecount);
+
int (*slot_reset)(struct dvb_ca_en50221 *ca, int slot);
int (*slot_shutdown)(struct dvb_ca_en50221 *ca, int slot);
int (*slot_ts_enable)(struct dvb_ca_en50221 *ca, int slot);
diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c
index 08f67d60a7d9..12bff778c97f 100644
--- a/drivers/media/dvb-frontends/cxd2841er.c
+++ b/drivers/media/dvb-frontends/cxd2841er.c
@@ -3279,7 +3279,10 @@ static int cxd2841er_get_frontend(struct dvb_frontend *fe,
else if (priv->state == STATE_ACTIVE_TC)
cxd2841er_read_status_tc(fe, &status);
- cxd2841er_read_signal_strength(fe);
+ if (priv->state == STATE_ACTIVE_TC || priv->state == STATE_ACTIVE_S)
+ cxd2841er_read_signal_strength(fe);
+ else
+ p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
if (status & FE_HAS_LOCK) {
cxd2841er_read_snr(fe);
diff --git a/drivers/media/dvb-frontends/drx39xyj/drx_driver.h b/drivers/media/dvb-frontends/drx39xyj/drx_driver.h
index 4442e478db72..cd69e187ba7a 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drx_driver.h
+++ b/drivers/media/dvb-frontends/drx39xyj/drx_driver.h
@@ -307,7 +307,7 @@ int drxbsp_tuner_default_i2c_write_read(struct tuner_instance *tuner,
* \def DRX_UNKNOWN
* \brief Generic UNKNOWN value for DRX enumerated types.
*
-* Used to indicate that the parameter value is unknown or not yet initalized.
+* Used to indicate that the parameter value is unknown or not yet initialized.
*/
#ifndef DRX_UNKNOWN
#define DRX_UNKNOWN (254)
@@ -450,19 +450,6 @@ MACROS
((u8)((((u16)x)>>8)&0xFF))
/**
-* \brief Macro to sign extend signed 9 bit value to signed 16 bit value
-*/
-#define DRX_S9TOS16(x) ((((u16)x)&0x100) ? ((s16)((u16)(x)|0xFF00)) : (x))
-
-/**
-* \brief Macro to sign extend signed 9 bit value to signed 16 bit value
-*/
-#define DRX_S24TODRXFREQ(x) ((((u32) x) & 0x00800000UL) ? \
- ((s32) \
- (((u32) x) | 0xFF000000)) : \
- ((s32) x))
-
-/**
* \brief Macro to convert 16 bit register value to a s32
*/
#define DRX_U16TODRXFREQ(x) ((x & 0x8000) ? \
diff --git a/drivers/media/dvb-frontends/lnbh25.c b/drivers/media/dvb-frontends/lnbh25.c
index ef3021e964be..cb486e879fdd 100644
--- a/drivers/media/dvb-frontends/lnbh25.c
+++ b/drivers/media/dvb-frontends/lnbh25.c
@@ -76,8 +76,8 @@ static int lnbh25_read_vmon(struct lnbh25_priv *priv)
return ret;
}
}
- print_hex_dump_bytes("lnbh25_read_vmon: ",
- DUMP_PREFIX_OFFSET, status, sizeof(status));
+ dev_dbg(&priv->i2c->dev, "%s(): %*ph\n",
+ __func__, (int) sizeof(status), status);
if ((status[0] & (LNBH25_STATUS_OFL | LNBH25_STATUS_VMON)) != 0) {
dev_err(&priv->i2c->dev,
"%s(): voltage in failure state, status reg 0x%x\n",
@@ -178,7 +178,7 @@ struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe,
fe->ops.release_sec = lnbh25_release;
fe->ops.set_voltage = lnbh25_set_voltage;
- dev_err(&i2c->dev, "%s(): attached at I2C addr 0x%02x\n",
+ dev_info(&i2c->dev, "%s(): attached at I2C addr 0x%02x\n",
__func__, priv->i2c_address);
return fe;
}
diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c
index e726c2e00460..8ac0f598978d 100644
--- a/drivers/media/dvb-frontends/stv0367.c
+++ b/drivers/media/dvb-frontends/stv0367.c
@@ -25,6 +25,8 @@
#include <linux/slab.h>
#include <linux/i2c.h>
+#include "dvb_math.h"
+
#include "stv0367.h"
#include "stv0367_defs.h"
#include "stv0367_regs.h"
@@ -1437,7 +1439,7 @@ static int stv0367ter_get_frontend(struct dvb_frontend *fe,
return 0;
}
-static int stv0367ter_read_snr(struct dvb_frontend *fe, u16 *snr)
+static u32 stv0367ter_snr_readreg(struct dvb_frontend *fe)
{
struct stv0367_state *state = fe->demodulator_priv;
u32 snru32 = 0;
@@ -1453,10 +1455,16 @@ static int stv0367ter_read_snr(struct dvb_frontend *fe, u16 *snr)
cpt++;
}
-
snru32 /= 10;/*average on 10 values*/
- *snr = snru32 / 1000;
+ return snru32;
+}
+
+static int stv0367ter_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ u32 snrval = stv0367ter_snr_readreg(fe);
+
+ *snr = snrval / 1000;
return 0;
}
@@ -1501,7 +1509,8 @@ static int stv0367ter_read_status(struct dvb_frontend *fe,
*status = 0;
if (stv0367_readbits(state, F367TER_LK)) {
- *status |= FE_HAS_LOCK;
+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI
+ | FE_HAS_SYNC | FE_HAS_LOCK;
dprintk("%s: stv0367 has locked\n", __func__);
}
@@ -2149,6 +2158,18 @@ static int stv0367cab_read_status(struct dvb_frontend *fe,
*status = 0;
+ if (state->cab_state->state > FE_CAB_NOSIGNAL)
+ *status |= FE_HAS_SIGNAL;
+
+ if (state->cab_state->state > FE_CAB_NOCARRIER)
+ *status |= FE_HAS_CARRIER;
+
+ if (state->cab_state->state >= FE_CAB_DEMODOK)
+ *status |= FE_HAS_VITERBI;
+
+ if (state->cab_state->state >= FE_CAB_DATAOK)
+ *status |= FE_HAS_SYNC;
+
if (stv0367_readbits(state, (state->cab_state->qamfec_status_reg ?
state->cab_state->qamfec_status_reg : F367CAB_QAMFEC_LOCK))) {
*status |= FE_HAS_LOCK;
@@ -2702,51 +2723,61 @@ static int stv0367cab_read_strength(struct dvb_frontend *fe, u16 *strength)
return 0;
}
-static int stv0367cab_read_snr(struct dvb_frontend *fe, u16 *snr)
+static int stv0367cab_snr_power(struct dvb_frontend *fe)
{
struct stv0367_state *state = fe->demodulator_priv;
- u32 noisepercentage;
enum stv0367cab_mod QAMSize;
- u32 regval = 0, temp = 0;
- int power, i;
QAMSize = stv0367_readbits(state, F367CAB_QAM_MODE);
switch (QAMSize) {
case FE_CAB_MOD_QAM4:
- power = 21904;
- break;
+ return 21904;
case FE_CAB_MOD_QAM16:
- power = 20480;
- break;
+ return 20480;
case FE_CAB_MOD_QAM32:
- power = 23040;
- break;
+ return 23040;
case FE_CAB_MOD_QAM64:
- power = 21504;
- break;
+ return 21504;
case FE_CAB_MOD_QAM128:
- power = 23616;
- break;
+ return 23616;
case FE_CAB_MOD_QAM256:
- power = 21760;
- break;
- case FE_CAB_MOD_QAM512:
- power = 1;
- break;
+ return 21760;
case FE_CAB_MOD_QAM1024:
- power = 21280;
- break;
+ return 21280;
default:
- power = 1;
break;
}
+ return 1;
+}
+
+static int stv0367cab_snr_readreg(struct dvb_frontend *fe, int avgdiv)
+{
+ struct stv0367_state *state = fe->demodulator_priv;
+ u32 regval = 0;
+ int i;
+
for (i = 0; i < 10; i++) {
regval += (stv0367_readbits(state, F367CAB_SNR_LO)
+ 256 * stv0367_readbits(state, F367CAB_SNR_HI));
}
- regval /= 10; /*for average over 10 times in for loop above*/
+ if (avgdiv)
+ regval /= 10;
+
+ return regval;
+}
+
+static int stv0367cab_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct stv0367_state *state = fe->demodulator_priv;
+ u32 noisepercentage;
+ u32 regval = 0, temp = 0;
+ int power;
+
+ power = stv0367cab_snr_power(fe);
+ regval = stv0367cab_snr_readreg(fe, 1);
+
if (regval != 0) {
temp = power
* (1 << (3 + stv0367_readbits(state, F367CAB_SNR_PER)));
@@ -2980,21 +3011,117 @@ static int stv0367ddb_set_frontend(struct dvb_frontend *fe)
return -EINVAL;
}
+static void stv0367ddb_read_signal_strength(struct dvb_frontend *fe)
+{
+ struct stv0367_state *state = fe->demodulator_priv;
+ struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+ s32 signalstrength;
+
+ switch (state->activedemod) {
+ case demod_cab:
+ signalstrength = stv0367cab_get_rf_lvl(state) * 1000;
+ break;
+ default:
+ p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ return;
+ }
+
+ p->strength.stat[0].scale = FE_SCALE_DECIBEL;
+ p->strength.stat[0].uvalue = signalstrength;
+}
+
+static void stv0367ddb_read_snr(struct dvb_frontend *fe)
+{
+ struct stv0367_state *state = fe->demodulator_priv;
+ struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+ int cab_pwr;
+ u32 regval, tmpval, snrval = 0;
+
+ switch (state->activedemod) {
+ case demod_ter:
+ snrval = stv0367ter_snr_readreg(fe);
+ break;
+ case demod_cab:
+ cab_pwr = stv0367cab_snr_power(fe);
+ regval = stv0367cab_snr_readreg(fe, 0);
+
+ /* prevent division by zero */
+ if (!regval) {
+ snrval = 0;
+ break;
+ }
+
+ tmpval = (cab_pwr * 320) / regval;
+ snrval = ((tmpval != 0) ? (intlog2(tmpval) / 5581) : 0);
+ break;
+ default:
+ p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ return;
+ }
+
+ p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+ p->cnr.stat[0].uvalue = snrval;
+}
+
+static void stv0367ddb_read_ucblocks(struct dvb_frontend *fe)
+{
+ struct stv0367_state *state = fe->demodulator_priv;
+ struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+ u32 ucblocks = 0;
+
+ switch (state->activedemod) {
+ case demod_ter:
+ stv0367ter_read_ucblocks(fe, &ucblocks);
+ break;
+ case demod_cab:
+ stv0367cab_read_ucblcks(fe, &ucblocks);
+ break;
+ default:
+ p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ return;
+ }
+
+ p->block_error.stat[0].scale = FE_SCALE_COUNTER;
+ p->block_error.stat[0].uvalue = ucblocks;
+}
+
static int stv0367ddb_read_status(struct dvb_frontend *fe,
enum fe_status *status)
{
struct stv0367_state *state = fe->demodulator_priv;
+ struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+ int ret;
switch (state->activedemod) {
case demod_ter:
- return stv0367ter_read_status(fe, status);
+ ret = stv0367ter_read_status(fe, status);
+ break;
case demod_cab:
- return stv0367cab_read_status(fe, status);
- default:
+ ret = stv0367cab_read_status(fe, status);
break;
+ default:
+ return 0;
}
- return -EINVAL;
+ /* stop and report on *_read_status failure */
+ if (ret)
+ return ret;
+
+ stv0367ddb_read_signal_strength(fe);
+
+ /* read carrier/noise when a carrier is detected */
+ if (*status & FE_HAS_CARRIER)
+ stv0367ddb_read_snr(fe);
+ else
+ p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+ /* read uncorrected blocks on FE_HAS_LOCK */
+ if (*status & FE_HAS_LOCK)
+ stv0367ddb_read_ucblocks(fe);
+ else
+ p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+ return 0;
}
static int stv0367ddb_get_frontend(struct dvb_frontend *fe,
@@ -3035,6 +3162,7 @@ static int stv0367ddb_sleep(struct dvb_frontend *fe)
static int stv0367ddb_init(struct stv0367_state *state)
{
struct stv0367ter_state *ter_state = state->ter_state;
+ struct dtv_frontend_properties *p = &state->fe.dtv_property_cache;
stv0367_writereg(state, R367TER_TOPCTRL, 0x10);
@@ -3109,6 +3237,13 @@ static int stv0367ddb_init(struct stv0367_state *state)
ter_state->first_lock = 0;
ter_state->unlock_counter = 2;
+ p->strength.len = 1;
+ p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ p->cnr.len = 1;
+ p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ p->block_error.len = 1;
+ p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
return 0;
}
@@ -3126,15 +3261,12 @@ static const struct dvb_frontend_ops stv0367ddb_ops = {
0x400 |/* FE_CAN_QAM_4 */
FE_CAN_QAM_16 | FE_CAN_QAM_32 |
FE_CAN_QAM_64 | FE_CAN_QAM_128 |
- FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
+ FE_CAN_QAM_256 | FE_CAN_QAM_AUTO |
/* DVB-T */
- FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
- FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
- FE_CAN_FEC_AUTO |
- FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
- FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO |
- FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
- FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_RECOVER | FE_CAN_INVERSION_AUTO |
FE_CAN_MUTE_TS
},
.release = stv0367_release,
diff --git a/drivers/media/i2c/et8ek8/et8ek8_driver.c b/drivers/media/i2c/et8ek8/et8ek8_driver.c
index 6e313d5243a0..f39f5179dd95 100644
--- a/drivers/media/i2c/et8ek8/et8ek8_driver.c
+++ b/drivers/media/i2c/et8ek8/et8ek8_driver.c
@@ -1496,7 +1496,6 @@ MODULE_DEVICE_TABLE(i2c, et8ek8_id_table);
static const struct dev_pm_ops et8ek8_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(et8ek8_suspend, et8ek8_resume)
};
-MODULE_DEVICE_TABLE(of, et8ek8_of_table);
static struct i2c_driver et8ek8_i2c_driver = {
.driver = {
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index 9da4bf4f2c7a..7b79a7498751 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -659,7 +659,7 @@ static int tvp5150_set_vbi(struct v4l2_subdev *sd,
struct tvp5150 *decoder = to_tvp5150(sd);
v4l2_std_id std = decoder->norm;
u8 reg;
- int pos=0;
+ int pos = 0;
if (std == V4L2_STD_ALL) {
dev_err(sd->dev, "VBI can't be configured without knowing number of lines\n");
@@ -669,33 +669,30 @@ static int tvp5150_set_vbi(struct v4l2_subdev *sd,
line += 3;
}
- if (line<6||line>27)
+ if (line < 6 || line > 27)
return 0;
- while (regs->reg != (u16)-1 ) {
+ while (regs->reg != (u16)-1) {
if ((type & regs->type.vbi_type) &&
- (line>=regs->type.ini_line) &&
- (line<=regs->type.end_line)) {
- type=regs->type.vbi_type;
+ (line >= regs->type.ini_line) &&
+ (line <= regs->type.end_line))
break;
- }
regs++;
pos++;
}
+
if (regs->reg == (u16)-1)
return 0;
- type=pos | (flags & 0xf0);
- reg=((line-6)<<1)+TVP5150_LINE_MODE_INI;
+ type = pos | (flags & 0xf0);
+ reg = ((line - 6) << 1) + TVP5150_LINE_MODE_INI;
- if (fields&1) {
+ if (fields & 1)
tvp5150_write(sd, reg, type);
- }
- if (fields&2) {
- tvp5150_write(sd, reg+1, type);
- }
+ if (fields & 2)
+ tvp5150_write(sd, reg + 1, type);
return type;
}
diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c
index 9420479bee9a..cd1723e79a07 100644
--- a/drivers/media/pci/ddbridge/ddbridge-core.c
+++ b/drivers/media/pci/ddbridge/ddbridge-core.c
@@ -17,6 +17,8 @@
* http://www.gnu.org/copyleft/gpl.html
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -114,6 +116,19 @@ static int i2c_write_reg(struct i2c_adapter *adap, u8 adr,
return i2c_write(adap, adr, msg, 2);
}
+static inline u32 safe_ddbreadl(struct ddb *dev, u32 adr)
+{
+ u32 val = ddbreadl(adr);
+
+ /* (ddb)readl returns (uint)-1 (all bits set) on failure, catch that */
+ if (val == ~0) {
+ dev_err(&dev->pdev->dev, "ddbreadl failure, adr=%08x\n", adr);
+ return 0;
+ }
+
+ return val;
+}
+
static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
{
struct ddb *dev = i2c->dev;
@@ -124,10 +139,10 @@ static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
ddbwritel((adr << 9) | cmd, i2c->regs + I2C_COMMAND);
stat = wait_event_timeout(i2c->wq, i2c->done == 1, HZ);
if (stat == 0) {
- printk(KERN_ERR "I2C timeout\n");
+ dev_err(&dev->pdev->dev, "I2C timeout\n");
{ /* MSI debugging*/
u32 istat = ddbreadl(INTERRUPT_STATUS);
- printk(KERN_ERR "IRS %08x\n", istat);
+ dev_err(&dev->pdev->dev, "IRS %08x\n", istat);
ddbwritel(istat, INTERRUPT_ACK);
}
return -EIO;
@@ -533,7 +548,7 @@ static u32 ddb_input_avail(struct ddb_input *input)
off = (stat & 0x7ff) << 7;
if (ctrl & 4) {
- printk(KERN_ERR "IA %d %d %08x\n", idx, off, ctrl);
+ dev_err(&dev->pdev->dev, "IA %d %d %08x\n", idx, off, ctrl);
ddbwritel(input->stat, DMA_BUFFER_ACK(input->nr));
return 0;
}
@@ -611,6 +626,7 @@ static int demod_attach_drxk(struct ddb_input *input)
struct i2c_adapter *i2c = &input->port->i2c->adap;
struct dvb_frontend *fe;
struct drxk_config config;
+ struct device *dev = &input->port->dev->pdev->dev;
memset(&config, 0, sizeof(config));
config.microcode_name = "drxk_a3.mc";
@@ -619,7 +635,7 @@ static int demod_attach_drxk(struct ddb_input *input)
fe = input->fe = dvb_attach(drxk_attach, &config, i2c);
if (!input->fe) {
- printk(KERN_ERR "No DRXK found!\n");
+ dev_err(dev, "No DRXK found!\n");
return -ENODEV;
}
fe->sec_priv = input;
@@ -632,12 +648,13 @@ static int tuner_attach_tda18271(struct ddb_input *input)
{
struct i2c_adapter *i2c = &input->port->i2c->adap;
struct dvb_frontend *fe;
+ struct device *dev = &input->port->dev->pdev->dev;
if (input->fe->ops.i2c_gate_ctrl)
input->fe->ops.i2c_gate_ctrl(input->fe, 1);
fe = dvb_attach(tda18271c2dd_attach, input->fe, i2c, 0x60);
if (!fe) {
- printk(KERN_ERR "No TDA18271 found!\n");
+ dev_err(dev, "No TDA18271 found!\n");
return -ENODEV;
}
if (input->fe->ops.i2c_gate_ctrl)
@@ -670,13 +687,14 @@ static struct stv0367_config ddb_stv0367_config[] = {
static int demod_attach_stv0367(struct ddb_input *input)
{
struct i2c_adapter *i2c = &input->port->i2c->adap;
+ struct device *dev = &input->port->dev->pdev->dev;
/* attach frontend */
input->fe = dvb_attach(stv0367ddb_attach,
&ddb_stv0367_config[(input->nr & 1)], i2c);
if (!input->fe) {
- printk(KERN_ERR "stv0367ddb_attach failed (not found?)\n");
+ dev_err(dev, "stv0367ddb_attach failed (not found?)\n");
return -ENODEV;
}
@@ -690,17 +708,19 @@ static int demod_attach_stv0367(struct ddb_input *input)
static int tuner_tda18212_ping(struct ddb_input *input, unsigned short adr)
{
struct i2c_adapter *adapter = &input->port->i2c->adap;
+ struct device *dev = &input->port->dev->pdev->dev;
+
u8 tda_id[2];
u8 subaddr = 0x00;
- printk(KERN_DEBUG "stv0367-tda18212 tuner ping\n");
+ dev_dbg(dev, "stv0367-tda18212 tuner ping\n");
if (input->fe->ops.i2c_gate_ctrl)
input->fe->ops.i2c_gate_ctrl(input->fe, 1);
if (i2c_read_regs(adapter, adr, subaddr, tda_id, sizeof(tda_id)) < 0)
- printk(KERN_DEBUG "tda18212 ping 1 fail\n");
+ dev_dbg(dev, "tda18212 ping 1 fail\n");
if (i2c_read_regs(adapter, adr, subaddr, tda_id, sizeof(tda_id)) < 0)
- printk(KERN_DEBUG "tda18212 ping 2 fail\n");
+ dev_warn(dev, "tda18212 ping failed, expect problems\n");
if (input->fe->ops.i2c_gate_ctrl)
input->fe->ops.i2c_gate_ctrl(input->fe, 0);
@@ -711,6 +731,7 @@ static int tuner_tda18212_ping(struct ddb_input *input, unsigned short adr)
static int demod_attach_cxd28xx(struct ddb_input *input, int par, int osc24)
{
struct i2c_adapter *i2c = &input->port->i2c->adap;
+ struct device *dev = &input->port->dev->pdev->dev;
struct cxd2841er_config cfg;
/* the cxd2841er driver expects 8bit/shifted I2C addresses */
@@ -728,7 +749,7 @@ static int demod_attach_cxd28xx(struct ddb_input *input, int par, int osc24)
input->fe = dvb_attach(cxd2841er_attach_t_c, &cfg, i2c);
if (!input->fe) {
- printk(KERN_ERR "No Sony CXD28xx found!\n");
+ dev_err(dev, "No Sony CXD28xx found!\n");
return -ENODEV;
}
@@ -742,6 +763,7 @@ static int demod_attach_cxd28xx(struct ddb_input *input, int par, int osc24)
static int tuner_attach_tda18212(struct ddb_input *input, u32 porttype)
{
struct i2c_adapter *adapter = &input->port->i2c->adap;
+ struct device *dev = &input->port->dev->pdev->dev;
struct i2c_client *client;
struct tda18212_config config = {
.fe = input->fe,
@@ -786,7 +808,7 @@ static int tuner_attach_tda18212(struct ddb_input *input, u32 porttype)
return 0;
err:
- printk(KERN_INFO "TDA18212 tuner not found. Device is not fully operational.\n");
+ dev_warn(dev, "TDA18212 tuner not found. Device is not fully operational.\n");
return -ENODEV;
}
@@ -847,19 +869,20 @@ static struct stv6110x_config stv6110b = {
static int demod_attach_stv0900(struct ddb_input *input, int type)
{
struct i2c_adapter *i2c = &input->port->i2c->adap;
+ struct device *dev = &input->port->dev->pdev->dev;
struct stv090x_config *feconf = type ? &stv0900_aa : &stv0900;
input->fe = dvb_attach(stv090x_attach, feconf, i2c,
(input->nr & 1) ? STV090x_DEMODULATOR_1
: STV090x_DEMODULATOR_0);
if (!input->fe) {
- printk(KERN_ERR "No STV0900 found!\n");
+ dev_err(dev, "No STV0900 found!\n");
return -ENODEV;
}
if (!dvb_attach(lnbh24_attach, input->fe, i2c, 0,
0, (input->nr & 1) ?
(0x09 - type) : (0x0b - type))) {
- printk(KERN_ERR "No LNBH24 found!\n");
+ dev_err(dev, "No LNBH24 found!\n");
return -ENODEV;
}
return 0;
@@ -868,6 +891,7 @@ static int demod_attach_stv0900(struct ddb_input *input, int type)
static int tuner_attach_stv6110(struct ddb_input *input, int type)
{
struct i2c_adapter *i2c = &input->port->i2c->adap;
+ struct device *dev = &input->port->dev->pdev->dev;
struct stv090x_config *feconf = type ? &stv0900_aa : &stv0900;
struct stv6110x_config *tunerconf = (input->nr & 1) ?
&stv6110b : &stv6110a;
@@ -875,10 +899,10 @@ static int tuner_attach_stv6110(struct ddb_input *input, int type)
ctl = dvb_attach(stv6110x_attach, input->fe, tunerconf, i2c);
if (!ctl) {
- printk(KERN_ERR "No STV6110X found!\n");
+ dev_err(dev, "No STV6110X found!\n");
return -ENODEV;
}
- printk(KERN_INFO "attach tuner input %d adr %02x\n",
+ dev_info(dev, "attach tuner input %d adr %02x\n",
input->nr, tunerconf->addr);
feconf->tuner_init = ctl->tuner_init;
@@ -1009,13 +1033,14 @@ static int dvb_input_attach(struct ddb_input *input)
struct ddb_port *port = input->port;
struct dvb_adapter *adap = &input->adap;
struct dvb_demux *dvbdemux = &input->demux;
+ struct device *dev = &input->port->dev->pdev->dev;
int sony_osc24 = 0, sony_tspar = 0;
ret = dvb_register_adapter(adap, "DDBridge", THIS_MODULE,
&input->port->dev->pdev->dev,
adapter_nr);
if (ret < 0) {
- printk(KERN_ERR "ddbridge: Could not register adapter.Check if you enabled enough adapters in dvb-core!\n");
+ dev_err(dev, "Could not register adapter. Check if you enabled enough adapters in dvb-core!\n");
return ret;
}
input->attached = 1;
@@ -1241,9 +1266,9 @@ static void input_tasklet(unsigned long data)
if (input->port->class == DDB_PORT_TUNER) {
if (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr)))
- printk(KERN_ERR "Overflow input %d\n", input->nr);
+ dev_err(&dev->pdev->dev, "Overflow input %d\n", input->nr);
while (input->cbuf != ((input->stat >> 11) & 0x1f)
- || (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr)))) {
+ || (4 & safe_ddbreadl(dev, DMA_BUFFER_CONTROL(input->nr)))) {
dvb_dmx_swfilter_packets(&input->demux,
input->vbuf[input->cbuf],
input->dma_buf_size / 188);
@@ -1280,6 +1305,7 @@ static struct cxd2099_cfg cxd_cfg = {
.adr = 0x40,
.polarity = 1,
.clock_mode = 1,
+ .max_i2c = 512,
};
static int ddb_ci_attach(struct ddb_port *port)
@@ -1310,6 +1336,7 @@ static int ddb_ci_attach(struct ddb_port *port)
static int ddb_port_attach(struct ddb_port *port)
{
+ struct device *dev = &port->dev->pdev->dev;
int ret = 0;
switch (port->class) {
@@ -1326,7 +1353,7 @@ static int ddb_port_attach(struct ddb_port *port)
break;
}
if (ret < 0)
- printk(KERN_ERR "port_attach on port %d failed\n", port->nr);
+ dev_err(dev, "port_attach on port %d failed\n", port->nr);
return ret;
}
@@ -1377,6 +1404,7 @@ static void ddb_ports_detach(struct ddb *dev)
static int init_xo2(struct ddb_port *port)
{
struct i2c_adapter *i2c = &port->i2c->adap;
+ struct device *dev = &port->dev->pdev->dev;
u8 val, data[2];
int res;
@@ -1385,7 +1413,7 @@ static int init_xo2(struct ddb_port *port)
return res;
if (data[0] != 0x01) {
- pr_info("Port %d: invalid XO2\n", port->nr);
+ dev_info(dev, "Port %d: invalid XO2\n", port->nr);
return -1;
}
@@ -1511,7 +1539,7 @@ static void ddb_port_probe(struct ddb_port *port)
port->class = DDB_PORT_CI;
ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING);
} else if (port_has_xo2(port, &xo2_type, &xo2_id)) {
- printk(KERN_INFO "Port %d (TAB %d): XO2 type: %d, id: %d\n",
+ dev_dbg(&dev->pdev->dev, "Port %d (TAB %d): XO2 type: %d, id: %d\n",
port->nr, port->nr+1, xo2_type, xo2_id);
ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING);
@@ -1556,10 +1584,10 @@ static void ddb_port_probe(struct ddb_port *port)
}
break;
case DDB_XO2_TYPE_CI:
- printk(KERN_INFO "DuoFlex CI modules not supported\n");
+ dev_info(&dev->pdev->dev, "DuoFlex CI modules not supported\n");
break;
default:
- printk(KERN_INFO "Unknown XO2 DuoFlex module\n");
+ dev_info(&dev->pdev->dev, "Unknown XO2 DuoFlex module\n");
break;
}
} else if (port_has_cxd28xx(port, &cxd_id)) {
@@ -1611,7 +1639,7 @@ static void ddb_port_probe(struct ddb_port *port)
ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING);
}
- printk(KERN_INFO "Port %d (TAB %d): %s\n",
+ dev_info(&dev->pdev->dev, "Port %d (TAB %d): %s\n",
port->nr, port->nr+1, modname);
}
@@ -1765,7 +1793,7 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
wbuf += 4;
wlen -= 4;
ddbwritel(data, SPI_DATA);
- while (ddbreadl(SPI_CONTROL) & 0x0004)
+ while (safe_ddbreadl(dev, SPI_CONTROL) & 0x0004)
;
}
@@ -1785,7 +1813,7 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
if (shift)
data <<= shift;
ddbwritel(data, SPI_DATA);
- while (ddbreadl(SPI_CONTROL) & 0x0004)
+ while (safe_ddbreadl(dev, SPI_CONTROL) & 0x0004)
;
if (!rlen) {
@@ -1797,7 +1825,7 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
while (rlen > 4) {
ddbwritel(0xffffffff, SPI_DATA);
- while (ddbreadl(SPI_CONTROL) & 0x0004)
+ while (safe_ddbreadl(dev, SPI_CONTROL) & 0x0004)
;
data = ddbreadl(SPI_DATA);
*(u32 *) rbuf = swab32(data);
@@ -1806,7 +1834,7 @@ static int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
}
ddbwritel(0x0003 | ((rlen << (8 + 3)) & 0x1F00), SPI_CONTROL);
ddbwritel(0xffffffff, SPI_DATA);
- while (ddbreadl(SPI_CONTROL) & 0x0004)
+ while (safe_ddbreadl(dev, SPI_CONTROL) & 0x0004)
;
data = ddbreadl(SPI_DATA);
@@ -1993,7 +2021,7 @@ static int ddb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
dev->pdev = pdev;
pci_set_drvdata(pdev, dev);
dev->info = (struct ddb_info *) id->driver_data;
- printk(KERN_INFO "DDBridge driver detected: %s\n", dev->info->name);
+ dev_info(&pdev->dev, "Detected %s\n", dev->info->name);
dev->regs = ioremap(pci_resource_start(dev->pdev, 0),
pci_resource_len(dev->pdev, 0));
@@ -2001,13 +2029,13 @@ static int ddb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
stat = -ENOMEM;
goto fail;
}
- printk(KERN_INFO "HW %08x FW %08x\n", ddbreadl(0), ddbreadl(4));
+ dev_info(&pdev->dev, "HW %08x FW %08x\n", ddbreadl(0), ddbreadl(4));
#ifdef CONFIG_PCI_MSI
if (pci_msi_enabled())
stat = pci_enable_msi(dev->pdev);
if (stat) {
- printk(KERN_INFO ": MSI not available.\n");
+ dev_info(&pdev->dev, "MSI not available.\n");
} else {
irq_flag = 0;
dev->msi = 1;
@@ -2040,7 +2068,7 @@ static int ddb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto fail1;
ddb_ports_init(dev);
if (ddb_buffers_alloc(dev) < 0) {
- printk(KERN_INFO ": Could not allocate buffer memory\n");
+ dev_err(&pdev->dev, "Could not allocate buffer memory\n");
goto fail2;
}
if (ddb_ports_attach(dev) < 0)
@@ -2050,19 +2078,19 @@ static int ddb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
fail3:
ddb_ports_detach(dev);
- printk(KERN_ERR "fail3\n");
+ dev_err(&pdev->dev, "fail3\n");
ddb_ports_release(dev);
fail2:
- printk(KERN_ERR "fail2\n");
+ dev_err(&pdev->dev, "fail2\n");
ddb_buffers_free(dev);
fail1:
- printk(KERN_ERR "fail1\n");
+ dev_err(&pdev->dev, "fail1\n");
if (dev->msi)
pci_disable_msi(dev->pdev);
if (stat == 0)
free_irq(dev->pdev->irq, dev);
fail:
- printk(KERN_ERR "fail\n");
+ dev_err(&pdev->dev, "fail\n");
ddb_unmap(dev);
pci_set_drvdata(pdev, NULL);
pci_disable_device(pdev);
@@ -2242,7 +2270,7 @@ static __init int module_init_ddbridge(void)
{
int ret;
- printk(KERN_INFO "Digital Devices PCIE bridge driver, Copyright (C) 2010-11 Digital Devices GmbH\n");
+ pr_info("Digital Devices PCIE bridge driver, Copyright (C) 2010-11 Digital Devices GmbH\n");
ret = ddb_class_create();
if (ret < 0)
diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c
index ce69e648b663..8c92cb7f7e72 100644
--- a/drivers/media/pci/ngene/ngene-core.c
+++ b/drivers/media/pci/ngene/ngene-core.c
@@ -336,9 +336,9 @@ int ngene_command(struct ngene *dev, struct ngene_command *com)
{
int result;
- down(&dev->cmd_mutex);
+ mutex_lock(&dev->cmd_mutex);
result = ngene_command_mutex(dev, com);
- up(&dev->cmd_mutex);
+ mutex_unlock(&dev->cmd_mutex);
return result;
}
@@ -560,7 +560,6 @@ static int ngene_command_stream_control(struct ngene *dev, u8 stream,
u16 BsSPI = ((stream & 1) ? 0x9800 : 0x9700);
u16 BsSDO = 0x9B00;
- down(&dev->stream_mutex);
memset(&com, 0, sizeof(com));
com.cmd.hdr.Opcode = CMD_CONTROL;
com.cmd.hdr.Length = sizeof(struct FW_STREAM_CONTROL) - 2;
@@ -586,17 +585,13 @@ static int ngene_command_stream_control(struct ngene *dev, u8 stream,
chan->State = KSSTATE_ACQUIRE;
chan->HWState = HWSTATE_STOP;
spin_unlock_irq(&chan->state_lock);
- if (ngene_command(dev, &com) < 0) {
- up(&dev->stream_mutex);
+ if (ngene_command(dev, &com) < 0)
return -1;
- }
/* clear_buffers(chan); */
flush_buffers(chan);
- up(&dev->stream_mutex);
return 0;
}
spin_unlock_irq(&chan->state_lock);
- up(&dev->stream_mutex);
return 0;
}
@@ -692,11 +687,9 @@ static int ngene_command_stream_control(struct ngene *dev, u8 stream,
chan->HWState = HWSTATE_STARTUP;
spin_unlock_irq(&chan->state_lock);
- if (ngene_command(dev, &com) < 0) {
- up(&dev->stream_mutex);
+ if (ngene_command(dev, &com) < 0)
return -1;
- }
- up(&dev->stream_mutex);
+
return 0;
}
@@ -750,8 +743,11 @@ void set_transfer(struct ngene_channel *chan, int state)
/* else printk(KERN_INFO DEVICE_NAME ": lock=%08x\n",
ngreadl(0x9310)); */
+ mutex_lock(&dev->stream_mutex);
ret = ngene_command_stream_control(dev, chan->number,
control, mode, flags);
+ mutex_unlock(&dev->stream_mutex);
+
if (!ret)
chan->running = state;
else
@@ -1283,7 +1279,7 @@ static int ngene_load_firm(struct ngene *dev)
static void ngene_stop(struct ngene *dev)
{
- down(&dev->cmd_mutex);
+ mutex_destroy(&dev->cmd_mutex);
i2c_del_adapter(&(dev->channel[0].i2c_adapter));
i2c_del_adapter(&(dev->channel[1].i2c_adapter));
ngwritel(0, NGENE_INT_ENABLE);
@@ -1346,10 +1342,10 @@ static int ngene_start(struct ngene *dev)
init_waitqueue_head(&dev->cmd_wq);
init_waitqueue_head(&dev->tx_wq);
init_waitqueue_head(&dev->rx_wq);
- sema_init(&dev->cmd_mutex, 1);
- sema_init(&dev->stream_mutex, 1);
+ mutex_init(&dev->cmd_mutex);
+ mutex_init(&dev->stream_mutex);
sema_init(&dev->pll_mutex, 1);
- sema_init(&dev->i2c_switch_mutex, 1);
+ mutex_init(&dev->i2c_switch_mutex);
spin_lock_init(&dev->cmd_lock);
for (i = 0; i < MAX_STREAM; i++)
spin_lock_init(&dev->channel[i].state_lock);
@@ -1606,10 +1602,10 @@ static void ngene_unlink(struct ngene *dev)
com.in_len = 3;
com.out_len = 1;
- down(&dev->cmd_mutex);
+ mutex_lock(&dev->cmd_mutex);
ngwritel(0, NGENE_INT_ENABLE);
ngene_command_mutex(dev, &com);
- up(&dev->cmd_mutex);
+ mutex_unlock(&dev->cmd_mutex);
}
void ngene_shutdown(struct pci_dev *pdev)
diff --git a/drivers/media/pci/ngene/ngene-i2c.c b/drivers/media/pci/ngene/ngene-i2c.c
index cf39fcf54adf..fbf36353c701 100644
--- a/drivers/media/pci/ngene/ngene-i2c.c
+++ b/drivers/media/pci/ngene/ngene-i2c.c
@@ -118,7 +118,7 @@ static int ngene_i2c_master_xfer(struct i2c_adapter *adapter,
(struct ngene_channel *)i2c_get_adapdata(adapter);
struct ngene *dev = chan->dev;
- down(&dev->i2c_switch_mutex);
+ mutex_lock(&dev->i2c_switch_mutex);
ngene_i2c_set_bus(dev, chan->number);
if (num == 2 && msg[1].flags & I2C_M_RD && !(msg[0].flags & I2C_M_RD))
@@ -136,11 +136,11 @@ static int ngene_i2c_master_xfer(struct i2c_adapter *adapter,
msg[0].buf, msg[0].len, 0))
goto done;
- up(&dev->i2c_switch_mutex);
+ mutex_unlock(&dev->i2c_switch_mutex);
return -EIO;
done:
- up(&dev->i2c_switch_mutex);
+ mutex_unlock(&dev->i2c_switch_mutex);
return num;
}
diff --git a/drivers/media/pci/ngene/ngene.h b/drivers/media/pci/ngene/ngene.h
index 10d8f74c4f0a..7c7cd217333d 100644
--- a/drivers/media/pci/ngene/ngene.h
+++ b/drivers/media/pci/ngene/ngene.h
@@ -762,10 +762,10 @@ struct ngene {
wait_queue_head_t cmd_wq;
int cmd_done;
- struct semaphore cmd_mutex;
- struct semaphore stream_mutex;
+ struct mutex cmd_mutex;
+ struct mutex stream_mutex;
struct semaphore pll_mutex;
- struct semaphore i2c_switch_mutex;
+ struct mutex i2c_switch_mutex;
int i2c_current_channel;
int i2c_current_bus;
spinlock_t cmd_lock;
diff --git a/drivers/media/pci/tw5864/tw5864-video.c b/drivers/media/pci/tw5864/tw5864-video.c
index 2a044be729da..e7bd2b8484e3 100644
--- a/drivers/media/pci/tw5864/tw5864-video.c
+++ b/drivers/media/pci/tw5864/tw5864-video.c
@@ -545,6 +545,7 @@ static int tw5864_fmt_vid_cap(struct file *file, void *priv,
switch (input->std) {
default:
WARN_ON_ONCE(1);
+ return -EINVAL;
case STD_NTSC:
f->fmt.pix.height = 480;
break;
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 1313cd533436..fb1fa0b82077 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -475,8 +475,8 @@ config VIDEO_QCOM_VENUS
tristate "Qualcomm Venus V4L2 encoder/decoder driver"
depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA
depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST
- select QCOM_MDT_LOADER if (ARM || ARM64)
- select QCOM_SCM if (ARM || ARM64)
+ select QCOM_MDT_LOADER if ARCH_QCOM
+ select QCOM_SCM if ARCH_QCOM
select VIDEOBUF2_DMA_SG
select V4L2_MEM2MEM_DEV
---help---
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c
index 25cbf9e5ac5a..bba1eb43b5d8 100644
--- a/drivers/media/platform/coda/coda-bit.c
+++ b/drivers/media/platform/coda/coda-bit.c
@@ -393,8 +393,8 @@ static int coda_alloc_framebuffers(struct coda_ctx *ctx,
int ret;
int i;
- if (ctx->codec && (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264 ||
- ctx->codec->dst_fourcc == V4L2_PIX_FMT_H264)) {
+ if (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264 ||
+ ctx->codec->dst_fourcc == V4L2_PIX_FMT_H264) {
width = round_up(q_data->width, 16);
height = round_up(q_data->height, 16);
} else {
@@ -2198,7 +2198,7 @@ static void coda_finish_decode(struct coda_ctx *ctx)
ctx->display_idx = display_idx;
}
-static void coda_error_decode(struct coda_ctx *ctx)
+static void coda_decode_timeout(struct coda_ctx *ctx)
{
struct vb2_v4l2_buffer *dst_buf;
@@ -2223,7 +2223,7 @@ const struct coda_context_ops coda_bit_decode_ops = {
.start_streaming = coda_start_decoding,
.prepare_run = coda_prepare_decode,
.finish_run = coda_finish_decode,
- .error_run = coda_error_decode,
+ .run_timeout = coda_decode_timeout,
.seq_end_work = coda_seq_end_work,
.release = coda_bit_release,
};
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
index f92cc7df58fb..829c7895a98a 100644
--- a/drivers/media/platform/coda/coda-common.c
+++ b/drivers/media/platform/coda/coda-common.c
@@ -1164,8 +1164,8 @@ static void coda_pic_run_work(struct work_struct *work)
coda_hw_reset(ctx);
- if (ctx->ops->error_run)
- ctx->ops->error_run(ctx);
+ if (ctx->ops->run_timeout)
+ ctx->ops->run_timeout(ctx);
} else if (!ctx->aborting) {
ctx->ops->finish_run(ctx);
}
diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h
index 40fe22f0d757..c5f504d8cf67 100644
--- a/drivers/media/platform/coda/coda.h
+++ b/drivers/media/platform/coda/coda.h
@@ -183,7 +183,7 @@ struct coda_context_ops {
int (*start_streaming)(struct coda_ctx *ctx);
int (*prepare_run)(struct coda_ctx *ctx);
void (*finish_run)(struct coda_ctx *ctx);
- void (*error_run)(struct coda_ctx *ctx);
+ void (*run_timeout)(struct coda_ctx *ctx);
void (*seq_end_work)(struct work_struct *work);
void (*release)(struct coda_ctx *ctx);
};
diff --git a/drivers/media/platform/davinci/ccdc_hw_device.h b/drivers/media/platform/davinci/ccdc_hw_device.h
index 8f6688a7a111..f1b521045d64 100644
--- a/drivers/media/platform/davinci/ccdc_hw_device.h
+++ b/drivers/media/platform/davinci/ccdc_hw_device.h
@@ -42,16 +42,6 @@ struct ccdc_hw_ops {
int (*set_hw_if_params) (struct vpfe_hw_if_param *param);
/* get interface parameters */
int (*get_hw_if_params) (struct vpfe_hw_if_param *param);
- /*
- * Pointer to function to set parameters. Used
- * for implementing VPFE_S_CCDC_PARAMS
- */
- int (*set_params) (void *params);
- /*
- * Pointer to function to get parameter. Used
- * for implementing VPFE_G_CCDC_PARAMS
- */
- int (*get_params) (void *params);
/* Pointer to function to configure ccdc */
int (*configure) (void);
diff --git a/drivers/media/platform/davinci/dm355_ccdc.c b/drivers/media/platform/davinci/dm355_ccdc.c
index 73db166dc338..6d492dc4c3a9 100644
--- a/drivers/media/platform/davinci/dm355_ccdc.c
+++ b/drivers/media/platform/davinci/dm355_ccdc.c
@@ -17,12 +17,7 @@
* This module is for configuring DM355 CCD controller of VPFE to capture
* Raw yuv or Bayer RGB data from a decoder. CCDC has several modules
* such as Defect Pixel Correction, Color Space Conversion etc to
- * pre-process the Bayer RGB data, before writing it to SDRAM. This
- * module also allows application to configure individual
- * module parameters through VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL.
- * To do so, application include dm355_ccdc.h and vpfe_capture.h header
- * files. The setparams() API is called by vpfe_capture driver
- * to configure module parameters
+ * pre-process the Bayer RGB data, before writing it to SDRAM.
*
* TODO: 1) Raw bayer parameter settings and bayer capture
* 2) Split module parameter structure to module specific ioctl structs
@@ -260,90 +255,6 @@ static void ccdc_setwin(struct v4l2_rect *image_win,
dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin...");
}
-static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
-{
- if (ccdcparam->datasft < CCDC_DATA_NO_SHIFT ||
- ccdcparam->datasft > CCDC_DATA_SHIFT_6BIT) {
- dev_dbg(ccdc_cfg.dev, "Invalid value of data shift\n");
- return -EINVAL;
- }
-
- if (ccdcparam->mfilt1 < CCDC_NO_MEDIAN_FILTER1 ||
- ccdcparam->mfilt1 > CCDC_MEDIAN_FILTER1) {
- dev_dbg(ccdc_cfg.dev, "Invalid value of median filter1\n");
- return -EINVAL;
- }
-
- if (ccdcparam->mfilt2 < CCDC_NO_MEDIAN_FILTER2 ||
- ccdcparam->mfilt2 > CCDC_MEDIAN_FILTER2) {
- dev_dbg(ccdc_cfg.dev, "Invalid value of median filter2\n");
- return -EINVAL;
- }
-
- if ((ccdcparam->med_filt_thres < 0) ||
- (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) {
- dev_dbg(ccdc_cfg.dev,
- "Invalid value of median filter threshold\n");
- return -EINVAL;
- }
-
- if (ccdcparam->data_sz < CCDC_DATA_16BITS ||
- ccdcparam->data_sz > CCDC_DATA_8BITS) {
- dev_dbg(ccdc_cfg.dev, "Invalid value of data size\n");
- return -EINVAL;
- }
-
- if (ccdcparam->alaw.enable) {
- if (ccdcparam->alaw.gamma_wd < CCDC_GAMMA_BITS_13_4 ||
- ccdcparam->alaw.gamma_wd > CCDC_GAMMA_BITS_09_0) {
- dev_dbg(ccdc_cfg.dev, "Invalid value of ALAW\n");
- return -EINVAL;
- }
- }
-
- if (ccdcparam->blk_clamp.b_clamp_enable) {
- if (ccdcparam->blk_clamp.sample_pixel < CCDC_SAMPLE_1PIXELS ||
- ccdcparam->blk_clamp.sample_pixel > CCDC_SAMPLE_16PIXELS) {
- dev_dbg(ccdc_cfg.dev,
- "Invalid value of sample pixel\n");
- return -EINVAL;
- }
- if (ccdcparam->blk_clamp.sample_ln < CCDC_SAMPLE_1LINES ||
- ccdcparam->blk_clamp.sample_ln > CCDC_SAMPLE_16LINES) {
- dev_dbg(ccdc_cfg.dev,
- "Invalid value of sample lines\n");
- return -EINVAL;
- }
- }
- return 0;
-}
-
-/* Parameter operations */
-static int ccdc_set_params(void __user *params)
-{
- struct ccdc_config_params_raw ccdc_raw_params;
- int x;
-
- /* only raw module parameters can be set through the IOCTL */
- if (ccdc_cfg.if_type != VPFE_RAW_BAYER)
- return -EINVAL;
-
- x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
- if (x) {
- dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copying ccdcparams, %d\n",
- x);
- return -EFAULT;
- }
-
- if (!validate_ccdc_param(&ccdc_raw_params)) {
- memcpy(&ccdc_cfg.bayer.config_params,
- &ccdc_raw_params,
- sizeof(ccdc_raw_params));
- return 0;
- }
- return -EINVAL;
-}
-
/* This function will configure CCDC for YCbCr video capture */
static void ccdc_config_ycbcr(void)
{
@@ -939,7 +850,6 @@ static struct ccdc_hw_device ccdc_hw_dev = {
.enable = ccdc_enable,
.enable_out_to_sdram = ccdc_enable_output_to_sdram,
.set_hw_if_params = ccdc_set_hw_if_params,
- .set_params = ccdc_set_params,
.configure = ccdc_configure,
.set_buftype = ccdc_set_buftype,
.get_buftype = ccdc_get_buftype,
diff --git a/drivers/media/platform/davinci/dm644x_ccdc.c b/drivers/media/platform/davinci/dm644x_ccdc.c
index 740fbc7a8c14..3b2d8a9317b8 100644
--- a/drivers/media/platform/davinci/dm644x_ccdc.c
+++ b/drivers/media/platform/davinci/dm644x_ccdc.c
@@ -17,13 +17,9 @@
* This module is for configuring CCD controller of DM6446 VPFE to capture
* Raw yuv or Bayer RGB data from a decoder. CCDC has several modules
* such as Defect Pixel Correction, Color Space Conversion etc to
- * pre-process the Raw Bayer RGB data, before writing it to SDRAM. This
- * module also allows application to configure individual
- * module parameters through VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL.
- * To do so, application includes dm644x_ccdc.h and vpfe_capture.h header
- * files. The setparams() API is called by vpfe_capture driver
- * to configure module parameters. This file is named DM644x so that other
- * variants such DM6443 may be supported using the same module.
+ * pre-process the Raw Bayer RGB data, before writing it to SDRAM.
+ * This file is named DM644x so that other variants such DM6443
+ * may be supported using the same module.
*
* TODO: Test Raw bayer parameter settings and bayer capture
* Split module parameter structure to module specific ioctl structs
@@ -216,96 +212,8 @@ static void ccdc_readregs(void)
dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VERT_LINES...\n", val);
}
-static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
-{
- if (ccdcparam->alaw.enable) {
- u8 max_gamma = ccdc_gamma_width_max_bit(ccdcparam->alaw.gamma_wd);
- u8 max_data = ccdc_data_size_max_bit(ccdcparam->data_sz);
-
- if ((ccdcparam->alaw.gamma_wd > CCDC_GAMMA_BITS_09_0) ||
- (ccdcparam->alaw.gamma_wd < CCDC_GAMMA_BITS_15_6) ||
- (max_gamma > max_data)) {
- dev_dbg(ccdc_cfg.dev, "\nInvalid data line select");
- return -1;
- }
- }
- return 0;
-}
-
-static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params)
-{
- struct ccdc_config_params_raw *config_params =
- &ccdc_cfg.bayer.config_params;
- unsigned int *fpc_virtaddr = NULL;
- unsigned int *fpc_physaddr = NULL;
-
- memcpy(config_params, raw_params, sizeof(*raw_params));
- /*
- * allocate memory for fault pixel table and copy the user
- * values to the table
- */
- if (!config_params->fault_pxl.enable)
- return 0;
-
- fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr;
- fpc_virtaddr = (unsigned int *)phys_to_virt(
- (unsigned long)fpc_physaddr);
- /*
- * Allocate memory for FPC table if current
- * FPC table buffer is not big enough to
- * accommodate FPC Number requested
- */
- if (raw_params->fault_pxl.fp_num != config_params->fault_pxl.fp_num) {
- if (fpc_physaddr != NULL) {
- free_pages((unsigned long)fpc_virtaddr,
- get_order
- (config_params->fault_pxl.fp_num *
- FP_NUM_BYTES));
- }
-
- /* Allocate memory for FPC table */
- fpc_virtaddr =
- (unsigned int *)__get_free_pages(GFP_KERNEL | GFP_DMA,
- get_order(raw_params->
- fault_pxl.fp_num *
- FP_NUM_BYTES));
-
- if (fpc_virtaddr == NULL) {
- dev_dbg(ccdc_cfg.dev,
- "\nUnable to allocate memory for FPC");
- return -EFAULT;
- }
- fpc_physaddr =
- (unsigned int *)virt_to_phys((void *)fpc_virtaddr);
- }
-
- /* Copy number of fault pixels and FPC table */
- config_params->fault_pxl.fp_num = raw_params->fault_pxl.fp_num;
- if (copy_from_user(fpc_virtaddr,
- (void __user *)raw_params->fault_pxl.fpc_table_addr,
- config_params->fault_pxl.fp_num * FP_NUM_BYTES)) {
- dev_dbg(ccdc_cfg.dev, "\n copy_from_user failed");
- return -EFAULT;
- }
- config_params->fault_pxl.fpc_table_addr = (unsigned long)fpc_physaddr;
- return 0;
-}
-
static int ccdc_close(struct device *dev)
{
- struct ccdc_config_params_raw *config_params =
- &ccdc_cfg.bayer.config_params;
- unsigned int *fpc_physaddr = NULL, *fpc_virtaddr = NULL;
-
- fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr;
-
- if (fpc_physaddr != NULL) {
- fpc_virtaddr = (unsigned int *)
- phys_to_virt((unsigned long)fpc_physaddr);
- free_pages((unsigned long)fpc_virtaddr,
- get_order(config_params->fault_pxl.fp_num *
- FP_NUM_BYTES));
- }
return 0;
}
@@ -339,29 +247,6 @@ static void ccdc_sbl_reset(void)
vpss_clear_wbl_overflow(VPSS_PCR_CCDC_WBL_O);
}
-/* Parameter operations */
-static int ccdc_set_params(void __user *params)
-{
- struct ccdc_config_params_raw ccdc_raw_params;
- int x;
-
- if (ccdc_cfg.if_type != VPFE_RAW_BAYER)
- return -EINVAL;
-
- x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
- if (x) {
- dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copyingccdc params, %d\n",
- x);
- return -EFAULT;
- }
-
- if (!validate_ccdc_param(&ccdc_raw_params)) {
- if (!ccdc_update_raw_params(&ccdc_raw_params))
- return 0;
- }
- return -EINVAL;
-}
-
/*
* ccdc_config_ycbcr()
* This function will configure CCDC for YCbCr video capture
@@ -489,32 +374,6 @@ static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
regw(val, CCDC_BLKCMP);
}
-static void ccdc_config_fpc(struct ccdc_fault_pixel *fpc)
-{
- u32 val;
-
- /* Initially disable FPC */
- val = CCDC_FPC_DISABLE;
- regw(val, CCDC_FPC);
-
- if (!fpc->enable)
- return;
-
- /* Configure Fault pixel if needed */
- regw(fpc->fpc_table_addr, CCDC_FPC_ADDR);
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%lx to FPC_ADDR...\n",
- (fpc->fpc_table_addr));
- /* Write the FPC params with FPC disable */
- val = fpc->fp_num & CCDC_FPC_FPC_NUM_MASK;
- regw(val, CCDC_FPC);
-
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC...\n", val);
- /* read the FPC register */
- val = regr(CCDC_FPC) | CCDC_FPC_ENABLE;
- regw(val, CCDC_FPC);
- dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC...\n", val);
-}
-
/*
* ccdc_config_raw()
* This function will configure CCDC for Raw capture mode
@@ -569,9 +428,6 @@ static void ccdc_config_raw(void)
/* Configure Black level compensation */
ccdc_config_black_compense(&config_params->blk_comp);
- /* Configure Fault Pixel Correction */
- ccdc_config_fpc(&config_params->fault_pxl);
-
/* If data size is 8 bit then pack the data */
if ((config_params->data_sz == CCDC_DATA_8BITS) ||
config_params->alaw.enable)
@@ -929,7 +785,6 @@ static struct ccdc_hw_device ccdc_hw_dev = {
.reset = ccdc_sbl_reset,
.enable = ccdc_enable,
.set_hw_if_params = ccdc_set_hw_if_params,
- .set_params = ccdc_set_params,
.configure = ccdc_configure,
.set_buftype = ccdc_set_buftype,
.get_buftype = ccdc_get_buftype,
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c
index e3fe3e0635aa..b1bf4a7e8eb7 100644
--- a/drivers/media/platform/davinci/vpfe_capture.c
+++ b/drivers/media/platform/davinci/vpfe_capture.c
@@ -281,45 +281,6 @@ void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev)
EXPORT_SYMBOL(vpfe_unregister_ccdc_device);
/*
- * vpfe_get_ccdc_image_format - Get image parameters based on CCDC settings
- */
-static int vpfe_get_ccdc_image_format(struct vpfe_device *vpfe_dev,
- struct v4l2_format *f)
-{
- struct v4l2_rect image_win;
- enum ccdc_buftype buf_type;
- enum ccdc_frmfmt frm_fmt;
-
- memset(f, 0, sizeof(*f));
- f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- ccdc_dev->hw_ops.get_image_window(&image_win);
- f->fmt.pix.width = image_win.width;
- f->fmt.pix.height = image_win.height;
- f->fmt.pix.bytesperline = ccdc_dev->hw_ops.get_line_length();
- f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
- f->fmt.pix.height;
- buf_type = ccdc_dev->hw_ops.get_buftype();
- f->fmt.pix.pixelformat = ccdc_dev->hw_ops.get_pixel_format();
- frm_fmt = ccdc_dev->hw_ops.get_frame_format();
- if (frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
- f->fmt.pix.field = V4L2_FIELD_NONE;
- else if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
- if (buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED)
- f->fmt.pix.field = V4L2_FIELD_INTERLACED;
- else if (buf_type == CCDC_BUFTYPE_FLD_SEPARATED)
- f->fmt.pix.field = V4L2_FIELD_SEQ_TB;
- else {
- v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf_type\n");
- return -EINVAL;
- }
- } else {
- v4l2_err(&vpfe_dev->v4l2_dev, "Invalid frm_fmt\n");
- return -EINVAL;
- }
- return 0;
-}
-
-/*
* vpfe_config_ccdc_image_format()
* For a pix format, configure ccdc to setup the capture
*/
@@ -1697,59 +1658,6 @@ unlock_out:
return ret;
}
-
-static long vpfe_param_handler(struct file *file, void *priv,
- bool valid_prio, unsigned int cmd, void *param)
-{
- struct vpfe_device *vpfe_dev = video_drvdata(file);
- int ret;
-
- v4l2_dbg(2, debug, &vpfe_dev->v4l2_dev, "vpfe_param_handler\n");
-
- if (vpfe_dev->started) {
- /* only allowed if streaming is not started */
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "device already started\n");
- return -EBUSY;
- }
-
- ret = mutex_lock_interruptible(&vpfe_dev->lock);
- if (ret)
- return ret;
-
- switch (cmd) {
- case VPFE_CMD_S_CCDC_RAW_PARAMS:
- v4l2_warn(&vpfe_dev->v4l2_dev,
- "VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n");
- if (ccdc_dev->hw_ops.set_params) {
- ret = ccdc_dev->hw_ops.set_params(param);
- if (ret) {
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "Error setting parameters in CCDC\n");
- goto unlock_out;
- }
- ret = vpfe_get_ccdc_image_format(vpfe_dev,
- &vpfe_dev->fmt);
- if (ret < 0) {
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "Invalid image format at CCDC\n");
- goto unlock_out;
- }
- } else {
- ret = -EINVAL;
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "VPFE_CMD_S_CCDC_RAW_PARAMS not supported\n");
- }
- break;
- default:
- ret = -ENOTTY;
- }
-unlock_out:
- mutex_unlock(&vpfe_dev->lock);
- return ret;
-}
-
-
/* vpfe capture ioctl operations */
static const struct v4l2_ioctl_ops vpfe_ioctl_ops = {
.vidioc_querycap = vpfe_querycap,
@@ -1772,7 +1680,6 @@ static const struct v4l2_ioctl_ops vpfe_ioctl_ops = {
.vidioc_cropcap = vpfe_cropcap,
.vidioc_g_selection = vpfe_g_selection,
.vidioc_s_selection = vpfe_s_selection,
- .vidioc_default = vpfe_param_handler,
};
static struct vpfe_device *vpfe_initialize(void)
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index d78580f9e431..4be6554c56c5 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -1719,7 +1719,6 @@ vpif_unregister:
*/
static int vpif_remove(struct platform_device *device)
{
- struct common_obj *common;
struct channel_obj *ch;
int i;
@@ -1730,7 +1729,6 @@ static int vpif_remove(struct platform_device *device)
for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
/* Get the pointer to the channel object */
ch = vpif_obj.dev[i];
- common = &ch->common[VPIF_VIDEO_INDEX];
/* Unregister video device */
video_unregister_device(&ch->video_dev);
kfree(vpif_obj.dev[i]);
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index b5ac6ce626b3..bf982bf86542 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -1339,7 +1339,6 @@ vpif_unregister:
*/
static int vpif_remove(struct platform_device *device)
{
- struct common_obj *common;
struct channel_obj *ch;
int i;
@@ -1350,7 +1349,6 @@ static int vpif_remove(struct platform_device *device)
for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
/* Get the pointer to the channel object */
ch = vpif_obj.dev[i];
- common = &ch->common[VPIF_VIDEO_INDEX];
/* Unregister video device */
video_unregister_device(&ch->video_dev);
kfree(vpif_obj.dev[i]);
diff --git a/drivers/media/platform/omap/omap_vout_vrfb.c b/drivers/media/platform/omap/omap_vout_vrfb.c
index 92c4e1826356..45a553d4f5b2 100644
--- a/drivers/media/platform/omap/omap_vout_vrfb.c
+++ b/drivers/media/platform/omap/omap_vout_vrfb.c
@@ -16,7 +16,6 @@
#include <media/videobuf-dma-contig.h>
#include <media/v4l2-device.h>
-#include <linux/omap-dma.h>
#include <video/omapvrfb.h>
#include "omap_voutdef.h"
@@ -63,7 +62,7 @@ static int omap_vout_allocate_vrfb_buffers(struct omap_vout_device *vout,
/*
* Wakes up the application once the DMA transfer to VRFB space is completed.
*/
-static void omap_vout_vrfb_dma_tx_callback(int lch, u16 ch_status, void *data)
+static void omap_vout_vrfb_dma_tx_callback(void *data)
{
struct vid_vrfb_dma *t = (struct vid_vrfb_dma *) data;
@@ -94,6 +93,7 @@ int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num,
int ret = 0, i, j;
struct omap_vout_device *vout;
struct video_device *vfd;
+ dma_cap_mask_t mask;
int image_width, image_height;
int vrfb_num_bufs = VRFB_NUM_BUFS;
struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
@@ -131,18 +131,27 @@ int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num,
/*
* Request and Initialize DMA, for DMA based VRFB transfer
*/
- vout->vrfb_dma_tx.dev_id = OMAP_DMA_NO_DEVICE;
- vout->vrfb_dma_tx.dma_ch = -1;
- vout->vrfb_dma_tx.req_status = DMA_CHAN_ALLOTED;
- ret = omap_request_dma(vout->vrfb_dma_tx.dev_id, "VRFB DMA TX",
- omap_vout_vrfb_dma_tx_callback,
- (void *) &vout->vrfb_dma_tx, &vout->vrfb_dma_tx.dma_ch);
- if (ret < 0) {
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_INTERLEAVE, mask);
+ vout->vrfb_dma_tx.chan = dma_request_chan_by_mask(&mask);
+ if (IS_ERR(vout->vrfb_dma_tx.chan)) {
vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED;
+ } else {
+ size_t xt_size = sizeof(struct dma_interleaved_template) +
+ sizeof(struct data_chunk);
+
+ vout->vrfb_dma_tx.xt = kzalloc(xt_size, GFP_KERNEL);
+ if (!vout->vrfb_dma_tx.xt) {
+ dma_release_channel(vout->vrfb_dma_tx.chan);
+ vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED;
+ }
+ }
+
+ if (vout->vrfb_dma_tx.req_status == DMA_CHAN_NOT_ALLOTED)
dev_info(&pdev->dev,
": failed to allocate DMA Channel for video%d\n",
vfd->minor);
- }
+
init_waitqueue_head(&vout->vrfb_dma_tx.wait);
/* statically allocated the VRFB buffer is done through
@@ -177,7 +186,9 @@ void omap_vout_release_vrfb(struct omap_vout_device *vout)
if (vout->vrfb_dma_tx.req_status == DMA_CHAN_ALLOTED) {
vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED;
- omap_free_dma(vout->vrfb_dma_tx.dma_ch);
+ kfree(vout->vrfb_dma_tx.xt);
+ dmaengine_terminate_sync(vout->vrfb_dma_tx.chan);
+ dma_release_channel(vout->vrfb_dma_tx.chan);
}
}
@@ -219,70 +230,84 @@ int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
}
int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
- struct videobuf_buffer *vb)
+ struct videobuf_buffer *vb)
{
- dma_addr_t dmabuf;
- struct vid_vrfb_dma *tx;
+ struct dma_async_tx_descriptor *tx;
+ enum dma_ctrl_flags flags;
+ struct dma_chan *chan = vout->vrfb_dma_tx.chan;
+ struct dma_device *dmadev = chan->device;
+ struct dma_interleaved_template *xt = vout->vrfb_dma_tx.xt;
+ dma_cookie_t cookie;
+ enum dma_status status;
enum dss_rotation rotation;
- u32 dest_frame_index = 0, src_element_index = 0;
- u32 dest_element_index = 0, src_frame_index = 0;
- u32 elem_count = 0, frame_count = 0, pixsize = 2;
+ size_t dst_icg;
+ u32 pixsize;
if (!is_rotation_enabled(vout))
return 0;
- dmabuf = vout->buf_phy_addr[vb->i];
/* If rotation is enabled, copy input buffer into VRFB
* memory space using DMA. We are copying input buffer
* into VRFB memory space of desired angle and DSS will
* read image VRFB memory for 0 degree angle
*/
+
pixsize = vout->bpp * vout->vrfb_bpp;
- /*
- * DMA transfer in double index mode
- */
+ dst_icg = ((MAX_PIXELS_PER_LINE * pixsize) -
+ (vout->pix.width * vout->bpp)) + 1;
+
+ xt->src_start = vout->buf_phy_addr[vb->i];
+ xt->dst_start = vout->vrfb_context[vb->i].paddr[0];
+
+ xt->numf = vout->pix.height;
+ xt->frame_size = 1;
+ xt->sgl[0].size = vout->pix.width * vout->bpp;
+ xt->sgl[0].icg = dst_icg;
+
+ xt->dir = DMA_MEM_TO_MEM;
+ xt->src_sgl = false;
+ xt->src_inc = true;
+ xt->dst_sgl = true;
+ xt->dst_inc = true;
+
+ tx = dmadev->device_prep_interleaved_dma(chan, xt, flags);
+ if (tx == NULL) {
+ pr_err("%s: DMA interleaved prep error\n", __func__);
+ return -EINVAL;
+ }
- /* Frame index */
- dest_frame_index = ((MAX_PIXELS_PER_LINE * pixsize) -
- (vout->pix.width * vout->bpp)) + 1;
-
- /* Source and destination parameters */
- src_element_index = 0;
- src_frame_index = 0;
- dest_element_index = 1;
- /* Number of elements per frame */
- elem_count = vout->pix.width * vout->bpp;
- frame_count = vout->pix.height;
- tx = &vout->vrfb_dma_tx;
- tx->tx_status = 0;
- omap_set_dma_transfer_params(tx->dma_ch, OMAP_DMA_DATA_TYPE_S32,
- (elem_count / 4), frame_count, OMAP_DMA_SYNC_ELEMENT,
- tx->dev_id, 0x0);
- /* src_port required only for OMAP1 */
- omap_set_dma_src_params(tx->dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
- dmabuf, src_element_index, src_frame_index);
- /*set dma source burst mode for VRFB */
- omap_set_dma_src_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16);
- rotation = calc_rotation(vout);
+ tx->callback = omap_vout_vrfb_dma_tx_callback;
+ tx->callback_param = &vout->vrfb_dma_tx;
+
+ cookie = dmaengine_submit(tx);
+ if (dma_submit_error(cookie)) {
+ pr_err("%s: dmaengine_submit failed (%d)\n", __func__, cookie);
+ return -EINVAL;
+ }
- /* dest_port required only for OMAP1 */
- omap_set_dma_dest_params(tx->dma_ch, 0, OMAP_DMA_AMODE_DOUBLE_IDX,
- vout->vrfb_context[vb->i].paddr[0], dest_element_index,
- dest_frame_index);
- /*set dma dest burst mode for VRFB */
- omap_set_dma_dest_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16);
- omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE, 0x20, 0);
+ vout->vrfb_dma_tx.tx_status = 0;
+ dma_async_issue_pending(chan);
- omap_start_dma(tx->dma_ch);
- wait_event_interruptible_timeout(tx->wait, tx->tx_status == 1,
+ wait_event_interruptible_timeout(vout->vrfb_dma_tx.wait,
+ vout->vrfb_dma_tx.tx_status == 1,
VRFB_TX_TIMEOUT);
- if (tx->tx_status == 0) {
- omap_stop_dma(tx->dma_ch);
+ status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
+
+ if (vout->vrfb_dma_tx.tx_status == 0) {
+ pr_err("%s: Timeout while waiting for DMA\n", __func__);
+ dmaengine_terminate_sync(chan);
+ return -EINVAL;
+ } else if (status != DMA_COMPLETE) {
+ pr_err("%s: DMA completion %s status\n", __func__,
+ status == DMA_ERROR ? "error" : "busy");
+ dmaengine_terminate_sync(chan);
return -EINVAL;
}
+
/* Store buffers physical address into an array. Addresses
* from this array will be used to configure DSS */
+ rotation = calc_rotation(vout);
vout->queued_buf_addr[vb->i] = (u8 *)
vout->vrfb_context[vb->i].paddr[rotation];
return 0;
diff --git a/drivers/media/platform/omap/omap_voutdef.h b/drivers/media/platform/omap/omap_voutdef.h
index 80c79fabdf95..56b630b1c8b4 100644
--- a/drivers/media/platform/omap/omap_voutdef.h
+++ b/drivers/media/platform/omap/omap_voutdef.h
@@ -14,6 +14,7 @@
#include <media/v4l2-ctrls.h>
#include <video/omapfb_dss.h>
#include <video/omapvrfb.h>
+#include <linux/dmaengine.h>
#define YUYV_BPP 2
#define RGB565_BPP 2
@@ -81,8 +82,9 @@ enum vout_rotaion_type {
* for VRFB hidden buffer
*/
struct vid_vrfb_dma {
- int dev_id;
- int dma_ch;
+ struct dma_chan *chan;
+ struct dma_interleaved_template *xt;
+
int req_status;
int tx_status;
wait_queue_head_t wait;
diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index 776d2bae6979..41eef376eb2d 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -76,7 +76,7 @@ static void venus_sys_error_handler(struct work_struct *work)
hfi_core_deinit(core, true);
hfi_destroy(core);
mutex_lock(&core->lock);
- venus_shutdown(&core->dev_fw);
+ venus_shutdown(core->dev);
pm_runtime_put_sync(core->dev);
@@ -84,7 +84,7 @@ static void venus_sys_error_handler(struct work_struct *work)
pm_runtime_get_sync(core->dev);
- ret |= venus_boot(core->dev, &core->dev_fw, core->res->fwname);
+ ret |= venus_boot(core->dev, core->res->fwname);
ret |= hfi_core_resume(core, true);
@@ -137,7 +137,7 @@ static int venus_clks_enable(struct venus_core *core)
return 0;
err:
- while (--i)
+ while (i--)
clk_disable_unprepare(core->clks[i]);
return ret;
@@ -207,7 +207,7 @@ static int venus_probe(struct platform_device *pdev)
if (ret < 0)
goto err_runtime_disable;
- ret = venus_boot(dev, &core->dev_fw, core->res->fwname);
+ ret = venus_boot(dev, core->res->fwname);
if (ret)
goto err_runtime_disable;
@@ -238,7 +238,7 @@ err_dev_unregister:
err_core_deinit:
hfi_core_deinit(core, false);
err_venus_shutdown:
- venus_shutdown(&core->dev_fw);
+ venus_shutdown(dev);
err_runtime_disable:
pm_runtime_set_suspended(dev);
pm_runtime_disable(dev);
@@ -259,7 +259,7 @@ static int venus_remove(struct platform_device *pdev)
WARN_ON(ret);
hfi_destroy(core);
- venus_shutdown(&core->dev_fw);
+ venus_shutdown(dev);
of_platform_depopulate(dev);
pm_runtime_put_sync(dev);
@@ -270,8 +270,7 @@ static int venus_remove(struct platform_device *pdev)
return ret;
}
-#ifdef CONFIG_PM
-static int venus_runtime_suspend(struct device *dev)
+static __maybe_unused int venus_runtime_suspend(struct device *dev)
{
struct venus_core *core = dev_get_drvdata(dev);
int ret;
@@ -283,7 +282,7 @@ static int venus_runtime_suspend(struct device *dev)
return ret;
}
-static int venus_runtime_resume(struct device *dev)
+static __maybe_unused int venus_runtime_resume(struct device *dev)
{
struct venus_core *core = dev_get_drvdata(dev);
int ret;
@@ -302,7 +301,6 @@ err_clks_disable:
venus_clks_disable(core);
return ret;
}
-#endif
static const struct dev_pm_ops venus_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h
index e542700eee32..cba092bcb76d 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -101,7 +101,6 @@ struct venus_core {
struct device *dev;
struct device *dev_dec;
struct device *dev_enc;
- struct device dev_fw;
struct mutex lock;
struct list_head instances;
atomic_t insts_count;
diff --git a/drivers/media/platform/qcom/venus/firmware.c b/drivers/media/platform/qcom/venus/firmware.c
index 1b1a4f355918..521d4b36c090 100644
--- a/drivers/media/platform/qcom/venus/firmware.c
+++ b/drivers/media/platform/qcom/venus/firmware.c
@@ -12,97 +12,87 @@
*
*/
-#include <linux/dma-mapping.h>
+#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/kernel.h>
+#include <linux/io.h>
#include <linux/of.h>
-#include <linux/of_reserved_mem.h>
-#include <linux/slab.h>
+#include <linux/of_address.h>
#include <linux/qcom_scm.h>
+#include <linux/sizes.h>
#include <linux/soc/qcom/mdt_loader.h>
#include "firmware.h"
#define VENUS_PAS_ID 9
-#define VENUS_FW_MEM_SIZE SZ_8M
+#define VENUS_FW_MEM_SIZE (6 * SZ_1M)
-static void device_release_dummy(struct device *dev)
-{
- of_reserved_mem_device_release(dev);
-}
-
-int venus_boot(struct device *parent, struct device *fw_dev, const char *fwname)
+int venus_boot(struct device *dev, const char *fwname)
{
const struct firmware *mdt;
+ struct device_node *node;
phys_addr_t mem_phys;
+ struct resource r;
ssize_t fw_size;
size_t mem_size;
void *mem_va;
int ret;
- if (!qcom_scm_is_available())
+ if (!IS_ENABLED(CONFIG_QCOM_MDT_LOADER) || !qcom_scm_is_available())
return -EPROBE_DEFER;
- fw_dev->parent = parent;
- fw_dev->release = device_release_dummy;
+ node = of_parse_phandle(dev->of_node, "memory-region", 0);
+ if (!node) {
+ dev_err(dev, "no memory-region specified\n");
+ return -EINVAL;
+ }
- ret = dev_set_name(fw_dev, "%s:%s", dev_name(parent), "firmware");
+ ret = of_address_to_resource(node, 0, &r);
if (ret)
return ret;
- ret = device_register(fw_dev);
- if (ret < 0)
- return ret;
+ mem_phys = r.start;
+ mem_size = resource_size(&r);
- ret = of_reserved_mem_device_init_by_idx(fw_dev, parent->of_node, 0);
- if (ret)
- goto err_unreg_device;
+ if (mem_size < VENUS_FW_MEM_SIZE)
+ return -EINVAL;
- mem_size = VENUS_FW_MEM_SIZE;
-
- mem_va = dmam_alloc_coherent(fw_dev, mem_size, &mem_phys, GFP_KERNEL);
+ mem_va = memremap(r.start, mem_size, MEMREMAP_WC);
if (!mem_va) {
- ret = -ENOMEM;
- goto err_unreg_device;
+ dev_err(dev, "unable to map memory region: %pa+%zx\n",
+ &r.start, mem_size);
+ return -ENOMEM;
}
- ret = request_firmware(&mdt, fwname, fw_dev);
+ ret = request_firmware(&mdt, fwname, dev);
if (ret < 0)
- goto err_unreg_device;
+ goto err_unmap;
fw_size = qcom_mdt_get_size(mdt);
if (fw_size < 0) {
ret = fw_size;
release_firmware(mdt);
- goto err_unreg_device;
+ goto err_unmap;
}
- ret = qcom_mdt_load(fw_dev, mdt, fwname, VENUS_PAS_ID, mem_va, mem_phys,
+ ret = qcom_mdt_load(dev, mdt, fwname, VENUS_PAS_ID, mem_va, mem_phys,
mem_size);
release_firmware(mdt);
if (ret)
- goto err_unreg_device;
+ goto err_unmap;
ret = qcom_scm_pas_auth_and_reset(VENUS_PAS_ID);
if (ret)
- goto err_unreg_device;
-
- return 0;
+ goto err_unmap;
-err_unreg_device:
- device_unregister(fw_dev);
+err_unmap:
+ memunmap(mem_va);
return ret;
}
-int venus_shutdown(struct device *fw_dev)
+int venus_shutdown(struct device *dev)
{
- int ret;
-
- ret = qcom_scm_pas_shutdown(VENUS_PAS_ID);
- device_unregister(fw_dev);
- memset(fw_dev, 0, sizeof(*fw_dev));
-
- return ret;
+ return qcom_scm_pas_shutdown(VENUS_PAS_ID);
}
diff --git a/drivers/media/platform/qcom/venus/firmware.h b/drivers/media/platform/qcom/venus/firmware.h
index f81a98979798..428efb56d339 100644
--- a/drivers/media/platform/qcom/venus/firmware.h
+++ b/drivers/media/platform/qcom/venus/firmware.h
@@ -16,8 +16,7 @@
struct device;
-int venus_boot(struct device *parent, struct device *fw_dev,
- const char *fwname);
-int venus_shutdown(struct device *fw_dev);
+int venus_boot(struct device *dev, const char *fwname);
+int venus_shutdown(struct device *dev);
#endif
diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c b/drivers/media/platform/qcom/venus/hfi_msgs.c
index f8841713e417..a681ae5381d6 100644
--- a/drivers/media/platform/qcom/venus/hfi_msgs.c
+++ b/drivers/media/platform/qcom/venus/hfi_msgs.c
@@ -239,11 +239,12 @@ static void hfi_sys_init_done(struct venus_core *core, struct venus_inst *inst,
break;
}
- if (!error) {
- rem_bytes -= read_bytes;
- data += read_bytes;
- num_properties--;
- }
+ if (error)
+ break;
+
+ rem_bytes -= read_bytes;
+ data += read_bytes;
+ num_properties--;
}
err_no_prop:
diff --git a/drivers/media/platform/sti/bdisp/bdisp-debug.c b/drivers/media/platform/sti/bdisp/bdisp-debug.c
index 7af66860d624..2cc289e4dea1 100644
--- a/drivers/media/platform/sti/bdisp/bdisp-debug.c
+++ b/drivers/media/platform/sti/bdisp/bdisp-debug.c
@@ -104,7 +104,7 @@ static void bdisp_dbg_dump_ins(struct seq_file *s, u32 val)
if (val & BLT_INS_IRQ)
seq_puts(s, "IRQ - ");
- seq_puts(s, "\n");
+ seq_putc(s, '\n');
}
static void bdisp_dbg_dump_tty(struct seq_file *s, u32 val)
@@ -153,7 +153,7 @@ static void bdisp_dbg_dump_tty(struct seq_file *s, u32 val)
if (val & BLT_TTY_BIG_END)
seq_puts(s, "BigEndian - ");
- seq_puts(s, "\n");
+ seq_putc(s, '\n');
}
static void bdisp_dbg_dump_xy(struct seq_file *s, u32 val, char *name)
@@ -230,7 +230,7 @@ static void bdisp_dbg_dump_sty(struct seq_file *s,
seq_puts(s, "BigEndian - ");
done:
- seq_puts(s, "\n");
+ seq_putc(s, '\n');
}
static void bdisp_dbg_dump_fctl(struct seq_file *s, u32 val)
@@ -247,7 +247,7 @@ static void bdisp_dbg_dump_fctl(struct seq_file *s, u32 val)
else if ((val & BLT_FCTL_HV_SCALE) == BLT_FCTL_HV_SAMPLE)
seq_puts(s, "Sample Chroma");
- seq_puts(s, "\n");
+ seq_putc(s, '\n');
}
static void bdisp_dbg_dump_rsf(struct seq_file *s, u32 val, char *name)
@@ -266,7 +266,7 @@ static void bdisp_dbg_dump_rsf(struct seq_file *s, u32 val, char *name)
seq_printf(s, "V: %d(6.10) / scale~%dx0.1", inc, 1024 * 10 / inc);
done:
- seq_puts(s, "\n");
+ seq_putc(s, '\n');
}
static void bdisp_dbg_dump_rzi(struct seq_file *s, u32 val, char *name)
@@ -281,7 +281,7 @@ static void bdisp_dbg_dump_rzi(struct seq_file *s, u32 val, char *name)
seq_printf(s, "V: init=%d repeat=%d", val & 0x3FF, (val >> 12) & 7);
done:
- seq_puts(s, "\n");
+ seq_putc(s, '\n');
}
static void bdisp_dbg_dump_ivmx(struct seq_file *s,
@@ -293,7 +293,7 @@ static void bdisp_dbg_dump_ivmx(struct seq_file *s,
seq_printf(s, "IVMX3\t0x%08X\t", c3);
if (!c0 && !c1 && !c2 && !c3) {
- seq_puts(s, "\n");
+ seq_putc(s, '\n');
return;
}
diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c
index 14cb32e21130..88a1e5670c72 100644
--- a/drivers/media/platform/vimc/vimc-capture.c
+++ b/drivers/media/platform/vimc/vimc-capture.c
@@ -517,21 +517,22 @@ static int vimc_cap_remove(struct platform_device *pdev)
return 0;
}
+static const struct platform_device_id vimc_cap_driver_ids[] = {
+ {
+ .name = VIMC_CAP_DRV_NAME,
+ },
+ { }
+};
+
static struct platform_driver vimc_cap_pdrv = {
.probe = vimc_cap_probe,
.remove = vimc_cap_remove,
+ .id_table = vimc_cap_driver_ids,
.driver = {
.name = VIMC_CAP_DRV_NAME,
},
};
-static const struct platform_device_id vimc_cap_driver_ids[] = {
- {
- .name = VIMC_CAP_DRV_NAME,
- },
- { }
-};
-
module_platform_driver(vimc_cap_pdrv);
MODULE_DEVICE_TABLE(platform, vimc_cap_driver_ids);
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c
index 35b15bd4d61d..033a131f67af 100644
--- a/drivers/media/platform/vimc/vimc-debayer.c
+++ b/drivers/media/platform/vimc/vimc-debayer.c
@@ -577,21 +577,22 @@ static int vimc_deb_remove(struct platform_device *pdev)
return 0;
}
+static const struct platform_device_id vimc_deb_driver_ids[] = {
+ {
+ .name = VIMC_DEB_DRV_NAME,
+ },
+ { }
+};
+
static struct platform_driver vimc_deb_pdrv = {
.probe = vimc_deb_probe,
.remove = vimc_deb_remove,
+ .id_table = vimc_deb_driver_ids,
.driver = {
.name = VIMC_DEB_DRV_NAME,
},
};
-static const struct platform_device_id vimc_deb_driver_ids[] = {
- {
- .name = VIMC_DEB_DRV_NAME,
- },
- { }
-};
-
module_platform_driver(vimc_deb_pdrv);
MODULE_DEVICE_TABLE(platform, vimc_deb_driver_ids);
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c
index fe77505d2679..0a3e086e12f3 100644
--- a/drivers/media/platform/vimc/vimc-scaler.c
+++ b/drivers/media/platform/vimc/vimc-scaler.c
@@ -431,21 +431,22 @@ static int vimc_sca_remove(struct platform_device *pdev)
return 0;
}
+static const struct platform_device_id vimc_sca_driver_ids[] = {
+ {
+ .name = VIMC_SCA_DRV_NAME,
+ },
+ { }
+};
+
static struct platform_driver vimc_sca_pdrv = {
.probe = vimc_sca_probe,
.remove = vimc_sca_remove,
+ .id_table = vimc_sca_driver_ids,
.driver = {
.name = VIMC_SCA_DRV_NAME,
},
};
-static const struct platform_device_id vimc_sca_driver_ids[] = {
- {
- .name = VIMC_SCA_DRV_NAME,
- },
- { }
-};
-
module_platform_driver(vimc_sca_pdrv);
MODULE_DEVICE_TABLE(platform, vimc_sca_driver_ids);
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
index ebdbbe8c05ed..615c2b18dcfc 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -365,21 +365,22 @@ static int vimc_sen_remove(struct platform_device *pdev)
return 0;
}
+static const struct platform_device_id vimc_sen_driver_ids[] = {
+ {
+ .name = VIMC_SEN_DRV_NAME,
+ },
+ { }
+};
+
static struct platform_driver vimc_sen_pdrv = {
.probe = vimc_sen_probe,
.remove = vimc_sen_remove,
+ .id_table = vimc_sen_driver_ids,
.driver = {
.name = VIMC_SEN_DRV_NAME,
},
};
-static const struct platform_device_id vimc_sen_driver_ids[] = {
- {
- .name = VIMC_SEN_DRV_NAME,
- },
- { }
-};
-
module_platform_driver(vimc_sen_pdrv);
MODULE_DEVICE_TABLE(platform, vimc_sen_driver_ids);
diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 847963b6e9eb..78ef838416b3 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -41,11 +41,11 @@ struct vsp1_rwpf;
struct vsp1_sru;
struct vsp1_uds;
+#define VSP1_MAX_LIF 2
#define VSP1_MAX_RPF 5
#define VSP1_MAX_UDS 3
#define VSP1_MAX_WPF 4
-#define VSP1_HAS_LIF (1 << 0)
#define VSP1_HAS_LUT (1 << 1)
#define VSP1_HAS_SRU (1 << 2)
#define VSP1_HAS_BRU (1 << 3)
@@ -54,12 +54,14 @@ struct vsp1_uds;
#define VSP1_HAS_WPF_HFLIP (1 << 6)
#define VSP1_HAS_HGO (1 << 7)
#define VSP1_HAS_HGT (1 << 8)
+#define VSP1_HAS_BRS (1 << 9)
struct vsp1_device_info {
u32 version;
const char *model;
unsigned int gen;
unsigned int features;
+ unsigned int lif_count;
unsigned int rpf_count;
unsigned int uds_count;
unsigned int wpf_count;
@@ -76,13 +78,14 @@ struct vsp1_device {
struct rcar_fcp_device *fcp;
struct device *bus_master;
+ struct vsp1_bru *brs;
struct vsp1_bru *bru;
struct vsp1_clu *clu;
struct vsp1_hgo *hgo;
struct vsp1_hgt *hgt;
struct vsp1_hsit *hsi;
struct vsp1_hsit *hst;
- struct vsp1_lif *lif;
+ struct vsp1_lif *lif[VSP1_MAX_LIF];
struct vsp1_lut *lut;
struct vsp1_rwpf *rpf[VSP1_MAX_RPF];
struct vsp1_sru *sru;
diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
index 85362c5ef57a..e8fd2ae3b3eb 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.c
+++ b/drivers/media/platform/vsp1/vsp1_bru.c
@@ -33,7 +33,7 @@
static inline void vsp1_bru_write(struct vsp1_bru *bru, struct vsp1_dl_list *dl,
u32 reg, u32 data)
{
- vsp1_dl_list_write(dl, reg, data);
+ vsp1_dl_list_write(dl, bru->base + reg, data);
}
/* -----------------------------------------------------------------------------
@@ -332,11 +332,14 @@ static void bru_configure(struct vsp1_entity *entity,
/*
* Route BRU input 1 as SRC input to the ROP unit and configure the ROP
* unit with a NOP operation to make BRU input 1 available as the
- * Blend/ROP unit B SRC input.
+ * Blend/ROP unit B SRC input. Only needed for BRU, the BRS has no ROP
+ * unit.
*/
- vsp1_bru_write(bru, dl, VI6_BRU_ROP, VI6_BRU_ROP_DSTSEL_BRUIN(1) |
- VI6_BRU_ROP_CROP(VI6_ROP_NOP) |
- VI6_BRU_ROP_AROP(VI6_ROP_NOP));
+ if (entity->type == VSP1_ENTITY_BRU)
+ vsp1_bru_write(bru, dl, VI6_BRU_ROP,
+ VI6_BRU_ROP_DSTSEL_BRUIN(1) |
+ VI6_BRU_ROP_CROP(VI6_ROP_NOP) |
+ VI6_BRU_ROP_AROP(VI6_ROP_NOP));
for (i = 0; i < bru->entity.source_pad; ++i) {
bool premultiplied = false;
@@ -366,12 +369,13 @@ static void bru_configure(struct vsp1_entity *entity,
ctrl |= VI6_BRU_CTRL_DSTSEL_VRPF;
/*
- * Route BRU inputs 0 to 3 as SRC inputs to Blend/ROP units A to
- * D in that order. The Blend/ROP unit B SRC is hardwired to the
- * ROP unit output, the corresponding register bits must be set
- * to 0.
+ * Route inputs 0 to 3 as SRC inputs to Blend/ROP units A to D
+ * in that order. In the BRU the Blend/ROP unit B SRC is
+ * hardwired to the ROP unit output, the corresponding register
+ * bits must be set to 0. The BRS has no ROP unit and doesn't
+ * need any special processing.
*/
- if (i != 1)
+ if (!(entity->type == VSP1_ENTITY_BRU && i == 1))
ctrl |= VI6_BRU_CTRL_SRCSEL_BRUIN(i);
vsp1_bru_write(bru, dl, VI6_BRU_CTRL(i), ctrl);
@@ -407,20 +411,31 @@ static const struct vsp1_entity_operations bru_entity_ops = {
* Initialization and Cleanup
*/
-struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1)
+struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1,
+ enum vsp1_entity_type type)
{
struct vsp1_bru *bru;
+ unsigned int num_pads;
+ const char *name;
int ret;
bru = devm_kzalloc(vsp1->dev, sizeof(*bru), GFP_KERNEL);
if (bru == NULL)
return ERR_PTR(-ENOMEM);
+ bru->base = type == VSP1_ENTITY_BRU ? VI6_BRU_BASE : VI6_BRS_BASE;
bru->entity.ops = &bru_entity_ops;
- bru->entity.type = VSP1_ENTITY_BRU;
+ bru->entity.type = type;
+
+ if (type == VSP1_ENTITY_BRU) {
+ num_pads = vsp1->info->num_bru_inputs + 1;
+ name = "bru";
+ } else {
+ num_pads = 3;
+ name = "brs";
+ }
- ret = vsp1_entity_init(vsp1, &bru->entity, "bru",
- vsp1->info->num_bru_inputs + 1, &bru_ops,
+ ret = vsp1_entity_init(vsp1, &bru->entity, name, num_pads, &bru_ops,
MEDIA_ENT_F_PROC_VIDEO_COMPOSER);
if (ret < 0)
return ERR_PTR(ret);
@@ -435,7 +450,7 @@ struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1)
bru->entity.subdev.ctrl_handler = &bru->ctrls;
if (bru->ctrls.error) {
- dev_err(vsp1->dev, "bru: failed to initialize controls\n");
+ dev_err(vsp1->dev, "%s: failed to initialize controls\n", name);
ret = bru->ctrls.error;
vsp1_entity_destroy(&bru->entity);
return ERR_PTR(ret);
diff --git a/drivers/media/platform/vsp1/vsp1_bru.h b/drivers/media/platform/vsp1/vsp1_bru.h
index 828a3fcadea8..c98ed96d8de6 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.h
+++ b/drivers/media/platform/vsp1/vsp1_bru.h
@@ -26,6 +26,7 @@ struct vsp1_rwpf;
struct vsp1_bru {
struct vsp1_entity entity;
+ unsigned int base;
struct v4l2_ctrl_handler ctrls;
@@ -41,6 +42,7 @@ static inline struct vsp1_bru *to_bru(struct v4l2_subdev *subdev)
return container_of(subdev, struct vsp1_bru, entity.subdev);
}
-struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1);
+struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1,
+ enum vsp1_entity_type type);
#endif /* __VSP1_BRU_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index aaf17b13fd78..8b5cbb6b7a70 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -95,6 +95,7 @@ enum vsp1_dl_mode {
* struct vsp1_dl_manager - Display List manager
* @index: index of the related WPF
* @mode: display list operation mode (header or headerless)
+ * @singleshot: execute the display list in single-shot mode
* @vsp1: the VSP1 device
* @lock: protects the free, active, queued, pending and gc_fragments lists
* @free: array of all free display lists
@@ -107,6 +108,7 @@ enum vsp1_dl_mode {
struct vsp1_dl_manager {
unsigned int index;
enum vsp1_dl_mode mode;
+ bool singleshot;
struct vsp1_device *vsp1;
spinlock_t lock;
@@ -437,6 +439,7 @@ int vsp1_dl_list_add_chain(struct vsp1_dl_list *head,
static void vsp1_dl_list_fill_header(struct vsp1_dl_list *dl, bool is_last)
{
+ struct vsp1_dl_manager *dlm = dl->dlm;
struct vsp1_dl_header_list *hdr = dl->header->lists;
struct vsp1_dl_body *dlb;
unsigned int num_lists = 0;
@@ -461,106 +464,152 @@ static void vsp1_dl_list_fill_header(struct vsp1_dl_list *dl, bool is_last)
dl->header->num_lists = num_lists;
- /*
- * If this display list's chain is not empty, we are on a list, where
- * the next item in the list is the display list entity which should be
- * automatically queued by the hardware.
- */
if (!list_empty(&dl->chain) && !is_last) {
+ /*
+ * If this display list's chain is not empty, we are on a list,
+ * and the next item is the display list that we must queue for
+ * automatic processing by the hardware.
+ */
struct vsp1_dl_list *next = list_next_entry(dl, chain);
dl->header->next_header = next->dma;
dl->header->flags = VSP1_DLH_AUTO_START;
+ } else if (!dlm->singleshot) {
+ /*
+ * if the display list manager works in continuous mode, the VSP
+ * should loop over the display list continuously until
+ * instructed to do otherwise.
+ */
+ dl->header->next_header = dl->dma;
+ dl->header->flags = VSP1_DLH_INT_ENABLE | VSP1_DLH_AUTO_START;
} else {
+ /*
+ * Otherwise, in mem-to-mem mode, we work in single-shot mode
+ * and the next display list must not be started automatically.
+ */
dl->header->flags = VSP1_DLH_INT_ENABLE;
}
}
-void vsp1_dl_list_commit(struct vsp1_dl_list *dl)
+static bool vsp1_dl_list_hw_update_pending(struct vsp1_dl_manager *dlm)
{
- struct vsp1_dl_manager *dlm = dl->dlm;
struct vsp1_device *vsp1 = dlm->vsp1;
- unsigned long flags;
- bool update;
- spin_lock_irqsave(&dlm->lock, flags);
+ if (!dlm->queued)
+ return false;
- if (dl->dlm->mode == VSP1_DL_MODE_HEADER) {
- struct vsp1_dl_list *dl_child;
+ /*
+ * Check whether the VSP1 has taken the update. In headerless mode the
+ * hardware indicates this by clearing the UPD bit in the DL_BODY_SIZE
+ * register, and in header mode by clearing the UPDHDR bit in the CMD
+ * register.
+ */
+ if (dlm->mode == VSP1_DL_MODE_HEADERLESS)
+ return !!(vsp1_read(vsp1, VI6_DL_BODY_SIZE)
+ & VI6_DL_BODY_SIZE_UPD);
+ else
+ return !!(vsp1_read(vsp1, VI6_CMD(dlm->index) & VI6_CMD_UPDHDR));
+}
+static void vsp1_dl_list_hw_enqueue(struct vsp1_dl_list *dl)
+{
+ struct vsp1_dl_manager *dlm = dl->dlm;
+ struct vsp1_device *vsp1 = dlm->vsp1;
+
+ if (dlm->mode == VSP1_DL_MODE_HEADERLESS) {
/*
- * In header mode the caller guarantees that the hardware is
- * idle at this point.
+ * In headerless mode, program the hardware directly with the
+ * display list body address and size and set the UPD bit. The
+ * bit will be cleared by the hardware when the display list
+ * processing starts.
*/
-
- /* Fill the header for the head and chained display lists. */
- vsp1_dl_list_fill_header(dl, list_empty(&dl->chain));
-
- list_for_each_entry(dl_child, &dl->chain, chain) {
- bool last = list_is_last(&dl_child->chain, &dl->chain);
-
- vsp1_dl_list_fill_header(dl_child, last);
- }
-
+ vsp1_write(vsp1, VI6_DL_HDR_ADDR(0), dl->body0.dma);
+ vsp1_write(vsp1, VI6_DL_BODY_SIZE, VI6_DL_BODY_SIZE_UPD |
+ (dl->body0.num_entries * sizeof(*dl->header->lists)));
+ } else {
/*
- * Commit the head display list to hardware. Chained headers
- * will auto-start.
+ * In header mode, program the display list header address. If
+ * the hardware is idle (single-shot mode or first frame in
+ * continuous mode) it will then be started independently. If
+ * the hardware is operating, the VI6_DL_HDR_REF_ADDR register
+ * will be updated with the display list address.
*/
vsp1_write(vsp1, VI6_DL_HDR_ADDR(dlm->index), dl->dma);
-
- dlm->active = dl;
- goto done;
}
+}
+
+static void vsp1_dl_list_commit_continuous(struct vsp1_dl_list *dl)
+{
+ struct vsp1_dl_manager *dlm = dl->dlm;
/*
- * Once the UPD bit has been set the hardware can start processing the
- * display list at any time and we can't touch the address and size
- * registers. In that case mark the update as pending, it will be
- * queued up to the hardware by the frame end interrupt handler.
+ * If a previous display list has been queued to the hardware but not
+ * processed yet, the VSP can start processing it at any time. In that
+ * case we can't replace the queued list by the new one, as we could
+ * race with the hardware. We thus mark the update as pending, it will
+ * be queued up to the hardware by the frame end interrupt handler.
*/
- update = !!(vsp1_read(vsp1, VI6_DL_BODY_SIZE) & VI6_DL_BODY_SIZE_UPD);
- if (update) {
+ if (vsp1_dl_list_hw_update_pending(dlm)) {
__vsp1_dl_list_put(dlm->pending);
dlm->pending = dl;
- goto done;
+ return;
}
/*
- * Program the hardware with the display list body address and size.
- * The UPD bit will be cleared by the device when the display list is
- * processed.
+ * Pass the new display list to the hardware and mark it as queued. It
+ * will become active when the hardware starts processing it.
*/
- vsp1_write(vsp1, VI6_DL_HDR_ADDR(0), dl->body0.dma);
- vsp1_write(vsp1, VI6_DL_BODY_SIZE, VI6_DL_BODY_SIZE_UPD |
- (dl->body0.num_entries * sizeof(*dl->header->lists)));
+ vsp1_dl_list_hw_enqueue(dl);
__vsp1_dl_list_put(dlm->queued);
dlm->queued = dl;
-
-done:
- spin_unlock_irqrestore(&dlm->lock, flags);
}
-/* -----------------------------------------------------------------------------
- * Display List Manager
- */
-
-/* Interrupt Handling */
-void vsp1_dlm_irq_display_start(struct vsp1_dl_manager *dlm)
+static void vsp1_dl_list_commit_singleshot(struct vsp1_dl_list *dl)
{
- spin_lock(&dlm->lock);
+ struct vsp1_dl_manager *dlm = dl->dlm;
/*
- * The display start interrupt signals the end of the display list
- * processing by the device. The active display list, if any, won't be
- * accessed anymore and can be reused.
+ * When working in single-shot mode, the caller guarantees that the
+ * hardware is idle at this point. Just commit the head display list
+ * to hardware. Chained lists will be started automatically.
*/
- __vsp1_dl_list_put(dlm->active);
- dlm->active = NULL;
+ vsp1_dl_list_hw_enqueue(dl);
- spin_unlock(&dlm->lock);
+ dlm->active = dl;
+}
+
+void vsp1_dl_list_commit(struct vsp1_dl_list *dl)
+{
+ struct vsp1_dl_manager *dlm = dl->dlm;
+ struct vsp1_dl_list *dl_child;
+ unsigned long flags;
+
+ if (dlm->mode == VSP1_DL_MODE_HEADER) {
+ /* Fill the header for the head and chained display lists. */
+ vsp1_dl_list_fill_header(dl, list_empty(&dl->chain));
+
+ list_for_each_entry(dl_child, &dl->chain, chain) {
+ bool last = list_is_last(&dl_child->chain, &dl->chain);
+
+ vsp1_dl_list_fill_header(dl_child, last);
+ }
+ }
+
+ spin_lock_irqsave(&dlm->lock, flags);
+
+ if (dlm->singleshot)
+ vsp1_dl_list_commit_singleshot(dl);
+ else
+ vsp1_dl_list_commit_continuous(dl);
+
+ spin_unlock_irqrestore(&dlm->lock, flags);
}
+/* -----------------------------------------------------------------------------
+ * Display List Manager
+ */
+
/**
* vsp1_dlm_irq_frame_end - Display list handler for the frame end interrupt
* @dlm: the display list manager
@@ -572,31 +621,28 @@ void vsp1_dlm_irq_display_start(struct vsp1_dl_manager *dlm)
*/
bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
{
- struct vsp1_device *vsp1 = dlm->vsp1;
bool completed = false;
spin_lock(&dlm->lock);
- __vsp1_dl_list_put(dlm->active);
- dlm->active = NULL;
-
/*
- * Header mode is used for mem-to-mem pipelines only. We don't need to
- * perform any operation as there can't be any new display list queued
- * in that case.
+ * The mem-to-mem pipelines work in single-shot mode. No new display
+ * list can be queued, we don't have to do anything.
*/
- if (dlm->mode == VSP1_DL_MODE_HEADER) {
+ if (dlm->singleshot) {
+ __vsp1_dl_list_put(dlm->active);
+ dlm->active = NULL;
completed = true;
goto done;
}
/*
- * The UPD bit set indicates that the commit operation raced with the
- * interrupt and occurred after the frame end event and UPD clear but
- * before interrupt processing. The hardware hasn't taken the update
- * into account yet, we'll thus skip one frame and retry.
+ * If the commit operation raced with the interrupt and occurred after
+ * the frame end event but before interrupt processing, the hardware
+ * hasn't taken the update into account yet. We have to skip one frame
+ * and retry.
*/
- if (vsp1_read(vsp1, VI6_DL_BODY_SIZE) & VI6_DL_BODY_SIZE_UPD)
+ if (vsp1_dl_list_hw_update_pending(dlm))
goto done;
/*
@@ -604,24 +650,20 @@ bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm)
* frame end interrupt. The display list thus becomes active.
*/
if (dlm->queued) {
+ __vsp1_dl_list_put(dlm->active);
dlm->active = dlm->queued;
dlm->queued = NULL;
completed = true;
}
/*
- * Now that the UPD bit has been cleared we can queue the next display
- * list to the hardware if one has been prepared.
+ * Now that the VSP has started processing the queued display list, we
+ * can queue the pending display list to the hardware if one has been
+ * prepared.
*/
if (dlm->pending) {
- struct vsp1_dl_list *dl = dlm->pending;
-
- vsp1_write(vsp1, VI6_DL_HDR_ADDR(0), dl->body0.dma);
- vsp1_write(vsp1, VI6_DL_BODY_SIZE, VI6_DL_BODY_SIZE_UPD |
- (dl->body0.num_entries *
- sizeof(*dl->header->lists)));
-
- dlm->queued = dl;
+ vsp1_dl_list_hw_enqueue(dlm->pending);
+ dlm->queued = dlm->pending;
dlm->pending = NULL;
}
@@ -714,6 +756,7 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
dlm->index = index;
dlm->mode = index == 0 && !vsp1->info->uapi
? VSP1_DL_MODE_HEADERLESS : VSP1_DL_MODE_HEADER;
+ dlm->singleshot = vsp1->info->uapi;
dlm->vsp1 = vsp1;
spin_lock_init(&dlm->lock);
diff --git a/drivers/media/platform/vsp1/vsp1_dl.h b/drivers/media/platform/vsp1/vsp1_dl.h
index 6ec1380a10af..ee3508172f0a 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.h
+++ b/drivers/media/platform/vsp1/vsp1_dl.h
@@ -27,7 +27,6 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
unsigned int prealloc);
void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm);
void vsp1_dlm_reset(struct vsp1_dl_manager *dlm);
-void vsp1_dlm_irq_display_start(struct vsp1_dl_manager *dlm);
bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm);
struct vsp1_dl_list *vsp1_dl_list_get(struct vsp1_dl_manager *dlm);
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index 9377aafa8996..4dfbeac8f42c 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -32,17 +32,13 @@
* Interrupt Handling
*/
-void vsp1_drm_display_start(struct vsp1_device *vsp1)
+static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe,
+ bool completed)
{
- vsp1_dlm_irq_display_start(vsp1->drm->pipe.output->dlm);
-}
-
-static void vsp1_du_pipeline_frame_end(struct vsp1_pipeline *pipe)
-{
- struct vsp1_drm *drm = to_vsp1_drm(pipe);
+ struct vsp1_drm_pipeline *drm_pipe = to_vsp1_drm_pipeline(pipe);
- if (drm->du_complete)
- drm->du_complete(drm->du_private);
+ if (drm_pipe->du_complete)
+ drm_pipe->du_complete(drm_pipe->du_private, completed);
}
/* -----------------------------------------------------------------------------
@@ -63,29 +59,44 @@ EXPORT_SYMBOL_GPL(vsp1_du_init);
/**
* vsp1_du_setup_lif - Setup the output part of the VSP pipeline
* @dev: the VSP device
+ * @pipe_index: the DRM pipeline index
* @cfg: the LIF configuration
*
* Configure the output part of VSP DRM pipeline for the given frame @cfg.width
- * and @cfg.height. This sets up formats on the BRU source pad, the WPF0 sink
- * and source pads, and the LIF sink pad.
+ * and @cfg.height. This sets up formats on the blend unit (BRU or BRS) source
+ * pad, the WPF sink and source pads, and the LIF sink pad.
+ *
+ * The @pipe_index argument selects which DRM pipeline to setup. The number of
+ * available pipelines depend on the VSP instance.
*
- * As the media bus code on the BRU source pad is conditioned by the
- * configuration of the BRU sink 0 pad, we also set up the formats on all BRU
+ * As the media bus code on the blend unit source pad is conditioned by the
+ * configuration of its sink 0 pad, we also set up the formats on all blend unit
* sinks, even if the configuration will be overwritten later by
- * vsp1_du_setup_rpf(). This ensures that the BRU configuration is set to a well
- * defined state.
+ * vsp1_du_setup_rpf(). This ensures that the blend unit configuration is set to
+ * a well defined state.
*
* Return 0 on success or a negative error code on failure.
*/
-int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
+int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index,
+ const struct vsp1_du_lif_config *cfg)
{
struct vsp1_device *vsp1 = dev_get_drvdata(dev);
- struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
- struct vsp1_bru *bru = vsp1->bru;
+ struct vsp1_drm_pipeline *drm_pipe;
+ struct vsp1_pipeline *pipe;
+ struct vsp1_bru *bru;
struct v4l2_subdev_format format;
+ const char *bru_name;
unsigned int i;
int ret;
+ if (pipe_index >= vsp1->info->lif_count)
+ return -EINVAL;
+
+ drm_pipe = &vsp1->drm->pipe[pipe_index];
+ pipe = &drm_pipe->pipe;
+ bru = to_bru(&pipe->bru->subdev);
+ bru_name = pipe->bru->type == VSP1_ENTITY_BRU ? "BRU" : "BRS";
+
if (!cfg) {
/*
* NULL configuration means the CRTC is being disabled, stop
@@ -97,14 +108,25 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
media_pipeline_stop(&pipe->output->entity.subdev.entity);
- for (i = 0; i < bru->entity.source_pad; ++i) {
- vsp1->drm->inputs[i].enabled = false;
- bru->inputs[i].rpf = NULL;
+ for (i = 0; i < ARRAY_SIZE(pipe->inputs); ++i) {
+ struct vsp1_rwpf *rpf = pipe->inputs[i];
+
+ if (!rpf)
+ continue;
+
+ /*
+ * Remove the RPF from the pipe and the list of BRU
+ * inputs.
+ */
+ WARN_ON(list_empty(&rpf->entity.list_pipe));
+ list_del_init(&rpf->entity.list_pipe);
pipe->inputs[i] = NULL;
+
+ bru->inputs[rpf->bru_input].rpf = NULL;
}
+ drm_pipe->du_complete = NULL;
pipe->num_inputs = 0;
- vsp1->drm->du_complete = NULL;
vsp1_dlm_reset(pipe->output->dlm);
vsp1_device_put(vsp1);
@@ -114,8 +136,8 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
return 0;
}
- dev_dbg(vsp1->dev, "%s: configuring LIF with format %ux%u\n",
- __func__, cfg->width, cfg->height);
+ dev_dbg(vsp1->dev, "%s: configuring LIF%u with format %ux%u\n",
+ __func__, pipe_index, cfg->width, cfg->height);
/*
* Configure the format at the BRU sinks and propagate it through the
@@ -124,7 +146,7 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
memset(&format, 0, sizeof(format));
format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- for (i = 0; i < bru->entity.source_pad; ++i) {
+ for (i = 0; i < pipe->bru->source_pad; ++i) {
format.pad = i;
format.format.width = cfg->width;
@@ -132,60 +154,60 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
format.format.field = V4L2_FIELD_NONE;
- ret = v4l2_subdev_call(&bru->entity.subdev, pad,
+ ret = v4l2_subdev_call(&pipe->bru->subdev, pad,
set_fmt, NULL, &format);
if (ret < 0)
return ret;
- dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on BRU pad %u\n",
+ dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n",
__func__, format.format.width, format.format.height,
- format.format.code, i);
+ format.format.code, bru_name, i);
}
- format.pad = bru->entity.source_pad;
+ format.pad = pipe->bru->source_pad;
format.format.width = cfg->width;
format.format.height = cfg->height;
format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
format.format.field = V4L2_FIELD_NONE;
- ret = v4l2_subdev_call(&bru->entity.subdev, pad, set_fmt, NULL,
+ ret = v4l2_subdev_call(&pipe->bru->subdev, pad, set_fmt, NULL,
&format);
if (ret < 0)
return ret;
- dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on BRU pad %u\n",
+ dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n",
__func__, format.format.width, format.format.height,
- format.format.code, i);
+ format.format.code, bru_name, i);
format.pad = RWPF_PAD_SINK;
- ret = v4l2_subdev_call(&vsp1->wpf[0]->entity.subdev, pad, set_fmt, NULL,
+ ret = v4l2_subdev_call(&pipe->output->entity.subdev, pad, set_fmt, NULL,
&format);
if (ret < 0)
return ret;
- dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on WPF0 sink\n",
+ dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on WPF%u sink\n",
__func__, format.format.width, format.format.height,
- format.format.code);
+ format.format.code, pipe->output->entity.index);
format.pad = RWPF_PAD_SOURCE;
- ret = v4l2_subdev_call(&vsp1->wpf[0]->entity.subdev, pad, get_fmt, NULL,
+ ret = v4l2_subdev_call(&pipe->output->entity.subdev, pad, get_fmt, NULL,
&format);
if (ret < 0)
return ret;
- dev_dbg(vsp1->dev, "%s: got format %ux%u (%x) on WPF0 source\n",
+ dev_dbg(vsp1->dev, "%s: got format %ux%u (%x) on WPF%u source\n",
__func__, format.format.width, format.format.height,
- format.format.code);
+ format.format.code, pipe->output->entity.index);
format.pad = LIF_PAD_SINK;
- ret = v4l2_subdev_call(&vsp1->lif->entity.subdev, pad, set_fmt, NULL,
+ ret = v4l2_subdev_call(&pipe->lif->subdev, pad, set_fmt, NULL,
&format);
if (ret < 0)
return ret;
- dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on LIF sink\n",
+ dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on LIF%u sink\n",
__func__, format.format.width, format.format.height,
- format.format.code);
+ format.format.code, pipe_index);
/*
* Verify that the format at the output of the pipeline matches the
@@ -213,8 +235,8 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
* Register a callback to allow us to notify the DRM driver of frame
* completion events.
*/
- vsp1->drm->du_complete = cfg->callback;
- vsp1->drm->du_private = cfg->callback_data;
+ drm_pipe->du_complete = cfg->callback;
+ drm_pipe->du_private = cfg->callback_data;
ret = media_pipeline_start(&pipe->output->entity.subdev.entity,
&pipe->pipe);
@@ -224,6 +246,10 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg)
return ret;
}
+ /* Disable the display interrupts. */
+ vsp1_write(vsp1, VI6_DISP_IRQ_STA, 0);
+ vsp1_write(vsp1, VI6_DISP_IRQ_ENB, 0);
+
dev_dbg(vsp1->dev, "%s: pipeline enabled\n", __func__);
return 0;
@@ -233,19 +259,21 @@ EXPORT_SYMBOL_GPL(vsp1_du_setup_lif);
/**
* vsp1_du_atomic_begin - Prepare for an atomic update
* @dev: the VSP device
+ * @pipe_index: the DRM pipeline index
*/
-void vsp1_du_atomic_begin(struct device *dev)
+void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index)
{
struct vsp1_device *vsp1 = dev_get_drvdata(dev);
- struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
+ struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
- vsp1->drm->num_inputs = pipe->num_inputs;
+ drm_pipe->enabled = drm_pipe->pipe.num_inputs != 0;
}
EXPORT_SYMBOL_GPL(vsp1_du_atomic_begin);
/**
* vsp1_du_atomic_update - Setup one RPF input of the VSP pipeline
* @dev: the VSP device
+ * @pipe_index: the DRM pipeline index
* @rpf_index: index of the RPF to setup (0-based)
* @cfg: the RPF configuration
*
@@ -272,10 +300,12 @@ EXPORT_SYMBOL_GPL(vsp1_du_atomic_begin);
*
* Return 0 on success or a negative error code on failure.
*/
-int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index,
+int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
+ unsigned int rpf_index,
const struct vsp1_du_atomic_config *cfg)
{
struct vsp1_device *vsp1 = dev_get_drvdata(dev);
+ struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
const struct vsp1_format_info *fmtinfo;
struct vsp1_rwpf *rpf;
@@ -288,7 +318,12 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index,
dev_dbg(vsp1->dev, "%s: RPF%u: disable requested\n", __func__,
rpf_index);
- vsp1->drm->inputs[rpf_index].enabled = false;
+ /*
+ * Remove the RPF from the pipe's inputs. The atomic flush
+ * handler will disable the input and remove the entity from the
+ * pipe's entities list.
+ */
+ drm_pipe->pipe.inputs[rpf_index] = NULL;
return 0;
}
@@ -324,13 +359,15 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index,
vsp1->drm->inputs[rpf_index].crop = cfg->src;
vsp1->drm->inputs[rpf_index].compose = cfg->dst;
vsp1->drm->inputs[rpf_index].zpos = cfg->zpos;
- vsp1->drm->inputs[rpf_index].enabled = true;
+
+ drm_pipe->pipe.inputs[rpf_index] = rpf;
return 0;
}
EXPORT_SYMBOL_GPL(vsp1_du_atomic_update);
static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1,
+ struct vsp1_pipeline *pipe,
struct vsp1_rwpf *rpf, unsigned int bru_input)
{
struct v4l2_subdev_selection sel;
@@ -404,7 +441,7 @@ static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1,
/* BRU sink, propagate the format from the RPF source. */
format.pad = bru_input;
- ret = v4l2_subdev_call(&vsp1->bru->entity.subdev, pad, set_fmt, NULL,
+ ret = v4l2_subdev_call(&pipe->bru->subdev, pad, set_fmt, NULL,
&format);
if (ret < 0)
return ret;
@@ -417,8 +454,8 @@ static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1,
sel.target = V4L2_SEL_TGT_COMPOSE;
sel.r = vsp1->drm->inputs[rpf->entity.index].compose;
- ret = v4l2_subdev_call(&vsp1->bru->entity.subdev, pad, set_selection,
- NULL, &sel);
+ ret = v4l2_subdev_call(&pipe->bru->subdev, pad, set_selection, NULL,
+ &sel);
if (ret < 0)
return ret;
@@ -438,18 +475,25 @@ static unsigned int rpf_zpos(struct vsp1_device *vsp1, struct vsp1_rwpf *rpf)
/**
* vsp1_du_atomic_flush - Commit an atomic update
* @dev: the VSP device
+ * @pipe_index: the DRM pipeline index
*/
-void vsp1_du_atomic_flush(struct device *dev)
+void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index)
{
struct vsp1_device *vsp1 = dev_get_drvdata(dev);
- struct vsp1_pipeline *pipe = &vsp1->drm->pipe;
+ struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[pipe_index];
+ struct vsp1_pipeline *pipe = &drm_pipe->pipe;
struct vsp1_rwpf *inputs[VSP1_MAX_RPF] = { NULL, };
+ struct vsp1_bru *bru = to_bru(&pipe->bru->subdev);
struct vsp1_entity *entity;
+ struct vsp1_entity *next;
struct vsp1_dl_list *dl;
+ const char *bru_name;
unsigned long flags;
unsigned int i;
int ret;
+ bru_name = pipe->bru->type == VSP1_ENTITY_BRU ? "BRU" : "BRS";
+
/* Prepare the display list. */
dl = vsp1_dl_list_get(pipe->output->dlm);
@@ -460,12 +504,8 @@ void vsp1_du_atomic_flush(struct device *dev)
struct vsp1_rwpf *rpf = vsp1->rpf[i];
unsigned int j;
- if (!vsp1->drm->inputs[i].enabled) {
- pipe->inputs[i] = NULL;
+ if (!pipe->inputs[i])
continue;
- }
-
- pipe->inputs[i] = rpf;
/* Insert the RPF in the sorted RPFs array. */
for (j = pipe->num_inputs++; j > 0; --j) {
@@ -478,22 +518,26 @@ void vsp1_du_atomic_flush(struct device *dev)
}
/* Setup the RPF input pipeline for every enabled input. */
- for (i = 0; i < vsp1->info->num_bru_inputs; ++i) {
+ for (i = 0; i < pipe->bru->source_pad; ++i) {
struct vsp1_rwpf *rpf = inputs[i];
if (!rpf) {
- vsp1->bru->inputs[i].rpf = NULL;
+ bru->inputs[i].rpf = NULL;
continue;
}
- vsp1->bru->inputs[i].rpf = rpf;
+ if (list_empty(&rpf->entity.list_pipe))
+ list_add_tail(&rpf->entity.list_pipe, &pipe->entities);
+
+ bru->inputs[i].rpf = rpf;
rpf->bru_input = i;
+ rpf->entity.sink = pipe->bru;
rpf->entity.sink_pad = i;
- dev_dbg(vsp1->dev, "%s: connecting RPF.%u to BRU:%u\n",
- __func__, rpf->entity.index, i);
+ dev_dbg(vsp1->dev, "%s: connecting RPF.%u to %s:%u\n",
+ __func__, rpf->entity.index, bru_name, i);
- ret = vsp1_du_setup_rpf_pipe(vsp1, rpf, i);
+ ret = vsp1_du_setup_rpf_pipe(vsp1, pipe, rpf, i);
if (ret < 0)
dev_err(vsp1->dev,
"%s: failed to setup RPF.%u\n",
@@ -501,16 +545,16 @@ void vsp1_du_atomic_flush(struct device *dev)
}
/* Configure all entities in the pipeline. */
- list_for_each_entry(entity, &pipe->entities, list_pipe) {
+ list_for_each_entry_safe(entity, next, &pipe->entities, list_pipe) {
/* Disconnect unused RPFs from the pipeline. */
- if (entity->type == VSP1_ENTITY_RPF) {
- struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);
+ if (entity->type == VSP1_ENTITY_RPF &&
+ !pipe->inputs[entity->index]) {
+ vsp1_dl_list_write(dl, entity->route->reg,
+ VI6_DPR_NODE_UNUSED);
- if (!pipe->inputs[rpf->entity.index]) {
- vsp1_dl_list_write(dl, entity->route->reg,
- VI6_DPR_NODE_UNUSED);
- continue;
- }
+ list_del_init(&entity->list_pipe);
+
+ continue;
}
vsp1_entity_route_setup(entity, pipe, dl);
@@ -528,14 +572,11 @@ void vsp1_du_atomic_flush(struct device *dev)
vsp1_dl_list_commit(dl);
/* Start or stop the pipeline if needed. */
- if (!vsp1->drm->num_inputs && pipe->num_inputs) {
- vsp1_write(vsp1, VI6_DISP_IRQ_STA, 0);
- vsp1_write(vsp1, VI6_DISP_IRQ_ENB, VI6_DISP_IRQ_ENB_DSTE);
+ if (!drm_pipe->enabled && pipe->num_inputs) {
spin_lock_irqsave(&pipe->irqlock, flags);
vsp1_pipeline_run(pipe);
spin_unlock_irqrestore(&pipe->irqlock, flags);
- } else if (vsp1->drm->num_inputs && !pipe->num_inputs) {
- vsp1_write(vsp1, VI6_DISP_IRQ_ENB, 0);
+ } else if (drm_pipe->enabled && !pipe->num_inputs) {
vsp1_pipeline_stop(pipe);
}
}
@@ -568,83 +609,48 @@ EXPORT_SYMBOL_GPL(vsp1_du_unmap_sg);
* Initialization
*/
-int vsp1_drm_create_links(struct vsp1_device *vsp1)
-{
- const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
- unsigned int i;
- int ret;
-
- /*
- * VSPD instances require a BRU to perform composition and a LIF to
- * output to the DU.
- */
- if (!vsp1->bru || !vsp1->lif)
- return -ENXIO;
-
- for (i = 0; i < vsp1->info->rpf_count; ++i) {
- struct vsp1_rwpf *rpf = vsp1->rpf[i];
-
- ret = media_create_pad_link(&rpf->entity.subdev.entity,
- RWPF_PAD_SOURCE,
- &vsp1->bru->entity.subdev.entity,
- i, flags);
- if (ret < 0)
- return ret;
-
- rpf->entity.sink = &vsp1->bru->entity.subdev.entity;
- rpf->entity.sink_pad = i;
- }
-
- ret = media_create_pad_link(&vsp1->bru->entity.subdev.entity,
- vsp1->bru->entity.source_pad,
- &vsp1->wpf[0]->entity.subdev.entity,
- RWPF_PAD_SINK, flags);
- if (ret < 0)
- return ret;
-
- vsp1->bru->entity.sink = &vsp1->wpf[0]->entity.subdev.entity;
- vsp1->bru->entity.sink_pad = RWPF_PAD_SINK;
-
- ret = media_create_pad_link(&vsp1->wpf[0]->entity.subdev.entity,
- RWPF_PAD_SOURCE,
- &vsp1->lif->entity.subdev.entity,
- LIF_PAD_SINK, flags);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
int vsp1_drm_init(struct vsp1_device *vsp1)
{
- struct vsp1_pipeline *pipe;
unsigned int i;
vsp1->drm = devm_kzalloc(vsp1->dev, sizeof(*vsp1->drm), GFP_KERNEL);
if (!vsp1->drm)
return -ENOMEM;
- pipe = &vsp1->drm->pipe;
+ /* Create one DRM pipeline per LIF. */
+ for (i = 0; i < vsp1->info->lif_count; ++i) {
+ struct vsp1_drm_pipeline *drm_pipe = &vsp1->drm->pipe[i];
+ struct vsp1_pipeline *pipe = &drm_pipe->pipe;
- vsp1_pipeline_init(pipe);
+ vsp1_pipeline_init(pipe);
- /* The DRM pipeline is static, add entities manually. */
+ /*
+ * The DRM pipeline is static, add entities manually. The first
+ * pipeline uses the BRU and the second pipeline the BRS.
+ */
+ pipe->bru = i == 0 ? &vsp1->bru->entity : &vsp1->brs->entity;
+ pipe->lif = &vsp1->lif[i]->entity;
+ pipe->output = vsp1->wpf[i];
+ pipe->output->pipe = pipe;
+ pipe->frame_end = vsp1_du_pipeline_frame_end;
+
+ pipe->bru->sink = &pipe->output->entity;
+ pipe->bru->sink_pad = 0;
+ pipe->output->entity.sink = pipe->lif;
+ pipe->output->entity.sink_pad = 0;
+
+ list_add_tail(&pipe->bru->list_pipe, &pipe->entities);
+ list_add_tail(&pipe->lif->list_pipe, &pipe->entities);
+ list_add_tail(&pipe->output->entity.list_pipe, &pipe->entities);
+ }
+
+ /* Disable all RPFs initially. */
for (i = 0; i < vsp1->info->rpf_count; ++i) {
struct vsp1_rwpf *input = vsp1->rpf[i];
- list_add_tail(&input->entity.list_pipe, &pipe->entities);
+ INIT_LIST_HEAD(&input->entity.list_pipe);
}
- list_add_tail(&vsp1->bru->entity.list_pipe, &pipe->entities);
- list_add_tail(&vsp1->wpf[0]->entity.list_pipe, &pipe->entities);
- list_add_tail(&vsp1->lif->entity.list_pipe, &pipe->entities);
-
- pipe->bru = &vsp1->bru->entity;
- pipe->lif = &vsp1->lif->entity;
- pipe->output = vsp1->wpf[0];
- pipe->output->pipe = pipe;
- pipe->frame_end = vsp1_du_pipeline_frame_end;
-
return 0;
}
diff --git a/drivers/media/platform/vsp1/vsp1_drm.h b/drivers/media/platform/vsp1/vsp1_drm.h
index e9f80727ff92..1cd9db785bf7 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.h
+++ b/drivers/media/platform/vsp1/vsp1_drm.h
@@ -18,38 +18,44 @@
#include "vsp1_pipe.h"
/**
- * vsp1_drm - State for the API exposed to the DRM driver
+ * vsp1_drm_pipeline - State for the API exposed to the DRM driver
* @pipe: the VSP1 pipeline used for display
- * @num_inputs: number of active pipeline inputs at the beginning of an update
- * @inputs: source crop rectangle, destination compose rectangle and z-order
- * position for every input
+ * @enabled: pipeline state at the beginning of an update
* @du_complete: frame completion callback for the DU driver (optional)
* @du_private: data to be passed to the du_complete callback
*/
-struct vsp1_drm {
+struct vsp1_drm_pipeline {
struct vsp1_pipeline pipe;
- unsigned int num_inputs;
+ bool enabled;
+
+ /* Frame synchronisation */
+ void (*du_complete)(void *, bool);
+ void *du_private;
+};
+
+/**
+ * vsp1_drm - State for the API exposed to the DRM driver
+ * @pipe: the VSP1 DRM pipeline used for display
+ * @inputs: source crop rectangle, destination compose rectangle and z-order
+ * position for every input (indexed by RPF index)
+ */
+struct vsp1_drm {
+ struct vsp1_drm_pipeline pipe[VSP1_MAX_LIF];
+
struct {
- bool enabled;
struct v4l2_rect crop;
struct v4l2_rect compose;
unsigned int zpos;
} inputs[VSP1_MAX_RPF];
-
- /* Frame synchronisation */
- void (*du_complete)(void *);
- void *du_private;
};
-static inline struct vsp1_drm *to_vsp1_drm(struct vsp1_pipeline *pipe)
+static inline struct vsp1_drm_pipeline *
+to_vsp1_drm_pipeline(struct vsp1_pipeline *pipe)
{
- return container_of(pipe, struct vsp1_drm, pipe);
+ return container_of(pipe, struct vsp1_drm_pipeline, pipe);
}
int vsp1_drm_init(struct vsp1_device *vsp1);
void vsp1_drm_cleanup(struct vsp1_device *vsp1);
-int vsp1_drm_create_links(struct vsp1_device *vsp1);
-
-void vsp1_drm_display_start(struct vsp1_device *vsp1);
#endif /* __VSP1_DRM_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 95c26edead85..962e4c304076 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -68,14 +68,6 @@ static irqreturn_t vsp1_irq_handler(int irq, void *data)
}
}
- status = vsp1_read(vsp1, VI6_DISP_IRQ_STA);
- vsp1_write(vsp1, VI6_DISP_IRQ_STA, ~status & VI6_DISP_IRQ_STA_DST);
-
- if (status & VI6_DISP_IRQ_STA_DST) {
- vsp1_drm_display_start(vsp1);
- ret = IRQ_HANDLED;
- }
-
return ret;
}
@@ -92,6 +84,10 @@ static irqreturn_t vsp1_irq_handler(int irq, void *data)
*
* - from a UDS to a UDS (UDS entities can't be chained)
* - from an entity to itself (no loops are allowed)
+ *
+ * Furthermore, the BRS can't be connected to histogram generators, but no
+ * special check is currently needed as all VSP instances that include a BRS
+ * have no histogram generator.
*/
static int vsp1_create_sink_links(struct vsp1_device *vsp1,
struct vsp1_entity *sink)
@@ -129,7 +125,7 @@ static int vsp1_create_sink_links(struct vsp1_device *vsp1,
return ret;
if (flags & MEDIA_LNK_FL_ENABLED)
- source->sink = entity;
+ source->sink = sink;
}
}
@@ -172,10 +168,13 @@ static int vsp1_uapi_create_links(struct vsp1_device *vsp1)
return ret;
}
- if (vsp1->lif) {
- ret = media_create_pad_link(&vsp1->wpf[0]->entity.subdev.entity,
+ for (i = 0; i < vsp1->info->lif_count; ++i) {
+ if (!vsp1->lif[i])
+ continue;
+
+ ret = media_create_pad_link(&vsp1->wpf[i]->entity.subdev.entity,
RWPF_PAD_SOURCE,
- &vsp1->lif->entity.subdev.entity,
+ &vsp1->lif[i]->entity.subdev.entity,
LIF_PAD_SINK, 0);
if (ret < 0)
return ret;
@@ -269,8 +268,18 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
}
/* Instantiate all the entities. */
+ if (vsp1->info->features & VSP1_HAS_BRS) {
+ vsp1->brs = vsp1_bru_create(vsp1, VSP1_ENTITY_BRS);
+ if (IS_ERR(vsp1->brs)) {
+ ret = PTR_ERR(vsp1->brs);
+ goto done;
+ }
+
+ list_add_tail(&vsp1->brs->entity.list_dev, &vsp1->entities);
+ }
+
if (vsp1->info->features & VSP1_HAS_BRU) {
- vsp1->bru = vsp1_bru_create(vsp1);
+ vsp1->bru = vsp1_bru_create(vsp1, VSP1_ENTITY_BRU);
if (IS_ERR(vsp1->bru)) {
ret = PTR_ERR(vsp1->bru);
goto done;
@@ -328,18 +337,23 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
}
/*
- * The LIF is only supported when used in conjunction with the DU, in
+ * The LIFs are only supported when used in conjunction with the DU, in
* which case the userspace API is disabled. If the userspace API is
- * enabled skip the LIF, even when present.
+ * enabled skip the LIFs, even when present.
*/
- if (vsp1->info->features & VSP1_HAS_LIF && !vsp1->info->uapi) {
- vsp1->lif = vsp1_lif_create(vsp1);
- if (IS_ERR(vsp1->lif)) {
- ret = PTR_ERR(vsp1->lif);
- goto done;
- }
+ if (!vsp1->info->uapi) {
+ for (i = 0; i < vsp1->info->lif_count; ++i) {
+ struct vsp1_lif *lif;
+
+ lif = vsp1_lif_create(vsp1, i);
+ if (IS_ERR(lif)) {
+ ret = PTR_ERR(lif);
+ goto done;
+ }
- list_add_tail(&vsp1->lif->entity.list_dev, &vsp1->entities);
+ vsp1->lif[i] = lif;
+ list_add_tail(&lif->entity.list_dev, &vsp1->entities);
+ }
}
if (vsp1->info->features & VSP1_HAS_LUT) {
@@ -420,7 +434,6 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
}
list_add_tail(&video->list, &vsp1->videos);
- wpf->entity.sink = &video->video.entity;
}
}
@@ -432,19 +445,15 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
goto done;
}
- /* Create links. */
- if (vsp1->info->uapi)
- ret = vsp1_uapi_create_links(vsp1);
- else
- ret = vsp1_drm_create_links(vsp1);
- if (ret < 0)
- goto done;
-
/*
- * Register subdev nodes if the userspace API is enabled or initialize
- * the DRM pipeline otherwise.
+ * Create links and register subdev nodes if the userspace API is
+ * enabled or initialize the DRM pipeline otherwise.
*/
if (vsp1->info->uapi) {
+ ret = vsp1_uapi_create_links(vsp1);
+ if (ret < 0)
+ goto done;
+
ret = v4l2_device_register_subdev_nodes(&vsp1->v4l2_dev);
if (ret < 0)
goto done;
@@ -515,6 +524,9 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
vsp1_write(vsp1, VI6_DPR_HSI_ROUTE, VI6_DPR_NODE_UNUSED);
vsp1_write(vsp1, VI6_DPR_BRU_ROUTE, VI6_DPR_NODE_UNUSED);
+ if (vsp1->info->features & VSP1_HAS_BRS)
+ vsp1_write(vsp1, VI6_DPR_ILV_BRS_ROUTE, VI6_DPR_NODE_UNUSED);
+
vsp1_write(vsp1, VI6_DPR_HGO_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
(VI6_DPR_NODE_UNUSED << VI6_DPR_SMPPT_PT_SHIFT));
vsp1_write(vsp1, VI6_DPR_HGT_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
@@ -634,8 +646,8 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
.version = VI6_IP_VERSION_MODEL_VSPD_GEN2,
.model = "VSP1-D",
.gen = 2,
- .features = VSP1_HAS_BRU | VSP1_HAS_HGO | VSP1_HAS_LIF
- | VSP1_HAS_LUT,
+ .features = VSP1_HAS_BRU | VSP1_HAS_HGO | VSP1_HAS_LUT,
+ .lif_count = 1,
.rpf_count = 4,
.uds_count = 1,
.wpf_count = 1,
@@ -668,8 +680,8 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
.version = VI6_IP_VERSION_MODEL_VSPD_V2H,
.model = "VSP1V-D",
.gen = 2,
- .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_LUT
- | VSP1_HAS_LIF,
+ .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_LUT,
+ .lif_count = 1,
.rpf_count = 4,
.uds_count = 1,
.wpf_count = 1,
@@ -706,10 +718,37 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
.num_bru_inputs = 5,
.uapi = true,
}, {
+ .version = VI6_IP_VERSION_MODEL_VSPBS_GEN3,
+ .model = "VSP2-BS",
+ .gen = 3,
+ .features = VSP1_HAS_BRS | VSP1_HAS_WPF_VFLIP,
+ .rpf_count = 2,
+ .wpf_count = 1,
+ .uapi = true,
+ }, {
.version = VI6_IP_VERSION_MODEL_VSPD_GEN3,
.model = "VSP2-D",
.gen = 3,
- .features = VSP1_HAS_BRU | VSP1_HAS_LIF | VSP1_HAS_WPF_VFLIP,
+ .features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP,
+ .lif_count = 1,
+ .rpf_count = 5,
+ .wpf_count = 2,
+ .num_bru_inputs = 5,
+ }, {
+ .version = VI6_IP_VERSION_MODEL_VSPD_V3,
+ .model = "VSP2-D",
+ .gen = 3,
+ .features = VSP1_HAS_BRS | VSP1_HAS_BRU,
+ .lif_count = 1,
+ .rpf_count = 5,
+ .wpf_count = 1,
+ .num_bru_inputs = 5,
+ }, {
+ .version = VI6_IP_VERSION_MODEL_VSPDL_GEN3,
+ .model = "VSP2-DL",
+ .gen = 3,
+ .features = VSP1_HAS_BRS | VSP1_HAS_BRU,
+ .lif_count = 2,
.rpf_count = 5,
.wpf_count = 2,
.num_bru_inputs = 5,
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 4bdb3b141611..54de15095709 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -24,18 +24,12 @@
#include "vsp1_pipe.h"
#include "vsp1_rwpf.h"
-static inline struct vsp1_entity *
-media_entity_to_vsp1_entity(struct media_entity *entity)
-{
- return container_of(entity, struct vsp1_entity, subdev.entity);
-}
-
void vsp1_entity_route_setup(struct vsp1_entity *entity,
struct vsp1_pipeline *pipe,
struct vsp1_dl_list *dl)
{
struct vsp1_entity *source;
- struct vsp1_entity *sink;
+ u32 route;
if (entity->type == VSP1_ENTITY_HGO) {
u32 smppt;
@@ -44,7 +38,7 @@ void vsp1_entity_route_setup(struct vsp1_entity *entity,
* The HGO is a special case, its routing is configured on the
* sink pad.
*/
- source = media_entity_to_vsp1_entity(entity->sources[0]);
+ source = entity->sources[0];
smppt = (pipe->output->entity.index << VI6_DPR_SMPPT_TGW_SHIFT)
| (source->route->output << VI6_DPR_SMPPT_PT_SHIFT);
@@ -57,7 +51,7 @@ void vsp1_entity_route_setup(struct vsp1_entity *entity,
* The HGT is a special case, its routing is configured on the
* sink pad.
*/
- source = media_entity_to_vsp1_entity(entity->sources[0]);
+ source = entity->sources[0];
smppt = (pipe->output->entity.index << VI6_DPR_SMPPT_TGW_SHIFT)
| (source->route->output << VI6_DPR_SMPPT_PT_SHIFT);
@@ -69,9 +63,14 @@ void vsp1_entity_route_setup(struct vsp1_entity *entity,
if (source->route->reg == 0)
return;
- sink = media_entity_to_vsp1_entity(source->sink);
- vsp1_dl_list_write(dl, source->route->reg,
- sink->route->inputs[source->sink_pad]);
+ route = source->sink->route->inputs[source->sink_pad];
+ /*
+ * The ILV and BRS share the same data path route. The extra BRSSEL bit
+ * selects between the ILV and BRS.
+ */
+ if (source->type == VSP1_ENTITY_BRS)
+ route |= VI6_DPR_ROUTE_BRSSEL;
+ vsp1_dl_list_write(dl, source->route->reg, route);
}
/* -----------------------------------------------------------------------------
@@ -316,6 +315,12 @@ done:
* Media Operations
*/
+static inline struct vsp1_entity *
+media_entity_to_vsp1_entity(struct media_entity *entity)
+{
+ return container_of(entity, struct vsp1_entity, subdev.entity);
+}
+
static int vsp1_entity_link_setup_source(const struct media_pad *source_pad,
const struct media_pad *sink_pad,
u32 flags)
@@ -339,7 +344,7 @@ static int vsp1_entity_link_setup_source(const struct media_pad *source_pad,
sink->type != VSP1_ENTITY_HGT) {
if (source->sink)
return -EBUSY;
- source->sink = sink_pad->entity;
+ source->sink = sink;
source->sink_pad = sink_pad->index;
}
} else {
@@ -355,15 +360,17 @@ static int vsp1_entity_link_setup_sink(const struct media_pad *source_pad,
u32 flags)
{
struct vsp1_entity *sink;
+ struct vsp1_entity *source;
sink = media_entity_to_vsp1_entity(sink_pad->entity);
+ source = media_entity_to_vsp1_entity(source_pad->entity);
if (flags & MEDIA_LNK_FL_ENABLED) {
/* Fan-in is limited to one. */
if (sink->sources[sink_pad->index])
return -EBUSY;
- sink->sources[sink_pad->index] = source_pad->entity;
+ sink->sources[sink_pad->index] = source;
} else {
sink->sources[sink_pad->index] = NULL;
}
@@ -450,6 +457,8 @@ struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad)
{ VI6_DPR_NODE_WPF(idx) }, VI6_DPR_NODE_WPF(idx) }
static const struct vsp1_route vsp1_routes[] = {
+ { VSP1_ENTITY_BRS, 0, VI6_DPR_ILV_BRS_ROUTE,
+ { VI6_DPR_NODE_BRS_IN(0), VI6_DPR_NODE_BRS_IN(1) }, 0 },
{ VSP1_ENTITY_BRU, 0, VI6_DPR_BRU_ROUTE,
{ VI6_DPR_NODE_BRU_IN(0), VI6_DPR_NODE_BRU_IN(1),
VI6_DPR_NODE_BRU_IN(2), VI6_DPR_NODE_BRU_IN(3),
@@ -459,7 +468,8 @@ static const struct vsp1_route vsp1_routes[] = {
{ VSP1_ENTITY_HGT, 0, 0, { 0, }, 0 },
VSP1_ENTITY_ROUTE(HSI),
VSP1_ENTITY_ROUTE(HST),
- { VSP1_ENTITY_LIF, 0, 0, { VI6_DPR_NODE_LIF, }, VI6_DPR_NODE_LIF },
+ { VSP1_ENTITY_LIF, 0, 0, { 0, }, 0 },
+ { VSP1_ENTITY_LIF, 1, 0, { 0, }, 0 },
VSP1_ENTITY_ROUTE(LUT),
VSP1_ENTITY_ROUTE_RPF(0),
VSP1_ENTITY_ROUTE_RPF(1),
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index c169a060b6d2..11f8363fa6b0 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -23,6 +23,7 @@ struct vsp1_dl_list;
struct vsp1_pipeline;
enum vsp1_entity_type {
+ VSP1_ENTITY_BRS,
VSP1_ENTITY_BRU,
VSP1_ENTITY_CLU,
VSP1_ENTITY_HGO,
@@ -104,8 +105,8 @@ struct vsp1_entity {
struct media_pad *pads;
unsigned int source_pad;
- struct media_entity **sources;
- struct media_entity *sink;
+ struct vsp1_entity **sources;
+ struct vsp1_entity *sink;
unsigned int sink_pad;
struct v4l2_subdev subdev;
diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
index 702487f895b3..e6fa16d7fda8 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.c
+++ b/drivers/media/platform/vsp1/vsp1_lif.c
@@ -30,7 +30,7 @@
static inline void vsp1_lif_write(struct vsp1_lif *lif, struct vsp1_dl_list *dl,
u32 reg, u32 data)
{
- vsp1_dl_list_write(dl, reg, data);
+ vsp1_dl_list_write(dl, reg + lif->entity.index * VI6_LIF_OFFSET, data);
}
/* -----------------------------------------------------------------------------
@@ -165,7 +165,7 @@ static const struct vsp1_entity_operations lif_entity_ops = {
* Initialization and Cleanup
*/
-struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1)
+struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1, unsigned int index)
{
struct vsp1_lif *lif;
int ret;
@@ -176,6 +176,7 @@ struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1)
lif->entity.ops = &lif_entity_ops;
lif->entity.type = VSP1_ENTITY_LIF;
+ lif->entity.index = index;
/*
* The LIF is never exposed to userspace, but media entity registration
diff --git a/drivers/media/platform/vsp1/vsp1_lif.h b/drivers/media/platform/vsp1/vsp1_lif.h
index 7b35879028de..3417339379b1 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.h
+++ b/drivers/media/platform/vsp1/vsp1_lif.h
@@ -32,6 +32,6 @@ static inline struct vsp1_lif *to_lif(struct v4l2_subdev *subdev)
return container_of(subdev, struct vsp1_lif, entity.subdev);
}
-struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1);
+struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1, unsigned int index);
#endif /* __VSP1_LIF_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
index e817623b84e0..4f4b732df84b 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.c
+++ b/drivers/media/platform/vsp1/vsp1_pipe.c
@@ -335,16 +335,12 @@ void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
if (pipe == NULL)
return;
+ /*
+ * If the DL commit raced with the frame end interrupt, the commit ends
+ * up being postponed by one frame. @completed represents whether the
+ * active frame was finished or postponed.
+ */
completed = vsp1_dlm_irq_frame_end(pipe->output->dlm);
- if (!completed) {
- /*
- * If the DL commit raced with the frame end interrupt, the
- * commit ends up being postponed by one frame. Return
- * immediately without calling the pipeline's frame end handler
- * or incrementing the sequence number.
- */
- return;
- }
if (pipe->hgo)
vsp1_hgo_frame_end(pipe->hgo);
@@ -352,8 +348,12 @@ void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
if (pipe->hgt)
vsp1_hgt_frame_end(pipe->hgt);
+ /*
+ * Regardless of frame completion we still need to notify the pipe
+ * frame_end to account for vblank events.
+ */
if (pipe->frame_end)
- pipe->frame_end(pipe);
+ pipe->frame_end(pipe, completed);
pipe->sequence++;
}
@@ -373,10 +373,11 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
return;
/*
- * The BRU background color has a fixed alpha value set to 255, the
- * output alpha value is thus always equal to 255.
+ * The BRU and BRS background color has a fixed alpha value set to 255,
+ * the output alpha value is thus always equal to 255.
*/
- if (pipe->uds_input->type == VSP1_ENTITY_BRU)
+ if (pipe->uds_input->type == VSP1_ENTITY_BRU ||
+ pipe->uds_input->type == VSP1_ENTITY_BRS)
alpha = 255;
vsp1_uds_set_alpha(pipe->uds, dl, alpha);
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h
index 91a784a13422..c5d01a365370 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.h
+++ b/drivers/media/platform/vsp1/vsp1_pipe.h
@@ -91,7 +91,7 @@ struct vsp1_pipeline {
enum vsp1_pipeline_state state;
wait_queue_head_t wq;
- void (*frame_end)(struct vsp1_pipeline *pipe);
+ void (*frame_end)(struct vsp1_pipeline *pipe, bool completed);
struct mutex lock;
struct kref kref;
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index cd3e32af6e3b..58d0bea963a6 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -18,6 +18,7 @@
*/
#define VI6_CMD(n) (0x0000 + (n) * 4)
+#define VI6_CMD_UPDHDR (1 << 4)
#define VI6_CMD_STRCMD (1 << 0)
#define VI6_CLK_DCSWT 0x0018
@@ -238,6 +239,10 @@
#define VI6_WPF_SRCRPF_VIRACT_SUB (1 << 28)
#define VI6_WPF_SRCRPF_VIRACT_MST (2 << 28)
#define VI6_WPF_SRCRPF_VIRACT_MASK (3 << 28)
+#define VI6_WPF_SRCRPF_VIRACT2_DIS (0 << 24)
+#define VI6_WPF_SRCRPF_VIRACT2_SUB (1 << 24)
+#define VI6_WPF_SRCRPF_VIRACT2_MST (2 << 24)
+#define VI6_WPF_SRCRPF_VIRACT2_MASK (3 << 24)
#define VI6_WPF_SRCRPF_RPF_ACT_DIS(n) (0 << ((n) * 2))
#define VI6_WPF_SRCRPF_RPF_ACT_SUB(n) (1 << ((n) * 2))
#define VI6_WPF_SRCRPF_RPF_ACT_MST(n) (2 << ((n) * 2))
@@ -321,6 +326,8 @@
#define VI6_DPR_HST_ROUTE 0x2044
#define VI6_DPR_HSI_ROUTE 0x2048
#define VI6_DPR_BRU_ROUTE 0x204c
+#define VI6_DPR_ILV_BRS_ROUTE 0x2050
+#define VI6_DPR_ROUTE_BRSSEL (1 << 28)
#define VI6_DPR_ROUTE_FXA_MASK (0xff << 16)
#define VI6_DPR_ROUTE_FXA_SHIFT 16
#define VI6_DPR_ROUTE_FP_MASK (0x3f << 8)
@@ -344,7 +351,8 @@
#define VI6_DPR_NODE_CLU 29
#define VI6_DPR_NODE_HST 30
#define VI6_DPR_NODE_HSI 31
-#define VI6_DPR_NODE_LIF 55
+#define VI6_DPR_NODE_BRS_IN(n) (38 + (n))
+#define VI6_DPR_NODE_LIF 55 /* Gen2 only */
#define VI6_DPR_NODE_WPF(n) (56 + (n))
#define VI6_DPR_NODE_UNUSED 63
@@ -476,7 +484,7 @@
#define VI6_HSI_CTRL_EN (1 << 0)
/* -----------------------------------------------------------------------------
- * BRU Control Registers
+ * BRS and BRU Control Registers
*/
#define VI6_ROP_NOP 0
@@ -496,7 +504,10 @@
#define VI6_ROP_NAND 14
#define VI6_ROP_SET 15
-#define VI6_BRU_INCTRL 0x2c00
+#define VI6_BRU_BASE 0x2c00
+#define VI6_BRS_BASE 0x3900
+
+#define VI6_BRU_INCTRL 0x0000
#define VI6_BRU_INCTRL_NRM (1 << 28)
#define VI6_BRU_INCTRL_DnON (1 << (16 + (n)))
#define VI6_BRU_INCTRL_DITHn_OFF (0 << ((n) * 4))
@@ -508,19 +519,19 @@
#define VI6_BRU_INCTRL_DITHn_MASK (7 << ((n) * 4))
#define VI6_BRU_INCTRL_DITHn_SHIFT ((n) * 4)
-#define VI6_BRU_VIRRPF_SIZE 0x2c04
+#define VI6_BRU_VIRRPF_SIZE 0x0004
#define VI6_BRU_VIRRPF_SIZE_HSIZE_MASK (0x1fff << 16)
#define VI6_BRU_VIRRPF_SIZE_HSIZE_SHIFT 16
#define VI6_BRU_VIRRPF_SIZE_VSIZE_MASK (0x1fff << 0)
#define VI6_BRU_VIRRPF_SIZE_VSIZE_SHIFT 0
-#define VI6_BRU_VIRRPF_LOC 0x2c08
+#define VI6_BRU_VIRRPF_LOC 0x0008
#define VI6_BRU_VIRRPF_LOC_HCOORD_MASK (0x1fff << 16)
#define VI6_BRU_VIRRPF_LOC_HCOORD_SHIFT 16
#define VI6_BRU_VIRRPF_LOC_VCOORD_MASK (0x1fff << 0)
#define VI6_BRU_VIRRPF_LOC_VCOORD_SHIFT 0
-#define VI6_BRU_VIRRPF_COL 0x2c0c
+#define VI6_BRU_VIRRPF_COL 0x000c
#define VI6_BRU_VIRRPF_COL_A_MASK (0xff << 24)
#define VI6_BRU_VIRRPF_COL_A_SHIFT 24
#define VI6_BRU_VIRRPF_COL_RCR_MASK (0xff << 16)
@@ -530,7 +541,7 @@
#define VI6_BRU_VIRRPF_COL_BCB_MASK (0xff << 0)
#define VI6_BRU_VIRRPF_COL_BCB_SHIFT 0
-#define VI6_BRU_CTRL(n) (0x2c10 + (n) * 8 + ((n) <= 3 ? 0 : 4))
+#define VI6_BRU_CTRL(n) (0x0010 + (n) * 8 + ((n) <= 3 ? 0 : 4))
#define VI6_BRU_CTRL_RBC (1 << 31)
#define VI6_BRU_CTRL_DSTSEL_BRUIN(n) (((n) <= 3 ? (n) : (n)+1) << 20)
#define VI6_BRU_CTRL_DSTSEL_VRPF (4 << 20)
@@ -543,7 +554,7 @@
#define VI6_BRU_CTRL_AROP(rop) ((rop) << 0)
#define VI6_BRU_CTRL_AROP_MASK (0xf << 0)
-#define VI6_BRU_BLD(n) (0x2c14 + (n) * 8 + ((n) <= 3 ? 0 : 4))
+#define VI6_BRU_BLD(n) (0x0014 + (n) * 8 + ((n) <= 3 ? 0 : 4))
#define VI6_BRU_BLD_CBES (1 << 31)
#define VI6_BRU_BLD_CCMDX_DST_A (0 << 28)
#define VI6_BRU_BLD_CCMDX_255_DST_A (1 << 28)
@@ -576,7 +587,7 @@
#define VI6_BRU_BLD_COEFY_MASK (0xff << 0)
#define VI6_BRU_BLD_COEFY_SHIFT 0
-#define VI6_BRU_ROP 0x2c30
+#define VI6_BRU_ROP 0x0030 /* Only available on BRU */
#define VI6_BRU_ROP_DSTSEL_BRUIN(n) (((n) <= 3 ? (n) : (n)+1) << 20)
#define VI6_BRU_ROP_DSTSEL_VRPF (4 << 20)
#define VI6_BRU_ROP_DSTSEL_MASK (7 << 20)
@@ -653,6 +664,8 @@
* LIF Control Registers
*/
+#define VI6_LIF_OFFSET (-0x100)
+
#define VI6_LIF_CTRL 0x3b00
#define VI6_LIF_CTRL_OBTH_MASK (0x7ff << 16)
#define VI6_LIF_CTRL_OBTH_SHIFT 16
@@ -689,9 +702,20 @@
#define VI6_IP_VERSION_MODEL_VSPBD_GEN3 (0x15 << 8)
#define VI6_IP_VERSION_MODEL_VSPBC_GEN3 (0x16 << 8)
#define VI6_IP_VERSION_MODEL_VSPD_GEN3 (0x17 << 8)
+#define VI6_IP_VERSION_MODEL_VSPD_V3 (0x18 << 8)
+#define VI6_IP_VERSION_MODEL_VSPDL_GEN3 (0x19 << 8)
+#define VI6_IP_VERSION_MODEL_VSPBS_GEN3 (0x1a << 8)
#define VI6_IP_VERSION_SOC_MASK (0xff << 0)
-#define VI6_IP_VERSION_SOC_H (0x01 << 0)
-#define VI6_IP_VERSION_SOC_M (0x02 << 0)
+#define VI6_IP_VERSION_SOC_H2 (0x01 << 0)
+#define VI6_IP_VERSION_SOC_V2H (0x01 << 0)
+#define VI6_IP_VERSION_SOC_V3M (0x01 << 0)
+#define VI6_IP_VERSION_SOC_M2 (0x02 << 0)
+#define VI6_IP_VERSION_SOC_M3W (0x02 << 0)
+#define VI6_IP_VERSION_SOC_V3H (0x02 << 0)
+#define VI6_IP_VERSION_SOC_H3 (0x03 << 0)
+#define VI6_IP_VERSION_SOC_D3 (0x04 << 0)
+#define VI6_IP_VERSION_SOC_M3N (0x04 << 0)
+#define VI6_IP_VERSION_SOC_E3 (0x04 << 0)
/* -----------------------------------------------------------------------------
* RPF CLUT Registers
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 5af3486afe07..e9f5dcb8fae5 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -440,13 +440,17 @@ static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe)
vsp1_pipeline_run(pipe);
}
-static void vsp1_video_pipeline_frame_end(struct vsp1_pipeline *pipe)
+static void vsp1_video_pipeline_frame_end(struct vsp1_pipeline *pipe,
+ bool completed)
{
struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
enum vsp1_pipeline_state state;
unsigned long flags;
unsigned int i;
+ /* M2M Pipelines should never call here with an incomplete frame. */
+ WARN_ON_ONCE(!completed);
+
spin_lock_irqsave(&pipe->irqlock, flags);
/* Complete buffers on all video nodes. */
@@ -481,7 +485,7 @@ static int vsp1_video_pipeline_build_branch(struct vsp1_pipeline *pipe,
struct media_entity_enum ent_enum;
struct vsp1_entity *entity;
struct media_pad *pad;
- bool bru_found = false;
+ struct vsp1_bru *bru = NULL;
int ret;
ret = media_entity_enum_init(&ent_enum, &input->entity.vsp1->media_dev);
@@ -511,16 +515,20 @@ static int vsp1_video_pipeline_build_branch(struct vsp1_pipeline *pipe,
media_entity_to_v4l2_subdev(pad->entity));
/*
- * A BRU is present in the pipeline, store the BRU input pad
+ * A BRU or BRS is present in the pipeline, store its input pad
* number in the input RPF for use when configuring the RPF.
*/
- if (entity->type == VSP1_ENTITY_BRU) {
- struct vsp1_bru *bru = to_bru(&entity->subdev);
+ if (entity->type == VSP1_ENTITY_BRU ||
+ entity->type == VSP1_ENTITY_BRS) {
+ /* BRU and BRS can't be chained. */
+ if (bru) {
+ ret = -EPIPE;
+ goto out;
+ }
+ bru = to_bru(&entity->subdev);
bru->inputs[pad->index].rpf = input;
input->bru_input = pad->index;
-
- bru_found = true;
}
/* We've reached the WPF, we're done. */
@@ -542,8 +550,7 @@ static int vsp1_video_pipeline_build_branch(struct vsp1_pipeline *pipe,
}
pipe->uds = entity;
- pipe->uds_input = bru_found ? pipe->bru
- : &input->entity;
+ pipe->uds_input = bru ? &bru->entity : &input->entity;
}
/* Follow the source link, ignoring any HGO or HGT. */
@@ -589,30 +596,42 @@ static int vsp1_video_pipeline_build(struct vsp1_pipeline *pipe,
e = to_vsp1_entity(subdev);
list_add_tail(&e->list_pipe, &pipe->entities);
- if (e->type == VSP1_ENTITY_RPF) {
+ switch (e->type) {
+ case VSP1_ENTITY_RPF:
rwpf = to_rwpf(subdev);
pipe->inputs[rwpf->entity.index] = rwpf;
rwpf->video->pipe_index = ++pipe->num_inputs;
rwpf->pipe = pipe;
- } else if (e->type == VSP1_ENTITY_WPF) {
+ break;
+
+ case VSP1_ENTITY_WPF:
rwpf = to_rwpf(subdev);
pipe->output = rwpf;
rwpf->video->pipe_index = 0;
rwpf->pipe = pipe;
- } else if (e->type == VSP1_ENTITY_LIF) {
+ break;
+
+ case VSP1_ENTITY_LIF:
pipe->lif = e;
- } else if (e->type == VSP1_ENTITY_BRU) {
+ break;
+
+ case VSP1_ENTITY_BRU:
+ case VSP1_ENTITY_BRS:
pipe->bru = e;
- } else if (e->type == VSP1_ENTITY_HGO) {
- struct vsp1_hgo *hgo = to_hgo(subdev);
+ break;
+ case VSP1_ENTITY_HGO:
pipe->hgo = e;
- hgo->histo.pipe = pipe;
- } else if (e->type == VSP1_ENTITY_HGT) {
- struct vsp1_hgt *hgt = to_hgt(subdev);
+ to_hgo(subdev)->histo.pipe = pipe;
+ break;
+ case VSP1_ENTITY_HGT:
pipe->hgt = e;
- hgt->histo.pipe = pipe;
+ to_hgt(subdev)->histo.pipe = pipe;
+ break;
+
+ default:
+ break;
}
}
@@ -796,12 +815,14 @@ static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe)
struct vsp1_uds *uds = to_uds(&pipe->uds->subdev);
/*
- * If a BRU is present in the pipeline before the UDS, the alpha
- * component doesn't need to be scaled as the BRU output alpha
- * value is fixed to 255. Otherwise we need to scale the alpha
- * component only when available at the input RPF.
+ * If a BRU or BRS is present in the pipeline before the UDS,
+ * the alpha component doesn't need to be scaled as the BRU and
+ * BRS output alpha value is fixed to 255. Otherwise we need to
+ * scale the alpha component only when available at the input
+ * RPF.
*/
- if (pipe->uds_input->type == VSP1_ENTITY_BRU) {
+ if (pipe->uds_input->type == VSP1_ENTITY_BRU ||
+ pipe->uds_input->type == VSP1_ENTITY_BRS) {
uds->scale_alpha = false;
} else {
struct vsp1_rwpf *rpf =
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 32df109b119f..b6c902be225b 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -453,7 +453,9 @@ static void wpf_configure(struct vsp1_entity *entity,
}
if (pipe->bru || pipe->num_inputs > 1)
- srcrpf |= VI6_WPF_SRCRPF_VIRACT_MST;
+ srcrpf |= pipe->bru->type == VSP1_ENTITY_BRU
+ ? VI6_WPF_SRCRPF_VIRACT_MST
+ : VI6_WPF_SRCRPF_VIRACT2_MST;
vsp1_wpf_write(wpf, dl, VI6_WPF_SRCRPF, srcrpf);
diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c
index 7240223dc15a..17e82a9a0109 100644
--- a/drivers/media/radio/radio-wl1273.c
+++ b/drivers/media/radio/radio-wl1273.c
@@ -610,10 +610,21 @@ static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
}
}
- if (radio->rds_on)
+ if (radio->rds_on) {
r = core->write(core, WL1273_RDS_DATA_ENB, 1);
- else
+ if (r) {
+ dev_err(dev, "%s: RDS_DATA_ENB ON fails\n",
+ __func__);
+ goto fail;
+ }
+ } else {
r = core->write(core, WL1273_RDS_DATA_ENB, 0);
+ if (r) {
+ dev_err(dev, "%s: RDS_DATA_ENB OFF fails\n",
+ __func__);
+ goto fail;
+ }
+ }
} else {
dev_warn(dev, "%s: Illegal mode.\n", __func__);
}
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index a30af91710fe..d2223c04e9ad 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -266,7 +266,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
if (!dev->rx_resolution)
return -ENOTTY;
- val = dev->rx_resolution;
+ val = dev->rx_resolution / 1000;
break;
case LIRC_SET_WIDEBAND_RECEIVER:
diff --git a/drivers/media/tuners/fc0011.c b/drivers/media/tuners/fc0011.c
index 192b1c7740df..145407dee3db 100644
--- a/drivers/media/tuners/fc0011.c
+++ b/drivers/media/tuners/fc0011.c
@@ -342,6 +342,7 @@ static int fc0011_set_params(struct dvb_frontend *fe)
switch (vco_sel) {
default:
WARN_ON(1);
+ return -EINVAL;
case 0:
if (vco_cal < 8) {
regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
diff --git a/drivers/media/tuners/mxl5005s.c b/drivers/media/tuners/mxl5005s.c
index 353744fee053..dd59c2c0e4a5 100644
--- a/drivers/media/tuners/mxl5005s.c
+++ b/drivers/media/tuners/mxl5005s.c
@@ -2737,8 +2737,6 @@ static u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq)
status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x0);
status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x7);
divider_val = 2 ;
- Fmax = FmaxBin ;
- Fmin = FminBin ;
}
/* TG_DIV_VAL */
diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c
index 9ec919c68482..9d82ec0a4b64 100644
--- a/drivers/media/usb/au0828/au0828-input.c
+++ b/drivers/media/usb/au0828/au0828-input.c
@@ -351,7 +351,7 @@ int au0828_rc_register(struct au0828_dev *dev)
if (err)
goto error;
- pr_info("Remote controller %s initalized\n", ir->name);
+ pr_info("Remote controller %s initialized\n", ir->name);
return 0;
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c
index 594360a63c18..a91fdad8f8d4 100644
--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
@@ -207,15 +207,13 @@ static int lme2510_stream_restart(struct dvb_usb_device *d)
struct lme2510_state *st = d->priv;
u8 all_pids[] = LME_ALL_PIDS;
u8 stream_on[] = LME_ST_ON_W;
- int ret;
u8 rbuff[1];
if (st->pid_off)
- ret = lme2510_usb_talk(d, all_pids, sizeof(all_pids),
- rbuff, sizeof(rbuff));
+ lme2510_usb_talk(d, all_pids, sizeof(all_pids),
+ rbuff, sizeof(rbuff));
/*Restart Stream Command*/
- ret = lme2510_usb_talk(d, stream_on, sizeof(stream_on),
- rbuff, sizeof(rbuff));
- return ret;
+ return lme2510_usb_talk(d, stream_on, sizeof(stream_on),
+ rbuff, sizeof(rbuff));
}
static int lme2510_enable_pid(struct dvb_usb_device *d, u8 index, u16 pid_out)
diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c
index 08acdd32e412..bea1b4764a66 100644
--- a/drivers/media/usb/dvb-usb/dib0700_core.c
+++ b/drivers/media/usb/dvb-usb/dib0700_core.c
@@ -215,13 +215,14 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
USB_CTRL_GET_TIMEOUT);
if (result < 0) {
deb_info("i2c read error (status = %d)\n", result);
- break;
+ goto unlock;
}
if (msg[i].len > sizeof(st->buf)) {
deb_info("buffer too small to fit %d bytes\n",
msg[i].len);
- return -EIO;
+ result = -EIO;
+ goto unlock;
}
memcpy(msg[i].buf, st->buf, msg[i].len);
@@ -233,8 +234,8 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
/* Write request */
if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
err("could not acquire lock");
- mutex_unlock(&d->i2c_mutex);
- return -EINTR;
+ result = -EINTR;
+ goto unlock;
}
st->buf[0] = REQUEST_NEW_I2C_WRITE;
st->buf[1] = msg[i].addr << 1;
@@ -247,7 +248,9 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
if (msg[i].len > sizeof(st->buf) - 4) {
deb_info("i2c message to big: %d\n",
msg[i].len);
- return -EIO;
+ mutex_unlock(&d->usb_mutex);
+ result = -EIO;
+ goto unlock;
}
/* The Actual i2c payload */
@@ -269,8 +272,11 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
}
}
}
+ result = i;
+
+unlock:
mutex_unlock(&d->i2c_mutex);
- return i;
+ return result;
}
/*
@@ -281,7 +287,7 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
{
struct dvb_usb_device *d = i2c_get_adapdata(adap);
struct dib0700_state *st = d->priv;
- int i,len;
+ int i, len, result;
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EINTR;
@@ -298,7 +304,8 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
if (msg[i].len > sizeof(st->buf) - 2) {
deb_info("i2c xfer to big: %d\n",
msg[i].len);
- return -EIO;
+ result = -EIO;
+ goto unlock;
}
memcpy(&st->buf[2], msg[i].buf, msg[i].len);
@@ -313,13 +320,15 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
if (len <= 0) {
deb_info("I2C read failed on address 0x%02x\n",
msg[i].addr);
- break;
+ result = -EIO;
+ goto unlock;
}
if (msg[i + 1].len > sizeof(st->buf)) {
deb_info("i2c xfer buffer to small for %d\n",
msg[i].len);
- return -EIO;
+ result = -EIO;
+ goto unlock;
}
memcpy(msg[i + 1].buf, st->buf, msg[i + 1].len);
@@ -328,14 +337,17 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
i++;
} else {
st->buf[0] = REQUEST_I2C_WRITE;
- if (dib0700_ctrl_wr(d, st->buf, msg[i].len + 2) < 0)
- break;
+ result = dib0700_ctrl_wr(d, st->buf, msg[i].len + 2);
+ if (result < 0)
+ goto unlock;
}
}
+ result = i;
+unlock:
mutex_unlock(&d->usb_mutex);
mutex_unlock(&d->i2c_mutex);
- return i;
+ return result;
}
static int dib0700_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index 146341aeb782..4c57fd7929cb 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -1193,6 +1193,22 @@ struct em28xx_board em28xx_boards[] = {
.i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE |
EM28XX_I2C_FREQ_400_KHZ,
},
+ [EM2884_BOARD_TERRATEC_H6] = {
+ .name = "Terratec Cinergy H6 rev. 2",
+ .has_dvb = 1,
+ .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS,
+#if 0
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .tuner_addr = 0x41,
+ .dvb_gpio = terratec_h5_digital, /* FIXME: probably wrong */
+ .tuner_gpio = terratec_h5_gpio,
+#else
+ .tuner_type = TUNER_ABSENT,
+#endif
+ .def_i2c_bus = 1,
+ .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE |
+ EM28XX_I2C_FREQ_400_KHZ,
+ },
[EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C] = {
.name = "Hauppauge WinTV HVR 930C",
.has_dvb = 1,
@@ -2496,6 +2512,8 @@ struct usb_device_id em28xx_id_table[] = {
.driver_info = EM2884_BOARD_TERRATEC_H5 },
{ USB_DEVICE(0x0ccd, 0x10b6), /* H5 Rev. 3 */
.driver_info = EM2884_BOARD_TERRATEC_H5 },
+ { USB_DEVICE(0x0ccd, 0x10b2), /* H6 */
+ .driver_info = EM2884_BOARD_TERRATEC_H6 },
{ USB_DEVICE(0x0ccd, 0x0084),
.driver_info = EM2860_BOARD_TERRATEC_AV350 },
{ USB_DEVICE(0x0ccd, 0x0096),
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index 82edd37f0d73..4a7db623fe29 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -1522,6 +1522,7 @@ static int em28xx_dvb_init(struct em28xx *dev)
break;
case EM2884_BOARD_ELGATO_EYETV_HYBRID_2008:
case EM2884_BOARD_CINERGY_HTC_STICK:
+ case EM2884_BOARD_TERRATEC_H6:
terratec_htc_stick_init(dev);
/* attach demodulator */
diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c
index 8c472d5adb50..60b195c157b8 100644
--- a/drivers/media/usb/em28xx/em28xx-i2c.c
+++ b/drivers/media/usb/em28xx/em28xx-i2c.c
@@ -982,8 +982,6 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus,
dev_err(&dev->intf->dev,
"%s: em28xx_i2_eeprom failed! retval [%d]\n",
__func__, retval);
-
- return retval;
}
}
diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c
index eba75736e654..ca9673917ad5 100644
--- a/drivers/media/usb/em28xx/em28xx-input.c
+++ b/drivers/media/usb/em28xx/em28xx-input.c
@@ -821,7 +821,7 @@ static int em28xx_ir_init(struct em28xx *dev)
if (err)
goto error;
- dev_info(&dev->intf->dev, "Input extension successfully initalized\n");
+ dev_info(&dev->intf->dev, "Input extension successfully initialized\n");
return 0;
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index e8d97d5ec161..88084f24f033 100644
--- a/drivers/media/usb/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
@@ -148,6 +148,7 @@
#define EM28178_BOARD_PLEX_PX_BCUD 98
#define EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB 99
#define EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595 100
+#define EM2884_BOARD_TERRATEC_H6 101
/* Limits minimum and default number of buffers */
#define EM28XX_MIN_BUF 4
diff --git a/drivers/media/usb/pulse8-cec/pulse8-cec.c b/drivers/media/usb/pulse8-cec/pulse8-cec.c
index c843070f24c1..f9ed9c950247 100644
--- a/drivers/media/usb/pulse8-cec/pulse8-cec.c
+++ b/drivers/media/usb/pulse8-cec/pulse8-cec.c
@@ -51,7 +51,7 @@ MODULE_DESCRIPTION("Pulse Eight HDMI CEC driver");
MODULE_LICENSE("GPL");
static int debug;
-static int persistent_config = 1;
+static int persistent_config;
module_param(debug, int, 0644);
module_param(persistent_config, int, 0644);
MODULE_PARM_DESC(debug, "debug level (0-1)");
diff --git a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c
index f203699e9c1b..65692576690f 100644
--- a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c
+++ b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c
@@ -116,21 +116,19 @@ static void rain_irq_work_handler(struct work_struct *work)
while (true) {
unsigned long flags;
- bool exit_loop = false;
char data;
spin_lock_irqsave(&rain->buf_lock, flags);
- if (rain->buf_len) {
- data = rain->buf[rain->buf_rd_idx];
- rain->buf_len--;
- rain->buf_rd_idx = (rain->buf_rd_idx + 1) & 0xff;
- } else {
- exit_loop = true;
+ if (!rain->buf_len) {
+ spin_unlock_irqrestore(&rain->buf_lock, flags);
+ break;
}
- spin_unlock_irqrestore(&rain->buf_lock, flags);
- if (exit_loop)
- break;
+ data = rain->buf[rain->buf_rd_idx];
+ rain->buf_len--;
+ rain->buf_rd_idx = (rain->buf_rd_idx + 1) & 0xff;
+
+ spin_unlock_irqrestore(&rain->buf_lock, flags);
if (!rain->cmd_started && data != '?')
continue;
diff --git a/drivers/media/usb/stkwebcam/stk-sensor.c b/drivers/media/usb/stkwebcam/stk-sensor.c
index 985af9933c7e..c1d4505f84ea 100644
--- a/drivers/media/usb/stkwebcam/stk-sensor.c
+++ b/drivers/media/usb/stkwebcam/stk-sensor.c
@@ -41,6 +41,8 @@
/* It seems the i2c bus is controlled with these registers */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include "stk-webcam.h"
#define STK_IIC_BASE (0x0200)
@@ -239,8 +241,8 @@ static int stk_sensor_outb(struct stk_camera *dev, u8 reg, u8 val)
} while (tmpval == 0 && i < MAX_RETRIES);
if (tmpval != STK_IIC_STAT_TX_OK) {
if (tmpval)
- STK_ERROR("stk_sensor_outb failed, status=0x%02x\n",
- tmpval);
+ pr_err("stk_sensor_outb failed, status=0x%02x\n",
+ tmpval);
return 1;
} else
return 0;
@@ -262,8 +264,8 @@ static int stk_sensor_inb(struct stk_camera *dev, u8 reg, u8 *val)
} while (tmpval == 0 && i < MAX_RETRIES);
if (tmpval != STK_IIC_STAT_RX_OK) {
if (tmpval)
- STK_ERROR("stk_sensor_inb failed, status=0x%02x\n",
- tmpval);
+ pr_err("stk_sensor_inb failed, status=0x%02x\n",
+ tmpval);
return 1;
}
@@ -366,29 +368,29 @@ int stk_sensor_init(struct stk_camera *dev)
if (stk_camera_write_reg(dev, STK_IIC_ENABLE, STK_IIC_ENABLE_YES)
|| stk_camera_write_reg(dev, STK_IIC_ADDR, SENSOR_ADDRESS)
|| stk_sensor_outb(dev, REG_COM7, COM7_RESET)) {
- STK_ERROR("Sensor resetting failed\n");
+ pr_err("Sensor resetting failed\n");
return -ENODEV;
}
msleep(10);
/* Read the manufacturer ID: ov = 0x7FA2 */
if (stk_sensor_inb(dev, REG_MIDH, &idh)
|| stk_sensor_inb(dev, REG_MIDL, &idl)) {
- STK_ERROR("Strange error reading sensor ID\n");
+ pr_err("Strange error reading sensor ID\n");
return -ENODEV;
}
if (idh != 0x7f || idl != 0xa2) {
- STK_ERROR("Huh? you don't have a sensor from ovt\n");
+ pr_err("Huh? you don't have a sensor from ovt\n");
return -ENODEV;
}
if (stk_sensor_inb(dev, REG_PID, &idh)
|| stk_sensor_inb(dev, REG_VER, &idl)) {
- STK_ERROR("Could not read sensor model\n");
+ pr_err("Could not read sensor model\n");
return -ENODEV;
}
stk_sensor_write_regvals(dev, ov_initvals);
msleep(10);
- STK_INFO("OmniVision sensor detected, id %02X%02X at address %x\n",
- idh, idl, SENSOR_ADDRESS);
+ pr_info("OmniVision sensor detected, id %02X%02X at address %x\n",
+ idh, idl, SENSOR_ADDRESS);
return 0;
}
@@ -520,7 +522,8 @@ int stk_sensor_configure(struct stk_camera *dev)
case MODE_SXGA: com7 = COM7_FMT_SXGA;
dummylines = 0;
break;
- default: STK_ERROR("Unsupported mode %d\n", dev->vsettings.mode);
+ default:
+ pr_err("Unsupported mode %d\n", dev->vsettings.mode);
return -EFAULT;
}
switch (dev->vsettings.palette) {
@@ -544,7 +547,8 @@ int stk_sensor_configure(struct stk_camera *dev)
com7 |= COM7_PBAYER;
rv = ov_fmt_bayer;
break;
- default: STK_ERROR("Unsupported colorspace\n");
+ default:
+ pr_err("Unsupported colorspace\n");
return -EFAULT;
}
/*FIXME sometimes the sensor go to a bad state
@@ -564,7 +568,7 @@ int stk_sensor_configure(struct stk_camera *dev)
switch (dev->vsettings.mode) {
case MODE_VGA:
if (stk_sensor_set_hw(dev, 302, 1582, 6, 486))
- STK_ERROR("stk_sensor_set_hw failed (VGA)\n");
+ pr_err("stk_sensor_set_hw failed (VGA)\n");
break;
case MODE_SXGA:
case MODE_CIF:
@@ -572,7 +576,7 @@ int stk_sensor_configure(struct stk_camera *dev)
case MODE_QCIF:
/*FIXME These settings seem ignored by the sensor
if (stk_sensor_set_hw(dev, 220, 1500, 10, 1034))
- STK_ERROR("stk_sensor_set_hw failed (SXGA)\n");
+ pr_err("stk_sensor_set_hw failed (SXGA)\n");
*/
break;
}
diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c
index 6e7fc36b658f..90d4a08cda31 100644
--- a/drivers/media/usb/stkwebcam/stk-webcam.c
+++ b/drivers/media/usb/stkwebcam/stk-webcam.c
@@ -18,6 +18,8 @@
* GNU General Public License for more details.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -175,15 +177,15 @@ static int stk_start_stream(struct stk_camera *dev)
if (!is_present(dev))
return -ENODEV;
if (!is_memallocd(dev) || !is_initialised(dev)) {
- STK_ERROR("FIXME: Buffers are not allocated\n");
+ pr_err("FIXME: Buffers are not allocated\n");
return -EFAULT;
}
ret = usb_set_interface(dev->udev, 0, 5);
if (ret < 0)
- STK_ERROR("usb_set_interface failed !\n");
+ pr_err("usb_set_interface failed !\n");
if (stk_sensor_wakeup(dev))
- STK_ERROR("error awaking the sensor\n");
+ pr_err("error awaking the sensor\n");
stk_camera_read_reg(dev, 0x0116, &value_116);
stk_camera_read_reg(dev, 0x0117, &value_117);
@@ -224,9 +226,9 @@ static int stk_stop_stream(struct stk_camera *dev)
unset_streaming(dev);
if (usb_set_interface(dev->udev, 0, 0))
- STK_ERROR("usb_set_interface failed !\n");
+ pr_err("usb_set_interface failed !\n");
if (stk_sensor_sleep(dev))
- STK_ERROR("error suspending the sensor\n");
+ pr_err("error suspending the sensor\n");
}
return 0;
}
@@ -313,7 +315,7 @@ static void stk_isoc_handler(struct urb *urb)
dev = (struct stk_camera *) urb->context;
if (dev == NULL) {
- STK_ERROR("isoc_handler called with NULL device !\n");
+ pr_err("isoc_handler called with NULL device !\n");
return;
}
@@ -326,14 +328,13 @@ static void stk_isoc_handler(struct urb *urb)
spin_lock_irqsave(&dev->spinlock, flags);
if (urb->status != -EINPROGRESS && urb->status != 0) {
- STK_ERROR("isoc_handler: urb->status == %d\n", urb->status);
+ pr_err("isoc_handler: urb->status == %d\n", urb->status);
goto resubmit;
}
if (list_empty(&dev->sio_avail)) {
/*FIXME Stop streaming after a while */
- (void) (printk_ratelimit() &&
- STK_ERROR("isoc_handler without available buffer!\n"));
+ pr_err_ratelimited("isoc_handler without available buffer!\n");
goto resubmit;
}
fb = list_first_entry(&dev->sio_avail,
@@ -343,8 +344,8 @@ static void stk_isoc_handler(struct urb *urb)
for (i = 0; i < urb->number_of_packets; i++) {
if (urb->iso_frame_desc[i].status != 0) {
if (urb->iso_frame_desc[i].status != -EXDEV)
- STK_ERROR("Frame %d has error %d\n", i,
- urb->iso_frame_desc[i].status);
+ pr_err("Frame %d has error %d\n",
+ i, urb->iso_frame_desc[i].status);
continue;
}
framelen = urb->iso_frame_desc[i].actual_length;
@@ -368,9 +369,8 @@ static void stk_isoc_handler(struct urb *urb)
/* This marks a new frame */
if (fb->v4lbuf.bytesused != 0
&& fb->v4lbuf.bytesused != dev->frame_size) {
- (void) (printk_ratelimit() &&
- STK_ERROR("frame %d, bytesused=%d, skipping\n",
- i, fb->v4lbuf.bytesused));
+ pr_err_ratelimited("frame %d, bytesused=%d, skipping\n",
+ i, fb->v4lbuf.bytesused);
fb->v4lbuf.bytesused = 0;
fill = fb->buffer;
} else if (fb->v4lbuf.bytesused == dev->frame_size) {
@@ -395,8 +395,7 @@ static void stk_isoc_handler(struct urb *urb)
/* Our buffer is full !!! */
if (framelen + fb->v4lbuf.bytesused > dev->frame_size) {
- (void) (printk_ratelimit() &&
- STK_ERROR("Frame buffer overflow, lost sync\n"));
+ pr_err_ratelimited("Frame buffer overflow, lost sync\n");
/*FIXME Do something here? */
continue;
}
@@ -414,8 +413,8 @@ resubmit:
urb->dev = dev->udev;
ret = usb_submit_urb(urb, GFP_ATOMIC);
if (ret != 0) {
- STK_ERROR("Error (%d) re-submitting urb in stk_isoc_handler.\n",
- ret);
+ pr_err("Error (%d) re-submitting urb in stk_isoc_handler\n",
+ ret);
}
}
@@ -433,32 +432,31 @@ static int stk_prepare_iso(struct stk_camera *dev)
udev = dev->udev;
if (dev->isobufs)
- STK_ERROR("isobufs already allocated. Bad\n");
+ pr_err("isobufs already allocated. Bad\n");
else
dev->isobufs = kcalloc(MAX_ISO_BUFS, sizeof(*dev->isobufs),
GFP_KERNEL);
if (dev->isobufs == NULL) {
- STK_ERROR("Unable to allocate iso buffers\n");
+ pr_err("Unable to allocate iso buffers\n");
return -ENOMEM;
}
for (i = 0; i < MAX_ISO_BUFS; i++) {
if (dev->isobufs[i].data == NULL) {
kbuf = kzalloc(ISO_BUFFER_SIZE, GFP_KERNEL);
if (kbuf == NULL) {
- STK_ERROR("Failed to allocate iso buffer %d\n",
- i);
+ pr_err("Failed to allocate iso buffer %d\n", i);
goto isobufs_out;
}
dev->isobufs[i].data = kbuf;
} else
- STK_ERROR("isobuf data already allocated\n");
+ pr_err("isobuf data already allocated\n");
if (dev->isobufs[i].urb == NULL) {
urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
if (urb == NULL)
goto isobufs_out;
dev->isobufs[i].urb = urb;
} else {
- STK_ERROR("Killing URB\n");
+ pr_err("Killing URB\n");
usb_kill_urb(dev->isobufs[i].urb);
urb = dev->isobufs[i].urb;
}
@@ -567,7 +565,7 @@ static int stk_prepare_sio_buffers(struct stk_camera *dev, unsigned n_sbufs)
{
int i;
if (dev->sio_bufs != NULL)
- STK_ERROR("sio_bufs already allocated\n");
+ pr_err("sio_bufs already allocated\n");
else {
dev->sio_bufs = kzalloc(n_sbufs * sizeof(struct stk_sio_buffer),
GFP_KERNEL);
@@ -690,7 +688,7 @@ static ssize_t stk_read(struct file *fp, char __user *buf,
spin_lock_irqsave(&dev->spinlock, flags);
if (list_empty(&dev->sio_full)) {
spin_unlock_irqrestore(&dev->spinlock, flags);
- STK_ERROR("BUG: No siobufs ready\n");
+ pr_err("BUG: No siobufs ready\n");
return 0;
}
sbuf = list_first_entry(&dev->sio_full, struct stk_sio_buffer, list);
@@ -907,7 +905,7 @@ static int stk_vidioc_g_fmt_vid_cap(struct file *filp,
stk_sizes[i].m != dev->vsettings.mode; i++)
;
if (i == ARRAY_SIZE(stk_sizes)) {
- STK_ERROR("ERROR: mode invalid\n");
+ pr_err("ERROR: mode invalid\n");
return -EINVAL;
}
pix_format->width = stk_sizes[i].w;
@@ -985,7 +983,7 @@ static int stk_setup_format(struct stk_camera *dev)
stk_sizes[i].m != dev->vsettings.mode)
i++;
if (i == ARRAY_SIZE(stk_sizes)) {
- STK_ERROR("Something is broken in %s\n", __func__);
+ pr_err("Something is broken in %s\n", __func__);
return -EFAULT;
}
/* This registers controls some timings, not sure of what. */
@@ -1241,7 +1239,7 @@ static void stk_v4l_dev_release(struct video_device *vd)
struct stk_camera *dev = vdev_to_camera(vd);
if (dev->sio_bufs != NULL || dev->isobufs != NULL)
- STK_ERROR("We are leaking memory\n");
+ pr_err("We are leaking memory\n");
usb_put_intf(dev->interface);
kfree(dev);
}
@@ -1264,10 +1262,10 @@ static int stk_register_video_device(struct stk_camera *dev)
video_set_drvdata(&dev->vdev, dev);
err = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1);
if (err)
- STK_ERROR("v4l registration failed\n");
+ pr_err("v4l registration failed\n");
else
- STK_INFO("Syntek USB2.0 Camera is now controlling device %s\n",
- video_device_node_name(&dev->vdev));
+ pr_info("Syntek USB2.0 Camera is now controlling device %s\n",
+ video_device_node_name(&dev->vdev));
return err;
}
@@ -1288,7 +1286,7 @@ static int stk_camera_probe(struct usb_interface *interface,
dev = kzalloc(sizeof(struct stk_camera), GFP_KERNEL);
if (dev == NULL) {
- STK_ERROR("Out of memory !\n");
+ pr_err("Out of memory !\n");
return -ENOMEM;
}
err = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
@@ -1352,7 +1350,7 @@ static int stk_camera_probe(struct usb_interface *interface,
}
}
if (!dev->isoc_ep) {
- STK_ERROR("Could not find isoc-in endpoint");
+ pr_err("Could not find isoc-in endpoint\n");
err = -ENODEV;
goto error;
}
@@ -1387,8 +1385,8 @@ static void stk_camera_disconnect(struct usb_interface *interface)
wake_up_interruptible(&dev->wait_frame);
- STK_INFO("Syntek USB2.0 Camera release resources device %s\n",
- video_device_node_name(&dev->vdev));
+ pr_info("Syntek USB2.0 Camera release resources device %s\n",
+ video_device_node_name(&dev->vdev));
video_unregister_device(&dev->vdev);
v4l2_ctrl_handler_free(&dev->hdl);
diff --git a/drivers/media/usb/stkwebcam/stk-webcam.h b/drivers/media/usb/stkwebcam/stk-webcam.h
index 0284120ce246..5cecbdc97573 100644
--- a/drivers/media/usb/stkwebcam/stk-webcam.h
+++ b/drivers/media/usb/stkwebcam/stk-webcam.h
@@ -31,12 +31,6 @@
#define ISO_MAX_FRAME_SIZE 3 * 1024
#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE)
-
-#define PREFIX "stkwebcam: "
-#define STK_INFO(str, args...) printk(KERN_INFO PREFIX str, ##args)
-#define STK_ERROR(str, args...) printk(KERN_ERR PREFIX str, ##args)
-#define STK_WARNING(str, args...) printk(KERN_WARNING PREFIX str, ##args)
-
struct stk_iso_buf {
void *data;
int length;
diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c
index e48b7c032c95..8db45dfc271b 100644
--- a/drivers/media/v4l2-core/tuner-core.c
+++ b/drivers/media/v4l2-core/tuner-core.c
@@ -43,8 +43,6 @@
#define UNSET (-1U)
-#define PREFIX (t->i2c->dev.driver->name)
-
/*
* Driver modprobe parameters
*/
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index 8621a198a2ce..bac33311f55a 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -216,6 +216,12 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata(pdev, dev);
/*
+ * MEI requires to resume from runtime suspend mode
+ * in order to perform link reset flow upon system suspend.
+ */
+ pdev->dev_flags |= PCI_DEV_FLAGS_NEEDS_RESUME;
+
+ /*
* For not wake-able HW runtime pm framework
* can't be used on pci device level.
* Use domain runtime pm callbacks instead.
diff --git a/drivers/misc/mei/pci-txe.c b/drivers/misc/mei/pci-txe.c
index f811cd524468..e38a5f144373 100644
--- a/drivers/misc/mei/pci-txe.c
+++ b/drivers/misc/mei/pci-txe.c
@@ -138,6 +138,12 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata(pdev, dev);
/*
+ * MEI requires to resume from runtime suspend mode
+ * in order to perform link reset flow upon system suspend.
+ */
+ pdev->dev_flags |= PCI_DEV_FLAGS_NEEDS_RESUME;
+
+ /*
* For not wake-able HW runtime pm framework
* can't be used on pci device level.
* Use domain runtime pm callbacks instead.
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 8ac59dc80f23..f1bbfd389367 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -2170,6 +2170,9 @@ static void mmc_blk_remove_req(struct mmc_blk_data *md)
* from being accepted.
*/
card = md->queue.card;
+ spin_lock_irq(md->queue.queue->queue_lock);
+ queue_flag_set(QUEUE_FLAG_BYPASS, md->queue.queue);
+ spin_unlock_irq(md->queue.queue->queue_lock);
blk_set_queue_dying(md->queue.queue);
mmc_cleanup_queue(&md->queue);
if (md->disk->flags & GENHD_FL_UP) {
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 4ffea14b7eb6..2bae69e39544 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1289,7 +1289,7 @@ out_err:
static int mmc_select_hs400es(struct mmc_card *card)
{
struct mmc_host *host = card->host;
- int err = 0;
+ int err = -EINVAL;
u8 val;
if (!(host->caps & MMC_CAP_8_BIT_DATA)) {
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index a9dfb26972f2..250dc6ec4c82 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -2957,7 +2957,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
}
/* find out number of slots supported */
- if (device_property_read_u32(dev, "num-slots", &pdata->num_slots))
+ if (!device_property_read_u32(dev, "num-slots", &pdata->num_slots))
dev_info(dev, "'num-slots' was deprecated.\n");
if (device_property_read_u32(dev, "fifo-depth", &pdata->fifo_depth))
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 7c12f3715676..2ab4788d021f 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -356,9 +356,6 @@ static int omap_hsmmc_set_power(struct omap_hsmmc_host *host, int power_on,
struct mmc_host *mmc = host->mmc;
int ret = 0;
- if (mmc_pdata(host)->set_power)
- return mmc_pdata(host)->set_power(host->dev, power_on, vdd);
-
/*
* If we don't see a Vcc regulator, assume it's a fixed
* voltage always-on regulator.
@@ -366,9 +363,6 @@ static int omap_hsmmc_set_power(struct omap_hsmmc_host *host, int power_on,
if (IS_ERR(mmc->supply.vmmc))
return 0;
- if (mmc_pdata(host)->before_set_reg)
- mmc_pdata(host)->before_set_reg(host->dev, power_on, vdd);
-
ret = omap_hsmmc_set_pbias(host, false, 0);
if (ret)
return ret;
@@ -400,9 +394,6 @@ static int omap_hsmmc_set_power(struct omap_hsmmc_host *host, int power_on,
return ret;
}
- if (mmc_pdata(host)->after_set_reg)
- mmc_pdata(host)->after_set_reg(host->dev, power_on, vdd);
-
return 0;
err_set_voltage:
@@ -469,8 +460,6 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
int ret;
struct mmc_host *mmc = host->mmc;
- if (mmc_pdata(host)->set_power)
- return 0;
ret = mmc_regulator_get_supply(mmc);
if (ret == -EPROBE_DEFER)
@@ -2097,7 +2086,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
mmc->max_seg_size = mmc->max_req_size;
mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
- MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE;
+ MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE | MMC_CAP_CMD23;
mmc->caps |= mmc_pdata(host)->caps;
if (mmc->caps & MMC_CAP_8_BIT_DATA)
diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c
index 7611fd679f1a..1485530c3592 100644
--- a/drivers/mmc/host/sdhci-of-at91.c
+++ b/drivers/mmc/host/sdhci-of-at91.c
@@ -31,6 +31,7 @@
#define SDMMC_MC1R 0x204
#define SDMMC_MC1R_DDR BIT(3)
+#define SDMMC_MC1R_FCD BIT(7)
#define SDMMC_CACR 0x230
#define SDMMC_CACR_CAPWREN BIT(0)
#define SDMMC_CACR_KEY (0x46 << 8)
@@ -43,6 +44,15 @@ struct sdhci_at91_priv {
struct clk *mainck;
};
+static void sdhci_at91_set_force_card_detect(struct sdhci_host *host)
+{
+ u8 mc1r;
+
+ mc1r = readb(host->ioaddr + SDMMC_MC1R);
+ mc1r |= SDMMC_MC1R_FCD;
+ writeb(mc1r, host->ioaddr + SDMMC_MC1R);
+}
+
static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock)
{
u16 clk;
@@ -110,10 +120,18 @@ void sdhci_at91_set_uhs_signaling(struct sdhci_host *host, unsigned int timing)
sdhci_set_uhs_signaling(host, timing);
}
+static void sdhci_at91_reset(struct sdhci_host *host, u8 mask)
+{
+ sdhci_reset(host, mask);
+
+ if (host->mmc->caps & MMC_CAP_NONREMOVABLE)
+ sdhci_at91_set_force_card_detect(host);
+}
+
static const struct sdhci_ops sdhci_at91_sama5d2_ops = {
.set_clock = sdhci_at91_set_clock,
.set_bus_width = sdhci_set_bus_width,
- .reset = sdhci_reset,
+ .reset = sdhci_at91_reset,
.set_uhs_signaling = sdhci_at91_set_uhs_signaling,
.set_power = sdhci_at91_set_power,
};
@@ -324,6 +342,21 @@ static int sdhci_at91_probe(struct platform_device *pdev)
host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
}
+ /*
+ * If the device attached to the MMC bus is not removable, it is safer
+ * to set the Force Card Detect bit. People often don't connect the
+ * card detect signal and use this pin for another purpose. If the card
+ * detect pin is not muxed to SDHCI controller, a default value is
+ * used. This value can be different from a SoC revision to another
+ * one. Problems come when this default value is not card present. To
+ * avoid this case, if the device is non removable then the card
+ * detection procedure using the SDMCC_CD signal is bypassed.
+ * This bit is reset when a software reset for all command is performed
+ * so we need to implement our own reset function to set back this bit.
+ */
+ if (host->mmc->caps & MMC_CAP_NONREMOVABLE)
+ sdhci_at91_set_force_card_detect(host);
+
pm_runtime_put_autosuspend(&pdev->dev);
return 0;
diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index d6fa2214aaae..0fb4e4c119e1 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -793,8 +793,12 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
}
mmc_writel(host, REG_CLKCR, rval);
- if (host->cfg->needs_new_timings)
- mmc_writel(host, REG_SD_NTSR, SDXC_2X_TIMING_MODE);
+ if (host->cfg->needs_new_timings) {
+ /* Don't touch the delay bits */
+ rval = mmc_readl(host, REG_SD_NTSR);
+ rval |= SDXC_2X_TIMING_MODE;
+ mmc_writel(host, REG_SD_NTSR, rval);
+ }
ret = sunxi_mmc_clk_set_phase(host, ios, rate);
if (ret)
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index f336a9b85576..9ec8f033ac5f 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -113,6 +113,7 @@ static blk_status_t do_blktrans_request(struct mtd_blktrans_ops *tr,
for (; nsect > 0; nsect--, block++, buf += tr->blksize)
if (tr->writesect(dev, block, buf))
return BLK_STS_IOERR;
+ return BLK_STS_OK;
default:
return BLK_STS_IOERR;
}
diff --git a/drivers/mtd/nand/atmel/nand-controller.c b/drivers/mtd/nand/atmel/nand-controller.c
index d922a88e407f..2c8baa0c2c4e 100644
--- a/drivers/mtd/nand/atmel/nand-controller.c
+++ b/drivers/mtd/nand/atmel/nand-controller.c
@@ -1201,7 +1201,7 @@ static int atmel_smc_nand_prepare_smcconf(struct atmel_nand *nand,
* tRC < 30ns implies EDO mode. This controller does not support this
* mode.
*/
- if (conf->timings.sdr.tRC_min < 30)
+ if (conf->timings.sdr.tRC_min < 30000)
return -ENOTSUPP;
atmel_smc_cs_conf_init(smcconf);
diff --git a/drivers/mtd/nand/atmel/pmecc.c b/drivers/mtd/nand/atmel/pmecc.c
index 55a8ee5306ea..8c210a5776bc 100644
--- a/drivers/mtd/nand/atmel/pmecc.c
+++ b/drivers/mtd/nand/atmel/pmecc.c
@@ -945,6 +945,7 @@ struct atmel_pmecc *devm_atmel_pmecc_get(struct device *userdev)
*/
struct platform_device *pdev = to_platform_device(userdev);
const struct atmel_pmecc_caps *caps;
+ const struct of_device_id *match;
/* No PMECC engine available. */
if (!of_property_read_bool(userdev->of_node,
@@ -953,21 +954,11 @@ struct atmel_pmecc *devm_atmel_pmecc_get(struct device *userdev)
caps = &at91sam9g45_caps;
- /*
- * Try to find the NFC subnode and extract the associated caps
- * from there.
- */
- np = of_find_compatible_node(userdev->of_node, NULL,
- "atmel,sama5d3-nfc");
- if (np) {
- const struct of_device_id *match;
-
- match = of_match_node(atmel_pmecc_legacy_match, np);
- if (match && match->data)
- caps = match->data;
-
- of_node_put(np);
- }
+ /* Find the caps associated to the NAND dev node. */
+ match = of_match_node(atmel_pmecc_legacy_match,
+ userdev->of_node);
+ if (match && match->data)
+ caps = match->data;
pmecc = atmel_pmecc_create(pdev, caps, 1, 2);
}
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 5fa5ddc94834..c6c18b82f8f4 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -65,8 +65,14 @@ static int nand_ooblayout_ecc_sp(struct mtd_info *mtd, int section,
if (!section) {
oobregion->offset = 0;
- oobregion->length = 4;
+ if (mtd->oobsize == 16)
+ oobregion->length = 4;
+ else
+ oobregion->length = 3;
} else {
+ if (mtd->oobsize == 8)
+ return -ERANGE;
+
oobregion->offset = 6;
oobregion->length = ecc->total - 4;
}
@@ -1125,7 +1131,9 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr)
* Ensure the timing mode has been changed on the chip side
* before changing timings on the controller side.
*/
- if (chip->onfi_version) {
+ if (chip->onfi_version &&
+ (le16_to_cpu(chip->onfi_params.opt_cmd) &
+ ONFI_OPT_CMD_SET_GET_FEATURES)) {
u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = {
chip->onfi_timing_mode_default,
};
@@ -2741,7 +2749,6 @@ static int nand_write_page_syndrome(struct mtd_info *mtd,
* @buf: the data to write
* @oob_required: must write chip->oob_poi to OOB
* @page: page number to write
- * @cached: cached programming
* @raw: use _raw version of write_page
*/
static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
diff --git a/drivers/mtd/nand/nand_timings.c b/drivers/mtd/nand/nand_timings.c
index f06312df3669..7e36d7d13c26 100644
--- a/drivers/mtd/nand/nand_timings.c
+++ b/drivers/mtd/nand/nand_timings.c
@@ -311,9 +311,9 @@ int onfi_init_data_interface(struct nand_chip *chip,
struct nand_sdr_timings *timings = &iface->timings.sdr;
/* microseconds -> picoseconds */
- timings->tPROG_max = 1000000UL * le16_to_cpu(params->t_prog);
- timings->tBERS_max = 1000000UL * le16_to_cpu(params->t_bers);
- timings->tR_max = 1000000UL * le16_to_cpu(params->t_r);
+ timings->tPROG_max = 1000000ULL * le16_to_cpu(params->t_prog);
+ timings->tBERS_max = 1000000ULL * le16_to_cpu(params->t_bers);
+ timings->tR_max = 1000000ULL * le16_to_cpu(params->t_r);
/* nanoseconds -> picoseconds */
timings->tCCS_min = 1000UL * le16_to_cpu(params->t_ccs);
diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index d0b6f8f9f297..6abd142b1324 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -1728,6 +1728,10 @@ static int sunxi_nfc_setup_data_interface(struct mtd_info *mtd, int csline,
*/
chip->clk_rate = NSEC_PER_SEC / min_clk_period;
real_clk_rate = clk_round_rate(nfc->mod_clk, chip->clk_rate);
+ if (real_clk_rate <= 0) {
+ dev_err(nfc->dev, "Unable to round clk %lu\n", chip->clk_rate);
+ return -EINVAL;
+ }
/*
* ONFI specification 3.1, paragraph 4.15.2 dictates that EDO data
diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig
index 7c754a0f14bb..19e4e904c9bf 100644
--- a/drivers/mux/Kconfig
+++ b/drivers/mux/Kconfig
@@ -2,20 +2,11 @@
# Multiplexer devices
#
-menuconfig MULTIPLEXER
- tristate "Multiplexer subsystem"
- help
- Multiplexer controller subsystem. Multiplexers are used in a
- variety of settings, and this subsystem abstracts their use
- so that the rest of the kernel sees a common interface. When
- multiple parallel multiplexers are controlled by one single
- multiplexer controller, this subsystem also coordinates the
- multiplexer accesses.
-
- To compile the subsystem as a module, choose M here: the module will
- be called mux-core.
+config MULTIPLEXER
+ tristate
-if MULTIPLEXER
+menu "Multiplexer drivers"
+ depends on MULTIPLEXER
config MUX_ADG792A
tristate "Analog Devices ADG792A/ADG792G Multiplexers"
@@ -56,4 +47,4 @@ config MUX_MMIO
To compile the driver as a module, choose M here: the module will
be called mux-mmio.
-endif
+endmenu
diff --git a/drivers/mux/mux-core.c b/drivers/mux/mux-core.c
index 90b8995f07cb..2fe96c470112 100644
--- a/drivers/mux/mux-core.c
+++ b/drivers/mux/mux-core.c
@@ -46,7 +46,7 @@ static int __init mux_init(void)
static void __exit mux_exit(void)
{
- class_register(&mux_class);
+ class_unregister(&mux_class);
ida_destroy(&mux_ida);
}
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 14ff622190a5..9bee6c1c70cc 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2050,6 +2050,7 @@ static int bond_miimon_inspect(struct bonding *bond)
continue;
bond_propose_link_state(slave, BOND_LINK_FAIL);
+ commit++;
slave->delay = bond->params.downdelay;
if (slave->delay) {
netdev_info(bond->dev, "link status down for %sinterface %s, disabling it in %d ms\n",
@@ -2088,6 +2089,7 @@ static int bond_miimon_inspect(struct bonding *bond)
continue;
bond_propose_link_state(slave, BOND_LINK_BACK);
+ commit++;
slave->delay = bond->params.updelay;
if (slave->delay) {
@@ -4596,7 +4598,7 @@ static int bond_check_params(struct bond_params *params)
}
ad_user_port_key = valptr->value;
- if (bond_mode == BOND_MODE_TLB) {
+ if ((bond_mode == BOND_MODE_TLB) || (bond_mode == BOND_MODE_ALB)) {
bond_opt_initstr(&newval, "default");
valptr = bond_opt_parse(bond_opt_get(BOND_OPT_TLB_DYNAMIC_LB),
&newval);
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index e68d368e20ac..7f36d3e3c98b 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1665,6 +1665,7 @@ static const struct b53_chip_data b53_switch_chips[] = {
.dev_name = "BCM53125",
.vlans = 4096,
.enabled_ports = 0xff,
+ .arl_entries = 4,
.cpu_port = B53_CPU_PORT,
.vta_regs = B53_VTA_REGS,
.duplex_reg = B53_DUPLEX_STAT_GE,
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 1e46418a3b74..264b281eb86b 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -625,6 +625,44 @@ static void mt7530_adjust_link(struct dsa_switch *ds, int port,
* all finished.
*/
mt7623_pad_clk_setup(ds);
+ } else {
+ u16 lcl_adv = 0, rmt_adv = 0;
+ u8 flowctrl;
+ u32 mcr = PMCR_USERP_LINK | PMCR_FORCE_MODE;
+
+ switch (phydev->speed) {
+ case SPEED_1000:
+ mcr |= PMCR_FORCE_SPEED_1000;
+ break;
+ case SPEED_100:
+ mcr |= PMCR_FORCE_SPEED_100;
+ break;
+ };
+
+ if (phydev->link)
+ mcr |= PMCR_FORCE_LNK;
+
+ if (phydev->duplex) {
+ mcr |= PMCR_FORCE_FDX;
+
+ if (phydev->pause)
+ rmt_adv = LPA_PAUSE_CAP;
+ if (phydev->asym_pause)
+ rmt_adv |= LPA_PAUSE_ASYM;
+
+ if (phydev->advertising & ADVERTISED_Pause)
+ lcl_adv |= ADVERTISE_PAUSE_CAP;
+ if (phydev->advertising & ADVERTISED_Asym_Pause)
+ lcl_adv |= ADVERTISE_PAUSE_ASYM;
+
+ flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
+
+ if (flowctrl & FLOW_CTRL_TX)
+ mcr |= PMCR_TX_FC_EN;
+ if (flowctrl & FLOW_CTRL_RX)
+ mcr |= PMCR_RX_FC_EN;
+ }
+ mt7530_write(priv, MT7530_PMCR_P(port), mcr);
}
}
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index b83d76b99802..74db9822eb40 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -151,6 +151,7 @@ enum mt7530_stp_state {
#define PMCR_TX_FC_EN BIT(5)
#define PMCR_RX_FC_EN BIT(4)
#define PMCR_FORCE_SPEED_1000 BIT(3)
+#define PMCR_FORCE_SPEED_100 BIT(2)
#define PMCR_FORCE_FDX BIT(1)
#define PMCR_FORCE_LNK BIT(0)
#define PMCR_COMMON_LINK (PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | \
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 53b088166c28..5bcdd33101b0 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -3178,6 +3178,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
.port_pause_limit = mv88e6390_port_pause_limit,
+ .port_set_cmode = mv88e6390x_port_set_cmode,
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index d3906f6b01bd..1d307f2def2d 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -1787,14 +1787,16 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
pdata->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(pdata->clk)) {
- /* Abort if the clock is defined but couldn't be retrived.
- * Always abort if the clock is missing on DT system as
- * the driver can't cope with this case.
- */
- if (PTR_ERR(pdata->clk) != -ENOENT || dev->of_node)
- return PTR_ERR(pdata->clk);
- /* Firmware may have set up the clock already. */
- dev_info(dev, "clocks have been setup already\n");
+ if (pdata->phy_mode != PHY_INTERFACE_MODE_SGMII) {
+ /* Abort if the clock is defined but couldn't be
+ * retrived. Always abort if the clock is missing on
+ * DT system as the driver can't cope with this case.
+ */
+ if (PTR_ERR(pdata->clk) != -ENOENT || dev->of_node)
+ return PTR_ERR(pdata->clk);
+ /* Firmware may have set up the clock already. */
+ dev_info(dev, "clocks have been setup already\n");
+ }
}
if (pdata->phy_mode != PHY_INTERFACE_MODE_XGMII)
diff --git a/drivers/net/ethernet/aurora/nb8800.c b/drivers/net/ethernet/aurora/nb8800.c
index 041cfb7952f8..e94159507847 100644
--- a/drivers/net/ethernet/aurora/nb8800.c
+++ b/drivers/net/ethernet/aurora/nb8800.c
@@ -609,7 +609,7 @@ static void nb8800_mac_config(struct net_device *dev)
mac_mode |= HALF_DUPLEX;
if (gigabit) {
- if (priv->phy_mode == PHY_INTERFACE_MODE_RGMII)
+ if (phy_interface_is_rgmii(dev->phydev))
mac_mode |= RGMII_MODE;
mac_mode |= GMAC_MODE;
@@ -1268,11 +1268,10 @@ static int nb8800_tangox_init(struct net_device *dev)
break;
case PHY_INTERFACE_MODE_RGMII:
- pad_mode = PAD_MODE_RGMII;
- break;
-
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_TXID:
- pad_mode = PAD_MODE_RGMII | PAD_MODE_GTX_CLK_DELAY;
+ pad_mode = PAD_MODE_RGMII;
break;
default:
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
index f411936b744c..a1125d10c825 100644
--- a/drivers/net/ethernet/broadcom/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -2368,6 +2368,7 @@ static int b44_init_one(struct ssb_device *sdev,
bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE);
spin_lock_init(&bp->lock);
+ u64_stats_init(&bp->hw_stats.syncp);
bp->rx_pending = B44_DEF_RX_RING_PENDING;
bp->tx_pending = B44_DEF_TX_RING_PENDING;
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
index 5333601f855f..dc3052751bc1 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -449,6 +449,10 @@ static void bcm_sysport_get_stats(struct net_device *dev,
p = (char *)&dev->stats;
else
p = (char *)priv;
+
+ if (priv->is_lite && !bcm_sysport_lite_stat_valid(s->type))
+ continue;
+
p += s->stat_offset;
data[j] = *(unsigned long *)p;
j++;
diff --git a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c
index 73aca97a96bc..d937083db9a4 100644
--- a/drivers/net/ethernet/broadcom/bgmac-platform.c
+++ b/drivers/net/ethernet/broadcom/bgmac-platform.c
@@ -50,11 +50,14 @@ static u32 platform_bgmac_idm_read(struct bgmac *bgmac, u16 offset)
static void platform_bgmac_idm_write(struct bgmac *bgmac, u16 offset, u32 value)
{
- return writel(value, bgmac->plat.idm_base + offset);
+ writel(value, bgmac->plat.idm_base + offset);
}
static bool platform_bgmac_clk_enabled(struct bgmac *bgmac)
{
+ if (!bgmac->plat.idm_base)
+ return true;
+
if ((bgmac_idm_read(bgmac, BCMA_IOCTL) & BGMAC_CLK_EN) != BGMAC_CLK_EN)
return false;
if (bgmac_idm_read(bgmac, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
@@ -66,6 +69,9 @@ static void platform_bgmac_clk_enable(struct bgmac *bgmac, u32 flags)
{
u32 val;
+ if (!bgmac->plat.idm_base)
+ return;
+
/* The Reset Control register only contains a single bit to show if the
* controller is currently in reset. Do a sanity check here, just in
* case the bootloader happened to leave the device in reset.
@@ -180,6 +186,7 @@ static int bgmac_probe(struct platform_device *pdev)
bgmac->feature_flags |= BGMAC_FEAT_CMDCFG_SR_REV4;
bgmac->feature_flags |= BGMAC_FEAT_TX_MASK_SETUP;
bgmac->feature_flags |= BGMAC_FEAT_RX_MASK_SETUP;
+ bgmac->feature_flags |= BGMAC_FEAT_IDM_MASK;
bgmac->dev = &pdev->dev;
bgmac->dma_dev = &pdev->dev;
@@ -207,15 +214,13 @@ static int bgmac_probe(struct platform_device *pdev)
return PTR_ERR(bgmac->plat.base);
regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "idm_base");
- if (!regs) {
- dev_err(&pdev->dev, "Unable to obtain idm resource\n");
- return -EINVAL;
+ if (regs) {
+ bgmac->plat.idm_base = devm_ioremap_resource(&pdev->dev, regs);
+ if (IS_ERR(bgmac->plat.idm_base))
+ return PTR_ERR(bgmac->plat.idm_base);
+ bgmac->feature_flags &= ~BGMAC_FEAT_IDM_MASK;
}
- bgmac->plat.idm_base = devm_ioremap_resource(&pdev->dev, regs);
- if (IS_ERR(bgmac->plat.idm_base))
- return PTR_ERR(bgmac->plat.idm_base);
-
regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base");
if (regs) {
bgmac->plat.nicpm_base = devm_ioremap_resource(&pdev->dev,
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
index ba4d2e145bb9..48d672b204a4 100644
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
@@ -622,9 +622,11 @@ static int bgmac_dma_alloc(struct bgmac *bgmac)
BUILD_BUG_ON(BGMAC_MAX_TX_RINGS > ARRAY_SIZE(ring_base));
BUILD_BUG_ON(BGMAC_MAX_RX_RINGS > ARRAY_SIZE(ring_base));
- if (!(bgmac_idm_read(bgmac, BCMA_IOST) & BCMA_IOST_DMA64)) {
- dev_err(bgmac->dev, "Core does not report 64-bit DMA\n");
- return -ENOTSUPP;
+ if (!(bgmac->feature_flags & BGMAC_FEAT_IDM_MASK)) {
+ if (!(bgmac_idm_read(bgmac, BCMA_IOST) & BCMA_IOST_DMA64)) {
+ dev_err(bgmac->dev, "Core does not report 64-bit DMA\n");
+ return -ENOTSUPP;
+ }
}
for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
@@ -855,9 +857,11 @@ static void bgmac_mac_speed(struct bgmac *bgmac)
static void bgmac_miiconfig(struct bgmac *bgmac)
{
if (bgmac->feature_flags & BGMAC_FEAT_FORCE_SPEED_2500) {
- bgmac_idm_write(bgmac, BCMA_IOCTL,
- bgmac_idm_read(bgmac, BCMA_IOCTL) | 0x40 |
- BGMAC_BCMA_IOCTL_SW_CLKEN);
+ if (!(bgmac->feature_flags & BGMAC_FEAT_IDM_MASK)) {
+ bgmac_idm_write(bgmac, BCMA_IOCTL,
+ bgmac_idm_read(bgmac, BCMA_IOCTL) |
+ 0x40 | BGMAC_BCMA_IOCTL_SW_CLKEN);
+ }
bgmac->mac_speed = SPEED_2500;
bgmac->mac_duplex = DUPLEX_FULL;
bgmac_mac_speed(bgmac);
@@ -874,11 +878,36 @@ static void bgmac_miiconfig(struct bgmac *bgmac)
}
}
+static void bgmac_chip_reset_idm_config(struct bgmac *bgmac)
+{
+ u32 iost;
+
+ iost = bgmac_idm_read(bgmac, BCMA_IOST);
+ if (bgmac->feature_flags & BGMAC_FEAT_IOST_ATTACHED)
+ iost &= ~BGMAC_BCMA_IOST_ATTACHED;
+
+ /* 3GMAC: for BCM4707 & BCM47094, only do core reset at bgmac_probe() */
+ if (!(bgmac->feature_flags & BGMAC_FEAT_NO_RESET)) {
+ u32 flags = 0;
+
+ if (iost & BGMAC_BCMA_IOST_ATTACHED) {
+ flags = BGMAC_BCMA_IOCTL_SW_CLKEN;
+ if (!bgmac->has_robosw)
+ flags |= BGMAC_BCMA_IOCTL_SW_RESET;
+ }
+ bgmac_clk_enable(bgmac, flags);
+ }
+
+ if (iost & BGMAC_BCMA_IOST_ATTACHED && !bgmac->has_robosw)
+ bgmac_idm_write(bgmac, BCMA_IOCTL,
+ bgmac_idm_read(bgmac, BCMA_IOCTL) &
+ ~BGMAC_BCMA_IOCTL_SW_RESET);
+}
+
/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipreset */
static void bgmac_chip_reset(struct bgmac *bgmac)
{
u32 cmdcfg_sr;
- u32 iost;
int i;
if (bgmac_clk_enabled(bgmac)) {
@@ -899,20 +928,8 @@ static void bgmac_chip_reset(struct bgmac *bgmac)
/* TODO: Clear software multicast filter list */
}
- iost = bgmac_idm_read(bgmac, BCMA_IOST);
- if (bgmac->feature_flags & BGMAC_FEAT_IOST_ATTACHED)
- iost &= ~BGMAC_BCMA_IOST_ATTACHED;
-
- /* 3GMAC: for BCM4707 & BCM47094, only do core reset at bgmac_probe() */
- if (!(bgmac->feature_flags & BGMAC_FEAT_NO_RESET)) {
- u32 flags = 0;
- if (iost & BGMAC_BCMA_IOST_ATTACHED) {
- flags = BGMAC_BCMA_IOCTL_SW_CLKEN;
- if (!bgmac->has_robosw)
- flags |= BGMAC_BCMA_IOCTL_SW_RESET;
- }
- bgmac_clk_enable(bgmac, flags);
- }
+ if (!(bgmac->feature_flags & BGMAC_FEAT_IDM_MASK))
+ bgmac_chip_reset_idm_config(bgmac);
/* Request Misc PLL for corerev > 2 */
if (bgmac->feature_flags & BGMAC_FEAT_MISC_PLL_REQ) {
@@ -970,11 +987,6 @@ static void bgmac_chip_reset(struct bgmac *bgmac)
BGMAC_CHIPCTL_7_IF_TYPE_RGMII);
}
- if (iost & BGMAC_BCMA_IOST_ATTACHED && !bgmac->has_robosw)
- bgmac_idm_write(bgmac, BCMA_IOCTL,
- bgmac_idm_read(bgmac, BCMA_IOCTL) &
- ~BGMAC_BCMA_IOCTL_SW_RESET);
-
/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_reset
* Specs don't say about using BGMAC_CMDCFG_SR, but in this routine
* BGMAC_CMDCFG is read _after_ putting chip in a reset. So it has to
@@ -1497,8 +1509,10 @@ int bgmac_enet_probe(struct bgmac *bgmac)
bgmac_clk_enable(bgmac, 0);
/* This seems to be fixing IRQ by assigning OOB #6 to the core */
- if (bgmac->feature_flags & BGMAC_FEAT_IRQ_ID_OOB_6)
- bgmac_idm_write(bgmac, BCMA_OOB_SEL_OUT_A30, 0x86);
+ if (!(bgmac->feature_flags & BGMAC_FEAT_IDM_MASK)) {
+ if (bgmac->feature_flags & BGMAC_FEAT_IRQ_ID_OOB_6)
+ bgmac_idm_write(bgmac, BCMA_OOB_SEL_OUT_A30, 0x86);
+ }
bgmac_chip_reset(bgmac);
diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h
index c1818766c501..443d57b10264 100644
--- a/drivers/net/ethernet/broadcom/bgmac.h
+++ b/drivers/net/ethernet/broadcom/bgmac.h
@@ -425,6 +425,7 @@
#define BGMAC_FEAT_CC4_IF_SW_TYPE BIT(17)
#define BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII BIT(18)
#define BGMAC_FEAT_CC7_IF_TYPE_RGMII BIT(19)
+#define BGMAC_FEAT_IDM_MASK BIT(20)
struct bgmac_slot_info {
union {
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index 43423744fdfa..1e33abde4a3e 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -2886,7 +2886,7 @@ static int bnx2x_test_nvram_tbl(struct bnx2x *bp,
static int bnx2x_test_nvram(struct bnx2x *bp)
{
- const struct crc_pair nvram_tbl[] = {
+ static const struct crc_pair nvram_tbl[] = {
{ 0, 0x14 }, /* bootstrap */
{ 0x14, 0xec }, /* dir */
{ 0x100, 0x350 }, /* manuf_info */
@@ -2895,7 +2895,7 @@ static int bnx2x_test_nvram(struct bnx2x *bp)
{ 0x708, 0x70 }, /* manuf_key_info */
{ 0, 0 }
};
- const struct crc_pair nvram_tbl2[] = {
+ static const struct crc_pair nvram_tbl2[] = {
{ 0x7e8, 0x350 }, /* manuf_info2 */
{ 0xb38, 0xf0 }, /* feature_info */
{ 0, 0 }
@@ -3162,7 +3162,8 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
if (is_multi(bp)) {
for_each_eth_queue(bp, i) {
memset(queue_name, 0, sizeof(queue_name));
- sprintf(queue_name, "%d", i);
+ snprintf(queue_name, sizeof(queue_name),
+ "%d", i);
for (j = 0; j < BNX2X_NUM_Q_STATS; j++)
snprintf(buf + (k + j)*ETH_GSTRING_LEN,
ETH_GSTRING_LEN,
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index daca1c9d254b..a981c4ee9d72 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1202,12 +1202,21 @@ static struct enet_cb *bcmgenet_get_txcb(struct bcmgenet_priv *priv,
return tx_cb_ptr;
}
-/* Simple helper to free a control block's resources */
-static void bcmgenet_free_cb(struct enet_cb *cb)
+static struct enet_cb *bcmgenet_put_txcb(struct bcmgenet_priv *priv,
+ struct bcmgenet_tx_ring *ring)
{
- dev_kfree_skb_any(cb->skb);
- cb->skb = NULL;
- dma_unmap_addr_set(cb, dma_addr, 0);
+ struct enet_cb *tx_cb_ptr;
+
+ tx_cb_ptr = ring->cbs;
+ tx_cb_ptr += ring->write_ptr - ring->cb_ptr;
+
+ /* Rewinding local write pointer */
+ if (ring->write_ptr == ring->cb_ptr)
+ ring->write_ptr = ring->end_ptr;
+ else
+ ring->write_ptr--;
+
+ return tx_cb_ptr;
}
static inline void bcmgenet_rx_ring16_int_disable(struct bcmgenet_rx_ring *ring)
@@ -1260,18 +1269,72 @@ static inline void bcmgenet_tx_ring_int_disable(struct bcmgenet_tx_ring *ring)
INTRL2_CPU_MASK_SET);
}
+/* Simple helper to free a transmit control block's resources
+ * Returns an skb when the last transmit control block associated with the
+ * skb is freed. The skb should be freed by the caller if necessary.
+ */
+static struct sk_buff *bcmgenet_free_tx_cb(struct device *dev,
+ struct enet_cb *cb)
+{
+ struct sk_buff *skb;
+
+ skb = cb->skb;
+
+ if (skb) {
+ cb->skb = NULL;
+ if (cb == GENET_CB(skb)->first_cb)
+ dma_unmap_single(dev, dma_unmap_addr(cb, dma_addr),
+ dma_unmap_len(cb, dma_len),
+ DMA_TO_DEVICE);
+ else
+ dma_unmap_page(dev, dma_unmap_addr(cb, dma_addr),
+ dma_unmap_len(cb, dma_len),
+ DMA_TO_DEVICE);
+ dma_unmap_addr_set(cb, dma_addr, 0);
+
+ if (cb == GENET_CB(skb)->last_cb)
+ return skb;
+
+ } else if (dma_unmap_addr(cb, dma_addr)) {
+ dma_unmap_page(dev,
+ dma_unmap_addr(cb, dma_addr),
+ dma_unmap_len(cb, dma_len),
+ DMA_TO_DEVICE);
+ dma_unmap_addr_set(cb, dma_addr, 0);
+ }
+
+ return 0;
+}
+
+/* Simple helper to free a receive control block's resources */
+static struct sk_buff *bcmgenet_free_rx_cb(struct device *dev,
+ struct enet_cb *cb)
+{
+ struct sk_buff *skb;
+
+ skb = cb->skb;
+ cb->skb = NULL;
+
+ if (dma_unmap_addr(cb, dma_addr)) {
+ dma_unmap_single(dev, dma_unmap_addr(cb, dma_addr),
+ dma_unmap_len(cb, dma_len), DMA_FROM_DEVICE);
+ dma_unmap_addr_set(cb, dma_addr, 0);
+ }
+
+ return skb;
+}
+
/* Unlocked version of the reclaim routine */
static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
struct bcmgenet_tx_ring *ring)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
- struct device *kdev = &priv->pdev->dev;
- struct enet_cb *tx_cb_ptr;
- unsigned int pkts_compl = 0;
+ unsigned int txbds_processed = 0;
unsigned int bytes_compl = 0;
- unsigned int c_index;
+ unsigned int pkts_compl = 0;
unsigned int txbds_ready;
- unsigned int txbds_processed = 0;
+ unsigned int c_index;
+ struct sk_buff *skb;
/* Clear status before servicing to reduce spurious interrupts */
if (ring->index == DESC_INDEX)
@@ -1292,21 +1355,12 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
/* Reclaim transmitted buffers */
while (txbds_processed < txbds_ready) {
- tx_cb_ptr = &priv->tx_cbs[ring->clean_ptr];
- if (tx_cb_ptr->skb) {
+ skb = bcmgenet_free_tx_cb(&priv->pdev->dev,
+ &priv->tx_cbs[ring->clean_ptr]);
+ if (skb) {
pkts_compl++;
- bytes_compl += GENET_CB(tx_cb_ptr->skb)->bytes_sent;
- dma_unmap_single(kdev,
- dma_unmap_addr(tx_cb_ptr, dma_addr),
- dma_unmap_len(tx_cb_ptr, dma_len),
- DMA_TO_DEVICE);
- bcmgenet_free_cb(tx_cb_ptr);
- } else if (dma_unmap_addr(tx_cb_ptr, dma_addr)) {
- dma_unmap_page(kdev,
- dma_unmap_addr(tx_cb_ptr, dma_addr),
- dma_unmap_len(tx_cb_ptr, dma_len),
- DMA_TO_DEVICE);
- dma_unmap_addr_set(tx_cb_ptr, dma_addr, 0);
+ bytes_compl += GENET_CB(skb)->bytes_sent;
+ dev_kfree_skb_any(skb);
}
txbds_processed++;
@@ -1380,95 +1434,6 @@ static void bcmgenet_tx_reclaim_all(struct net_device *dev)
bcmgenet_tx_reclaim(dev, &priv->tx_rings[DESC_INDEX]);
}
-/* Transmits a single SKB (either head of a fragment or a single SKB)
- * caller must hold priv->lock
- */
-static int bcmgenet_xmit_single(struct net_device *dev,
- struct sk_buff *skb,
- u16 dma_desc_flags,
- struct bcmgenet_tx_ring *ring)
-{
- struct bcmgenet_priv *priv = netdev_priv(dev);
- struct device *kdev = &priv->pdev->dev;
- struct enet_cb *tx_cb_ptr;
- unsigned int skb_len;
- dma_addr_t mapping;
- u32 length_status;
- int ret;
-
- tx_cb_ptr = bcmgenet_get_txcb(priv, ring);
-
- if (unlikely(!tx_cb_ptr))
- BUG();
-
- tx_cb_ptr->skb = skb;
-
- skb_len = skb_headlen(skb);
-
- mapping = dma_map_single(kdev, skb->data, skb_len, DMA_TO_DEVICE);
- ret = dma_mapping_error(kdev, mapping);
- if (ret) {
- priv->mib.tx_dma_failed++;
- netif_err(priv, tx_err, dev, "Tx DMA map failed\n");
- dev_kfree_skb(skb);
- return ret;
- }
-
- dma_unmap_addr_set(tx_cb_ptr, dma_addr, mapping);
- dma_unmap_len_set(tx_cb_ptr, dma_len, skb_len);
- length_status = (skb_len << DMA_BUFLENGTH_SHIFT) | dma_desc_flags |
- (priv->hw_params->qtag_mask << DMA_TX_QTAG_SHIFT) |
- DMA_TX_APPEND_CRC;
-
- if (skb->ip_summed == CHECKSUM_PARTIAL)
- length_status |= DMA_TX_DO_CSUM;
-
- dmadesc_set(priv, tx_cb_ptr->bd_addr, mapping, length_status);
-
- return 0;
-}
-
-/* Transmit a SKB fragment */
-static int bcmgenet_xmit_frag(struct net_device *dev,
- skb_frag_t *frag,
- u16 dma_desc_flags,
- struct bcmgenet_tx_ring *ring)
-{
- struct bcmgenet_priv *priv = netdev_priv(dev);
- struct device *kdev = &priv->pdev->dev;
- struct enet_cb *tx_cb_ptr;
- unsigned int frag_size;
- dma_addr_t mapping;
- int ret;
-
- tx_cb_ptr = bcmgenet_get_txcb(priv, ring);
-
- if (unlikely(!tx_cb_ptr))
- BUG();
-
- tx_cb_ptr->skb = NULL;
-
- frag_size = skb_frag_size(frag);
-
- mapping = skb_frag_dma_map(kdev, frag, 0, frag_size, DMA_TO_DEVICE);
- ret = dma_mapping_error(kdev, mapping);
- if (ret) {
- priv->mib.tx_dma_failed++;
- netif_err(priv, tx_err, dev, "%s: Tx DMA map failed\n",
- __func__);
- return ret;
- }
-
- dma_unmap_addr_set(tx_cb_ptr, dma_addr, mapping);
- dma_unmap_len_set(tx_cb_ptr, dma_len, frag_size);
-
- dmadesc_set(priv, tx_cb_ptr->bd_addr, mapping,
- (frag_size << DMA_BUFLENGTH_SHIFT) | dma_desc_flags |
- (priv->hw_params->qtag_mask << DMA_TX_QTAG_SHIFT));
-
- return 0;
-}
-
/* Reallocate the SKB to put enough headroom in front of it and insert
* the transmit checksum offsets in the descriptors
*/
@@ -1535,11 +1500,16 @@ static struct sk_buff *bcmgenet_put_tx_csum(struct net_device *dev,
static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
+ struct device *kdev = &priv->pdev->dev;
struct bcmgenet_tx_ring *ring = NULL;
+ struct enet_cb *tx_cb_ptr;
struct netdev_queue *txq;
unsigned long flags = 0;
int nr_frags, index;
- u16 dma_desc_flags;
+ dma_addr_t mapping;
+ unsigned int size;
+ skb_frag_t *frag;
+ u32 len_stat;
int ret;
int i;
@@ -1592,29 +1562,53 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
- dma_desc_flags = DMA_SOP;
- if (nr_frags == 0)
- dma_desc_flags |= DMA_EOP;
+ for (i = 0; i <= nr_frags; i++) {
+ tx_cb_ptr = bcmgenet_get_txcb(priv, ring);
- /* Transmit single SKB or head of fragment list */
- ret = bcmgenet_xmit_single(dev, skb, dma_desc_flags, ring);
- if (ret) {
- ret = NETDEV_TX_OK;
- goto out;
- }
+ if (unlikely(!tx_cb_ptr))
+ BUG();
+
+ if (!i) {
+ /* Transmit single SKB or head of fragment list */
+ GENET_CB(skb)->first_cb = tx_cb_ptr;
+ size = skb_headlen(skb);
+ mapping = dma_map_single(kdev, skb->data, size,
+ DMA_TO_DEVICE);
+ } else {
+ /* xmit fragment */
+ frag = &skb_shinfo(skb)->frags[i - 1];
+ size = skb_frag_size(frag);
+ mapping = skb_frag_dma_map(kdev, frag, 0, size,
+ DMA_TO_DEVICE);
+ }
- /* xmit fragment */
- for (i = 0; i < nr_frags; i++) {
- ret = bcmgenet_xmit_frag(dev,
- &skb_shinfo(skb)->frags[i],
- (i == nr_frags - 1) ? DMA_EOP : 0,
- ring);
+ ret = dma_mapping_error(kdev, mapping);
if (ret) {
+ priv->mib.tx_dma_failed++;
+ netif_err(priv, tx_err, dev, "Tx DMA map failed\n");
ret = NETDEV_TX_OK;
- goto out;
+ goto out_unmap_frags;
+ }
+ dma_unmap_addr_set(tx_cb_ptr, dma_addr, mapping);
+ dma_unmap_len_set(tx_cb_ptr, dma_len, size);
+
+ tx_cb_ptr->skb = skb;
+
+ len_stat = (size << DMA_BUFLENGTH_SHIFT) |
+ (priv->hw_params->qtag_mask << DMA_TX_QTAG_SHIFT);
+
+ if (!i) {
+ len_stat |= DMA_TX_APPEND_CRC | DMA_SOP;
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ len_stat |= DMA_TX_DO_CSUM;
}
+ if (i == nr_frags)
+ len_stat |= DMA_EOP;
+
+ dmadesc_set(priv, tx_cb_ptr->bd_addr, mapping, len_stat);
}
+ GENET_CB(skb)->last_cb = tx_cb_ptr;
skb_tx_timestamp(skb);
/* Decrement total BD count and advance our write pointer */
@@ -1635,6 +1629,19 @@ out:
spin_unlock_irqrestore(&ring->lock, flags);
return ret;
+
+out_unmap_frags:
+ /* Back up for failed control block mapping */
+ bcmgenet_put_txcb(priv, ring);
+
+ /* Unmap successfully mapped control blocks */
+ while (i-- > 0) {
+ tx_cb_ptr = bcmgenet_put_txcb(priv, ring);
+ bcmgenet_free_tx_cb(kdev, tx_cb_ptr);
+ }
+
+ dev_kfree_skb(skb);
+ goto out;
}
static struct sk_buff *bcmgenet_rx_refill(struct bcmgenet_priv *priv,
@@ -1666,14 +1673,12 @@ static struct sk_buff *bcmgenet_rx_refill(struct bcmgenet_priv *priv,
}
/* Grab the current Rx skb from the ring and DMA-unmap it */
- rx_skb = cb->skb;
- if (likely(rx_skb))
- dma_unmap_single(kdev, dma_unmap_addr(cb, dma_addr),
- priv->rx_buf_len, DMA_FROM_DEVICE);
+ rx_skb = bcmgenet_free_rx_cb(kdev, cb);
/* Put the new Rx skb on the ring */
cb->skb = skb;
dma_unmap_addr_set(cb, dma_addr, mapping);
+ dma_unmap_len_set(cb, dma_len, priv->rx_buf_len);
dmadesc_set_addr(priv, cb->bd_addr, mapping);
/* Return the current Rx skb to caller */
@@ -1880,22 +1885,16 @@ static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv,
static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv)
{
- struct device *kdev = &priv->pdev->dev;
+ struct sk_buff *skb;
struct enet_cb *cb;
int i;
for (i = 0; i < priv->num_rx_bds; i++) {
cb = &priv->rx_cbs[i];
- if (dma_unmap_addr(cb, dma_addr)) {
- dma_unmap_single(kdev,
- dma_unmap_addr(cb, dma_addr),
- priv->rx_buf_len, DMA_FROM_DEVICE);
- dma_unmap_addr_set(cb, dma_addr, 0);
- }
-
- if (cb->skb)
- bcmgenet_free_cb(cb);
+ skb = bcmgenet_free_rx_cb(&priv->pdev->dev, cb);
+ if (skb)
+ dev_kfree_skb_any(skb);
}
}
@@ -2479,8 +2478,10 @@ static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv)
static void bcmgenet_fini_dma(struct bcmgenet_priv *priv)
{
- int i;
struct netdev_queue *txq;
+ struct sk_buff *skb;
+ struct enet_cb *cb;
+ int i;
bcmgenet_fini_rx_napi(priv);
bcmgenet_fini_tx_napi(priv);
@@ -2489,10 +2490,10 @@ static void bcmgenet_fini_dma(struct bcmgenet_priv *priv)
bcmgenet_dma_teardown(priv);
for (i = 0; i < priv->num_tx_bds; i++) {
- if (priv->tx_cbs[i].skb != NULL) {
- dev_kfree_skb(priv->tx_cbs[i].skb);
- priv->tx_cbs[i].skb = NULL;
- }
+ cb = priv->tx_cbs + i;
+ skb = bcmgenet_free_tx_cb(&priv->pdev->dev, cb);
+ if (skb)
+ dev_kfree_skb(skb);
}
for (i = 0; i < priv->hw_params->tx_queues; i++) {
@@ -3668,7 +3669,7 @@ static int bcmgenet_resume(struct device *d)
phy_init_hw(priv->phydev);
/* Speed settings must be restored */
- bcmgenet_mii_config(priv->dev);
+ bcmgenet_mii_config(priv->dev, false);
/* disable ethernet MAC while updating its registers */
umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, false);
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
index efd07020b89f..3a34fdba5301 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
@@ -544,6 +544,8 @@ struct bcmgenet_hw_params {
};
struct bcmgenet_skb_cb {
+ struct enet_cb *first_cb; /* First control block of SKB */
+ struct enet_cb *last_cb; /* Last control block of SKB */
unsigned int bytes_sent; /* bytes on the wire (no TSB) */
};
@@ -696,7 +698,7 @@ GENET_IO_MACRO(rbuf, GENET_RBUF_OFF);
/* MDIO routines */
int bcmgenet_mii_init(struct net_device *dev);
-int bcmgenet_mii_config(struct net_device *dev);
+int bcmgenet_mii_config(struct net_device *dev, bool init);
int bcmgenet_mii_probe(struct net_device *dev);
void bcmgenet_mii_exit(struct net_device *dev);
void bcmgenet_mii_reset(struct net_device *dev);
diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
index 071fcbd14e6a..30cb97b4a1d7 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
@@ -238,7 +238,7 @@ static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
bcmgenet_fixed_phy_link_update);
}
-int bcmgenet_mii_config(struct net_device *dev)
+int bcmgenet_mii_config(struct net_device *dev, bool init)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
struct phy_device *phydev = priv->phydev;
@@ -327,7 +327,8 @@ int bcmgenet_mii_config(struct net_device *dev)
bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
}
- dev_info_once(kdev, "configuring instance for %s\n", phy_name);
+ if (init)
+ dev_info(kdev, "configuring instance for %s\n", phy_name);
return 0;
}
@@ -375,7 +376,7 @@ int bcmgenet_mii_probe(struct net_device *dev)
* PHY speed which is needed for bcmgenet_mii_config() to configure
* things appropriately.
*/
- ret = bcmgenet_mii_config(dev);
+ ret = bcmgenet_mii_config(dev, true);
if (ret) {
phy_disconnect(priv->phydev);
return ret;
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c b/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c
index 28ecda3d3404..ebd353bc78ff 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_ethtool.c
@@ -335,7 +335,7 @@ lio_ethtool_get_channels(struct net_device *dev,
static int lio_get_eeprom_len(struct net_device *netdev)
{
- u8 buf[128];
+ u8 buf[192];
struct lio *lio = GET_LIO(netdev);
struct octeon_device *oct_dev = lio->oct_dev;
struct octeon_board_info *board_info;
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
index a0ca68ce3fbb..5e5c4d7796b8 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -292,11 +292,30 @@ static void bgx_sgmii_change_link_state(struct lmac *lmac)
u64 cmr_cfg;
u64 port_cfg = 0;
u64 misc_ctl = 0;
+ bool tx_en, rx_en;
cmr_cfg = bgx_reg_read(bgx, lmac->lmacid, BGX_CMRX_CFG);
- cmr_cfg &= ~CMR_EN;
+ tx_en = cmr_cfg & CMR_PKT_TX_EN;
+ rx_en = cmr_cfg & CMR_PKT_RX_EN;
+ cmr_cfg &= ~(CMR_PKT_RX_EN | CMR_PKT_TX_EN);
bgx_reg_write(bgx, lmac->lmacid, BGX_CMRX_CFG, cmr_cfg);
+ /* Wait for BGX RX to be idle */
+ if (bgx_poll_reg(bgx, lmac->lmacid, BGX_GMP_GMI_PRTX_CFG,
+ GMI_PORT_CFG_RX_IDLE, false)) {
+ dev_err(&bgx->pdev->dev, "BGX%d LMAC%d GMI RX not idle\n",
+ bgx->bgx_id, lmac->lmacid);
+ return;
+ }
+
+ /* Wait for BGX TX to be idle */
+ if (bgx_poll_reg(bgx, lmac->lmacid, BGX_GMP_GMI_PRTX_CFG,
+ GMI_PORT_CFG_TX_IDLE, false)) {
+ dev_err(&bgx->pdev->dev, "BGX%d LMAC%d GMI TX not idle\n",
+ bgx->bgx_id, lmac->lmacid);
+ return;
+ }
+
port_cfg = bgx_reg_read(bgx, lmac->lmacid, BGX_GMP_GMI_PRTX_CFG);
misc_ctl = bgx_reg_read(bgx, lmac->lmacid, BGX_GMP_PCS_MISCX_CTL);
@@ -347,10 +366,8 @@ static void bgx_sgmii_change_link_state(struct lmac *lmac)
bgx_reg_write(bgx, lmac->lmacid, BGX_GMP_PCS_MISCX_CTL, misc_ctl);
bgx_reg_write(bgx, lmac->lmacid, BGX_GMP_GMI_PRTX_CFG, port_cfg);
- port_cfg = bgx_reg_read(bgx, lmac->lmacid, BGX_GMP_GMI_PRTX_CFG);
-
- /* Re-enable lmac */
- cmr_cfg |= CMR_EN;
+ /* Restore CMR config settings */
+ cmr_cfg |= (rx_en ? CMR_PKT_RX_EN : 0) | (tx_en ? CMR_PKT_TX_EN : 0);
bgx_reg_write(bgx, lmac->lmacid, BGX_CMRX_CFG, cmr_cfg);
if (bgx->is_rgx && (cmr_cfg & (CMR_PKT_RX_EN | CMR_PKT_TX_EN)))
@@ -1008,7 +1025,7 @@ static void bgx_print_qlm_mode(struct bgx *bgx, u8 lmacid)
{
struct device *dev = &bgx->pdev->dev;
struct lmac *lmac;
- char str[20];
+ char str[27];
if (!bgx->is_dlm && lmacid)
return;
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
index 6b7fe6fdd13b..23acdc5ab896 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
@@ -170,6 +170,8 @@
#define GMI_PORT_CFG_DUPLEX BIT_ULL(2)
#define GMI_PORT_CFG_SLOT_TIME BIT_ULL(3)
#define GMI_PORT_CFG_SPEED_MSB BIT_ULL(8)
+#define GMI_PORT_CFG_RX_IDLE BIT_ULL(12)
+#define GMI_PORT_CFG_TX_IDLE BIT_ULL(13)
#define BGX_GMP_GMI_RXX_JABBER 0x38038
#define BGX_GMP_GMI_TXX_THRESH 0x38210
#define BGX_GMP_GMI_TXX_APPEND 0x38218
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ptp.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ptp.c
index 50517cfd9671..9f9d6cae39d5 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ptp.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ptp.c
@@ -441,7 +441,8 @@ void cxgb4_ptp_init(struct adapter *adapter)
adapter->ptp_clock = ptp_clock_register(&adapter->ptp_clock_info,
&adapter->pdev->dev);
- if (!adapter->ptp_clock) {
+ if (IS_ERR_OR_NULL(adapter->ptp_clock)) {
+ adapter->ptp_clock = NULL;
dev_err(adapter->pdev_dev,
"PTP %s Clock registration has failed\n", __func__);
return;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h b/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h
index 99987d8e437e..aa28299aef5f 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h
@@ -174,6 +174,8 @@ CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN
CH_PCI_ID_TABLE_FENTRY(0x50a0), /* Custom T540-CR */
CH_PCI_ID_TABLE_FENTRY(0x50a1), /* Custom T540-CR */
CH_PCI_ID_TABLE_FENTRY(0x50a2), /* Custom T540-KR4 */
+ CH_PCI_ID_TABLE_FENTRY(0x50a3), /* Custom T580-KR4 */
+ CH_PCI_ID_TABLE_FENTRY(0x50a4), /* Custom 2x T540-CR */
/* T6 adapters:
*/
diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
index 95bf5e89cfd1..34dae51effd4 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -125,7 +125,7 @@ static int ftgmac100_reset_mac(struct ftgmac100 *priv, u32 maccr)
iowrite32(maccr, priv->base + FTGMAC100_OFFSET_MACCR);
iowrite32(maccr | FTGMAC100_MACCR_SW_RST,
priv->base + FTGMAC100_OFFSET_MACCR);
- for (i = 0; i < 50; i++) {
+ for (i = 0; i < 200; i++) {
unsigned int maccr;
maccr = ioread32(priv->base + FTGMAC100_OFFSET_MACCR);
@@ -392,7 +392,7 @@ static int ftgmac100_alloc_rx_buf(struct ftgmac100 *priv, unsigned int entry,
struct net_device *netdev = priv->netdev;
struct sk_buff *skb;
dma_addr_t map;
- int err;
+ int err = 0;
skb = netdev_alloc_skb_ip_align(netdev, RX_BUF_SIZE);
if (unlikely(!skb)) {
@@ -428,7 +428,7 @@ static int ftgmac100_alloc_rx_buf(struct ftgmac100 *priv, unsigned int entry,
else
rxdes->rxdes0 = 0;
- return 0;
+ return err;
}
static unsigned int ftgmac100_next_rx_pointer(struct ftgmac100 *priv,
@@ -1682,6 +1682,7 @@ static int ftgmac100_setup_mdio(struct net_device *netdev)
priv->mii_bus->name = "ftgmac100_mdio";
snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%d",
pdev->name, pdev->id);
+ priv->mii_bus->parent = priv->dev;
priv->mii_bus->priv = priv->netdev;
priv->mii_bus->read = ftgmac100_mdiobus_read;
priv->mii_bus->write = ftgmac100_mdiobus_write;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index ff864a187d5a..a37166ee577b 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -776,8 +776,9 @@ void hns_ae_update_led_status(struct hnae_handle *handle)
assert(handle);
mac_cb = hns_get_mac_cb(handle);
- if (!mac_cb->cpld_ctrl)
+ if (mac_cb->media_type != HNAE_MEDIA_TYPE_FIBER)
return;
+
hns_set_led_opt(mac_cb);
}
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
index 7a8addda726e..408b63faf9a8 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
@@ -53,6 +53,34 @@ static u32 dsaf_read_sub(struct dsaf_device *dsaf_dev, u32 reg)
return ret;
}
+static void hns_dsaf_acpi_ledctrl_by_port(struct hns_mac_cb *mac_cb, u8 op_type,
+ u32 link, u32 port, u32 act)
+{
+ union acpi_object *obj;
+ union acpi_object obj_args[3], argv4;
+
+ obj_args[0].integer.type = ACPI_TYPE_INTEGER;
+ obj_args[0].integer.value = link;
+ obj_args[1].integer.type = ACPI_TYPE_INTEGER;
+ obj_args[1].integer.value = port;
+ obj_args[2].integer.type = ACPI_TYPE_INTEGER;
+ obj_args[2].integer.value = act;
+
+ argv4.type = ACPI_TYPE_PACKAGE;
+ argv4.package.count = 3;
+ argv4.package.elements = obj_args;
+
+ obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev),
+ &hns_dsaf_acpi_dsm_guid, 0, op_type, &argv4);
+ if (!obj) {
+ dev_warn(mac_cb->dev, "ledctrl fail, link:%d port:%d act:%d!\n",
+ link, port, act);
+ return;
+ }
+
+ ACPI_FREE(obj);
+}
+
static void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status,
u16 speed, int data)
{
@@ -93,6 +121,18 @@ static void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status,
}
}
+static void hns_cpld_set_led_acpi(struct hns_mac_cb *mac_cb, int link_status,
+ u16 speed, int data)
+{
+ if (!mac_cb) {
+ pr_err("cpld_led_set mac_cb is null!\n");
+ return;
+ }
+
+ hns_dsaf_acpi_ledctrl_by_port(mac_cb, HNS_OP_LED_SET_FUNC,
+ link_status, mac_cb->mac_id, data);
+}
+
static void cpld_led_reset(struct hns_mac_cb *mac_cb)
{
if (!mac_cb || !mac_cb->cpld_ctrl)
@@ -103,6 +143,20 @@ static void cpld_led_reset(struct hns_mac_cb *mac_cb)
mac_cb->cpld_led_value = CPLD_LED_DEFAULT_VALUE;
}
+static void cpld_led_reset_acpi(struct hns_mac_cb *mac_cb)
+{
+ if (!mac_cb) {
+ pr_err("cpld_led_reset mac_cb is null!\n");
+ return;
+ }
+
+ if (mac_cb->media_type != HNAE_MEDIA_TYPE_FIBER)
+ return;
+
+ hns_dsaf_acpi_ledctrl_by_port(mac_cb, HNS_OP_LED_SET_FUNC,
+ 0, mac_cb->mac_id, 0);
+}
+
static int cpld_set_led_id(struct hns_mac_cb *mac_cb,
enum hnae_led_state status)
{
@@ -604,8 +658,8 @@ struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev)
misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback;
} else if (is_acpi_node(dsaf_dev->dev->fwnode)) {
- misc_op->cpld_set_led = hns_cpld_set_led;
- misc_op->cpld_reset_led = cpld_led_reset;
+ misc_op->cpld_set_led = hns_cpld_set_led_acpi;
+ misc_op->cpld_reset_led = cpld_led_reset_acpi;
misc_op->cpld_set_led_id = cpld_set_led_id;
misc_op->dsaf_reset = hns_dsaf_rst_acpi;
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index a3e694679635..c45e8e3b82d3 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -111,6 +111,7 @@ static void send_request_map(struct ibmvnic_adapter *, dma_addr_t, __be32, u8);
static void send_request_unmap(struct ibmvnic_adapter *, u8);
static void send_login(struct ibmvnic_adapter *adapter);
static void send_cap_queries(struct ibmvnic_adapter *adapter);
+static int init_sub_crqs(struct ibmvnic_adapter *);
static int init_sub_crq_irqs(struct ibmvnic_adapter *adapter);
static int ibmvnic_init(struct ibmvnic_adapter *);
static void release_crq_queue(struct ibmvnic_adapter *);
@@ -651,6 +652,7 @@ static int ibmvnic_login(struct net_device *netdev)
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
unsigned long timeout = msecs_to_jiffies(30000);
struct device *dev = &adapter->vdev->dev;
+ int rc;
do {
if (adapter->renegotiate) {
@@ -664,6 +666,18 @@ static int ibmvnic_login(struct net_device *netdev)
dev_err(dev, "Capabilities query timeout\n");
return -1;
}
+ rc = init_sub_crqs(adapter);
+ if (rc) {
+ dev_err(dev,
+ "Initialization of SCRQ's failed\n");
+ return -1;
+ }
+ rc = init_sub_crq_irqs(adapter);
+ if (rc) {
+ dev_err(dev,
+ "Initialization of SCRQ's irqs failed\n");
+ return -1;
+ }
}
reinit_completion(&adapter->init_done);
@@ -3004,7 +3018,6 @@ static void handle_request_cap_rsp(union ibmvnic_crq *crq,
*req_value,
(long int)be64_to_cpu(crq->request_capability_rsp.
number), name);
- release_sub_crqs(adapter);
*req_value = be64_to_cpu(crq->request_capability_rsp.number);
ibmvnic_send_req_caps(adapter, 1);
return;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index b936febc315a..2194960d5855 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -1113,6 +1113,8 @@ int i40e_setup_tx_descriptors(struct i40e_ring *tx_ring)
if (!tx_ring->tx_bi)
goto err;
+ u64_stats_init(&tx_ring->syncp);
+
/* round up to nearest 4K */
tx_ring->size = tx_ring->count * sizeof(struct i40e_tx_desc);
/* add u32 for head writeback, align after this takes care of
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 084c53582793..032f8ac06357 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -2988,6 +2988,8 @@ int ixgbevf_setup_tx_resources(struct ixgbevf_ring *tx_ring)
if (!tx_ring->tx_buffer_info)
goto err;
+ u64_stats_init(&tx_ring->syncp);
+
/* round up to nearest 4K */
tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc);
tx_ring->size = ALIGN(tx_ring->size, 4096);
@@ -3046,6 +3048,8 @@ int ixgbevf_setup_rx_resources(struct ixgbevf_ring *rx_ring)
if (!rx_ring->rx_buffer_info)
goto err;
+ u64_stats_init(&rx_ring->syncp);
+
/* Round up to nearest 4K */
rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc);
rx_ring->size = ALIGN(rx_ring->size, 4096);
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 5794d98d946f..9c94ea9b2b80 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -2734,7 +2734,7 @@ static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev,
ppd.shared = pdev;
memset(&res, 0, sizeof(res));
- if (!of_irq_to_resource(pnp, 0, &res)) {
+ if (of_irq_to_resource(pnp, 0, &res) <= 0) {
dev_err(&pdev->dev, "missing interrupt on %s\n", pnp->name);
return -EINVAL;
}
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index b3d0c2e6347a..e588a0cdb074 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -22,6 +22,7 @@
#include <linux/if_vlan.h>
#include <linux/reset.h>
#include <linux/tcp.h>
+#include <linux/interrupt.h>
#include "mtk_eth_soc.h"
@@ -947,6 +948,10 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
RX_DMA_FPORT_MASK;
mac--;
+ if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
+ !eth->netdev[mac]))
+ goto release_desc;
+
netdev = eth->netdev[mac];
if (unlikely(test_bit(MTK_RESETTING, &eth->state)))
diff --git a/drivers/net/ethernet/mellanox/mlx4/alloc.c b/drivers/net/ethernet/mellanox/mlx4/alloc.c
index 249a4584401a..b651c1210555 100644
--- a/drivers/net/ethernet/mellanox/mlx4/alloc.c
+++ b/drivers/net/ethernet/mellanox/mlx4/alloc.c
@@ -283,7 +283,7 @@ int mlx4_zone_add_one(struct mlx4_zone_allocator *zone_alloc,
}
/* Should be called under a lock */
-static int __mlx4_zone_remove_one_entry(struct mlx4_zone_entry *entry)
+static void __mlx4_zone_remove_one_entry(struct mlx4_zone_entry *entry)
{
struct mlx4_zone_allocator *zone_alloc = entry->allocator;
@@ -315,8 +315,6 @@ static int __mlx4_zone_remove_one_entry(struct mlx4_zone_entry *entry)
}
zone_alloc->mask = mask;
}
-
- return 0;
}
void mlx4_zone_allocator_destroy(struct mlx4_zone_allocator *zone_alloc)
@@ -457,7 +455,7 @@ struct mlx4_bitmap *mlx4_zone_get_bitmap(struct mlx4_zone_allocator *zones, u32
int mlx4_zone_remove_one(struct mlx4_zone_allocator *zones, u32 uid)
{
struct mlx4_zone_entry *zone;
- int res;
+ int res = 0;
spin_lock(&zones->lock);
@@ -468,7 +466,7 @@ int mlx4_zone_remove_one(struct mlx4_zone_allocator *zones, u32 uid)
goto out;
}
- res = __mlx4_zone_remove_one_entry(zone);
+ __mlx4_zone_remove_one_entry(zone);
out:
spin_unlock(&zones->lock);
@@ -578,7 +576,7 @@ out:
}
static int mlx4_buf_direct_alloc(struct mlx4_dev *dev, int size,
- struct mlx4_buf *buf, gfp_t gfp)
+ struct mlx4_buf *buf)
{
dma_addr_t t;
@@ -587,7 +585,7 @@ static int mlx4_buf_direct_alloc(struct mlx4_dev *dev, int size,
buf->page_shift = get_order(size) + PAGE_SHIFT;
buf->direct.buf =
dma_zalloc_coherent(&dev->persist->pdev->dev,
- size, &t, gfp);
+ size, &t, GFP_KERNEL);
if (!buf->direct.buf)
return -ENOMEM;
@@ -607,10 +605,10 @@ static int mlx4_buf_direct_alloc(struct mlx4_dev *dev, int size,
* multiple pages, so we don't require too much contiguous memory.
*/
int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct,
- struct mlx4_buf *buf, gfp_t gfp)
+ struct mlx4_buf *buf)
{
if (size <= max_direct) {
- return mlx4_buf_direct_alloc(dev, size, buf, gfp);
+ return mlx4_buf_direct_alloc(dev, size, buf);
} else {
dma_addr_t t;
int i;
@@ -620,14 +618,14 @@ int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct,
buf->npages = buf->nbufs;
buf->page_shift = PAGE_SHIFT;
buf->page_list = kcalloc(buf->nbufs, sizeof(*buf->page_list),
- gfp);
+ GFP_KERNEL);
if (!buf->page_list)
return -ENOMEM;
for (i = 0; i < buf->nbufs; ++i) {
buf->page_list[i].buf =
dma_zalloc_coherent(&dev->persist->pdev->dev,
- PAGE_SIZE, &t, gfp);
+ PAGE_SIZE, &t, GFP_KERNEL);
if (!buf->page_list[i].buf)
goto err_free;
@@ -663,12 +661,11 @@ void mlx4_buf_free(struct mlx4_dev *dev, int size, struct mlx4_buf *buf)
}
EXPORT_SYMBOL_GPL(mlx4_buf_free);
-static struct mlx4_db_pgdir *mlx4_alloc_db_pgdir(struct device *dma_device,
- gfp_t gfp)
+static struct mlx4_db_pgdir *mlx4_alloc_db_pgdir(struct device *dma_device)
{
struct mlx4_db_pgdir *pgdir;
- pgdir = kzalloc(sizeof *pgdir, gfp);
+ pgdir = kzalloc(sizeof(*pgdir), GFP_KERNEL);
if (!pgdir)
return NULL;
@@ -676,7 +673,7 @@ static struct mlx4_db_pgdir *mlx4_alloc_db_pgdir(struct device *dma_device,
pgdir->bits[0] = pgdir->order0;
pgdir->bits[1] = pgdir->order1;
pgdir->db_page = dma_alloc_coherent(dma_device, PAGE_SIZE,
- &pgdir->db_dma, gfp);
+ &pgdir->db_dma, GFP_KERNEL);
if (!pgdir->db_page) {
kfree(pgdir);
return NULL;
@@ -716,7 +713,7 @@ found:
return 0;
}
-int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order, gfp_t gfp)
+int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order)
{
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_db_pgdir *pgdir;
@@ -728,7 +725,7 @@ int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order, gfp_t gfp
if (!mlx4_alloc_db_from_pgdir(pgdir, db, order))
goto out;
- pgdir = mlx4_alloc_db_pgdir(&dev->persist->pdev->dev, gfp);
+ pgdir = mlx4_alloc_db_pgdir(&dev->persist->pdev->dev);
if (!pgdir) {
ret = -ENOMEM;
goto out;
@@ -780,13 +777,13 @@ int mlx4_alloc_hwq_res(struct mlx4_dev *dev, struct mlx4_hwq_resources *wqres,
{
int err;
- err = mlx4_db_alloc(dev, &wqres->db, 1, GFP_KERNEL);
+ err = mlx4_db_alloc(dev, &wqres->db, 1);
if (err)
return err;
*wqres->db.db = 0;
- err = mlx4_buf_direct_alloc(dev, size, &wqres->buf, GFP_KERNEL);
+ err = mlx4_buf_direct_alloc(dev, size, &wqres->buf);
if (err)
goto err_db;
@@ -795,7 +792,7 @@ int mlx4_alloc_hwq_res(struct mlx4_dev *dev, struct mlx4_hwq_resources *wqres,
if (err)
goto err_buf;
- err = mlx4_buf_write_mtt(dev, &wqres->mtt, &wqres->buf, GFP_KERNEL);
+ err = mlx4_buf_write_mtt(dev, &wqres->mtt, &wqres->buf);
if (err)
goto err_mtt;
diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c
index fa6d2354a0e9..c56a511b918e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cq.c
@@ -224,11 +224,11 @@ int __mlx4_cq_alloc_icm(struct mlx4_dev *dev, int *cqn)
if (*cqn == -1)
return -ENOMEM;
- err = mlx4_table_get(dev, &cq_table->table, *cqn, GFP_KERNEL);
+ err = mlx4_table_get(dev, &cq_table->table, *cqn);
if (err)
goto err_out;
- err = mlx4_table_get(dev, &cq_table->cmpt_table, *cqn, GFP_KERNEL);
+ err = mlx4_table_get(dev, &cq_table->cmpt_table, *cqn);
if (err)
goto err_put;
return 0;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index c751a1d434ad..3d4e4a5d00d1 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -223,6 +223,7 @@ static void mlx4_en_get_wol(struct net_device *netdev,
struct ethtool_wolinfo *wol)
{
struct mlx4_en_priv *priv = netdev_priv(netdev);
+ struct mlx4_caps *caps = &priv->mdev->dev->caps;
int err = 0;
u64 config = 0;
u64 mask;
@@ -235,24 +236,24 @@ static void mlx4_en_get_wol(struct net_device *netdev,
mask = (priv->port == 1) ? MLX4_DEV_CAP_FLAG_WOL_PORT1 :
MLX4_DEV_CAP_FLAG_WOL_PORT2;
- if (!(priv->mdev->dev->caps.flags & mask)) {
+ if (!(caps->flags & mask)) {
wol->supported = 0;
wol->wolopts = 0;
return;
}
+ if (caps->wol_port[priv->port])
+ wol->supported = WAKE_MAGIC;
+ else
+ wol->supported = 0;
+
err = mlx4_wol_read(priv->mdev->dev, &config, priv->port);
if (err) {
en_err(priv, "Failed to get WoL information\n");
return;
}
- if (config & MLX4_EN_WOL_MAGIC)
- wol->supported = WAKE_MAGIC;
- else
- wol->supported = 0;
-
- if (config & MLX4_EN_WOL_ENABLED)
+ if ((config & MLX4_EN_WOL_ENABLED) && (config & MLX4_EN_WOL_MAGIC))
wol->wolopts = WAKE_MAGIC;
else
wol->wolopts = 0;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index e5fb89505a13..bf1638044a7a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -574,16 +574,21 @@ static inline __wsum get_fixed_vlan_csum(__wsum hw_checksum,
* header, the HW adds it. To address that, we are subtracting the pseudo
* header checksum from the checksum value provided by the HW.
*/
-static void get_fixed_ipv4_csum(__wsum hw_checksum, struct sk_buff *skb,
- struct iphdr *iph)
+static int get_fixed_ipv4_csum(__wsum hw_checksum, struct sk_buff *skb,
+ struct iphdr *iph)
{
__u16 length_for_csum = 0;
__wsum csum_pseudo_header = 0;
+ __u8 ipproto = iph->protocol;
+
+ if (unlikely(ipproto == IPPROTO_SCTP))
+ return -1;
length_for_csum = (be16_to_cpu(iph->tot_len) - (iph->ihl << 2));
csum_pseudo_header = csum_tcpudp_nofold(iph->saddr, iph->daddr,
- length_for_csum, iph->protocol, 0);
+ length_for_csum, ipproto, 0);
skb->csum = csum_sub(hw_checksum, csum_pseudo_header);
+ return 0;
}
#if IS_ENABLED(CONFIG_IPV6)
@@ -594,17 +599,20 @@ static void get_fixed_ipv4_csum(__wsum hw_checksum, struct sk_buff *skb,
static int get_fixed_ipv6_csum(__wsum hw_checksum, struct sk_buff *skb,
struct ipv6hdr *ipv6h)
{
+ __u8 nexthdr = ipv6h->nexthdr;
__wsum csum_pseudo_hdr = 0;
- if (unlikely(ipv6h->nexthdr == IPPROTO_FRAGMENT ||
- ipv6h->nexthdr == IPPROTO_HOPOPTS))
+ if (unlikely(nexthdr == IPPROTO_FRAGMENT ||
+ nexthdr == IPPROTO_HOPOPTS ||
+ nexthdr == IPPROTO_SCTP))
return -1;
- hw_checksum = csum_add(hw_checksum, (__force __wsum)htons(ipv6h->nexthdr));
+ hw_checksum = csum_add(hw_checksum, (__force __wsum)htons(nexthdr));
csum_pseudo_hdr = csum_partial(&ipv6h->saddr,
sizeof(ipv6h->saddr) + sizeof(ipv6h->daddr), 0);
csum_pseudo_hdr = csum_add(csum_pseudo_hdr, (__force __wsum)ipv6h->payload_len);
- csum_pseudo_hdr = csum_add(csum_pseudo_hdr, (__force __wsum)ntohs(ipv6h->nexthdr));
+ csum_pseudo_hdr = csum_add(csum_pseudo_hdr,
+ (__force __wsum)htons(nexthdr));
skb->csum = csum_sub(hw_checksum, csum_pseudo_hdr);
skb->csum = csum_add(skb->csum, csum_partial(ipv6h, sizeof(struct ipv6hdr), 0));
@@ -627,11 +635,10 @@ static int check_csum(struct mlx4_cqe *cqe, struct sk_buff *skb, void *va,
}
if (cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPV4))
- get_fixed_ipv4_csum(hw_checksum, skb, hdr);
+ return get_fixed_ipv4_csum(hw_checksum, skb, hdr);
#if IS_ENABLED(CONFIG_IPV6)
- else if (cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPV6))
- if (unlikely(get_fixed_ipv6_csum(hw_checksum, skb, hdr)))
- return -1;
+ if (cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPV6))
+ return get_fixed_ipv6_csum(hw_checksum, skb, hdr);
#endif
return 0;
}
@@ -1042,7 +1049,7 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn,
if (!context)
return -ENOMEM;
- err = mlx4_qp_alloc(mdev->dev, qpn, qp, GFP_KERNEL);
+ err = mlx4_qp_alloc(mdev->dev, qpn, qp);
if (err) {
en_err(priv, "Failed to allocate qp #%x\n", qpn);
goto out;
@@ -1086,7 +1093,7 @@ int mlx4_en_create_drop_qp(struct mlx4_en_priv *priv)
en_err(priv, "Failed reserving drop qpn\n");
return err;
}
- err = mlx4_qp_alloc(priv->mdev->dev, qpn, &priv->drop_qp, GFP_KERNEL);
+ err = mlx4_qp_alloc(priv->mdev->dev, qpn, &priv->drop_qp);
if (err) {
en_err(priv, "Failed allocating drop qp\n");
mlx4_qp_release_range(priv->mdev->dev, qpn, 1);
@@ -1158,8 +1165,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
}
/* Configure RSS indirection qp */
- err = mlx4_qp_alloc(mdev->dev, priv->base_qpn, rss_map->indir_qp,
- GFP_KERNEL);
+ err = mlx4_qp_alloc(mdev->dev, priv->base_qpn, rss_map->indir_qp);
if (err) {
en_err(priv, "Failed to allocate RSS indirection QP\n");
goto rss_err;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index 4f3a9b27ce4a..73faa3d77921 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -111,7 +111,7 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
goto err_hwq_res;
}
- err = mlx4_qp_alloc(mdev->dev, ring->qpn, &ring->sp_qp, GFP_KERNEL);
+ err = mlx4_qp_alloc(mdev->dev, ring->qpn, &ring->sp_qp);
if (err) {
en_err(priv, "Failed allocating qp %d\n", ring->qpn);
goto err_reserve;
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 37e84a59e751..041c0ed65929 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -159,8 +159,9 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
[32] = "Loopback source checks support",
[33] = "RoCEv2 support",
[34] = "DMFS Sniffer support (UC & MC)",
- [35] = "QinQ VST mode support",
- [36] = "sl to vl mapping table change event support"
+ [35] = "Diag counters per port",
+ [36] = "QinQ VST mode support",
+ [37] = "sl to vl mapping table change event support",
};
int i;
@@ -764,6 +765,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
#define QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET 0x3e
#define QUERY_DEV_CAP_MAX_PKEY_OFFSET 0x3f
#define QUERY_DEV_CAP_EXT_FLAGS_OFFSET 0x40
+#define QUERY_DEV_CAP_WOL_OFFSET 0x43
#define QUERY_DEV_CAP_FLAGS_OFFSET 0x44
#define QUERY_DEV_CAP_RSVD_UAR_OFFSET 0x48
#define QUERY_DEV_CAP_UAR_SZ_OFFSET 0x49
@@ -920,6 +922,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
MLX4_GET(ext_flags, outbox, QUERY_DEV_CAP_EXT_FLAGS_OFFSET);
MLX4_GET(flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET);
dev_cap->flags = flags | (u64)ext_flags << 32;
+ MLX4_GET(field, outbox, QUERY_DEV_CAP_WOL_OFFSET);
+ dev_cap->wol_port[1] = !!(field & 0x20);
+ dev_cap->wol_port[2] = !!(field & 0x40);
MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET);
dev_cap->reserved_uars = field >> 4;
MLX4_GET(field, outbox, QUERY_DEV_CAP_UAR_SZ_OFFSET);
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h
index 5343a0599253..b52ba01aa486 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.h
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.h
@@ -129,6 +129,7 @@ struct mlx4_dev_cap {
u32 dmfs_high_rate_qpn_range;
struct mlx4_rate_limit_caps rl_caps;
struct mlx4_port_cap port_cap[MLX4_MAX_PORTS + 1];
+ bool wol_port[MLX4_MAX_PORTS + 1];
};
struct mlx4_func_cap {
diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.c b/drivers/net/ethernet/mellanox/mlx4/icm.c
index e1f9e7cebf8f..5a7816e7c7b4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/icm.c
+++ b/drivers/net/ethernet/mellanox/mlx4/icm.c
@@ -251,8 +251,7 @@ int mlx4_UNMAP_ICM_AUX(struct mlx4_dev *dev)
MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
}
-int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj,
- gfp_t gfp)
+int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj)
{
u32 i = (obj & (table->num_obj - 1)) /
(MLX4_TABLE_CHUNK_SIZE / table->obj_size);
@@ -266,7 +265,7 @@ int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj,
}
table->icm[i] = mlx4_alloc_icm(dev, MLX4_TABLE_CHUNK_SIZE >> PAGE_SHIFT,
- (table->lowmem ? gfp : GFP_HIGHUSER) |
+ (table->lowmem ? GFP_KERNEL : GFP_HIGHUSER) |
__GFP_NOWARN, table->coherent);
if (!table->icm[i]) {
ret = -ENOMEM;
@@ -363,7 +362,7 @@ int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
u32 i;
for (i = start; i <= end; i += inc) {
- err = mlx4_table_get(dev, table, i, GFP_KERNEL);
+ err = mlx4_table_get(dev, table, i);
if (err)
goto fail;
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.h b/drivers/net/ethernet/mellanox/mlx4/icm.h
index 0c7364550150..dee67fa39107 100644
--- a/drivers/net/ethernet/mellanox/mlx4/icm.h
+++ b/drivers/net/ethernet/mellanox/mlx4/icm.h
@@ -71,8 +71,7 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
gfp_t gfp_mask, int coherent);
void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent);
-int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj,
- gfp_t gfp);
+int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj);
void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj);
int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
u32 start, u32 end);
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index a27c9c13a36e..09b9bc17bce9 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -424,6 +424,8 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
dev->caps.stat_rate_support = dev_cap->stat_rate_support;
dev->caps.max_gso_sz = dev_cap->max_gso_sz;
dev->caps.max_rss_tbl_sz = dev_cap->max_rss_tbl_sz;
+ dev->caps.wol_port[1] = dev_cap->wol_port[1];
+ dev->caps.wol_port[2] = dev_cap->wol_port[2];
/* Save uar page shift */
if (!mlx4_is_slave(dev)) {
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 30616cd0140d..706d7f21ac5c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -969,7 +969,7 @@ void mlx4_cleanup_cq_table(struct mlx4_dev *dev);
void mlx4_cleanup_qp_table(struct mlx4_dev *dev);
void mlx4_cleanup_srq_table(struct mlx4_dev *dev);
void mlx4_cleanup_mcg_table(struct mlx4_dev *dev);
-int __mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn, gfp_t gfp);
+int __mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn);
void __mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn);
int __mlx4_cq_alloc_icm(struct mlx4_dev *dev, int *cqn);
void __mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn);
@@ -977,7 +977,7 @@ int __mlx4_srq_alloc_icm(struct mlx4_dev *dev, int *srqn);
void __mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn);
int __mlx4_mpt_reserve(struct mlx4_dev *dev);
void __mlx4_mpt_release(struct mlx4_dev *dev, u32 index);
-int __mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index, gfp_t gfp);
+int __mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index);
void __mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index);
u32 __mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order);
void __mlx4_free_mtt_range(struct mlx4_dev *dev, u32 first_seg, int order);
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c
index ce852ca22a96..24282cd017d3 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mr.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mr.c
@@ -479,14 +479,14 @@ static void mlx4_mpt_release(struct mlx4_dev *dev, u32 index)
__mlx4_mpt_release(dev, index);
}
-int __mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index, gfp_t gfp)
+int __mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index)
{
struct mlx4_mr_table *mr_table = &mlx4_priv(dev)->mr_table;
- return mlx4_table_get(dev, &mr_table->dmpt_table, index, gfp);
+ return mlx4_table_get(dev, &mr_table->dmpt_table, index);
}
-static int mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index, gfp_t gfp)
+static int mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index)
{
u64 param = 0;
@@ -497,7 +497,7 @@ static int mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index, gfp_t gfp)
MLX4_CMD_TIME_CLASS_A,
MLX4_CMD_WRAPPED);
}
- return __mlx4_mpt_alloc_icm(dev, index, gfp);
+ return __mlx4_mpt_alloc_icm(dev, index);
}
void __mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index)
@@ -629,7 +629,7 @@ int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr)
struct mlx4_mpt_entry *mpt_entry;
int err;
- err = mlx4_mpt_alloc_icm(dev, key_to_hw_index(mr->key), GFP_KERNEL);
+ err = mlx4_mpt_alloc_icm(dev, key_to_hw_index(mr->key));
if (err)
return err;
@@ -787,14 +787,13 @@ int mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
EXPORT_SYMBOL_GPL(mlx4_write_mtt);
int mlx4_buf_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
- struct mlx4_buf *buf, gfp_t gfp)
+ struct mlx4_buf *buf)
{
u64 *page_list;
int err;
int i;
- page_list = kmalloc(buf->npages * sizeof *page_list,
- gfp);
+ page_list = kcalloc(buf->npages, sizeof(*page_list), GFP_KERNEL);
if (!page_list)
return -ENOMEM;
@@ -841,7 +840,7 @@ int mlx4_mw_enable(struct mlx4_dev *dev, struct mlx4_mw *mw)
struct mlx4_mpt_entry *mpt_entry;
int err;
- err = mlx4_mpt_alloc_icm(dev, key_to_hw_index(mw->key), GFP_KERNEL);
+ err = mlx4_mpt_alloc_icm(dev, key_to_hw_index(mw->key));
if (err)
return err;
diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c
index 5a310d313e94..26747212526b 100644
--- a/drivers/net/ethernet/mellanox/mlx4/qp.c
+++ b/drivers/net/ethernet/mellanox/mlx4/qp.c
@@ -301,29 +301,29 @@ void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt)
}
EXPORT_SYMBOL_GPL(mlx4_qp_release_range);
-int __mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn, gfp_t gfp)
+int __mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn)
{
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_qp_table *qp_table = &priv->qp_table;
int err;
- err = mlx4_table_get(dev, &qp_table->qp_table, qpn, gfp);
+ err = mlx4_table_get(dev, &qp_table->qp_table, qpn);
if (err)
goto err_out;
- err = mlx4_table_get(dev, &qp_table->auxc_table, qpn, gfp);
+ err = mlx4_table_get(dev, &qp_table->auxc_table, qpn);
if (err)
goto err_put_qp;
- err = mlx4_table_get(dev, &qp_table->altc_table, qpn, gfp);
+ err = mlx4_table_get(dev, &qp_table->altc_table, qpn);
if (err)
goto err_put_auxc;
- err = mlx4_table_get(dev, &qp_table->rdmarc_table, qpn, gfp);
+ err = mlx4_table_get(dev, &qp_table->rdmarc_table, qpn);
if (err)
goto err_put_altc;
- err = mlx4_table_get(dev, &qp_table->cmpt_table, qpn, gfp);
+ err = mlx4_table_get(dev, &qp_table->cmpt_table, qpn);
if (err)
goto err_put_rdmarc;
@@ -345,7 +345,7 @@ err_out:
return err;
}
-static int mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn, gfp_t gfp)
+static int mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn)
{
u64 param = 0;
@@ -355,7 +355,7 @@ static int mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn, gfp_t gfp)
MLX4_CMD_ALLOC_RES, MLX4_CMD_TIME_CLASS_A,
MLX4_CMD_WRAPPED);
}
- return __mlx4_qp_alloc_icm(dev, qpn, gfp);
+ return __mlx4_qp_alloc_icm(dev, qpn);
}
void __mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn)
@@ -397,7 +397,7 @@ struct mlx4_qp *mlx4_qp_lookup(struct mlx4_dev *dev, u32 qpn)
return qp;
}
-int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp, gfp_t gfp)
+int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp)
{
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_qp_table *qp_table = &priv->qp_table;
@@ -408,7 +408,7 @@ int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp, gfp_t gfp)
qp->qpn = qpn;
- err = mlx4_qp_alloc_icm(dev, qpn, gfp);
+ err = mlx4_qp_alloc_icm(dev, qpn);
if (err)
return err;
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index 812783865205..215e21c3dc8a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -1822,7 +1822,7 @@ static int qp_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
return err;
if (!fw_reserved(dev, qpn)) {
- err = __mlx4_qp_alloc_icm(dev, qpn, GFP_KERNEL);
+ err = __mlx4_qp_alloc_icm(dev, qpn);
if (err) {
res_abort_move(dev, slave, RES_QP, qpn);
return err;
@@ -1909,7 +1909,7 @@ static int mpt_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
if (err)
return err;
- err = __mlx4_mpt_alloc_icm(dev, mpt->key, GFP_KERNEL);
+ err = __mlx4_mpt_alloc_icm(dev, mpt->key);
if (err) {
res_abort_move(dev, slave, RES_MPT, id);
return err;
diff --git a/drivers/net/ethernet/mellanox/mlx4/srq.c b/drivers/net/ethernet/mellanox/mlx4/srq.c
index f44d089e2ca6..bedf52126824 100644
--- a/drivers/net/ethernet/mellanox/mlx4/srq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/srq.c
@@ -100,11 +100,11 @@ int __mlx4_srq_alloc_icm(struct mlx4_dev *dev, int *srqn)
if (*srqn == -1)
return -ENOMEM;
- err = mlx4_table_get(dev, &srq_table->table, *srqn, GFP_KERNEL);
+ err = mlx4_table_get(dev, &srq_table->table, *srqn);
if (err)
goto err_out;
- err = mlx4_table_get(dev, &srq_table->cmpt_table, *srqn, GFP_KERNEL);
+ err = mlx4_table_get(dev, &srq_table->cmpt_table, *srqn);
if (err)
goto err_put;
return 0;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
index f5a2c605749f..31cbe5e86a01 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
@@ -786,6 +786,10 @@ static void cb_timeout_handler(struct work_struct *work)
mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true);
}
+static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg);
+static void mlx5_free_cmd_msg(struct mlx5_core_dev *dev,
+ struct mlx5_cmd_msg *msg);
+
static void cmd_work_handler(struct work_struct *work)
{
struct mlx5_cmd_work_ent *ent = container_of(work, struct mlx5_cmd_work_ent, work);
@@ -796,17 +800,28 @@ static void cmd_work_handler(struct work_struct *work)
struct semaphore *sem;
unsigned long flags;
bool poll_cmd = ent->polling;
+ int alloc_ret;
sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem;
down(sem);
if (!ent->page_queue) {
- ent->idx = alloc_ent(cmd);
- if (ent->idx < 0) {
+ alloc_ret = alloc_ent(cmd);
+ if (alloc_ret < 0) {
mlx5_core_err(dev, "failed to allocate command entry\n");
+ if (ent->callback) {
+ ent->callback(-EAGAIN, ent->context);
+ mlx5_free_cmd_msg(dev, ent->out);
+ free_msg(dev, ent->in);
+ free_cmd(ent);
+ } else {
+ ent->ret = -EAGAIN;
+ complete(&ent->done);
+ }
up(sem);
return;
}
+ ent->idx = alloc_ret;
} else {
ent->idx = cmd->max_reg_cmds;
spin_lock_irqsave(&cmd->alloc_lock, flags);
@@ -967,7 +982,7 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
err = wait_func(dev, ent);
if (err == -ETIMEDOUT)
- goto out_free;
+ goto out;
ds = ent->ts2 - ent->ts1;
op = MLX5_GET(mbox_in, in->first.data, opcode);
@@ -1430,6 +1445,7 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool forced)
mlx5_core_err(dev, "Command completion arrived after timeout (entry idx = %d).\n",
ent->idx);
free_ent(cmd, ent->idx);
+ free_cmd(ent);
}
continue;
}
@@ -1488,7 +1504,8 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool forced)
free_msg(dev, ent->in);
err = err ? err : ent->status;
- free_cmd(ent);
+ if (!forced)
+ free_cmd(ent);
callback(err, context);
} else {
complete(&ent->done);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index e1b7ddfecd01..0039b4725405 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -266,6 +266,14 @@ struct mlx5e_dcbx {
};
#endif
+#define MAX_PIN_NUM 8
+struct mlx5e_pps {
+ u8 pin_caps[MAX_PIN_NUM];
+ struct work_struct out_work;
+ u64 start[MAX_PIN_NUM];
+ u8 enabled;
+};
+
struct mlx5e_tstamp {
rwlock_t lock;
struct cyclecounter cycles;
@@ -277,7 +285,7 @@ struct mlx5e_tstamp {
struct mlx5_core_dev *mdev;
struct ptp_clock *ptp;
struct ptp_clock_info ptp_info;
- u8 *pps_pin_caps;
+ struct mlx5e_pps pps_info;
};
enum {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_clock.c b/drivers/net/ethernet/mellanox/mlx5/core/en_clock.c
index 66f432385dbb..84dd63e74041 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_clock.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_clock.c
@@ -53,6 +53,15 @@ enum {
MLX5E_EVENT_MODE_ONCE_TILL_ARM = 0x2,
};
+enum {
+ MLX5E_MTPPS_FS_ENABLE = BIT(0x0),
+ MLX5E_MTPPS_FS_PATTERN = BIT(0x2),
+ MLX5E_MTPPS_FS_PIN_MODE = BIT(0x3),
+ MLX5E_MTPPS_FS_TIME_STAMP = BIT(0x4),
+ MLX5E_MTPPS_FS_OUT_PULSE_DURATION = BIT(0x5),
+ MLX5E_MTPPS_FS_ENH_OUT_PER_ADJ = BIT(0x7),
+};
+
void mlx5e_fill_hwstamp(struct mlx5e_tstamp *tstamp, u64 timestamp,
struct skb_shared_hwtstamps *hwts)
{
@@ -73,17 +82,46 @@ static u64 mlx5e_read_internal_timer(const struct cyclecounter *cc)
return mlx5_read_internal_timer(tstamp->mdev) & cc->mask;
}
+static void mlx5e_pps_out(struct work_struct *work)
+{
+ struct mlx5e_pps *pps_info = container_of(work, struct mlx5e_pps,
+ out_work);
+ struct mlx5e_tstamp *tstamp = container_of(pps_info, struct mlx5e_tstamp,
+ pps_info);
+ u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0};
+ unsigned long flags;
+ int i;
+
+ for (i = 0; i < tstamp->ptp_info.n_pins; i++) {
+ u64 tstart;
+
+ write_lock_irqsave(&tstamp->lock, flags);
+ tstart = tstamp->pps_info.start[i];
+ tstamp->pps_info.start[i] = 0;
+ write_unlock_irqrestore(&tstamp->lock, flags);
+ if (!tstart)
+ continue;
+
+ MLX5_SET(mtpps_reg, in, pin, i);
+ MLX5_SET64(mtpps_reg, in, time_stamp, tstart);
+ MLX5_SET(mtpps_reg, in, field_select, MLX5E_MTPPS_FS_TIME_STAMP);
+ mlx5_set_mtpps(tstamp->mdev, in, sizeof(in));
+ }
+}
+
static void mlx5e_timestamp_overflow(struct work_struct *work)
{
struct delayed_work *dwork = to_delayed_work(work);
struct mlx5e_tstamp *tstamp = container_of(dwork, struct mlx5e_tstamp,
overflow_work);
+ struct mlx5e_priv *priv = container_of(tstamp, struct mlx5e_priv, tstamp);
unsigned long flags;
write_lock_irqsave(&tstamp->lock, flags);
timecounter_read(&tstamp->clock);
write_unlock_irqrestore(&tstamp->lock, flags);
- schedule_delayed_work(&tstamp->overflow_work, tstamp->overflow_period);
+ queue_delayed_work(priv->wq, &tstamp->overflow_work,
+ msecs_to_jiffies(tstamp->overflow_period * 1000));
}
int mlx5e_hwstamp_set(struct mlx5e_priv *priv, struct ifreq *ifr)
@@ -213,18 +251,6 @@ static int mlx5e_ptp_adjfreq(struct ptp_clock_info *ptp, s32 delta)
int neg_adj = 0;
struct mlx5e_tstamp *tstamp = container_of(ptp, struct mlx5e_tstamp,
ptp_info);
- struct mlx5e_priv *priv =
- container_of(tstamp, struct mlx5e_priv, tstamp);
-
- if (MLX5_CAP_GEN(priv->mdev, pps_modify)) {
- u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0};
-
- /* For future use need to add a loop for finding all 1PPS out pins */
- MLX5_SET(mtpps_reg, in, pin_mode, MLX5E_PIN_MODE_OUT);
- MLX5_SET(mtpps_reg, in, out_periodic_adjustment, delta & 0xFFFF);
-
- mlx5_set_mtpps(priv->mdev, in, sizeof(in));
- }
if (delta < 0) {
neg_adj = 1;
@@ -253,12 +279,13 @@ static int mlx5e_extts_configure(struct ptp_clock_info *ptp,
struct mlx5e_priv *priv =
container_of(tstamp, struct mlx5e_priv, tstamp);
u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0};
+ u32 field_select = 0;
+ u8 pin_mode = 0;
u8 pattern = 0;
int pin = -1;
int err = 0;
- if (!MLX5_CAP_GEN(priv->mdev, pps) ||
- !MLX5_CAP_GEN(priv->mdev, pps_modify))
+ if (!MLX5_PPS_CAP(priv->mdev))
return -EOPNOTSUPP;
if (rq->extts.index >= tstamp->ptp_info.n_pins)
@@ -268,15 +295,21 @@ static int mlx5e_extts_configure(struct ptp_clock_info *ptp,
pin = ptp_find_pin(tstamp->ptp, PTP_PF_EXTTS, rq->extts.index);
if (pin < 0)
return -EBUSY;
+ pin_mode = MLX5E_PIN_MODE_IN;
+ pattern = !!(rq->extts.flags & PTP_FALLING_EDGE);
+ field_select = MLX5E_MTPPS_FS_PIN_MODE |
+ MLX5E_MTPPS_FS_PATTERN |
+ MLX5E_MTPPS_FS_ENABLE;
+ } else {
+ pin = rq->extts.index;
+ field_select = MLX5E_MTPPS_FS_ENABLE;
}
- if (rq->extts.flags & PTP_FALLING_EDGE)
- pattern = 1;
-
MLX5_SET(mtpps_reg, in, pin, pin);
- MLX5_SET(mtpps_reg, in, pin_mode, MLX5E_PIN_MODE_IN);
+ MLX5_SET(mtpps_reg, in, pin_mode, pin_mode);
MLX5_SET(mtpps_reg, in, pattern, pattern);
MLX5_SET(mtpps_reg, in, enable, on);
+ MLX5_SET(mtpps_reg, in, field_select, field_select);
err = mlx5_set_mtpps(priv->mdev, in, sizeof(in));
if (err)
@@ -295,14 +328,18 @@ static int mlx5e_perout_configure(struct ptp_clock_info *ptp,
struct mlx5e_priv *priv =
container_of(tstamp, struct mlx5e_priv, tstamp);
u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0};
- u64 nsec_now, nsec_delta, time_stamp;
+ u64 nsec_now, nsec_delta, time_stamp = 0;
u64 cycles_now, cycles_delta;
struct timespec64 ts;
unsigned long flags;
+ u32 field_select = 0;
+ u8 pin_mode = 0;
+ u8 pattern = 0;
int pin = -1;
+ int err = 0;
s64 ns;
- if (!MLX5_CAP_GEN(priv->mdev, pps_modify))
+ if (!MLX5_PPS_CAP(priv->mdev))
return -EOPNOTSUPP;
if (rq->perout.index >= tstamp->ptp_info.n_pins)
@@ -313,32 +350,60 @@ static int mlx5e_perout_configure(struct ptp_clock_info *ptp,
rq->perout.index);
if (pin < 0)
return -EBUSY;
- }
- ts.tv_sec = rq->perout.period.sec;
- ts.tv_nsec = rq->perout.period.nsec;
- ns = timespec64_to_ns(&ts);
- if (on)
+ pin_mode = MLX5E_PIN_MODE_OUT;
+ pattern = MLX5E_OUT_PATTERN_PERIODIC;
+ ts.tv_sec = rq->perout.period.sec;
+ ts.tv_nsec = rq->perout.period.nsec;
+ ns = timespec64_to_ns(&ts);
+
if ((ns >> 1) != 500000000LL)
return -EINVAL;
- ts.tv_sec = rq->perout.start.sec;
- ts.tv_nsec = rq->perout.start.nsec;
- ns = timespec64_to_ns(&ts);
- cycles_now = mlx5_read_internal_timer(tstamp->mdev);
- write_lock_irqsave(&tstamp->lock, flags);
- nsec_now = timecounter_cyc2time(&tstamp->clock, cycles_now);
- nsec_delta = ns - nsec_now;
- cycles_delta = div64_u64(nsec_delta << tstamp->cycles.shift,
- tstamp->cycles.mult);
- write_unlock_irqrestore(&tstamp->lock, flags);
- time_stamp = cycles_now + cycles_delta;
+
+ ts.tv_sec = rq->perout.start.sec;
+ ts.tv_nsec = rq->perout.start.nsec;
+ ns = timespec64_to_ns(&ts);
+ cycles_now = mlx5_read_internal_timer(tstamp->mdev);
+ write_lock_irqsave(&tstamp->lock, flags);
+ nsec_now = timecounter_cyc2time(&tstamp->clock, cycles_now);
+ nsec_delta = ns - nsec_now;
+ cycles_delta = div64_u64(nsec_delta << tstamp->cycles.shift,
+ tstamp->cycles.mult);
+ write_unlock_irqrestore(&tstamp->lock, flags);
+ time_stamp = cycles_now + cycles_delta;
+ field_select = MLX5E_MTPPS_FS_PIN_MODE |
+ MLX5E_MTPPS_FS_PATTERN |
+ MLX5E_MTPPS_FS_ENABLE |
+ MLX5E_MTPPS_FS_TIME_STAMP;
+ } else {
+ pin = rq->perout.index;
+ field_select = MLX5E_MTPPS_FS_ENABLE;
+ }
+
MLX5_SET(mtpps_reg, in, pin, pin);
- MLX5_SET(mtpps_reg, in, pin_mode, MLX5E_PIN_MODE_OUT);
- MLX5_SET(mtpps_reg, in, pattern, MLX5E_OUT_PATTERN_PERIODIC);
+ MLX5_SET(mtpps_reg, in, pin_mode, pin_mode);
+ MLX5_SET(mtpps_reg, in, pattern, pattern);
MLX5_SET(mtpps_reg, in, enable, on);
MLX5_SET64(mtpps_reg, in, time_stamp, time_stamp);
+ MLX5_SET(mtpps_reg, in, field_select, field_select);
+
+ err = mlx5_set_mtpps(priv->mdev, in, sizeof(in));
+ if (err)
+ return err;
- return mlx5_set_mtpps(priv->mdev, in, sizeof(in));
+ return mlx5_set_mtppse(priv->mdev, pin, 0,
+ MLX5E_EVENT_MODE_REPETETIVE & on);
+}
+
+static int mlx5e_pps_configure(struct ptp_clock_info *ptp,
+ struct ptp_clock_request *rq,
+ int on)
+{
+ struct mlx5e_tstamp *tstamp =
+ container_of(ptp, struct mlx5e_tstamp, ptp_info);
+
+ tstamp->pps_info.enabled = !!on;
+ return 0;
}
static int mlx5e_ptp_enable(struct ptp_clock_info *ptp,
@@ -350,6 +415,8 @@ static int mlx5e_ptp_enable(struct ptp_clock_info *ptp,
return mlx5e_extts_configure(ptp, rq, on);
case PTP_CLK_REQ_PEROUT:
return mlx5e_perout_configure(ptp, rq, on);
+ case PTP_CLK_REQ_PPS:
+ return mlx5e_pps_configure(ptp, rq, on);
default:
return -EOPNOTSUPP;
}
@@ -395,6 +462,7 @@ static int mlx5e_init_pin_config(struct mlx5e_tstamp *tstamp)
return -ENOMEM;
tstamp->ptp_info.enable = mlx5e_ptp_enable;
tstamp->ptp_info.verify = mlx5e_ptp_verify;
+ tstamp->ptp_info.pps = 1;
for (i = 0; i < tstamp->ptp_info.n_pins; i++) {
snprintf(tstamp->ptp_info.pin_config[i].name,
@@ -422,22 +490,56 @@ static void mlx5e_get_pps_caps(struct mlx5e_priv *priv,
tstamp->ptp_info.n_per_out = MLX5_GET(mtpps_reg, out,
cap_max_num_of_pps_out_pins);
- tstamp->pps_pin_caps[0] = MLX5_GET(mtpps_reg, out, cap_pin_0_mode);
- tstamp->pps_pin_caps[1] = MLX5_GET(mtpps_reg, out, cap_pin_1_mode);
- tstamp->pps_pin_caps[2] = MLX5_GET(mtpps_reg, out, cap_pin_2_mode);
- tstamp->pps_pin_caps[3] = MLX5_GET(mtpps_reg, out, cap_pin_3_mode);
- tstamp->pps_pin_caps[4] = MLX5_GET(mtpps_reg, out, cap_pin_4_mode);
- tstamp->pps_pin_caps[5] = MLX5_GET(mtpps_reg, out, cap_pin_5_mode);
- tstamp->pps_pin_caps[6] = MLX5_GET(mtpps_reg, out, cap_pin_6_mode);
- tstamp->pps_pin_caps[7] = MLX5_GET(mtpps_reg, out, cap_pin_7_mode);
+ tstamp->pps_info.pin_caps[0] = MLX5_GET(mtpps_reg, out, cap_pin_0_mode);
+ tstamp->pps_info.pin_caps[1] = MLX5_GET(mtpps_reg, out, cap_pin_1_mode);
+ tstamp->pps_info.pin_caps[2] = MLX5_GET(mtpps_reg, out, cap_pin_2_mode);
+ tstamp->pps_info.pin_caps[3] = MLX5_GET(mtpps_reg, out, cap_pin_3_mode);
+ tstamp->pps_info.pin_caps[4] = MLX5_GET(mtpps_reg, out, cap_pin_4_mode);
+ tstamp->pps_info.pin_caps[5] = MLX5_GET(mtpps_reg, out, cap_pin_5_mode);
+ tstamp->pps_info.pin_caps[6] = MLX5_GET(mtpps_reg, out, cap_pin_6_mode);
+ tstamp->pps_info.pin_caps[7] = MLX5_GET(mtpps_reg, out, cap_pin_7_mode);
}
void mlx5e_pps_event_handler(struct mlx5e_priv *priv,
struct ptp_clock_event *event)
{
+ struct net_device *netdev = priv->netdev;
struct mlx5e_tstamp *tstamp = &priv->tstamp;
+ struct timespec64 ts;
+ u64 nsec_now, nsec_delta;
+ u64 cycles_now, cycles_delta;
+ int pin = event->index;
+ s64 ns;
+ unsigned long flags;
- ptp_clock_event(tstamp->ptp, event);
+ switch (tstamp->ptp_info.pin_config[pin].func) {
+ case PTP_PF_EXTTS:
+ if (tstamp->pps_info.enabled) {
+ event->type = PTP_CLOCK_PPSUSR;
+ event->pps_times.ts_real = ns_to_timespec64(event->timestamp);
+ } else {
+ event->type = PTP_CLOCK_EXTTS;
+ }
+ ptp_clock_event(tstamp->ptp, event);
+ break;
+ case PTP_PF_PEROUT:
+ mlx5e_ptp_gettime(&tstamp->ptp_info, &ts);
+ cycles_now = mlx5_read_internal_timer(tstamp->mdev);
+ ts.tv_sec += 1;
+ ts.tv_nsec = 0;
+ ns = timespec64_to_ns(&ts);
+ write_lock_irqsave(&tstamp->lock, flags);
+ nsec_now = timecounter_cyc2time(&tstamp->clock, cycles_now);
+ nsec_delta = ns - nsec_now;
+ cycles_delta = div64_u64(nsec_delta << tstamp->cycles.shift,
+ tstamp->cycles.mult);
+ tstamp->pps_info.start[pin] = cycles_now + cycles_delta;
+ queue_work(priv->wq, &tstamp->pps_info.out_work);
+ write_unlock_irqrestore(&tstamp->lock, flags);
+ break;
+ default:
+ netdev_err(netdev, "%s: Unhandled event\n", __func__);
+ }
}
void mlx5e_timestamp_init(struct mlx5e_priv *priv)
@@ -473,9 +575,10 @@ void mlx5e_timestamp_init(struct mlx5e_priv *priv)
do_div(ns, NSEC_PER_SEC / 2 / HZ);
tstamp->overflow_period = ns;
+ INIT_WORK(&tstamp->pps_info.out_work, mlx5e_pps_out);
INIT_DELAYED_WORK(&tstamp->overflow_work, mlx5e_timestamp_overflow);
if (tstamp->overflow_period)
- schedule_delayed_work(&tstamp->overflow_work, 0);
+ queue_delayed_work(priv->wq, &tstamp->overflow_work, 0);
else
mlx5_core_warn(priv->mdev, "invalid overflow period, overflow_work is not scheduled\n");
@@ -484,16 +587,10 @@ void mlx5e_timestamp_init(struct mlx5e_priv *priv)
snprintf(tstamp->ptp_info.name, 16, "mlx5 ptp");
/* Initialize 1PPS data structures */
-#define MAX_PIN_NUM 8
- tstamp->pps_pin_caps = kzalloc(sizeof(u8) * MAX_PIN_NUM, GFP_KERNEL);
- if (tstamp->pps_pin_caps) {
- if (MLX5_CAP_GEN(priv->mdev, pps))
- mlx5e_get_pps_caps(priv, tstamp);
- if (tstamp->ptp_info.n_pins)
- mlx5e_init_pin_config(tstamp);
- } else {
- mlx5_core_warn(priv->mdev, "1PPS initialization failed\n");
- }
+ if (MLX5_PPS_CAP(priv->mdev))
+ mlx5e_get_pps_caps(priv, tstamp);
+ if (tstamp->ptp_info.n_pins)
+ mlx5e_init_pin_config(tstamp);
tstamp->ptp = ptp_clock_register(&tstamp->ptp_info,
&priv->mdev->pdev->dev);
@@ -516,8 +613,7 @@ void mlx5e_timestamp_cleanup(struct mlx5e_priv *priv)
priv->tstamp.ptp = NULL;
}
- kfree(tstamp->pps_pin_caps);
- kfree(tstamp->ptp_info.pin_config);
-
+ cancel_work_sync(&tstamp->pps_info.out_work);
cancel_delayed_work_sync(&tstamp->overflow_work);
+ kfree(tstamp->ptp_info.pin_config);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
index bdd82c9b3992..eafc59280ada 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
@@ -276,7 +276,7 @@ static void add_rule_to_list(struct mlx5e_priv *priv,
static bool outer_header_zero(u32 *match_criteria)
{
- int size = MLX5_ST_SZ_BYTES(fte_match_param);
+ int size = MLX5_FLD_SZ_BYTES(fte_match_param, outer_headers);
char *outer_headers_c = MLX5_ADDR_OF(fte_match_param, match_criteria,
outer_headers);
@@ -320,7 +320,7 @@ add_ethtool_flow_rule(struct mlx5e_priv *priv,
spec->match_criteria_enable = (!outer_header_zero(spec->match_criteria));
flow_act.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG;
- rule = mlx5_add_flow_rules(ft, spec, &flow_act, dst, 1);
+ rule = mlx5_add_flow_rules(ft, spec, &flow_act, dst, dst ? 1 : 0);
if (IS_ERR(rule)) {
err = PTR_ERR(rule);
netdev_err(priv->netdev, "%s: failed to add ethtool steering rule: %d\n",
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 1eac5003084f..57f31fa478ce 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -377,7 +377,6 @@ static void mlx5e_async_event(struct mlx5_core_dev *mdev, void *vpriv,
break;
case MLX5_DEV_EVENT_PPS:
eqe = (struct mlx5_eqe *)param;
- ptp_event.type = PTP_CLOCK_EXTTS;
ptp_event.index = eqe->data.pps.pin;
ptp_event.timestamp =
timecounter_cyc2time(&priv->tstamp.clock,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
index af51a5d2b912..52b9a64cd3a2 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
@@ -698,7 +698,7 @@ int mlx5_start_eqs(struct mlx5_core_dev *dev)
else
mlx5_core_dbg(dev, "port_module_event is not set\n");
- if (MLX5_CAP_GEN(dev, pps))
+ if (MLX5_PPS_CAP(dev))
async_event_mask |= (1ull << MLX5_EVENT_TYPE_PPS_EVENT);
if (MLX5_CAP_GEN(dev, fpga))
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
index 89bfda419efe..8b18cc9ec026 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -1668,7 +1668,8 @@ void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw)
int i;
if (!esw || !MLX5_CAP_GEN(esw->dev, vport_group_manager) ||
- MLX5_CAP_GEN(esw->dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
+ MLX5_CAP_GEN(esw->dev, port_type) != MLX5_CAP_PORT_TYPE_ETH ||
+ esw->mode == SRIOV_NONE)
return;
esw_info(esw->dev, "disable SRIOV: active vports(%d) mode(%d)\n",
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
index 1ee5bce85901..85298051a3e4 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
@@ -178,8 +178,6 @@ out:
static void mlx5i_destroy_underlay_qp(struct mlx5_core_dev *mdev, struct mlx5_core_qp *qp)
{
- mlx5_fs_remove_rx_underlay_qpn(mdev, qp->qpn);
-
mlx5_core_destroy_qp(mdev, qp);
}
@@ -194,8 +192,6 @@ static int mlx5i_init_tx(struct mlx5e_priv *priv)
return err;
}
- mlx5_fs_add_rx_underlay_qpn(priv->mdev, ipriv->qp.qpn);
-
err = mlx5e_create_tis(priv->mdev, 0 /* tc */, ipriv->qp.qpn, &priv->tisn[0]);
if (err) {
mlx5_core_warn(priv->mdev, "create tis failed, %d\n", err);
@@ -253,6 +249,7 @@ static void mlx5i_destroy_flow_steering(struct mlx5e_priv *priv)
static int mlx5i_init_rx(struct mlx5e_priv *priv)
{
+ struct mlx5i_priv *ipriv = priv->ppriv;
int err;
err = mlx5e_create_indirect_rqt(priv);
@@ -271,12 +268,18 @@ static int mlx5i_init_rx(struct mlx5e_priv *priv)
if (err)
goto err_destroy_indirect_tirs;
- err = mlx5i_create_flow_steering(priv);
+ err = mlx5_fs_add_rx_underlay_qpn(priv->mdev, ipriv->qp.qpn);
if (err)
goto err_destroy_direct_tirs;
+ err = mlx5i_create_flow_steering(priv);
+ if (err)
+ goto err_remove_rx_underlay_qpn;
+
return 0;
+err_remove_rx_underlay_qpn:
+ mlx5_fs_remove_rx_underlay_qpn(priv->mdev, ipriv->qp.qpn);
err_destroy_direct_tirs:
mlx5e_destroy_direct_tirs(priv);
err_destroy_indirect_tirs:
@@ -290,6 +293,9 @@ err_destroy_indirect_rqts:
static void mlx5i_cleanup_rx(struct mlx5e_priv *priv)
{
+ struct mlx5i_priv *ipriv = priv->ppriv;
+
+ mlx5_fs_remove_rx_underlay_qpn(priv->mdev, ipriv->qp.qpn);
mlx5i_destroy_flow_steering(priv);
mlx5e_destroy_direct_tirs(priv);
mlx5e_destroy_indirect_tirs(priv);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag.c
index a3a836bdcfd2..f26f97fe4666 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lag.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lag.c
@@ -162,22 +162,17 @@ static bool mlx5_lag_is_bonded(struct mlx5_lag *ldev)
static void mlx5_infer_tx_affinity_mapping(struct lag_tracker *tracker,
u8 *port1, u8 *port2)
{
- if (tracker->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP) {
- if (tracker->netdev_state[0].tx_enabled) {
- *port1 = 1;
- *port2 = 1;
- } else {
- *port1 = 2;
- *port2 = 2;
- }
- } else {
- *port1 = 1;
- *port2 = 2;
- if (!tracker->netdev_state[0].link_up)
- *port1 = 2;
- else if (!tracker->netdev_state[1].link_up)
- *port2 = 1;
+ *port1 = 1;
+ *port2 = 2;
+ if (!tracker->netdev_state[0].tx_enabled ||
+ !tracker->netdev_state[0].link_up) {
+ *port1 = 2;
+ return;
}
+
+ if (!tracker->netdev_state[1].tx_enabled ||
+ !tracker->netdev_state[1].link_up)
+ *port2 = 1;
}
static void mlx5_activate_lag(struct mlx5_lag *ldev,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
index 6a3d6bef7dd4..6a263e8d883a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
@@ -154,6 +154,11 @@ int mlx5_set_mtpps(struct mlx5_core_dev *mdev, u32 *mtpps, u32 mtpps_size);
int mlx5_query_mtppse(struct mlx5_core_dev *mdev, u8 pin, u8 *arm, u8 *mode);
int mlx5_set_mtppse(struct mlx5_core_dev *mdev, u8 pin, u8 arm, u8 mode);
+#define MLX5_PPS_CAP(mdev) (MLX5_CAP_GEN((mdev), pps) && \
+ MLX5_CAP_GEN((mdev), pps_modify) && \
+ MLX5_CAP_MCAM_FEATURE((mdev), mtpps_fs) && \
+ MLX5_CAP_MCAM_FEATURE((mdev), mtpps_enh_out_per_adj))
+
int mlx5_firmware_flash(struct mlx5_core_dev *dev, const struct firmware *fw);
void mlx5e_init(void);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
index bcdf7779c48d..bf99d40e30b4 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c
@@ -88,7 +88,11 @@ static void mlx5_device_disable_sriov(struct mlx5_core_dev *dev)
int vf;
if (!sriov->enabled_vfs)
+#ifdef CONFIG_MLX5_CORE_EN
+ goto disable_sriov_resources;
+#else
return;
+#endif
for (vf = 0; vf < sriov->num_vfs; vf++) {
if (!sriov->vfs_ctx[vf].enabled)
@@ -103,6 +107,7 @@ static void mlx5_device_disable_sriov(struct mlx5_core_dev *dev)
}
#ifdef CONFIG_MLX5_CORE_EN
+disable_sriov_resources:
mlx5_eswitch_disable_sriov(dev->priv.eswitch);
#endif
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 383fef5a8e24..4b2e0fd7d51e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -1512,6 +1512,10 @@ mlxsw_sp_nexthop_group_mac_update(struct mlxsw_sp *mlxsw_sp,
static int mlxsw_sp_fib_entry_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry);
+static bool
+mlxsw_sp_fib_node_entry_is_first(const struct mlxsw_sp_fib_node *fib_node,
+ const struct mlxsw_sp_fib_entry *fib_entry);
+
static int
mlxsw_sp_nexthop_fib_entries_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_group *nh_grp)
@@ -1520,6 +1524,9 @@ mlxsw_sp_nexthop_fib_entries_update(struct mlxsw_sp *mlxsw_sp,
int err;
list_for_each_entry(fib_entry, &nh_grp->fib_list, nexthop_group_node) {
+ if (!mlxsw_sp_fib_node_entry_is_first(fib_entry->fib_node,
+ fib_entry))
+ continue;
err = mlxsw_sp_fib_entry_update(mlxsw_sp, fib_entry);
if (err)
return err;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 656b2d3f1bee..5eb1606765c5 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -626,8 +626,8 @@ static int mlxsw_sp_port_attr_br_flags_set(struct mlxsw_sp_port *mlxsw_sp_port,
bridge_port = mlxsw_sp_bridge_port_find(mlxsw_sp_port->mlxsw_sp->bridge,
orig_dev);
- if (WARN_ON(!bridge_port))
- return -EINVAL;
+ if (!bridge_port)
+ return 0;
err = mlxsw_sp_bridge_port_flood_table_set(mlxsw_sp_port, bridge_port,
MLXSW_SP_FLOOD_TYPE_UC,
@@ -711,8 +711,8 @@ static int mlxsw_sp_port_attr_mc_router_set(struct mlxsw_sp_port *mlxsw_sp_port,
bridge_port = mlxsw_sp_bridge_port_find(mlxsw_sp_port->mlxsw_sp->bridge,
orig_dev);
- if (WARN_ON(!bridge_port))
- return -EINVAL;
+ if (!bridge_port)
+ return 0;
if (!bridge_port->bridge_device->multicast_enabled)
return 0;
@@ -1283,15 +1283,15 @@ static int mlxsw_sp_port_mdb_add(struct mlxsw_sp_port *mlxsw_sp_port,
return 0;
bridge_port = mlxsw_sp_bridge_port_find(mlxsw_sp->bridge, orig_dev);
- if (WARN_ON(!bridge_port))
- return -EINVAL;
+ if (!bridge_port)
+ return 0;
bridge_device = bridge_port->bridge_device;
mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_bridge(mlxsw_sp_port,
bridge_device,
mdb->vid);
- if (WARN_ON(!mlxsw_sp_port_vlan))
- return -EINVAL;
+ if (!mlxsw_sp_port_vlan)
+ return 0;
fid_index = mlxsw_sp_fid_index(mlxsw_sp_port_vlan->fid);
@@ -1407,15 +1407,15 @@ static int mlxsw_sp_port_mdb_del(struct mlxsw_sp_port *mlxsw_sp_port,
int err = 0;
bridge_port = mlxsw_sp_bridge_port_find(mlxsw_sp->bridge, orig_dev);
- if (WARN_ON(!bridge_port))
- return -EINVAL;
+ if (!bridge_port)
+ return 0;
bridge_device = bridge_port->bridge_device;
mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_bridge(mlxsw_sp_port,
bridge_device,
mdb->vid);
- if (WARN_ON(!mlxsw_sp_port_vlan))
- return -EINVAL;
+ if (!mlxsw_sp_port_vlan)
+ return 0;
fid_index = mlxsw_sp_fid_index(mlxsw_sp_port_vlan->fid);
@@ -1974,6 +1974,17 @@ static void mlxsw_sp_fdb_fini(struct mlxsw_sp *mlxsw_sp)
}
+static void mlxsw_sp_mids_fini(struct mlxsw_sp *mlxsw_sp)
+{
+ struct mlxsw_sp_mid *mid, *tmp;
+
+ list_for_each_entry_safe(mid, tmp, &mlxsw_sp->bridge->mids_list, list) {
+ list_del(&mid->list);
+ clear_bit(mid->mid, mlxsw_sp->bridge->mids_bitmap);
+ kfree(mid);
+ }
+}
+
int mlxsw_sp_switchdev_init(struct mlxsw_sp *mlxsw_sp)
{
struct mlxsw_sp_bridge *bridge;
@@ -1996,7 +2007,7 @@ int mlxsw_sp_switchdev_init(struct mlxsw_sp *mlxsw_sp)
void mlxsw_sp_switchdev_fini(struct mlxsw_sp *mlxsw_sp)
{
mlxsw_sp_fdb_fini(mlxsw_sp);
- WARN_ON(!list_empty(&mlxsw_sp->bridge->mids_list));
+ mlxsw_sp_mids_fini(mlxsw_sp);
WARN_ON(!list_empty(&mlxsw_sp->bridge->bridges_list));
kfree(mlxsw_sp->bridge);
}
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 18750ff0ede6..4631ca8b8eb2 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -513,6 +513,7 @@ nfp_net_tx_ring_init(struct nfp_net_tx_ring *tx_ring,
tx_ring->idx = idx;
tx_ring->r_vec = r_vec;
tx_ring->is_xdp = is_xdp;
+ u64_stats_init(&tx_ring->r_vec->tx_sync);
tx_ring->qcidx = tx_ring->idx * nn->stride_tx;
tx_ring->qcp_q = nn->tx_bar + NFP_QCP_QUEUE_OFF(tx_ring->qcidx);
@@ -532,6 +533,7 @@ nfp_net_rx_ring_init(struct nfp_net_rx_ring *rx_ring,
rx_ring->idx = idx;
rx_ring->r_vec = r_vec;
+ u64_stats_init(&rx_ring->r_vec->rx_sync);
rx_ring->fl_qcidx = rx_ring->idx * nn->stride_rx;
rx_ring->qcp_fl = nn->rx_bar + NFP_QCP_QUEUE_OFF(rx_ring->fl_qcidx);
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
index 9da91045d167..3eb241657368 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
@@ -253,7 +253,7 @@ int qed_mcp_cmd_init(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
size = MFW_DRV_MSG_MAX_DWORDS(p_info->mfw_mb_length) * sizeof(u32);
p_info->mfw_mb_cur = kzalloc(size, GFP_KERNEL);
p_info->mfw_mb_shadow = kzalloc(size, GFP_KERNEL);
- if (!p_info->mfw_mb_shadow || !p_info->mfw_mb_addr)
+ if (!p_info->mfw_mb_cur || !p_info->mfw_mb_shadow)
goto err;
return 0;
diff --git a/drivers/net/ethernet/qualcomm/emac/emac.c b/drivers/net/ethernet/qualcomm/emac/emac.c
index 746d94e28470..60850bfa3d32 100644
--- a/drivers/net/ethernet/qualcomm/emac/emac.c
+++ b/drivers/net/ethernet/qualcomm/emac/emac.c
@@ -766,11 +766,13 @@ static void emac_shutdown(struct platform_device *pdev)
struct emac_adapter *adpt = netdev_priv(netdev);
struct emac_sgmii *sgmii = &adpt->phy;
- /* Closing the SGMII turns off its interrupts */
- sgmii->close(adpt);
+ if (netdev->flags & IFF_UP) {
+ /* Closing the SGMII turns off its interrupts */
+ sgmii->close(adpt);
- /* Resetting the MAC turns off all DMA and its interrupts */
- emac_mac_reset(adpt);
+ /* Resetting the MAC turns off all DMA and its interrupts */
+ emac_mac_reset(adpt);
+ }
}
static struct platform_driver emac_platform_driver = {
diff --git a/drivers/net/ethernet/sgi/ioc3-eth.c b/drivers/net/ethernet/sgi/ioc3-eth.c
index b607936e1b3e..9c0488e0f08e 100644
--- a/drivers/net/ethernet/sgi/ioc3-eth.c
+++ b/drivers/net/ethernet/sgi/ioc3-eth.c
@@ -90,17 +90,13 @@ struct ioc3_private {
spinlock_t ioc3_lock;
struct mii_if_info mii;
+ struct net_device *dev;
struct pci_dev *pdev;
/* Members used by autonegotiation */
struct timer_list ioc3_timer;
};
-static inline struct net_device *priv_netdev(struct ioc3_private *dev)
-{
- return (void *)dev - ((sizeof(struct net_device) + 31) & ~31);
-}
-
static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static void ioc3_set_multicast_list(struct net_device *dev);
static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev);
@@ -427,7 +423,7 @@ static void ioc3_get_eaddr_nic(struct ioc3_private *ip)
nic[i] = nic_read_byte(ioc3);
for (i = 2; i < 8; i++)
- priv_netdev(ip)->dev_addr[i - 2] = nic[i];
+ ip->dev->dev_addr[i - 2] = nic[i];
}
/*
@@ -439,7 +435,7 @@ static void ioc3_get_eaddr(struct ioc3_private *ip)
{
ioc3_get_eaddr_nic(ip);
- printk("Ethernet address is %pM.\n", priv_netdev(ip)->dev_addr);
+ printk("Ethernet address is %pM.\n", ip->dev->dev_addr);
}
static void __ioc3_set_mac_address(struct net_device *dev)
@@ -790,13 +786,12 @@ static void ioc3_timer(unsigned long data)
*/
static int ioc3_mii_init(struct ioc3_private *ip)
{
- struct net_device *dev = priv_netdev(ip);
int i, found = 0, res = 0;
int ioc3_phy_workaround = 1;
u16 word;
for (i = 0; i < 32; i++) {
- word = ioc3_mdio_read(dev, i, MII_PHYSID1);
+ word = ioc3_mdio_read(ip->dev, i, MII_PHYSID1);
if (word != 0xffff && word != 0x0000) {
found = 1;
@@ -1276,6 +1271,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
SET_NETDEV_DEV(dev, &pdev->dev);
ip = netdev_priv(dev);
+ ip->dev = dev;
dev->irq = pdev->irq;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
index 22cf6353ba04..7ecf549c7f1c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -205,7 +205,7 @@ static void dwmac1000_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space)
{
int i;
- for (i = 0; i < 23; i++)
+ for (i = 0; i < NUM_DWMAC1000_DMA_REGS; i++)
if ((i < 12) || (i > 17))
reg_space[DMA_BUS_MODE / 4 + i] =
readl(ioaddr + DMA_BUS_MODE + i * 4);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
index eef2f222ce9a..6502b9aa3bf5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
@@ -70,7 +70,7 @@ static void dwmac100_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space)
{
int i;
- for (i = 0; i < 9; i++)
+ for (i = 0; i < NUM_DWMAC100_DMA_REGS; i++)
reg_space[DMA_BUS_MODE / 4 + i] =
readl(ioaddr + DMA_BUS_MODE + i * 4);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
index f233bf8b4ebb..c4407e8e39a3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -117,7 +117,7 @@ static void dwmac4_tx_queue_routing(struct mac_device_info *hw,
void __iomem *ioaddr = hw->pcsr;
u32 value;
- const struct stmmac_rx_routing route_possibilities[] = {
+ static const struct stmmac_rx_routing route_possibilities[] = {
{ GMAC_RXQCTRL_AVCPQ_MASK, GMAC_RXQCTRL_AVCPQ_SHIFT },
{ GMAC_RXQCTRL_PTPQ_MASK, GMAC_RXQCTRL_PTPQ_SHIFT },
{ GMAC_RXQCTRL_DCBCPQ_MASK, GMAC_RXQCTRL_DCBCPQ_SHIFT },
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
index 9091df86723a..adc54006f884 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
@@ -136,6 +136,9 @@
#define DMA_STATUS_TI 0x00000001 /* Transmit Interrupt */
#define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */
+#define NUM_DWMAC100_DMA_REGS 9
+#define NUM_DWMAC1000_DMA_REGS 23
+
void dwmac_enable_dma_transmission(void __iomem *ioaddr);
void dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan);
void dwmac_disable_dma_irq(void __iomem *ioaddr, u32 chan);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index babb39c646ff..af30b4857c3b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -33,6 +33,8 @@
#define MAC100_ETHTOOL_NAME "st_mac100"
#define GMAC_ETHTOOL_NAME "st_gmac"
+#define ETHTOOL_DMA_OFFSET 55
+
struct stmmac_stats {
char stat_string[ETH_GSTRING_LEN];
int sizeof_stat;
@@ -442,6 +444,9 @@ static void stmmac_ethtool_gregs(struct net_device *dev,
priv->hw->mac->dump_regs(priv->hw, reg_space);
priv->hw->dma->dump_regs(priv->ioaddr, reg_space);
+ /* Copy DMA registers to where ethtool expects them */
+ memcpy(&reg_space[ETHTOOL_DMA_OFFSET], &reg_space[DMA_BUS_MODE / 4],
+ NUM_DWMAC1000_DMA_REGS * 4);
}
static void
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 1853f7ff6657..1763e48c84e2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4120,8 +4120,15 @@ int stmmac_dvr_probe(struct device *device,
if ((phyaddr >= 0) && (phyaddr <= 31))
priv->plat->phy_addr = phyaddr;
- if (priv->plat->stmmac_rst)
+ if (priv->plat->stmmac_rst) {
+ ret = reset_control_assert(priv->plat->stmmac_rst);
reset_control_deassert(priv->plat->stmmac_rst);
+ /* Some reset controllers have only reset callback instead of
+ * assert + deassert callbacks pair.
+ */
+ if (ret == -ENOTSUPP)
+ reset_control_reset(priv->plat->stmmac_rst);
+ }
/* Init MAC and get the capabilities */
ret = stmmac_hw_init(priv);
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index 46cb7f8955a2..4bb04aaf9650 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -9532,7 +9532,7 @@ static struct niu_parent *niu_get_parent(struct niu *np,
p = niu_new_parent(np, id, ptype);
if (p) {
- char port_name[6];
+ char port_name[8];
int err;
sprintf(port_name, "port%d", port);
@@ -9553,7 +9553,7 @@ static void niu_put_parent(struct niu *np)
{
struct niu_parent *p = np->parent;
u8 port = np->port;
- char port_name[6];
+ char port_name[8];
BUG_ON(!p || p->ports[port] != np);
diff --git a/drivers/net/ethernet/sun/sunhme.h b/drivers/net/ethernet/sun/sunhme.h
index 3af540adb3c5..fca1bca7f69d 100644
--- a/drivers/net/ethernet/sun/sunhme.h
+++ b/drivers/net/ethernet/sun/sunhme.h
@@ -13,9 +13,9 @@
/* Happy Meal global registers. */
#define GREG_SWRESET 0x000UL /* Software Reset */
#define GREG_CFG 0x004UL /* Config Register */
-#define GREG_STAT 0x108UL /* Status */
-#define GREG_IMASK 0x10cUL /* Interrupt Mask */
-#define GREG_REG_SIZE 0x110UL
+#define GREG_STAT 0x100UL /* Status */
+#define GREG_IMASK 0x104UL /* Interrupt Mask */
+#define GREG_REG_SIZE 0x108UL
/* Global reset register. */
#define GREG_RESET_ETX 0x01
diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c
index 711fbbbc4b1f..163d8d16bc24 100644
--- a/drivers/net/ethernet/tehuti/tehuti.c
+++ b/drivers/net/ethernet/tehuti/tehuti.c
@@ -654,6 +654,8 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd)
RET(-EFAULT);
}
DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]);
+ } else {
+ return -EOPNOTSUPP;
}
if (!capable(CAP_SYS_RAWIO))
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 1850e348f555..badd0a8caeb9 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -3089,6 +3089,31 @@ static int cpsw_probe(struct platform_device *pdev)
cpsw->quirk_irq = true;
}
+ ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
+
+ ndev->netdev_ops = &cpsw_netdev_ops;
+ ndev->ethtool_ops = &cpsw_ethtool_ops;
+ netif_napi_add(ndev, &cpsw->napi_rx, cpsw_rx_poll, CPSW_POLL_WEIGHT);
+ netif_tx_napi_add(ndev, &cpsw->napi_tx, cpsw_tx_poll, CPSW_POLL_WEIGHT);
+ cpsw_split_res(ndev);
+
+ /* register the network device */
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+ ret = register_netdev(ndev);
+ if (ret) {
+ dev_err(priv->dev, "error registering net device\n");
+ ret = -ENODEV;
+ goto clean_ale_ret;
+ }
+
+ if (cpsw->data.dual_emac) {
+ ret = cpsw_probe_dual_emac(priv);
+ if (ret) {
+ cpsw_err(priv, probe, "error probe slave 2 emac interface\n");
+ goto clean_unregister_netdev_ret;
+ }
+ }
+
/* Grab RX and TX IRQs. Note that we also have RX_THRESHOLD and
* MISC IRQs which are always kept disabled with this driver so
* we will not request them.
@@ -3127,33 +3152,9 @@ static int cpsw_probe(struct platform_device *pdev)
goto clean_ale_ret;
}
- ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
-
- ndev->netdev_ops = &cpsw_netdev_ops;
- ndev->ethtool_ops = &cpsw_ethtool_ops;
- netif_napi_add(ndev, &cpsw->napi_rx, cpsw_rx_poll, CPSW_POLL_WEIGHT);
- netif_tx_napi_add(ndev, &cpsw->napi_tx, cpsw_tx_poll, CPSW_POLL_WEIGHT);
- cpsw_split_res(ndev);
-
- /* register the network device */
- SET_NETDEV_DEV(ndev, &pdev->dev);
- ret = register_netdev(ndev);
- if (ret) {
- dev_err(priv->dev, "error registering net device\n");
- ret = -ENODEV;
- goto clean_ale_ret;
- }
-
cpsw_notice(priv, probe,
"initialized device (regs %pa, irq %d, pool size %d)\n",
&ss_res->start, ndev->irq, dma_params.descs_pool_size);
- if (cpsw->data.dual_emac) {
- ret = cpsw_probe_dual_emac(priv);
- if (ret) {
- cpsw_err(priv, probe, "error probe slave 2 emac interface\n");
- goto clean_unregister_netdev_ret;
- }
- }
pm_runtime_put(&pdev->dev);
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
index 32279d21c836..c2121d214f08 100644
--- a/drivers/net/ethernet/ti/cpts.c
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -31,9 +31,18 @@
#include "cpts.h"
+#define CPTS_SKB_TX_WORK_TIMEOUT 1 /* jiffies */
+
+struct cpts_skb_cb_data {
+ unsigned long tmo;
+};
+
#define cpts_read32(c, r) readl_relaxed(&c->reg->r)
#define cpts_write32(c, v, r) writel_relaxed(v, &c->reg->r)
+static int cpts_match(struct sk_buff *skb, unsigned int ptp_class,
+ u16 ts_seqid, u8 ts_msgtype);
+
static int event_expired(struct cpts_event *event)
{
return time_after(jiffies, event->tmo);
@@ -77,6 +86,47 @@ static int cpts_purge_events(struct cpts *cpts)
return removed ? 0 : -1;
}
+static bool cpts_match_tx_ts(struct cpts *cpts, struct cpts_event *event)
+{
+ struct sk_buff *skb, *tmp;
+ u16 seqid;
+ u8 mtype;
+ bool found = false;
+
+ mtype = (event->high >> MESSAGE_TYPE_SHIFT) & MESSAGE_TYPE_MASK;
+ seqid = (event->high >> SEQUENCE_ID_SHIFT) & SEQUENCE_ID_MASK;
+
+ /* no need to grab txq.lock as access is always done under cpts->lock */
+ skb_queue_walk_safe(&cpts->txq, skb, tmp) {
+ struct skb_shared_hwtstamps ssh;
+ unsigned int class = ptp_classify_raw(skb);
+ struct cpts_skb_cb_data *skb_cb =
+ (struct cpts_skb_cb_data *)skb->cb;
+
+ if (cpts_match(skb, class, seqid, mtype)) {
+ u64 ns = timecounter_cyc2time(&cpts->tc, event->low);
+
+ memset(&ssh, 0, sizeof(ssh));
+ ssh.hwtstamp = ns_to_ktime(ns);
+ skb_tstamp_tx(skb, &ssh);
+ found = true;
+ __skb_unlink(skb, &cpts->txq);
+ dev_consume_skb_any(skb);
+ dev_dbg(cpts->dev, "match tx timestamp mtype %u seqid %04x\n",
+ mtype, seqid);
+ } else if (time_after(jiffies, skb_cb->tmo)) {
+ /* timeout any expired skbs over 1s */
+ dev_dbg(cpts->dev,
+ "expiring tx timestamp mtype %u seqid %04x\n",
+ mtype, seqid);
+ __skb_unlink(skb, &cpts->txq);
+ dev_consume_skb_any(skb);
+ }
+ }
+
+ return found;
+}
+
/*
* Returns zero if matching event type was found.
*/
@@ -101,9 +151,15 @@ static int cpts_fifo_read(struct cpts *cpts, int match)
event->low = lo;
type = event_type(event);
switch (type) {
+ case CPTS_EV_TX:
+ if (cpts_match_tx_ts(cpts, event)) {
+ /* if the new event matches an existing skb,
+ * then don't queue it
+ */
+ break;
+ }
case CPTS_EV_PUSH:
case CPTS_EV_RX:
- case CPTS_EV_TX:
list_del_init(&event->list);
list_add_tail(&event->list, &cpts->events);
break;
@@ -224,6 +280,24 @@ static int cpts_ptp_enable(struct ptp_clock_info *ptp,
return -EOPNOTSUPP;
}
+static long cpts_overflow_check(struct ptp_clock_info *ptp)
+{
+ struct cpts *cpts = container_of(ptp, struct cpts, info);
+ unsigned long delay = cpts->ov_check_period;
+ struct timespec64 ts;
+ unsigned long flags;
+
+ spin_lock_irqsave(&cpts->lock, flags);
+ ts = ns_to_timespec64(timecounter_read(&cpts->tc));
+
+ if (!skb_queue_empty(&cpts->txq))
+ delay = CPTS_SKB_TX_WORK_TIMEOUT;
+ spin_unlock_irqrestore(&cpts->lock, flags);
+
+ pr_debug("cpts overflow check at %lld.%09lu\n", ts.tv_sec, ts.tv_nsec);
+ return (long)delay;
+}
+
static struct ptp_clock_info cpts_info = {
.owner = THIS_MODULE,
.name = "CTPS timer",
@@ -236,18 +310,9 @@ static struct ptp_clock_info cpts_info = {
.gettime64 = cpts_ptp_gettime,
.settime64 = cpts_ptp_settime,
.enable = cpts_ptp_enable,
+ .do_aux_work = cpts_overflow_check,
};
-static void cpts_overflow_check(struct work_struct *work)
-{
- struct timespec64 ts;
- struct cpts *cpts = container_of(work, struct cpts, overflow_work.work);
-
- cpts_ptp_gettime(&cpts->info, &ts);
- pr_debug("cpts overflow check at %lld.%09lu\n", ts.tv_sec, ts.tv_nsec);
- schedule_delayed_work(&cpts->overflow_work, cpts->ov_check_period);
-}
-
static int cpts_match(struct sk_buff *skb, unsigned int ptp_class,
u16 ts_seqid, u8 ts_msgtype)
{
@@ -299,7 +364,7 @@ static u64 cpts_find_ts(struct cpts *cpts, struct sk_buff *skb, int ev_type)
return 0;
spin_lock_irqsave(&cpts->lock, flags);
- cpts_fifo_read(cpts, CPTS_EV_PUSH);
+ cpts_fifo_read(cpts, -1);
list_for_each_safe(this, next, &cpts->events) {
event = list_entry(this, struct cpts_event, list);
if (event_expired(event)) {
@@ -317,6 +382,19 @@ static u64 cpts_find_ts(struct cpts *cpts, struct sk_buff *skb, int ev_type)
break;
}
}
+
+ if (ev_type == CPTS_EV_TX && !ns) {
+ struct cpts_skb_cb_data *skb_cb =
+ (struct cpts_skb_cb_data *)skb->cb;
+ /* Not found, add frame to queue for processing later.
+ * The periodic FIFO check will handle this.
+ */
+ skb_get(skb);
+ /* get the timestamp for timeouts */
+ skb_cb->tmo = jiffies + msecs_to_jiffies(100);
+ __skb_queue_tail(&cpts->txq, skb);
+ ptp_schedule_worker(cpts->clock, 0);
+ }
spin_unlock_irqrestore(&cpts->lock, flags);
return ns;
@@ -358,6 +436,7 @@ int cpts_register(struct cpts *cpts)
{
int err, i;
+ skb_queue_head_init(&cpts->txq);
INIT_LIST_HEAD(&cpts->events);
INIT_LIST_HEAD(&cpts->pool);
for (i = 0; i < CPTS_MAX_EVENTS; i++)
@@ -378,7 +457,7 @@ int cpts_register(struct cpts *cpts)
}
cpts->phc_index = ptp_clock_index(cpts->clock);
- schedule_delayed_work(&cpts->overflow_work, cpts->ov_check_period);
+ ptp_schedule_worker(cpts->clock, cpts->ov_check_period);
return 0;
err_ptp:
@@ -392,14 +471,15 @@ void cpts_unregister(struct cpts *cpts)
if (WARN_ON(!cpts->clock))
return;
- cancel_delayed_work_sync(&cpts->overflow_work);
-
ptp_clock_unregister(cpts->clock);
cpts->clock = NULL;
cpts_write32(cpts, 0, int_enable);
cpts_write32(cpts, 0, control);
+ /* Drop all packet */
+ skb_queue_purge(&cpts->txq);
+
clk_disable(cpts->refclk);
}
EXPORT_SYMBOL_GPL(cpts_unregister);
@@ -476,7 +556,6 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs,
cpts->dev = dev;
cpts->reg = (struct cpsw_cpts __iomem *)regs;
spin_lock_init(&cpts->lock);
- INIT_DELAYED_WORK(&cpts->overflow_work, cpts_overflow_check);
ret = cpts_of_parse(cpts, node);
if (ret)
diff --git a/drivers/net/ethernet/ti/cpts.h b/drivers/net/ethernet/ti/cpts.h
index 01ea82ba9cdc..73d73faf0f38 100644
--- a/drivers/net/ethernet/ti/cpts.h
+++ b/drivers/net/ethernet/ti/cpts.h
@@ -119,13 +119,13 @@ struct cpts {
u32 cc_mult; /* for the nominal frequency */
struct cyclecounter cc;
struct timecounter tc;
- struct delayed_work overflow_work;
int phc_index;
struct clk *refclk;
struct list_head events;
struct list_head pool;
struct cpts_event pool_data[CPTS_MAX_EVENTS];
unsigned long ov_check_period;
+ struct sk_buff_head txq;
};
void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb);
diff --git a/drivers/net/ethernet/toshiba/tc35815.c b/drivers/net/ethernet/toshiba/tc35815.c
index d9db8a06afd2..cce9c9ed46aa 100644
--- a/drivers/net/ethernet/toshiba/tc35815.c
+++ b/drivers/net/ethernet/toshiba/tc35815.c
@@ -1338,7 +1338,7 @@ static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev)
static void tc35815_fatal_error_interrupt(struct net_device *dev, u32 status)
{
static int count;
- printk(KERN_WARNING "%s: Fatal Error Intterrupt (%#x):",
+ printk(KERN_WARNING "%s: Fatal Error Interrupt (%#x):",
dev->name, status);
if (status & Int_IntPCI)
printk(" IntPCI");
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index de8156c6b292..2bbda71818ad 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -1091,7 +1091,7 @@ static int geneve_validate(struct nlattr *tb[], struct nlattr *data[],
if (data[IFLA_GENEVE_ID]) {
__u32 vni = nla_get_u32(data[IFLA_GENEVE_ID]);
- if (vni >= GENEVE_VID_MASK)
+ if (vni >= GENEVE_N_VID)
return -ERANGE;
}
diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 1542e837fdfa..f38e32a7ec9c 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -364,7 +364,7 @@ static int gtp_dev_init(struct net_device *dev)
gtp->dev = dev;
- dev->tstats = alloc_percpu(struct pcpu_sw_netstats);
+ dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
if (!dev->tstats)
return -ENOMEM;
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index d6c25580f8dd..12cc64bfcff8 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -765,7 +765,8 @@ struct netvsc_device {
u32 max_chn;
u32 num_chn;
- refcount_t sc_offered;
+ atomic_t open_chn;
+ wait_queue_head_t subchan_open;
struct rndis_device *extension;
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 0a9167dd72fb..d18c3326a1f7 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -78,6 +78,7 @@ static struct netvsc_device *alloc_net_device(void)
net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT;
net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT;
init_completion(&net_device->channel_init_wait);
+ init_waitqueue_head(&net_device->subchan_open);
return net_device;
}
@@ -1302,6 +1303,8 @@ int netvsc_device_add(struct hv_device *device,
struct netvsc_channel *nvchan = &net_device->chan_table[i];
nvchan->channel = device->channel;
+ u64_stats_init(&nvchan->tx_stats.syncp);
+ u64_stats_init(&nvchan->rx_stats.syncp);
}
/* Enable NAPI handler before init callbacks */
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 63c98bbbc596..0d78727f1a14 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -315,14 +315,34 @@ static u32 init_page_array(void *hdr, u32 len, struct sk_buff *skb,
return slots_used;
}
-/* Estimate number of page buffers neede to transmit
- * Need at most 2 for RNDIS header plus skb body and fragments.
- */
-static unsigned int netvsc_get_slots(const struct sk_buff *skb)
+static int count_skb_frag_slots(struct sk_buff *skb)
+{
+ int i, frags = skb_shinfo(skb)->nr_frags;
+ int pages = 0;
+
+ for (i = 0; i < frags; i++) {
+ skb_frag_t *frag = skb_shinfo(skb)->frags + i;
+ unsigned long size = skb_frag_size(frag);
+ unsigned long offset = frag->page_offset;
+
+ /* Skip unused frames from start of page */
+ offset &= ~PAGE_MASK;
+ pages += PFN_UP(offset + size);
+ }
+ return pages;
+}
+
+static int netvsc_get_slots(struct sk_buff *skb)
{
- return PFN_UP(offset_in_page(skb->data) + skb_headlen(skb))
- + skb_shinfo(skb)->nr_frags
- + 2;
+ char *data = skb->data;
+ unsigned int offset = offset_in_page(data);
+ unsigned int len = skb_headlen(skb);
+ int slots;
+ int frag_slots;
+
+ slots = DIV_ROUND_UP(offset + len, PAGE_SIZE);
+ frag_slots = count_skb_frag_slots(skb);
+ return slots + frag_slots;
}
static u32 net_checksum_info(struct sk_buff *skb)
@@ -360,18 +380,21 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
struct hv_page_buffer page_buf[MAX_PAGE_BUFFER_COUNT];
struct hv_page_buffer *pb = page_buf;
- /* We can only transmit MAX_PAGE_BUFFER_COUNT number
+ /* We will atmost need two pages to describe the rndis
+ * header. We can only transmit MAX_PAGE_BUFFER_COUNT number
* of pages in a single packet. If skb is scattered around
* more pages we try linearizing it.
*/
- num_data_pgs = netvsc_get_slots(skb);
+
+ num_data_pgs = netvsc_get_slots(skb) + 2;
+
if (unlikely(num_data_pgs > MAX_PAGE_BUFFER_COUNT)) {
++net_device_ctx->eth_stats.tx_scattered;
if (skb_linearize(skb))
goto no_memory;
- num_data_pgs = netvsc_get_slots(skb);
+ num_data_pgs = netvsc_get_slots(skb) + 2;
if (num_data_pgs > MAX_PAGE_BUFFER_COUNT) {
++net_device_ctx->eth_stats.tx_too_big;
goto drop;
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 85c00e1c52b6..d6308ffda53e 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -1048,8 +1048,8 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
else
netif_napi_del(&nvchan->napi);
- if (refcount_dec_and_test(&nvscdev->sc_offered))
- complete(&nvscdev->channel_init_wait);
+ atomic_inc(&nvscdev->open_chn);
+ wake_up(&nvscdev->subchan_open);
}
int rndis_filter_device_add(struct hv_device *dev,
@@ -1090,8 +1090,6 @@ int rndis_filter_device_add(struct hv_device *dev,
net_device->max_chn = 1;
net_device->num_chn = 1;
- refcount_set(&net_device->sc_offered, 0);
-
net_device->extension = rndis_device;
rndis_device->ndev = net;
@@ -1221,11 +1219,11 @@ int rndis_filter_device_add(struct hv_device *dev,
rndis_device->ind_table[i] = ethtool_rxfh_indir_default(i,
net_device->num_chn);
+ atomic_set(&net_device->open_chn, 1);
num_rss_qs = net_device->num_chn - 1;
if (num_rss_qs == 0)
return 0;
- refcount_set(&net_device->sc_offered, num_rss_qs);
vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open);
init_packet = &net_device->channel_init_pkt;
@@ -1242,15 +1240,19 @@ int rndis_filter_device_add(struct hv_device *dev,
if (ret)
goto out;
+ wait_for_completion(&net_device->channel_init_wait);
if (init_packet->msg.v5_msg.subchn_comp.status != NVSP_STAT_SUCCESS) {
ret = -ENODEV;
goto out;
}
- wait_for_completion(&net_device->channel_init_wait);
net_device->num_chn = 1 +
init_packet->msg.v5_msg.subchn_comp.num_subchannels;
+ /* wait for all sub channels to open */
+ wait_event(net_device->subchan_open,
+ atomic_read(&net_device->open_chn) == net_device->num_chn);
+
/* ignore failues from setting rss parameters, still have channels */
rndis_filter_set_rss_param(rndis_device, netvsc_hash_key,
net_device->num_chn);
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index f37e3c1fd4e7..8dab74a81303 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -192,7 +192,7 @@ static int ipvlan_init(struct net_device *dev)
netdev_lockdep_set_classes(dev);
- ipvlan->pcpu_stats = alloc_percpu(struct ipvl_pcpu_stats);
+ ipvlan->pcpu_stats = netdev_alloc_pcpu_stats(struct ipvl_pcpu_stats);
if (!ipvlan->pcpu_stats)
return -ENOMEM;
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c
index 6f6ed75b63c9..765de3bedb88 100644
--- a/drivers/net/irda/mcs7780.c
+++ b/drivers/net/irda/mcs7780.c
@@ -141,9 +141,19 @@ static int mcs_set_reg(struct mcs_cb *mcs, __u16 reg, __u16 val)
static int mcs_get_reg(struct mcs_cb *mcs, __u16 reg, __u16 * val)
{
struct usb_device *dev = mcs->usbdev;
- int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
- MCS_RD_RTYPE, 0, reg, val, 2,
- msecs_to_jiffies(MCS_CTRL_TIMEOUT));
+ void *dmabuf;
+ int ret;
+
+ dmabuf = kmalloc(sizeof(__u16), GFP_KERNEL);
+ if (!dmabuf)
+ return -ENOMEM;
+
+ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
+ MCS_RD_RTYPE, 0, reg, dmabuf, 2,
+ msecs_to_jiffies(MCS_CTRL_TIMEOUT));
+
+ memcpy(val, dmabuf, sizeof(__u16));
+ kfree(dmabuf);
return ret;
}
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 2dda72004a7d..928fd892f167 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -7,7 +7,16 @@ menuconfig MDIO_DEVICE
help
MDIO devices and driver infrastructure code.
-if MDIO_DEVICE
+config MDIO_BUS
+ tristate
+ default m if PHYLIB=m
+ default MDIO_DEVICE
+ help
+ This internal symbol is used for link time dependencies and it
+ reflects whether the mdio_bus/mdio_device code is built as a
+ loadable module or built-in.
+
+if MDIO_BUS
config MDIO_BCM_IPROC
tristate "Broadcom iProc MDIO bus controller"
@@ -28,7 +37,6 @@ config MDIO_BCM_UNIMAC
config MDIO_BITBANG
tristate "Bitbanged MDIO buses"
- depends on !(MDIO_DEVICE=y && PHYLIB=m)
help
This module implements the MDIO bus protocol in software,
for use by low level drivers that export the ability to
@@ -127,7 +135,6 @@ config MDIO_THUNDER
tristate "ThunderX SOCs MDIO buses"
depends on 64BIT
depends on PCI
- depends on !(MDIO_DEVICE=y && PHYLIB=m)
select MDIO_CAVIUM
help
This driver supports the MDIO interfaces found on Cavium
diff --git a/drivers/net/phy/mdio-mux.c b/drivers/net/phy/mdio-mux.c
index 00755b6a42cf..c608e1dfaf09 100644
--- a/drivers/net/phy/mdio-mux.c
+++ b/drivers/net/phy/mdio-mux.c
@@ -135,8 +135,8 @@ int mdio_mux_init(struct device *dev,
for_each_available_child_of_node(dev->of_node, child_bus_node) {
int v;
- v = of_mdio_parse_addr(dev, child_bus_node);
- if (v < 0) {
+ r = of_property_read_u32(child_bus_node, "reg", &v);
+ if (r) {
dev_err(dev,
"Error: Failed to find reg for child %s\n",
of_node_full_name(child_bus_node));
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index d0626bf5c540..5068c582d502 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -749,6 +749,9 @@ void phy_stop_machine(struct phy_device *phydev)
if (phydev->state > PHY_UP && phydev->state != PHY_HALTED)
phydev->state = PHY_UP;
mutex_unlock(&phydev->lock);
+
+ /* Now we can run the state machine synchronously */
+ phy_state_machine(&phydev->state_queue.work);
}
/**
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 13028833bee3..a404552555d4 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -120,6 +120,7 @@ struct ppp {
int n_channels; /* how many channels are attached 54 */
spinlock_t rlock; /* lock for receive side 58 */
spinlock_t wlock; /* lock for transmit side 5c */
+ int *xmit_recursion __percpu; /* xmit recursion detect */
int mru; /* max receive unit 60 */
unsigned int flags; /* control bits 64 */
unsigned int xstate; /* transmit state bits 68 */
@@ -1025,6 +1026,7 @@ static int ppp_dev_configure(struct net *src_net, struct net_device *dev,
struct ppp *ppp = netdev_priv(dev);
int indx;
int err;
+ int cpu;
ppp->dev = dev;
ppp->ppp_net = src_net;
@@ -1039,6 +1041,15 @@ static int ppp_dev_configure(struct net *src_net, struct net_device *dev,
INIT_LIST_HEAD(&ppp->channels);
spin_lock_init(&ppp->rlock);
spin_lock_init(&ppp->wlock);
+
+ ppp->xmit_recursion = alloc_percpu(int);
+ if (!ppp->xmit_recursion) {
+ err = -ENOMEM;
+ goto err1;
+ }
+ for_each_possible_cpu(cpu)
+ (*per_cpu_ptr(ppp->xmit_recursion, cpu)) = 0;
+
#ifdef CONFIG_PPP_MULTILINK
ppp->minseq = -1;
skb_queue_head_init(&ppp->mrq);
@@ -1050,11 +1061,15 @@ static int ppp_dev_configure(struct net *src_net, struct net_device *dev,
err = ppp_unit_register(ppp, conf->unit, conf->ifname_is_set);
if (err < 0)
- return err;
+ goto err2;
conf->file->private_data = &ppp->file;
return 0;
+err2:
+ free_percpu(ppp->xmit_recursion);
+err1:
+ return err;
}
static const struct nla_policy ppp_nl_policy[IFLA_PPP_MAX + 1] = {
@@ -1400,18 +1415,16 @@ static void __ppp_xmit_process(struct ppp *ppp)
ppp_xmit_unlock(ppp);
}
-static DEFINE_PER_CPU(int, ppp_xmit_recursion);
-
static void ppp_xmit_process(struct ppp *ppp)
{
local_bh_disable();
- if (unlikely(__this_cpu_read(ppp_xmit_recursion)))
+ if (unlikely(*this_cpu_ptr(ppp->xmit_recursion)))
goto err;
- __this_cpu_inc(ppp_xmit_recursion);
+ (*this_cpu_ptr(ppp->xmit_recursion))++;
__ppp_xmit_process(ppp);
- __this_cpu_dec(ppp_xmit_recursion);
+ (*this_cpu_ptr(ppp->xmit_recursion))--;
local_bh_enable();
@@ -1902,23 +1915,23 @@ static void __ppp_channel_push(struct channel *pch)
spin_unlock(&pch->downl);
/* see if there is anything from the attached unit to be sent */
if (skb_queue_empty(&pch->file.xq)) {
- read_lock(&pch->upl);
ppp = pch->ppp;
if (ppp)
__ppp_xmit_process(ppp);
- read_unlock(&pch->upl);
}
}
static void ppp_channel_push(struct channel *pch)
{
- local_bh_disable();
-
- __this_cpu_inc(ppp_xmit_recursion);
- __ppp_channel_push(pch);
- __this_cpu_dec(ppp_xmit_recursion);
-
- local_bh_enable();
+ read_lock_bh(&pch->upl);
+ if (pch->ppp) {
+ (*this_cpu_ptr(pch->ppp->xmit_recursion))++;
+ __ppp_channel_push(pch);
+ (*this_cpu_ptr(pch->ppp->xmit_recursion))--;
+ } else {
+ __ppp_channel_push(pch);
+ }
+ read_unlock_bh(&pch->upl);
}
/*
@@ -3057,6 +3070,7 @@ static void ppp_destroy_interface(struct ppp *ppp)
#endif /* CONFIG_PPP_FILTER */
kfree_skb(ppp->xmit_pending);
+ free_percpu(ppp->xmit_recursion);
free_netdev(ppp->dev);
}
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
index eac499c58aa7..6dde9a0cfe76 100644
--- a/drivers/net/ppp/pptp.c
+++ b/drivers/net/ppp/pptp.c
@@ -131,7 +131,6 @@ static void del_chan(struct pppox_sock *sock)
clear_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap);
RCU_INIT_POINTER(callid_sock[sock->proto.pptp.src_addr.call_id], NULL);
spin_unlock(&chan_lock);
- synchronize_rcu();
}
static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
@@ -520,6 +519,7 @@ static int pptp_release(struct socket *sock)
po = pppox_sk(sk);
del_chan(po);
+ synchronize_rcu();
pppox_unbind_sock(sk);
sk->sk_state = PPPOX_DEAD;
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 464570409796..ae53e899259f 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -60,11 +60,11 @@ static struct team_port *team_port_get_rtnl(const struct net_device *dev)
static int __set_port_dev_addr(struct net_device *port_dev,
const unsigned char *dev_addr)
{
- struct sockaddr addr;
+ struct sockaddr_storage addr;
- memcpy(addr.sa_data, dev_addr, port_dev->addr_len);
- addr.sa_family = port_dev->type;
- return dev_set_mac_address(port_dev, &addr);
+ memcpy(addr.__data, dev_addr, port_dev->addr_len);
+ addr.ss_family = port_dev->type;
+ return dev_set_mac_address(port_dev, (struct sockaddr *)&addr);
}
static int team_port_set_orig_dev_addr(struct team_port *port)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 3d4c24572ecd..32ad87345f57 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -2598,8 +2598,16 @@ static int __init tun_init(void)
goto err_misc;
}
- register_netdevice_notifier(&tun_notifier_block);
+ ret = register_netdevice_notifier(&tun_notifier_block);
+ if (ret) {
+ pr_err("Can't register netdevice notifier\n");
+ goto err_notifier;
+ }
+
return 0;
+
+err_notifier:
+ misc_deregister(&tun_miscdev);
err_misc:
rtnl_link_unregister(&tun_link_ops);
err_linkops:
diff --git a/drivers/net/usb/asix.h b/drivers/net/usb/asix.h
index d1092421aaa7..9a4171b90947 100644
--- a/drivers/net/usb/asix.h
+++ b/drivers/net/usb/asix.h
@@ -209,6 +209,7 @@ void asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value,
int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb,
struct asix_rx_fixup_info *rx);
int asix_rx_fixup_common(struct usbnet *dev, struct sk_buff *skb);
+void asix_rx_fixup_common_free(struct asix_common_private *dp);
struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
gfp_t flags);
diff --git a/drivers/net/usb/asix_common.c b/drivers/net/usb/asix_common.c
index 7847436c441e..522d2900cd1d 100644
--- a/drivers/net/usb/asix_common.c
+++ b/drivers/net/usb/asix_common.c
@@ -75,6 +75,27 @@ void asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
value, index, data, size);
}
+static void reset_asix_rx_fixup_info(struct asix_rx_fixup_info *rx)
+{
+ /* Reset the variables that have a lifetime outside of
+ * asix_rx_fixup_internal() so that future processing starts from a
+ * known set of initial conditions.
+ */
+
+ if (rx->ax_skb) {
+ /* Discard any incomplete Ethernet frame in the netdev buffer */
+ kfree_skb(rx->ax_skb);
+ rx->ax_skb = NULL;
+ }
+
+ /* Assume the Data header 32-bit word is at the start of the current
+ * or next URB socket buffer so reset all the state variables.
+ */
+ rx->remaining = 0;
+ rx->split_head = false;
+ rx->header = 0;
+}
+
int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb,
struct asix_rx_fixup_info *rx)
{
@@ -99,15 +120,7 @@ int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb,
if (size != ((~rx->header >> 16) & 0x7ff)) {
netdev_err(dev->net, "asix_rx_fixup() Data Header synchronisation was lost, remaining %d\n",
rx->remaining);
- if (rx->ax_skb) {
- kfree_skb(rx->ax_skb);
- rx->ax_skb = NULL;
- /* Discard the incomplete netdev Ethernet frame
- * and assume the Data header is at the start of
- * the current URB socket buffer.
- */
- }
- rx->remaining = 0;
+ reset_asix_rx_fixup_info(rx);
}
}
@@ -139,11 +152,13 @@ int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb,
if (size != ((~rx->header >> 16) & 0x7ff)) {
netdev_err(dev->net, "asix_rx_fixup() Bad Header Length 0x%x, offset %d\n",
rx->header, offset);
+ reset_asix_rx_fixup_info(rx);
return 0;
}
if (size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) {
netdev_dbg(dev->net, "asix_rx_fixup() Bad RX Length %d\n",
size);
+ reset_asix_rx_fixup_info(rx);
return 0;
}
@@ -168,8 +183,10 @@ int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb,
if (rx->ax_skb) {
skb_put_data(rx->ax_skb, skb->data + offset,
copy_length);
- if (!rx->remaining)
+ if (!rx->remaining) {
usbnet_skb_return(dev, rx->ax_skb);
+ rx->ax_skb = NULL;
+ }
}
offset += (copy_length + 1) & 0xfffe;
@@ -178,6 +195,7 @@ int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb,
if (skb->len != offset) {
netdev_err(dev->net, "asix_rx_fixup() Bad SKB Length %d, %d\n",
skb->len, offset);
+ reset_asix_rx_fixup_info(rx);
return 0;
}
@@ -192,6 +210,21 @@ int asix_rx_fixup_common(struct usbnet *dev, struct sk_buff *skb)
return asix_rx_fixup_internal(dev, skb, rx);
}
+void asix_rx_fixup_common_free(struct asix_common_private *dp)
+{
+ struct asix_rx_fixup_info *rx;
+
+ if (!dp)
+ return;
+
+ rx = &dp->rx_fixup_info;
+
+ if (rx->ax_skb) {
+ kfree_skb(rx->ax_skb);
+ rx->ax_skb = NULL;
+ }
+}
+
struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
gfp_t flags)
{
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c
index a3aa0a27dfe5..b2ff88e69a81 100644
--- a/drivers/net/usb/asix_devices.c
+++ b/drivers/net/usb/asix_devices.c
@@ -764,6 +764,7 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
static void ax88772_unbind(struct usbnet *dev, struct usb_interface *intf)
{
+ asix_rx_fixup_common_free(dev->driver_priv);
kfree(dev->driver_priv);
}
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index d103a1d4fb36..8f572b9f3625 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -768,8 +768,10 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
u8 *buf;
int len;
int temp;
+ int err;
u8 iface_no;
struct usb_cdc_parsed_header hdr;
+ u16 curr_ntb_format;
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
@@ -874,6 +876,32 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
goto error2;
}
+ /*
+ * Some Huawei devices have been observed to come out of reset in NDP32 mode.
+ * Let's check if this is the case, and set the device to NDP16 mode again if
+ * needed.
+ */
+ if (ctx->drvflags & CDC_NCM_FLAG_RESET_NTB16) {
+ err = usbnet_read_cmd(dev, USB_CDC_GET_NTB_FORMAT,
+ USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
+ 0, iface_no, &curr_ntb_format, 2);
+ if (err < 0) {
+ goto error2;
+ }
+
+ if (curr_ntb_format == USB_CDC_NCM_NTB32_FORMAT) {
+ dev_info(&intf->dev, "resetting NTB format to 16-bit");
+ err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_FORMAT,
+ USB_TYPE_CLASS | USB_DIR_OUT
+ | USB_RECIP_INTERFACE,
+ USB_CDC_NCM_NTB16_FORMAT,
+ iface_no, NULL, 0);
+
+ if (err < 0)
+ goto error2;
+ }
+ }
+
cdc_ncm_find_endpoints(dev, ctx->data);
cdc_ncm_find_endpoints(dev, ctx->control);
if (!dev->in || !dev->out || !dev->status) {
diff --git a/drivers/net/usb/huawei_cdc_ncm.c b/drivers/net/usb/huawei_cdc_ncm.c
index 2680a65cd5e4..63f28908afda 100644
--- a/drivers/net/usb/huawei_cdc_ncm.c
+++ b/drivers/net/usb/huawei_cdc_ncm.c
@@ -80,6 +80,12 @@ static int huawei_cdc_ncm_bind(struct usbnet *usbnet_dev,
* be at the end of the frame.
*/
drvflags |= CDC_NCM_FLAG_NDP_TO_END;
+
+ /* Additionally, it has been reported that some Huawei E3372H devices, with
+ * firmware version 21.318.01.00.541, come out of reset in NTB32 format mode, hence
+ * needing to be set to the NTB16 one again.
+ */
+ drvflags |= CDC_NCM_FLAG_RESET_NTB16;
ret = cdc_ncm_bind_common(usbnet_dev, intf, 1, drvflags);
if (ret)
goto err;
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index 5833f7e2a127..b99a7fb09f8e 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -2367,9 +2367,6 @@ static int lan78xx_reset(struct lan78xx_net *dev)
/* Init LTM */
lan78xx_init_ltm(dev);
- dev->net->hard_header_len += TX_OVERHEAD;
- dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
-
if (dev->udev->speed == USB_SPEED_SUPER) {
buf = DEFAULT_BURST_CAP_SIZE / SS_USB_PKT_SIZE;
dev->rx_urb_size = DEFAULT_BURST_CAP_SIZE;
@@ -2855,16 +2852,19 @@ static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf)
return ret;
}
+ dev->net->hard_header_len += TX_OVERHEAD;
+ dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
+
/* Init all registers */
ret = lan78xx_reset(dev);
- lan78xx_mdio_init(dev);
+ ret = lan78xx_mdio_init(dev);
dev->net->flags |= IFF_MULTICAST;
pdata->wol = WAKE_MAGIC;
- return 0;
+ return ret;
}
static void lan78xx_unbind(struct lan78xx_net *dev, struct usb_interface *intf)
@@ -3525,11 +3525,11 @@ static int lan78xx_probe(struct usb_interface *intf,
udev = interface_to_usbdev(intf);
udev = usb_get_dev(udev);
- ret = -ENOMEM;
netdev = alloc_etherdev(sizeof(struct lan78xx_net));
if (!netdev) {
- dev_err(&intf->dev, "Error: OOM\n");
- goto out1;
+ dev_err(&intf->dev, "Error: OOM\n");
+ ret = -ENOMEM;
+ goto out1;
}
/* netdev_printk() needs this */
@@ -3610,7 +3610,7 @@ static int lan78xx_probe(struct usb_interface *intf,
ret = register_netdev(netdev);
if (ret != 0) {
netif_err(dev, probe, netdev, "couldn't register the device\n");
- goto out2;
+ goto out3;
}
usb_set_intfdata(intf, dev);
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 5894e3c9468f..8c3733608271 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -1175,6 +1175,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x19d2, 0x1428, 2)}, /* Telewell TW-LTE 4G v2 */
{QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */
{QMI_FIXED_INTF(0x2001, 0x7e19, 4)}, /* D-Link DWM-221 B1 */
+ {QMI_FIXED_INTF(0x2001, 0x7e35, 4)}, /* D-Link DWM-222 */
{QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */
{QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */
{QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */
@@ -1340,10 +1341,14 @@ static int qmi_wwan_probe(struct usb_interface *intf,
static void qmi_wwan_disconnect(struct usb_interface *intf)
{
struct usbnet *dev = usb_get_intfdata(intf);
- struct qmi_wwan_state *info = (void *)&dev->data;
+ struct qmi_wwan_state *info;
struct list_head *iter;
struct net_device *ldev;
+ /* called twice if separate control and data intf */
+ if (!dev)
+ return;
+ info = (void *)&dev->data;
if (info->flags & QMI_WWAN_FLAG_MUX) {
if (!rtnl_trylock()) {
restart_syscall();
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 2dfca96a63b6..340c13484e5c 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -898,6 +898,7 @@ static const struct ethtool_ops smsc95xx_ethtool_ops = {
.set_wol = smsc95xx_ethtool_set_wol,
.get_link_ksettings = smsc95xx_get_link_ksettings,
.set_link_ksettings = smsc95xx_set_link_ksettings,
+ .get_ts_info = ethtool_op_get_ts_info,
};
static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 99a26a9efec1..98f17b05c68b 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -889,21 +889,20 @@ static int add_recvbuf_mergeable(struct virtnet_info *vi,
buf = (char *)page_address(alloc_frag->page) + alloc_frag->offset;
buf += headroom; /* advance address leaving hole at front of pkt */
- ctx = (void *)(unsigned long)len;
get_page(alloc_frag->page);
alloc_frag->offset += len + headroom;
hole = alloc_frag->size - alloc_frag->offset;
if (hole < len + headroom) {
/* To avoid internal fragmentation, if there is very likely not
* enough space for another buffer, add the remaining space to
- * the current buffer. This extra space is not included in
- * the truesize stored in ctx.
+ * the current buffer.
*/
len += hole;
alloc_frag->offset += hole;
}
sg_init_one(rq->sg, buf, len);
+ ctx = (void *)(unsigned long)len;
err = virtqueue_add_inbuf_ctx(rq->vq, rq->sg, 1, buf, ctx, gfp);
if (err < 0)
put_page(virt_to_head_page(buf));
@@ -2743,9 +2742,9 @@ module_init(virtio_net_driver_init);
static __exit void virtio_net_driver_exit(void)
{
+ unregister_virtio_driver(&virtio_net_driver);
cpuhp_remove_multi_state(CPUHP_VIRT_NET_DEAD);
cpuhp_remove_multi_state(virtionet_online);
- unregister_virtio_driver(&virtio_net_driver);
}
module_exit(virtio_net_driver_exit);
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
index ba1c9f93592b..9c51b8be0038 100644
--- a/drivers/net/vmxnet3/vmxnet3_int.h
+++ b/drivers/net/vmxnet3/vmxnet3_int.h
@@ -311,7 +311,7 @@ struct vmxnet3_intr {
u8 num_intrs; /* # of intr vectors */
u8 event_intr_idx; /* idx of the intr vector for event */
u8 mod_levels[VMXNET3_LINUX_MAX_MSIX_VECT]; /* moderation level */
- char event_msi_vector_name[IFNAMSIZ+11];
+ char event_msi_vector_name[IFNAMSIZ+17];
#ifdef CONFIG_PCI_MSI
struct msix_entry msix_entries[VMXNET3_LINUX_MAX_MSIX_VECT];
#endif
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 96aa7e6cf214..e17baac70f43 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -623,6 +623,7 @@ static struct sk_buff **vxlan_gro_receive(struct sock *sk,
out:
skb_gro_remcsum_cleanup(skb, &grc);
+ skb->remcsum_offload = 0;
NAPI_GRO_CB(skb)->flush |= flush;
return pp;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index 2153e8062b4c..5cc3a07dda9e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -214,7 +214,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
/* Make sure there's enough writeable headroom */
if (skb_headroom(skb) < drvr->hdrlen || skb_header_cloned(skb)) {
- head_delta = drvr->hdrlen - skb_headroom(skb);
+ head_delta = max_t(int, drvr->hdrlen - skb_headroom(skb), 0);
brcmf_dbg(INFO, "%s: insufficient headroom (%d)\n",
brcmf_ifname(ifp), head_delta);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index fbcbb4325936..f3556122c6ac 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -2053,12 +2053,13 @@ static int brcmf_sdio_txpkt_hdalign(struct brcmf_sdio *bus, struct sk_buff *pkt)
atomic_inc(&stats->pktcow_failed);
return -ENOMEM;
}
+ head_pad = 0;
}
skb_push(pkt, head_pad);
dat_buf = (u8 *)(pkt->data);
}
memset(dat_buf, 0, head_pad + bus->tx_hdrlen);
- return 0;
+ return head_pad;
}
/**
@@ -4174,11 +4175,6 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
goto fail;
}
- /* allocate scatter-gather table. sg support
- * will be disabled upon allocation failure.
- */
- brcmf_sdiod_sgtable_alloc(bus->sdiodev);
-
/* Query the F2 block size, set roundup accordingly */
bus->blocksize = bus->sdiodev->func[2]->cur_blksize;
bus->roundup = min(max_roundup, bus->blocksize);
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
index adaa2f0097cc..fb40ddfced99 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
@@ -1189,11 +1189,11 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb)
next_reclaimed;
IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n",
next_reclaimed);
+ iwlagn_check_ratid_empty(priv, sta_id, tid);
}
iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs);
- iwlagn_check_ratid_empty(priv, sta_id, tid);
freed = 0;
/* process frames */
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
index 545d14b0bc92..f5c1127253cb 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
@@ -55,8 +55,8 @@ static inline bool iwl_trace_data(struct sk_buff *skb)
/* also account for the RFC 1042 header, of course */
offs += 6;
- return skb->len > offs + 2 &&
- *(__be16 *)(skb->data + offs) == cpu_to_be16(ETH_P_PAE);
+ return skb->len <= offs + 2 ||
+ *(__be16 *)(skb->data + offs) != cpu_to_be16(ETH_P_PAE);
}
static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index bcde1ba0f1c8..c7b1e58e3384 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -1084,7 +1084,13 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm)
lockdep_assert_held(&mvm->mutex);
- if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
+ if (test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status)) {
+ /*
+ * Now convert the HW_RESTART_REQUESTED flag to IN_HW_RESTART
+ * so later code will - from now on - see that we're doing it.
+ */
+ set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
+ clear_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
/* Clean up some internal and mac80211 state on restart */
iwl_mvm_restart_cleanup(mvm);
} else {
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index eaacfaf37206..ddd8719f27b8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1090,6 +1090,7 @@ struct iwl_mvm {
* @IWL_MVM_STATUS_HW_RFKILL: HW RF-kill is asserted
* @IWL_MVM_STATUS_HW_CTKILL: CT-kill is active
* @IWL_MVM_STATUS_ROC_RUNNING: remain-on-channel is running
+ * @IWL_MVM_STATUS_HW_RESTART_REQUESTED: HW restart was requested
* @IWL_MVM_STATUS_IN_HW_RESTART: HW restart is active
* @IWL_MVM_STATUS_IN_D0I3: NIC is in D0i3
* @IWL_MVM_STATUS_ROC_AUX_RUNNING: AUX remain-on-channel is running
@@ -1101,6 +1102,7 @@ enum iwl_mvm_status {
IWL_MVM_STATUS_HW_RFKILL,
IWL_MVM_STATUS_HW_CTKILL,
IWL_MVM_STATUS_ROC_RUNNING,
+ IWL_MVM_STATUS_HW_RESTART_REQUESTED,
IWL_MVM_STATUS_IN_HW_RESTART,
IWL_MVM_STATUS_IN_D0I3,
IWL_MVM_STATUS_ROC_AUX_RUNNING,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 4d1188b8736a..9c175d5e9d67 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -1235,9 +1235,8 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
*/
if (!mvm->fw_restart && fw_error) {
iwl_mvm_fw_dbg_collect_desc(mvm, &iwl_mvm_dump_desc_assert,
- NULL);
- } else if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART,
- &mvm->status)) {
+ NULL);
+ } else if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
struct iwl_mvm_reprobe *reprobe;
IWL_ERR(mvm,
@@ -1268,6 +1267,7 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
if (fw_error && mvm->fw_restart > 0)
mvm->fw_restart--;
+ set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
ieee80211_restart_hw(mvm->hw);
}
}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 4df5f13fcdae..ab66b4394dfc 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -277,6 +277,18 @@ static void iwl_mvm_rx_agg_session_expired(unsigned long data)
/* Timer expired */
sta = rcu_dereference(ba_data->mvm->fw_id_to_mac_id[ba_data->sta_id]);
+
+ /*
+ * sta should be valid unless the following happens:
+ * The firmware asserts which triggers a reconfig flow, but
+ * the reconfig fails before we set the pointer to sta into
+ * the fw_id_to_mac_id pointer table. Mac80211 can't stop
+ * A-MDPU and hence the timer continues to run. Then, the
+ * timer expires and sta is NULL.
+ */
+ if (!sta)
+ goto unlock;
+
mvm_sta = iwl_mvm_sta_from_mac80211(sta);
ieee80211_stop_rx_ba_session_offl(mvm_sta->vif,
sta->addr, ba_data->tid);
@@ -2015,7 +2027,8 @@ int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
IWL_MAX_TID_COUNT,
wdg_timeout);
- if (vif->type == NL80211_IFTYPE_AP)
+ if (vif->type == NL80211_IFTYPE_AP ||
+ vif->type == NL80211_IFTYPE_ADHOC)
mvm->probe_queue = queue;
else if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
mvm->p2p_dev_queue = queue;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 92b3a55d0fbc..f95eec52508e 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -3150,7 +3150,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
init_waitqueue_head(&trans_pcie->d0i3_waitq);
if (trans_pcie->msix_enabled) {
- if (iwl_pcie_init_msix_handler(pdev, trans_pcie))
+ ret = iwl_pcie_init_msix_handler(pdev, trans_pcie);
+ if (ret)
goto out_no_pci;
} else {
ret = iwl_pcie_alloc_ict(trans);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index de50418adae5..034bdb4a0b06 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -298,6 +298,9 @@ void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans)
for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) {
struct iwl_txq *txq = trans_pcie->txq[i];
+ if (!test_bit(i, trans_pcie->queue_used))
+ continue;
+
spin_lock_bh(&txq->lock);
if (txq->need_update) {
iwl_pcie_txq_inc_wr_ptr(trans, txq);
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 6e2e760d98b1..0b75def39c6c 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -5704,7 +5704,7 @@ static void rt2800_init_freq_calibration(struct rt2x00_dev *rt2x00dev)
static void rt2800_init_bbp_5592_glrt(struct rt2x00_dev *rt2x00dev)
{
- const u8 glrt_table[] = {
+ static const u8 glrt_table[] = {
0xE0, 0x1F, 0X38, 0x32, 0x08, 0x28, 0x19, 0x0A, 0xFF, 0x00, /* 128 ~ 137 */
0x16, 0x10, 0x10, 0x0B, 0x36, 0x2C, 0x26, 0x24, 0x42, 0x36, /* 138 ~ 147 */
0x30, 0x2D, 0x4C, 0x46, 0x3D, 0x40, 0x3E, 0x42, 0x3D, 0x40, /* 148 ~ 157 */
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
index 2a7ad5ffe997..cd5dc6dcb19f 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
@@ -846,9 +846,6 @@ static bool _rtl8723be_init_mac(struct ieee80211_hw *hw)
return false;
}
- if (rtlpriv->cfg->ops->get_btc_status())
- rtlpriv->btcoexist.btc_ops->btc_power_on_setting(rtlpriv);
-
bytetmp = rtl_read_byte(rtlpriv, REG_MULTI_FUNC_CTRL);
rtl_write_byte(rtlpriv, REG_MULTI_FUNC_CTRL, bytetmp | BIT(3));
diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h
index fb1ebb01133f..70723e67b7d7 100644
--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h
+++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h
@@ -2547,7 +2547,6 @@ struct bt_coexist_info {
struct rtl_btc_ops {
void (*btc_init_variables) (struct rtl_priv *rtlpriv);
void (*btc_init_hal_vars) (struct rtl_priv *rtlpriv);
- void (*btc_power_on_setting)(struct rtl_priv *rtlpriv);
void (*btc_init_hw_config) (struct rtl_priv *rtlpriv);
void (*btc_ips_notify) (struct rtl_priv *rtlpriv, u8 type);
void (*btc_lps_notify)(struct rtl_priv *rtlpriv, u8 type);
diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c
index 7cd99b1f8596..75bc08c6838c 100644
--- a/drivers/nvdimm/core.c
+++ b/drivers/nvdimm/core.c
@@ -421,14 +421,15 @@ static void set_badblock(struct badblocks *bb, sector_t s, int num)
static void __add_badblock_range(struct badblocks *bb, u64 ns_offset, u64 len)
{
const unsigned int sector_size = 512;
- sector_t start_sector;
+ sector_t start_sector, end_sector;
u64 num_sectors;
u32 rem;
start_sector = div_u64(ns_offset, sector_size);
- num_sectors = div_u64_rem(len, sector_size, &rem);
+ end_sector = div_u64_rem(ns_offset + len, sector_size, &rem);
if (rem)
- num_sectors++;
+ end_sector++;
+ num_sectors = end_sector - start_sector;
if (unlikely(num_sectors > (u64)INT_MAX)) {
u64 remaining = num_sectors;
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index cb96f4a7ae3a..37046ac2c441 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -336,7 +336,7 @@ static int nvme_get_stream_params(struct nvme_ctrl *ctrl,
c.directive.opcode = nvme_admin_directive_recv;
c.directive.nsid = cpu_to_le32(nsid);
- c.directive.numd = sizeof(*s);
+ c.directive.numd = cpu_to_le32((sizeof(*s) >> 2) - 1);
c.directive.doper = NVME_DIR_RCV_ST_OP_PARAM;
c.directive.dtype = NVME_DIR_STREAMS;
@@ -1509,7 +1509,7 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,
blk_queue_write_cache(q, vwc, vwc);
}
-static void nvme_configure_apst(struct nvme_ctrl *ctrl)
+static int nvme_configure_apst(struct nvme_ctrl *ctrl)
{
/*
* APST (Autonomous Power State Transition) lets us program a
@@ -1538,16 +1538,16 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl)
* then don't do anything.
*/
if (!ctrl->apsta)
- return;
+ return 0;
if (ctrl->npss > 31) {
dev_warn(ctrl->device, "NPSS is invalid; not using APST\n");
- return;
+ return 0;
}
table = kzalloc(sizeof(*table), GFP_KERNEL);
if (!table)
- return;
+ return 0;
if (!ctrl->apst_enabled || ctrl->ps_max_latency_us == 0) {
/* Turn off APST. */
@@ -1629,6 +1629,7 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl)
dev_err(ctrl->device, "failed to set APST feature (%d)\n", ret);
kfree(table);
+ return ret;
}
static void nvme_set_latency_tolerance(struct device *dev, s32 val)
@@ -1835,13 +1836,16 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
* In fabrics we need to verify the cntlid matches the
* admin connect
*/
- if (ctrl->cntlid != le16_to_cpu(id->cntlid))
+ if (ctrl->cntlid != le16_to_cpu(id->cntlid)) {
ret = -EINVAL;
+ goto out_free;
+ }
if (!ctrl->opts->discovery_nqn && !ctrl->kas) {
dev_err(ctrl->device,
"keep-alive support is mandatory for fabrics\n");
ret = -EINVAL;
+ goto out_free;
}
} else {
ctrl->cntlid = le16_to_cpu(id->cntlid);
@@ -1856,11 +1860,20 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
else if (!ctrl->apst_enabled && prev_apst_enabled)
dev_pm_qos_hide_latency_tolerance(ctrl->device);
- nvme_configure_apst(ctrl);
- nvme_configure_directives(ctrl);
+ ret = nvme_configure_apst(ctrl);
+ if (ret < 0)
+ return ret;
+
+ ret = nvme_configure_directives(ctrl);
+ if (ret < 0)
+ return ret;
ctrl->identified = true;
+ return 0;
+
+out_free:
+ kfree(id);
return ret;
}
EXPORT_SYMBOL_GPL(nvme_init_identify);
@@ -1995,15 +2008,20 @@ static ssize_t wwid_show(struct device *dev, struct device_attribute *attr,
int serial_len = sizeof(ctrl->serial);
int model_len = sizeof(ctrl->model);
+ if (!uuid_is_null(&ns->uuid))
+ return sprintf(buf, "uuid.%pU\n", &ns->uuid);
+
if (memchr_inv(ns->nguid, 0, sizeof(ns->nguid)))
return sprintf(buf, "eui.%16phN\n", ns->nguid);
if (memchr_inv(ns->eui, 0, sizeof(ns->eui)))
return sprintf(buf, "eui.%8phN\n", ns->eui);
- while (ctrl->serial[serial_len - 1] == ' ')
+ while (serial_len > 0 && (ctrl->serial[serial_len - 1] == ' ' ||
+ ctrl->serial[serial_len - 1] == '\0'))
serial_len--;
- while (ctrl->model[model_len - 1] == ' ')
+ while (model_len > 0 && (ctrl->model[model_len - 1] == ' ' ||
+ ctrl->model[model_len - 1] == '\0'))
model_len--;
return sprintf(buf, "nvme.%04x-%*phN-%*phN-%08x\n", ctrl->vid,
@@ -2709,7 +2727,8 @@ void nvme_kill_queues(struct nvme_ctrl *ctrl)
mutex_lock(&ctrl->namespaces_mutex);
/* Forcibly unquiesce queues to avoid blocking dispatch */
- blk_mq_unquiesce_queue(ctrl->admin_q);
+ if (ctrl->admin_q)
+ blk_mq_unquiesce_queue(ctrl->admin_q);
list_for_each_entry(ns, &ctrl->namespaces, list) {
/*
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
index d666ada39a9b..5c2a08ef08ba 100644
--- a/drivers/nvme/host/fc.c
+++ b/drivers/nvme/host/fc.c
@@ -1888,7 +1888,7 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue,
* the target device is present
*/
if (ctrl->rport->remoteport.port_state != FC_OBJSTATE_ONLINE)
- return BLK_STS_IOERR;
+ goto busy;
if (!nvme_fc_ctrl_get(ctrl))
return BLK_STS_IOERR;
@@ -1958,22 +1958,25 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue,
queue->lldd_handle, &op->fcp_req);
if (ret) {
- if (op->rq) /* normal request */
+ if (!(op->flags & FCOP_FLAGS_AEN))
nvme_fc_unmap_data(ctrl, op->rq, op);
- /* else - aen. no cleanup needed */
nvme_fc_ctrl_put(ctrl);
- if (ret != -EBUSY)
+ if (ctrl->rport->remoteport.port_state == FC_OBJSTATE_ONLINE &&
+ ret != -EBUSY)
return BLK_STS_IOERR;
- if (op->rq)
- blk_mq_delay_run_hw_queue(queue->hctx, NVMEFC_QUEUE_DELAY);
-
- return BLK_STS_RESOURCE;
+ goto busy;
}
return BLK_STS_OK;
+
+busy:
+ if (!(op->flags & FCOP_FLAGS_AEN) && queue->hctx)
+ blk_mq_delay_run_hw_queue(queue->hctx, NVMEFC_QUEUE_DELAY);
+
+ return BLK_STS_RESOURCE;
}
static blk_status_t
@@ -2802,66 +2805,70 @@ out_fail:
return ERR_PTR(ret);
}
-enum {
- FCT_TRADDR_ERR = 0,
- FCT_TRADDR_WWNN = 1 << 0,
- FCT_TRADDR_WWPN = 1 << 1,
-};
struct nvmet_fc_traddr {
u64 nn;
u64 pn;
};
-static const match_table_t traddr_opt_tokens = {
- { FCT_TRADDR_WWNN, "nn-%s" },
- { FCT_TRADDR_WWPN, "pn-%s" },
- { FCT_TRADDR_ERR, NULL }
-};
-
static int
-nvme_fc_parse_address(struct nvmet_fc_traddr *traddr, char *buf)
+__nvme_fc_parse_u64(substring_t *sstr, u64 *val)
{
- substring_t args[MAX_OPT_ARGS];
- char *options, *o, *p;
- int token, ret = 0;
u64 token64;
- options = o = kstrdup(buf, GFP_KERNEL);
- if (!options)
- return -ENOMEM;
+ if (match_u64(sstr, &token64))
+ return -EINVAL;
+ *val = token64;
- while ((p = strsep(&o, ":\n")) != NULL) {
- if (!*p)
- continue;
+ return 0;
+}
- token = match_token(p, traddr_opt_tokens, args);
- switch (token) {
- case FCT_TRADDR_WWNN:
- if (match_u64(args, &token64)) {
- ret = -EINVAL;
- goto out;
- }
- traddr->nn = token64;
- break;
- case FCT_TRADDR_WWPN:
- if (match_u64(args, &token64)) {
- ret = -EINVAL;
- goto out;
- }
- traddr->pn = token64;
- break;
- default:
- pr_warn("unknown traddr token or missing value '%s'\n",
- p);
- ret = -EINVAL;
- goto out;
- }
- }
+/*
+ * This routine validates and extracts the WWN's from the TRADDR string.
+ * As kernel parsers need the 0x to determine number base, universally
+ * build string to parse with 0x prefix before parsing name strings.
+ */
+static int
+nvme_fc_parse_traddr(struct nvmet_fc_traddr *traddr, char *buf, size_t blen)
+{
+ char name[2 + NVME_FC_TRADDR_HEXNAMELEN + 1];
+ substring_t wwn = { name, &name[sizeof(name)-1] };
+ int nnoffset, pnoffset;
+
+ /* validate it string one of the 2 allowed formats */
+ if (strnlen(buf, blen) == NVME_FC_TRADDR_MAXLENGTH &&
+ !strncmp(buf, "nn-0x", NVME_FC_TRADDR_OXNNLEN) &&
+ !strncmp(&buf[NVME_FC_TRADDR_MAX_PN_OFFSET],
+ "pn-0x", NVME_FC_TRADDR_OXNNLEN)) {
+ nnoffset = NVME_FC_TRADDR_OXNNLEN;
+ pnoffset = NVME_FC_TRADDR_MAX_PN_OFFSET +
+ NVME_FC_TRADDR_OXNNLEN;
+ } else if ((strnlen(buf, blen) == NVME_FC_TRADDR_MINLENGTH &&
+ !strncmp(buf, "nn-", NVME_FC_TRADDR_NNLEN) &&
+ !strncmp(&buf[NVME_FC_TRADDR_MIN_PN_OFFSET],
+ "pn-", NVME_FC_TRADDR_NNLEN))) {
+ nnoffset = NVME_FC_TRADDR_NNLEN;
+ pnoffset = NVME_FC_TRADDR_MIN_PN_OFFSET + NVME_FC_TRADDR_NNLEN;
+ } else
+ goto out_einval;
-out:
- kfree(options);
- return ret;
+ name[0] = '0';
+ name[1] = 'x';
+ name[2 + NVME_FC_TRADDR_HEXNAMELEN] = 0;
+
+ memcpy(&name[2], &buf[nnoffset], NVME_FC_TRADDR_HEXNAMELEN);
+ if (__nvme_fc_parse_u64(&wwn, &traddr->nn))
+ goto out_einval;
+
+ memcpy(&name[2], &buf[pnoffset], NVME_FC_TRADDR_HEXNAMELEN);
+ if (__nvme_fc_parse_u64(&wwn, &traddr->pn))
+ goto out_einval;
+
+ return 0;
+
+out_einval:
+ pr_warn("%s: bad traddr string\n", __func__);
+ return -EINVAL;
}
static struct nvme_ctrl *
@@ -2875,11 +2882,11 @@ nvme_fc_create_ctrl(struct device *dev, struct nvmf_ctrl_options *opts)
unsigned long flags;
int ret;
- ret = nvme_fc_parse_address(&raddr, opts->traddr);
+ ret = nvme_fc_parse_traddr(&raddr, opts->traddr, NVMF_TRADDR_SIZE);
if (ret || !raddr.nn || !raddr.pn)
return ERR_PTR(-EINVAL);
- ret = nvme_fc_parse_address(&laddr, opts->host_traddr);
+ ret = nvme_fc_parse_traddr(&laddr, opts->host_traddr, NVMF_TRADDR_SIZE);
if (ret || !laddr.nn || !laddr.pn)
return ERR_PTR(-EINVAL);
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index d10d2f279d19..74a124a06264 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -539,7 +539,7 @@ static void nvme_dif_complete(u32 p, u32 v, struct t10_pi_tuple *pi)
}
#endif
-static bool nvme_setup_prps(struct nvme_dev *dev, struct request *req)
+static blk_status_t nvme_setup_prps(struct nvme_dev *dev, struct request *req)
{
struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
struct dma_pool *pool;
@@ -556,7 +556,7 @@ static bool nvme_setup_prps(struct nvme_dev *dev, struct request *req)
length -= (page_size - offset);
if (length <= 0)
- return true;
+ return BLK_STS_OK;
dma_len -= (page_size - offset);
if (dma_len) {
@@ -569,7 +569,7 @@ static bool nvme_setup_prps(struct nvme_dev *dev, struct request *req)
if (length <= page_size) {
iod->first_dma = dma_addr;
- return true;
+ return BLK_STS_OK;
}
nprps = DIV_ROUND_UP(length, page_size);
@@ -585,7 +585,7 @@ static bool nvme_setup_prps(struct nvme_dev *dev, struct request *req)
if (!prp_list) {
iod->first_dma = dma_addr;
iod->npages = -1;
- return false;
+ return BLK_STS_RESOURCE;
}
list[0] = prp_list;
iod->first_dma = prp_dma;
@@ -595,7 +595,7 @@ static bool nvme_setup_prps(struct nvme_dev *dev, struct request *req)
__le64 *old_prp_list = prp_list;
prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma);
if (!prp_list)
- return false;
+ return BLK_STS_RESOURCE;
list[iod->npages++] = prp_list;
prp_list[0] = old_prp_list[i - 1];
old_prp_list[i - 1] = cpu_to_le64(prp_dma);
@@ -609,13 +609,29 @@ static bool nvme_setup_prps(struct nvme_dev *dev, struct request *req)
break;
if (dma_len > 0)
continue;
- BUG_ON(dma_len < 0);
+ if (unlikely(dma_len < 0))
+ goto bad_sgl;
sg = sg_next(sg);
dma_addr = sg_dma_address(sg);
dma_len = sg_dma_len(sg);
}
- return true;
+ return BLK_STS_OK;
+
+ bad_sgl:
+ if (WARN_ONCE(1, "Invalid SGL for payload:%d nents:%d\n",
+ blk_rq_payload_bytes(req), iod->nents)) {
+ for_each_sg(iod->sg, sg, iod->nents, i) {
+ dma_addr_t phys = sg_phys(sg);
+ pr_warn("sg[%d] phys_addr:%pad offset:%d length:%d "
+ "dma_address:%pad dma_length:%d\n", i, &phys,
+ sg->offset, sg->length,
+ &sg_dma_address(sg),
+ sg_dma_len(sg));
+ }
+ }
+ return BLK_STS_IOERR;
+
}
static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req,
@@ -637,7 +653,8 @@ static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req,
DMA_ATTR_NO_WARN))
goto out;
- if (!nvme_setup_prps(dev, req))
+ ret = nvme_setup_prps(dev, req);
+ if (ret != BLK_STS_OK)
goto out_unmap;
ret = BLK_STS_IOERR;
@@ -1541,11 +1558,9 @@ static inline void nvme_release_cmb(struct nvme_dev *dev)
if (dev->cmb) {
iounmap(dev->cmb);
dev->cmb = NULL;
- if (dev->cmbsz) {
- sysfs_remove_file_from_group(&dev->ctrl.device->kobj,
- &dev_attr_cmb.attr, NULL);
- dev->cmbsz = 0;
- }
+ sysfs_remove_file_from_group(&dev->ctrl.device->kobj,
+ &dev_attr_cmb.attr, NULL);
+ dev->cmbsz = 0;
}
}
@@ -1602,7 +1617,7 @@ static void nvme_free_host_mem(struct nvme_dev *dev)
static int nvme_alloc_host_mem(struct nvme_dev *dev, u64 min, u64 preferred)
{
struct nvme_host_mem_buf_desc *descs;
- u32 chunk_size, max_entries;
+ u32 chunk_size, max_entries, len;
int i = 0;
void **bufs;
u64 size = 0, tmp;
@@ -1621,10 +1636,10 @@ retry:
if (!bufs)
goto out_free_descs;
- for (size = 0; size < preferred; size += chunk_size) {
- u32 len = min_t(u64, chunk_size, preferred - size);
+ for (size = 0; size < preferred; size += len) {
dma_addr_t dma_addr;
+ len = min_t(u64, chunk_size, preferred - size);
bufs[i] = dma_alloc_attrs(dev->dev, len, &dma_addr, GFP_KERNEL,
DMA_ATTR_NO_KERNEL_MAPPING | DMA_ATTR_NO_WARN);
if (!bufs[i])
@@ -1936,16 +1951,14 @@ static int nvme_pci_enable(struct nvme_dev *dev)
/*
* CMBs can currently only exist on >=1.2 PCIe devices. We only
- * populate sysfs if a CMB is implemented. Note that we add the
- * CMB attribute to the nvme_ctrl kobj which removes the need to remove
- * it on exit. Since nvme_dev_attrs_group has no name we can pass
- * NULL as final argument to sysfs_add_file_to_group.
+ * populate sysfs if a CMB is implemented. Since nvme_dev_attrs_group
+ * has no name we can pass NULL as final argument to
+ * sysfs_add_file_to_group.
*/
if (readl(dev->bar + NVME_REG_VS) >= NVME_VS(1, 2, 0)) {
dev->cmb = nvme_map_cmb(dev);
-
- if (dev->cmbsz) {
+ if (dev->cmb) {
if (sysfs_add_file_to_group(&dev->ctrl.device->kobj,
&dev_attr_cmb.attr, NULL))
dev_warn(dev->ctrl.device,
@@ -2282,7 +2295,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
result = nvme_dev_map(dev);
if (result)
- goto free;
+ goto put_pci;
INIT_WORK(&dev->ctrl.reset_work, nvme_reset_work);
INIT_WORK(&dev->remove_work, nvme_remove_dead_ctrl_work);
@@ -2291,7 +2304,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
result = nvme_setup_prp_pools(dev);
if (result)
- goto put_pci;
+ goto unmap;
quirks |= check_dell_samsung_bug(pdev);
@@ -2308,9 +2321,10 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
release_pools:
nvme_release_prp_pools(dev);
+ unmap:
+ nvme_dev_unmap(dev);
put_pci:
put_device(dev->dev);
- nvme_dev_unmap(dev);
free:
kfree(dev->queues);
kfree(dev);
@@ -2466,6 +2480,9 @@ static const struct pci_device_id nvme_id_table[] = {
{ PCI_VDEVICE(INTEL, 0x0a54),
.driver_data = NVME_QUIRK_STRIPE_SIZE |
NVME_QUIRK_DEALLOCATE_ZEROES, },
+ { PCI_VDEVICE(INTEL, 0x0a55),
+ .driver_data = NVME_QUIRK_STRIPE_SIZE |
+ NVME_QUIRK_DEALLOCATE_ZEROES, },
{ PCI_VDEVICE(INTEL, 0xf1a5), /* Intel 600P/P3100 */
.driver_data = NVME_QUIRK_NO_DEEPEST_PS },
{ PCI_VDEVICE(INTEL, 0x5845), /* Qemu emulated controller */
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
index 35f930db3c02..2d7a98ab53fb 100644
--- a/drivers/nvme/target/admin-cmd.c
+++ b/drivers/nvme/target/admin-cmd.c
@@ -168,11 +168,21 @@ out:
nvmet_req_complete(req, status);
}
+static void copy_and_pad(char *dst, int dst_len, const char *src, int src_len)
+{
+ int len = min(src_len, dst_len);
+
+ memcpy(dst, src, len);
+ if (dst_len > len)
+ memset(dst + len, ' ', dst_len - len);
+}
+
static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
{
struct nvmet_ctrl *ctrl = req->sq->ctrl;
struct nvme_id_ctrl *id;
u16 status = 0;
+ const char model[] = "Linux";
id = kzalloc(sizeof(*id), GFP_KERNEL);
if (!id) {
@@ -184,8 +194,10 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
id->vid = 0;
id->ssvid = 0;
- memset(id->sn, ' ', sizeof(id->sn));
- snprintf(id->sn, sizeof(id->sn), "%llx", ctrl->serial);
+ bin2hex(id->sn, &ctrl->subsys->serial,
+ min(sizeof(ctrl->subsys->serial), sizeof(id->sn) / 2));
+ copy_and_pad(id->mn, sizeof(id->mn), model, sizeof(model) - 1);
+ copy_and_pad(id->fr, sizeof(id->fr), UTS_RELEASE, strlen(UTS_RELEASE));
memset(id->mn, ' ', sizeof(id->mn));
strncpy((char *)id->mn, "Linux", sizeof(id->mn));
diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
index a358ecd93e11..0a0067e771f5 100644
--- a/drivers/nvme/target/configfs.c
+++ b/drivers/nvme/target/configfs.c
@@ -650,7 +650,7 @@ out_unlock:
CONFIGFS_ATTR(nvmet_subsys_, attr_allow_any_host);
-static ssize_t nvmet_subsys_version_show(struct config_item *item,
+static ssize_t nvmet_subsys_attr_version_show(struct config_item *item,
char *page)
{
struct nvmet_subsys *subsys = to_subsys(item);
@@ -666,7 +666,7 @@ static ssize_t nvmet_subsys_version_show(struct config_item *item,
(int)NVME_MINOR(subsys->ver));
}
-static ssize_t nvmet_subsys_version_store(struct config_item *item,
+static ssize_t nvmet_subsys_attr_version_store(struct config_item *item,
const char *page, size_t count)
{
struct nvmet_subsys *subsys = to_subsys(item);
@@ -684,11 +684,33 @@ static ssize_t nvmet_subsys_version_store(struct config_item *item,
return count;
}
-CONFIGFS_ATTR(nvmet_subsys_, version);
+CONFIGFS_ATTR(nvmet_subsys_, attr_version);
+
+static ssize_t nvmet_subsys_attr_serial_show(struct config_item *item,
+ char *page)
+{
+ struct nvmet_subsys *subsys = to_subsys(item);
+
+ return snprintf(page, PAGE_SIZE, "%llx\n", subsys->serial);
+}
+
+static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct nvmet_subsys *subsys = to_subsys(item);
+
+ down_write(&nvmet_config_sem);
+ sscanf(page, "%llx\n", &subsys->serial);
+ up_write(&nvmet_config_sem);
+
+ return count;
+}
+CONFIGFS_ATTR(nvmet_subsys_, attr_serial);
static struct configfs_attribute *nvmet_subsys_attrs[] = {
&nvmet_subsys_attr_attr_allow_any_host,
- &nvmet_subsys_attr_version,
+ &nvmet_subsys_attr_attr_version,
+ &nvmet_subsys_attr_attr_serial,
NULL,
};
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index b5b4ac103748..f4b02bb4a1a8 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -767,9 +767,6 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
memcpy(ctrl->subsysnqn, subsysnqn, NVMF_NQN_SIZE);
memcpy(ctrl->hostnqn, hostnqn, NVMF_NQN_SIZE);
- /* generate a random serial number as our controllers are ephemeral: */
- get_random_bytes(&ctrl->serial, sizeof(ctrl->serial));
-
kref_init(&ctrl->ref);
ctrl->subsys = subsys;
@@ -928,6 +925,8 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn,
return NULL;
subsys->ver = NVME_VS(1, 3, 0); /* NVMe 1.3.0 */
+ /* generate a random serial number as our controllers are ephemeral: */
+ get_random_bytes(&subsys->serial, sizeof(subsys->serial));
switch (type) {
case NVME_NQN_NVME:
diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c
index 1e6dcc241b3c..1b7f2520a20d 100644
--- a/drivers/nvme/target/fc.c
+++ b/drivers/nvme/target/fc.c
@@ -114,6 +114,11 @@ struct nvmet_fc_tgtport {
struct kref ref;
};
+struct nvmet_fc_defer_fcp_req {
+ struct list_head req_list;
+ struct nvmefc_tgt_fcp_req *fcp_req;
+};
+
struct nvmet_fc_tgt_queue {
bool ninetypercent;
u16 qid;
@@ -132,6 +137,8 @@ struct nvmet_fc_tgt_queue {
struct nvmet_fc_tgt_assoc *assoc;
struct nvmet_fc_fcp_iod *fod; /* array of fcp_iods */
struct list_head fod_list;
+ struct list_head pending_cmd_list;
+ struct list_head avail_defer_list;
struct workqueue_struct *work_q;
struct kref ref;
} __aligned(sizeof(unsigned long long));
@@ -223,6 +230,8 @@ static void nvmet_fc_tgt_q_put(struct nvmet_fc_tgt_queue *queue);
static int nvmet_fc_tgt_q_get(struct nvmet_fc_tgt_queue *queue);
static void nvmet_fc_tgtport_put(struct nvmet_fc_tgtport *tgtport);
static int nvmet_fc_tgtport_get(struct nvmet_fc_tgtport *tgtport);
+static void nvmet_fc_handle_fcp_rqst(struct nvmet_fc_tgtport *tgtport,
+ struct nvmet_fc_fcp_iod *fod);
/* *********************** FC-NVME DMA Handling **************************** */
@@ -463,9 +472,9 @@ static struct nvmet_fc_fcp_iod *
nvmet_fc_alloc_fcp_iod(struct nvmet_fc_tgt_queue *queue)
{
static struct nvmet_fc_fcp_iod *fod;
- unsigned long flags;
- spin_lock_irqsave(&queue->qlock, flags);
+ lockdep_assert_held(&queue->qlock);
+
fod = list_first_entry_or_null(&queue->fod_list,
struct nvmet_fc_fcp_iod, fcp_list);
if (fod) {
@@ -477,17 +486,37 @@ nvmet_fc_alloc_fcp_iod(struct nvmet_fc_tgt_queue *queue)
* will "inherit" that reference.
*/
}
- spin_unlock_irqrestore(&queue->qlock, flags);
return fod;
}
static void
+nvmet_fc_queue_fcp_req(struct nvmet_fc_tgtport *tgtport,
+ struct nvmet_fc_tgt_queue *queue,
+ struct nvmefc_tgt_fcp_req *fcpreq)
+{
+ struct nvmet_fc_fcp_iod *fod = fcpreq->nvmet_fc_private;
+
+ /*
+ * put all admin cmds on hw queue id 0. All io commands go to
+ * the respective hw queue based on a modulo basis
+ */
+ fcpreq->hwqid = queue->qid ?
+ ((queue->qid - 1) % tgtport->ops->max_hw_queues) : 0;
+
+ if (tgtport->ops->target_features & NVMET_FCTGTFEAT_CMD_IN_ISR)
+ queue_work_on(queue->cpu, queue->work_q, &fod->work);
+ else
+ nvmet_fc_handle_fcp_rqst(tgtport, fod);
+}
+
+static void
nvmet_fc_free_fcp_iod(struct nvmet_fc_tgt_queue *queue,
struct nvmet_fc_fcp_iod *fod)
{
struct nvmefc_tgt_fcp_req *fcpreq = fod->fcpreq;
struct nvmet_fc_tgtport *tgtport = fod->tgtport;
+ struct nvmet_fc_defer_fcp_req *deferfcp;
unsigned long flags;
fc_dma_sync_single_for_cpu(tgtport->dev, fod->rspdma,
@@ -495,21 +524,56 @@ nvmet_fc_free_fcp_iod(struct nvmet_fc_tgt_queue *queue,
fcpreq->nvmet_fc_private = NULL;
- spin_lock_irqsave(&queue->qlock, flags);
- list_add_tail(&fod->fcp_list, &fod->queue->fod_list);
fod->active = false;
fod->abort = false;
fod->aborted = false;
fod->writedataactive = false;
fod->fcpreq = NULL;
+
+ tgtport->ops->fcp_req_release(&tgtport->fc_target_port, fcpreq);
+
+ spin_lock_irqsave(&queue->qlock, flags);
+ deferfcp = list_first_entry_or_null(&queue->pending_cmd_list,
+ struct nvmet_fc_defer_fcp_req, req_list);
+ if (!deferfcp) {
+ list_add_tail(&fod->fcp_list, &fod->queue->fod_list);
+ spin_unlock_irqrestore(&queue->qlock, flags);
+
+ /* Release reference taken at queue lookup and fod allocation */
+ nvmet_fc_tgt_q_put(queue);
+ return;
+ }
+
+ /* Re-use the fod for the next pending cmd that was deferred */
+ list_del(&deferfcp->req_list);
+
+ fcpreq = deferfcp->fcp_req;
+
+ /* deferfcp can be reused for another IO at a later date */
+ list_add_tail(&deferfcp->req_list, &queue->avail_defer_list);
+
spin_unlock_irqrestore(&queue->qlock, flags);
+ /* Save NVME CMD IO in fod */
+ memcpy(&fod->cmdiubuf, fcpreq->rspaddr, fcpreq->rsplen);
+
+ /* Setup new fcpreq to be processed */
+ fcpreq->rspaddr = NULL;
+ fcpreq->rsplen = 0;
+ fcpreq->nvmet_fc_private = fod;
+ fod->fcpreq = fcpreq;
+ fod->active = true;
+
+ /* inform LLDD IO is now being processed */
+ tgtport->ops->defer_rcv(&tgtport->fc_target_port, fcpreq);
+
+ /* Submit deferred IO for processing */
+ nvmet_fc_queue_fcp_req(tgtport, queue, fcpreq);
+
/*
- * release the reference taken at queue lookup and fod allocation
+ * Leave the queue lookup get reference taken when
+ * fod was originally allocated.
*/
- nvmet_fc_tgt_q_put(queue);
-
- tgtport->ops->fcp_req_release(&tgtport->fc_target_port, fcpreq);
}
static int
@@ -569,6 +633,8 @@ nvmet_fc_alloc_target_queue(struct nvmet_fc_tgt_assoc *assoc,
queue->port = assoc->tgtport->port;
queue->cpu = nvmet_fc_queue_to_cpu(assoc->tgtport, qid);
INIT_LIST_HEAD(&queue->fod_list);
+ INIT_LIST_HEAD(&queue->avail_defer_list);
+ INIT_LIST_HEAD(&queue->pending_cmd_list);
atomic_set(&queue->connected, 0);
atomic_set(&queue->sqtail, 0);
atomic_set(&queue->rsn, 1);
@@ -638,6 +704,7 @@ nvmet_fc_delete_target_queue(struct nvmet_fc_tgt_queue *queue)
{
struct nvmet_fc_tgtport *tgtport = queue->assoc->tgtport;
struct nvmet_fc_fcp_iod *fod = queue->fod;
+ struct nvmet_fc_defer_fcp_req *deferfcp;
unsigned long flags;
int i, writedataactive;
bool disconnect;
@@ -666,6 +733,35 @@ nvmet_fc_delete_target_queue(struct nvmet_fc_tgt_queue *queue)
}
}
}
+
+ /* Cleanup defer'ed IOs in queue */
+ list_for_each_entry(deferfcp, &queue->avail_defer_list, req_list) {
+ list_del(&deferfcp->req_list);
+ kfree(deferfcp);
+ }
+
+ for (;;) {
+ deferfcp = list_first_entry_or_null(&queue->pending_cmd_list,
+ struct nvmet_fc_defer_fcp_req, req_list);
+ if (!deferfcp)
+ break;
+
+ list_del(&deferfcp->req_list);
+ spin_unlock_irqrestore(&queue->qlock, flags);
+
+ tgtport->ops->defer_rcv(&tgtport->fc_target_port,
+ deferfcp->fcp_req);
+
+ tgtport->ops->fcp_abort(&tgtport->fc_target_port,
+ deferfcp->fcp_req);
+
+ tgtport->ops->fcp_req_release(&tgtport->fc_target_port,
+ deferfcp->fcp_req);
+
+ kfree(deferfcp);
+
+ spin_lock_irqsave(&queue->qlock, flags);
+ }
spin_unlock_irqrestore(&queue->qlock, flags);
flush_workqueue(queue->work_q);
@@ -1174,14 +1270,14 @@ nvmet_fc_ls_create_association(struct nvmet_fc_tgtport *tgtport,
*/
if (iod->rqstdatalen < FCNVME_LSDESC_CRA_RQST_MINLEN)
ret = VERR_CR_ASSOC_LEN;
- else if (rqst->desc_list_len <
- cpu_to_be32(FCNVME_LSDESC_CRA_RQST_MIN_LISTLEN))
+ else if (be32_to_cpu(rqst->desc_list_len) <
+ FCNVME_LSDESC_CRA_RQST_MIN_LISTLEN)
ret = VERR_CR_ASSOC_RQST_LEN;
else if (rqst->assoc_cmd.desc_tag !=
cpu_to_be32(FCNVME_LSDESC_CREATE_ASSOC_CMD))
ret = VERR_CR_ASSOC_CMD;
- else if (rqst->assoc_cmd.desc_len <
- cpu_to_be32(FCNVME_LSDESC_CRA_CMD_DESC_MIN_DESCLEN))
+ else if (be32_to_cpu(rqst->assoc_cmd.desc_len) <
+ FCNVME_LSDESC_CRA_CMD_DESC_MIN_DESCLEN)
ret = VERR_CR_ASSOC_CMD_LEN;
else if (!rqst->assoc_cmd.ersp_ratio ||
(be16_to_cpu(rqst->assoc_cmd.ersp_ratio) >=
@@ -2172,11 +2268,38 @@ nvmet_fc_handle_fcp_rqst_work(struct work_struct *work)
* Pass a FC-NVME FCP CMD IU received from the FC link to the nvmet-fc
* layer for processing.
*
- * The nvmet-fc layer will copy cmd payload to an internal structure for
- * processing. As such, upon completion of the routine, the LLDD may
- * immediately free/reuse the CMD IU buffer passed in the call.
+ * The nvmet_fc layer allocates a local job structure (struct
+ * nvmet_fc_fcp_iod) from the queue for the io and copies the
+ * CMD IU buffer to the job structure. As such, on a successful
+ * completion (returns 0), the LLDD may immediately free/reuse
+ * the CMD IU buffer passed in the call.
*
- * If this routine returns error, the lldd should abort the exchange.
+ * However, in some circumstances, due to the packetized nature of FC
+ * and the api of the FC LLDD which may issue a hw command to send the
+ * response, but the LLDD may not get the hw completion for that command
+ * and upcall the nvmet_fc layer before a new command may be
+ * asynchronously received - its possible for a command to be received
+ * before the LLDD and nvmet_fc have recycled the job structure. It gives
+ * the appearance of more commands received than fits in the sq.
+ * To alleviate this scenario, a temporary queue is maintained in the
+ * transport for pending LLDD requests waiting for a queue job structure.
+ * In these "overrun" cases, a temporary queue element is allocated
+ * the LLDD request and CMD iu buffer information remembered, and the
+ * routine returns a -EOVERFLOW status. Subsequently, when a queue job
+ * structure is freed, it is immediately reallocated for anything on the
+ * pending request list. The LLDDs defer_rcv() callback is called,
+ * informing the LLDD that it may reuse the CMD IU buffer, and the io
+ * is then started normally with the transport.
+ *
+ * The LLDD, when receiving an -EOVERFLOW completion status, is to treat
+ * the completion as successful but must not reuse the CMD IU buffer
+ * until the LLDD's defer_rcv() callback has been called for the
+ * corresponding struct nvmefc_tgt_fcp_req pointer.
+ *
+ * If there is any other condition in which an error occurs, the
+ * transport will return a non-zero status indicating the error.
+ * In all cases other than -EOVERFLOW, the transport has not accepted the
+ * request and the LLDD should abort the exchange.
*
* @target_port: pointer to the (registered) target port the FCP CMD IU
* was received on.
@@ -2194,6 +2317,8 @@ nvmet_fc_rcv_fcp_req(struct nvmet_fc_target_port *target_port,
struct nvme_fc_cmd_iu *cmdiu = cmdiubuf;
struct nvmet_fc_tgt_queue *queue;
struct nvmet_fc_fcp_iod *fod;
+ struct nvmet_fc_defer_fcp_req *deferfcp;
+ unsigned long flags;
/* validate iu, so the connection id can be used to find the queue */
if ((cmdiubuf_len != sizeof(*cmdiu)) ||
@@ -2214,29 +2339,60 @@ nvmet_fc_rcv_fcp_req(struct nvmet_fc_target_port *target_port,
* when the fod is freed.
*/
+ spin_lock_irqsave(&queue->qlock, flags);
+
fod = nvmet_fc_alloc_fcp_iod(queue);
- if (!fod) {
+ if (fod) {
+ spin_unlock_irqrestore(&queue->qlock, flags);
+
+ fcpreq->nvmet_fc_private = fod;
+ fod->fcpreq = fcpreq;
+
+ memcpy(&fod->cmdiubuf, cmdiubuf, cmdiubuf_len);
+
+ nvmet_fc_queue_fcp_req(tgtport, queue, fcpreq);
+
+ return 0;
+ }
+
+ if (!tgtport->ops->defer_rcv) {
+ spin_unlock_irqrestore(&queue->qlock, flags);
/* release the queue lookup reference */
nvmet_fc_tgt_q_put(queue);
return -ENOENT;
}
- fcpreq->nvmet_fc_private = fod;
- fod->fcpreq = fcpreq;
- /*
- * put all admin cmds on hw queue id 0. All io commands go to
- * the respective hw queue based on a modulo basis
- */
- fcpreq->hwqid = queue->qid ?
- ((queue->qid - 1) % tgtport->ops->max_hw_queues) : 0;
- memcpy(&fod->cmdiubuf, cmdiubuf, cmdiubuf_len);
+ deferfcp = list_first_entry_or_null(&queue->avail_defer_list,
+ struct nvmet_fc_defer_fcp_req, req_list);
+ if (deferfcp) {
+ /* Just re-use one that was previously allocated */
+ list_del(&deferfcp->req_list);
+ } else {
+ spin_unlock_irqrestore(&queue->qlock, flags);
- if (tgtport->ops->target_features & NVMET_FCTGTFEAT_CMD_IN_ISR)
- queue_work_on(queue->cpu, queue->work_q, &fod->work);
- else
- nvmet_fc_handle_fcp_rqst(tgtport, fod);
+ /* Now we need to dynamically allocate one */
+ deferfcp = kmalloc(sizeof(*deferfcp), GFP_KERNEL);
+ if (!deferfcp) {
+ /* release the queue lookup reference */
+ nvmet_fc_tgt_q_put(queue);
+ return -ENOMEM;
+ }
+ spin_lock_irqsave(&queue->qlock, flags);
+ }
- return 0;
+ /* For now, use rspaddr / rsplen to save payload information */
+ fcpreq->rspaddr = cmdiubuf;
+ fcpreq->rsplen = cmdiubuf_len;
+ deferfcp->fcp_req = fcpreq;
+
+ /* defer processing till a fod becomes available */
+ list_add_tail(&deferfcp->req_list, &queue->pending_cmd_list);
+
+ /* NOTE: the queue lookup reference is still valid */
+
+ spin_unlock_irqrestore(&queue->qlock, flags);
+
+ return -EOVERFLOW;
}
EXPORT_SYMBOL_GPL(nvmet_fc_rcv_fcp_req);
@@ -2293,66 +2449,70 @@ nvmet_fc_rcv_fcp_abort(struct nvmet_fc_target_port *target_port,
}
EXPORT_SYMBOL_GPL(nvmet_fc_rcv_fcp_abort);
-enum {
- FCT_TRADDR_ERR = 0,
- FCT_TRADDR_WWNN = 1 << 0,
- FCT_TRADDR_WWPN = 1 << 1,
-};
struct nvmet_fc_traddr {
u64 nn;
u64 pn;
};
-static const match_table_t traddr_opt_tokens = {
- { FCT_TRADDR_WWNN, "nn-%s" },
- { FCT_TRADDR_WWPN, "pn-%s" },
- { FCT_TRADDR_ERR, NULL }
-};
-
static int
-nvmet_fc_parse_traddr(struct nvmet_fc_traddr *traddr, char *buf)
+__nvme_fc_parse_u64(substring_t *sstr, u64 *val)
{
- substring_t args[MAX_OPT_ARGS];
- char *options, *o, *p;
- int token, ret = 0;
u64 token64;
- options = o = kstrdup(buf, GFP_KERNEL);
- if (!options)
- return -ENOMEM;
+ if (match_u64(sstr, &token64))
+ return -EINVAL;
+ *val = token64;
- while ((p = strsep(&o, ":\n")) != NULL) {
- if (!*p)
- continue;
+ return 0;
+}
- token = match_token(p, traddr_opt_tokens, args);
- switch (token) {
- case FCT_TRADDR_WWNN:
- if (match_u64(args, &token64)) {
- ret = -EINVAL;
- goto out;
- }
- traddr->nn = token64;
- break;
- case FCT_TRADDR_WWPN:
- if (match_u64(args, &token64)) {
- ret = -EINVAL;
- goto out;
- }
- traddr->pn = token64;
- break;
- default:
- pr_warn("unknown traddr token or missing value '%s'\n",
- p);
- ret = -EINVAL;
- goto out;
- }
- }
+/*
+ * This routine validates and extracts the WWN's from the TRADDR string.
+ * As kernel parsers need the 0x to determine number base, universally
+ * build string to parse with 0x prefix before parsing name strings.
+ */
+static int
+nvme_fc_parse_traddr(struct nvmet_fc_traddr *traddr, char *buf, size_t blen)
+{
+ char name[2 + NVME_FC_TRADDR_HEXNAMELEN + 1];
+ substring_t wwn = { name, &name[sizeof(name)-1] };
+ int nnoffset, pnoffset;
+
+ /* validate it string one of the 2 allowed formats */
+ if (strnlen(buf, blen) == NVME_FC_TRADDR_MAXLENGTH &&
+ !strncmp(buf, "nn-0x", NVME_FC_TRADDR_OXNNLEN) &&
+ !strncmp(&buf[NVME_FC_TRADDR_MAX_PN_OFFSET],
+ "pn-0x", NVME_FC_TRADDR_OXNNLEN)) {
+ nnoffset = NVME_FC_TRADDR_OXNNLEN;
+ pnoffset = NVME_FC_TRADDR_MAX_PN_OFFSET +
+ NVME_FC_TRADDR_OXNNLEN;
+ } else if ((strnlen(buf, blen) == NVME_FC_TRADDR_MINLENGTH &&
+ !strncmp(buf, "nn-", NVME_FC_TRADDR_NNLEN) &&
+ !strncmp(&buf[NVME_FC_TRADDR_MIN_PN_OFFSET],
+ "pn-", NVME_FC_TRADDR_NNLEN))) {
+ nnoffset = NVME_FC_TRADDR_NNLEN;
+ pnoffset = NVME_FC_TRADDR_MIN_PN_OFFSET + NVME_FC_TRADDR_NNLEN;
+ } else
+ goto out_einval;
+
+ name[0] = '0';
+ name[1] = 'x';
+ name[2 + NVME_FC_TRADDR_HEXNAMELEN] = 0;
+
+ memcpy(&name[2], &buf[nnoffset], NVME_FC_TRADDR_HEXNAMELEN);
+ if (__nvme_fc_parse_u64(&wwn, &traddr->nn))
+ goto out_einval;
+
+ memcpy(&name[2], &buf[pnoffset], NVME_FC_TRADDR_HEXNAMELEN);
+ if (__nvme_fc_parse_u64(&wwn, &traddr->pn))
+ goto out_einval;
-out:
- kfree(options);
- return ret;
+ return 0;
+
+out_einval:
+ pr_warn("%s: bad traddr string\n", __func__);
+ return -EINVAL;
}
static int
@@ -2370,7 +2530,8 @@ nvmet_fc_add_port(struct nvmet_port *port)
/* map the traddr address info to a target port */
- ret = nvmet_fc_parse_traddr(&traddr, port->disc_addr.traddr);
+ ret = nvme_fc_parse_traddr(&traddr, port->disc_addr.traddr,
+ sizeof(port->disc_addr.traddr));
if (ret)
return ret;
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 747bbdb4f9c6..e3b244c7e443 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -112,7 +112,6 @@ struct nvmet_ctrl {
struct mutex lock;
u64 cap;
- u64 serial;
u32 cc;
u32 csts;
@@ -152,6 +151,7 @@ struct nvmet_subsys {
u16 max_qid;
u64 ver;
+ u64 serial;
char *subsysnqn;
struct config_group group;
diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c
index a0d4ede9b8fc..63e3eb55f3ac 100644
--- a/drivers/nvmem/rockchip-efuse.c
+++ b/drivers/nvmem/rockchip-efuse.c
@@ -170,7 +170,7 @@ static const struct of_device_id rockchip_efuse_match[] = {
.data = (void *)&rockchip_rk3288_efuse_read,
},
{
- .compatible = "rockchip,rk322x-efuse",
+ .compatible = "rockchip,rk3228-efuse",
.data = (void *)&rockchip_rk3288_efuse_read,
},
{
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 6ce72aa65425..ab21c846eb27 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -476,7 +476,7 @@ int of_irq_to_resource_table(struct device_node *dev, struct resource *res,
int i;
for (i = 0; i < nr_irqs; i++, res++)
- if (!of_irq_to_resource(dev, i, res))
+ if (of_irq_to_resource(dev, i, res) <= 0)
break;
return i;
diff --git a/drivers/of/property.c b/drivers/of/property.c
index eda50b4be934..067f9fab7b77 100644
--- a/drivers/of/property.c
+++ b/drivers/of/property.c
@@ -708,6 +708,15 @@ struct device_node *of_graph_get_port_parent(struct device_node *node)
{
unsigned int depth;
+ if (!node)
+ return NULL;
+
+ /*
+ * Preserve usecount for passed in node as of_get_next_parent()
+ * will do of_node_put() on it.
+ */
+ of_node_get(node);
+
/* Walk 3 levels up only if there is 'ports' node. */
for (depth = 3; depth && node; depth--) {
node = of_get_next_parent(node);
@@ -728,12 +737,16 @@ EXPORT_SYMBOL(of_graph_get_port_parent);
struct device_node *of_graph_get_remote_port_parent(
const struct device_node *node)
{
- struct device_node *np;
+ struct device_node *np, *pp;
/* Get remote endpoint node. */
np = of_graph_get_remote_endpoint(node);
- return of_graph_get_port_parent(np);
+ pp = of_graph_get_port_parent(np);
+
+ of_node_put(np);
+
+ return pp;
}
EXPORT_SYMBOL(of_graph_get_remote_port_parent);
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c
index 055f83fddc18..b1ff46fe4547 100644
--- a/drivers/parisc/pdc_stable.c
+++ b/drivers/parisc/pdc_stable.c
@@ -333,11 +333,11 @@ pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t coun
/* Update the symlink to the real device */
sysfs_remove_link(&entry->kobj, "device");
+ write_unlock(&entry->rw_lock);
+
ret = sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
WARN_ON(ret);
- write_unlock(&entry->rw_lock);
-
printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" path to \"%s\"\n",
entry->name, buf);
@@ -954,7 +954,7 @@ static struct attribute *pdcs_subsys_attrs[] = {
NULL,
};
-static struct attribute_group pdcs_attr_group = {
+static const struct attribute_group pdcs_attr_group = {
.attrs = pdcs_subsys_attrs,
};
@@ -998,6 +998,7 @@ pdcs_register_pathentries(void)
/* kobject is now registered */
write_lock(&entry->rw_lock);
entry->ready = 2;
+ write_unlock(&entry->rw_lock);
/* Add a nice symlink to the real device */
if (entry->dev) {
@@ -1005,7 +1006,6 @@ pdcs_register_pathentries(void)
WARN_ON(err);
}
- write_unlock(&entry->rw_lock);
kobject_uevent(&entry->kobj, KOBJ_ADD);
}
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index af0cc3456dc1..b4b7eab29400 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4260,6 +4260,41 @@ int pci_reset_function(struct pci_dev *dev)
EXPORT_SYMBOL_GPL(pci_reset_function);
/**
+ * pci_reset_function_locked - quiesce and reset a PCI device function
+ * @dev: PCI device to reset
+ *
+ * Some devices allow an individual function to be reset without affecting
+ * other functions in the same device. The PCI device must be responsive
+ * to PCI config space in order to use this function.
+ *
+ * This function does not just reset the PCI portion of a device, but
+ * clears all the state associated with the device. This function differs
+ * from __pci_reset_function() in that it saves and restores device state
+ * over the reset. It also differs from pci_reset_function() in that it
+ * requires the PCI device lock to be held.
+ *
+ * Returns 0 if the device function was successfully reset or negative if the
+ * device doesn't support resetting a single function.
+ */
+int pci_reset_function_locked(struct pci_dev *dev)
+{
+ int rc;
+
+ rc = pci_probe_reset_function(dev);
+ if (rc)
+ return rc;
+
+ pci_dev_save_and_disable(dev);
+
+ rc = __pci_reset_function_locked(dev);
+
+ pci_dev_restore(dev);
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(pci_reset_function_locked);
+
+/**
* pci_try_reset_function - quiesce and reset a PCI device function
* @dev: PCI device to reset
*
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
index dc459eb1246b..1c5e0f333779 100644
--- a/drivers/perf/arm_pmu.c
+++ b/drivers/perf/arm_pmu.c
@@ -569,22 +569,41 @@ int armpmu_request_irq(struct arm_pmu *armpmu, int cpu)
if (irq != other_irq) {
pr_warn("mismatched PPIs detected.\n");
err = -EINVAL;
+ goto err_out;
}
} else {
- err = request_irq(irq, handler,
- IRQF_NOBALANCING | IRQF_NO_THREAD, "arm-pmu",
+ struct arm_pmu_platdata *platdata = armpmu_get_platdata(armpmu);
+ unsigned long irq_flags;
+
+ err = irq_force_affinity(irq, cpumask_of(cpu));
+
+ if (err && num_possible_cpus() > 1) {
+ pr_warn("unable to set irq affinity (irq=%d, cpu=%u)\n",
+ irq, cpu);
+ goto err_out;
+ }
+
+ if (platdata && platdata->irq_flags) {
+ irq_flags = platdata->irq_flags;
+ } else {
+ irq_flags = IRQF_PERCPU |
+ IRQF_NOBALANCING |
+ IRQF_NO_THREAD;
+ }
+
+ err = request_irq(irq, handler, irq_flags, "arm-pmu",
per_cpu_ptr(&hw_events->percpu_pmu, cpu));
}
- if (err) {
- pr_err("unable to request IRQ%d for ARM PMU counters\n",
- irq);
- return err;
- }
+ if (err)
+ goto err_out;
cpumask_set_cpu(cpu, &armpmu->active_irqs);
-
return 0;
+
+err_out:
+ pr_err("unable to request IRQ%d for ARM PMU counters\n", irq);
+ return err;
}
int armpmu_request_irqs(struct arm_pmu *armpmu)
@@ -628,12 +647,6 @@ static int arm_perf_starting_cpu(unsigned int cpu, struct hlist_node *node)
enable_percpu_irq(irq, IRQ_TYPE_NONE);
return 0;
}
-
- if (irq_force_affinity(irq, cpumask_of(cpu)) &&
- num_possible_cpus() > 1) {
- pr_warn("unable to set irq affinity (irq=%d, cpu=%u)\n",
- irq, cpu);
- }
}
return 0;
diff --git a/drivers/perf/arm_pmu_platform.c b/drivers/perf/arm_pmu_platform.c
index 69255f53057a..4eafa7a42e52 100644
--- a/drivers/perf/arm_pmu_platform.c
+++ b/drivers/perf/arm_pmu_platform.c
@@ -131,8 +131,8 @@ static int pmu_parse_irqs(struct arm_pmu *pmu)
}
if (!pmu_has_irq_affinity(pdev->dev.of_node)) {
- pr_warn("no interrupt-affinity property for %s, guessing.\n",
- of_node_full_name(pdev->dev.of_node));
+ pr_warn("no interrupt-affinity property for %pOF, guessing.\n",
+ pdev->dev.of_node);
}
/*
@@ -211,7 +211,7 @@ int arm_pmu_device_probe(struct platform_device *pdev,
}
if (ret) {
- pr_info("%s: failed to probe PMU!\n", of_node_full_name(node));
+ pr_info("%pOF: failed to probe PMU!\n", node);
goto out_free;
}
@@ -228,8 +228,7 @@ int arm_pmu_device_probe(struct platform_device *pdev,
out_free_irqs:
armpmu_free_irqs(pmu);
out_free:
- pr_info("%s: failed to register PMU devices!\n",
- of_node_full_name(node));
+ pr_info("%pOF: failed to register PMU devices!\n", node);
armpmu_free(pmu);
return ret;
}
diff --git a/drivers/perf/qcom_l2_pmu.c b/drivers/perf/qcom_l2_pmu.c
index c259848228b4..b242cce10468 100644
--- a/drivers/perf/qcom_l2_pmu.c
+++ b/drivers/perf/qcom_l2_pmu.c
@@ -546,6 +546,7 @@ static int l2_cache_event_init(struct perf_event *event)
}
if ((event != event->group_leader) &&
+ !is_software_event(event->group_leader) &&
(L2_EVT_GROUP(event->group_leader->attr.config) ==
L2_EVT_GROUP(event->attr.config))) {
dev_dbg_ratelimited(&l2cache_pmu->pdev->dev,
@@ -558,6 +559,7 @@ static int l2_cache_event_init(struct perf_event *event)
list_for_each_entry(sibling, &event->group_leader->sibling_list,
group_entry) {
if ((sibling != event) &&
+ !is_software_event(sibling) &&
(L2_EVT_GROUP(sibling->attr.config) ==
L2_EVT_GROUP(event->attr.config))) {
dev_dbg_ratelimited(&l2cache_pmu->pdev->dev,
diff --git a/drivers/phy/broadcom/Kconfig b/drivers/phy/broadcom/Kconfig
index 37371b89b14f..64fc59c3ae6d 100644
--- a/drivers/phy/broadcom/Kconfig
+++ b/drivers/phy/broadcom/Kconfig
@@ -30,8 +30,8 @@ config PHY_BCM_NS_USB3
tristate "Broadcom Northstar USB 3.0 PHY Driver"
depends on ARCH_BCM_IPROC || COMPILE_TEST
depends on HAS_IOMEM && OF
+ depends on MDIO_BUS
select GENERIC_PHY
- select MDIO_DEVICE
help
Enable this to support Broadcom USB 3.0 PHY connected to the USB
controller on Northstar family.
diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c
index 20f1b4493994..04e929fd0ffe 100644
--- a/drivers/pinctrl/intel/pinctrl-cherryview.c
+++ b/drivers/pinctrl/intel/pinctrl-cherryview.c
@@ -1548,6 +1548,13 @@ static const struct dmi_system_id chv_no_valid_mask[] = {
},
},
{
+ .ident = "HP Chromebook 11 G5 (Setzer)",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Setzer"),
+ },
+ },
+ {
.ident = "Acer Chromebook R11 (Cyan)",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
diff --git a/drivers/pinctrl/intel/pinctrl-merrifield.c b/drivers/pinctrl/intel/pinctrl-merrifield.c
index 4d4ef42a39b5..86c4b3fab7b0 100644
--- a/drivers/pinctrl/intel/pinctrl-merrifield.c
+++ b/drivers/pinctrl/intel/pinctrl-merrifield.c
@@ -343,9 +343,9 @@ static const struct pinctrl_pin_desc mrfld_pins[] = {
static const unsigned int mrfld_sdio_pins[] = { 50, 51, 52, 53, 54, 55, 56 };
static const unsigned int mrfld_spi5_pins[] = { 90, 91, 92, 93, 94, 95, 96 };
-static const unsigned int mrfld_uart0_pins[] = { 124, 125, 126, 127 };
-static const unsigned int mrfld_uart1_pins[] = { 128, 129, 130, 131 };
-static const unsigned int mrfld_uart2_pins[] = { 132, 133, 134, 135 };
+static const unsigned int mrfld_uart0_pins[] = { 115, 116, 117, 118 };
+static const unsigned int mrfld_uart1_pins[] = { 119, 120, 121, 122 };
+static const unsigned int mrfld_uart2_pins[] = { 123, 124, 125, 126 };
static const unsigned int mrfld_pwm0_pins[] = { 144 };
static const unsigned int mrfld_pwm1_pins[] = { 145 };
static const unsigned int mrfld_pwm2_pins[] = { 132 };
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
index f024e25787fc..0c6d7812d6fd 100644
--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
@@ -37,7 +37,7 @@
#define IRQ_STATUS 0x10
#define IRQ_WKUP 0x18
-#define NB_FUNCS 2
+#define NB_FUNCS 3
#define GPIO_PER_REG 32
/**
@@ -126,6 +126,16 @@ struct armada_37xx_pinctrl {
.funcs = {_func1, "gpio"} \
}
+#define PIN_GRP_GPIO_3(_name, _start, _nr, _mask, _v1, _v2, _v3, _f1, _f2) \
+ { \
+ .name = _name, \
+ .start_pin = _start, \
+ .npins = _nr, \
+ .reg_mask = _mask, \
+ .val = {_v1, _v2, _v3}, \
+ .funcs = {_f1, _f2, "gpio"} \
+ }
+
#define PIN_GRP_EXTRA(_name, _start, _nr, _mask, _v1, _v2, _start2, _nr2, \
_f1, _f2) \
{ \
@@ -171,12 +181,13 @@ static struct armada_37xx_pin_group armada_37xx_sb_groups[] = {
PIN_GRP_GPIO("usb32_drvvbus0", 0, 1, BIT(0), "drvbus"),
PIN_GRP_GPIO("usb2_drvvbus1", 1, 1, BIT(1), "drvbus"),
PIN_GRP_GPIO("sdio_sb", 24, 6, BIT(2), "sdio"),
- PIN_GRP_EXTRA("rgmii", 6, 12, BIT(3), 0, BIT(3), 23, 1, "mii", "gpio"),
+ PIN_GRP_GPIO("rgmii", 6, 12, BIT(3), "mii"),
PIN_GRP_GPIO("pcie1", 3, 2, BIT(4), "pcie"),
PIN_GRP_GPIO("ptp", 20, 3, BIT(5), "ptp"),
PIN_GRP("ptp_clk", 21, 1, BIT(6), "ptp", "mii"),
PIN_GRP("ptp_trig", 22, 1, BIT(7), "ptp", "mii"),
- PIN_GRP("mii_col", 23, 1, BIT(8), "mii", "mii_err"),
+ PIN_GRP_GPIO_3("mii_col", 23, 1, BIT(8) | BIT(14), 0, BIT(8), BIT(14),
+ "mii", "mii_err"),
};
const struct armada_37xx_pin_data armada_37xx_pin_nb = {
@@ -187,7 +198,7 @@ const struct armada_37xx_pin_data armada_37xx_pin_nb = {
};
const struct armada_37xx_pin_data armada_37xx_pin_sb = {
- .nr_pins = 29,
+ .nr_pins = 30,
.name = "GPIO2",
.groups = armada_37xx_sb_groups,
.ngroups = ARRAY_SIZE(armada_37xx_sb_groups),
@@ -208,7 +219,7 @@ static int armada_37xx_get_func_reg(struct armada_37xx_pin_group *grp,
{
int f;
- for (f = 0; f < NB_FUNCS; f++)
+ for (f = 0; (f < NB_FUNCS) && grp->funcs[f]; f++)
if (!strcmp(grp->funcs[f], func))
return f;
@@ -795,7 +806,7 @@ static int armada_37xx_fill_group(struct armada_37xx_pinctrl *info)
for (j = 0; j < grp->extra_npins; j++)
grp->pins[i+j] = grp->extra_pin + j;
- for (f = 0; f < NB_FUNCS; f++) {
+ for (f = 0; (f < NB_FUNCS) && grp->funcs[f]; f++) {
int ret;
/* check for unique functions and count groups */
ret = armada_37xx_add_function(info->funcs, &funcsize,
@@ -847,7 +858,7 @@ static int armada_37xx_fill_func(struct armada_37xx_pinctrl *info)
struct armada_37xx_pin_group *gp = &info->groups[g];
int f;
- for (f = 0; f < NB_FUNCS; f++) {
+ for (f = 0; (f < NB_FUNCS) && gp->funcs[f]; f++) {
if (strcmp(gp->funcs[f], name) == 0) {
*groups = gp->name;
groups++;
diff --git a/drivers/pinctrl/stm32/Kconfig b/drivers/pinctrl/stm32/Kconfig
index 3b8026fca057..7e1fe39a56a5 100644
--- a/drivers/pinctrl/stm32/Kconfig
+++ b/drivers/pinctrl/stm32/Kconfig
@@ -6,29 +6,30 @@ config PINCTRL_STM32
select PINMUX
select GENERIC_PINCONF
select GPIOLIB
+ select IRQ_DOMAIN_HIERARCHY
select MFD_SYSCON
config PINCTRL_STM32F429
bool "STMicroelectronics STM32F429 pin control" if COMPILE_TEST && !MACH_STM32F429
- depends on OF && IRQ_DOMAIN_HIERARCHY
+ depends on OF
default MACH_STM32F429
select PINCTRL_STM32
config PINCTRL_STM32F469
bool "STMicroelectronics STM32F469 pin control" if COMPILE_TEST && !MACH_STM32F469
- depends on OF && IRQ_DOMAIN_HIERARCHY
+ depends on OF
default MACH_STM32F469
select PINCTRL_STM32
config PINCTRL_STM32F746
bool "STMicroelectronics STM32F746 pin control" if COMPILE_TEST && !MACH_STM32F746
- depends on OF && IRQ_DOMAIN_HIERARCHY
+ depends on OF
default MACH_STM32F746
select PINCTRL_STM32
config PINCTRL_STM32H743
bool "STMicroelectronics STM32H743 pin control" if COMPILE_TEST && !MACH_STM32H743
- depends on OF && IRQ_DOMAIN_HIERARCHY
+ depends on OF
default MACH_STM32H743
select PINCTRL_STM32
endif
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
index 159580c04b14..47a392bc73c8 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
@@ -918,6 +918,7 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
SUNXI_FUNCTION_VARIANT(0x3, "emac", /* ETXD1 */
PINCTRL_SUN7I_A20),
SUNXI_FUNCTION(0x4, "keypad"), /* IN6 */
+ SUNXI_FUNCTION(0x5, "sim"), /* DET */
SUNXI_FUNCTION_IRQ(0x6, 16), /* EINT16 */
SUNXI_FUNCTION(0x7, "csi1")), /* D16 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 17),
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c
index a433a306a2d0..c75e094b2d90 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c
@@ -1084,7 +1084,7 @@ static const unsigned usb1_pins[] = {182, 183};
static const int usb1_muxvals[] = {0, 0};
static const unsigned usb2_pins[] = {184, 185};
static const int usb2_muxvals[] = {0, 0};
-static const unsigned usb3_pins[] = {186, 187};
+static const unsigned usb3_pins[] = {187, 188};
static const int usb3_muxvals[] = {0, 0};
static const unsigned port_range0_pins[] = {
300, 301, 302, 303, 304, 305, 306, 307, /* PORT0x */
diff --git a/drivers/pinctrl/zte/pinctrl-zx.c b/drivers/pinctrl/zte/pinctrl-zx.c
index 787e3967bd5c..f828ee340a98 100644
--- a/drivers/pinctrl/zte/pinctrl-zx.c
+++ b/drivers/pinctrl/zte/pinctrl-zx.c
@@ -64,10 +64,8 @@ static int zx_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
struct zx_pinctrl_soc_info *info = zpctl->info;
const struct pinctrl_pin_desc *pindesc = info->pins + group_selector;
struct zx_pin_data *data = pindesc->drv_data;
- struct zx_mux_desc *mux = data->muxes;
- u32 mask = (1 << data->width) - 1;
- u32 offset = data->offset;
- u32 bitpos = data->bitpos;
+ struct zx_mux_desc *mux;
+ u32 mask, offset, bitpos;
struct function_desc *func;
unsigned long flags;
u32 val, mval;
@@ -76,6 +74,11 @@ static int zx_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
if (!data)
return -EINVAL;
+ mux = data->muxes;
+ mask = (1 << data->width) - 1;
+ offset = data->offset;
+ bitpos = data->bitpos;
+
func = pinmux_generic_get_function(pctldev, func_selector);
if (!func)
return -EINVAL;
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index b04860703740..80b87954f6dd 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -675,6 +675,7 @@ config PEAQ_WMI
tristate "PEAQ 2-in-1 WMI hotkey driver"
depends on ACPI_WMI
depends on INPUT
+ select INPUT_POLLDEV
help
Say Y here if you want to support WMI-based hotkeys on PEAQ 2-in-1s.
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c
index f8978464df31..dad8f4afa17c 100644
--- a/drivers/platform/x86/dell-wmi.c
+++ b/drivers/platform/x86/dell-wmi.c
@@ -626,7 +626,7 @@ static void dell_wmi_input_destroy(struct wmi_device *wdev)
* WMI Interface Version 8 4 <version>
* WMI buffer length 12 4 4096
*/
-static int __init dell_wmi_check_descriptor_buffer(void)
+static int dell_wmi_check_descriptor_buffer(void)
{
struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj;
@@ -717,9 +717,15 @@ static int dell_wmi_events_set_enabled(bool enable)
static int dell_wmi_probe(struct wmi_device *wdev)
{
+ int err;
+
struct dell_wmi_priv *priv = devm_kzalloc(
&wdev->dev, sizeof(struct dell_wmi_priv), GFP_KERNEL);
+ err = dell_wmi_check_descriptor_buffer();
+ if (err)
+ return err;
+
dev_set_drvdata(&wdev->dev, priv);
return dell_wmi_input_setup(wdev);
@@ -749,10 +755,6 @@ static int __init dell_wmi_init(void)
{
int err;
- err = dell_wmi_check_descriptor_buffer();
- if (err)
- return err;
-
dmi_check_system(dell_wmi_smbios_list);
if (wmi_requires_smbios_request) {
diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c
index 61f106377661..480926786cb8 100644
--- a/drivers/platform/x86/intel-vbtn.c
+++ b/drivers/platform/x86/intel-vbtn.c
@@ -36,8 +36,8 @@ static const struct acpi_device_id intel_vbtn_ids[] = {
/* In theory, these are HID usages. */
static const struct key_entry intel_vbtn_keymap[] = {
- { KE_IGNORE, 0xC0, { KEY_POWER } }, /* power key press */
- { KE_KEY, 0xC1, { KEY_POWER } }, /* power key release */
+ { KE_KEY, 0xC0, { KEY_POWER } }, /* power key press */
+ { KE_IGNORE, 0xC1, { KEY_POWER } }, /* power key release */
{ KE_KEY, 0xC4, { KEY_VOLUMEUP } }, /* volume-up key press */
{ KE_IGNORE, 0xC5, { KEY_VOLUMEUP } }, /* volume-up key release */
{ KE_KEY, 0xC6, { KEY_VOLUMEDOWN } }, /* volume-down key press */
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index 1a764e311e11..e32ba575e8d9 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -1252,12 +1252,12 @@ static int __init acpi_wmi_init(void)
return 0;
-err_unreg_class:
- class_unregister(&wmi_bus_class);
-
err_unreg_bus:
bus_unregister(&wmi_bus_type);
+err_unreg_class:
+ class_unregister(&wmi_bus_class);
+
return error;
}
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
index b77435783ef3..7eacc1c4b3b1 100644
--- a/drivers/ptp/ptp_clock.c
+++ b/drivers/ptp/ptp_clock.c
@@ -28,6 +28,7 @@
#include <linux/slab.h>
#include <linux/syscalls.h>
#include <linux/uaccess.h>
+#include <uapi/linux/sched/types.h>
#include "ptp_private.h"
@@ -184,6 +185,19 @@ static void delete_ptp_clock(struct posix_clock *pc)
kfree(ptp);
}
+static void ptp_aux_kworker(struct kthread_work *work)
+{
+ struct ptp_clock *ptp = container_of(work, struct ptp_clock,
+ aux_work.work);
+ struct ptp_clock_info *info = ptp->info;
+ long delay;
+
+ delay = info->do_aux_work(info);
+
+ if (delay >= 0)
+ kthread_queue_delayed_work(ptp->kworker, &ptp->aux_work, delay);
+}
+
/* public interface */
struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
@@ -217,6 +231,20 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
mutex_init(&ptp->pincfg_mux);
init_waitqueue_head(&ptp->tsev_wq);
+ if (ptp->info->do_aux_work) {
+ char *worker_name = kasprintf(GFP_KERNEL, "ptp%d", ptp->index);
+
+ kthread_init_delayed_work(&ptp->aux_work, ptp_aux_kworker);
+ ptp->kworker = kthread_create_worker(0, worker_name ?
+ worker_name : info->name);
+ kfree(worker_name);
+ if (IS_ERR(ptp->kworker)) {
+ err = PTR_ERR(ptp->kworker);
+ pr_err("failed to create ptp aux_worker %d\n", err);
+ goto kworker_err;
+ }
+ }
+
err = ptp_populate_pin_groups(ptp);
if (err)
goto no_pin_groups;
@@ -259,6 +287,9 @@ no_pps:
no_device:
ptp_cleanup_pin_groups(ptp);
no_pin_groups:
+ if (ptp->kworker)
+ kthread_destroy_worker(ptp->kworker);
+kworker_err:
mutex_destroy(&ptp->tsevq_mux);
mutex_destroy(&ptp->pincfg_mux);
ida_simple_remove(&ptp_clocks_map, index);
@@ -274,6 +305,11 @@ int ptp_clock_unregister(struct ptp_clock *ptp)
ptp->defunct = 1;
wake_up_interruptible(&ptp->tsev_wq);
+ if (ptp->kworker) {
+ kthread_cancel_delayed_work_sync(&ptp->aux_work);
+ kthread_destroy_worker(ptp->kworker);
+ }
+
/* Release the clock's resources. */
if (ptp->pps_source)
pps_unregister_source(ptp->pps_source);
@@ -339,6 +375,12 @@ int ptp_find_pin(struct ptp_clock *ptp,
}
EXPORT_SYMBOL(ptp_find_pin);
+int ptp_schedule_worker(struct ptp_clock *ptp, unsigned long delay)
+{
+ return kthread_mod_delayed_work(ptp->kworker, &ptp->aux_work, delay);
+}
+EXPORT_SYMBOL(ptp_schedule_worker);
+
/* module operations */
static void __exit ptp_exit(void)
diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h
index d95888974d0c..b86f1bfecd6f 100644
--- a/drivers/ptp/ptp_private.h
+++ b/drivers/ptp/ptp_private.h
@@ -22,6 +22,7 @@
#include <linux/cdev.h>
#include <linux/device.h>
+#include <linux/kthread.h>
#include <linux/mutex.h>
#include <linux/posix-clock.h>
#include <linux/ptp_clock.h>
@@ -56,6 +57,8 @@ struct ptp_clock {
struct attribute_group pin_attr_group;
/* 1st entry is a pointer to the real group, 2nd is NULL terminator */
const struct attribute_group *pin_attr_groups[2];
+ struct kthread_worker *kworker;
+ struct kthread_delayed_work aux_work;
};
/*
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index 7e0d4f724dda..432fc40990bd 100644
--- a/drivers/s390/cio/chp.c
+++ b/drivers/s390/cio/chp.c
@@ -559,6 +559,7 @@ static void chp_process_crw(struct crw *crw0, struct crw *crw1,
chpid.id = crw0->rsid;
switch (crw0->erc) {
case CRW_ERC_IPARM: /* Path has come. */
+ case CRW_ERC_INIT:
if (!chp_is_registered(chpid))
chp_new(chpid);
chsc_chp_online(chpid);
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 8975cd321390..d42e758518ed 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -2512,7 +2512,7 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
struct rtable *rt = (struct rtable *) dst;
__be32 *pkey = &ip_hdr(skb)->daddr;
- if (rt->rt_gateway)
+ if (rt && rt->rt_gateway)
pkey = &rt->rt_gateway;
/* IPv4 */
@@ -2523,7 +2523,7 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
struct rt6_info *rt = (struct rt6_info *) dst;
struct in6_addr *pkey = &ipv6_hdr(skb)->daddr;
- if (!ipv6_addr_any(&rt->rt6i_gateway))
+ if (rt && !ipv6_addr_any(&rt->rt6i_gateway))
pkey = &rt->rt6i_gateway;
/* IPv6 */
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index 04efed171c88..f32765d3cbd8 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -212,8 +212,8 @@ static int d7s_probe(struct platform_device *op)
writeb(regs, p->regs);
- printk(KERN_INFO PFX "7-Segment Display%s at [%s:0x%llx] %s\n",
- op->dev.of_node->full_name,
+ printk(KERN_INFO PFX "7-Segment Display%pOF at [%s:0x%llx] %s\n",
+ op->dev.of_node,
(regs & D7S_FLIP) ? " (FLIPPED)" : "",
op->resource[0].start,
sol_compat ? "in sol_compat mode" : "");
diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c
index 216f923161d1..a610b8d3d11f 100644
--- a/drivers/sbus/char/flash.c
+++ b/drivers/sbus/char/flash.c
@@ -181,8 +181,8 @@ static int flash_probe(struct platform_device *op)
}
flash.busy = 0;
- printk(KERN_INFO "%s: OBP Flash, RD %lx[%lx] WR %lx[%lx]\n",
- op->dev.of_node->full_name,
+ printk(KERN_INFO "%pOF: OBP Flash, RD %lx[%lx] WR %lx[%lx]\n",
+ op->dev.of_node,
flash.read_base, flash.read_size,
flash.write_base, flash.write_size);
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c
index 57696fc0b482..0a5013350acd 100644
--- a/drivers/sbus/char/uctrl.c
+++ b/drivers/sbus/char/uctrl.c
@@ -379,8 +379,8 @@ static int uctrl_probe(struct platform_device *op)
}
sbus_writel(UCTRL_INTR_RXNE_REQ|UCTRL_INTR_RXNE_MSK, &p->regs->uctrl_intr);
- printk(KERN_INFO "%s: uctrl regs[0x%p] (irq %d)\n",
- op->dev.of_node->full_name, p->regs, p->irq);
+ printk(KERN_INFO "%pOF: uctrl regs[0x%p] (irq %d)\n",
+ op->dev.of_node, p->regs, p->irq);
uctrl_get_event_status(p);
uctrl_get_external_status(p);
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index d384f4f86c26..f4538d7a3016 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1230,6 +1230,8 @@ config SCSI_LPFC
tristate "Emulex LightPulse Fibre Channel Support"
depends on PCI && SCSI
depends on SCSI_FC_ATTRS
+ depends on NVME_TARGET_FC || NVME_TARGET_FC=n
+ depends on NVME_FC || NVME_FC=n
select CRC_T10DIF
---help---
This lpfc driver supports the Emulex LightPulse
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 707ee2f5954d..4591113c49de 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -3198,10 +3198,11 @@ static int query_disk(struct aac_dev *dev, void __user *arg)
return -EBUSY;
if (copy_from_user(&qd, arg, sizeof (struct aac_query_disk)))
return -EFAULT;
- if (qd.cnum == -1)
+ if (qd.cnum == -1) {
+ if (qd.id < 0 || qd.id >= dev->maximum_num_containers)
+ return -EINVAL;
qd.cnum = qd.id;
- else if ((qd.bus == -1) && (qd.id == -1) && (qd.lun == -1))
- {
+ } else if ((qd.bus == -1) && (qd.id == -1) && (qd.lun == -1)) {
if (qd.cnum < 0 || qd.cnum >= dev->maximum_num_containers)
return -EINVAL;
qd.instance = dev->scsi_host_ptr->host_no;
diff --git a/drivers/scsi/aic7xxx/Makefile b/drivers/scsi/aic7xxx/Makefile
index 741d81861d17..07b60a780c06 100644
--- a/drivers/scsi/aic7xxx/Makefile
+++ b/drivers/scsi/aic7xxx/Makefile
@@ -55,9 +55,9 @@ aicasm-7xxx-opts-$(CONFIG_AIC7XXX_REG_PRETTY_PRINT) := \
ifeq ($(CONFIG_AIC7XXX_BUILD_FIRMWARE),y)
$(obj)/aic7xxx_seq.h: $(src)/aic7xxx.seq $(src)/aic7xxx.reg $(obj)/aicasm/aicasm
- $(obj)/aicasm/aicasm -I$(src) -r $(obj)/aic7xxx_reg.h \
+ $(obj)/aicasm/aicasm -I$(srctree)/$(src) -r $(obj)/aic7xxx_reg.h \
$(aicasm-7xxx-opts-y) -o $(obj)/aic7xxx_seq.h \
- $(src)/aic7xxx.seq
+ $(srctree)/$(src)/aic7xxx.seq
$(aic7xxx-gen-y): $(obj)/aic7xxx_seq.h
else
@@ -72,14 +72,14 @@ aicasm-79xx-opts-$(CONFIG_AIC79XX_REG_PRETTY_PRINT) := \
ifeq ($(CONFIG_AIC79XX_BUILD_FIRMWARE),y)
$(obj)/aic79xx_seq.h: $(src)/aic79xx.seq $(src)/aic79xx.reg $(obj)/aicasm/aicasm
- $(obj)/aicasm/aicasm -I$(src) -r $(obj)/aic79xx_reg.h \
+ $(obj)/aicasm/aicasm -I$(srctree)/$(src) -r $(obj)/aic79xx_reg.h \
$(aicasm-79xx-opts-y) -o $(obj)/aic79xx_seq.h \
- $(src)/aic79xx.seq
+ $(srctree)/$(src)/aic79xx.seq
$(aic79xx-gen-y): $(obj)/aic79xx_seq.h
else
$(obj)/aic79xx_reg_print.c: $(src)/aic79xx_reg_print.c_shipped
endif
-$(obj)/aicasm/aicasm: $(src)/aicasm/*.[chyl]
- $(MAKE) -C $(src)/aicasm
+$(obj)/aicasm/aicasm: $(srctree)/$(src)/aicasm/*.[chyl]
+ $(MAKE) -C $(srctree)/$(src)/aicasm OUTDIR=$(shell pwd)/$(obj)/aicasm/
diff --git a/drivers/scsi/aic7xxx/aicasm/Makefile b/drivers/scsi/aic7xxx/aicasm/Makefile
index b98c5c1056c3..45e2d49c1fff 100644
--- a/drivers/scsi/aic7xxx/aicasm/Makefile
+++ b/drivers/scsi/aic7xxx/aicasm/Makefile
@@ -1,19 +1,21 @@
PROG= aicasm
+OUTDIR ?= ./
+
.SUFFIXES= .l .y .c .h
CSRCS= aicasm.c aicasm_symbol.c
YSRCS= aicasm_gram.y aicasm_macro_gram.y
LSRCS= aicasm_scan.l aicasm_macro_scan.l
-GENHDRS= aicdb.h $(YSRCS:.y=.h)
-GENSRCS= $(YSRCS:.y=.c) $(LSRCS:.l=.c)
+GENHDRS= $(addprefix ${OUTDIR}/,aicdb.h $(YSRCS:.y=.h))
+GENSRCS= $(addprefix ${OUTDIR}/,$(YSRCS:.y=.c) $(LSRCS:.l=.c))
SRCS= ${CSRCS} ${GENSRCS}
LIBS= -ldb
clean-files:= ${GENSRCS} ${GENHDRS} $(YSRCS:.y=.output) $(PROG)
# Override default kernel CFLAGS. This is a userland app.
-AICASM_CFLAGS:= -I/usr/include -I.
+AICASM_CFLAGS:= -I/usr/include -I. -I$(OUTDIR)
LEX= flex
YACC= bison
YFLAGS= -d
@@ -32,22 +34,25 @@ YFLAGS+= -t -v
LFLAGS= -d
endif
-$(PROG): ${GENHDRS} $(SRCS)
- $(AICASM_CC) $(AICASM_CFLAGS) $(SRCS) -o $(PROG) $(LIBS)
+$(PROG): $(OUTDIR) ${GENHDRS} $(SRCS)
+ $(AICASM_CC) $(AICASM_CFLAGS) $(SRCS) -o $(OUTDIR)/$(PROG) $(LIBS)
+
+$(OUTDIR):
+ mkdir -p $(OUTDIR)
-aicdb.h:
+$(OUTDIR)/aicdb.h:
@if [ -e "/usr/include/db4/db_185.h" ]; then \
- echo "#include <db4/db_185.h>" > aicdb.h; \
+ echo "#include <db4/db_185.h>" > $@; \
elif [ -e "/usr/include/db3/db_185.h" ]; then \
- echo "#include <db3/db_185.h>" > aicdb.h; \
+ echo "#include <db3/db_185.h>" > $@; \
elif [ -e "/usr/include/db2/db_185.h" ]; then \
- echo "#include <db2/db_185.h>" > aicdb.h; \
+ echo "#include <db2/db_185.h>" > $@; \
elif [ -e "/usr/include/db1/db_185.h" ]; then \
- echo "#include <db1/db_185.h>" > aicdb.h; \
+ echo "#include <db1/db_185.h>" > $@; \
elif [ -e "/usr/include/db/db_185.h" ]; then \
- echo "#include <db/db_185.h>" > aicdb.h; \
+ echo "#include <db/db_185.h>" > $@; \
elif [ -e "/usr/include/db_185.h" ]; then \
- echo "#include <db_185.h>" > aicdb.h; \
+ echo "#include <db_185.h>" > $@; \
else \
echo "*** Install db development libraries"; \
fi
@@ -58,23 +63,23 @@ clean:
# Create a dependency chain in generated files
# to avoid concurrent invocations of the single
# rule that builds them all.
-aicasm_gram.c: aicasm_gram.h
-aicasm_gram.c aicasm_gram.h: aicasm_gram.y
+$(OUTDIR)/aicasm_gram.c: $(OUTDIR)/aicasm_gram.h
+$(OUTDIR)/aicasm_gram.c $(OUTDIR)/aicasm_gram.h: aicasm_gram.y
$(YACC) $(YFLAGS) -b $(<:.y=) $<
- mv $(<:.y=).tab.c $(<:.y=.c)
- mv $(<:.y=).tab.h $(<:.y=.h)
+ mv $(<:.y=).tab.c $(OUTDIR)/$(<:.y=.c)
+ mv $(<:.y=).tab.h $(OUTDIR)/$(<:.y=.h)
# Create a dependency chain in generated files
# to avoid concurrent invocations of the single
# rule that builds them all.
-aicasm_macro_gram.c: aicasm_macro_gram.h
-aicasm_macro_gram.c aicasm_macro_gram.h: aicasm_macro_gram.y
+$(OUTDIR)/aicasm_macro_gram.c: $(OUTDIR)/aicasm_macro_gram.h
+$(OUTDIR)/aicasm_macro_gram.c $(OUTDIR)/aicasm_macro_gram.h: aicasm_macro_gram.y
$(YACC) $(YFLAGS) -b $(<:.y=) -p mm $<
- mv $(<:.y=).tab.c $(<:.y=.c)
- mv $(<:.y=).tab.h $(<:.y=.h)
+ mv $(<:.y=).tab.c $(OUTDIR)/$(<:.y=.c)
+ mv $(<:.y=).tab.h $(OUTDIR)/$(<:.y=.h)
-aicasm_scan.c: aicasm_scan.l
- $(LEX) $(LFLAGS) -o$@ $<
+$(OUTDIR)/aicasm_scan.c: aicasm_scan.l
+ $(LEX) $(LFLAGS) -o $@ $<
-aicasm_macro_scan.c: aicasm_macro_scan.l
- $(LEX) $(LFLAGS) -Pmm -o$@ $<
+$(OUTDIR)/aicasm_macro_scan.c: aicasm_macro_scan.l
+ $(LEX) $(LFLAGS) -Pmm -o $@ $<
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
index 7dfe709a7138..6844ba361616 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
@@ -2624,12 +2624,11 @@ static struct fcoe_transport bnx2fc_transport = {
};
/**
- * bnx2fc_percpu_thread_create - Create a receive thread for an
- * online CPU
+ * bnx2fc_cpu_online - Create a receive thread for an online CPU
*
* @cpu: cpu index for the online cpu
*/
-static void bnx2fc_percpu_thread_create(unsigned int cpu)
+static int bnx2fc_cpu_online(unsigned int cpu)
{
struct bnx2fc_percpu_s *p;
struct task_struct *thread;
@@ -2639,15 +2638,17 @@ static void bnx2fc_percpu_thread_create(unsigned int cpu)
thread = kthread_create_on_node(bnx2fc_percpu_io_thread,
(void *)p, cpu_to_node(cpu),
"bnx2fc_thread/%d", cpu);
+ if (IS_ERR(thread))
+ return PTR_ERR(thread);
+
/* bind thread to the cpu */
- if (likely(!IS_ERR(thread))) {
- kthread_bind(thread, cpu);
- p->iothread = thread;
- wake_up_process(thread);
- }
+ kthread_bind(thread, cpu);
+ p->iothread = thread;
+ wake_up_process(thread);
+ return 0;
}
-static void bnx2fc_percpu_thread_destroy(unsigned int cpu)
+static int bnx2fc_cpu_offline(unsigned int cpu)
{
struct bnx2fc_percpu_s *p;
struct task_struct *thread;
@@ -2661,7 +2662,6 @@ static void bnx2fc_percpu_thread_destroy(unsigned int cpu)
thread = p->iothread;
p->iothread = NULL;
-
/* Free all work in the list */
list_for_each_entry_safe(work, tmp, &p->work_list, list) {
list_del_init(&work->list);
@@ -2673,20 +2673,6 @@ static void bnx2fc_percpu_thread_destroy(unsigned int cpu)
if (thread)
kthread_stop(thread);
-}
-
-
-static int bnx2fc_cpu_online(unsigned int cpu)
-{
- printk(PFX "CPU %x online: Create Rx thread\n", cpu);
- bnx2fc_percpu_thread_create(cpu);
- return 0;
-}
-
-static int bnx2fc_cpu_dead(unsigned int cpu)
-{
- printk(PFX "CPU %x offline: Remove Rx thread\n", cpu);
- bnx2fc_percpu_thread_destroy(cpu);
return 0;
}
@@ -2761,30 +2747,16 @@ static int __init bnx2fc_mod_init(void)
spin_lock_init(&p->fp_work_lock);
}
- get_online_cpus();
-
- for_each_online_cpu(cpu)
- bnx2fc_percpu_thread_create(cpu);
-
- rc = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
- "scsi/bnx2fc:online",
- bnx2fc_cpu_online, NULL);
+ rc = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "scsi/bnx2fc:online",
+ bnx2fc_cpu_online, bnx2fc_cpu_offline);
if (rc < 0)
- goto stop_threads;
+ goto stop_thread;
bnx2fc_online_state = rc;
- cpuhp_setup_state_nocalls(CPUHP_SCSI_BNX2FC_DEAD, "scsi/bnx2fc:dead",
- NULL, bnx2fc_cpu_dead);
- put_online_cpus();
-
cnic_register_driver(CNIC_ULP_FCOE, &bnx2fc_cnic_cb);
-
return 0;
-stop_threads:
- for_each_online_cpu(cpu)
- bnx2fc_percpu_thread_destroy(cpu);
- put_online_cpus();
+stop_thread:
kthread_stop(l2_thread);
free_wq:
destroy_workqueue(bnx2fc_wq);
@@ -2803,7 +2775,6 @@ static void __exit bnx2fc_mod_exit(void)
struct fcoe_percpu_s *bg;
struct task_struct *l2_thread;
struct sk_buff *skb;
- unsigned int cpu = 0;
/*
* NOTE: Since cnic calls register_driver routine rtnl_lock,
@@ -2844,16 +2815,7 @@ static void __exit bnx2fc_mod_exit(void)
if (l2_thread)
kthread_stop(l2_thread);
- get_online_cpus();
- /* Destroy per cpu threads */
- for_each_online_cpu(cpu) {
- bnx2fc_percpu_thread_destroy(cpu);
- }
-
- cpuhp_remove_state_nocalls(bnx2fc_online_state);
- cpuhp_remove_state_nocalls(CPUHP_SCSI_BNX2FC_DEAD);
-
- put_online_cpus();
+ cpuhp_remove_state(bnx2fc_online_state);
destroy_workqueue(bnx2fc_wq);
/*
diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
index 913c750205ce..26de61d65a4d 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
@@ -1008,6 +1008,28 @@ static struct bnx2fc_work *bnx2fc_alloc_work(struct bnx2fc_rport *tgt, u16 wqe)
return work;
}
+/* Pending work request completion */
+static void bnx2fc_pending_work(struct bnx2fc_rport *tgt, unsigned int wqe)
+{
+ unsigned int cpu = wqe % num_possible_cpus();
+ struct bnx2fc_percpu_s *fps;
+ struct bnx2fc_work *work;
+
+ fps = &per_cpu(bnx2fc_percpu, cpu);
+ spin_lock_bh(&fps->fp_work_lock);
+ if (fps->iothread) {
+ work = bnx2fc_alloc_work(tgt, wqe);
+ if (work) {
+ list_add_tail(&work->list, &fps->work_list);
+ wake_up_process(fps->iothread);
+ spin_unlock_bh(&fps->fp_work_lock);
+ return;
+ }
+ }
+ spin_unlock_bh(&fps->fp_work_lock);
+ bnx2fc_process_cq_compl(tgt, wqe);
+}
+
int bnx2fc_process_new_cqes(struct bnx2fc_rport *tgt)
{
struct fcoe_cqe *cq;
@@ -1042,28 +1064,7 @@ int bnx2fc_process_new_cqes(struct bnx2fc_rport *tgt)
/* Unsolicited event notification */
bnx2fc_process_unsol_compl(tgt, wqe);
} else {
- /* Pending work request completion */
- struct bnx2fc_work *work = NULL;
- struct bnx2fc_percpu_s *fps = NULL;
- unsigned int cpu = wqe % num_possible_cpus();
-
- fps = &per_cpu(bnx2fc_percpu, cpu);
- spin_lock_bh(&fps->fp_work_lock);
- if (unlikely(!fps->iothread))
- goto unlock;
-
- work = bnx2fc_alloc_work(tgt, wqe);
- if (work)
- list_add_tail(&work->list,
- &fps->work_list);
-unlock:
- spin_unlock_bh(&fps->fp_work_lock);
-
- /* Pending work request completion */
- if (fps->iothread && work)
- wake_up_process(fps->iothread);
- else
- bnx2fc_process_cq_compl(tgt, wqe);
+ bnx2fc_pending_work(tgt, wqe);
num_free_sqes++;
}
cqe++;
diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c
index 86afc002814c..4ebcda8d9500 100644
--- a/drivers/scsi/bnx2i/bnx2i_init.c
+++ b/drivers/scsi/bnx2i/bnx2i_init.c
@@ -404,12 +404,11 @@ int bnx2i_get_stats(void *handle)
/**
- * bnx2i_percpu_thread_create - Create a receive thread for an
- * online CPU
+ * bnx2i_cpu_online - Create a receive thread for an online CPU
*
* @cpu: cpu index for the online cpu
*/
-static void bnx2i_percpu_thread_create(unsigned int cpu)
+static int bnx2i_cpu_online(unsigned int cpu)
{
struct bnx2i_percpu_s *p;
struct task_struct *thread;
@@ -419,16 +418,17 @@ static void bnx2i_percpu_thread_create(unsigned int cpu)
thread = kthread_create_on_node(bnx2i_percpu_io_thread, (void *)p,
cpu_to_node(cpu),
"bnx2i_thread/%d", cpu);
+ if (IS_ERR(thread))
+ return PTR_ERR(thread);
+
/* bind thread to the cpu */
- if (likely(!IS_ERR(thread))) {
- kthread_bind(thread, cpu);
- p->iothread = thread;
- wake_up_process(thread);
- }
+ kthread_bind(thread, cpu);
+ p->iothread = thread;
+ wake_up_process(thread);
+ return 0;
}
-
-static void bnx2i_percpu_thread_destroy(unsigned int cpu)
+static int bnx2i_cpu_offline(unsigned int cpu)
{
struct bnx2i_percpu_s *p;
struct task_struct *thread;
@@ -451,19 +451,6 @@ static void bnx2i_percpu_thread_destroy(unsigned int cpu)
spin_unlock_bh(&p->p_work_lock);
if (thread)
kthread_stop(thread);
-}
-
-static int bnx2i_cpu_online(unsigned int cpu)
-{
- pr_info("bnx2i: CPU %x online: Create Rx thread\n", cpu);
- bnx2i_percpu_thread_create(cpu);
- return 0;
-}
-
-static int bnx2i_cpu_dead(unsigned int cpu)
-{
- pr_info("CPU %x offline: Remove Rx thread\n", cpu);
- bnx2i_percpu_thread_destroy(cpu);
return 0;
}
@@ -511,27 +498,14 @@ static int __init bnx2i_mod_init(void)
p->iothread = NULL;
}
- get_online_cpus();
-
- for_each_online_cpu(cpu)
- bnx2i_percpu_thread_create(cpu);
-
- err = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
- "scsi/bnx2i:online",
- bnx2i_cpu_online, NULL);
+ err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "scsi/bnx2i:online",
+ bnx2i_cpu_online, bnx2i_cpu_offline);
if (err < 0)
- goto remove_threads;
+ goto unreg_driver;
bnx2i_online_state = err;
-
- cpuhp_setup_state_nocalls(CPUHP_SCSI_BNX2I_DEAD, "scsi/bnx2i:dead",
- NULL, bnx2i_cpu_dead);
- put_online_cpus();
return 0;
-remove_threads:
- for_each_online_cpu(cpu)
- bnx2i_percpu_thread_destroy(cpu);
- put_online_cpus();
+unreg_driver:
cnic_unregister_driver(CNIC_ULP_ISCSI);
unreg_xport:
iscsi_unregister_transport(&bnx2i_iscsi_transport);
@@ -551,7 +525,6 @@ out:
static void __exit bnx2i_mod_exit(void)
{
struct bnx2i_hba *hba;
- unsigned cpu = 0;
mutex_lock(&bnx2i_dev_lock);
while (!list_empty(&adapter_list)) {
@@ -569,14 +542,7 @@ static void __exit bnx2i_mod_exit(void)
}
mutex_unlock(&bnx2i_dev_lock);
- get_online_cpus();
-
- for_each_online_cpu(cpu)
- bnx2i_percpu_thread_destroy(cpu);
-
- cpuhp_remove_state_nocalls(bnx2i_online_state);
- cpuhp_remove_state_nocalls(CPUHP_SCSI_BNX2I_DEAD);
- put_online_cpus();
+ cpuhp_remove_state(bnx2i_online_state);
iscsi_unregister_transport(&bnx2i_iscsi_transport);
cnic_unregister_driver(CNIC_ULP_ISCSI);
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index e4c83b7c96a8..1a4cfa562a60 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -2128,6 +2128,13 @@ void cxgbi_cleanup_task(struct iscsi_task *task)
struct iscsi_tcp_task *tcp_task = task->dd_data;
struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task);
+ if (!tcp_task || !tdata || (tcp_task->dd_data != tdata)) {
+ pr_info("task 0x%p,0x%p, tcp_task 0x%p, tdata 0x%p/0x%p.\n",
+ task, task->sc, tcp_task,
+ tcp_task ? tcp_task->dd_data : NULL, tdata);
+ return;
+ }
+
log_debug(1 << CXGBI_DBG_ISCSI,
"task 0x%p, skb 0x%p, itt 0x%x.\n",
task, tdata->skb, task->hdr_itt);
diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c
index 077f62e208aa..6a4367cc9caa 100644
--- a/drivers/scsi/cxlflash/main.c
+++ b/drivers/scsi/cxlflash/main.c
@@ -3401,9 +3401,10 @@ static int cxlflash_afu_debug(struct cxlflash_cfg *cfg,
if (is_write) {
req_flags |= SISL_REQ_FLAGS_HOST_WRITE;
- rc = copy_from_user(kbuf, ubuf, ulen);
- if (unlikely(rc))
+ if (copy_from_user(kbuf, ubuf, ulen)) {
+ rc = -EFAULT;
goto out;
+ }
}
}
@@ -3431,8 +3432,10 @@ static int cxlflash_afu_debug(struct cxlflash_cfg *cfg,
goto out;
}
- if (ulen && !is_write)
- rc = copy_to_user(ubuf, kbuf, ulen);
+ if (ulen && !is_write) {
+ if (copy_to_user(ubuf, kbuf, ulen))
+ rc = -EFAULT;
+ }
out:
kfree(buf);
dev_dbg(dev, "%s: returning rc=%d\n", __func__, rc);
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 551d103c27f1..2bfea7082e3a 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -1693,7 +1693,7 @@ static int prep_ssp_v2_hw(struct hisi_hba *hisi_hba,
static int parse_trans_tx_err_code_v2_hw(u32 err_msk)
{
- const u8 trans_tx_err_code_prio[] = {
+ static const u8 trans_tx_err_code_prio[] = {
TRANS_TX_OPEN_FAIL_WITH_IT_NEXUS_LOSS,
TRANS_TX_ERR_PHY_NOT_ENABLE,
TRANS_TX_OPEN_CNX_ERR_WRONG_DESTINATION,
@@ -1738,7 +1738,7 @@ static int parse_trans_tx_err_code_v2_hw(u32 err_msk)
static int parse_trans_rx_err_code_v2_hw(u32 err_msk)
{
- const u8 trans_rx_err_code_prio[] = {
+ static const u8 trans_rx_err_code_prio[] = {
TRANS_RX_ERR_WITH_RXFRAME_CRC_ERR,
TRANS_RX_ERR_WITH_RXFIS_8B10B_DISP_ERR,
TRANS_RX_ERR_WITH_RXFRAME_HAVE_ERRPRM,
@@ -1784,7 +1784,7 @@ static int parse_trans_rx_err_code_v2_hw(u32 err_msk)
static int parse_dma_tx_err_code_v2_hw(u32 err_msk)
{
- const u8 dma_tx_err_code_prio[] = {
+ static const u8 dma_tx_err_code_prio[] = {
DMA_TX_UNEXP_XFER_ERR,
DMA_TX_UNEXP_RETRANS_ERR,
DMA_TX_XFER_LEN_OVERFLOW,
@@ -1810,7 +1810,7 @@ static int parse_dma_tx_err_code_v2_hw(u32 err_msk)
static int parse_sipc_rx_err_code_v2_hw(u32 err_msk)
{
- const u8 sipc_rx_err_code_prio[] = {
+ static const u8 sipc_rx_err_code_prio[] = {
SIPC_RX_FIS_STATUS_ERR_BIT_VLD,
SIPC_RX_PIO_WRSETUP_STATUS_DRQ_ERR,
SIPC_RX_FIS_STATUS_BSY_BIT_ERR,
@@ -1836,7 +1836,7 @@ static int parse_sipc_rx_err_code_v2_hw(u32 err_msk)
static int parse_dma_rx_err_code_v2_hw(u32 err_msk)
{
- const u8 dma_rx_err_code_prio[] = {
+ static const u8 dma_rx_err_code_prio[] = {
DMA_RX_UNKNOWN_FRM_ERR,
DMA_RX_DATA_LEN_OVERFLOW,
DMA_RX_DATA_LEN_UNDERFLOW,
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 8914eab84337..4f7cdb28bd38 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -938,7 +938,7 @@ static struct scsi_host_template hpsa_driver_template = {
#endif
.sdev_attrs = hpsa_sdev_attrs,
.shost_attrs = hpsa_shost_attrs,
- .max_sectors = 8192,
+ .max_sectors = 1024,
.no_write_same = 1,
};
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index 47f66e949745..ed197bc8e801 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -213,7 +213,7 @@ static void sci_task_request_build_ssp_task_iu(struct isci_request *ireq)
* @task_context:
*
*/
-static void scu_ssp_reqeust_construct_task_context(
+static void scu_ssp_request_construct_task_context(
struct isci_request *ireq,
struct scu_task_context *task_context)
{
@@ -425,7 +425,7 @@ static void scu_ssp_io_request_construct_task_context(struct isci_request *ireq,
u8 prot_type = scsi_get_prot_type(scmd);
u8 prot_op = scsi_get_prot_op(scmd);
- scu_ssp_reqeust_construct_task_context(ireq, task_context);
+ scu_ssp_request_construct_task_context(ireq, task_context);
task_context->ssp_command_iu_length =
sizeof(struct ssp_cmd_iu) / sizeof(u32);
@@ -472,7 +472,7 @@ static void scu_ssp_task_request_construct_task_context(struct isci_request *ire
{
struct scu_task_context *task_context = ireq->tc;
- scu_ssp_reqeust_construct_task_context(ireq, task_context);
+ scu_ssp_request_construct_task_context(ireq, task_context);
task_context->control_frame = 1;
task_context->priority = SCU_TASK_PRIORITY_HIGH;
@@ -495,7 +495,7 @@ static void scu_ssp_task_request_construct_task_context(struct isci_request *ire
* the command buffer is complete. none Revisit task context construction to
* determine what is common for SSP/SMP/STP task context structures.
*/
-static void scu_sata_reqeust_construct_task_context(
+static void scu_sata_request_construct_task_context(
struct isci_request *ireq,
struct scu_task_context *task_context)
{
@@ -562,7 +562,7 @@ static void scu_stp_raw_request_construct_task_context(struct isci_request *ireq
{
struct scu_task_context *task_context = ireq->tc;
- scu_sata_reqeust_construct_task_context(ireq, task_context);
+ scu_sata_request_construct_task_context(ireq, task_context);
task_context->control_frame = 0;
task_context->priority = SCU_TASK_PRIORITY_NORMAL;
@@ -613,7 +613,7 @@ static void sci_stp_optimized_request_construct(struct isci_request *ireq,
struct scu_task_context *task_context = ireq->tc;
/* Build the STP task context structure */
- scu_sata_reqeust_construct_task_context(ireq, task_context);
+ scu_sata_request_construct_task_context(ireq, task_context);
/* Copy over the SGL elements */
sci_request_build_sgl(ireq);
@@ -1401,7 +1401,7 @@ static enum sci_status sci_stp_request_pio_data_out_transmit_data(struct isci_re
* @data_buffer: The buffer of data to be copied.
* @length: The length of the data transfer.
*
- * Copy the data from the buffer for the length specified to the IO reqeust SGL
+ * Copy the data from the buffer for the length specified to the IO request SGL
* specified data region. enum sci_status
*/
static enum sci_status
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
index fd501f8dbb11..8660f923ace0 100644
--- a/drivers/scsi/libfc/fc_disc.c
+++ b/drivers/scsi/libfc/fc_disc.c
@@ -573,7 +573,7 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
event = DISC_EV_FAILED;
}
if (error)
- fc_disc_error(disc, fp);
+ fc_disc_error(disc, ERR_PTR(error));
else if (event != DISC_EV_NONE)
fc_disc_done(disc, event);
fc_frame_free(fp);
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 4ed48ed38e79..7ee1a94c0b33 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -205,8 +205,10 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
atomic_read(&tgtp->xmt_ls_rsp_error));
len += snprintf(buf+len, PAGE_SIZE-len,
- "FCP: Rcv %08x Release %08x Drop %08x\n",
+ "FCP: Rcv %08x Defer %08x Release %08x "
+ "Drop %08x\n",
atomic_read(&tgtp->rcv_fcp_cmd_in),
+ atomic_read(&tgtp->rcv_fcp_cmd_defer),
atomic_read(&tgtp->xmt_fcp_release),
atomic_read(&tgtp->rcv_fcp_cmd_drop));
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 5cc8b0f7d885..744f3f395b64 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -782,8 +782,11 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size)
atomic_read(&tgtp->xmt_ls_rsp_error));
len += snprintf(buf + len, size - len,
- "FCP: Rcv %08x Drop %08x\n",
+ "FCP: Rcv %08x Defer %08x Release %08x "
+ "Drop %08x\n",
atomic_read(&tgtp->rcv_fcp_cmd_in),
+ atomic_read(&tgtp->rcv_fcp_cmd_defer),
+ atomic_read(&tgtp->xmt_fcp_release),
atomic_read(&tgtp->rcv_fcp_cmd_drop));
if (atomic_read(&tgtp->rcv_fcp_cmd_in) !=
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index fbeec344c6cc..bbbd0f84160d 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
@@ -841,12 +841,31 @@ lpfc_nvmet_xmt_fcp_release(struct nvmet_fc_target_port *tgtport,
lpfc_nvmet_ctxbuf_post(phba, ctxp->ctxbuf);
}
+static void
+lpfc_nvmet_defer_rcv(struct nvmet_fc_target_port *tgtport,
+ struct nvmefc_tgt_fcp_req *rsp)
+{
+ struct lpfc_nvmet_tgtport *tgtp;
+ struct lpfc_nvmet_rcv_ctx *ctxp =
+ container_of(rsp, struct lpfc_nvmet_rcv_ctx, ctx.fcp_req);
+ struct rqb_dmabuf *nvmebuf = ctxp->rqb_buffer;
+ struct lpfc_hba *phba = ctxp->phba;
+
+ lpfc_nvmeio_data(phba, "NVMET DEFERRCV: xri x%x sz %d CPU %02x\n",
+ ctxp->oxid, ctxp->size, smp_processor_id());
+
+ tgtp = phba->targetport->private;
+ atomic_inc(&tgtp->rcv_fcp_cmd_defer);
+ lpfc_rq_buf_free(phba, &nvmebuf->hbuf); /* repost */
+}
+
static struct nvmet_fc_target_template lpfc_tgttemplate = {
.targetport_delete = lpfc_nvmet_targetport_delete,
.xmt_ls_rsp = lpfc_nvmet_xmt_ls_rsp,
.fcp_op = lpfc_nvmet_xmt_fcp_op,
.fcp_abort = lpfc_nvmet_xmt_fcp_abort,
.fcp_req_release = lpfc_nvmet_xmt_fcp_release,
+ .defer_rcv = lpfc_nvmet_defer_rcv,
.max_hw_queues = 1,
.max_sgl_segments = LPFC_NVMET_DEFAULT_SEGS,
@@ -1504,6 +1523,17 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba,
return;
}
+ /* Processing of FCP command is deferred */
+ if (rc == -EOVERFLOW) {
+ lpfc_nvmeio_data(phba,
+ "NVMET RCV BUSY: xri x%x sz %d from %06x\n",
+ oxid, size, sid);
+ /* defer reposting rcv buffer till .defer_rcv callback */
+ ctxp->rqb_buffer = nvmebuf;
+ atomic_inc(&tgtp->rcv_fcp_cmd_out);
+ return;
+ }
+
atomic_inc(&tgtp->rcv_fcp_cmd_drop);
lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR,
"6159 FCP Drop IO x%x: err x%x: x%x x%x x%x\n",
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.h b/drivers/scsi/lpfc/lpfc_nvmet.h
index e675ef17be08..48a76788b003 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.h
+++ b/drivers/scsi/lpfc/lpfc_nvmet.h
@@ -49,6 +49,7 @@ struct lpfc_nvmet_tgtport {
atomic_t rcv_fcp_cmd_in;
atomic_t rcv_fcp_cmd_out;
atomic_t rcv_fcp_cmd_drop;
+ atomic_t rcv_fcp_cmd_defer;
atomic_t xmt_fcp_release;
/* Stats counters - lpfc_nvmet_xmt_fcp_op */
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index f990ab4d45e1..985510628f56 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -425,7 +425,7 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
int
megasas_alloc_cmdlist_fusion(struct megasas_instance *instance)
{
- u32 max_mpt_cmd, i;
+ u32 max_mpt_cmd, i, j;
struct fusion_context *fusion;
fusion = instance->ctrl_context;
@@ -450,11 +450,15 @@ megasas_alloc_cmdlist_fusion(struct megasas_instance *instance)
fusion->cmd_list[i] = kzalloc(sizeof(struct megasas_cmd_fusion),
GFP_KERNEL);
if (!fusion->cmd_list[i]) {
+ for (j = 0; j < i; j++)
+ kfree(fusion->cmd_list[j]);
+ kfree(fusion->cmd_list);
dev_err(&instance->pdev->dev,
"Failed from %s %d\n", __func__, __LINE__);
return -ENOMEM;
}
}
+
return 0;
}
int
diff --git a/drivers/scsi/qedf/qedf.h b/drivers/scsi/qedf/qedf.h
index 4d038926a455..351f06dfc5a0 100644
--- a/drivers/scsi/qedf/qedf.h
+++ b/drivers/scsi/qedf/qedf.h
@@ -528,7 +528,8 @@ struct fip_vlan {
#define QEDF_WRITE (1 << 0)
#define MAX_FIBRE_LUNS 0xffffffff
-#define QEDF_MAX_NUM_CQS 8
+#define MIN_NUM_CPUS_MSIX(x) min_t(u32, x->dev_info.num_cqs, \
+ num_online_cpus())
/*
* PCI function probe defines
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
index b58bba4604e8..1d13c9ca517d 100644
--- a/drivers/scsi/qedf/qedf_main.c
+++ b/drivers/scsi/qedf/qedf_main.c
@@ -1227,7 +1227,7 @@ static void qedf_rport_event_handler(struct fc_lport *lport,
if (rdata->spp_type != FC_TYPE_FCP) {
QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC,
- "Not offlading since since spp type isn't FCP\n");
+ "Not offloading since spp type isn't FCP\n");
break;
}
if (!(rdata->ids.roles & FC_RPORT_ROLE_FCP_TARGET)) {
@@ -2760,11 +2760,9 @@ static int qedf_set_fcoe_pf_param(struct qedf_ctx *qedf)
* we allocation is the minimum off:
*
* Number of CPUs
- * Number of MSI-X vectors
- * Max number allocated in hardware (QEDF_MAX_NUM_CQS)
+ * Number allocated by qed for our PCI function
*/
- qedf->num_queues = min((unsigned int)QEDF_MAX_NUM_CQS,
- num_online_cpus());
+ qedf->num_queues = MIN_NUM_CPUS_MSIX(qedf);
QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "Number of CQs is %d.\n",
qedf->num_queues);
@@ -2962,6 +2960,13 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
goto err1;
}
+ /* Learn information crucial for qedf to progress */
+ rc = qed_ops->fill_dev_info(qedf->cdev, &qedf->dev_info);
+ if (rc) {
+ QEDF_ERR(&(qedf->dbg_ctx), "Failed to dev info.\n");
+ goto err1;
+ }
+
/* queue allocation code should come here
* order should be
* slowpath_start
@@ -2977,13 +2982,6 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
}
qed_ops->common->update_pf_params(qedf->cdev, &qedf->pf_params);
- /* Learn information crucial for qedf to progress */
- rc = qed_ops->fill_dev_info(qedf->cdev, &qedf->dev_info);
- if (rc) {
- QEDF_ERR(&(qedf->dbg_ctx), "Failed to dev info.\n");
- goto err1;
- }
-
/* Record BDQ producer doorbell addresses */
qedf->bdq_primary_prod = qedf->dev_info.primary_dbq_rq_addr;
qedf->bdq_secondary_prod = qedf->dev_info.secondary_bdq_rq_addr;
diff --git a/drivers/scsi/qedi/Kconfig b/drivers/scsi/qedi/Kconfig
index 21331453db7b..2ff753ce6e27 100644
--- a/drivers/scsi/qedi/Kconfig
+++ b/drivers/scsi/qedi/Kconfig
@@ -5,6 +5,7 @@ config QEDI
select SCSI_ISCSI_ATTRS
select QED_LL2
select QED_ISCSI
+ select ISCSI_BOOT_SYSFS
---help---
This driver supports iSCSI offload for the QLogic FastLinQ
41000 Series Converged Network Adapters.
diff --git a/drivers/scsi/qedi/qedi.h b/drivers/scsi/qedi/qedi.h
index 32632c9b2276..91d2f51c351b 100644
--- a/drivers/scsi/qedi/qedi.h
+++ b/drivers/scsi/qedi/qedi.h
@@ -23,11 +23,17 @@
#include <linux/qed/qed_iscsi_if.h>
#include <linux/qed/qed_ll2_if.h>
#include "qedi_version.h"
+#include "qedi_nvm_iscsi_cfg.h"
#define QEDI_MODULE_NAME "qedi"
struct qedi_endpoint;
+#ifndef GET_FIELD2
+#define GET_FIELD2(value, name) \
+ (((value) & (name ## _MASK)) >> (name ## _OFFSET))
+#endif
+
/*
* PCI function probe defines
*/
@@ -66,6 +72,11 @@ struct qedi_endpoint;
#define QEDI_HW_DMA_BOUNDARY 0xfff
#define QEDI_PATH_HANDLE 0xFE0000000UL
+enum qedi_nvm_tgts {
+ QEDI_NVM_TGT_PRI,
+ QEDI_NVM_TGT_SEC,
+};
+
struct qedi_uio_ctrl {
/* meta data */
u32 uio_hsi_version;
@@ -283,6 +294,8 @@ struct qedi_ctx {
void *bdq_pbl_list;
dma_addr_t bdq_pbl_list_dma;
u8 bdq_pbl_list_num_entries;
+ struct nvm_iscsi_cfg *iscsi_cfg;
+ dma_addr_t nvm_buf_dma;
void __iomem *bdq_primary_prod;
void __iomem *bdq_secondary_prod;
u16 bdq_prod_idx;
@@ -337,6 +350,10 @@ struct qedi_ctx {
bool use_fast_sge;
atomic_t num_offloads;
+#define SYSFS_FLAG_FW_SEL_BOOT 2
+#define IPV6_LEN 41
+#define IPV4_LEN 17
+ struct iscsi_boot_kset *boot_kset;
};
struct qedi_work {
diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c
index 19254bd739d9..93d54acd4a22 100644
--- a/drivers/scsi/qedi/qedi_fw.c
+++ b/drivers/scsi/qedi/qedi_fw.c
@@ -1411,7 +1411,7 @@ static void qedi_tmf_work(struct work_struct *work)
list_work = kzalloc(sizeof(*list_work), GFP_ATOMIC);
if (!list_work) {
- QEDI_ERR(&qedi->dbg_ctx, "Memory alloction failed\n");
+ QEDI_ERR(&qedi->dbg_ctx, "Memory allocation failed\n");
goto abort_ret;
}
diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c
index 80edd28b635f..37da9a8b43b1 100644
--- a/drivers/scsi/qedi/qedi_iscsi.c
+++ b/drivers/scsi/qedi/qedi_iscsi.c
@@ -824,7 +824,7 @@ qedi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
u32 iscsi_cid = QEDI_CID_RESERVED;
u16 len = 0;
char *buf = NULL;
- int ret;
+ int ret, tmp;
if (!shost) {
ret = -ENXIO;
@@ -940,10 +940,10 @@ qedi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
ep_rel_conn:
qedi->ep_tbl[iscsi_cid] = NULL;
- ret = qedi_ops->release_conn(qedi->cdev, qedi_ep->handle);
- if (ret)
+ tmp = qedi_ops->release_conn(qedi->cdev, qedi_ep->handle);
+ if (tmp)
QEDI_WARN(&qedi->dbg_ctx, "release_conn returned %d\n",
- ret);
+ tmp);
ep_free_sq:
qedi_free_sq(qedi, qedi_ep);
ep_conn_exit:
diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c
index 5f5a4ef2e529..2c3783684815 100644
--- a/drivers/scsi/qedi/qedi_main.c
+++ b/drivers/scsi/qedi/qedi_main.c
@@ -19,6 +19,7 @@
#include <linux/mm.h>
#include <linux/if_vlan.h>
#include <linux/cpu.h>
+#include <linux/iscsi_boot_sysfs.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
@@ -1143,6 +1144,30 @@ exit_setup_int:
return rc;
}
+static void qedi_free_nvm_iscsi_cfg(struct qedi_ctx *qedi)
+{
+ if (qedi->iscsi_cfg)
+ dma_free_coherent(&qedi->pdev->dev,
+ sizeof(struct nvm_iscsi_cfg),
+ qedi->iscsi_cfg, qedi->nvm_buf_dma);
+}
+
+static int qedi_alloc_nvm_iscsi_cfg(struct qedi_ctx *qedi)
+{
+ qedi->iscsi_cfg = dma_zalloc_coherent(&qedi->pdev->dev,
+ sizeof(struct nvm_iscsi_cfg),
+ &qedi->nvm_buf_dma, GFP_KERNEL);
+ if (!qedi->iscsi_cfg) {
+ QEDI_ERR(&qedi->dbg_ctx, "Could not allocate NVM BUF.\n");
+ return -ENOMEM;
+ }
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
+ "NVM BUF addr=0x%p dma=0x%llx.\n", qedi->iscsi_cfg,
+ qedi->nvm_buf_dma);
+
+ return 0;
+}
+
static void qedi_free_bdq(struct qedi_ctx *qedi)
{
int i;
@@ -1183,6 +1208,7 @@ static void qedi_free_global_queues(struct qedi_ctx *qedi)
kfree(gl[i]);
}
qedi_free_bdq(qedi);
+ qedi_free_nvm_iscsi_cfg(qedi);
}
static int qedi_alloc_bdq(struct qedi_ctx *qedi)
@@ -1309,6 +1335,11 @@ static int qedi_alloc_global_queues(struct qedi_ctx *qedi)
if (rc)
goto mem_alloc_failure;
+ /* Allocate DMA coherent buffers for NVM_ISCSI_CFG */
+ rc = qedi_alloc_nvm_iscsi_cfg(qedi);
+ if (rc)
+ goto mem_alloc_failure;
+
/* Allocate a CQ and an associated PBL for each MSI-X
* vector.
*/
@@ -1671,6 +1702,387 @@ void qedi_reset_host_mtu(struct qedi_ctx *qedi, u16 mtu)
qedi_ops->ll2->start(qedi->cdev, &params);
}
+/**
+ * qedi_get_nvram_block: - Scan through the iSCSI NVRAM block (while accounting
+ * for gaps) for the matching absolute-pf-id of the QEDI device.
+ */
+static struct nvm_iscsi_block *
+qedi_get_nvram_block(struct qedi_ctx *qedi)
+{
+ int i;
+ u8 pf;
+ u32 flags;
+ struct nvm_iscsi_block *block;
+
+ pf = qedi->dev_info.common.abs_pf_id;
+ block = &qedi->iscsi_cfg->block[0];
+ for (i = 0; i < NUM_OF_ISCSI_PF_SUPPORTED; i++, block++) {
+ flags = ((block->id) & NVM_ISCSI_CFG_BLK_CTRL_FLAG_MASK) >>
+ NVM_ISCSI_CFG_BLK_CTRL_FLAG_OFFSET;
+ if (flags & (NVM_ISCSI_CFG_BLK_CTRL_FLAG_IS_NOT_EMPTY |
+ NVM_ISCSI_CFG_BLK_CTRL_FLAG_PF_MAPPED) &&
+ (pf == (block->id & NVM_ISCSI_CFG_BLK_MAPPED_PF_ID_MASK)
+ >> NVM_ISCSI_CFG_BLK_MAPPED_PF_ID_OFFSET))
+ return block;
+ }
+ return NULL;
+}
+
+static ssize_t qedi_show_boot_eth_info(void *data, int type, char *buf)
+{
+ struct qedi_ctx *qedi = data;
+ struct nvm_iscsi_initiator *initiator;
+ char *str = buf;
+ int rc = 1;
+ u32 ipv6_en, dhcp_en, ip_len;
+ struct nvm_iscsi_block *block;
+ char *fmt, *ip, *sub, *gw;
+
+ block = qedi_get_nvram_block(qedi);
+ if (!block)
+ return 0;
+
+ initiator = &block->initiator;
+ ipv6_en = block->generic.ctrl_flags &
+ NVM_ISCSI_CFG_GEN_IPV6_ENABLED;
+ dhcp_en = block->generic.ctrl_flags &
+ NVM_ISCSI_CFG_GEN_DHCP_TCPIP_CONFIG_ENABLED;
+ /* Static IP assignments. */
+ fmt = ipv6_en ? "%pI6\n" : "%pI4\n";
+ ip = ipv6_en ? initiator->ipv6.addr.byte : initiator->ipv4.addr.byte;
+ ip_len = ipv6_en ? IPV6_LEN : IPV4_LEN;
+ sub = ipv6_en ? initiator->ipv6.subnet_mask.byte :
+ initiator->ipv4.subnet_mask.byte;
+ gw = ipv6_en ? initiator->ipv6.gateway.byte :
+ initiator->ipv4.gateway.byte;
+ /* DHCP IP adjustments. */
+ fmt = dhcp_en ? "%s\n" : fmt;
+ if (dhcp_en) {
+ ip = ipv6_en ? "0::0" : "0.0.0.0";
+ sub = ip;
+ gw = ip;
+ ip_len = ipv6_en ? 5 : 8;
+ }
+
+ switch (type) {
+ case ISCSI_BOOT_ETH_IP_ADDR:
+ rc = snprintf(str, ip_len, fmt, ip);
+ break;
+ case ISCSI_BOOT_ETH_SUBNET_MASK:
+ rc = snprintf(str, ip_len, fmt, sub);
+ break;
+ case ISCSI_BOOT_ETH_GATEWAY:
+ rc = snprintf(str, ip_len, fmt, gw);
+ break;
+ case ISCSI_BOOT_ETH_FLAGS:
+ rc = snprintf(str, 3, "%hhd\n",
+ SYSFS_FLAG_FW_SEL_BOOT);
+ break;
+ case ISCSI_BOOT_ETH_INDEX:
+ rc = snprintf(str, 3, "0\n");
+ break;
+ case ISCSI_BOOT_ETH_MAC:
+ rc = sysfs_format_mac(str, qedi->mac, ETH_ALEN);
+ break;
+ case ISCSI_BOOT_ETH_VLAN:
+ rc = snprintf(str, 12, "%d\n",
+ GET_FIELD2(initiator->generic_cont0,
+ NVM_ISCSI_CFG_INITIATOR_VLAN));
+ break;
+ case ISCSI_BOOT_ETH_ORIGIN:
+ if (dhcp_en)
+ rc = snprintf(str, 3, "3\n");
+ break;
+ default:
+ rc = 0;
+ break;
+ }
+
+ return rc;
+}
+
+static umode_t qedi_eth_get_attr_visibility(void *data, int type)
+{
+ int rc = 1;
+
+ switch (type) {
+ case ISCSI_BOOT_ETH_FLAGS:
+ case ISCSI_BOOT_ETH_MAC:
+ case ISCSI_BOOT_ETH_INDEX:
+ case ISCSI_BOOT_ETH_IP_ADDR:
+ case ISCSI_BOOT_ETH_SUBNET_MASK:
+ case ISCSI_BOOT_ETH_GATEWAY:
+ case ISCSI_BOOT_ETH_ORIGIN:
+ case ISCSI_BOOT_ETH_VLAN:
+ rc = 0444;
+ break;
+ default:
+ rc = 0;
+ break;
+ }
+ return rc;
+}
+
+static ssize_t qedi_show_boot_ini_info(void *data, int type, char *buf)
+{
+ struct qedi_ctx *qedi = data;
+ struct nvm_iscsi_initiator *initiator;
+ char *str = buf;
+ int rc;
+ struct nvm_iscsi_block *block;
+
+ block = qedi_get_nvram_block(qedi);
+ if (!block)
+ return 0;
+
+ initiator = &block->initiator;
+
+ switch (type) {
+ case ISCSI_BOOT_INI_INITIATOR_NAME:
+ rc = snprintf(str, NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN, "%s\n",
+ initiator->initiator_name.byte);
+ break;
+ default:
+ rc = 0;
+ break;
+ }
+ return rc;
+}
+
+static umode_t qedi_ini_get_attr_visibility(void *data, int type)
+{
+ int rc;
+
+ switch (type) {
+ case ISCSI_BOOT_INI_INITIATOR_NAME:
+ rc = 0444;
+ break;
+ default:
+ rc = 0;
+ break;
+ }
+ return rc;
+}
+
+static ssize_t
+qedi_show_boot_tgt_info(struct qedi_ctx *qedi, int type,
+ char *buf, enum qedi_nvm_tgts idx)
+{
+ char *str = buf;
+ int rc = 1;
+ u32 ctrl_flags, ipv6_en, chap_en, mchap_en, ip_len;
+ struct nvm_iscsi_block *block;
+ char *chap_name, *chap_secret;
+ char *mchap_name, *mchap_secret;
+
+ block = qedi_get_nvram_block(qedi);
+ if (!block)
+ goto exit_show_tgt_info;
+
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_EVT,
+ "Port:%d, tgt_idx:%d\n",
+ GET_FIELD2(block->id, NVM_ISCSI_CFG_BLK_MAPPED_PF_ID), idx);
+
+ ctrl_flags = block->target[idx].ctrl_flags &
+ NVM_ISCSI_CFG_TARGET_ENABLED;
+
+ if (!ctrl_flags) {
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_EVT,
+ "Target disabled\n");
+ goto exit_show_tgt_info;
+ }
+
+ ipv6_en = block->generic.ctrl_flags &
+ NVM_ISCSI_CFG_GEN_IPV6_ENABLED;
+ ip_len = ipv6_en ? IPV6_LEN : IPV4_LEN;
+ chap_en = block->generic.ctrl_flags &
+ NVM_ISCSI_CFG_GEN_CHAP_ENABLED;
+ chap_name = chap_en ? block->initiator.chap_name.byte : NULL;
+ chap_secret = chap_en ? block->initiator.chap_password.byte : NULL;
+
+ mchap_en = block->generic.ctrl_flags &
+ NVM_ISCSI_CFG_GEN_CHAP_MUTUAL_ENABLED;
+ mchap_name = mchap_en ? block->target[idx].chap_name.byte : NULL;
+ mchap_secret = mchap_en ? block->target[idx].chap_password.byte : NULL;
+
+ switch (type) {
+ case ISCSI_BOOT_TGT_NAME:
+ rc = snprintf(str, NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN, "%s\n",
+ block->target[idx].target_name.byte);
+ break;
+ case ISCSI_BOOT_TGT_IP_ADDR:
+ if (ipv6_en)
+ rc = snprintf(str, ip_len, "%pI6\n",
+ block->target[idx].ipv6_addr.byte);
+ else
+ rc = snprintf(str, ip_len, "%pI4\n",
+ block->target[idx].ipv4_addr.byte);
+ break;
+ case ISCSI_BOOT_TGT_PORT:
+ rc = snprintf(str, 12, "%d\n",
+ GET_FIELD2(block->target[idx].generic_cont0,
+ NVM_ISCSI_CFG_TARGET_TCP_PORT));
+ break;
+ case ISCSI_BOOT_TGT_LUN:
+ rc = snprintf(str, 22, "%.*d\n",
+ block->target[idx].lun.value[1],
+ block->target[idx].lun.value[0]);
+ break;
+ case ISCSI_BOOT_TGT_CHAP_NAME:
+ rc = snprintf(str, NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, "%s\n",
+ chap_name);
+ break;
+ case ISCSI_BOOT_TGT_CHAP_SECRET:
+ rc = snprintf(str, NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN, "%s\n",
+ chap_secret);
+ break;
+ case ISCSI_BOOT_TGT_REV_CHAP_NAME:
+ rc = snprintf(str, NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, "%s\n",
+ mchap_name);
+ break;
+ case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
+ rc = snprintf(str, NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN, "%s\n",
+ mchap_secret);
+ break;
+ case ISCSI_BOOT_TGT_FLAGS:
+ rc = snprintf(str, 3, "%hhd\n", SYSFS_FLAG_FW_SEL_BOOT);
+ break;
+ case ISCSI_BOOT_TGT_NIC_ASSOC:
+ rc = snprintf(str, 3, "0\n");
+ break;
+ default:
+ rc = 0;
+ break;
+ }
+
+exit_show_tgt_info:
+ return rc;
+}
+
+static ssize_t qedi_show_boot_tgt_pri_info(void *data, int type, char *buf)
+{
+ struct qedi_ctx *qedi = data;
+
+ return qedi_show_boot_tgt_info(qedi, type, buf, QEDI_NVM_TGT_PRI);
+}
+
+static ssize_t qedi_show_boot_tgt_sec_info(void *data, int type, char *buf)
+{
+ struct qedi_ctx *qedi = data;
+
+ return qedi_show_boot_tgt_info(qedi, type, buf, QEDI_NVM_TGT_SEC);
+}
+
+static umode_t qedi_tgt_get_attr_visibility(void *data, int type)
+{
+ int rc;
+
+ switch (type) {
+ case ISCSI_BOOT_TGT_NAME:
+ case ISCSI_BOOT_TGT_IP_ADDR:
+ case ISCSI_BOOT_TGT_PORT:
+ case ISCSI_BOOT_TGT_LUN:
+ case ISCSI_BOOT_TGT_CHAP_NAME:
+ case ISCSI_BOOT_TGT_CHAP_SECRET:
+ case ISCSI_BOOT_TGT_REV_CHAP_NAME:
+ case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
+ case ISCSI_BOOT_TGT_NIC_ASSOC:
+ case ISCSI_BOOT_TGT_FLAGS:
+ rc = 0444;
+ break;
+ default:
+ rc = 0;
+ break;
+ }
+ return rc;
+}
+
+static void qedi_boot_release(void *data)
+{
+ struct qedi_ctx *qedi = data;
+
+ scsi_host_put(qedi->shost);
+}
+
+static int qedi_get_boot_info(struct qedi_ctx *qedi)
+{
+ int ret = 1;
+ u16 len;
+
+ len = sizeof(struct nvm_iscsi_cfg);
+
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
+ "Get NVM iSCSI CFG image\n");
+ ret = qedi_ops->common->nvm_get_image(qedi->cdev,
+ QED_NVM_IMAGE_ISCSI_CFG,
+ (char *)qedi->iscsi_cfg, len);
+ if (ret)
+ QEDI_ERR(&qedi->dbg_ctx,
+ "Could not get NVM image. ret = %d\n", ret);
+
+ return ret;
+}
+
+static int qedi_setup_boot_info(struct qedi_ctx *qedi)
+{
+ struct iscsi_boot_kobj *boot_kobj;
+
+ if (qedi_get_boot_info(qedi))
+ return -EPERM;
+
+ qedi->boot_kset = iscsi_boot_create_host_kset(qedi->shost->host_no);
+ if (!qedi->boot_kset)
+ goto kset_free;
+
+ if (!scsi_host_get(qedi->shost))
+ goto kset_free;
+
+ boot_kobj = iscsi_boot_create_target(qedi->boot_kset, 0, qedi,
+ qedi_show_boot_tgt_pri_info,
+ qedi_tgt_get_attr_visibility,
+ qedi_boot_release);
+ if (!boot_kobj)
+ goto put_host;
+
+ if (!scsi_host_get(qedi->shost))
+ goto kset_free;
+
+ boot_kobj = iscsi_boot_create_target(qedi->boot_kset, 1, qedi,
+ qedi_show_boot_tgt_sec_info,
+ qedi_tgt_get_attr_visibility,
+ qedi_boot_release);
+ if (!boot_kobj)
+ goto put_host;
+
+ if (!scsi_host_get(qedi->shost))
+ goto kset_free;
+
+ boot_kobj = iscsi_boot_create_initiator(qedi->boot_kset, 0, qedi,
+ qedi_show_boot_ini_info,
+ qedi_ini_get_attr_visibility,
+ qedi_boot_release);
+ if (!boot_kobj)
+ goto put_host;
+
+ if (!scsi_host_get(qedi->shost))
+ goto kset_free;
+
+ boot_kobj = iscsi_boot_create_ethernet(qedi->boot_kset, 0, qedi,
+ qedi_show_boot_eth_info,
+ qedi_eth_get_attr_visibility,
+ qedi_boot_release);
+ if (!boot_kobj)
+ goto put_host;
+
+ return 0;
+
+put_host:
+ scsi_host_put(qedi->shost);
+kset_free:
+ iscsi_boot_destroy_kset(qedi->boot_kset);
+ return -ENOMEM;
+}
+
static void __qedi_remove(struct pci_dev *pdev, int mode)
{
struct qedi_ctx *qedi = pci_get_drvdata(pdev);
@@ -1724,6 +2136,9 @@ static void __qedi_remove(struct pci_dev *pdev, int mode)
qedi->ll2_recv_thread = NULL;
}
qedi_ll2_free_skbs(qedi);
+
+ if (qedi->boot_kset)
+ iscsi_boot_destroy_kset(qedi->boot_kset);
}
}
@@ -1967,6 +2382,10 @@ static int __qedi_probe(struct pci_dev *pdev, int mode)
/* F/w needs 1st task context memory entry for performance */
set_bit(QEDI_RESERVE_TASK_ID, qedi->task_idx_map);
atomic_set(&qedi->num_offloads, 0);
+
+ if (qedi_setup_boot_info(qedi))
+ QEDI_ERR(&qedi->dbg_ctx,
+ "No iSCSI boot target configured\n");
}
return 0;
diff --git a/drivers/scsi/qedi/qedi_nvm_iscsi_cfg.h b/drivers/scsi/qedi/qedi_nvm_iscsi_cfg.h
new file mode 100644
index 000000000000..df39b69b366d
--- /dev/null
+++ b/drivers/scsi/qedi/qedi_nvm_iscsi_cfg.h
@@ -0,0 +1,210 @@
+/*
+ * QLogic iSCSI Offload Driver
+ * Copyright (c) 2016 Cavium Inc.
+ *
+ * This software is available under the terms of the GNU General Public License
+ * (GPL) Version 2, available from the file COPYING in the main directory of
+ * this source tree.
+ */
+
+#ifndef NVM_ISCSI_CFG_H
+#define NVM_ISCSI_CFG_H
+
+#define NUM_OF_ISCSI_TARGET_PER_PF 4 /* Defined as per the
+ * ISCSI IBFT constraint
+ */
+#define NUM_OF_ISCSI_PF_SUPPORTED 4 /* One PF per Port -
+ * assuming 4 port card
+ */
+
+#define NVM_ISCSI_CFG_DHCP_NAME_MAX_LEN 256
+
+union nvm_iscsi_dhcp_vendor_id {
+ u32 value[NVM_ISCSI_CFG_DHCP_NAME_MAX_LEN / 4];
+ u8 byte[NVM_ISCSI_CFG_DHCP_NAME_MAX_LEN];
+};
+
+#define NVM_ISCSI_IPV4_ADDR_BYTE_LEN 4
+union nvm_iscsi_ipv4_addr {
+ u32 addr;
+ u8 byte[NVM_ISCSI_IPV4_ADDR_BYTE_LEN];
+};
+
+#define NVM_ISCSI_IPV6_ADDR_BYTE_LEN 16
+union nvm_iscsi_ipv6_addr {
+ u32 addr[4];
+ u8 byte[NVM_ISCSI_IPV6_ADDR_BYTE_LEN];
+};
+
+struct nvm_iscsi_initiator_ipv4 {
+ union nvm_iscsi_ipv4_addr addr; /* 0x0 */
+ union nvm_iscsi_ipv4_addr subnet_mask; /* 0x4 */
+ union nvm_iscsi_ipv4_addr gateway; /* 0x8 */
+ union nvm_iscsi_ipv4_addr primary_dns; /* 0xC */
+ union nvm_iscsi_ipv4_addr secondary_dns; /* 0x10 */
+ union nvm_iscsi_ipv4_addr dhcp_addr; /* 0x14 */
+
+ union nvm_iscsi_ipv4_addr isns_server; /* 0x18 */
+ union nvm_iscsi_ipv4_addr slp_server; /* 0x1C */
+ union nvm_iscsi_ipv4_addr primay_radius_server; /* 0x20 */
+ union nvm_iscsi_ipv4_addr secondary_radius_server; /* 0x24 */
+
+ union nvm_iscsi_ipv4_addr rsvd[4]; /* 0x28 */
+};
+
+struct nvm_iscsi_initiator_ipv6 {
+ union nvm_iscsi_ipv6_addr addr; /* 0x0 */
+ union nvm_iscsi_ipv6_addr subnet_mask; /* 0x10 */
+ union nvm_iscsi_ipv6_addr gateway; /* 0x20 */
+ union nvm_iscsi_ipv6_addr primary_dns; /* 0x30 */
+ union nvm_iscsi_ipv6_addr secondary_dns; /* 0x40 */
+ union nvm_iscsi_ipv6_addr dhcp_addr; /* 0x50 */
+
+ union nvm_iscsi_ipv6_addr isns_server; /* 0x60 */
+ union nvm_iscsi_ipv6_addr slp_server; /* 0x70 */
+ union nvm_iscsi_ipv6_addr primay_radius_server; /* 0x80 */
+ union nvm_iscsi_ipv6_addr secondary_radius_server; /* 0x90 */
+
+ union nvm_iscsi_ipv6_addr rsvd[3]; /* 0xA0 */
+
+ u32 config; /* 0xD0 */
+#define NVM_ISCSI_CFG_INITIATOR_IPV6_SUBNET_MASK_PREFIX_MASK 0x000000FF
+#define NVM_ISCSI_CFG_INITIATOR_IPV6_SUBNET_MASK_PREFIX_OFFSET 0
+
+ u32 rsvd_1[3];
+};
+
+#define NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN 256
+union nvm_iscsi_name {
+ u32 value[NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN / 4];
+ u8 byte[NVM_ISCSI_CFG_ISCSI_NAME_MAX_LEN];
+};
+
+#define NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN 256
+union nvm_iscsi_chap_name {
+ u32 value[NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN / 4];
+ u8 byte[NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN];
+};
+
+#define NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN 16 /* md5 need per RFC1996
+ * is 16 octets
+ */
+union nvm_iscsi_chap_password {
+ u32 value[NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN / 4];
+ u8 byte[NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN];
+};
+
+union nvm_iscsi_lun {
+ u8 byte[8];
+ u32 value[2];
+};
+
+struct nvm_iscsi_generic {
+ u32 ctrl_flags; /* 0x0 */
+#define NVM_ISCSI_CFG_GEN_CHAP_ENABLED BIT(0)
+#define NVM_ISCSI_CFG_GEN_DHCP_TCPIP_CONFIG_ENABLED BIT(1)
+#define NVM_ISCSI_CFG_GEN_DHCP_ISCSI_CONFIG_ENABLED BIT(2)
+#define NVM_ISCSI_CFG_GEN_IPV6_ENABLED BIT(3)
+#define NVM_ISCSI_CFG_GEN_IPV4_FALLBACK_ENABLED BIT(4)
+#define NVM_ISCSI_CFG_GEN_ISNS_WORLD_LOGIN BIT(5)
+#define NVM_ISCSI_CFG_GEN_ISNS_SELECTIVE_LOGIN BIT(6)
+#define NVM_ISCSI_CFG_GEN_ADDR_REDIRECT_ENABLED BIT(7)
+#define NVM_ISCSI_CFG_GEN_CHAP_MUTUAL_ENABLED BIT(8)
+
+ u32 timeout; /* 0x4 */
+#define NVM_ISCSI_CFG_GEN_DHCP_REQUEST_TIMEOUT_MASK 0x0000FFFF
+#define NVM_ISCSI_CFG_GEN_DHCP_REQUEST_TIMEOUT_OFFSET 0
+#define NVM_ISCSI_CFG_GEN_PORT_LOGIN_TIMEOUT_MASK 0xFFFF0000
+#define NVM_ISCSI_CFG_GEN_PORT_LOGIN_TIMEOUT_OFFSET 16
+
+ union nvm_iscsi_dhcp_vendor_id dhcp_vendor_id; /* 0x8 */
+ u32 rsvd[62]; /* 0x108 */
+};
+
+struct nvm_iscsi_initiator {
+ struct nvm_iscsi_initiator_ipv4 ipv4; /* 0x0 */
+ struct nvm_iscsi_initiator_ipv6 ipv6; /* 0x38 */
+
+ union nvm_iscsi_name initiator_name; /* 0x118 */
+ union nvm_iscsi_chap_name chap_name; /* 0x218 */
+ union nvm_iscsi_chap_password chap_password; /* 0x318 */
+
+ u32 generic_cont0; /* 0x398 */
+#define NVM_ISCSI_CFG_INITIATOR_VLAN_MASK 0x0000FFFF
+#define NVM_ISCSI_CFG_INITIATOR_VLAN_OFFSET 0
+#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_MASK 0x00030000
+#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_OFFSET 16
+#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_4 1
+#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_6 2
+#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_4_AND_6 3
+
+ u32 ctrl_flags;
+#define NVM_ISCSI_CFG_INITIATOR_IP_VERSION_PRIORITY_V6 BIT(0)
+#define NVM_ISCSI_CFG_INITIATOR_VLAN_ENABLED BIT(1)
+
+ u32 rsvd[116]; /* 0x32C */
+};
+
+struct nvm_iscsi_target {
+ u32 ctrl_flags; /* 0x0 */
+#define NVM_ISCSI_CFG_TARGET_ENABLED BIT(0)
+#define NVM_ISCSI_CFG_BOOT_TIME_LOGIN_STATUS BIT(1)
+
+ u32 generic_cont0; /* 0x4 */
+#define NVM_ISCSI_CFG_TARGET_TCP_PORT_MASK 0x0000FFFF
+#define NVM_ISCSI_CFG_TARGET_TCP_PORT_OFFSET 0
+
+ u32 ip_ver;
+#define NVM_ISCSI_CFG_IPv4 4
+#define NVM_ISCSI_CFG_IPv6 6
+
+ u32 rsvd_1[7]; /* 0x24 */
+ union nvm_iscsi_ipv4_addr ipv4_addr; /* 0x28 */
+ union nvm_iscsi_ipv6_addr ipv6_addr; /* 0x2C */
+ union nvm_iscsi_lun lun; /* 0x3C */
+
+ union nvm_iscsi_name target_name; /* 0x44 */
+ union nvm_iscsi_chap_name chap_name; /* 0x144 */
+ union nvm_iscsi_chap_password chap_password; /* 0x244 */
+
+ u32 rsvd_2[107]; /* 0x2C4 */
+};
+
+struct nvm_iscsi_block {
+ u32 id; /* 0x0 */
+#define NVM_ISCSI_CFG_BLK_MAPPED_PF_ID_MASK 0x0000000F
+#define NVM_ISCSI_CFG_BLK_MAPPED_PF_ID_OFFSET 0
+#define NVM_ISCSI_CFG_BLK_CTRL_FLAG_MASK 0x00000FF0
+#define NVM_ISCSI_CFG_BLK_CTRL_FLAG_OFFSET 4
+#define NVM_ISCSI_CFG_BLK_CTRL_FLAG_IS_NOT_EMPTY BIT(0)
+#define NVM_ISCSI_CFG_BLK_CTRL_FLAG_PF_MAPPED BIT(1)
+
+ u32 rsvd_1[5]; /* 0x4 */
+
+ struct nvm_iscsi_generic generic; /* 0x18 */
+ struct nvm_iscsi_initiator initiator; /* 0x218 */
+ struct nvm_iscsi_target target[NUM_OF_ISCSI_TARGET_PER_PF];
+ /* 0x718 */
+
+ u32 rsvd_2[58]; /* 0x1718 */
+ /* total size - 0x1800 - 6K block */
+};
+
+struct nvm_iscsi_cfg {
+ u32 id; /* 0x0 */
+#define NVM_ISCSI_CFG_BLK_VERSION_MINOR_MASK 0x000000FF
+#define NVM_ISCSI_CFG_BLK_VERSION_MAJOR_MASK 0x0000FF00
+#define NVM_ISCSI_CFG_BLK_SIGNATURE_MASK 0xFFFF0000
+#define NVM_ISCSI_CFG_BLK_SIGNATURE 0x49430000 /* IC - Iscsi
+ * Config
+ */
+
+#define NVM_ISCSI_CFG_BLK_VERSION_MAJOR 0
+#define NVM_ISCSI_CFG_BLK_VERSION_MINOR 10
+#define NVM_ISCSI_CFG_BLK_VERSION ((NVM_ISCSI_CFG_BLK_VERSION_MAJOR << 8) | \
+ NVM_ISCSI_CFG_BLK_VERSION_MINOR)
+
+ struct nvm_iscsi_block block[NUM_OF_ISCSI_PF_SUPPORTED]; /* 0x4 */
+};
+
+#endif
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index c2dc836dc484..e101cd3043b9 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -3727,7 +3727,7 @@ static struct qla_tgt_cmd *qlt_ctio_to_cmd(struct scsi_qla_host *vha,
h &= QLA_CMD_HANDLE_MASK;
if (h != QLA_TGT_NULL_HANDLE) {
- if (unlikely(h > req->num_outstanding_cmds)) {
+ if (unlikely(h >= req->num_outstanding_cmds)) {
ql_dbg(ql_dbg_tgt, vha, 0xe052,
"qla_target(%d): Wrong handle %x received\n",
vha->vp_idx, handle);
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index b20da0d27ad7..3f82ea1b72dc 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -500,7 +500,6 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
{
struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
- unsigned long flags;
/*
* Ensure that the complete FCP WRITE payload has been received.
@@ -508,17 +507,6 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
*/
cmd->cmd_in_wq = 0;
- spin_lock_irqsave(&cmd->cmd_lock, flags);
- cmd->data_work = 1;
- if (cmd->aborted) {
- cmd->data_work_free = 1;
- spin_unlock_irqrestore(&cmd->cmd_lock, flags);
-
- tcm_qla2xxx_free_cmd(cmd);
- return;
- }
- spin_unlock_irqrestore(&cmd->cmd_lock, flags);
-
cmd->qpair->tgt_counters.qla_core_ret_ctio++;
if (!cmd->write_data_transferred) {
/*
@@ -765,31 +753,13 @@ static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)
qlt_xmit_tm_rsp(mcmd);
}
-#define DATA_WORK_NOT_FREE(_cmd) (_cmd->data_work && !_cmd->data_work_free)
static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
{
struct qla_tgt_cmd *cmd = container_of(se_cmd,
struct qla_tgt_cmd, se_cmd);
- unsigned long flags;
if (qlt_abort_cmd(cmd))
return;
-
- spin_lock_irqsave(&cmd->cmd_lock, flags);
- if ((cmd->state == QLA_TGT_STATE_NEW)||
- ((cmd->state == QLA_TGT_STATE_DATA_IN) &&
- DATA_WORK_NOT_FREE(cmd))) {
- cmd->data_work_free = 1;
- spin_unlock_irqrestore(&cmd->cmd_lock, flags);
- /*
- * cmd has not reached fw, Use this trigger to free it.
- */
- tcm_qla2xxx_free_cmd(cmd);
- return;
- }
- spin_unlock_irqrestore(&cmd->cmd_lock, flags);
- return;
-
}
static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 7e24aa30c3b0..892fbd9800d9 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -1286,7 +1286,7 @@ store_fc_vport_delete(struct device *dev, struct device_attribute *attr,
unsigned long flags;
spin_lock_irqsave(shost->host_lock, flags);
- if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) {
+ if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING | FC_VPORT_DELETING)) {
spin_unlock_irqrestore(shost->host_lock, flags);
return -EBUSY;
}
@@ -2430,8 +2430,10 @@ fc_remove_host(struct Scsi_Host *shost)
spin_lock_irqsave(shost->host_lock, flags);
/* Remove any vports */
- list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers)
+ list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers) {
+ vport->flags |= FC_VPORT_DELETING;
fc_queue_work(shost, &vport->vport_delete_work);
+ }
/* Remove any remote ports */
list_for_each_entry_safe(rport, next_rport,
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 21225d62b0c1..d7ff71e0c85c 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -751,29 +751,6 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf,
return count;
}
-static bool sg_is_valid_dxfer(sg_io_hdr_t *hp)
-{
- switch (hp->dxfer_direction) {
- case SG_DXFER_NONE:
- if (hp->dxferp || hp->dxfer_len > 0)
- return false;
- return true;
- case SG_DXFER_TO_DEV:
- case SG_DXFER_FROM_DEV:
- case SG_DXFER_TO_FROM_DEV:
- if (!hp->dxferp || hp->dxfer_len == 0)
- return false;
- return true;
- case SG_DXFER_UNKNOWN:
- if ((!hp->dxferp && hp->dxfer_len) ||
- (hp->dxferp && hp->dxfer_len == 0))
- return false;
- return true;
- default:
- return false;
- }
-}
-
static int
sg_common_write(Sg_fd * sfp, Sg_request * srp,
unsigned char *cmnd, int timeout, int blocking)
@@ -794,7 +771,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
"sg_common_write: scsi opcode=0x%02x, cmd_size=%d\n",
(int) cmnd[0], (int) hp->cmd_len));
- if (!sg_is_valid_dxfer(hp))
+ if (hp->dxfer_len >= SZ_256M)
return -EINVAL;
k = sg_start_req(srp, cmnd);
diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index 07ec8a8877de..e164ffade38a 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -690,7 +690,7 @@ struct pqi_config_table_heartbeat {
#define PQI_MAX_OUTSTANDING_REQUESTS ((u32)~0)
#define PQI_MAX_OUTSTANDING_REQUESTS_KDUMP 32
-#define PQI_MAX_TRANSFER_SIZE (4 * 1024U * 1024U)
+#define PQI_MAX_TRANSFER_SIZE (1024U * 1024U)
#define PQI_MAX_TRANSFER_SIZE_KDUMP (512 * 1024U)
#define RAID_MAP_MAX_ENTRIES 1024
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index 8b93197daefe..9be211d68b15 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -837,6 +837,7 @@ static struct scsi_host_template virtscsi_host_template_multi = {
.eh_abort_handler = virtscsi_abort,
.eh_device_reset_handler = virtscsi_device_reset,
.eh_timed_out = virtscsi_eh_timed_out,
+ .slave_alloc = virtscsi_device_alloc,
.can_queue = 1024,
.dma_boundary = UINT_MAX,
diff --git a/drivers/soc/zte/Kconfig b/drivers/soc/zte/Kconfig
index 20bde38ce2f9..e9d750c510cd 100644
--- a/drivers/soc/zte/Kconfig
+++ b/drivers/soc/zte/Kconfig
@@ -2,6 +2,7 @@
# ZTE SoC drivers
#
menuconfig SOC_ZTE
+ depends on ARCH_ZX || COMPILE_TEST
bool "ZTE SoC driver support"
if SOC_ZTE
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 2afe3597982e..f4b7a98a7913 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -134,7 +134,6 @@ struct apid_data {
* @spmic: SPMI controller object
* @ver_ops: version dependent operations.
* @ppid_to_apid in-memory copy of PPID -> channel (APID) mapping table.
- * v2 only.
*/
struct spmi_pmic_arb {
void __iomem *rd_base;
@@ -1016,6 +1015,13 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
goto err_put_ctrl;
}
+ pa->ppid_to_apid = devm_kcalloc(&ctrl->dev, PMIC_ARB_MAX_PPID,
+ sizeof(*pa->ppid_to_apid), GFP_KERNEL);
+ if (!pa->ppid_to_apid) {
+ err = -ENOMEM;
+ goto err_put_ctrl;
+ }
+
hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
if (hw_ver < PMIC_ARB_VERSION_V2_MIN) {
@@ -1048,15 +1054,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
err = PTR_ERR(pa->wr_base);
goto err_put_ctrl;
}
-
- pa->ppid_to_apid = devm_kcalloc(&ctrl->dev,
- PMIC_ARB_MAX_PPID,
- sizeof(*pa->ppid_to_apid),
- GFP_KERNEL);
- if (!pa->ppid_to_apid) {
- err = -ENOMEM;
- goto err_put_ctrl;
- }
}
dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index 2b9b0941d9eb..6d23226e5f69 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -365,11 +365,23 @@ static int spmi_drv_remove(struct device *dev)
return 0;
}
+static int spmi_drv_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ int ret;
+
+ ret = of_device_uevent_modalias(dev, env);
+ if (ret != -ENODEV)
+ return ret;
+
+ return 0;
+}
+
static struct bus_type spmi_bus_type = {
.name = "spmi",
.match = spmi_device_match,
.probe = spmi_drv_probe,
.remove = spmi_drv_remove,
+ .uevent = spmi_drv_uevent,
};
/**
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 268d4e6ef48a..ef28a1cb64ae 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -110,4 +110,6 @@ source "drivers/staging/ccree/Kconfig"
source "drivers/staging/typec/Kconfig"
+source "drivers/staging/vboxvideo/Kconfig"
+
endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index b93e6f5f0f6e..2918580bdb9e 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -44,3 +44,4 @@ obj-$(CONFIG_KS7010) += ks7010/
obj-$(CONFIG_GREYBUS) += greybus/
obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/
obj-$(CONFIG_CRYPTO_DEV_CCREE) += ccree/
+obj-$(CONFIG_DRM_VBOXVIDEO) += vboxvideo/
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index ca11be21f64b..34ca7823255d 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -2396,6 +2396,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
continue;
}
+ set_current_state(TASK_RUNNING);
wp = async->buf_write_ptr;
n1 = min(n, async->prealloc_bufsz - wp);
n2 = n - n1;
@@ -2528,6 +2529,8 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
}
continue;
}
+
+ set_current_state(TASK_RUNNING);
rp = async->buf_read_ptr;
n1 = min(n, async->prealloc_bufsz - rp);
n2 = n - n1;
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
index b2e382888981..2f7bfc1c59e5 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -3116,8 +3116,7 @@ static void ni_ao_cmd_set_update(struct comedi_device *dev,
/* following line: 2-1 per STC */
ni_stc_writel(dev, 1, NISTC_AO_UI_LOADA_REG);
ni_stc_writew(dev, NISTC_AO_CMD1_UI_LOAD, NISTC_AO_CMD1_REG);
- /* following line: N-1 per STC */
- ni_stc_writel(dev, trigvar - 1, NISTC_AO_UI_LOADA_REG);
+ ni_stc_writel(dev, trigvar, NISTC_AO_UI_LOADA_REG);
} else { /* TRIG_EXT */
/* FIXME: assert scan_begin_arg != 0, ret failure otherwise */
devpriv->ao_cmd2 |= NISTC_AO_CMD2_BC_GATE_ENA;
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index a6a8393d6664..3e00df74b18c 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -472,7 +472,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
long m)
{
struct ad2s1210_state *st = iio_priv(indio_dev);
- bool negative;
+ u16 negative;
int ret = 0;
u16 pos;
s16 vel;
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
index 85b242ec5f9b..8fc191d99927 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
@@ -1640,8 +1640,13 @@ kiblnd_send(struct lnet_ni *ni, void *private, struct lnet_msg *lntmsg)
ibmsg = tx->tx_msg;
ibmsg->ibm_u.immediate.ibim_hdr = *hdr;
- copy_from_iter(&ibmsg->ibm_u.immediate.ibim_payload, IBLND_MSG_SIZE,
- &from);
+ rc = copy_from_iter(&ibmsg->ibm_u.immediate.ibim_payload, payload_nob,
+ &from);
+ if (rc != payload_nob) {
+ kiblnd_pool_free_node(&tx->tx_pool->tpo_pool, &tx->tx_list);
+ return -EFAULT;
+ }
+
nob = offsetof(struct kib_immediate_msg, ibim_payload[payload_nob]);
kiblnd_init_tx_msg(ni, tx, IBLND_MSG_IMMEDIATE, nob);
@@ -1741,8 +1746,14 @@ kiblnd_recv(struct lnet_ni *ni, void *private, struct lnet_msg *lntmsg,
break;
}
- copy_to_iter(&rxmsg->ibm_u.immediate.ibim_payload,
- IBLND_MSG_SIZE, to);
+ rc = copy_to_iter(&rxmsg->ibm_u.immediate.ibim_payload, rlen,
+ to);
+ if (rc != rlen) {
+ rc = -EFAULT;
+ break;
+ }
+
+ rc = 0;
lnet_finalize(ni, lntmsg, 0);
break;
diff --git a/drivers/staging/media/atomisp/i2c/ap1302.h b/drivers/staging/media/atomisp/i2c/ap1302.h
index 9341232c580d..4d0b181a9671 100644
--- a/drivers/staging/media/atomisp/i2c/ap1302.h
+++ b/drivers/staging/media/atomisp/i2c/ap1302.h
@@ -158,8 +158,8 @@ struct ap1302_res_struct {
};
struct ap1302_context_res {
- s32 res_num;
- s32 cur_res;
+ u32 res_num;
+ u32 cur_res;
struct ap1302_res_struct *res_table;
};
diff --git a/drivers/staging/media/atomisp/i2c/gc0310.h b/drivers/staging/media/atomisp/i2c/gc0310.h
index f31eb277f542..7d8a0aeecb6c 100644
--- a/drivers/staging/media/atomisp/i2c/gc0310.h
+++ b/drivers/staging/media/atomisp/i2c/gc0310.h
@@ -454,6 +454,6 @@ struct gc0310_resolution gc0310_res_video[] = {
#define N_RES_VIDEO (ARRAY_SIZE(gc0310_res_video))
static struct gc0310_resolution *gc0310_res = gc0310_res_preview;
-static int N_RES = N_RES_PREVIEW;
+static unsigned long N_RES = N_RES_PREVIEW;
#endif
diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h b/drivers/staging/media/atomisp/i2c/gc2235.h
index ccbc757045a5..7c3d994180cc 100644
--- a/drivers/staging/media/atomisp/i2c/gc2235.h
+++ b/drivers/staging/media/atomisp/i2c/gc2235.h
@@ -668,5 +668,5 @@ struct gc2235_resolution gc2235_res_video[] = {
#define N_RES_VIDEO (ARRAY_SIZE(gc2235_res_video))
static struct gc2235_resolution *gc2235_res = gc2235_res_preview;
-static int N_RES = N_RES_PREVIEW;
+static unsigned long N_RES = N_RES_PREVIEW;
#endif
diff --git a/drivers/staging/media/atomisp/i2c/imx/imx.h b/drivers/staging/media/atomisp/i2c/imx/imx.h
index 36b3f3a5a41f..41b4133ca995 100644
--- a/drivers/staging/media/atomisp/i2c/imx/imx.h
+++ b/drivers/staging/media/atomisp/i2c/imx/imx.h
@@ -480,7 +480,7 @@ struct imx_device {
struct imx_vcm *vcm_driver;
struct imx_otp *otp_driver;
const struct imx_resolution *curr_res_table;
- int entries_curr_table;
+ unsigned long entries_curr_table;
const struct firmware *fw;
struct imx_reg_addr *reg_addr;
const struct imx_reg *param_hold;
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index 944fe8e3bcbf..ab8907e6c9ef 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -934,7 +934,6 @@ static struct ov2680_resolution ov2680_res_video[] = {
#define N_RES_VIDEO (ARRAY_SIZE(ov2680_res_video))
static struct ov2680_resolution *ov2680_res = ov2680_res_preview;
-static int N_RES = N_RES_PREVIEW;
-
+static unsigned long N_RES = N_RES_PREVIEW;
#endif
diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h b/drivers/staging/media/atomisp/i2c/ov2722.h
index b0d40965d89e..73ecb1679718 100644
--- a/drivers/staging/media/atomisp/i2c/ov2722.h
+++ b/drivers/staging/media/atomisp/i2c/ov2722.h
@@ -1263,5 +1263,5 @@ struct ov2722_resolution ov2722_res_video[] = {
#define N_RES_VIDEO (ARRAY_SIZE(ov2722_res_video))
static struct ov2722_resolution *ov2722_res = ov2722_res_preview;
-static int N_RES = N_RES_PREVIEW;
+static unsigned long N_RES = N_RES_PREVIEW;
#endif
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
index d88ac1777d86..8c2e6794463b 100644
--- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
+++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
@@ -1377,5 +1377,5 @@ struct ov5693_resolution ov5693_res_video[] = {
#define N_RES_VIDEO (ARRAY_SIZE(ov5693_res_video))
static struct ov5693_resolution *ov5693_res = ov5693_res_preview;
-static int N_RES = N_RES_PREVIEW;
+static unsigned long N_RES = N_RES_PREVIEW;
#endif
diff --git a/drivers/staging/media/atomisp/i2c/ov8858.h b/drivers/staging/media/atomisp/i2c/ov8858.h
index 9be6a0e63861..d3fde200c013 100644
--- a/drivers/staging/media/atomisp/i2c/ov8858.h
+++ b/drivers/staging/media/atomisp/i2c/ov8858.h
@@ -266,7 +266,7 @@ struct ov8858_device {
const struct ov8858_reg *regs;
struct ov8858_vcm *vcm_driver;
const struct ov8858_resolution *curr_res_table;
- int entries_curr_table;
+ unsigned long entries_curr_table;
struct v4l2_ctrl_handler ctrl_handler;
struct v4l2_ctrl *run_mode;
diff --git a/drivers/staging/media/atomisp/i2c/ov8858_btns.h b/drivers/staging/media/atomisp/i2c/ov8858_btns.h
index 09e3cdc1a394..f9a3cf8fbf1a 100644
--- a/drivers/staging/media/atomisp/i2c/ov8858_btns.h
+++ b/drivers/staging/media/atomisp/i2c/ov8858_btns.h
@@ -266,7 +266,7 @@ struct ov8858_device {
const struct ov8858_reg *regs;
struct ov8858_vcm *vcm_driver;
const struct ov8858_resolution *curr_res_table;
- int entries_curr_table;
+ unsigned long entries_curr_table;
struct v4l2_ctrl_handler ctrl_handler;
struct v4l2_ctrl *run_mode;
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/Makefile b/drivers/staging/media/atomisp/pci/atomisp2/Makefile
index 726eaa293c55..2bd98f0667ec 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/Makefile
+++ b/drivers/staging/media/atomisp/pci/atomisp2/Makefile
@@ -354,7 +354,9 @@ ccflags-y += $(INCLUDES) $(DEFINES) -fno-common
# HACK! While this driver is in bad shape, don't enable several warnings
# that would be otherwise enabled with W=1
-ccflags-y += -Wno-unused-const-variable -Wno-missing-prototypes \
- -Wno-unused-but-set-variable -Wno-missing-declarations \
- -Wno-suggest-attribute=format -Wno-missing-prototypes \
- -Wno-implicit-fallthrough
+ccflags-y += $(call cc-disable-warning, implicit-fallthrough)
+ccflags-y += $(call cc-disable-warning, missing-prototypes)
+ccflags-y += $(call cc-disable-warning, missing-declarations)
+ccflags-y += $(call cc-disable-warning, suggest-attribute=format)
+ccflags-y += $(call cc-disable-warning, unused-const-variable)
+ccflags-y += $(call cc-disable-warning, unused-but-set-variable)
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h
index d3667132851b..c8e0c4fe3717 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h
@@ -275,7 +275,7 @@ struct atomisp_device {
*/
struct mutex streamoff_mutex;
- int input_cnt;
+ unsigned int input_cnt;
struct atomisp_input_subdev inputs[ATOM_ISP_MAX_INPUTS];
struct v4l2_subdev *flash;
struct v4l2_subdev *motor;
diff --git a/drivers/staging/media/cxd2099/cxd2099.c b/drivers/staging/media/cxd2099/cxd2099.c
index 370ecb959543..f28916ea69f1 100644
--- a/drivers/staging/media/cxd2099/cxd2099.c
+++ b/drivers/staging/media/cxd2099/cxd2099.c
@@ -1,7 +1,7 @@
/*
* cxd2099.c: Driver for the CXD2099AR Common Interface Controller
*
- * Copyright (C) 2010-2011 Digital Devices GmbH
+ * Copyright (C) 2010-2013 Digital Devices GmbH
*
*
* This program is free software; you can redistribute it and/or
@@ -33,7 +33,10 @@
#include "cxd2099.h"
-#define MAX_BUFFER_SIZE 248
+/* comment this line to deactivate the cxd2099ar buffer mode */
+#define BUFFER_MODE 1
+
+static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount);
struct cxd {
struct dvb_ca_en50221 en;
@@ -48,6 +51,7 @@ struct cxd {
int mode;
int ready;
int dr;
+ int write_busy;
int slot_stat;
u8 amem[1024];
@@ -55,6 +59,9 @@ struct cxd {
int cammode;
struct mutex lock;
+
+ u8 rbuf[1028];
+ u8 wbuf[1028];
};
static int i2c_write_reg(struct i2c_adapter *adapter, u8 adr,
@@ -73,7 +80,7 @@ static int i2c_write_reg(struct i2c_adapter *adapter, u8 adr,
}
static int i2c_write(struct i2c_adapter *adapter, u8 adr,
- u8 *data, u8 len)
+ u8 *data, u16 len)
{
struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = data, .len = len};
@@ -100,12 +107,12 @@ static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr,
}
static int i2c_read(struct i2c_adapter *adapter, u8 adr,
- u8 reg, u8 *data, u8 n)
+ u8 reg, u8 *data, u16 n)
{
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
- .buf = &reg, .len = 1},
- {.addr = adr, .flags = I2C_M_RD,
- .buf = data, .len = n} };
+ .buf = &reg, .len = 1},
+ {.addr = adr, .flags = I2C_M_RD,
+ .buf = data, .len = n} };
if (i2c_transfer(adapter, msgs, 2) != 2) {
dev_err(&adapter->dev, "error in i2c_read\n");
@@ -114,14 +121,26 @@ static int i2c_read(struct i2c_adapter *adapter, u8 adr,
return 0;
}
-static int read_block(struct cxd *ci, u8 adr, u8 *data, u8 n)
+static int read_block(struct cxd *ci, u8 adr, u8 *data, u16 n)
{
- int status;
+ int status = 0;
- status = i2c_write_reg(ci->i2c, ci->cfg.adr, 0, adr);
+ if (ci->lastaddress != adr)
+ status = i2c_write_reg(ci->i2c, ci->cfg.adr, 0, adr);
if (!status) {
ci->lastaddress = adr;
- status = i2c_read(ci->i2c, ci->cfg.adr, 1, data, n);
+
+ while (n) {
+ int len = n;
+
+ if (ci->cfg.max_i2c && (len > ci->cfg.max_i2c))
+ len = ci->cfg.max_i2c;
+ status = i2c_read(ci->i2c, ci->cfg.adr, 1, data, len);
+ if (status)
+ return status;
+ data += len;
+ n -= len;
+ }
}
return status;
}
@@ -182,16 +201,16 @@ static int write_io(struct cxd *ci, u16 address, u8 val)
static int write_regm(struct cxd *ci, u8 reg, u8 val, u8 mask)
{
- int status;
+ int status = 0;
- status = i2c_write_reg(ci->i2c, ci->cfg.adr, 0, reg);
+ if (ci->lastaddress != reg)
+ status = i2c_write_reg(ci->i2c, ci->cfg.adr, 0, reg);
if (!status && reg >= 6 && reg <= 8 && mask != 0xff)
status = i2c_read_reg(ci->i2c, ci->cfg.adr, 1, &ci->regs[reg]);
+ ci->lastaddress = reg;
ci->regs[reg] = (ci->regs[reg] & (~mask)) | val;
- if (!status) {
- ci->lastaddress = reg;
+ if (!status)
status = i2c_write_reg(ci->i2c, ci->cfg.adr, 1, ci->regs[reg]);
- }
if (reg == 0x20)
ci->regs[reg] &= 0x7f;
return status;
@@ -203,16 +222,29 @@ static int write_reg(struct cxd *ci, u8 reg, u8 val)
}
#ifdef BUFFER_MODE
-static int write_block(struct cxd *ci, u8 adr, u8 *data, int n)
+static int write_block(struct cxd *ci, u8 adr, u8 *data, u16 n)
{
- int status;
- u8 buf[256] = {1};
-
- status = i2c_write_reg(ci->i2c, ci->cfg.adr, 0, adr);
- if (!status) {
- ci->lastaddress = adr;
- memcpy(buf + 1, data, n);
- status = i2c_write(ci->i2c, ci->cfg.adr, buf, n + 1);
+ int status = 0;
+ u8 *buf = ci->wbuf;
+
+ if (ci->lastaddress != adr)
+ status = i2c_write_reg(ci->i2c, ci->cfg.adr, 0, adr);
+ if (status)
+ return status;
+
+ ci->lastaddress = adr;
+ buf[0] = 1;
+ while (n) {
+ int len = n;
+
+ if (ci->cfg.max_i2c && (len + 1 > ci->cfg.max_i2c))
+ len = ci->cfg.max_i2c - 1;
+ memcpy(buf + 1, data, len);
+ status = i2c_write(ci->i2c, ci->cfg.adr, buf, len + 1);
+ if (status)
+ return status;
+ n -= len;
+ data += len;
}
return status;
}
@@ -238,6 +270,8 @@ static void set_mode(struct cxd *ci, int mode)
static void cam_mode(struct cxd *ci, int mode)
{
+ u8 dummy;
+
if (mode == ci->cammode)
return;
@@ -246,16 +280,15 @@ static void cam_mode(struct cxd *ci, int mode)
write_regm(ci, 0x20, 0x80, 0x80);
break;
case 0x01:
-#ifdef BUFFER_MODE
if (!ci->en.read_data)
return;
+ ci->write_busy = 0;
dev_info(&ci->i2c->dev, "enable cam buffer mode\n");
- /* write_reg(ci, 0x0d, 0x00); */
- /* write_reg(ci, 0x0e, 0x01); */
+ write_reg(ci, 0x0d, 0x00);
+ write_reg(ci, 0x0e, 0x01);
write_regm(ci, 0x08, 0x40, 0x40);
- /* read_reg(ci, 0x12, &dummy); */
+ read_reg(ci, 0x12, &dummy);
write_regm(ci, 0x08, 0x80, 0x80);
-#endif
break;
default:
break;
@@ -325,7 +358,10 @@ static int init(struct cxd *ci)
if (status < 0)
break;
- if (ci->cfg.clock_mode) {
+ if (ci->cfg.clock_mode == 2) {
+ /* bitrate*2^13/ 72000 */
+ u32 reg = ((ci->cfg.bitrate << 13) + 71999) / 72000;
+
if (ci->cfg.polarity) {
status = write_reg(ci, 0x09, 0x6f);
if (status < 0)
@@ -335,6 +371,25 @@ static int init(struct cxd *ci)
if (status < 0)
break;
}
+ status = write_reg(ci, 0x20, 0x08);
+ if (status < 0)
+ break;
+ status = write_reg(ci, 0x21, (reg >> 8) & 0xff);
+ if (status < 0)
+ break;
+ status = write_reg(ci, 0x22, reg & 0xff);
+ if (status < 0)
+ break;
+ } else if (ci->cfg.clock_mode == 1) {
+ if (ci->cfg.polarity) {
+ status = write_reg(ci, 0x09, 0x6f); /* D */
+ if (status < 0)
+ break;
+ } else {
+ status = write_reg(ci, 0x09, 0x6d);
+ if (status < 0)
+ break;
+ }
status = write_reg(ci, 0x20, 0x68);
if (status < 0)
break;
@@ -346,7 +401,7 @@ static int init(struct cxd *ci)
break;
} else {
if (ci->cfg.polarity) {
- status = write_reg(ci, 0x09, 0x4f);
+ status = write_reg(ci, 0x09, 0x4f); /* C */
if (status < 0)
break;
} else {
@@ -354,7 +409,6 @@ static int init(struct cxd *ci)
if (status < 0)
break;
}
-
status = write_reg(ci, 0x20, 0x28);
if (status < 0)
break;
@@ -401,7 +455,6 @@ static int read_attribute_mem(struct dvb_ca_en50221 *ca,
set_mode(ci, 1);
read_pccard(ci, address, &val, 1);
mutex_unlock(&ci->lock);
- /* printk(KERN_INFO "%02x:%02x\n", address,val); */
return val;
}
@@ -446,6 +499,9 @@ static int slot_reset(struct dvb_ca_en50221 *ca, int slot)
{
struct cxd *ci = ca->data;
+ if (ci->cammode)
+ read_data(ca, slot, ci->rbuf, 0);
+
mutex_lock(&ci->lock);
cam_mode(ci, 0);
write_reg(ci, 0x00, 0x21);
@@ -465,7 +521,6 @@ static int slot_reset(struct dvb_ca_en50221 *ca, int slot)
}
}
mutex_unlock(&ci->lock);
- /* msleep(500); */
return 0;
}
@@ -474,11 +529,19 @@ static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
struct cxd *ci = ca->data;
dev_info(&ci->i2c->dev, "%s\n", __func__);
+ if (ci->cammode)
+ read_data(ca, slot, ci->rbuf, 0);
mutex_lock(&ci->lock);
+ write_reg(ci, 0x00, 0x21);
+ write_reg(ci, 0x06, 0x1F);
+ msleep(300);
+
write_regm(ci, 0x09, 0x08, 0x08);
write_regm(ci, 0x20, 0x80, 0x80); /* Reset CAM Mode */
write_regm(ci, 0x06, 0x07, 0x07); /* Clear IO Mode */
+
ci->mode = -1;
+ ci->write_busy = 0;
mutex_unlock(&ci->lock);
return 0;
}
@@ -490,9 +553,7 @@ static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
mutex_lock(&ci->lock);
write_regm(ci, 0x09, 0x00, 0x08);
set_mode(ci, 0);
-#ifdef BUFFER_MODE
cam_mode(ci, 1);
-#endif
mutex_unlock(&ci->lock);
return 0;
}
@@ -506,12 +567,10 @@ static int campoll(struct cxd *ci)
return 0;
write_reg(ci, 0x05, istat);
- if (istat & 0x40) {
+ if (istat & 0x40)
ci->dr = 1;
- dev_info(&ci->i2c->dev, "DR\n");
- }
if (istat & 0x20)
- dev_info(&ci->i2c->dev, "WC\n");
+ ci->write_busy = 0;
if (istat & 2) {
u8 slotstat;
@@ -519,7 +578,8 @@ static int campoll(struct cxd *ci)
read_reg(ci, 0x01, &slotstat);
if (!(2 & slotstat)) {
if (!ci->slot_stat) {
- ci->slot_stat = DVB_CA_EN50221_POLL_CAM_PRESENT;
+ ci->slot_stat |=
+ DVB_CA_EN50221_POLL_CAM_PRESENT;
write_regm(ci, 0x03, 0x08, 0x08);
}
@@ -531,8 +591,8 @@ static int campoll(struct cxd *ci)
ci->ready = 0;
}
}
- if (istat & 8 &&
- ci->slot_stat == DVB_CA_EN50221_POLL_CAM_PRESENT) {
+ if ((istat & 8) &&
+ (ci->slot_stat == DVB_CA_EN50221_POLL_CAM_PRESENT)) {
ci->ready = 1;
ci->slot_stat |= DVB_CA_EN50221_POLL_CAM_READY;
}
@@ -553,7 +613,6 @@ static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
return ci->slot_stat;
}
-#ifdef BUFFER_MODE
static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
{
struct cxd *ci = ca->data;
@@ -564,30 +623,38 @@ static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
campoll(ci);
mutex_unlock(&ci->lock);
- dev_info(&ci->i2c->dev, "%s\n", __func__);
if (!ci->dr)
return 0;
mutex_lock(&ci->lock);
read_reg(ci, 0x0f, &msb);
read_reg(ci, 0x10, &lsb);
- len = (msb << 8) | lsb;
+ len = ((u16)msb << 8) | lsb;
+ if (len > ecount || len < 2) {
+ /* read it anyway or cxd may hang */
+ read_block(ci, 0x12, ci->rbuf, len);
+ mutex_unlock(&ci->lock);
+ return -EIO;
+ }
read_block(ci, 0x12, ebuf, len);
ci->dr = 0;
mutex_unlock(&ci->lock);
-
return len;
}
+#ifdef BUFFER_MODE
+
static int write_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
{
struct cxd *ci = ca->data;
+ if (ci->write_busy)
+ return -EAGAIN;
mutex_lock(&ci->lock);
- dev_info(&ci->i2c->dev, "%s %d\n", __func__, ecount);
write_reg(ci, 0x0d, ecount >> 8);
write_reg(ci, 0x0e, ecount & 0xff);
write_block(ci, 0x11, ebuf, ecount);
+ ci->write_busy = 1;
mutex_unlock(&ci->lock);
return ecount;
}
diff --git a/drivers/staging/media/cxd2099/cxd2099.h b/drivers/staging/media/cxd2099/cxd2099.h
index 0eb607c5b423..f4b29b1d6eb8 100644
--- a/drivers/staging/media/cxd2099/cxd2099.h
+++ b/drivers/staging/media/cxd2099/cxd2099.h
@@ -30,8 +30,10 @@
struct cxd2099_cfg {
u32 bitrate;
u8 adr;
- u8 polarity:1;
- u8 clock_mode:1;
+ u8 polarity;
+ u8 clock_mode;
+
+ u32 max_i2c;
};
#if defined(CONFIG_DVB_CXD2099) || \
diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c
index 002d09159896..a69007ef77bf 100644
--- a/drivers/staging/rtl8188eu/core/rtw_cmd.c
+++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c
@@ -132,7 +132,7 @@ void rtw_free_cmd_obj(struct cmd_obj *pcmd)
kfree(pcmd->parmbuf);
}
- if (!pcmd->rsp) {
+ if (pcmd->rsp) {
if (pcmd->rspsz != 0) {
/* free rsp in cmd_obj */
kfree(pcmd->rsp);
diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c
index 963235fd7292..d283341cfe43 100644
--- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c
+++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c
@@ -43,6 +43,7 @@ static struct usb_device_id rtw_usb_id_tbl[] = {
{USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */
{USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */
{USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */
+ {USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */
{USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */
{} /* Terminating entry */
};
diff --git a/drivers/staging/sm750fb/ddk750_chip.c b/drivers/staging/sm750fb/ddk750_chip.c
index 944dd25924be..4754f7a20684 100644
--- a/drivers/staging/sm750fb/ddk750_chip.c
+++ b/drivers/staging/sm750fb/ddk750_chip.c
@@ -40,7 +40,7 @@ static unsigned int get_mxclk_freq(void)
pll_reg = peek32(MXCLK_PLL_CTRL);
M = (pll_reg & PLL_CTRL_M_MASK) >> PLL_CTRL_M_SHIFT;
- N = (pll_reg & PLL_CTRL_N_MASK) >> PLL_CTRL_M_SHIFT;
+ N = (pll_reg & PLL_CTRL_N_MASK) >> PLL_CTRL_N_SHIFT;
OD = (pll_reg & PLL_CTRL_OD_MASK) >> PLL_CTRL_OD_SHIFT;
POD = (pll_reg & PLL_CTRL_POD_MASK) >> PLL_CTRL_POD_SHIFT;
diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index 3aa4128703d5..67207b0554cd 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -1053,6 +1053,26 @@ release_fb:
return err;
}
+static int lynxfb_kick_out_firmware_fb(struct pci_dev *pdev)
+{
+ struct apertures_struct *ap;
+ bool primary = false;
+
+ ap = alloc_apertures(1);
+ if (!ap)
+ return -ENOMEM;
+
+ ap->ranges[0].base = pci_resource_start(pdev, 0);
+ ap->ranges[0].size = pci_resource_len(pdev, 0);
+#ifdef CONFIG_X86
+ primary = pdev->resource[PCI_ROM_RESOURCE].flags &
+ IORESOURCE_ROM_SHADOW;
+#endif
+ remove_conflicting_framebuffers(ap, "sm750_fb1", primary);
+ kfree(ap);
+ return 0;
+}
+
static int lynxfb_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -1061,6 +1081,10 @@ static int lynxfb_pci_probe(struct pci_dev *pdev,
int fbidx;
int err;
+ err = lynxfb_kick_out_firmware_fb(pdev);
+ if (err)
+ return err;
+
/* enable device */
err = pcim_enable_device(pdev);
if (err)
diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c
index 82e5de248947..67956e24779c 100644
--- a/drivers/staging/speakup/main.c
+++ b/drivers/staging/speakup/main.c
@@ -2314,6 +2314,7 @@ static void __exit speakup_exit(void)
mutex_lock(&spk_mutex);
synth_release();
mutex_unlock(&spk_mutex);
+ spk_ttyio_unregister_ldisc();
speakup_kobj_exit();
@@ -2376,6 +2377,7 @@ static int __init speakup_init(void)
if (err)
goto error_kobjects;
+ spk_ttyio_register_ldisc();
synth_init(synth_name);
speakup_register_devsynth();
/*
diff --git a/drivers/staging/speakup/spk_priv.h b/drivers/staging/speakup/spk_priv.h
index 87b6a0a4c54d..046040ac074c 100644
--- a/drivers/staging/speakup/spk_priv.h
+++ b/drivers/staging/speakup/spk_priv.h
@@ -48,6 +48,8 @@ void spk_stop_serial_interrupt(void);
int spk_wait_for_xmitr(struct spk_synth *in_synth);
void spk_serial_release(void);
void spk_ttyio_release(void);
+void spk_ttyio_register_ldisc(void);
+void spk_ttyio_unregister_ldisc(void);
void synth_buffer_skip_nonlatin1(void);
u16 synth_buffer_getc(void);
diff --git a/drivers/staging/speakup/spk_ttyio.c b/drivers/staging/speakup/spk_ttyio.c
index ed8e96b06ead..fe340b07c482 100644
--- a/drivers/staging/speakup/spk_ttyio.c
+++ b/drivers/staging/speakup/spk_ttyio.c
@@ -154,12 +154,6 @@ static int spk_ttyio_initialise_ldisc(struct spk_synth *synth)
struct ktermios tmp_termios;
dev_t dev;
- ret = tty_register_ldisc(N_SPEAKUP, &spk_ttyio_ldisc_ops);
- if (ret) {
- pr_err("Error registering line discipline.\n");
- return ret;
- }
-
ret = get_dev_to_use(synth, &dev);
if (ret)
return ret;
@@ -196,10 +190,24 @@ static int spk_ttyio_initialise_ldisc(struct spk_synth *synth)
tty_unlock(tty);
ret = tty_set_ldisc(tty, N_SPEAKUP);
+ if (ret)
+ pr_err("speakup: Failed to set N_SPEAKUP on tty\n");
return ret;
}
+void spk_ttyio_register_ldisc(void)
+{
+ if (tty_register_ldisc(N_SPEAKUP, &spk_ttyio_ldisc_ops))
+ pr_warn("speakup: Error registering line discipline. Most synths won't work.\n");
+}
+
+void spk_ttyio_unregister_ldisc(void)
+{
+ if (tty_unregister_ldisc(N_SPEAKUP))
+ pr_warn("speakup: Couldn't unregister ldisc\n");
+}
+
static int spk_ttyio_out(struct spk_synth *in_synth, const char ch)
{
if (in_synth->alive && speakup_tty && speakup_tty->ops->write) {
@@ -300,7 +308,7 @@ void spk_ttyio_release(void)
tty_ldisc_flush(speakup_tty);
tty_unlock(speakup_tty);
- tty_ldisc_release(speakup_tty);
+ tty_release_struct(speakup_tty, speakup_tty->index);
}
EXPORT_SYMBOL_GPL(spk_ttyio_release);
diff --git a/drivers/staging/vboxvideo/Kconfig b/drivers/staging/vboxvideo/Kconfig
new file mode 100644
index 000000000000..a52746f9a670
--- /dev/null
+++ b/drivers/staging/vboxvideo/Kconfig
@@ -0,0 +1,12 @@
+config DRM_VBOXVIDEO
+ tristate "Virtual Box Graphics Card"
+ depends on DRM && X86 && PCI
+ select DRM_KMS_HELPER
+ help
+ This is a KMS driver for the virtual Graphics Card used in
+ Virtual Box virtual machines.
+
+ Although it is possible to builtin this module, it is advised
+ to build this driver as a module, so that it can be updated
+ independently of the kernel. Select M to built this driver as a
+ module and add support for these devices via drm/kms interfaces.
diff --git a/drivers/staging/vboxvideo/Makefile b/drivers/staging/vboxvideo/Makefile
new file mode 100644
index 000000000000..2d0b3bc7ad73
--- /dev/null
+++ b/drivers/staging/vboxvideo/Makefile
@@ -0,0 +1,7 @@
+ccflags-y := -Iinclude/drm
+
+vboxvideo-y := hgsmi_base.o modesetting.o vbva_base.o \
+ vbox_drv.o vbox_fb.o vbox_hgsmi.o vbox_irq.o vbox_main.o \
+ vbox_mode.o vbox_prime.o vbox_ttm.o
+
+obj-$(CONFIG_DRM_VBOXVIDEO) += vboxvideo.o
diff --git a/drivers/staging/vboxvideo/TODO b/drivers/staging/vboxvideo/TODO
new file mode 100644
index 000000000000..ce764309b079
--- /dev/null
+++ b/drivers/staging/vboxvideo/TODO
@@ -0,0 +1,9 @@
+TODO:
+-Move the driver over to the atomic API
+-Stop using old load / unload drm_driver hooks
+-Get a full review from the drm-maintainers on dri-devel done on this driver
+-Extend this TODO with the results of that review
+
+Please send any patches to Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
+Hans de Goede <hdegoede@redhat.com> and
+Michael Thayer <michael.thayer@oracle.com>.
diff --git a/drivers/staging/vboxvideo/hgsmi_base.c b/drivers/staging/vboxvideo/hgsmi_base.c
new file mode 100644
index 000000000000..15ff5f42e2cd
--- /dev/null
+++ b/drivers/staging/vboxvideo/hgsmi_base.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2006-2017 Oracle Corporation
+ *
+ * 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.
+ */
+
+#include "vbox_drv.h"
+#include "vbox_err.h"
+#include "vboxvideo_guest.h"
+#include "vboxvideo_vbe.h"
+#include "hgsmi_channels.h"
+#include "hgsmi_ch_setup.h"
+
+/**
+ * Inform the host of the location of the host flags in VRAM via an HGSMI cmd.
+ * @param ctx the context of the guest heap to use.
+ * @param location the offset chosen for the flags within guest VRAM.
+ * @returns 0 on success, -errno on failure
+ */
+int hgsmi_report_flags_location(struct gen_pool *ctx, u32 location)
+{
+ struct hgsmi_buffer_location *p;
+
+ p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_HGSMI,
+ HGSMI_CC_HOST_FLAGS_LOCATION);
+ if (!p)
+ return -ENOMEM;
+
+ p->buf_location = location;
+ p->buf_len = sizeof(struct hgsmi_host_flags);
+
+ hgsmi_buffer_submit(ctx, p);
+ hgsmi_buffer_free(ctx, p);
+
+ return 0;
+}
+
+/**
+ * Notify the host of HGSMI-related guest capabilities via an HGSMI command.
+ * @param ctx the context of the guest heap to use.
+ * @param caps the capabilities to report, see vbva_caps.
+ * @returns 0 on success, -errno on failure
+ */
+int hgsmi_send_caps_info(struct gen_pool *ctx, u32 caps)
+{
+ struct vbva_caps *p;
+
+ p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, VBVA_INFO_CAPS);
+ if (!p)
+ return -ENOMEM;
+
+ p->rc = VERR_NOT_IMPLEMENTED;
+ p->caps = caps;
+
+ hgsmi_buffer_submit(ctx, p);
+
+ WARN_ON_ONCE(RT_FAILURE(p->rc));
+
+ hgsmi_buffer_free(ctx, p);
+
+ return 0;
+}
+
+int hgsmi_test_query_conf(struct gen_pool *ctx)
+{
+ u32 value = 0;
+ int ret;
+
+ ret = hgsmi_query_conf(ctx, U32_MAX, &value);
+ if (ret)
+ return ret;
+
+ return value == U32_MAX ? 0 : -EIO;
+}
+
+/**
+ * Query the host for an HGSMI configuration parameter via an HGSMI command.
+ * @param ctx the context containing the heap used
+ * @param index the index of the parameter to query,
+ * @see vbva_conf32::index
+ * @param value_ret where to store the value of the parameter on success
+ * @returns 0 on success, -errno on failure
+ */
+int hgsmi_query_conf(struct gen_pool *ctx, u32 index, u32 *value_ret)
+{
+ struct vbva_conf32 *p;
+
+ p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
+ VBVA_QUERY_CONF32);
+ if (!p)
+ return -ENOMEM;
+
+ p->index = index;
+ p->value = U32_MAX;
+
+ hgsmi_buffer_submit(ctx, p);
+
+ *value_ret = p->value;
+
+ hgsmi_buffer_free(ctx, p);
+
+ return 0;
+}
+
+/**
+ * Pass the host a new mouse pointer shape via an HGSMI command.
+ *
+ * @param ctx the context containing the heap to be used
+ * @param flags cursor flags, @see VMMDevReqMousePointer::flags
+ * @param hot_x horizontal position of the hot spot
+ * @param hot_y vertical position of the hot spot
+ * @param width width in pixels of the cursor
+ * @param height height in pixels of the cursor
+ * @param pixels pixel data, @see VMMDevReqMousePointer for the format
+ * @param len size in bytes of the pixel data
+ * @returns 0 on success, -errno on failure
+ */
+int hgsmi_update_pointer_shape(struct gen_pool *ctx, u32 flags,
+ u32 hot_x, u32 hot_y, u32 width, u32 height,
+ u8 *pixels, u32 len)
+{
+ struct vbva_mouse_pointer_shape *p;
+ u32 pixel_len = 0;
+ int rc;
+
+ if (flags & VBOX_MOUSE_POINTER_SHAPE) {
+ /*
+ * Size of the pointer data:
+ * sizeof (AND mask) + sizeof (XOR_MASK)
+ */
+ pixel_len = ((((width + 7) / 8) * height + 3) & ~3) +
+ width * 4 * height;
+ if (pixel_len > len)
+ return -EINVAL;
+
+ /*
+ * If shape is supplied, then always create the pointer visible.
+ * See comments in 'vboxUpdatePointerShape'
+ */
+ flags |= VBOX_MOUSE_POINTER_VISIBLE;
+ }
+
+ p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len, HGSMI_CH_VBVA,
+ VBVA_MOUSE_POINTER_SHAPE);
+ if (!p)
+ return -ENOMEM;
+
+ p->result = VINF_SUCCESS;
+ p->flags = flags;
+ p->hot_X = hot_x;
+ p->hot_y = hot_y;
+ p->width = width;
+ p->height = height;
+ if (pixel_len)
+ memcpy(p->data, pixels, pixel_len);
+
+ hgsmi_buffer_submit(ctx, p);
+
+ switch (p->result) {
+ case VINF_SUCCESS:
+ rc = 0;
+ break;
+ case VERR_NO_MEMORY:
+ rc = -ENOMEM;
+ break;
+ case VERR_NOT_SUPPORTED:
+ rc = -EBUSY;
+ break;
+ default:
+ rc = -EINVAL;
+ }
+
+ hgsmi_buffer_free(ctx, p);
+
+ return rc;
+}
+
+/**
+ * Report the guest cursor position. The host may wish to use this information
+ * to re-position its own cursor (though this is currently unlikely). The
+ * current host cursor position is returned.
+ * @param ctx The context containing the heap used.
+ * @param report_position Are we reporting a position?
+ * @param x Guest cursor X position.
+ * @param y Guest cursor Y position.
+ * @param x_host Host cursor X position is stored here. Optional.
+ * @param y_host Host cursor Y position is stored here. Optional.
+ * @returns 0 on success, -errno on failure
+ */
+int hgsmi_cursor_position(struct gen_pool *ctx, bool report_position,
+ u32 x, u32 y, u32 *x_host, u32 *y_host)
+{
+ struct vbva_cursor_position *p;
+
+ p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
+ VBVA_CURSOR_POSITION);
+ if (!p)
+ return -ENOMEM;
+
+ p->report_position = report_position;
+ p->x = x;
+ p->y = y;
+
+ hgsmi_buffer_submit(ctx, p);
+
+ *x_host = p->x;
+ *y_host = p->y;
+
+ hgsmi_buffer_free(ctx, p);
+
+ return 0;
+}
+
+/**
+ * @todo Mouse pointer position to be read from VMMDev memory, address of the
+ * memory region can be queried from VMMDev via an IOCTL. This VMMDev memory
+ * region will contain host information which is needed by the guest.
+ *
+ * Reading will not cause a switch to the host.
+ *
+ * Have to take into account:
+ * * synchronization: host must write to the memory only from EMT,
+ * large structures must be read under flag, which tells the host
+ * that the guest is currently reading the memory (OWNER flag?).
+ * * guest writes: may be allocate a page for the host info and make
+ * the page readonly for the guest.
+ * * the information should be available only for additions drivers.
+ * * VMMDev additions driver will inform the host which version of the info
+ * it expects, host must support all versions.
+ */
diff --git a/drivers/staging/vboxvideo/hgsmi_ch_setup.h b/drivers/staging/vboxvideo/hgsmi_ch_setup.h
new file mode 100644
index 000000000000..8e6d9e11a69c
--- /dev/null
+++ b/drivers/staging/vboxvideo/hgsmi_ch_setup.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2006-2017 Oracle Corporation
+ *
+ * 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 __HGSMI_CH_SETUP_H__
+#define __HGSMI_CH_SETUP_H__
+
+/*
+ * Tell the host the location of hgsmi_host_flags structure, where the host
+ * can write information about pending buffers, etc, and which can be quickly
+ * polled by the guest without a need to port IO.
+ */
+#define HGSMI_CC_HOST_FLAGS_LOCATION 0
+
+struct hgsmi_buffer_location {
+ u32 buf_location;
+ u32 buf_len;
+} __packed;
+
+/* HGSMI setup and configuration data structures. */
+/* host->guest commands pending, should be accessed under FIFO lock only */
+#define HGSMIHOSTFLAGS_COMMANDS_PENDING 0x01u
+/* IRQ is fired, should be accessed under VGAState::lock only */
+#define HGSMIHOSTFLAGS_IRQ 0x02u
+/* vsync interrupt flag, should be accessed under VGAState::lock only */
+#define HGSMIHOSTFLAGS_VSYNC 0x10u
+/** monitor hotplug flag, should be accessed under VGAState::lock only */
+#define HGSMIHOSTFLAGS_HOTPLUG 0x20u
+/**
+ * Cursor capability state change flag, should be accessed under
+ * VGAState::lock only. @see vbva_conf32.
+ */
+#define HGSMIHOSTFLAGS_CURSOR_CAPABILITIES 0x40u
+
+struct hgsmi_host_flags {
+ /*
+ * Host flags can be accessed and modified in multiple threads
+ * concurrently, e.g. CrOpenGL HGCM and GUI threads when completing
+ * HGSMI 3D and Video Accel respectively, EMT thread when dealing with
+ * HGSMI command processing, etc.
+ * Besides settings/cleaning flags atomically, some flags have their
+ * own special sync restrictions, see comments for flags above.
+ */
+ u32 host_flags;
+ u32 reserved[3];
+} __packed;
+
+#endif
diff --git a/drivers/staging/vboxvideo/hgsmi_channels.h b/drivers/staging/vboxvideo/hgsmi_channels.h
new file mode 100644
index 000000000000..a2a34b2167b4
--- /dev/null
+++ b/drivers/staging/vboxvideo/hgsmi_channels.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2006-2017 Oracle Corporation
+ *
+ * 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 __HGSMI_CHANNELS_H__
+#define __HGSMI_CHANNELS_H__
+
+/*
+ * Each channel has an 8 bit identifier. There are a number of predefined
+ * (hardcoded) channels.
+ *
+ * HGSMI_CH_HGSMI channel can be used to map a string channel identifier
+ * to a free 16 bit numerical value. values are allocated in range
+ * [HGSMI_CH_STRING_FIRST;HGSMI_CH_STRING_LAST].
+ */
+
+/* A reserved channel value */
+#define HGSMI_CH_RESERVED 0x00
+/* HGCMI: setup and configuration */
+#define HGSMI_CH_HGSMI 0x01
+/* Graphics: VBVA */
+#define HGSMI_CH_VBVA 0x02
+/* Graphics: Seamless with a single guest region */
+#define HGSMI_CH_SEAMLESS 0x03
+/* Graphics: Seamless with separate host windows */
+#define HGSMI_CH_SEAMLESS2 0x04
+/* Graphics: OpenGL HW acceleration */
+#define HGSMI_CH_OPENGL 0x05
+
+/* The first channel index to be used for string mappings (inclusive) */
+#define HGSMI_CH_STRING_FIRST 0x20
+/* The last channel index for string mappings (inclusive) */
+#define HGSMI_CH_STRING_LAST 0xff
+
+#endif
diff --git a/drivers/staging/vboxvideo/hgsmi_defs.h b/drivers/staging/vboxvideo/hgsmi_defs.h
new file mode 100644
index 000000000000..5b21fb974d20
--- /dev/null
+++ b/drivers/staging/vboxvideo/hgsmi_defs.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2006-2017 Oracle Corporation
+ *
+ * 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 __HGSMI_DEFS_H__
+#define __HGSMI_DEFS_H__
+
+/* Buffer sequence type mask. */
+#define HGSMI_BUFFER_HEADER_F_SEQ_MASK 0x03
+/* Single buffer, not a part of a sequence. */
+#define HGSMI_BUFFER_HEADER_F_SEQ_SINGLE 0x00
+/* The first buffer in a sequence. */
+#define HGSMI_BUFFER_HEADER_F_SEQ_START 0x01
+/* A middle buffer in a sequence. */
+#define HGSMI_BUFFER_HEADER_F_SEQ_CONTINUE 0x02
+/* The last buffer in a sequence. */
+#define HGSMI_BUFFER_HEADER_F_SEQ_END 0x03
+
+/* 16 bytes buffer header. */
+struct hgsmi_buffer_header {
+ u32 data_size; /* Size of data that follows the header. */
+ u8 flags; /* HGSMI_BUFFER_HEADER_F_* */
+ u8 channel; /* The channel the data must be routed to. */
+ u16 channel_info; /* Opaque to the HGSMI, used by the channel. */
+
+ union {
+ /* Opaque placeholder to make the union 8 bytes. */
+ u8 header_data[8];
+
+ /* HGSMI_BUFFER_HEADER_F_SEQ_SINGLE */
+ struct {
+ u32 reserved1; /* A reserved field, initialize to 0. */
+ u32 reserved2; /* A reserved field, initialize to 0. */
+ } buffer;
+
+ /* HGSMI_BUFFER_HEADER_F_SEQ_START */
+ struct {
+ /* Must be the same for all buffers in the sequence. */
+ u32 sequence_number;
+ /* The total size of the sequence. */
+ u32 sequence_size;
+ } sequence_start;
+
+ /*
+ * HGSMI_BUFFER_HEADER_F_SEQ_CONTINUE and
+ * HGSMI_BUFFER_HEADER_F_SEQ_END
+ */
+ struct {
+ /* Must be the same for all buffers in the sequence. */
+ u32 sequence_number;
+ /* Data offset in the entire sequence. */
+ u32 sequence_offset;
+ } sequence_continue;
+ } u;
+} __packed;
+
+/* 8 bytes buffer tail. */
+struct hgsmi_buffer_tail {
+ /* Reserved, must be initialized to 0. */
+ u32 reserved;
+ /*
+ * One-at-a-Time Hash: http://www.burtleburtle.net/bob/hash/doobs.html
+ * Over the header, offset and for first 4 bytes of the tail.
+ */
+ u32 checksum;
+} __packed;
+
+/*
+ * The size of the array of channels. Array indexes are u8.
+ * Note: the value must not be changed.
+ */
+#define HGSMI_NUMBER_OF_CHANNELS 0x100
+
+#endif
diff --git a/drivers/staging/vboxvideo/modesetting.c b/drivers/staging/vboxvideo/modesetting.c
new file mode 100644
index 000000000000..7616b8aab23a
--- /dev/null
+++ b/drivers/staging/vboxvideo/modesetting.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2006-2017 Oracle Corporation
+ *
+ * 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.
+ */
+
+#include "vbox_drv.h"
+#include "vbox_err.h"
+#include "vboxvideo_guest.h"
+#include "vboxvideo_vbe.h"
+#include "hgsmi_channels.h"
+
+/**
+ * Set a video mode via an HGSMI request. The views must have been
+ * initialised first using @a VBoxHGSMISendViewInfo and if the mode is being
+ * set on the first display then it must be set first using registers.
+ * @param ctx The context containing the heap to use
+ * @param display The screen number
+ * @param origin_x The horizontal displacement relative to the first scrn
+ * @param origin_y The vertical displacement relative to the first screen
+ * @param start_offset The offset of the visible area of the framebuffer
+ * relative to the framebuffer start
+ * @param pitch The offset in bytes between the starts of two adjecent
+ * scan lines in video RAM
+ * @param width The mode width
+ * @param height The mode height
+ * @param bpp The colour depth of the mode
+ * @param flags Flags
+ */
+void hgsmi_process_display_info(struct gen_pool *ctx, u32 display,
+ s32 origin_x, s32 origin_y, u32 start_offset,
+ u32 pitch, u32 width, u32 height,
+ u16 bpp, u16 flags)
+{
+ struct vbva_infoscreen *p;
+
+ p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
+ VBVA_INFO_SCREEN);
+ if (!p)
+ return;
+
+ p->view_index = display;
+ p->origin_x = origin_x;
+ p->origin_y = origin_y;
+ p->start_offset = start_offset;
+ p->line_size = pitch;
+ p->width = width;
+ p->height = height;
+ p->bits_per_pixel = bpp;
+ p->flags = flags;
+
+ hgsmi_buffer_submit(ctx, p);
+ hgsmi_buffer_free(ctx, p);
+}
+
+/**
+ * Report the rectangle relative to which absolute pointer events should be
+ * expressed. This information remains valid until the next VBVA resize event
+ * for any screen, at which time it is reset to the bounding rectangle of all
+ * virtual screens.
+ * @param ctx The context containing the heap to use.
+ * @param origin_x Upper left X co-ordinate relative to the first screen.
+ * @param origin_y Upper left Y co-ordinate relative to the first screen.
+ * @param width Rectangle width.
+ * @param height Rectangle height.
+ * @returns 0 on success, -errno on failure
+ */
+int hgsmi_update_input_mapping(struct gen_pool *ctx, s32 origin_x, s32 origin_y,
+ u32 width, u32 height)
+{
+ struct vbva_report_input_mapping *p;
+
+ p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
+ VBVA_REPORT_INPUT_MAPPING);
+ if (!p)
+ return -ENOMEM;
+
+ p->x = origin_x;
+ p->y = origin_y;
+ p->cx = width;
+ p->cy = height;
+
+ hgsmi_buffer_submit(ctx, p);
+ hgsmi_buffer_free(ctx, p);
+
+ return 0;
+}
+
+/**
+ * Get most recent video mode hints.
+ * @param ctx The context containing the heap to use.
+ * @param screens The number of screens to query hints for, starting at 0.
+ * @param hints Array of vbva_modehint structures for receiving the hints.
+ * @returns 0 on success, -errno on failure
+ */
+int hgsmi_get_mode_hints(struct gen_pool *ctx, unsigned int screens,
+ struct vbva_modehint *hints)
+{
+ struct vbva_query_mode_hints *p;
+ size_t size;
+
+ if (WARN_ON(!hints))
+ return -EINVAL;
+
+ size = screens * sizeof(struct vbva_modehint);
+ p = hgsmi_buffer_alloc(ctx, sizeof(*p) + size, HGSMI_CH_VBVA,
+ VBVA_QUERY_MODE_HINTS);
+ if (!p)
+ return -ENOMEM;
+
+ p->hints_queried_count = screens;
+ p->hint_structure_guest_size = sizeof(struct vbva_modehint);
+ p->rc = VERR_NOT_SUPPORTED;
+
+ hgsmi_buffer_submit(ctx, p);
+
+ if (RT_FAILURE(p->rc)) {
+ hgsmi_buffer_free(ctx, p);
+ return -EIO;
+ }
+
+ memcpy(hints, ((u8 *)p) + sizeof(struct vbva_query_mode_hints), size);
+ hgsmi_buffer_free(ctx, p);
+
+ return 0;
+}
diff --git a/drivers/staging/vboxvideo/vbox_drv.c b/drivers/staging/vboxvideo/vbox_drv.c
new file mode 100644
index 000000000000..6d0600c37c0c
--- /dev/null
+++ b/drivers/staging/vboxvideo/vbox_drv.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2013-2017 Oracle Corporation
+ * This file is based on ast_drv.c
+ * Copyright 2012 Red Hat 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, 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 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * Authors: Dave Airlie <airlied@redhat.com>
+ * Michael Thayer <michael.thayer@oracle.com,
+ * Hans de Goede <hdegoede@redhat.com>
+ */
+#include <linux/module.h>
+#include <linux/console.h>
+#include <linux/vt_kern.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+
+#include "vbox_drv.h"
+
+int vbox_modeset = -1;
+
+MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
+module_param_named(modeset, vbox_modeset, int, 0400);
+
+static struct drm_driver driver;
+
+static const struct pci_device_id pciidlist[] = {
+ { 0x80ee, 0xbeef, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { 0, 0, 0},
+};
+MODULE_DEVICE_TABLE(pci, pciidlist);
+
+static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ return drm_get_pci_dev(pdev, ent, &driver);
+}
+
+static void vbox_pci_remove(struct pci_dev *pdev)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+
+ drm_put_dev(dev);
+}
+
+static int vbox_drm_freeze(struct drm_device *dev)
+{
+ struct vbox_private *vbox = dev->dev_private;
+
+ drm_kms_helper_poll_disable(dev);
+
+ pci_save_state(dev->pdev);
+
+ drm_fb_helper_set_suspend_unlocked(&vbox->fbdev->helper, true);
+
+ return 0;
+}
+
+static int vbox_drm_thaw(struct drm_device *dev)
+{
+ struct vbox_private *vbox = dev->dev_private;
+
+ drm_mode_config_reset(dev);
+ drm_helper_resume_force_mode(dev);
+ drm_fb_helper_set_suspend_unlocked(&vbox->fbdev->helper, false);
+
+ return 0;
+}
+
+static int vbox_drm_resume(struct drm_device *dev)
+{
+ int ret;
+
+ if (pci_enable_device(dev->pdev))
+ return -EIO;
+
+ ret = vbox_drm_thaw(dev);
+ if (ret)
+ return ret;
+
+ drm_kms_helper_poll_enable(dev);
+
+ return 0;
+}
+
+static int vbox_pm_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct drm_device *ddev = pci_get_drvdata(pdev);
+ int error;
+
+ error = vbox_drm_freeze(ddev);
+ if (error)
+ return error;
+
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+
+ return 0;
+}
+
+static int vbox_pm_resume(struct device *dev)
+{
+ struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
+
+ return vbox_drm_resume(ddev);
+}
+
+static int vbox_pm_freeze(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct drm_device *ddev = pci_get_drvdata(pdev);
+
+ if (!ddev || !ddev->dev_private)
+ return -ENODEV;
+
+ return vbox_drm_freeze(ddev);
+}
+
+static int vbox_pm_thaw(struct device *dev)
+{
+ struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
+
+ return vbox_drm_thaw(ddev);
+}
+
+static int vbox_pm_poweroff(struct device *dev)
+{
+ struct drm_device *ddev = pci_get_drvdata(to_pci_dev(dev));
+
+ return vbox_drm_freeze(ddev);
+}
+
+static const struct dev_pm_ops vbox_pm_ops = {
+ .suspend = vbox_pm_suspend,
+ .resume = vbox_pm_resume,
+ .freeze = vbox_pm_freeze,
+ .thaw = vbox_pm_thaw,
+ .poweroff = vbox_pm_poweroff,
+ .restore = vbox_pm_resume,
+};
+
+static struct pci_driver vbox_pci_driver = {
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+ .probe = vbox_pci_probe,
+ .remove = vbox_pci_remove,
+ .driver.pm = &vbox_pm_ops,
+};
+
+static const struct file_operations vbox_fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .unlocked_ioctl = drm_ioctl,
+ .mmap = vbox_mmap,
+ .poll = drm_poll,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = drm_compat_ioctl,
+#endif
+ .read = drm_read,
+};
+
+static int vbox_master_set(struct drm_device *dev,
+ struct drm_file *file_priv, bool from_open)
+{
+ struct vbox_private *vbox = dev->dev_private;
+
+ /*
+ * We do not yet know whether the new owner can handle hotplug, so we
+ * do not advertise dynamic modes on the first query and send a
+ * tentative hotplug notification after that to see if they query again.
+ */
+ vbox->initial_mode_queried = false;
+
+ mutex_lock(&vbox->hw_mutex);
+ /*
+ * Disable VBVA when someone releases master in case the next person
+ * tries tries to do VESA.
+ */
+ /** @todo work out if anyone is likely to and whether it will work. */
+ /*
+ * Update: we also disable it because if the new master does not do
+ * dirty rectangle reporting (e.g. old versions of Plymouth) then at
+ * least the first screen will still be updated. We enable it as soon
+ * as we receive a dirty rectangle report.
+ */
+ vbox_disable_accel(vbox);
+ mutex_unlock(&vbox->hw_mutex);
+
+ return 0;
+}
+
+static void vbox_master_drop(struct drm_device *dev, struct drm_file *file_priv)
+{
+ struct vbox_private *vbox = dev->dev_private;
+
+ /* See vbox_master_set() */
+ vbox->initial_mode_queried = false;
+
+ mutex_lock(&vbox->hw_mutex);
+ vbox_disable_accel(vbox);
+ mutex_unlock(&vbox->hw_mutex);
+}
+
+static struct drm_driver driver = {
+ .driver_features =
+ DRIVER_MODESET | DRIVER_GEM | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
+ DRIVER_PRIME,
+ .dev_priv_size = 0,
+
+ .load = vbox_driver_load,
+ .unload = vbox_driver_unload,
+ .lastclose = vbox_driver_lastclose,
+ .master_set = vbox_master_set,
+ .master_drop = vbox_master_drop,
+
+ .fops = &vbox_fops,
+ .irq_handler = vbox_irq_handler,
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
+
+ .gem_free_object = vbox_gem_free_object,
+ .dumb_create = vbox_dumb_create,
+ .dumb_map_offset = vbox_dumb_mmap_offset,
+ .dumb_destroy = drm_gem_dumb_destroy,
+ .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+ .gem_prime_export = drm_gem_prime_export,
+ .gem_prime_import = drm_gem_prime_import,
+ .gem_prime_pin = vbox_gem_prime_pin,
+ .gem_prime_unpin = vbox_gem_prime_unpin,
+ .gem_prime_get_sg_table = vbox_gem_prime_get_sg_table,
+ .gem_prime_import_sg_table = vbox_gem_prime_import_sg_table,
+ .gem_prime_vmap = vbox_gem_prime_vmap,
+ .gem_prime_vunmap = vbox_gem_prime_vunmap,
+ .gem_prime_mmap = vbox_gem_prime_mmap,
+};
+
+static int __init vbox_init(void)
+{
+#ifdef CONFIG_VGA_CONSOLE
+ if (vgacon_text_force() && vbox_modeset == -1)
+ return -EINVAL;
+#endif
+
+ if (vbox_modeset == 0)
+ return -EINVAL;
+
+ return pci_register_driver(&vbox_pci_driver);
+}
+
+static void __exit vbox_exit(void)
+{
+ pci_unregister_driver(&vbox_pci_driver);
+}
+
+module_init(vbox_init);
+module_exit(vbox_exit);
+
+MODULE_AUTHOR("Oracle Corporation");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/staging/vboxvideo/vbox_drv.h b/drivers/staging/vboxvideo/vbox_drv.h
new file mode 100644
index 000000000000..4b9302703b36
--- /dev/null
+++ b/drivers/staging/vboxvideo/vbox_drv.h
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2013-2017 Oracle Corporation
+ * This file is based on ast_drv.h
+ * Copyright 2012 Red Hat 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, 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 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * Authors: Dave Airlie <airlied@redhat.com>
+ * Michael Thayer <michael.thayer@oracle.com,
+ * Hans de Goede <hdegoede@redhat.com>
+ */
+#ifndef __VBOX_DRV_H__
+#define __VBOX_DRV_H__
+
+#include <linux/genalloc.h>
+#include <linux/io.h>
+#include <linux/string.h>
+#include <linux/version.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_encoder.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_gem.h>
+
+#include <drm/ttm/ttm_bo_api.h>
+#include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_placement.h>
+#include <drm/ttm/ttm_memory.h>
+#include <drm/ttm/ttm_module.h>
+
+#include "vboxvideo_guest.h"
+#include "vboxvideo_vbe.h"
+#include "hgsmi_ch_setup.h"
+
+#define DRIVER_NAME "vboxvideo"
+#define DRIVER_DESC "Oracle VM VirtualBox Graphics Card"
+#define DRIVER_DATE "20130823"
+
+#define DRIVER_MAJOR 1
+#define DRIVER_MINOR 0
+#define DRIVER_PATCHLEVEL 0
+
+#define VBOX_MAX_CURSOR_WIDTH 64
+#define VBOX_MAX_CURSOR_HEIGHT 64
+#define CURSOR_PIXEL_COUNT (VBOX_MAX_CURSOR_WIDTH * VBOX_MAX_CURSOR_HEIGHT)
+#define CURSOR_DATA_SIZE (CURSOR_PIXEL_COUNT * 4 + CURSOR_PIXEL_COUNT / 8)
+
+#define VBOX_MAX_SCREENS 32
+
+#define GUEST_HEAP_OFFSET(vbox) ((vbox)->full_vram_size - \
+ VBVA_ADAPTER_INFORMATION_SIZE)
+#define GUEST_HEAP_SIZE VBVA_ADAPTER_INFORMATION_SIZE
+#define GUEST_HEAP_USABLE_SIZE (VBVA_ADAPTER_INFORMATION_SIZE - \
+ sizeof(struct hgsmi_host_flags))
+#define HOST_FLAGS_OFFSET GUEST_HEAP_USABLE_SIZE
+
+struct vbox_fbdev;
+
+struct vbox_private {
+ struct drm_device *dev;
+
+ u8 __iomem *guest_heap;
+ u8 __iomem *vbva_buffers;
+ struct gen_pool *guest_pool;
+ struct vbva_buf_ctx *vbva_info;
+ bool any_pitch;
+ u32 num_crtcs;
+ /** Amount of available VRAM, including space used for buffers. */
+ u32 full_vram_size;
+ /** Amount of available VRAM, not including space used for buffers. */
+ u32 available_vram_size;
+ /** Array of structures for receiving mode hints. */
+ struct vbva_modehint *last_mode_hints;
+
+ struct vbox_fbdev *fbdev;
+
+ int fb_mtrr;
+
+ struct {
+ struct drm_global_reference mem_global_ref;
+ struct ttm_bo_global_ref bo_global_ref;
+ struct ttm_bo_device bdev;
+ } ttm;
+
+ struct mutex hw_mutex; /* protects modeset and accel/vbva accesses */
+ /**
+ * We decide whether or not user-space supports display hot-plug
+ * depending on whether they react to a hot-plug event after the initial
+ * mode query.
+ */
+ bool initial_mode_queried;
+ struct work_struct hotplug_work;
+ u32 input_mapping_width;
+ u32 input_mapping_height;
+ /**
+ * Is user-space using an X.Org-style layout of one large frame-buffer
+ * encompassing all screen ones or is the fbdev console active?
+ */
+ bool single_framebuffer;
+ u32 cursor_width;
+ u32 cursor_height;
+ u32 cursor_hot_x;
+ u32 cursor_hot_y;
+ size_t cursor_data_size;
+ u8 cursor_data[CURSOR_DATA_SIZE];
+};
+
+#undef CURSOR_PIXEL_COUNT
+#undef CURSOR_DATA_SIZE
+
+int vbox_driver_load(struct drm_device *dev, unsigned long flags);
+void vbox_driver_unload(struct drm_device *dev);
+void vbox_driver_lastclose(struct drm_device *dev);
+
+struct vbox_gem_object;
+
+struct vbox_connector {
+ struct drm_connector base;
+ char name[32];
+ struct vbox_crtc *vbox_crtc;
+ struct {
+ u16 width;
+ u16 height;
+ bool disconnected;
+ } mode_hint;
+};
+
+struct vbox_crtc {
+ struct drm_crtc base;
+ bool blanked;
+ bool disconnected;
+ unsigned int crtc_id;
+ u32 fb_offset;
+ bool cursor_enabled;
+ u16 x_hint;
+ u16 y_hint;
+};
+
+struct vbox_encoder {
+ struct drm_encoder base;
+};
+
+struct vbox_framebuffer {
+ struct drm_framebuffer base;
+ struct drm_gem_object *obj;
+};
+
+struct vbox_fbdev {
+ struct drm_fb_helper helper;
+ struct vbox_framebuffer afb;
+ int size;
+ struct ttm_bo_kmap_obj mapping;
+ int x1, y1, x2, y2; /* dirty rect */
+ spinlock_t dirty_lock;
+};
+
+#define to_vbox_crtc(x) container_of(x, struct vbox_crtc, base)
+#define to_vbox_connector(x) container_of(x, struct vbox_connector, base)
+#define to_vbox_encoder(x) container_of(x, struct vbox_encoder, base)
+#define to_vbox_framebuffer(x) container_of(x, struct vbox_framebuffer, base)
+
+int vbox_mode_init(struct drm_device *dev);
+void vbox_mode_fini(struct drm_device *dev);
+
+#define DRM_MODE_FB_CMD drm_mode_fb_cmd2
+#define CRTC_FB(crtc) ((crtc)->primary->fb)
+
+void vbox_enable_accel(struct vbox_private *vbox);
+void vbox_disable_accel(struct vbox_private *vbox);
+void vbox_report_caps(struct vbox_private *vbox);
+
+void vbox_framebuffer_dirty_rectangles(struct drm_framebuffer *fb,
+ struct drm_clip_rect *rects,
+ unsigned int num_rects);
+
+int vbox_framebuffer_init(struct drm_device *dev,
+ struct vbox_framebuffer *vbox_fb,
+ const struct DRM_MODE_FB_CMD *mode_cmd,
+ struct drm_gem_object *obj);
+
+int vbox_fbdev_init(struct drm_device *dev);
+void vbox_fbdev_fini(struct drm_device *dev);
+void vbox_fbdev_set_base(struct vbox_private *vbox, unsigned long gpu_addr);
+
+struct vbox_bo {
+ struct ttm_buffer_object bo;
+ struct ttm_placement placement;
+ struct ttm_bo_kmap_obj kmap;
+ struct drm_gem_object gem;
+ struct ttm_place placements[3];
+ int pin_count;
+};
+
+#define gem_to_vbox_bo(gobj) container_of((gobj), struct vbox_bo, gem)
+
+static inline struct vbox_bo *vbox_bo(struct ttm_buffer_object *bo)
+{
+ return container_of(bo, struct vbox_bo, bo);
+}
+
+#define to_vbox_obj(x) container_of(x, struct vbox_gem_object, base)
+
+int vbox_dumb_create(struct drm_file *file,
+ struct drm_device *dev,
+ struct drm_mode_create_dumb *args);
+
+void vbox_gem_free_object(struct drm_gem_object *obj);
+int vbox_dumb_mmap_offset(struct drm_file *file,
+ struct drm_device *dev,
+ u32 handle, u64 *offset);
+
+#define DRM_FILE_PAGE_OFFSET (0x10000000ULL >> PAGE_SHIFT)
+
+int vbox_mm_init(struct vbox_private *vbox);
+void vbox_mm_fini(struct vbox_private *vbox);
+
+int vbox_bo_create(struct drm_device *dev, int size, int align,
+ u32 flags, struct vbox_bo **pvboxbo);
+
+int vbox_gem_create(struct drm_device *dev,
+ u32 size, bool iskernel, struct drm_gem_object **obj);
+
+int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag, u64 *gpu_addr);
+int vbox_bo_unpin(struct vbox_bo *bo);
+
+static inline int vbox_bo_reserve(struct vbox_bo *bo, bool no_wait)
+{
+ int ret;
+
+ ret = ttm_bo_reserve(&bo->bo, true, no_wait, NULL);
+ if (ret) {
+ if (ret != -ERESTARTSYS && ret != -EBUSY)
+ DRM_ERROR("reserve failed %p\n", bo);
+ return ret;
+ }
+ return 0;
+}
+
+static inline void vbox_bo_unreserve(struct vbox_bo *bo)
+{
+ ttm_bo_unreserve(&bo->bo);
+}
+
+void vbox_ttm_placement(struct vbox_bo *bo, int domain);
+int vbox_bo_push_sysram(struct vbox_bo *bo);
+int vbox_mmap(struct file *filp, struct vm_area_struct *vma);
+
+/* vbox_prime.c */
+int vbox_gem_prime_pin(struct drm_gem_object *obj);
+void vbox_gem_prime_unpin(struct drm_gem_object *obj);
+struct sg_table *vbox_gem_prime_get_sg_table(struct drm_gem_object *obj);
+struct drm_gem_object *vbox_gem_prime_import_sg_table(
+ struct drm_device *dev, struct dma_buf_attachment *attach,
+ struct sg_table *table);
+void *vbox_gem_prime_vmap(struct drm_gem_object *obj);
+void vbox_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
+int vbox_gem_prime_mmap(struct drm_gem_object *obj,
+ struct vm_area_struct *area);
+
+/* vbox_irq.c */
+int vbox_irq_init(struct vbox_private *vbox);
+void vbox_irq_fini(struct vbox_private *vbox);
+void vbox_report_hotplug(struct vbox_private *vbox);
+irqreturn_t vbox_irq_handler(int irq, void *arg);
+
+/* vbox_hgsmi.c */
+void *hgsmi_buffer_alloc(struct gen_pool *guest_pool, size_t size,
+ u8 channel, u16 channel_info);
+void hgsmi_buffer_free(struct gen_pool *guest_pool, void *buf);
+int hgsmi_buffer_submit(struct gen_pool *guest_pool, void *buf);
+
+static inline void vbox_write_ioport(u16 index, u16 data)
+{
+ outw(index, VBE_DISPI_IOPORT_INDEX);
+ outw(data, VBE_DISPI_IOPORT_DATA);
+}
+
+#endif
diff --git a/drivers/staging/vboxvideo/vbox_err.h b/drivers/staging/vboxvideo/vbox_err.h
new file mode 100644
index 000000000000..562db8630eb0
--- /dev/null
+++ b/drivers/staging/vboxvideo/vbox_err.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017 Oracle Corporation
+ *
+ * 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 __VBOX_ERR_H__
+#define __VBOX_ERR_H__
+
+/**
+ * @name VirtualBox virtual-hardware error macros
+ * @{
+ */
+
+#define VINF_SUCCESS 0
+#define VERR_INVALID_PARAMETER (-2)
+#define VERR_INVALID_POINTER (-6)
+#define VERR_NO_MEMORY (-8)
+#define VERR_NOT_IMPLEMENTED (-12)
+#define VERR_INVALID_FUNCTION (-36)
+#define VERR_NOT_SUPPORTED (-37)
+#define VERR_TOO_MUCH_DATA (-42)
+#define VERR_INVALID_STATE (-79)
+#define VERR_OUT_OF_RESOURCES (-80)
+#define VERR_ALREADY_EXISTS (-105)
+#define VERR_INTERNAL_ERROR (-225)
+
+#define RT_SUCCESS_NP(rc) ((int)(rc) >= VINF_SUCCESS)
+#define RT_SUCCESS(rc) (likely(RT_SUCCESS_NP(rc)))
+#define RT_FAILURE(rc) (unlikely(!RT_SUCCESS_NP(rc)))
+
+/** @} */
+
+#endif
diff --git a/drivers/staging/vboxvideo/vbox_fb.c b/drivers/staging/vboxvideo/vbox_fb.c
new file mode 100644
index 000000000000..c1572843003a
--- /dev/null
+++ b/drivers/staging/vboxvideo/vbox_fb.c
@@ -0,0 +1,397 @@
+/*
+ * Copyright (C) 2013-2017 Oracle Corporation
+ * This file is based on ast_fb.c
+ * Copyright 2012 Red Hat 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, 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 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * Authors: Dave Airlie <airlied@redhat.com>
+ * Michael Thayer <michael.thayer@oracle.com,
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/sysrq.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
+
+#include "vbox_drv.h"
+#include "vboxvideo.h"
+
+#define VBOX_DIRTY_DELAY (HZ / 30)
+/**
+ * Tell the host about dirty rectangles to update.
+ */
+static void vbox_dirty_update(struct vbox_fbdev *fbdev,
+ int x, int y, int width, int height)
+{
+ struct drm_gem_object *obj;
+ struct vbox_bo *bo;
+ int ret = -EBUSY;
+ bool store_for_later = false;
+ int x2, y2;
+ unsigned long flags;
+ struct drm_clip_rect rect;
+
+ obj = fbdev->afb.obj;
+ bo = gem_to_vbox_bo(obj);
+
+ /*
+ * try and reserve the BO, if we fail with busy
+ * then the BO is being moved and we should
+ * store up the damage until later.
+ */
+ if (drm_can_sleep())
+ ret = vbox_bo_reserve(bo, true);
+ if (ret) {
+ if (ret != -EBUSY)
+ return;
+
+ store_for_later = true;
+ }
+
+ x2 = x + width - 1;
+ y2 = y + height - 1;
+ spin_lock_irqsave(&fbdev->dirty_lock, flags);
+
+ if (fbdev->y1 < y)
+ y = fbdev->y1;
+ if (fbdev->y2 > y2)
+ y2 = fbdev->y2;
+ if (fbdev->x1 < x)
+ x = fbdev->x1;
+ if (fbdev->x2 > x2)
+ x2 = fbdev->x2;
+
+ if (store_for_later) {
+ fbdev->x1 = x;
+ fbdev->x2 = x2;
+ fbdev->y1 = y;
+ fbdev->y2 = y2;
+ spin_unlock_irqrestore(&fbdev->dirty_lock, flags);
+ return;
+ }
+
+ fbdev->x1 = INT_MAX;
+ fbdev->y1 = INT_MAX;
+ fbdev->x2 = 0;
+ fbdev->y2 = 0;
+
+ spin_unlock_irqrestore(&fbdev->dirty_lock, flags);
+
+ /*
+ * Not sure why the original code subtracted 1 here, but I will keep
+ * it that way to avoid unnecessary differences.
+ */
+ rect.x1 = x;
+ rect.x2 = x2 + 1;
+ rect.y1 = y;
+ rect.y2 = y2 + 1;
+ vbox_framebuffer_dirty_rectangles(&fbdev->afb.base, &rect, 1);
+
+ vbox_bo_unreserve(bo);
+}
+
+#ifdef CONFIG_FB_DEFERRED_IO
+static void vbox_deferred_io(struct fb_info *info, struct list_head *pagelist)
+{
+ struct vbox_fbdev *fbdev = info->par;
+ unsigned long start, end, min, max;
+ struct page *page;
+ int y1, y2;
+
+ min = ULONG_MAX;
+ max = 0;
+ list_for_each_entry(page, pagelist, lru) {
+ start = page->index << PAGE_SHIFT;
+ end = start + PAGE_SIZE - 1;
+ min = min(min, start);
+ max = max(max, end);
+ }
+
+ if (min < max) {
+ y1 = min / info->fix.line_length;
+ y2 = (max / info->fix.line_length) + 1;
+ DRM_INFO("%s: Calling dirty update: 0, %d, %d, %d\n",
+ __func__, y1, info->var.xres, y2 - y1 - 1);
+ vbox_dirty_update(fbdev, 0, y1, info->var.xres, y2 - y1 - 1);
+ }
+}
+
+static struct fb_deferred_io vbox_defio = {
+ .delay = VBOX_DIRTY_DELAY,
+ .deferred_io = vbox_deferred_io,
+};
+#endif
+
+static void vbox_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+{
+ struct vbox_fbdev *fbdev = info->par;
+
+ sys_fillrect(info, rect);
+ vbox_dirty_update(fbdev, rect->dx, rect->dy, rect->width, rect->height);
+}
+
+static void vbox_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+{
+ struct vbox_fbdev *fbdev = info->par;
+
+ sys_copyarea(info, area);
+ vbox_dirty_update(fbdev, area->dx, area->dy, area->width, area->height);
+}
+
+static void vbox_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+ struct vbox_fbdev *fbdev = info->par;
+
+ sys_imageblit(info, image);
+ vbox_dirty_update(fbdev, image->dx, image->dy, image->width,
+ image->height);
+}
+
+static struct fb_ops vboxfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = drm_fb_helper_check_var,
+ .fb_set_par = drm_fb_helper_set_par,
+ .fb_fillrect = vbox_fillrect,
+ .fb_copyarea = vbox_copyarea,
+ .fb_imageblit = vbox_imageblit,
+ .fb_pan_display = drm_fb_helper_pan_display,
+ .fb_blank = drm_fb_helper_blank,
+ .fb_setcmap = drm_fb_helper_setcmap,
+ .fb_debug_enter = drm_fb_helper_debug_enter,
+ .fb_debug_leave = drm_fb_helper_debug_leave,
+};
+
+static int vboxfb_create_object(struct vbox_fbdev *fbdev,
+ struct DRM_MODE_FB_CMD *mode_cmd,
+ struct drm_gem_object **gobj_p)
+{
+ struct drm_device *dev = fbdev->helper.dev;
+ u32 size;
+ struct drm_gem_object *gobj;
+ u32 pitch = mode_cmd->pitches[0];
+ int ret;
+
+ size = pitch * mode_cmd->height;
+ ret = vbox_gem_create(dev, size, true, &gobj);
+ if (ret)
+ return ret;
+
+ *gobj_p = gobj;
+
+ return 0;
+}
+
+static int vboxfb_create(struct drm_fb_helper *helper,
+ struct drm_fb_helper_surface_size *sizes)
+{
+ struct vbox_fbdev *fbdev =
+ container_of(helper, struct vbox_fbdev, helper);
+ struct drm_device *dev = fbdev->helper.dev;
+ struct DRM_MODE_FB_CMD mode_cmd;
+ struct drm_framebuffer *fb;
+ struct fb_info *info;
+ struct device *device = &dev->pdev->dev;
+ struct drm_gem_object *gobj;
+ struct vbox_bo *bo;
+ int size, ret;
+ u32 pitch;
+
+ mode_cmd.width = sizes->surface_width;
+ mode_cmd.height = sizes->surface_height;
+ pitch = mode_cmd.width * ((sizes->surface_bpp + 7) / 8);
+ mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
+ sizes->surface_depth);
+ mode_cmd.pitches[0] = pitch;
+
+ size = pitch * mode_cmd.height;
+
+ ret = vboxfb_create_object(fbdev, &mode_cmd, &gobj);
+ if (ret) {
+ DRM_ERROR("failed to create fbcon backing object %d\n", ret);
+ return ret;
+ }
+
+ ret = vbox_framebuffer_init(dev, &fbdev->afb, &mode_cmd, gobj);
+ if (ret)
+ return ret;
+
+ bo = gem_to_vbox_bo(gobj);
+
+ ret = vbox_bo_reserve(bo, false);
+ if (ret)
+ return ret;
+
+ ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL);
+ if (ret) {
+ vbox_bo_unreserve(bo);
+ return ret;
+ }
+
+ ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
+ vbox_bo_unreserve(bo);
+ if (ret) {
+ DRM_ERROR("failed to kmap fbcon\n");
+ return ret;
+ }
+
+ info = framebuffer_alloc(0, device);
+ if (!info)
+ return -ENOMEM;
+ info->par = fbdev;
+
+ fbdev->size = size;
+
+ fb = &fbdev->afb.base;
+ fbdev->helper.fb = fb;
+ fbdev->helper.fbdev = info;
+
+ strcpy(info->fix.id, "vboxdrmfb");
+
+ /*
+ * The last flag forces a mode set on VT switches even if the kernel
+ * does not think it is needed.
+ */
+ info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT |
+ FBINFO_MISC_ALWAYS_SETPAR;
+ info->fbops = &vboxfb_ops;
+
+ ret = fb_alloc_cmap(&info->cmap, 256, 0);
+ if (ret)
+ return -ENOMEM;
+
+ /*
+ * This seems to be done for safety checking that the framebuffer
+ * is not registered twice by different drivers.
+ */
+ info->apertures = alloc_apertures(1);
+ if (!info->apertures)
+ return -ENOMEM;
+ info->apertures->ranges[0].base = pci_resource_start(dev->pdev, 0);
+ info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0);
+
+ drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth);
+ drm_fb_helper_fill_var(info, &fbdev->helper, sizes->fb_width,
+ sizes->fb_height);
+
+ info->screen_base = bo->kmap.virtual;
+ info->screen_size = size;
+
+#ifdef CONFIG_FB_DEFERRED_IO
+ info->fbdefio = &vbox_defio;
+ fb_deferred_io_init(info);
+#endif
+
+ info->pixmap.flags = FB_PIXMAP_SYSTEM;
+
+ DRM_DEBUG_KMS("allocated %dx%d\n", fb->width, fb->height);
+
+ return 0;
+}
+
+static struct drm_fb_helper_funcs vbox_fb_helper_funcs = {
+ .fb_probe = vboxfb_create,
+};
+
+void vbox_fbdev_fini(struct drm_device *dev)
+{
+ struct vbox_private *vbox = dev->dev_private;
+ struct vbox_fbdev *fbdev = vbox->fbdev;
+ struct vbox_framebuffer *afb = &fbdev->afb;
+
+ drm_fb_helper_unregister_fbi(&fbdev->helper);
+
+ if (afb->obj) {
+ struct vbox_bo *bo = gem_to_vbox_bo(afb->obj);
+
+ if (!vbox_bo_reserve(bo, false)) {
+ if (bo->kmap.virtual)
+ ttm_bo_kunmap(&bo->kmap);
+ /*
+ * QXL does this, but is it really needed before
+ * freeing?
+ */
+ if (bo->pin_count)
+ vbox_bo_unpin(bo);
+ vbox_bo_unreserve(bo);
+ }
+ drm_gem_object_put_unlocked(afb->obj);
+ afb->obj = NULL;
+ }
+ drm_fb_helper_fini(&fbdev->helper);
+
+ drm_framebuffer_unregister_private(&afb->base);
+ drm_framebuffer_cleanup(&afb->base);
+}
+
+int vbox_fbdev_init(struct drm_device *dev)
+{
+ struct vbox_private *vbox = dev->dev_private;
+ struct vbox_fbdev *fbdev;
+ int ret;
+
+ fbdev = devm_kzalloc(dev->dev, sizeof(*fbdev), GFP_KERNEL);
+ if (!fbdev)
+ return -ENOMEM;
+
+ vbox->fbdev = fbdev;
+ spin_lock_init(&fbdev->dirty_lock);
+
+ drm_fb_helper_prepare(dev, &fbdev->helper, &vbox_fb_helper_funcs);
+ ret = drm_fb_helper_init(dev, &fbdev->helper, vbox->num_crtcs);
+ if (ret)
+ return ret;
+
+ ret = drm_fb_helper_single_add_all_connectors(&fbdev->helper);
+ if (ret)
+ goto err_fini;
+
+ /* disable all the possible outputs/crtcs before entering KMS mode */
+ drm_helper_disable_unused_functions(dev);
+
+ ret = drm_fb_helper_initial_config(&fbdev->helper, 32);
+ if (ret)
+ goto err_fini;
+
+ return 0;
+
+err_fini:
+ drm_fb_helper_fini(&fbdev->helper);
+ return ret;
+}
+
+void vbox_fbdev_set_base(struct vbox_private *vbox, unsigned long gpu_addr)
+{
+ struct fb_info *fbdev = vbox->fbdev->helper.fbdev;
+
+ fbdev->fix.smem_start = fbdev->apertures->ranges[0].base + gpu_addr;
+ fbdev->fix.smem_len = vbox->available_vram_size - gpu_addr;
+}
diff --git a/drivers/staging/vboxvideo/vbox_hgsmi.c b/drivers/staging/vboxvideo/vbox_hgsmi.c
new file mode 100644
index 000000000000..822fd31121cb
--- /dev/null
+++ b/drivers/staging/vboxvideo/vbox_hgsmi.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2017 Oracle Corporation
+ *
+ * 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 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * Authors: Hans de Goede <hdegoede@redhat.com>
+ */
+
+#include "vbox_drv.h"
+#include "vboxvideo_vbe.h"
+#include "hgsmi_defs.h"
+
+/* One-at-a-Time Hash from http://www.burtleburtle.net/bob/hash/doobs.html */
+static u32 hgsmi_hash_process(u32 hash, const u8 *data, int size)
+{
+ while (size--) {
+ hash += *data++;
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+ }
+
+ return hash;
+}
+
+static u32 hgsmi_hash_end(u32 hash)
+{
+ hash += (hash << 3);
+ hash ^= (hash >> 11);
+ hash += (hash << 15);
+
+ return hash;
+}
+
+/* Not really a checksum but that is the naming used in all vbox code */
+static u32 hgsmi_checksum(u32 offset,
+ const struct hgsmi_buffer_header *header,
+ const struct hgsmi_buffer_tail *tail)
+{
+ u32 checksum;
+
+ checksum = hgsmi_hash_process(0, (u8 *)&offset, sizeof(offset));
+ checksum = hgsmi_hash_process(checksum, (u8 *)header, sizeof(*header));
+ /* 4 -> Do not checksum the checksum itself */
+ checksum = hgsmi_hash_process(checksum, (u8 *)tail, 4);
+
+ return hgsmi_hash_end(checksum);
+}
+
+void *hgsmi_buffer_alloc(struct gen_pool *guest_pool, size_t size,
+ u8 channel, u16 channel_info)
+{
+ struct hgsmi_buffer_header *h;
+ struct hgsmi_buffer_tail *t;
+ size_t total_size;
+ dma_addr_t offset;
+
+ total_size = size + sizeof(*h) + sizeof(*t);
+ h = gen_pool_dma_alloc(guest_pool, total_size, &offset);
+ if (!h)
+ return NULL;
+
+ t = (struct hgsmi_buffer_tail *)((u8 *)h + sizeof(*h) + size);
+
+ h->flags = HGSMI_BUFFER_HEADER_F_SEQ_SINGLE;
+ h->data_size = size;
+ h->channel = channel;
+ h->channel_info = channel_info;
+ memset(&h->u.header_data, 0, sizeof(h->u.header_data));
+
+ t->reserved = 0;
+ t->checksum = hgsmi_checksum(offset, h, t);
+
+ return (u8 *)h + sizeof(*h);
+}
+
+void hgsmi_buffer_free(struct gen_pool *guest_pool, void *buf)
+{
+ struct hgsmi_buffer_header *h =
+ (struct hgsmi_buffer_header *)((u8 *)buf - sizeof(*h));
+ size_t total_size = h->data_size + sizeof(*h) +
+ sizeof(struct hgsmi_buffer_tail);
+
+ gen_pool_free(guest_pool, (unsigned long)h, total_size);
+}
+
+int hgsmi_buffer_submit(struct gen_pool *guest_pool, void *buf)
+{
+ phys_addr_t offset;
+
+ offset = gen_pool_virt_to_phys(guest_pool, (unsigned long)buf -
+ sizeof(struct hgsmi_buffer_header));
+ outl(offset, VGA_PORT_HGSMI_GUEST);
+ /* Make the compiler aware that the host has changed memory. */
+ mb();
+
+ return 0;
+}
diff --git a/drivers/staging/vboxvideo/vbox_irq.c b/drivers/staging/vboxvideo/vbox_irq.c
new file mode 100644
index 000000000000..3ca8bec62ac4
--- /dev/null
+++ b/drivers/staging/vboxvideo/vbox_irq.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2016-2017 Oracle Corporation
+ * This file is based on qxl_irq.c
+ * Copyright 2013 Red Hat 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: Dave Airlie
+ * Alon Levy
+ * Michael Thayer <michael.thayer@oracle.com,
+ * Hans de Goede <hdegoede@redhat.com>
+ */
+
+#include <drm/drm_crtc_helper.h>
+
+#include "vbox_drv.h"
+#include "vboxvideo.h"
+
+static void vbox_clear_irq(void)
+{
+ outl((u32)~0, VGA_PORT_HGSMI_HOST);
+}
+
+static u32 vbox_get_flags(struct vbox_private *vbox)
+{
+ return readl(vbox->guest_heap + HOST_FLAGS_OFFSET);
+}
+
+void vbox_report_hotplug(struct vbox_private *vbox)
+{
+ schedule_work(&vbox->hotplug_work);
+}
+
+irqreturn_t vbox_irq_handler(int irq, void *arg)
+{
+ struct drm_device *dev = (struct drm_device *)arg;
+ struct vbox_private *vbox = (struct vbox_private *)dev->dev_private;
+ u32 host_flags = vbox_get_flags(vbox);
+
+ if (!(host_flags & HGSMIHOSTFLAGS_IRQ))
+ return IRQ_NONE;
+
+ /*
+ * Due to a bug in the initial host implementation of hot-plug irqs,
+ * the hot-plug and cursor capability flags were never cleared.
+ * Fortunately we can tell when they would have been set by checking
+ * that the VSYNC flag is not set.
+ */
+ if (host_flags &
+ (HGSMIHOSTFLAGS_HOTPLUG | HGSMIHOSTFLAGS_CURSOR_CAPABILITIES) &&
+ !(host_flags & HGSMIHOSTFLAGS_VSYNC))
+ vbox_report_hotplug(vbox);
+
+ vbox_clear_irq();
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * Check that the position hints provided by the host are suitable for GNOME
+ * shell (i.e. all screens disjoint and hints for all enabled screens) and if
+ * not replace them with default ones. Providing valid hints improves the
+ * chances that we will get a known screen layout for pointer mapping.
+ */
+static void validate_or_set_position_hints(struct vbox_private *vbox)
+{
+ struct vbva_modehint *hintsi, *hintsj;
+ bool valid = true;
+ u16 currentx = 0;
+ int i, j;
+
+ for (i = 0; i < vbox->num_crtcs; ++i) {
+ for (j = 0; j < i; ++j) {
+ hintsi = &vbox->last_mode_hints[i];
+ hintsj = &vbox->last_mode_hints[j];
+
+ if (hintsi->enabled && hintsj->enabled) {
+ if (hintsi->dx >= 0xffff ||
+ hintsi->dy >= 0xffff ||
+ hintsj->dx >= 0xffff ||
+ hintsj->dy >= 0xffff ||
+ (hintsi->dx <
+ hintsj->dx + (hintsj->cx & 0x8fff) &&
+ hintsi->dx + (hintsi->cx & 0x8fff) >
+ hintsj->dx) ||
+ (hintsi->dy <
+ hintsj->dy + (hintsj->cy & 0x8fff) &&
+ hintsi->dy + (hintsi->cy & 0x8fff) >
+ hintsj->dy))
+ valid = false;
+ }
+ }
+ }
+ if (!valid)
+ for (i = 0; i < vbox->num_crtcs; ++i) {
+ if (vbox->last_mode_hints[i].enabled) {
+ vbox->last_mode_hints[i].dx = currentx;
+ vbox->last_mode_hints[i].dy = 0;
+ currentx +=
+ vbox->last_mode_hints[i].cx & 0x8fff;
+ }
+ }
+}
+
+/**
+ * Query the host for the most recent video mode hints.
+ */
+static void vbox_update_mode_hints(struct vbox_private *vbox)
+{
+ struct drm_device *dev = vbox->dev;
+ struct drm_connector *connector;
+ struct vbox_connector *vbox_conn;
+ struct vbva_modehint *hints;
+ u16 flags;
+ bool disconnected;
+ unsigned int crtc_id;
+ int ret;
+
+ ret = hgsmi_get_mode_hints(vbox->guest_pool, vbox->num_crtcs,
+ vbox->last_mode_hints);
+ if (ret) {
+ DRM_ERROR("vboxvideo: hgsmi_get_mode_hints failed: %d\n", ret);
+ return;
+ }
+
+ validate_or_set_position_hints(vbox);
+ drm_modeset_lock_all(dev);
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ vbox_conn = to_vbox_connector(connector);
+
+ hints = &vbox->last_mode_hints[vbox_conn->vbox_crtc->crtc_id];
+ if (hints->magic != VBVAMODEHINT_MAGIC)
+ continue;
+
+ disconnected = !(hints->enabled);
+ crtc_id = vbox_conn->vbox_crtc->crtc_id;
+ vbox_conn->mode_hint.width = hints->cx & 0x8fff;
+ vbox_conn->mode_hint.height = hints->cy & 0x8fff;
+ vbox_conn->vbox_crtc->x_hint = hints->dx;
+ vbox_conn->vbox_crtc->y_hint = hints->dy;
+ vbox_conn->mode_hint.disconnected = disconnected;
+
+ if (vbox_conn->vbox_crtc->disconnected == disconnected)
+ continue;
+
+ if (disconnected)
+ flags = VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_DISABLED;
+ else
+ flags = VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_BLANK;
+
+ hgsmi_process_display_info(vbox->guest_pool, crtc_id, 0, 0, 0,
+ hints->cx * 4, hints->cx,
+ hints->cy, 0, flags);
+
+ vbox_conn->vbox_crtc->disconnected = disconnected;
+ }
+ drm_modeset_unlock_all(dev);
+}
+
+static void vbox_hotplug_worker(struct work_struct *work)
+{
+ struct vbox_private *vbox = container_of(work, struct vbox_private,
+ hotplug_work);
+
+ vbox_update_mode_hints(vbox);
+ drm_kms_helper_hotplug_event(vbox->dev);
+}
+
+int vbox_irq_init(struct vbox_private *vbox)
+{
+ INIT_WORK(&vbox->hotplug_work, vbox_hotplug_worker);
+ vbox_update_mode_hints(vbox);
+
+ return drm_irq_install(vbox->dev, vbox->dev->pdev->irq);
+}
+
+void vbox_irq_fini(struct vbox_private *vbox)
+{
+ drm_irq_uninstall(vbox->dev);
+ flush_work(&vbox->hotplug_work);
+}
diff --git a/drivers/staging/vboxvideo/vbox_main.c b/drivers/staging/vboxvideo/vbox_main.c
new file mode 100644
index 000000000000..80bd039fa08e
--- /dev/null
+++ b/drivers/staging/vboxvideo/vbox_main.c
@@ -0,0 +1,534 @@
+/*
+ * Copyright (C) 2013-2017 Oracle Corporation
+ * This file is based on ast_main.c
+ * Copyright 2012 Red Hat 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, 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 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * Authors: Dave Airlie <airlied@redhat.com>,
+ * Michael Thayer <michael.thayer@oracle.com,
+ * Hans de Goede <hdegoede@redhat.com>
+ */
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
+
+#include "vbox_drv.h"
+#include "vbox_err.h"
+#include "vboxvideo_guest.h"
+#include "vboxvideo_vbe.h"
+
+static void vbox_user_framebuffer_destroy(struct drm_framebuffer *fb)
+{
+ struct vbox_framebuffer *vbox_fb = to_vbox_framebuffer(fb);
+
+ if (vbox_fb->obj)
+ drm_gem_object_put_unlocked(vbox_fb->obj);
+
+ drm_framebuffer_cleanup(fb);
+ kfree(fb);
+}
+
+void vbox_enable_accel(struct vbox_private *vbox)
+{
+ unsigned int i;
+ struct vbva_buffer *vbva;
+
+ if (!vbox->vbva_info || !vbox->vbva_buffers) {
+ /* Should never happen... */
+ DRM_ERROR("vboxvideo: failed to set up VBVA.\n");
+ return;
+ }
+
+ for (i = 0; i < vbox->num_crtcs; ++i) {
+ if (vbox->vbva_info[i].vbva)
+ continue;
+
+ vbva = (void *)vbox->vbva_buffers + i * VBVA_MIN_BUFFER_SIZE;
+ if (!vbva_enable(&vbox->vbva_info[i],
+ vbox->guest_pool, vbva, i)) {
+ /* very old host or driver error. */
+ DRM_ERROR("vboxvideo: vbva_enable failed\n");
+ return;
+ }
+ }
+}
+
+void vbox_disable_accel(struct vbox_private *vbox)
+{
+ unsigned int i;
+
+ for (i = 0; i < vbox->num_crtcs; ++i)
+ vbva_disable(&vbox->vbva_info[i], vbox->guest_pool, i);
+}
+
+void vbox_report_caps(struct vbox_private *vbox)
+{
+ u32 caps = VBVACAPS_DISABLE_CURSOR_INTEGRATION |
+ VBVACAPS_IRQ | VBVACAPS_USE_VBVA_ONLY;
+
+ if (vbox->initial_mode_queried)
+ caps |= VBVACAPS_VIDEO_MODE_HINTS;
+
+ hgsmi_send_caps_info(vbox->guest_pool, caps);
+}
+
+/**
+ * Send information about dirty rectangles to VBVA. If necessary we enable
+ * VBVA first, as this is normally disabled after a change of master in case
+ * the new master does not send dirty rectangle information (is this even
+ * allowed?)
+ */
+void vbox_framebuffer_dirty_rectangles(struct drm_framebuffer *fb,
+ struct drm_clip_rect *rects,
+ unsigned int num_rects)
+{
+ struct vbox_private *vbox = fb->dev->dev_private;
+ struct drm_crtc *crtc;
+ unsigned int i;
+
+ mutex_lock(&vbox->hw_mutex);
+ list_for_each_entry(crtc, &fb->dev->mode_config.crtc_list, head) {
+ if (CRTC_FB(crtc) != fb)
+ continue;
+
+ vbox_enable_accel(vbox);
+
+ for (i = 0; i < num_rects; ++i) {
+ struct vbva_cmd_hdr cmd_hdr;
+ unsigned int crtc_id = to_vbox_crtc(crtc)->crtc_id;
+
+ if ((rects[i].x1 > crtc->x + crtc->hwmode.hdisplay) ||
+ (rects[i].y1 > crtc->y + crtc->hwmode.vdisplay) ||
+ (rects[i].x2 < crtc->x) ||
+ (rects[i].y2 < crtc->y))
+ continue;
+
+ cmd_hdr.x = (s16)rects[i].x1;
+ cmd_hdr.y = (s16)rects[i].y1;
+ cmd_hdr.w = (u16)rects[i].x2 - rects[i].x1;
+ cmd_hdr.h = (u16)rects[i].y2 - rects[i].y1;
+
+ if (!vbva_buffer_begin_update(&vbox->vbva_info[crtc_id],
+ vbox->guest_pool))
+ continue;
+
+ vbva_write(&vbox->vbva_info[crtc_id], vbox->guest_pool,
+ &cmd_hdr, sizeof(cmd_hdr));
+ vbva_buffer_end_update(&vbox->vbva_info[crtc_id]);
+ }
+ }
+ mutex_unlock(&vbox->hw_mutex);
+}
+
+static int vbox_user_framebuffer_dirty(struct drm_framebuffer *fb,
+ struct drm_file *file_priv,
+ unsigned int flags, unsigned int color,
+ struct drm_clip_rect *rects,
+ unsigned int num_rects)
+{
+ vbox_framebuffer_dirty_rectangles(fb, rects, num_rects);
+
+ return 0;
+}
+
+static const struct drm_framebuffer_funcs vbox_fb_funcs = {
+ .destroy = vbox_user_framebuffer_destroy,
+ .dirty = vbox_user_framebuffer_dirty,
+};
+
+int vbox_framebuffer_init(struct drm_device *dev,
+ struct vbox_framebuffer *vbox_fb,
+ const struct DRM_MODE_FB_CMD *mode_cmd,
+ struct drm_gem_object *obj)
+{
+ int ret;
+
+ drm_helper_mode_fill_fb_struct(dev, &vbox_fb->base, mode_cmd);
+ vbox_fb->obj = obj;
+ ret = drm_framebuffer_init(dev, &vbox_fb->base, &vbox_fb_funcs);
+ if (ret) {
+ DRM_ERROR("framebuffer init failed %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct drm_framebuffer *vbox_user_framebuffer_create(
+ struct drm_device *dev,
+ struct drm_file *filp,
+ const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+ struct drm_gem_object *obj;
+ struct vbox_framebuffer *vbox_fb;
+ int ret = -ENOMEM;
+
+ obj = drm_gem_object_lookup(filp, mode_cmd->handles[0]);
+ if (!obj)
+ return ERR_PTR(-ENOENT);
+
+ vbox_fb = kzalloc(sizeof(*vbox_fb), GFP_KERNEL);
+ if (!vbox_fb)
+ goto err_unref_obj;
+
+ ret = vbox_framebuffer_init(dev, vbox_fb, mode_cmd, obj);
+ if (ret)
+ goto err_free_vbox_fb;
+
+ return &vbox_fb->base;
+
+err_free_vbox_fb:
+ kfree(vbox_fb);
+err_unref_obj:
+ drm_gem_object_put_unlocked(obj);
+ return ERR_PTR(ret);
+}
+
+static const struct drm_mode_config_funcs vbox_mode_funcs = {
+ .fb_create = vbox_user_framebuffer_create,
+};
+
+static int vbox_accel_init(struct vbox_private *vbox)
+{
+ unsigned int i;
+
+ vbox->vbva_info = devm_kcalloc(vbox->dev->dev, vbox->num_crtcs,
+ sizeof(*vbox->vbva_info), GFP_KERNEL);
+ if (!vbox->vbva_info)
+ return -ENOMEM;
+
+ /* Take a command buffer for each screen from the end of usable VRAM. */
+ vbox->available_vram_size -= vbox->num_crtcs * VBVA_MIN_BUFFER_SIZE;
+
+ vbox->vbva_buffers = pci_iomap_range(vbox->dev->pdev, 0,
+ vbox->available_vram_size,
+ vbox->num_crtcs *
+ VBVA_MIN_BUFFER_SIZE);
+ if (!vbox->vbva_buffers)
+ return -ENOMEM;
+
+ for (i = 0; i < vbox->num_crtcs; ++i)
+ vbva_setup_buffer_context(&vbox->vbva_info[i],
+ vbox->available_vram_size +
+ i * VBVA_MIN_BUFFER_SIZE,
+ VBVA_MIN_BUFFER_SIZE);
+
+ return 0;
+}
+
+static void vbox_accel_fini(struct vbox_private *vbox)
+{
+ vbox_disable_accel(vbox);
+ pci_iounmap(vbox->dev->pdev, vbox->vbva_buffers);
+}
+
+/** Do we support the 4.3 plus mode hint reporting interface? */
+static bool have_hgsmi_mode_hints(struct vbox_private *vbox)
+{
+ u32 have_hints, have_cursor;
+ int ret;
+
+ ret = hgsmi_query_conf(vbox->guest_pool,
+ VBOX_VBVA_CONF32_MODE_HINT_REPORTING,
+ &have_hints);
+ if (ret)
+ return false;
+
+ ret = hgsmi_query_conf(vbox->guest_pool,
+ VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING,
+ &have_cursor);
+ if (ret)
+ return false;
+
+ return have_hints == VINF_SUCCESS && have_cursor == VINF_SUCCESS;
+}
+
+static bool vbox_check_supported(u16 id)
+{
+ u16 dispi_id;
+
+ vbox_write_ioport(VBE_DISPI_INDEX_ID, id);
+ dispi_id = inw(VBE_DISPI_IOPORT_DATA);
+
+ return dispi_id == id;
+}
+
+/**
+ * Set up our heaps and data exchange buffers in VRAM before handing the rest
+ * to the memory manager.
+ */
+static int vbox_hw_init(struct vbox_private *vbox)
+{
+ int ret = -ENOMEM;
+
+ vbox->full_vram_size = inl(VBE_DISPI_IOPORT_DATA);
+ vbox->any_pitch = vbox_check_supported(VBE_DISPI_ID_ANYX);
+
+ DRM_INFO("VRAM %08x\n", vbox->full_vram_size);
+
+ /* Map guest-heap at end of vram */
+ vbox->guest_heap =
+ pci_iomap_range(vbox->dev->pdev, 0, GUEST_HEAP_OFFSET(vbox),
+ GUEST_HEAP_SIZE);
+ if (!vbox->guest_heap)
+ return -ENOMEM;
+
+ /* Create guest-heap mem-pool use 2^4 = 16 byte chunks */
+ vbox->guest_pool = gen_pool_create(4, -1);
+ if (!vbox->guest_pool)
+ goto err_unmap_guest_heap;
+
+ ret = gen_pool_add_virt(vbox->guest_pool,
+ (unsigned long)vbox->guest_heap,
+ GUEST_HEAP_OFFSET(vbox),
+ GUEST_HEAP_USABLE_SIZE, -1);
+ if (ret)
+ goto err_destroy_guest_pool;
+
+ ret = hgsmi_test_query_conf(vbox->guest_pool);
+ if (ret) {
+ DRM_ERROR("vboxvideo: hgsmi_test_query_conf failed\n");
+ goto err_destroy_guest_pool;
+ }
+
+ /* Reduce available VRAM size to reflect the guest heap. */
+ vbox->available_vram_size = GUEST_HEAP_OFFSET(vbox);
+ /* Linux drm represents monitors as a 32-bit array. */
+ hgsmi_query_conf(vbox->guest_pool, VBOX_VBVA_CONF32_MONITOR_COUNT,
+ &vbox->num_crtcs);
+ vbox->num_crtcs = clamp_t(u32, vbox->num_crtcs, 1, VBOX_MAX_SCREENS);
+
+ if (!have_hgsmi_mode_hints(vbox)) {
+ ret = -ENOTSUPP;
+ goto err_destroy_guest_pool;
+ }
+
+ vbox->last_mode_hints = devm_kcalloc(vbox->dev->dev, vbox->num_crtcs,
+ sizeof(struct vbva_modehint),
+ GFP_KERNEL);
+ if (!vbox->last_mode_hints) {
+ ret = -ENOMEM;
+ goto err_destroy_guest_pool;
+ }
+
+ ret = vbox_accel_init(vbox);
+ if (ret)
+ goto err_destroy_guest_pool;
+
+ return 0;
+
+err_destroy_guest_pool:
+ gen_pool_destroy(vbox->guest_pool);
+err_unmap_guest_heap:
+ pci_iounmap(vbox->dev->pdev, vbox->guest_heap);
+ return ret;
+}
+
+static void vbox_hw_fini(struct vbox_private *vbox)
+{
+ vbox_accel_fini(vbox);
+ gen_pool_destroy(vbox->guest_pool);
+ pci_iounmap(vbox->dev->pdev, vbox->guest_heap);
+}
+
+int vbox_driver_load(struct drm_device *dev, unsigned long flags)
+{
+ struct vbox_private *vbox;
+ int ret = 0;
+
+ if (!vbox_check_supported(VBE_DISPI_ID_HGSMI))
+ return -ENODEV;
+
+ vbox = devm_kzalloc(dev->dev, sizeof(*vbox), GFP_KERNEL);
+ if (!vbox)
+ return -ENOMEM;
+
+ dev->dev_private = vbox;
+ vbox->dev = dev;
+
+ mutex_init(&vbox->hw_mutex);
+
+ ret = vbox_hw_init(vbox);
+ if (ret)
+ return ret;
+
+ ret = vbox_mm_init(vbox);
+ if (ret)
+ goto err_hw_fini;
+
+ drm_mode_config_init(dev);
+
+ dev->mode_config.funcs = (void *)&vbox_mode_funcs;
+ dev->mode_config.min_width = 64;
+ dev->mode_config.min_height = 64;
+ dev->mode_config.preferred_depth = 24;
+ dev->mode_config.max_width = VBE_DISPI_MAX_XRES;
+ dev->mode_config.max_height = VBE_DISPI_MAX_YRES;
+
+ ret = vbox_mode_init(dev);
+ if (ret)
+ goto err_drm_mode_cleanup;
+
+ ret = vbox_irq_init(vbox);
+ if (ret)
+ goto err_mode_fini;
+
+ ret = vbox_fbdev_init(dev);
+ if (ret)
+ goto err_irq_fini;
+
+ return 0;
+
+err_irq_fini:
+ vbox_irq_fini(vbox);
+err_mode_fini:
+ vbox_mode_fini(dev);
+err_drm_mode_cleanup:
+ drm_mode_config_cleanup(dev);
+ vbox_mm_fini(vbox);
+err_hw_fini:
+ vbox_hw_fini(vbox);
+ return ret;
+}
+
+void vbox_driver_unload(struct drm_device *dev)
+{
+ struct vbox_private *vbox = dev->dev_private;
+
+ vbox_fbdev_fini(dev);
+ vbox_irq_fini(vbox);
+ vbox_mode_fini(dev);
+ drm_mode_config_cleanup(dev);
+ vbox_mm_fini(vbox);
+ vbox_hw_fini(vbox);
+}
+
+/**
+ * @note this is described in the DRM framework documentation. AST does not
+ * have it, but we get an oops on driver unload if it is not present.
+ */
+void vbox_driver_lastclose(struct drm_device *dev)
+{
+ struct vbox_private *vbox = dev->dev_private;
+
+ if (vbox->fbdev)
+ drm_fb_helper_restore_fbdev_mode_unlocked(&vbox->fbdev->helper);
+}
+
+int vbox_gem_create(struct drm_device *dev,
+ u32 size, bool iskernel, struct drm_gem_object **obj)
+{
+ struct vbox_bo *vboxbo;
+ int ret;
+
+ *obj = NULL;
+
+ size = roundup(size, PAGE_SIZE);
+ if (size == 0)
+ return -EINVAL;
+
+ ret = vbox_bo_create(dev, size, 0, 0, &vboxbo);
+ if (ret) {
+ if (ret != -ERESTARTSYS)
+ DRM_ERROR("failed to allocate GEM object\n");
+ return ret;
+ }
+
+ *obj = &vboxbo->gem;
+
+ return 0;
+}
+
+int vbox_dumb_create(struct drm_file *file,
+ struct drm_device *dev, struct drm_mode_create_dumb *args)
+{
+ int ret;
+ struct drm_gem_object *gobj;
+ u32 handle;
+
+ args->pitch = args->width * ((args->bpp + 7) / 8);
+ args->size = args->pitch * args->height;
+
+ ret = vbox_gem_create(dev, args->size, false, &gobj);
+ if (ret)
+ return ret;
+
+ ret = drm_gem_handle_create(file, gobj, &handle);
+ drm_gem_object_put_unlocked(gobj);
+ if (ret)
+ return ret;
+
+ args->handle = handle;
+
+ return 0;
+}
+
+static void vbox_bo_unref(struct vbox_bo **bo)
+{
+ struct ttm_buffer_object *tbo;
+
+ if ((*bo) == NULL)
+ return;
+
+ tbo = &((*bo)->bo);
+ ttm_bo_unref(&tbo);
+ if (!tbo)
+ *bo = NULL;
+}
+
+void vbox_gem_free_object(struct drm_gem_object *obj)
+{
+ struct vbox_bo *vbox_bo = gem_to_vbox_bo(obj);
+
+ vbox_bo_unref(&vbox_bo);
+}
+
+static inline u64 vbox_bo_mmap_offset(struct vbox_bo *bo)
+{
+ return drm_vma_node_offset_addr(&bo->bo.vma_node);
+}
+
+int
+vbox_dumb_mmap_offset(struct drm_file *file,
+ struct drm_device *dev,
+ u32 handle, u64 *offset)
+{
+ struct drm_gem_object *obj;
+ int ret;
+ struct vbox_bo *bo;
+
+ mutex_lock(&dev->struct_mutex);
+ obj = drm_gem_object_lookup(file, handle);
+ if (!obj) {
+ ret = -ENOENT;
+ goto out_unlock;
+ }
+
+ bo = gem_to_vbox_bo(obj);
+ *offset = vbox_bo_mmap_offset(bo);
+
+ drm_gem_object_put(obj);
+ ret = 0;
+
+out_unlock:
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+}
diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c
new file mode 100644
index 000000000000..e5b6383984e7
--- /dev/null
+++ b/drivers/staging/vboxvideo/vbox_mode.c
@@ -0,0 +1,872 @@
+/*
+ * Copyright (C) 2013-2017 Oracle Corporation
+ * This file is based on ast_mode.c
+ * Copyright 2012 Red Hat Inc.
+ * Parts based on xf86-video-ast
+ * Copyright (c) 2005 ASPEED Technology 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, 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 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ */
+/*
+ * Authors: Dave Airlie <airlied@redhat.com>
+ * Michael Thayer <michael.thayer@oracle.com,
+ * Hans de Goede <hdegoede@redhat.com>
+ */
+#include <linux/export.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_plane_helper.h>
+
+#include "vbox_drv.h"
+#include "vboxvideo.h"
+#include "hgsmi_channels.h"
+
+static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
+ u32 handle, u32 width, u32 height,
+ s32 hot_x, s32 hot_y);
+static int vbox_cursor_move(struct drm_crtc *crtc, int x, int y);
+
+/**
+ * Set a graphics mode. Poke any required values into registers, do an HGSMI
+ * mode set and tell the host we support advanced graphics functions.
+ */
+static void vbox_do_modeset(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode)
+{
+ struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
+ struct vbox_private *vbox;
+ int width, height, bpp, pitch;
+ unsigned int crtc_id;
+ u16 flags;
+ s32 x_offset, y_offset;
+
+ vbox = crtc->dev->dev_private;
+ width = mode->hdisplay ? mode->hdisplay : 640;
+ height = mode->vdisplay ? mode->vdisplay : 480;
+ crtc_id = vbox_crtc->crtc_id;
+ bpp = crtc->enabled ? CRTC_FB(crtc)->format->cpp[0] * 8 : 32;
+ pitch = crtc->enabled ? CRTC_FB(crtc)->pitches[0] : width * bpp / 8;
+ x_offset = vbox->single_framebuffer ? crtc->x : vbox_crtc->x_hint;
+ y_offset = vbox->single_framebuffer ? crtc->y : vbox_crtc->y_hint;
+
+ /*
+ * This is the old way of setting graphics modes. It assumed one screen
+ * and a frame-buffer at the start of video RAM. On older versions of
+ * VirtualBox, certain parts of the code still assume that the first
+ * screen is programmed this way, so try to fake it.
+ */
+ if (vbox_crtc->crtc_id == 0 && crtc->enabled &&
+ vbox_crtc->fb_offset / pitch < 0xffff - crtc->y &&
+ vbox_crtc->fb_offset % (bpp / 8) == 0) {
+ vbox_write_ioport(VBE_DISPI_INDEX_XRES, width);
+ vbox_write_ioport(VBE_DISPI_INDEX_YRES, height);
+ vbox_write_ioport(VBE_DISPI_INDEX_VIRT_WIDTH, pitch * 8 / bpp);
+ vbox_write_ioport(VBE_DISPI_INDEX_BPP,
+ CRTC_FB(crtc)->format->cpp[0] * 8);
+ vbox_write_ioport(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED);
+ vbox_write_ioport(
+ VBE_DISPI_INDEX_X_OFFSET,
+ vbox_crtc->fb_offset % pitch / bpp * 8 + crtc->x);
+ vbox_write_ioport(VBE_DISPI_INDEX_Y_OFFSET,
+ vbox_crtc->fb_offset / pitch + crtc->y);
+ }
+
+ flags = VBVA_SCREEN_F_ACTIVE;
+ flags |= (crtc->enabled && !vbox_crtc->blanked) ?
+ 0 : VBVA_SCREEN_F_BLANK;
+ flags |= vbox_crtc->disconnected ? VBVA_SCREEN_F_DISABLED : 0;
+ hgsmi_process_display_info(vbox->guest_pool, vbox_crtc->crtc_id,
+ x_offset, y_offset,
+ crtc->x * bpp / 8 + crtc->y * pitch,
+ pitch, width, height,
+ vbox_crtc->blanked ? 0 : bpp, flags);
+}
+
+static int vbox_set_view(struct drm_crtc *crtc)
+{
+ struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
+ struct vbox_private *vbox = crtc->dev->dev_private;
+ struct vbva_infoview *p;
+
+ /*
+ * Tell the host about the view. This design originally targeted the
+ * Windows XP driver architecture and assumed that each screen would
+ * have a dedicated frame buffer with the command buffer following it,
+ * the whole being a "view". The host works out which screen a command
+ * buffer belongs to by checking whether it is in the first view, then
+ * whether it is in the second and so on. The first match wins. We
+ * cheat around this by making the first view be the managed memory
+ * plus the first command buffer, the second the same plus the second
+ * buffer and so on.
+ */
+ p = hgsmi_buffer_alloc(vbox->guest_pool, sizeof(*p),
+ HGSMI_CH_VBVA, VBVA_INFO_VIEW);
+ if (!p)
+ return -ENOMEM;
+
+ p->view_index = vbox_crtc->crtc_id;
+ p->view_offset = vbox_crtc->fb_offset;
+ p->view_size = vbox->available_vram_size - vbox_crtc->fb_offset +
+ vbox_crtc->crtc_id * VBVA_MIN_BUFFER_SIZE;
+ p->max_screen_size = vbox->available_vram_size - vbox_crtc->fb_offset;
+
+ hgsmi_buffer_submit(vbox->guest_pool, p);
+ hgsmi_buffer_free(vbox->guest_pool, p);
+
+ return 0;
+}
+
+static void vbox_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+ struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
+ struct vbox_private *vbox = crtc->dev->dev_private;
+
+ switch (mode) {
+ case DRM_MODE_DPMS_ON:
+ vbox_crtc->blanked = false;
+ break;
+ case DRM_MODE_DPMS_STANDBY:
+ case DRM_MODE_DPMS_SUSPEND:
+ case DRM_MODE_DPMS_OFF:
+ vbox_crtc->blanked = true;
+ break;
+ }
+
+ mutex_lock(&vbox->hw_mutex);
+ vbox_do_modeset(crtc, &crtc->hwmode);
+ mutex_unlock(&vbox->hw_mutex);
+}
+
+static bool vbox_crtc_mode_fixup(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ return true;
+}
+
+/*
+ * Try to map the layout of virtual screens to the range of the input device.
+ * Return true if we need to re-set the crtc modes due to screen offset
+ * changes.
+ */
+static bool vbox_set_up_input_mapping(struct vbox_private *vbox)
+{
+ struct drm_crtc *crtci;
+ struct drm_connector *connectori;
+ struct drm_framebuffer *fb1 = NULL;
+ bool single_framebuffer = true;
+ bool old_single_framebuffer = vbox->single_framebuffer;
+ u16 width = 0, height = 0;
+
+ /*
+ * Are we using an X.Org-style single large frame-buffer for all crtcs?
+ * If so then screen layout can be deduced from the crtc offsets.
+ * Same fall-back if this is the fbdev frame-buffer.
+ */
+ list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list, head) {
+ if (!fb1) {
+ fb1 = CRTC_FB(crtci);
+ if (to_vbox_framebuffer(fb1) == &vbox->fbdev->afb)
+ break;
+ } else if (CRTC_FB(crtci) && fb1 != CRTC_FB(crtci)) {
+ single_framebuffer = false;
+ }
+ }
+ if (single_framebuffer) {
+ list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
+ head) {
+ if (to_vbox_crtc(crtci)->crtc_id != 0)
+ continue;
+
+ vbox->single_framebuffer = true;
+ vbox->input_mapping_width = CRTC_FB(crtci)->width;
+ vbox->input_mapping_height = CRTC_FB(crtci)->height;
+ return old_single_framebuffer !=
+ vbox->single_framebuffer;
+ }
+ }
+ /* Otherwise calculate the total span of all screens. */
+ list_for_each_entry(connectori, &vbox->dev->mode_config.connector_list,
+ head) {
+ struct vbox_connector *vbox_connector =
+ to_vbox_connector(connectori);
+ struct vbox_crtc *vbox_crtc = vbox_connector->vbox_crtc;
+
+ width = max_t(u16, width, vbox_crtc->x_hint +
+ vbox_connector->mode_hint.width);
+ height = max_t(u16, height, vbox_crtc->y_hint +
+ vbox_connector->mode_hint.height);
+ }
+
+ vbox->single_framebuffer = false;
+ vbox->input_mapping_width = width;
+ vbox->input_mapping_height = height;
+
+ return old_single_framebuffer != vbox->single_framebuffer;
+}
+
+static int vbox_crtc_do_set_base(struct drm_crtc *crtc,
+ struct drm_framebuffer *old_fb, int x, int y)
+{
+ struct vbox_private *vbox = crtc->dev->dev_private;
+ struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
+ struct drm_gem_object *obj;
+ struct vbox_framebuffer *vbox_fb;
+ struct vbox_bo *bo;
+ int ret;
+ u64 gpu_addr;
+
+ /* Unpin the previous fb. */
+ if (old_fb) {
+ vbox_fb = to_vbox_framebuffer(old_fb);
+ obj = vbox_fb->obj;
+ bo = gem_to_vbox_bo(obj);
+ ret = vbox_bo_reserve(bo, false);
+ if (ret)
+ return ret;
+
+ vbox_bo_unpin(bo);
+ vbox_bo_unreserve(bo);
+ }
+
+ vbox_fb = to_vbox_framebuffer(CRTC_FB(crtc));
+ obj = vbox_fb->obj;
+ bo = gem_to_vbox_bo(obj);
+
+ ret = vbox_bo_reserve(bo, false);
+ if (ret)
+ return ret;
+
+ ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
+ if (ret) {
+ vbox_bo_unreserve(bo);
+ return ret;
+ }
+
+ if (&vbox->fbdev->afb == vbox_fb)
+ vbox_fbdev_set_base(vbox, gpu_addr);
+ vbox_bo_unreserve(bo);
+
+ /* vbox_set_start_address_crt1(crtc, (u32)gpu_addr); */
+ vbox_crtc->fb_offset = gpu_addr;
+ if (vbox_set_up_input_mapping(vbox)) {
+ struct drm_crtc *crtci;
+
+ list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
+ head) {
+ vbox_set_view(crtc);
+ vbox_do_modeset(crtci, &crtci->mode);
+ }
+ }
+
+ return 0;
+}
+
+static int vbox_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+ struct drm_framebuffer *old_fb)
+{
+ return vbox_crtc_do_set_base(crtc, old_fb, x, y);
+}
+
+static int vbox_crtc_mode_set(struct drm_crtc *crtc,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode,
+ int x, int y, struct drm_framebuffer *old_fb)
+{
+ struct vbox_private *vbox = crtc->dev->dev_private;
+ int ret;
+
+ vbox_crtc_mode_set_base(crtc, x, y, old_fb);
+
+ mutex_lock(&vbox->hw_mutex);
+ ret = vbox_set_view(crtc);
+ if (!ret)
+ vbox_do_modeset(crtc, mode);
+ hgsmi_update_input_mapping(vbox->guest_pool, 0, 0,
+ vbox->input_mapping_width,
+ vbox->input_mapping_height);
+ mutex_unlock(&vbox->hw_mutex);
+
+ return ret;
+}
+
+static void vbox_crtc_disable(struct drm_crtc *crtc)
+{
+}
+
+static void vbox_crtc_prepare(struct drm_crtc *crtc)
+{
+}
+
+static void vbox_crtc_commit(struct drm_crtc *crtc)
+{
+}
+
+static const struct drm_crtc_helper_funcs vbox_crtc_helper_funcs = {
+ .dpms = vbox_crtc_dpms,
+ .mode_fixup = vbox_crtc_mode_fixup,
+ .mode_set = vbox_crtc_mode_set,
+ /* .mode_set_base = vbox_crtc_mode_set_base, */
+ .disable = vbox_crtc_disable,
+ .prepare = vbox_crtc_prepare,
+ .commit = vbox_crtc_commit,
+};
+
+static void vbox_crtc_reset(struct drm_crtc *crtc)
+{
+}
+
+static void vbox_crtc_destroy(struct drm_crtc *crtc)
+{
+ drm_crtc_cleanup(crtc);
+ kfree(crtc);
+}
+
+static const struct drm_crtc_funcs vbox_crtc_funcs = {
+ .cursor_move = vbox_cursor_move,
+ .cursor_set2 = vbox_cursor_set2,
+ .reset = vbox_crtc_reset,
+ .set_config = drm_crtc_helper_set_config,
+ /* .gamma_set = vbox_crtc_gamma_set, */
+ .destroy = vbox_crtc_destroy,
+};
+
+static struct vbox_crtc *vbox_crtc_init(struct drm_device *dev, unsigned int i)
+{
+ struct vbox_crtc *vbox_crtc;
+
+ vbox_crtc = kzalloc(sizeof(*vbox_crtc), GFP_KERNEL);
+ if (!vbox_crtc)
+ return NULL;
+
+ vbox_crtc->crtc_id = i;
+
+ drm_crtc_init(dev, &vbox_crtc->base, &vbox_crtc_funcs);
+ drm_mode_crtc_set_gamma_size(&vbox_crtc->base, 256);
+ drm_crtc_helper_add(&vbox_crtc->base, &vbox_crtc_helper_funcs);
+
+ return vbox_crtc;
+}
+
+static void vbox_encoder_destroy(struct drm_encoder *encoder)
+{
+ drm_encoder_cleanup(encoder);
+ kfree(encoder);
+}
+
+static struct drm_encoder *vbox_best_single_encoder(struct drm_connector
+ *connector)
+{
+ int enc_id = connector->encoder_ids[0];
+
+ /* pick the encoder ids */
+ if (enc_id)
+ return drm_encoder_find(connector->dev, enc_id);
+
+ return NULL;
+}
+
+static const struct drm_encoder_funcs vbox_enc_funcs = {
+ .destroy = vbox_encoder_destroy,
+};
+
+static void vbox_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+}
+
+static bool vbox_mode_fixup(struct drm_encoder *encoder,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ return true;
+}
+
+static void vbox_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+}
+
+static void vbox_encoder_prepare(struct drm_encoder *encoder)
+{
+}
+
+static void vbox_encoder_commit(struct drm_encoder *encoder)
+{
+}
+
+static const struct drm_encoder_helper_funcs vbox_enc_helper_funcs = {
+ .dpms = vbox_encoder_dpms,
+ .mode_fixup = vbox_mode_fixup,
+ .prepare = vbox_encoder_prepare,
+ .commit = vbox_encoder_commit,
+ .mode_set = vbox_encoder_mode_set,
+};
+
+static struct drm_encoder *vbox_encoder_init(struct drm_device *dev,
+ unsigned int i)
+{
+ struct vbox_encoder *vbox_encoder;
+
+ vbox_encoder = kzalloc(sizeof(*vbox_encoder), GFP_KERNEL);
+ if (!vbox_encoder)
+ return NULL;
+
+ drm_encoder_init(dev, &vbox_encoder->base, &vbox_enc_funcs,
+ DRM_MODE_ENCODER_DAC, NULL);
+ drm_encoder_helper_add(&vbox_encoder->base, &vbox_enc_helper_funcs);
+
+ vbox_encoder->base.possible_crtcs = 1 << i;
+ return &vbox_encoder->base;
+}
+
+/**
+ * Generate EDID data with a mode-unique serial number for the virtual
+ * monitor to try to persuade Unity that different modes correspond to
+ * different monitors and it should not try to force the same resolution on
+ * them.
+ */
+static void vbox_set_edid(struct drm_connector *connector, int width,
+ int height)
+{
+ enum { EDID_SIZE = 128 };
+ unsigned char edid[EDID_SIZE] = {
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* header */
+ 0x58, 0x58, /* manufacturer (VBX) */
+ 0x00, 0x00, /* product code */
+ 0x00, 0x00, 0x00, 0x00, /* serial number goes here */
+ 0x01, /* week of manufacture */
+ 0x00, /* year of manufacture */
+ 0x01, 0x03, /* EDID version */
+ 0x80, /* capabilities - digital */
+ 0x00, /* horiz. res in cm, zero for projectors */
+ 0x00, /* vert. res in cm */
+ 0x78, /* display gamma (120 == 2.2). */
+ 0xEE, /* features (standby, suspend, off, RGB, std */
+ /* colour space, preferred timing mode) */
+ 0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54,
+ /* chromaticity for standard colour space. */
+ 0x00, 0x00, 0x00, /* no default timings */
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, /* no standard timings */
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x02, 0x02,
+ 0x02, 0x02,
+ /* descriptor block 1 goes below */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* descriptor block 2, monitor ranges */
+ 0x00, 0x00, 0x00, 0xFD, 0x00,
+ 0x00, 0xC8, 0x00, 0xC8, 0x64, 0x00, 0x0A, 0x20, 0x20, 0x20,
+ 0x20, 0x20,
+ /* 0-200Hz vertical, 0-200KHz horizontal, 1000MHz pixel clock */
+ 0x20,
+ /* descriptor block 3, monitor name */
+ 0x00, 0x00, 0x00, 0xFC, 0x00,
+ 'V', 'B', 'O', 'X', ' ', 'm', 'o', 'n', 'i', 't', 'o', 'r',
+ '\n',
+ /* descriptor block 4: dummy data */
+ 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20,
+ 0x00, /* number of extensions */
+ 0x00 /* checksum goes here */
+ };
+ int clock = (width + 6) * (height + 6) * 60 / 10000;
+ unsigned int i, sum = 0;
+
+ edid[12] = width & 0xff;
+ edid[13] = width >> 8;
+ edid[14] = height & 0xff;
+ edid[15] = height >> 8;
+ edid[54] = clock & 0xff;
+ edid[55] = clock >> 8;
+ edid[56] = width & 0xff;
+ edid[58] = (width >> 4) & 0xf0;
+ edid[59] = height & 0xff;
+ edid[61] = (height >> 4) & 0xf0;
+ for (i = 0; i < EDID_SIZE - 1; ++i)
+ sum += edid[i];
+ edid[EDID_SIZE - 1] = (0x100 - (sum & 0xFF)) & 0xFF;
+ drm_mode_connector_update_edid_property(connector, (struct edid *)edid);
+}
+
+static int vbox_get_modes(struct drm_connector *connector)
+{
+ struct vbox_connector *vbox_connector = NULL;
+ struct drm_display_mode *mode = NULL;
+ struct vbox_private *vbox = NULL;
+ unsigned int num_modes = 0;
+ int preferred_width, preferred_height;
+
+ vbox_connector = to_vbox_connector(connector);
+ vbox = connector->dev->dev_private;
+ /*
+ * Heuristic: we do not want to tell the host that we support dynamic
+ * resizing unless we feel confident that the user space client using
+ * the video driver can handle hot-plug events. So the first time modes
+ * are queried after a "master" switch we tell the host that we do not,
+ * and immediately after we send the client a hot-plug notification as
+ * a test to see if they will respond and query again.
+ * That is also the reason why capabilities are reported to the host at
+ * this place in the code rather than elsewhere.
+ * We need to report the flags location before reporting the IRQ
+ * capability.
+ */
+ hgsmi_report_flags_location(vbox->guest_pool, GUEST_HEAP_OFFSET(vbox) +
+ HOST_FLAGS_OFFSET);
+ if (vbox_connector->vbox_crtc->crtc_id == 0)
+ vbox_report_caps(vbox);
+ if (!vbox->initial_mode_queried) {
+ if (vbox_connector->vbox_crtc->crtc_id == 0) {
+ vbox->initial_mode_queried = true;
+ vbox_report_hotplug(vbox);
+ }
+ return drm_add_modes_noedid(connector, 800, 600);
+ }
+ num_modes = drm_add_modes_noedid(connector, 2560, 1600);
+ preferred_width = vbox_connector->mode_hint.width ?
+ vbox_connector->mode_hint.width : 1024;
+ preferred_height = vbox_connector->mode_hint.height ?
+ vbox_connector->mode_hint.height : 768;
+ mode = drm_cvt_mode(connector->dev, preferred_width, preferred_height,
+ 60, false, false, false);
+ if (mode) {
+ mode->type |= DRM_MODE_TYPE_PREFERRED;
+ drm_mode_probed_add(connector, mode);
+ ++num_modes;
+ }
+ vbox_set_edid(connector, preferred_width, preferred_height);
+ drm_object_property_set_value(
+ &connector->base, vbox->dev->mode_config.suggested_x_property,
+ vbox_connector->vbox_crtc->x_hint);
+ drm_object_property_set_value(
+ &connector->base, vbox->dev->mode_config.suggested_y_property,
+ vbox_connector->vbox_crtc->y_hint);
+
+ return num_modes;
+}
+
+static int vbox_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ return MODE_OK;
+}
+
+static void vbox_connector_destroy(struct drm_connector *connector)
+{
+ struct vbox_connector *vbox_connector;
+
+ vbox_connector = to_vbox_connector(connector);
+ drm_connector_unregister(connector);
+ drm_connector_cleanup(connector);
+ kfree(connector);
+}
+
+static enum drm_connector_status
+vbox_connector_detect(struct drm_connector *connector, bool force)
+{
+ struct vbox_connector *vbox_connector;
+
+ vbox_connector = to_vbox_connector(connector);
+
+ return vbox_connector->mode_hint.disconnected ?
+ connector_status_disconnected : connector_status_connected;
+}
+
+static int vbox_fill_modes(struct drm_connector *connector, u32 max_x,
+ u32 max_y)
+{
+ struct vbox_connector *vbox_connector;
+ struct drm_device *dev;
+ struct drm_display_mode *mode, *iterator;
+
+ vbox_connector = to_vbox_connector(connector);
+ dev = vbox_connector->base.dev;
+ list_for_each_entry_safe(mode, iterator, &connector->modes, head) {
+ list_del(&mode->head);
+ drm_mode_destroy(dev, mode);
+ }
+
+ return drm_helper_probe_single_connector_modes(connector, max_x, max_y);
+}
+
+static const struct drm_connector_helper_funcs vbox_connector_helper_funcs = {
+ .mode_valid = vbox_mode_valid,
+ .get_modes = vbox_get_modes,
+ .best_encoder = vbox_best_single_encoder,
+};
+
+static const struct drm_connector_funcs vbox_connector_funcs = {
+ .dpms = drm_helper_connector_dpms,
+ .detect = vbox_connector_detect,
+ .fill_modes = vbox_fill_modes,
+ .destroy = vbox_connector_destroy,
+};
+
+static int vbox_connector_init(struct drm_device *dev,
+ struct vbox_crtc *vbox_crtc,
+ struct drm_encoder *encoder)
+{
+ struct vbox_connector *vbox_connector;
+ struct drm_connector *connector;
+
+ vbox_connector = kzalloc(sizeof(*vbox_connector), GFP_KERNEL);
+ if (!vbox_connector)
+ return -ENOMEM;
+
+ connector = &vbox_connector->base;
+ vbox_connector->vbox_crtc = vbox_crtc;
+
+ drm_connector_init(dev, connector, &vbox_connector_funcs,
+ DRM_MODE_CONNECTOR_VGA);
+ drm_connector_helper_add(connector, &vbox_connector_helper_funcs);
+
+ connector->interlace_allowed = 0;
+ connector->doublescan_allowed = 0;
+
+ drm_mode_create_suggested_offset_properties(dev);
+ drm_object_attach_property(&connector->base,
+ dev->mode_config.suggested_x_property, -1);
+ drm_object_attach_property(&connector->base,
+ dev->mode_config.suggested_y_property, -1);
+ drm_connector_register(connector);
+
+ drm_mode_connector_attach_encoder(connector, encoder);
+
+ return 0;
+}
+
+int vbox_mode_init(struct drm_device *dev)
+{
+ struct vbox_private *vbox = dev->dev_private;
+ struct drm_encoder *encoder;
+ struct vbox_crtc *vbox_crtc;
+ unsigned int i;
+ int ret;
+
+ /* vbox_cursor_init(dev); */
+ for (i = 0; i < vbox->num_crtcs; ++i) {
+ vbox_crtc = vbox_crtc_init(dev, i);
+ if (!vbox_crtc)
+ return -ENOMEM;
+ encoder = vbox_encoder_init(dev, i);
+ if (!encoder)
+ return -ENOMEM;
+ ret = vbox_connector_init(dev, vbox_crtc, encoder);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+void vbox_mode_fini(struct drm_device *dev)
+{
+ /* vbox_cursor_fini(dev); */
+}
+
+/**
+ * Copy the ARGB image and generate the mask, which is needed in case the host
+ * does not support ARGB cursors. The mask is a 1BPP bitmap with the bit set
+ * if the corresponding alpha value in the ARGB image is greater than 0xF0.
+ */
+static void copy_cursor_image(u8 *src, u8 *dst, u32 width, u32 height,
+ size_t mask_size)
+{
+ size_t line_size = (width + 7) / 8;
+ u32 i, j;
+
+ memcpy(dst + mask_size, src, width * height * 4);
+ for (i = 0; i < height; ++i)
+ for (j = 0; j < width; ++j)
+ if (((u32 *)src)[i * width + j] > 0xf0000000)
+ dst[i * line_size + j / 8] |= (0x80 >> (j % 8));
+}
+
+static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
+ u32 handle, u32 width, u32 height,
+ s32 hot_x, s32 hot_y)
+{
+ struct vbox_private *vbox = crtc->dev->dev_private;
+ struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
+ struct ttm_bo_kmap_obj uobj_map;
+ size_t data_size, mask_size;
+ struct drm_gem_object *obj;
+ u32 flags, caps = 0;
+ struct vbox_bo *bo;
+ bool src_isiomem;
+ u8 *dst = NULL;
+ u8 *src;
+ int ret;
+
+ /*
+ * Re-set this regularly as in 5.0.20 and earlier the information was
+ * lost on save and restore.
+ */
+ hgsmi_update_input_mapping(vbox->guest_pool, 0, 0,
+ vbox->input_mapping_width,
+ vbox->input_mapping_height);
+ if (!handle) {
+ bool cursor_enabled = false;
+ struct drm_crtc *crtci;
+
+ /* Hide cursor. */
+ vbox_crtc->cursor_enabled = false;
+ list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
+ head) {
+ if (to_vbox_crtc(crtci)->cursor_enabled)
+ cursor_enabled = true;
+ }
+
+ if (!cursor_enabled)
+ hgsmi_update_pointer_shape(vbox->guest_pool, 0, 0, 0,
+ 0, 0, NULL, 0);
+ return 0;
+ }
+
+ vbox_crtc->cursor_enabled = true;
+
+ if (width > VBOX_MAX_CURSOR_WIDTH || height > VBOX_MAX_CURSOR_HEIGHT ||
+ width == 0 || height == 0)
+ return -EINVAL;
+
+ ret = hgsmi_query_conf(vbox->guest_pool,
+ VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &caps);
+ if (ret)
+ return ret;
+
+ if (!(caps & VBOX_VBVA_CURSOR_CAPABILITY_HARDWARE)) {
+ /*
+ * -EINVAL means cursor_set2() not supported, -EAGAIN means
+ * retry at once.
+ */
+ return -EBUSY;
+ }
+
+ obj = drm_gem_object_lookup(file_priv, handle);
+ if (!obj) {
+ DRM_ERROR("Cannot find cursor object %x for crtc\n", handle);
+ return -ENOENT;
+ }
+
+ bo = gem_to_vbox_bo(obj);
+ ret = vbox_bo_reserve(bo, false);
+ if (ret)
+ goto out_unref_obj;
+
+ /*
+ * The mask must be calculated based on the alpha
+ * channel, one bit per ARGB word, and must be 32-bit
+ * padded.
+ */
+ mask_size = ((width + 7) / 8 * height + 3) & ~3;
+ data_size = width * height * 4 + mask_size;
+ vbox->cursor_hot_x = min_t(u32, max(hot_x, 0), width);
+ vbox->cursor_hot_y = min_t(u32, max(hot_y, 0), height);
+ vbox->cursor_width = width;
+ vbox->cursor_height = height;
+ vbox->cursor_data_size = data_size;
+ dst = vbox->cursor_data;
+
+ ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &uobj_map);
+ if (ret) {
+ vbox->cursor_data_size = 0;
+ goto out_unreserve_bo;
+ }
+
+ src = ttm_kmap_obj_virtual(&uobj_map, &src_isiomem);
+ if (src_isiomem) {
+ DRM_ERROR("src cursor bo not in main memory\n");
+ ret = -EIO;
+ goto out_unmap_bo;
+ }
+
+ copy_cursor_image(src, dst, width, height, mask_size);
+
+ flags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE |
+ VBOX_MOUSE_POINTER_ALPHA;
+ ret = hgsmi_update_pointer_shape(vbox->guest_pool, flags,
+ vbox->cursor_hot_x, vbox->cursor_hot_y,
+ width, height, dst, data_size);
+out_unmap_bo:
+ ttm_bo_kunmap(&uobj_map);
+out_unreserve_bo:
+ vbox_bo_unreserve(bo);
+out_unref_obj:
+ drm_gem_object_put_unlocked(obj);
+
+ return ret;
+}
+
+static int vbox_cursor_move(struct drm_crtc *crtc, int x, int y)
+{
+ struct vbox_private *vbox = crtc->dev->dev_private;
+ u32 flags = VBOX_MOUSE_POINTER_VISIBLE |
+ VBOX_MOUSE_POINTER_SHAPE | VBOX_MOUSE_POINTER_ALPHA;
+ s32 crtc_x =
+ vbox->single_framebuffer ? crtc->x : to_vbox_crtc(crtc)->x_hint;
+ s32 crtc_y =
+ vbox->single_framebuffer ? crtc->y : to_vbox_crtc(crtc)->y_hint;
+ u32 host_x, host_y;
+ u32 hot_x = 0;
+ u32 hot_y = 0;
+ int ret;
+
+ /*
+ * We compare these to unsigned later and don't
+ * need to handle negative.
+ */
+ if (x + crtc_x < 0 || y + crtc_y < 0 || vbox->cursor_data_size == 0)
+ return 0;
+
+ ret = hgsmi_cursor_position(vbox->guest_pool, true, x + crtc_x,
+ y + crtc_y, &host_x, &host_y);
+
+ /*
+ * The only reason we have vbox_cursor_move() is that some older clients
+ * might use DRM_IOCTL_MODE_CURSOR instead of DRM_IOCTL_MODE_CURSOR2 and
+ * use DRM_MODE_CURSOR_MOVE to set the hot-spot.
+ *
+ * However VirtualBox 5.0.20 and earlier has a bug causing it to return
+ * 0,0 as host cursor location after a save and restore.
+ *
+ * To work around this we ignore a 0, 0 return, since missing the odd
+ * time when it legitimately happens is not going to hurt much.
+ */
+ if (ret || (host_x == 0 && host_y == 0))
+ return ret;
+
+ if (x + crtc_x < host_x)
+ hot_x = min(host_x - x - crtc_x, vbox->cursor_width);
+ if (y + crtc_y < host_y)
+ hot_y = min(host_y - y - crtc_y, vbox->cursor_height);
+
+ if (hot_x == vbox->cursor_hot_x && hot_y == vbox->cursor_hot_y)
+ return 0;
+
+ vbox->cursor_hot_x = hot_x;
+ vbox->cursor_hot_y = hot_y;
+
+ return hgsmi_update_pointer_shape(vbox->guest_pool, flags,
+ hot_x, hot_y, vbox->cursor_width, vbox->cursor_height,
+ vbox->cursor_data, vbox->cursor_data_size);
+}
diff --git a/drivers/staging/vboxvideo/vbox_prime.c b/drivers/staging/vboxvideo/vbox_prime.c
new file mode 100644
index 000000000000..b7453e427a1d
--- /dev/null
+++ b/drivers/staging/vboxvideo/vbox_prime.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2017 Oracle Corporation
+ * Copyright 2017 Canonical
+ *
+ * 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: Andreas Pokorny
+ */
+
+#include "vbox_drv.h"
+
+/*
+ * Based on qxl_prime.c:
+ * Empty Implementations as there should not be any other driver for a virtual
+ * device that might share buffers with vboxvideo
+ */
+
+int vbox_gem_prime_pin(struct drm_gem_object *obj)
+{
+ WARN_ONCE(1, "not implemented");
+ return -ENOSYS;
+}
+
+void vbox_gem_prime_unpin(struct drm_gem_object *obj)
+{
+ WARN_ONCE(1, "not implemented");
+}
+
+struct sg_table *vbox_gem_prime_get_sg_table(struct drm_gem_object *obj)
+{
+ WARN_ONCE(1, "not implemented");
+ return ERR_PTR(-ENOSYS);
+}
+
+struct drm_gem_object *vbox_gem_prime_import_sg_table(
+ struct drm_device *dev, struct dma_buf_attachment *attach,
+ struct sg_table *table)
+{
+ WARN_ONCE(1, "not implemented");
+ return ERR_PTR(-ENOSYS);
+}
+
+void *vbox_gem_prime_vmap(struct drm_gem_object *obj)
+{
+ WARN_ONCE(1, "not implemented");
+ return ERR_PTR(-ENOSYS);
+}
+
+void vbox_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
+{
+ WARN_ONCE(1, "not implemented");
+}
+
+int vbox_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *area)
+{
+ WARN_ONCE(1, "not implemented");
+ return -ENOSYS;
+}
diff --git a/drivers/staging/vboxvideo/vbox_ttm.c b/drivers/staging/vboxvideo/vbox_ttm.c
new file mode 100644
index 000000000000..34a905d40735
--- /dev/null
+++ b/drivers/staging/vboxvideo/vbox_ttm.c
@@ -0,0 +1,472 @@
+/*
+ * Copyright (C) 2013-2017 Oracle Corporation
+ * This file is based on ast_ttm.c
+ * Copyright 2012 Red Hat 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, 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 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ * Authors: Dave Airlie <airlied@redhat.com>
+ * Michael Thayer <michael.thayer@oracle.com>
+ */
+#include "vbox_drv.h"
+#include <ttm/ttm_page_alloc.h>
+
+static inline struct vbox_private *vbox_bdev(struct ttm_bo_device *bd)
+{
+ return container_of(bd, struct vbox_private, ttm.bdev);
+}
+
+static int vbox_ttm_mem_global_init(struct drm_global_reference *ref)
+{
+ return ttm_mem_global_init(ref->object);
+}
+
+static void vbox_ttm_mem_global_release(struct drm_global_reference *ref)
+{
+ ttm_mem_global_release(ref->object);
+}
+
+/**
+ * Adds the vbox memory manager object/structures to the global memory manager.
+ */
+static int vbox_ttm_global_init(struct vbox_private *vbox)
+{
+ struct drm_global_reference *global_ref;
+ int ret;
+
+ global_ref = &vbox->ttm.mem_global_ref;
+ global_ref->global_type = DRM_GLOBAL_TTM_MEM;
+ global_ref->size = sizeof(struct ttm_mem_global);
+ global_ref->init = &vbox_ttm_mem_global_init;
+ global_ref->release = &vbox_ttm_mem_global_release;
+ ret = drm_global_item_ref(global_ref);
+ if (ret) {
+ DRM_ERROR("Failed setting up TTM memory subsystem.\n");
+ return ret;
+ }
+
+ vbox->ttm.bo_global_ref.mem_glob = vbox->ttm.mem_global_ref.object;
+ global_ref = &vbox->ttm.bo_global_ref.ref;
+ global_ref->global_type = DRM_GLOBAL_TTM_BO;
+ global_ref->size = sizeof(struct ttm_bo_global);
+ global_ref->init = &ttm_bo_global_init;
+ global_ref->release = &ttm_bo_global_release;
+
+ ret = drm_global_item_ref(global_ref);
+ if (ret) {
+ DRM_ERROR("Failed setting up TTM BO subsystem.\n");
+ drm_global_item_unref(&vbox->ttm.mem_global_ref);
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * Removes the vbox memory manager object from the global memory manager.
+ */
+static void vbox_ttm_global_release(struct vbox_private *vbox)
+{
+ drm_global_item_unref(&vbox->ttm.bo_global_ref.ref);
+ drm_global_item_unref(&vbox->ttm.mem_global_ref);
+}
+
+static void vbox_bo_ttm_destroy(struct ttm_buffer_object *tbo)
+{
+ struct vbox_bo *bo;
+
+ bo = container_of(tbo, struct vbox_bo, bo);
+
+ drm_gem_object_release(&bo->gem);
+ kfree(bo);
+}
+
+static bool vbox_ttm_bo_is_vbox_bo(struct ttm_buffer_object *bo)
+{
+ if (bo->destroy == &vbox_bo_ttm_destroy)
+ return true;
+
+ return false;
+}
+
+static int
+vbox_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type,
+ struct ttm_mem_type_manager *man)
+{
+ switch (type) {
+ case TTM_PL_SYSTEM:
+ man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
+ man->available_caching = TTM_PL_MASK_CACHING;
+ man->default_caching = TTM_PL_FLAG_CACHED;
+ break;
+ case TTM_PL_VRAM:
+ man->func = &ttm_bo_manager_func;
+ man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_MAPPABLE;
+ man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
+ man->default_caching = TTM_PL_FLAG_WC;
+ break;
+ default:
+ DRM_ERROR("Unsupported memory type %u\n", (unsigned int)type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void
+vbox_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
+{
+ struct vbox_bo *vboxbo = vbox_bo(bo);
+
+ if (!vbox_ttm_bo_is_vbox_bo(bo))
+ return;
+
+ vbox_ttm_placement(vboxbo, TTM_PL_FLAG_SYSTEM);
+ *pl = vboxbo->placement;
+}
+
+static int vbox_bo_verify_access(struct ttm_buffer_object *bo,
+ struct file *filp)
+{
+ return 0;
+}
+
+static int vbox_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
+ struct ttm_mem_reg *mem)
+{
+ struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
+ struct vbox_private *vbox = vbox_bdev(bdev);
+
+ mem->bus.addr = NULL;
+ mem->bus.offset = 0;
+ mem->bus.size = mem->num_pages << PAGE_SHIFT;
+ mem->bus.base = 0;
+ mem->bus.is_iomem = false;
+ if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
+ return -EINVAL;
+ switch (mem->mem_type) {
+ case TTM_PL_SYSTEM:
+ /* system memory */
+ return 0;
+ case TTM_PL_VRAM:
+ mem->bus.offset = mem->start << PAGE_SHIFT;
+ mem->bus.base = pci_resource_start(vbox->dev->pdev, 0);
+ mem->bus.is_iomem = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void vbox_ttm_io_mem_free(struct ttm_bo_device *bdev,
+ struct ttm_mem_reg *mem)
+{
+}
+
+static int vbox_bo_move(struct ttm_buffer_object *bo,
+ bool evict, bool interruptible,
+ bool no_wait_gpu, struct ttm_mem_reg *new_mem)
+{
+ return ttm_bo_move_memcpy(bo, interruptible, no_wait_gpu, new_mem);
+}
+
+static void vbox_ttm_backend_destroy(struct ttm_tt *tt)
+{
+ ttm_tt_fini(tt);
+ kfree(tt);
+}
+
+static struct ttm_backend_func vbox_tt_backend_func = {
+ .destroy = &vbox_ttm_backend_destroy,
+};
+
+static struct ttm_tt *vbox_ttm_tt_create(struct ttm_bo_device *bdev,
+ unsigned long size,
+ u32 page_flags,
+ struct page *dummy_read_page)
+{
+ struct ttm_tt *tt;
+
+ tt = kzalloc(sizeof(*tt), GFP_KERNEL);
+ if (!tt)
+ return NULL;
+
+ tt->func = &vbox_tt_backend_func;
+ if (ttm_tt_init(tt, bdev, size, page_flags, dummy_read_page)) {
+ kfree(tt);
+ return NULL;
+ }
+
+ return tt;
+}
+
+static int vbox_ttm_tt_populate(struct ttm_tt *ttm)
+{
+ return ttm_pool_populate(ttm);
+}
+
+static void vbox_ttm_tt_unpopulate(struct ttm_tt *ttm)
+{
+ ttm_pool_unpopulate(ttm);
+}
+
+struct ttm_bo_driver vbox_bo_driver = {
+ .ttm_tt_create = vbox_ttm_tt_create,
+ .ttm_tt_populate = vbox_ttm_tt_populate,
+ .ttm_tt_unpopulate = vbox_ttm_tt_unpopulate,
+ .init_mem_type = vbox_bo_init_mem_type,
+ .eviction_valuable = ttm_bo_eviction_valuable,
+ .evict_flags = vbox_bo_evict_flags,
+ .move = vbox_bo_move,
+ .verify_access = vbox_bo_verify_access,
+ .io_mem_reserve = &vbox_ttm_io_mem_reserve,
+ .io_mem_free = &vbox_ttm_io_mem_free,
+ .io_mem_pfn = ttm_bo_default_io_mem_pfn,
+};
+
+int vbox_mm_init(struct vbox_private *vbox)
+{
+ int ret;
+ struct drm_device *dev = vbox->dev;
+ struct ttm_bo_device *bdev = &vbox->ttm.bdev;
+
+ ret = vbox_ttm_global_init(vbox);
+ if (ret)
+ return ret;
+
+ ret = ttm_bo_device_init(&vbox->ttm.bdev,
+ vbox->ttm.bo_global_ref.ref.object,
+ &vbox_bo_driver,
+ dev->anon_inode->i_mapping,
+ DRM_FILE_PAGE_OFFSET, true);
+ if (ret) {
+ DRM_ERROR("Error initialising bo driver; %d\n", ret);
+ goto err_ttm_global_release;
+ }
+
+ ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
+ vbox->available_vram_size >> PAGE_SHIFT);
+ if (ret) {
+ DRM_ERROR("Failed ttm VRAM init: %d\n", ret);
+ goto err_device_release;
+ }
+
+#ifdef DRM_MTRR_WC
+ vbox->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0),
+ pci_resource_len(dev->pdev, 0),
+ DRM_MTRR_WC);
+#else
+ vbox->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0),
+ pci_resource_len(dev->pdev, 0));
+#endif
+ return 0;
+
+err_device_release:
+ ttm_bo_device_release(&vbox->ttm.bdev);
+err_ttm_global_release:
+ vbox_ttm_global_release(vbox);
+ return ret;
+}
+
+void vbox_mm_fini(struct vbox_private *vbox)
+{
+#ifdef DRM_MTRR_WC
+ drm_mtrr_del(vbox->fb_mtrr,
+ pci_resource_start(vbox->dev->pdev, 0),
+ pci_resource_len(vbox->dev->pdev, 0), DRM_MTRR_WC);
+#else
+ arch_phys_wc_del(vbox->fb_mtrr);
+#endif
+ ttm_bo_device_release(&vbox->ttm.bdev);
+ vbox_ttm_global_release(vbox);
+}
+
+void vbox_ttm_placement(struct vbox_bo *bo, int domain)
+{
+ unsigned int i;
+ u32 c = 0;
+
+ bo->placement.placement = bo->placements;
+ bo->placement.busy_placement = bo->placements;
+
+ if (domain & TTM_PL_FLAG_VRAM)
+ bo->placements[c++].flags =
+ TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM;
+ if (domain & TTM_PL_FLAG_SYSTEM)
+ bo->placements[c++].flags =
+ TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
+ if (!c)
+ bo->placements[c++].flags =
+ TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
+
+ bo->placement.num_placement = c;
+ bo->placement.num_busy_placement = c;
+
+ for (i = 0; i < c; ++i) {
+ bo->placements[i].fpfn = 0;
+ bo->placements[i].lpfn = 0;
+ }
+}
+
+int vbox_bo_create(struct drm_device *dev, int size, int align,
+ u32 flags, struct vbox_bo **pvboxbo)
+{
+ struct vbox_private *vbox = dev->dev_private;
+ struct vbox_bo *vboxbo;
+ size_t acc_size;
+ int ret;
+
+ vboxbo = kzalloc(sizeof(*vboxbo), GFP_KERNEL);
+ if (!vboxbo)
+ return -ENOMEM;
+
+ ret = drm_gem_object_init(dev, &vboxbo->gem, size);
+ if (ret)
+ goto err_free_vboxbo;
+
+ vboxbo->bo.bdev = &vbox->ttm.bdev;
+
+ vbox_ttm_placement(vboxbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
+
+ acc_size = ttm_bo_dma_acc_size(&vbox->ttm.bdev, size,
+ sizeof(struct vbox_bo));
+
+ ret = ttm_bo_init(&vbox->ttm.bdev, &vboxbo->bo, size,
+ ttm_bo_type_device, &vboxbo->placement,
+ align >> PAGE_SHIFT, false, NULL, acc_size,
+ NULL, NULL, vbox_bo_ttm_destroy);
+ if (ret)
+ goto err_free_vboxbo;
+
+ *pvboxbo = vboxbo;
+
+ return 0;
+
+err_free_vboxbo:
+ kfree(vboxbo);
+ return ret;
+}
+
+static inline u64 vbox_bo_gpu_offset(struct vbox_bo *bo)
+{
+ return bo->bo.offset;
+}
+
+int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag, u64 *gpu_addr)
+{
+ int i, ret;
+
+ if (bo->pin_count) {
+ bo->pin_count++;
+ if (gpu_addr)
+ *gpu_addr = vbox_bo_gpu_offset(bo);
+
+ return 0;
+ }
+
+ vbox_ttm_placement(bo, pl_flag);
+
+ for (i = 0; i < bo->placement.num_placement; i++)
+ bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
+
+ ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false);
+ if (ret)
+ return ret;
+
+ bo->pin_count = 1;
+
+ if (gpu_addr)
+ *gpu_addr = vbox_bo_gpu_offset(bo);
+
+ return 0;
+}
+
+int vbox_bo_unpin(struct vbox_bo *bo)
+{
+ int i, ret;
+
+ if (!bo->pin_count) {
+ DRM_ERROR("unpin bad %p\n", bo);
+ return 0;
+ }
+ bo->pin_count--;
+ if (bo->pin_count)
+ return 0;
+
+ for (i = 0; i < bo->placement.num_placement; i++)
+ bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
+
+ ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+/*
+ * Move a vbox-owned buffer object to system memory if no one else has it
+ * pinned. The caller must have pinned it previously, and this call will
+ * release the caller's pin.
+ */
+int vbox_bo_push_sysram(struct vbox_bo *bo)
+{
+ int i, ret;
+
+ if (!bo->pin_count) {
+ DRM_ERROR("unpin bad %p\n", bo);
+ return 0;
+ }
+ bo->pin_count--;
+ if (bo->pin_count)
+ return 0;
+
+ if (bo->kmap.virtual)
+ ttm_bo_kunmap(&bo->kmap);
+
+ vbox_ttm_placement(bo, TTM_PL_FLAG_SYSTEM);
+
+ for (i = 0; i < bo->placement.num_placement; i++)
+ bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
+
+ ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false);
+ if (ret) {
+ DRM_ERROR("pushing to VRAM failed\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+int vbox_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct drm_file *file_priv;
+ struct vbox_private *vbox;
+
+ if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET))
+ return -EINVAL;
+
+ file_priv = filp->private_data;
+ vbox = file_priv->minor->dev->dev_private;
+
+ return ttm_bo_mmap(filp, vma, &vbox->ttm.bdev);
+}
diff --git a/drivers/staging/vboxvideo/vboxvideo.h b/drivers/staging/vboxvideo/vboxvideo.h
new file mode 100644
index 000000000000..d835d75d761c
--- /dev/null
+++ b/drivers/staging/vboxvideo/vboxvideo.h
@@ -0,0 +1,491 @@
+/*
+ * Copyright (C) 2006-2016 Oracle Corporation
+ *
+ * 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 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.
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ */
+
+#ifndef __VBOXVIDEO_H__
+#define __VBOXVIDEO_H__
+
+/*
+ * This should be in sync with monitorCount <xsd:maxInclusive value="64"/> in
+ * src/VBox/Main/xml/VirtualBox-settings-common.xsd
+ */
+#define VBOX_VIDEO_MAX_SCREENS 64
+
+/*
+ * The last 4096 bytes of the guest VRAM contains the generic info for all
+ * DualView chunks: sizes and offsets of chunks. This is filled by miniport.
+ *
+ * Last 4096 bytes of each chunk contain chunk specific data: framebuffer info,
+ * etc. This is used exclusively by the corresponding instance of a display
+ * driver.
+ *
+ * The VRAM layout:
+ * Last 4096 bytes - Adapter information area.
+ * 4096 bytes aligned miniport heap (value specified in the config rouded up).
+ * Slack - what left after dividing the VRAM.
+ * 4096 bytes aligned framebuffers:
+ * last 4096 bytes of each framebuffer is the display information area.
+ *
+ * The Virtual Graphics Adapter information in the guest VRAM is stored by the
+ * guest video driver using structures prepended by VBOXVIDEOINFOHDR.
+ *
+ * When the guest driver writes dword 0 to the VBE_DISPI_INDEX_VBOX_VIDEO
+ * the host starts to process the info. The first element at the start of
+ * the 4096 bytes region should be normally be a LINK that points to
+ * actual information chain. That way the guest driver can have some
+ * fixed layout of the information memory block and just rewrite
+ * the link to point to relevant memory chain.
+ *
+ * The processing stops at the END element.
+ *
+ * The host can access the memory only when the port IO is processed.
+ * All data that will be needed later must be copied from these 4096 bytes.
+ * But other VRAM can be used by host until the mode is disabled.
+ *
+ * The guest driver writes dword 0xffffffff to the VBE_DISPI_INDEX_VBOX_VIDEO
+ * to disable the mode.
+ *
+ * VBE_DISPI_INDEX_VBOX_VIDEO is used to read the configuration information
+ * from the host and issue commands to the host.
+ *
+ * The guest writes the VBE_DISPI_INDEX_VBOX_VIDEO index register, the the
+ * following operations with the VBE data register can be performed:
+ *
+ * Operation Result
+ * write 16 bit value NOP
+ * read 16 bit value count of monitors
+ * write 32 bit value set the vbox cmd value and the cmd processed by the host
+ * read 32 bit value result of the last vbox command is returned
+ */
+
+/**
+ * VBVA command header.
+ *
+ * @todo Where does this fit in?
+ */
+struct vbva_cmd_hdr {
+ /** Coordinates of affected rectangle. */
+ s16 x;
+ s16 y;
+ u16 w;
+ u16 h;
+} __packed;
+
+/** @name VBVA ring defines.
+ *
+ * The VBVA ring buffer is suitable for transferring large (< 2GB) amount of
+ * data. For example big bitmaps which do not fit to the buffer.
+ *
+ * Guest starts writing to the buffer by initializing a record entry in the
+ * records queue. VBVA_F_RECORD_PARTIAL indicates that the record is being
+ * written. As data is written to the ring buffer, the guest increases
+ * free_offset.
+ *
+ * The host reads the records on flushes and processes all completed records.
+ * When host encounters situation when only a partial record presents and
+ * len_and_flags & ~VBVA_F_RECORD_PARTIAL >= VBVA_RING_BUFFER_SIZE -
+ * VBVA_RING_BUFFER_THRESHOLD, the host fetched all record data and updates
+ * data_offset. After that on each flush the host continues fetching the data
+ * until the record is completed.
+ *
+ */
+#define VBVA_RING_BUFFER_SIZE (4194304 - 1024)
+#define VBVA_RING_BUFFER_THRESHOLD (4096)
+
+#define VBVA_MAX_RECORDS (64)
+
+#define VBVA_F_MODE_ENABLED 0x00000001u
+#define VBVA_F_MODE_VRDP 0x00000002u
+#define VBVA_F_MODE_VRDP_RESET 0x00000004u
+#define VBVA_F_MODE_VRDP_ORDER_MASK 0x00000008u
+
+#define VBVA_F_STATE_PROCESSING 0x00010000u
+
+#define VBVA_F_RECORD_PARTIAL 0x80000000u
+
+/**
+ * VBVA record.
+ */
+struct vbva_record {
+ /** The length of the record. Changed by guest. */
+ u32 len_and_flags;
+} __packed;
+
+/*
+ * The minimum HGSMI heap size is PAGE_SIZE (4096 bytes) and is a restriction of
+ * the runtime heapsimple API. Use minimum 2 pages here, because the info area
+ * also may contain other data (for example hgsmi_host_flags structure).
+ */
+#define VBVA_ADAPTER_INFORMATION_SIZE 65536
+#define VBVA_MIN_BUFFER_SIZE 65536
+
+/* The value for port IO to let the adapter to interpret the adapter memory. */
+#define VBOX_VIDEO_DISABLE_ADAPTER_MEMORY 0xFFFFFFFF
+
+/* The value for port IO to let the adapter to interpret the adapter memory. */
+#define VBOX_VIDEO_INTERPRET_ADAPTER_MEMORY 0x00000000
+
+/* The value for port IO to let the adapter to interpret the display memory.
+ * The display number is encoded in low 16 bits.
+ */
+#define VBOX_VIDEO_INTERPRET_DISPLAY_MEMORY_BASE 0x00010000
+
+struct vbva_host_flags {
+ u32 host_events;
+ u32 supported_orders;
+} __packed;
+
+struct vbva_buffer {
+ struct vbva_host_flags host_flags;
+
+ /* The offset where the data start in the buffer. */
+ u32 data_offset;
+ /* The offset where next data must be placed in the buffer. */
+ u32 free_offset;
+
+ /* The queue of record descriptions. */
+ struct vbva_record records[VBVA_MAX_RECORDS];
+ u32 record_first_index;
+ u32 record_free_index;
+
+ /* Space to leave free when large partial records are transferred. */
+ u32 partial_write_tresh;
+
+ u32 data_len;
+ /* variable size for the rest of the vbva_buffer area in VRAM. */
+ u8 data[0];
+} __packed;
+
+#define VBVA_MAX_RECORD_SIZE (128 * 1024 * 1024)
+
+/* guest->host commands */
+#define VBVA_QUERY_CONF32 1
+#define VBVA_SET_CONF32 2
+#define VBVA_INFO_VIEW 3
+#define VBVA_INFO_HEAP 4
+#define VBVA_FLUSH 5
+#define VBVA_INFO_SCREEN 6
+#define VBVA_ENABLE 7
+#define VBVA_MOUSE_POINTER_SHAPE 8
+/* informs host about HGSMI caps. see vbva_caps below */
+#define VBVA_INFO_CAPS 12
+/* configures scanline, see VBVASCANLINECFG below */
+#define VBVA_SCANLINE_CFG 13
+/* requests scanline info, see VBVASCANLINEINFO below */
+#define VBVA_SCANLINE_INFO 14
+/* inform host about VBVA Command submission */
+#define VBVA_CMDVBVA_SUBMIT 16
+/* inform host about VBVA Command submission */
+#define VBVA_CMDVBVA_FLUSH 17
+/* G->H DMA command */
+#define VBVA_CMDVBVA_CTL 18
+/* Query most recent mode hints sent */
+#define VBVA_QUERY_MODE_HINTS 19
+/**
+ * Report the guest virtual desktop position and size for mapping host and
+ * guest pointer positions.
+ */
+#define VBVA_REPORT_INPUT_MAPPING 20
+/** Report the guest cursor position and query the host position. */
+#define VBVA_CURSOR_POSITION 21
+
+/* host->guest commands */
+#define VBVAHG_EVENT 1
+#define VBVAHG_DISPLAY_CUSTOM 2
+
+/* vbva_conf32::index */
+#define VBOX_VBVA_CONF32_MONITOR_COUNT 0
+#define VBOX_VBVA_CONF32_HOST_HEAP_SIZE 1
+/**
+ * Returns VINF_SUCCESS if the host can report mode hints via VBVA.
+ * Set value to VERR_NOT_SUPPORTED before calling.
+ */
+#define VBOX_VBVA_CONF32_MODE_HINT_REPORTING 2
+/**
+ * Returns VINF_SUCCESS if the host can report guest cursor enabled status via
+ * VBVA. Set value to VERR_NOT_SUPPORTED before calling.
+ */
+#define VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING 3
+/**
+ * Returns the currently available host cursor capabilities. Available if
+ * vbva_conf32::VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING returns success.
+ * @see VMMDevReqMouseStatus::mouseFeatures.
+ */
+#define VBOX_VBVA_CONF32_CURSOR_CAPABILITIES 4
+/** Returns the supported flags in vbva_infoscreen::flags. */
+#define VBOX_VBVA_CONF32_SCREEN_FLAGS 5
+/** Returns the max size of VBVA record. */
+#define VBOX_VBVA_CONF32_MAX_RECORD_SIZE 6
+
+struct vbva_conf32 {
+ u32 index;
+ u32 value;
+} __packed;
+
+/** Reserved for historical reasons. */
+#define VBOX_VBVA_CURSOR_CAPABILITY_RESERVED0 BIT(0)
+/**
+ * Guest cursor capability: can the host show a hardware cursor at the host
+ * pointer location?
+ */
+#define VBOX_VBVA_CURSOR_CAPABILITY_HARDWARE BIT(1)
+/** Reserved for historical reasons. */
+#define VBOX_VBVA_CURSOR_CAPABILITY_RESERVED2 BIT(2)
+/** Reserved for historical reasons. Must always be unset. */
+#define VBOX_VBVA_CURSOR_CAPABILITY_RESERVED3 BIT(3)
+/** Reserved for historical reasons. */
+#define VBOX_VBVA_CURSOR_CAPABILITY_RESERVED4 BIT(4)
+/** Reserved for historical reasons. */
+#define VBOX_VBVA_CURSOR_CAPABILITY_RESERVED5 BIT(5)
+
+struct vbva_infoview {
+ /* Index of the screen, assigned by the guest. */
+ u32 view_index;
+
+ /* The screen offset in VRAM, the framebuffer starts here. */
+ u32 view_offset;
+
+ /* The size of the VRAM memory that can be used for the view. */
+ u32 view_size;
+
+ /* The recommended maximum size of the VRAM memory for the screen. */
+ u32 max_screen_size;
+} __packed;
+
+struct vbva_flush {
+ u32 reserved;
+} __packed;
+
+/* vbva_infoscreen::flags */
+#define VBVA_SCREEN_F_NONE 0x0000
+#define VBVA_SCREEN_F_ACTIVE 0x0001
+/**
+ * The virtual monitor has been disabled by the guest and should be removed
+ * by the host and ignored for purposes of pointer position calculation.
+ */
+#define VBVA_SCREEN_F_DISABLED 0x0002
+/**
+ * The virtual monitor has been blanked by the guest and should be blacked
+ * out by the host using width, height, etc values from the vbva_infoscreen
+ * request.
+ */
+#define VBVA_SCREEN_F_BLANK 0x0004
+/**
+ * The virtual monitor has been blanked by the guest and should be blacked
+ * out by the host using the previous mode values for width. height, etc.
+ */
+#define VBVA_SCREEN_F_BLANK2 0x0008
+
+struct vbva_infoscreen {
+ /* Which view contains the screen. */
+ u32 view_index;
+
+ /* Physical X origin relative to the primary screen. */
+ s32 origin_x;
+
+ /* Physical Y origin relative to the primary screen. */
+ s32 origin_y;
+
+ /* Offset of visible framebuffer relative to the framebuffer start. */
+ u32 start_offset;
+
+ /* The scan line size in bytes. */
+ u32 line_size;
+
+ /* Width of the screen. */
+ u32 width;
+
+ /* Height of the screen. */
+ u32 height;
+
+ /* Color depth. */
+ u16 bits_per_pixel;
+
+ /* VBVA_SCREEN_F_* */
+ u16 flags;
+} __packed;
+
+/* vbva_enable::flags */
+#define VBVA_F_NONE 0x00000000
+#define VBVA_F_ENABLE 0x00000001
+#define VBVA_F_DISABLE 0x00000002
+/* extended VBVA to be used with WDDM */
+#define VBVA_F_EXTENDED 0x00000004
+/* vbva offset is absolute VRAM offset */
+#define VBVA_F_ABSOFFSET 0x00000008
+
+struct vbva_enable {
+ u32 flags;
+ u32 offset;
+ s32 result;
+} __packed;
+
+struct vbva_enable_ex {
+ struct vbva_enable base;
+ u32 screen_id;
+} __packed;
+
+struct vbva_mouse_pointer_shape {
+ /* The host result. */
+ s32 result;
+
+ /* VBOX_MOUSE_POINTER_* bit flags. */
+ u32 flags;
+
+ /* X coordinate of the hot spot. */
+ u32 hot_X;
+
+ /* Y coordinate of the hot spot. */
+ u32 hot_y;
+
+ /* Width of the pointer in pixels. */
+ u32 width;
+
+ /* Height of the pointer in scanlines. */
+ u32 height;
+
+ /* Pointer data.
+ *
+ ****
+ * The data consists of 1 bpp AND mask followed by 32 bpp XOR (color)
+ * mask.
+ *
+ * For pointers without alpha channel the XOR mask pixels are 32 bit
+ * values: (lsb)BGR0(msb). For pointers with alpha channel the XOR mask
+ * consists of (lsb)BGRA(msb) 32 bit values.
+ *
+ * Guest driver must create the AND mask for pointers with alpha chan.,
+ * so if host does not support alpha, the pointer could be displayed as
+ * a normal color pointer. The AND mask can be constructed from alpha
+ * values. For example alpha value >= 0xf0 means bit 0 in the AND mask.
+ *
+ * The AND mask is 1 bpp bitmap with byte aligned scanlines. Size of AND
+ * mask, therefore, is and_len = (width + 7) / 8 * height. The padding
+ * bits at the end of any scanline are undefined.
+ *
+ * The XOR mask follows the AND mask on the next 4 bytes aligned offset:
+ * u8 *xor = and + (and_len + 3) & ~3
+ * Bytes in the gap between the AND and the XOR mask are undefined.
+ * XOR mask scanlines have no gap between them and size of XOR mask is:
+ * xor_len = width * 4 * height.
+ ****
+ *
+ * Preallocate 4 bytes for accessing actual data as p->data.
+ */
+ u8 data[4];
+} __packed;
+
+/**
+ * @name vbva_mouse_pointer_shape::flags
+ * @note The VBOX_MOUSE_POINTER_* flags are used in the guest video driver,
+ * values must be <= 0x8000 and must not be changed. (try make more sense
+ * of this, please).
+ * @{
+ */
+
+/** pointer is visible */
+#define VBOX_MOUSE_POINTER_VISIBLE 0x0001
+/** pointer has alpha channel */
+#define VBOX_MOUSE_POINTER_ALPHA 0x0002
+/** pointerData contains new pointer shape */
+#define VBOX_MOUSE_POINTER_SHAPE 0x0004
+
+/** @} */
+
+/*
+ * The guest driver can handle asynch guest cmd completion by reading the
+ * command offset from io port.
+ */
+#define VBVACAPS_COMPLETEGCMD_BY_IOREAD 0x00000001
+/* the guest driver can handle video adapter IRQs */
+#define VBVACAPS_IRQ 0x00000002
+/** The guest can read video mode hints sent via VBVA. */
+#define VBVACAPS_VIDEO_MODE_HINTS 0x00000004
+/** The guest can switch to a software cursor on demand. */
+#define VBVACAPS_DISABLE_CURSOR_INTEGRATION 0x00000008
+/** The guest does not depend on host handling the VBE registers. */
+#define VBVACAPS_USE_VBVA_ONLY 0x00000010
+
+struct vbva_caps {
+ s32 rc;
+ u32 caps;
+} __packed;
+
+/** Query the most recent mode hints received from the host. */
+struct vbva_query_mode_hints {
+ /** The maximum number of screens to return hints for. */
+ u16 hints_queried_count;
+ /** The size of the mode hint structures directly following this one. */
+ u16 hint_structure_guest_size;
+ /** Return code for the operation. Initialise to VERR_NOT_SUPPORTED. */
+ s32 rc;
+} __packed;
+
+/**
+ * Structure in which a mode hint is returned. The guest allocates an array
+ * of these immediately after the vbva_query_mode_hints structure.
+ * To accommodate future extensions, the vbva_query_mode_hints structure
+ * specifies the size of the vbva_modehint structures allocated by the guest,
+ * and the host only fills out structure elements which fit into that size. The
+ * host should fill any unused members (e.g. dx, dy) or structure space on the
+ * end with ~0. The whole structure can legally be set to ~0 to skip a screen.
+ */
+struct vbva_modehint {
+ u32 magic;
+ u32 cx;
+ u32 cy;
+ u32 bpp; /* Which has never been used... */
+ u32 display;
+ u32 dx; /**< X offset into the virtual frame-buffer. */
+ u32 dy; /**< Y offset into the virtual frame-buffer. */
+ u32 enabled; /* Not flags. Add new members for new flags. */
+} __packed;
+
+#define VBVAMODEHINT_MAGIC 0x0801add9u
+
+/**
+ * Report the rectangle relative to which absolute pointer events should be
+ * expressed. This information remains valid until the next VBVA resize event
+ * for any screen, at which time it is reset to the bounding rectangle of all
+ * virtual screens and must be re-set.
+ * @see VBVA_REPORT_INPUT_MAPPING.
+ */
+struct vbva_report_input_mapping {
+ s32 x; /**< Upper left X co-ordinate relative to the first screen. */
+ s32 y; /**< Upper left Y co-ordinate relative to the first screen. */
+ u32 cx; /**< Rectangle width. */
+ u32 cy; /**< Rectangle height. */
+} __packed;
+
+/**
+ * Report the guest cursor position and query the host one. The host may wish
+ * to use the guest information to re-position its own cursor (though this is
+ * currently unlikely).
+ * @see VBVA_CURSOR_POSITION
+ */
+struct vbva_cursor_position {
+ u32 report_position; /**< Are we reporting a position? */
+ u32 x; /**< Guest cursor X position */
+ u32 y; /**< Guest cursor Y position */
+} __packed;
+
+#endif
diff --git a/drivers/staging/vboxvideo/vboxvideo_guest.h b/drivers/staging/vboxvideo/vboxvideo_guest.h
new file mode 100644
index 000000000000..d09da841711a
--- /dev/null
+++ b/drivers/staging/vboxvideo/vboxvideo_guest.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2006-2017 Oracle Corporation
+ *
+ * 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 __VBOXVIDEO_GUEST_H__
+#define __VBOXVIDEO_GUEST_H__
+
+#include <linux/genalloc.h>
+#include "vboxvideo.h"
+
+/**
+ * Structure grouping the context needed for sending graphics acceleration
+ * information to the host via VBVA. Each screen has its own VBVA buffer.
+ */
+struct vbva_buf_ctx {
+ /** Offset of the buffer in the VRAM section for the screen */
+ u32 buffer_offset;
+ /** Length of the buffer in bytes */
+ u32 buffer_length;
+ /** Set if we wrote to the buffer faster than the host could read it */
+ bool buffer_overflow;
+ /** VBVA record that we are currently preparing for the host, or NULL */
+ struct vbva_record *record;
+ /**
+ * Pointer to the VBVA buffer mapped into the current address space.
+ * Will be NULL if VBVA is not enabled.
+ */
+ struct vbva_buffer *vbva;
+};
+
+/**
+ * @name Base HGSMI APIs
+ * @{
+ */
+int hgsmi_report_flags_location(struct gen_pool *ctx, u32 location);
+int hgsmi_send_caps_info(struct gen_pool *ctx, u32 caps);
+int hgsmi_test_query_conf(struct gen_pool *ctx);
+int hgsmi_query_conf(struct gen_pool *ctx, u32 index, u32 *value_ret);
+int hgsmi_update_pointer_shape(struct gen_pool *ctx, u32 flags,
+ u32 hot_x, u32 hot_y, u32 width, u32 height,
+ u8 *pixels, u32 len);
+int hgsmi_cursor_position(struct gen_pool *ctx, bool report_position,
+ u32 x, u32 y, u32 *x_host, u32 *y_host);
+/** @} */
+
+/**
+ * @name VBVA APIs
+ * @{
+ */
+bool vbva_enable(struct vbva_buf_ctx *vbva_ctx, struct gen_pool *ctx,
+ struct vbva_buffer *vbva, s32 screen);
+void vbva_disable(struct vbva_buf_ctx *vbva_ctx, struct gen_pool *ctx,
+ s32 screen);
+bool vbva_buffer_begin_update(struct vbva_buf_ctx *vbva_ctx,
+ struct gen_pool *ctx);
+void vbva_buffer_end_update(struct vbva_buf_ctx *vbva_ctx);
+bool vbva_write(struct vbva_buf_ctx *vbva_ctx, struct gen_pool *ctx,
+ const void *p, u32 len);
+void vbva_setup_buffer_context(struct vbva_buf_ctx *vbva_ctx,
+ u32 buffer_offset, u32 buffer_length);
+/** @} */
+
+/**
+ * @name Modesetting APIs
+ * @{
+ */
+void hgsmi_process_display_info(struct gen_pool *ctx, u32 display,
+ s32 origin_x, s32 origin_y, u32 start_offset,
+ u32 pitch, u32 width, u32 height,
+ u16 bpp, u16 flags);
+int hgsmi_update_input_mapping(struct gen_pool *ctx, s32 origin_x, s32 origin_y,
+ u32 width, u32 height);
+int hgsmi_get_mode_hints(struct gen_pool *ctx, unsigned int screens,
+ struct vbva_modehint *hints);
+/** @} */
+
+#endif
diff --git a/drivers/staging/vboxvideo/vboxvideo_vbe.h b/drivers/staging/vboxvideo/vboxvideo_vbe.h
new file mode 100644
index 000000000000..f842f4d9c80a
--- /dev/null
+++ b/drivers/staging/vboxvideo/vboxvideo_vbe.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2006-2017 Oracle Corporation
+ *
+ * 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 __VBOXVIDEO_VBE_H__
+#define __VBOXVIDEO_VBE_H__
+
+/* GUEST <-> HOST Communication API */
+
+/**
+ * @todo FIXME: Either dynamicly ask host for this or put somewhere high in
+ * physical memory like 0xE0000000.
+ */
+
+#define VBE_DISPI_BANK_ADDRESS 0xA0000
+#define VBE_DISPI_BANK_SIZE_KB 64
+
+#define VBE_DISPI_MAX_XRES 16384
+#define VBE_DISPI_MAX_YRES 16384
+#define VBE_DISPI_MAX_BPP 32
+
+#define VBE_DISPI_IOPORT_INDEX 0x01CE
+#define VBE_DISPI_IOPORT_DATA 0x01CF
+
+#define VBE_DISPI_IOPORT_DAC_WRITE_INDEX 0x03C8
+#define VBE_DISPI_IOPORT_DAC_DATA 0x03C9
+
+#define VBE_DISPI_INDEX_ID 0x0
+#define VBE_DISPI_INDEX_XRES 0x1
+#define VBE_DISPI_INDEX_YRES 0x2
+#define VBE_DISPI_INDEX_BPP 0x3
+#define VBE_DISPI_INDEX_ENABLE 0x4
+#define VBE_DISPI_INDEX_BANK 0x5
+#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
+#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
+#define VBE_DISPI_INDEX_X_OFFSET 0x8
+#define VBE_DISPI_INDEX_Y_OFFSET 0x9
+#define VBE_DISPI_INDEX_VBOX_VIDEO 0xa
+#define VBE_DISPI_INDEX_FB_BASE_HI 0xb
+
+#define VBE_DISPI_ID0 0xB0C0
+#define VBE_DISPI_ID1 0xB0C1
+#define VBE_DISPI_ID2 0xB0C2
+#define VBE_DISPI_ID3 0xB0C3
+#define VBE_DISPI_ID4 0xB0C4
+
+#define VBE_DISPI_ID_VBOX_VIDEO 0xBE00
+/* The VBOX interface id. Indicates support for VBVA shared memory interface. */
+#define VBE_DISPI_ID_HGSMI 0xBE01
+#define VBE_DISPI_ID_ANYX 0xBE02
+
+#define VBE_DISPI_DISABLED 0x00
+#define VBE_DISPI_ENABLED 0x01
+#define VBE_DISPI_GETCAPS 0x02
+#define VBE_DISPI_8BIT_DAC 0x20
+/**
+ * @note this definition is a BOCHS legacy, used only in the video BIOS
+ * code and ignored by the emulated hardware.
+ */
+#define VBE_DISPI_LFB_ENABLED 0x40
+#define VBE_DISPI_NOCLEARMEM 0x80
+
+#define VGA_PORT_HGSMI_HOST 0x3b0
+#define VGA_PORT_HGSMI_GUEST 0x3d0
+
+#endif
diff --git a/drivers/staging/vboxvideo/vbva_base.c b/drivers/staging/vboxvideo/vbva_base.c
new file mode 100644
index 000000000000..c10c782f94e1
--- /dev/null
+++ b/drivers/staging/vboxvideo/vbva_base.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2006-2017 Oracle Corporation
+ *
+ * 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.
+ */
+
+#include "vbox_drv.h"
+#include "vbox_err.h"
+#include "vboxvideo_guest.h"
+#include "hgsmi_channels.h"
+
+/*
+ * There is a hardware ring buffer in the graphics device video RAM, formerly
+ * in the VBox VMMDev PCI memory space.
+ * All graphics commands go there serialized by vbva_buffer_begin_update.
+ * and vbva_buffer_end_update.
+ *
+ * free_offset is writing position. data_offset is reading position.
+ * free_offset == data_offset means buffer is empty.
+ * There must be always gap between data_offset and free_offset when data
+ * are in the buffer.
+ * Guest only changes free_offset, host changes data_offset.
+ */
+
+static u32 vbva_buffer_available(const struct vbva_buffer *vbva)
+{
+ s32 diff = vbva->data_offset - vbva->free_offset;
+
+ return diff > 0 ? diff : vbva->data_len + diff;
+}
+
+static void vbva_buffer_place_data_at(struct vbva_buf_ctx *vbva_ctx,
+ const void *p, u32 len, u32 offset)
+{
+ struct vbva_buffer *vbva = vbva_ctx->vbva;
+ u32 bytes_till_boundary = vbva->data_len - offset;
+ u8 *dst = &vbva->data[offset];
+ s32 diff = len - bytes_till_boundary;
+
+ if (diff <= 0) {
+ /* Chunk will not cross buffer boundary. */
+ memcpy(dst, p, len);
+ } else {
+ /* Chunk crosses buffer boundary. */
+ memcpy(dst, p, bytes_till_boundary);
+ memcpy(&vbva->data[0], (u8 *)p + bytes_till_boundary, diff);
+ }
+}
+
+static void vbva_buffer_flush(struct gen_pool *ctx)
+{
+ struct vbva_flush *p;
+
+ p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, VBVA_FLUSH);
+ if (!p)
+ return;
+
+ p->reserved = 0;
+
+ hgsmi_buffer_submit(ctx, p);
+ hgsmi_buffer_free(ctx, p);
+}
+
+bool vbva_write(struct vbva_buf_ctx *vbva_ctx, struct gen_pool *ctx,
+ const void *p, u32 len)
+{
+ struct vbva_record *record;
+ struct vbva_buffer *vbva;
+ u32 available;
+
+ vbva = vbva_ctx->vbva;
+ record = vbva_ctx->record;
+
+ if (!vbva || vbva_ctx->buffer_overflow ||
+ !record || !(record->len_and_flags & VBVA_F_RECORD_PARTIAL))
+ return false;
+
+ available = vbva_buffer_available(vbva);
+
+ while (len > 0) {
+ u32 chunk = len;
+
+ if (chunk >= available) {
+ vbva_buffer_flush(ctx);
+ available = vbva_buffer_available(vbva);
+ }
+
+ if (chunk >= available) {
+ if (WARN_ON(available <= vbva->partial_write_tresh)) {
+ vbva_ctx->buffer_overflow = true;
+ return false;
+ }
+ chunk = available - vbva->partial_write_tresh;
+ }
+
+ vbva_buffer_place_data_at(vbva_ctx, p, chunk,
+ vbva->free_offset);
+
+ vbva->free_offset = (vbva->free_offset + chunk) %
+ vbva->data_len;
+ record->len_and_flags += chunk;
+ available -= chunk;
+ len -= chunk;
+ p += chunk;
+ }
+
+ return true;
+}
+
+static bool vbva_inform_host(struct vbva_buf_ctx *vbva_ctx,
+ struct gen_pool *ctx, s32 screen, bool enable)
+{
+ struct vbva_enable_ex *p;
+ bool ret;
+
+ p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, VBVA_ENABLE);
+ if (!p)
+ return false;
+
+ p->base.flags = enable ? VBVA_F_ENABLE : VBVA_F_DISABLE;
+ p->base.offset = vbva_ctx->buffer_offset;
+ p->base.result = VERR_NOT_SUPPORTED;
+ if (screen >= 0) {
+ p->base.flags |= VBVA_F_EXTENDED | VBVA_F_ABSOFFSET;
+ p->screen_id = screen;
+ }
+
+ hgsmi_buffer_submit(ctx, p);
+
+ if (enable)
+ ret = RT_SUCCESS(p->base.result);
+ else
+ ret = true;
+
+ hgsmi_buffer_free(ctx, p);
+
+ return ret;
+}
+
+bool vbva_enable(struct vbva_buf_ctx *vbva_ctx, struct gen_pool *ctx,
+ struct vbva_buffer *vbva, s32 screen)
+{
+ bool ret = false;
+
+ memset(vbva, 0, sizeof(*vbva));
+ vbva->partial_write_tresh = 256;
+ vbva->data_len = vbva_ctx->buffer_length - sizeof(struct vbva_buffer);
+ vbva_ctx->vbva = vbva;
+
+ ret = vbva_inform_host(vbva_ctx, ctx, screen, true);
+ if (!ret)
+ vbva_disable(vbva_ctx, ctx, screen);
+
+ return ret;
+}
+
+void vbva_disable(struct vbva_buf_ctx *vbva_ctx, struct gen_pool *ctx,
+ s32 screen)
+{
+ vbva_ctx->buffer_overflow = false;
+ vbva_ctx->record = NULL;
+ vbva_ctx->vbva = NULL;
+
+ vbva_inform_host(vbva_ctx, ctx, screen, false);
+}
+
+bool vbva_buffer_begin_update(struct vbva_buf_ctx *vbva_ctx,
+ struct gen_pool *ctx)
+{
+ struct vbva_record *record;
+ u32 next;
+
+ if (!vbva_ctx->vbva ||
+ !(vbva_ctx->vbva->host_flags.host_events & VBVA_F_MODE_ENABLED))
+ return false;
+
+ WARN_ON(vbva_ctx->buffer_overflow || vbva_ctx->record);
+
+ next = (vbva_ctx->vbva->record_free_index + 1) % VBVA_MAX_RECORDS;
+
+ /* Flush if all slots in the records queue are used */
+ if (next == vbva_ctx->vbva->record_first_index)
+ vbva_buffer_flush(ctx);
+
+ /* If even after flush there is no place then fail the request */
+ if (next == vbva_ctx->vbva->record_first_index)
+ return false;
+
+ record = &vbva_ctx->vbva->records[vbva_ctx->vbva->record_free_index];
+ record->len_and_flags = VBVA_F_RECORD_PARTIAL;
+ vbva_ctx->vbva->record_free_index = next;
+ /* Remember which record we are using. */
+ vbva_ctx->record = record;
+
+ return true;
+}
+
+void vbva_buffer_end_update(struct vbva_buf_ctx *vbva_ctx)
+{
+ struct vbva_record *record = vbva_ctx->record;
+
+ WARN_ON(!vbva_ctx->vbva || !record ||
+ !(record->len_and_flags & VBVA_F_RECORD_PARTIAL));
+
+ /* Mark the record completed. */
+ record->len_and_flags &= ~VBVA_F_RECORD_PARTIAL;
+
+ vbva_ctx->buffer_overflow = false;
+ vbva_ctx->record = NULL;
+}
+
+void vbva_setup_buffer_context(struct vbva_buf_ctx *vbva_ctx,
+ u32 buffer_offset, u32 buffer_length)
+{
+ vbva_ctx->buffer_offset = buffer_offset;
+ vbva_ctx->buffer_length = buffer_length;
+}
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index 030bec855d86..314ffac50bb8 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -3391,7 +3391,6 @@ static int vchiq_probe(struct platform_device *pdev)
struct device_node *fw_node;
struct rpi_firmware *fw;
int err;
- void *ptr_err;
fw_node = of_parse_phandle(pdev->dev.of_node, "firmware", 0);
if (!fw_node) {
@@ -3427,14 +3426,14 @@ static int vchiq_probe(struct platform_device *pdev)
/* create sysfs entries */
vchiq_class = class_create(THIS_MODULE, DEVICE_NAME);
- ptr_err = vchiq_class;
- if (IS_ERR(ptr_err))
+ err = PTR_ERR(vchiq_class);
+ if (IS_ERR(vchiq_class))
goto failed_class_create;
vchiq_dev = device_create(vchiq_class, NULL,
vchiq_devid, NULL, "vchiq");
- ptr_err = vchiq_dev;
- if (IS_ERR(ptr_err))
+ err = PTR_ERR(vchiq_dev);
+ if (IS_ERR(vchiq_dev))
goto failed_device_create;
/* create debugfs entries */
@@ -3455,7 +3454,6 @@ failed_device_create:
class_destroy(vchiq_class);
failed_class_create:
cdev_del(&vchiq_cdev);
- err = PTR_ERR(ptr_err);
failed_cdev_add:
unregister_chrdev_region(vchiq_devid, 1);
failed_platform_init:
diff --git a/drivers/target/iscsi/cxgbit/cxgbit_cm.c b/drivers/target/iscsi/cxgbit/cxgbit_cm.c
index e583dd8a418b..d4fa41be80f9 100644
--- a/drivers/target/iscsi/cxgbit/cxgbit_cm.c
+++ b/drivers/target/iscsi/cxgbit/cxgbit_cm.c
@@ -1510,11 +1510,13 @@ cxgbit_pass_open_rpl(struct cxgbit_device *cdev, struct sk_buff *skb)
if (!cnp) {
pr_info("%s stid %d lookup failure\n", __func__, stid);
- return;
+ goto rel_skb;
}
cxgbit_wake_up(&cnp->com.wr_wait, __func__, rpl->status);
cxgbit_put_cnp(cnp);
+rel_skb:
+ __kfree_skb(skb);
}
static void
@@ -1530,11 +1532,13 @@ cxgbit_close_listsrv_rpl(struct cxgbit_device *cdev, struct sk_buff *skb)
if (!cnp) {
pr_info("%s stid %d lookup failure\n", __func__, stid);
- return;
+ goto rel_skb;
}
cxgbit_wake_up(&cnp->com.wr_wait, __func__, rpl->status);
cxgbit_put_cnp(cnp);
+rel_skb:
+ __kfree_skb(skb);
}
static void
@@ -1819,12 +1823,16 @@ static void cxgbit_set_tcb_rpl(struct cxgbit_device *cdev, struct sk_buff *skb)
struct tid_info *t = lldi->tids;
csk = lookup_tid(t, tid);
- if (unlikely(!csk))
+ if (unlikely(!csk)) {
pr_err("can't find connection for tid %u.\n", tid);
- else
+ goto rel_skb;
+ } else {
cxgbit_wake_up(&csk->com.wr_wait, __func__, rpl->status);
+ }
cxgbit_put_csk(csk);
+rel_skb:
+ __kfree_skb(skb);
}
static void cxgbit_rx_data(struct cxgbit_device *cdev, struct sk_buff *skb)
diff --git a/drivers/target/iscsi/cxgbit/cxgbit_target.c b/drivers/target/iscsi/cxgbit/cxgbit_target.c
index dda13f1af38e..514986b57c2d 100644
--- a/drivers/target/iscsi/cxgbit/cxgbit_target.c
+++ b/drivers/target/iscsi/cxgbit/cxgbit_target.c
@@ -827,7 +827,7 @@ cxgbit_put_login_tx(struct iscsi_conn *conn, struct iscsi_login *login,
static void
cxgbit_skb_copy_to_sg(struct sk_buff *skb, struct scatterlist *sg,
- unsigned int nents)
+ unsigned int nents, u32 skip)
{
struct skb_seq_state st;
const u8 *buf;
@@ -846,7 +846,7 @@ cxgbit_skb_copy_to_sg(struct sk_buff *skb, struct scatterlist *sg,
}
consumed += sg_pcopy_from_buffer(sg, nents, (void *)buf,
- buf_len, consumed);
+ buf_len, skip + consumed);
}
}
@@ -912,7 +912,7 @@ cxgbit_handle_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr,
struct scatterlist *sg = &cmd->se_cmd.t_data_sg[0];
u32 sg_nents = max(1UL, DIV_ROUND_UP(pdu_cb->dlen, PAGE_SIZE));
- cxgbit_skb_copy_to_sg(csk->skb, sg, sg_nents);
+ cxgbit_skb_copy_to_sg(csk->skb, sg, sg_nents, 0);
}
cmd->write_data_done += pdu_cb->dlen;
@@ -1069,11 +1069,13 @@ static int cxgbit_handle_iscsi_dataout(struct cxgbit_sock *csk)
cmd->se_cmd.data_length);
if (!(pdu_cb->flags & PDUCBF_RX_DATA_DDPD)) {
+ u32 skip = data_offset % PAGE_SIZE;
+
sg_off = data_offset / PAGE_SIZE;
sg_start = &cmd->se_cmd.t_data_sg[sg_off];
- sg_nents = max(1UL, DIV_ROUND_UP(data_len, PAGE_SIZE));
+ sg_nents = max(1UL, DIV_ROUND_UP(skip + data_len, PAGE_SIZE));
- cxgbit_skb_copy_to_sg(csk->skb, sg_start, sg_nents);
+ cxgbit_skb_copy_to_sg(csk->skb, sg_start, sg_nents, skip);
}
check_payload:
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 74e4975dd1b1..5001261f5d69 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -418,6 +418,7 @@ int iscsit_reset_np_thread(
return 0;
}
np->np_thread_state = ISCSI_NP_THREAD_RESET;
+ atomic_inc(&np->np_reset_count);
if (np->np_thread) {
spin_unlock_bh(&np->np_thread_lock);
@@ -2167,6 +2168,7 @@ iscsit_setup_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
cmd->cmd_sn = be32_to_cpu(hdr->cmdsn);
cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn);
cmd->data_direction = DMA_NONE;
+ kfree(cmd->text_in_ptr);
cmd->text_in_ptr = NULL;
return 0;
@@ -3487,9 +3489,9 @@ iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
return text_length;
if (completed) {
- hdr->flags |= ISCSI_FLAG_CMD_FINAL;
+ hdr->flags = ISCSI_FLAG_CMD_FINAL;
} else {
- hdr->flags |= ISCSI_FLAG_TEXT_CONTINUE;
+ hdr->flags = ISCSI_FLAG_TEXT_CONTINUE;
cmd->read_data_done += text_length;
if (cmd->targ_xfer_tag == 0xFFFFFFFF)
cmd->targ_xfer_tag = session_get_next_ttt(conn->sess);
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index e9bdc8b86e7d..dc13afbd4c88 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -1243,9 +1243,11 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
flush_signals(current);
spin_lock_bh(&np->np_thread_lock);
- if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
+ if (atomic_dec_if_positive(&np->np_reset_count) >= 0) {
np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
+ spin_unlock_bh(&np->np_thread_lock);
complete(&np->np_restart_comp);
+ return 1;
} else if (np->np_thread_state == ISCSI_NP_THREAD_SHUTDOWN) {
spin_unlock_bh(&np->np_thread_lock);
goto exit;
@@ -1278,7 +1280,8 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
goto exit;
} else if (rc < 0) {
spin_lock_bh(&np->np_thread_lock);
- if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
+ if (atomic_dec_if_positive(&np->np_reset_count) >= 0) {
+ np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
spin_unlock_bh(&np->np_thread_lock);
complete(&np->np_restart_comp);
iscsit_put_transport(conn->conn_transport);
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
index 36913734c6bc..02e8a5d86658 100644
--- a/drivers/target/target_core_tpg.c
+++ b/drivers/target/target_core_tpg.c
@@ -364,7 +364,7 @@ void core_tpg_del_initiator_node_acl(struct se_node_acl *acl)
mutex_lock(&tpg->acl_node_mutex);
if (acl->dynamic_node_acl)
acl->dynamic_node_acl = 0;
- list_del(&acl->acl_list);
+ list_del_init(&acl->acl_list);
mutex_unlock(&tpg->acl_node_mutex);
target_shutdown_sessions(acl);
@@ -548,7 +548,7 @@ int core_tpg_deregister(struct se_portal_group *se_tpg)
* in transport_deregister_session().
*/
list_for_each_entry_safe(nacl, nacl_tmp, &node_list, acl_list) {
- list_del(&nacl->acl_list);
+ list_del_init(&nacl->acl_list);
core_tpg_wait_for_nacl_pr_ref(nacl);
core_free_device_list_for_node(nacl, se_tpg);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 97fed9a298bd..836d552b0385 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -466,7 +466,7 @@ static void target_complete_nacl(struct kref *kref)
}
mutex_lock(&se_tpg->acl_node_mutex);
- list_del(&nacl->acl_list);
+ list_del_init(&nacl->acl_list);
mutex_unlock(&se_tpg->acl_node_mutex);
core_tpg_wait_for_nacl_pr_ref(nacl);
@@ -538,7 +538,7 @@ void transport_free_session(struct se_session *se_sess)
spin_unlock_irqrestore(&se_nacl->nacl_sess_lock, flags);
if (se_nacl->dynamic_stop)
- list_del(&se_nacl->acl_list);
+ list_del_init(&se_nacl->acl_list);
}
mutex_unlock(&se_tpg->acl_node_mutex);
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
index 80ee130f8253..942d094269fb 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -563,8 +563,6 @@ static int scatter_data_area(struct tcmu_dev *udev,
block_remaining);
to_offset = get_block_offset_user(udev, dbi,
block_remaining);
- offset = DATA_BLOCK_SIZE - block_remaining;
- to += offset;
if (*iov_cnt != 0 &&
to_offset == iov_tail(*iov)) {
@@ -575,8 +573,10 @@ static int scatter_data_area(struct tcmu_dev *udev,
(*iov)->iov_len = copy_bytes;
}
if (copy_data) {
- memcpy(to, from + sg->length - sg_remaining,
- copy_bytes);
+ offset = DATA_BLOCK_SIZE - block_remaining;
+ memcpy(to + offset,
+ from + sg->length - sg_remaining,
+ copy_bytes);
tcmu_flush_dcache_range(to, copy_bytes);
}
sg_remaining -= copy_bytes;
@@ -637,9 +637,8 @@ static void gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd,
copy_bytes = min_t(size_t, sg_remaining,
block_remaining);
offset = DATA_BLOCK_SIZE - block_remaining;
- from += offset;
tcmu_flush_dcache_range(from, copy_bytes);
- memcpy(to + sg->length - sg_remaining, from,
+ memcpy(to + sg->length - sg_remaining, from + offset,
copy_bytes);
sg_remaining -= copy_bytes;
@@ -1433,6 +1432,8 @@ static int tcmu_update_uio_info(struct tcmu_dev *udev)
if (udev->dev_config[0])
snprintf(str + used, size - used, "/%s", udev->dev_config);
+ /* If the old string exists, free it */
+ kfree(info->name);
info->name = str;
return 0;
diff --git a/drivers/thunderbolt/eeprom.c b/drivers/thunderbolt/eeprom.c
index 308b6e17c88a..fe2f00ceafc5 100644
--- a/drivers/thunderbolt/eeprom.c
+++ b/drivers/thunderbolt/eeprom.c
@@ -333,6 +333,15 @@ static int tb_drom_parse_entry_port(struct tb_switch *sw,
int res;
enum tb_port_type type;
+ /*
+ * Some DROMs list more ports than the controller actually has
+ * so we skip those but allow the parser to continue.
+ */
+ if (header->index > sw->config.max_port_number) {
+ dev_info_once(&sw->dev, "ignoring unnecessary extra entries in DROM\n");
+ return 0;
+ }
+
port = &sw->ports[header->index];
port->disabled = header->port_disabled;
if (port->disabled)
diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c
index 8ee340290219..bdaac1ff00a5 100644
--- a/drivers/thunderbolt/icm.c
+++ b/drivers/thunderbolt/icm.c
@@ -904,7 +904,14 @@ static int icm_driver_ready(struct tb *tb)
static int icm_suspend(struct tb *tb)
{
- return nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_SAVE_DEVS, 0);
+ int ret;
+
+ ret = nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_SAVE_DEVS, 0);
+ if (ret)
+ tb_info(tb, "Ignoring mailbox command error (%d) in %s\n",
+ ret, __func__);
+
+ return 0;
}
/*
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index ab3e8f410444..e9391bbd4036 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -30,7 +30,7 @@ static DEFINE_IDA(nvm_ida);
struct nvm_auth_status {
struct list_head list;
- uuid_be uuid;
+ uuid_t uuid;
u32 status;
};
@@ -47,7 +47,7 @@ static struct nvm_auth_status *__nvm_get_auth_status(const struct tb_switch *sw)
struct nvm_auth_status *st;
list_for_each_entry(st, &nvm_auth_status_cache, list) {
- if (!uuid_be_cmp(st->uuid, *sw->uuid))
+ if (uuid_equal(&st->uuid, sw->uuid))
return st;
}
@@ -281,9 +281,11 @@ static struct nvmem_device *register_nvmem(struct tb_switch *sw, int id,
if (active) {
config.name = "nvm_active";
config.reg_read = tb_switch_nvm_read;
+ config.read_only = true;
} else {
config.name = "nvm_non_active";
config.reg_write = tb_switch_nvm_write;
+ config.root_only = true;
}
config.id = id;
@@ -292,7 +294,6 @@ static struct nvmem_device *register_nvmem(struct tb_switch *sw, int id,
config.size = size;
config.dev = &sw->dev;
config.owner = THIS_MODULE;
- config.root_only = true;
config.priv = sw;
return nvmem_register(&config);
@@ -1460,7 +1461,7 @@ struct tb_sw_lookup {
struct tb *tb;
u8 link;
u8 depth;
- const uuid_be *uuid;
+ const uuid_t *uuid;
};
static int tb_switch_match(struct device *dev, void *data)
@@ -1517,7 +1518,7 @@ struct tb_switch *tb_switch_find_by_link_depth(struct tb *tb, u8 link, u8 depth)
* Returned switch has reference count increased so the caller needs to
* call tb_switch_put() when done with the switch.
*/
-struct tb_switch *tb_switch_find_by_uuid(struct tb *tb, const uuid_be *uuid)
+struct tb_switch *tb_switch_find_by_uuid(struct tb *tb, const uuid_t *uuid)
{
struct tb_sw_lookup lookup;
struct device *dev;
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index 3d9f64676e58..e0deee4f1eb0 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -101,7 +101,7 @@ struct tb_switch {
struct tb_dma_port *dma_port;
struct tb *tb;
u64 uid;
- uuid_be *uuid;
+ uuid_t *uuid;
u16 vendor;
u16 device;
const char *vendor_name;
@@ -407,7 +407,7 @@ void tb_sw_set_unplugged(struct tb_switch *sw);
struct tb_switch *get_switch_at_route(struct tb_switch *sw, u64 route);
struct tb_switch *tb_switch_find_by_link_depth(struct tb *tb, u8 link,
u8 depth);
-struct tb_switch *tb_switch_find_by_uuid(struct tb *tb, const uuid_be *uuid);
+struct tb_switch *tb_switch_find_by_uuid(struct tb *tb, const uuid_t *uuid);
static inline unsigned int tb_switch_phy_port_from_link(unsigned int link)
{
diff --git a/drivers/thunderbolt/tb_msgs.h b/drivers/thunderbolt/tb_msgs.h
index 85b6d33c0919..de6441e4a060 100644
--- a/drivers/thunderbolt/tb_msgs.h
+++ b/drivers/thunderbolt/tb_msgs.h
@@ -179,7 +179,7 @@ struct icm_fr_pkg_get_topology_response {
struct icm_fr_event_device_connected {
struct icm_pkg_header hdr;
- uuid_be ep_uuid;
+ uuid_t ep_uuid;
u8 connection_key;
u8 connection_id;
u16 link_info;
@@ -193,7 +193,7 @@ struct icm_fr_event_device_connected {
struct icm_fr_pkg_approve_device {
struct icm_pkg_header hdr;
- uuid_be ep_uuid;
+ uuid_t ep_uuid;
u8 connection_key;
u8 connection_id;
u16 reserved;
@@ -207,7 +207,7 @@ struct icm_fr_event_device_disconnected {
struct icm_fr_pkg_add_device_key {
struct icm_pkg_header hdr;
- uuid_be ep_uuid;
+ uuid_t ep_uuid;
u8 connection_key;
u8 connection_id;
u16 reserved;
@@ -216,7 +216,7 @@ struct icm_fr_pkg_add_device_key {
struct icm_fr_pkg_add_device_key_response {
struct icm_pkg_header hdr;
- uuid_be ep_uuid;
+ uuid_t ep_uuid;
u8 connection_key;
u8 connection_id;
u16 reserved;
@@ -224,7 +224,7 @@ struct icm_fr_pkg_add_device_key_response {
struct icm_fr_pkg_challenge_device {
struct icm_pkg_header hdr;
- uuid_be ep_uuid;
+ uuid_t ep_uuid;
u8 connection_key;
u8 connection_id;
u16 reserved;
@@ -233,7 +233,7 @@ struct icm_fr_pkg_challenge_device {
struct icm_fr_pkg_challenge_device_response {
struct icm_pkg_header hdr;
- uuid_be ep_uuid;
+ uuid_t ep_uuid;
u8 connection_key;
u8 connection_id;
u16 reserved;
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index d1399aac05a1..284749fb0f6b 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -448,48 +448,6 @@ err:
return retval;
}
-/**
- * pty_open_peer - open the peer of a pty
- * @tty: the peer of the pty being opened
- *
- * Open the cached dentry in tty->link, providing a safe way for userspace
- * to get the slave end of a pty (where they have the master fd and cannot
- * access or trust the mount namespace /dev/pts was mounted inside).
- */
-static struct file *pty_open_peer(struct tty_struct *tty, int flags)
-{
- if (tty->driver->subtype != PTY_TYPE_MASTER)
- return ERR_PTR(-EIO);
- return dentry_open(tty->link->driver_data, flags, current_cred());
-}
-
-static int pty_get_peer(struct tty_struct *tty, int flags)
-{
- int fd = -1;
- struct file *filp = NULL;
- int retval = -EINVAL;
-
- fd = get_unused_fd_flags(0);
- if (fd < 0) {
- retval = fd;
- goto err;
- }
-
- filp = pty_open_peer(tty, flags);
- if (IS_ERR(filp)) {
- retval = PTR_ERR(filp);
- goto err_put;
- }
-
- fd_install(fd, filp);
- return fd;
-
-err_put:
- put_unused_fd(fd);
-err:
- return retval;
-}
-
static void pty_cleanup(struct tty_struct *tty)
{
tty_port_put(tty->port);
@@ -646,9 +604,50 @@ static inline void legacy_pty_init(void) { }
/* Unix98 devices */
#ifdef CONFIG_UNIX98_PTYS
-
static struct cdev ptmx_cdev;
+/**
+ * pty_open_peer - open the peer of a pty
+ * @tty: the peer of the pty being opened
+ *
+ * Open the cached dentry in tty->link, providing a safe way for userspace
+ * to get the slave end of a pty (where they have the master fd and cannot
+ * access or trust the mount namespace /dev/pts was mounted inside).
+ */
+static struct file *pty_open_peer(struct tty_struct *tty, int flags)
+{
+ if (tty->driver->subtype != PTY_TYPE_MASTER)
+ return ERR_PTR(-EIO);
+ return dentry_open(tty->link->driver_data, flags, current_cred());
+}
+
+static int pty_get_peer(struct tty_struct *tty, int flags)
+{
+ int fd = -1;
+ struct file *filp = NULL;
+ int retval = -EINVAL;
+
+ fd = get_unused_fd_flags(0);
+ if (fd < 0) {
+ retval = fd;
+ goto err;
+ }
+
+ filp = pty_open_peer(tty, flags);
+ if (IS_ERR(filp)) {
+ retval = PTR_ERR(filp);
+ goto err_put;
+ }
+
+ fd_install(fd, filp);
+ return fd;
+
+err_put:
+ put_unused_fd(fd);
+err:
+ return retval;
+}
+
static int pty_unix98_ioctl(struct tty_struct *tty,
unsigned int cmd, unsigned long arg)
{
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index b5def356af63..1aab3010fbfa 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -1043,13 +1043,24 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
if (up->dl_write)
uart->dl_write = up->dl_write;
- if (serial8250_isa_config != NULL)
- serial8250_isa_config(0, &uart->port,
- &uart->capabilities);
+ if (uart->port.type != PORT_8250_CIR) {
+ if (serial8250_isa_config != NULL)
+ serial8250_isa_config(0, &uart->port,
+ &uart->capabilities);
+
+ ret = uart_add_one_port(&serial8250_reg,
+ &uart->port);
+ if (ret == 0)
+ ret = uart->port.line;
+ } else {
+ dev_info(uart->port.dev,
+ "skipping CIR port at 0x%lx / 0x%llx, IRQ %d\n",
+ uart->port.iobase,
+ (unsigned long long)uart->port.mapbase,
+ uart->port.irq);
- ret = uart_add_one_port(&serial8250_reg, &uart->port);
- if (ret == 0)
- ret = uart->port.line;
+ ret = 0;
+ }
}
mutex_unlock(&serial_mutex);
diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c
index b5c98e5bf524..c6360fbdf808 100644
--- a/drivers/tty/serial/8250/8250_exar.c
+++ b/drivers/tty/serial/8250/8250_exar.c
@@ -261,7 +261,7 @@ __xr17v35x_register_gpio(struct pci_dev *pcidev,
}
static const struct property_entry exar_gpio_properties[] = {
- PROPERTY_ENTRY_U32("linux,first-pin", 0),
+ PROPERTY_ENTRY_U32("exar,first-pin", 0),
PROPERTY_ENTRY_U32("ngpios", 16),
{ }
};
@@ -326,7 +326,7 @@ static int iot2040_rs485_config(struct uart_port *port,
}
static const struct property_entry iot2040_gpio_properties[] = {
- PROPERTY_ENTRY_U32("linux,first-pin", 10),
+ PROPERTY_ENTRY_U32("exar,first-pin", 10),
PROPERTY_ENTRY_U32("ngpios", 1),
{ }
};
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 8a857bb34fbb..1888d168a41c 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -142,15 +142,7 @@ static struct vendor_data vendor_sbsa = {
.fixed_options = true,
};
-/*
- * Erratum 44 for QDF2432v1 and QDF2400v1 SoCs describes the BUSY bit as
- * occasionally getting stuck as 1. To avoid the potential for a hang, check
- * TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART
- * implementations, so only do so if an affected platform is detected in
- * parse_spcr().
- */
-static bool qdf2400_e44_present = false;
-
+#ifdef CONFIG_ACPI_SPCR_TABLE
static struct vendor_data vendor_qdt_qdf2400_e44 = {
.reg_offset = pl011_std_offsets,
.fr_busy = UART011_FR_TXFE,
@@ -165,6 +157,7 @@ static struct vendor_data vendor_qdt_qdf2400_e44 = {
.always_enabled = true,
.fixed_options = true,
};
+#endif
static u16 pl011_st_offsets[REG_ARRAY_SIZE] = {
[REG_DR] = UART01x_DR,
@@ -2375,12 +2368,14 @@ static int __init pl011_console_match(struct console *co, char *name, int idx,
resource_size_t addr;
int i;
- if (strcmp(name, "qdf2400_e44") == 0) {
- pr_info_once("UART: Working around QDF2400 SoC erratum 44");
- qdf2400_e44_present = true;
- } else if (strcmp(name, "pl011") != 0) {
+ /*
+ * Systems affected by the Qualcomm Technologies QDF2400 E44 erratum
+ * have a distinct console name, so make sure we check for that.
+ * The actual implementation of the erratum occurs in the probe
+ * function.
+ */
+ if ((strcmp(name, "qdf2400_e44") != 0) && (strcmp(name, "pl011") != 0))
return -ENODEV;
- }
if (uart_parse_earlycon(options, &iotype, &addr, &options))
return -ENODEV;
@@ -2734,11 +2729,17 @@ static int sbsa_uart_probe(struct platform_device *pdev)
}
uap->port.irq = ret;
- uap->reg_offset = vendor_sbsa.reg_offset;
- uap->vendor = qdf2400_e44_present ?
- &vendor_qdt_qdf2400_e44 : &vendor_sbsa;
+#ifdef CONFIG_ACPI_SPCR_TABLE
+ if (qdf2400_e44_present) {
+ dev_info(&pdev->dev, "working around QDF2400 SoC erratum 44\n");
+ uap->vendor = &vendor_qdt_qdf2400_e44;
+ } else
+#endif
+ uap->vendor = &vendor_sbsa;
+
+ uap->reg_offset = uap->vendor->reg_offset;
uap->fifosize = 32;
- uap->port.iotype = vendor_sbsa.access_32b ? UPIO_MEM32 : UPIO_MEM;
+ uap->port.iotype = uap->vendor->access_32b ? UPIO_MEM32 : UPIO_MEM;
uap->port.ops = &sbsa_uart_pops;
uap->fixed_baud = baudrate;
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 343de8c384b0..898dcb091a27 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -619,6 +619,12 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port)
TIOCSER_TEMT : 0;
}
+static bool lpuart_is_32(struct lpuart_port *sport)
+{
+ return sport->port.iotype == UPIO_MEM32 ||
+ sport->port.iotype == UPIO_MEM32BE;
+}
+
static irqreturn_t lpuart_txint(int irq, void *dev_id)
{
struct lpuart_port *sport = dev_id;
@@ -627,7 +633,7 @@ static irqreturn_t lpuart_txint(int irq, void *dev_id)
spin_lock_irqsave(&sport->port.lock, flags);
if (sport->port.x_char) {
- if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
+ if (lpuart_is_32(sport))
lpuart32_write(&sport->port, sport->port.x_char, UARTDATA);
else
writeb(sport->port.x_char, sport->port.membase + UARTDR);
@@ -635,14 +641,14 @@ static irqreturn_t lpuart_txint(int irq, void *dev_id)
}
if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
- if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
+ if (lpuart_is_32(sport))
lpuart32_stop_tx(&sport->port);
else
lpuart_stop_tx(&sport->port);
goto out;
}
- if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
+ if (lpuart_is_32(sport))
lpuart32_transmit_buffer(sport);
else
lpuart_transmit_buffer(sport);
@@ -1978,12 +1984,12 @@ static int __init lpuart_console_setup(struct console *co, char *options)
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
else
- if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
+ if (lpuart_is_32(sport))
lpuart32_console_get_options(sport, &baud, &parity, &bits);
else
lpuart_console_get_options(sport, &baud, &parity, &bits);
- if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
+ if (lpuart_is_32(sport))
lpuart32_setup_watermark(sport);
else
lpuart_setup_watermark(sport);
@@ -2118,7 +2124,7 @@ static int lpuart_probe(struct platform_device *pdev)
}
sport->port.irq = ret;
sport->port.iotype = sdata->iotype;
- if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
+ if (lpuart_is_32(sport))
sport->port.ops = &lpuart32_pops;
else
sport->port.ops = &lpuart_pops;
@@ -2145,7 +2151,7 @@ static int lpuart_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, &sport->port);
- if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE))
+ if (lpuart_is_32(sport))
lpuart_reg.cons = LPUART32_CONSOLE;
else
lpuart_reg.cons = LPUART_CONSOLE;
@@ -2198,7 +2204,7 @@ static int lpuart_suspend(struct device *dev)
struct lpuart_port *sport = dev_get_drvdata(dev);
unsigned long temp;
- if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE)) {
+ if (lpuart_is_32(sport)) {
/* disable Rx/Tx and interrupts */
temp = lpuart32_read(&sport->port, UARTCTRL);
temp &= ~(UARTCTRL_TE | UARTCTRL_TIE | UARTCTRL_TCIE);
@@ -2249,7 +2255,7 @@ static int lpuart_resume(struct device *dev)
if (sport->port.suspended && !sport->port.irq_wake)
clk_prepare_enable(sport->clk);
- if (sport->port.iotype & (UPIO_MEM32 | UPIO_MEM32BE)) {
+ if (lpuart_is_32(sport)) {
lpuart32_setup_watermark(sport);
temp = lpuart32_read(&sport->port, UARTCTRL);
temp |= (UARTCTRL_RIE | UARTCTRL_TIE | UARTCTRL_RE |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 9e3162bf3bd1..80934e7bd67f 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -186,11 +186,6 @@
#define UART_NR 8
-/* RX DMA buffer periods */
-#define RX_DMA_PERIODS 4
-#define RX_BUF_SIZE (PAGE_SIZE)
-
-
/* i.MX21 type uart runs on all i.mx except i.MX1 and i.MX6q */
enum imx_uart_type {
IMX1_UART,
@@ -226,7 +221,6 @@ struct imx_port {
struct dma_chan *dma_chan_rx, *dma_chan_tx;
struct scatterlist rx_sgl, tx_sgl[2];
void *rx_buf;
- unsigned int rx_buf_size;
struct circ_buf rx_ring;
unsigned int rx_periods;
dma_cookie_t rx_cookie;
@@ -464,7 +458,7 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
}
}
- while (!uart_circ_empty(xmit) &&
+ while (!uart_circ_empty(xmit) && !sport->dma_is_txing &&
!(readl(sport->port.membase + uts_reg(sport)) & UTS_TXFULL)) {
/* send xmit->buf[xmit->tail]
* out the port here */
@@ -967,6 +961,8 @@ static void imx_timeout(unsigned long data)
}
}
+#define RX_BUF_SIZE (PAGE_SIZE)
+
/*
* There are two kinds of RX DMA interrupts(such as in the MX6Q):
* [1] the RX DMA buffer is full.
@@ -1049,6 +1045,9 @@ static void dma_rx_callback(void *data)
}
}
+/* RX DMA buffer periods */
+#define RX_DMA_PERIODS 4
+
static int start_rx_dma(struct imx_port *sport)
{
struct scatterlist *sgl = &sport->rx_sgl;
@@ -1059,8 +1058,9 @@ static int start_rx_dma(struct imx_port *sport)
sport->rx_ring.head = 0;
sport->rx_ring.tail = 0;
+ sport->rx_periods = RX_DMA_PERIODS;
- sg_init_one(sgl, sport->rx_buf, sport->rx_buf_size);
+ sg_init_one(sgl, sport->rx_buf, RX_BUF_SIZE);
ret = dma_map_sg(dev, sgl, 1, DMA_FROM_DEVICE);
if (ret == 0) {
dev_err(dev, "DMA mapping error for RX.\n");
@@ -1171,7 +1171,7 @@ static int imx_uart_dma_init(struct imx_port *sport)
goto err;
}
- sport->rx_buf = kzalloc(sport->rx_buf_size, GFP_KERNEL);
+ sport->rx_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
if (!sport->rx_buf) {
ret = -ENOMEM;
goto err;
@@ -2036,7 +2036,6 @@ static int serial_imx_probe_dt(struct imx_port *sport,
{
struct device_node *np = pdev->dev.of_node;
int ret;
- u32 dma_buf_size[2];
sport->devdata = of_device_get_match_data(&pdev->dev);
if (!sport->devdata)
@@ -2060,14 +2059,6 @@ static int serial_imx_probe_dt(struct imx_port *sport,
if (of_get_property(np, "rts-gpios", NULL))
sport->have_rtsgpio = 1;
- if (!of_property_read_u32_array(np, "fsl,dma-size", dma_buf_size, 2)) {
- sport->rx_buf_size = dma_buf_size[0] * dma_buf_size[1];
- sport->rx_periods = dma_buf_size[1];
- } else {
- sport->rx_buf_size = RX_BUF_SIZE;
- sport->rx_periods = RX_DMA_PERIODS;
- }
-
return 0;
}
#else
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index da5ddfc14778..e08b16b070c0 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1085,10 +1085,12 @@ static ssize_t rx_trigger_store(struct device *dev,
{
struct uart_port *port = dev_get_drvdata(dev);
struct sci_port *sci = to_sci_port(port);
+ int ret;
long r;
- if (kstrtol(buf, 0, &r) == -EINVAL)
- return -EINVAL;
+ ret = kstrtol(buf, 0, &r);
+ if (ret)
+ return ret;
sci->rx_trigger = scif_set_rtrg(port, r);
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
@@ -1116,10 +1118,12 @@ static ssize_t rx_fifo_timeout_store(struct device *dev,
{
struct uart_port *port = dev_get_drvdata(dev);
struct sci_port *sci = to_sci_port(port);
+ int ret;
long r;
- if (kstrtol(buf, 0, &r) == -EINVAL)
- return -EINVAL;
+ ret = kstrtol(buf, 0, &r);
+ if (ret)
+ return ret;
sci->rx_fifo_timeout = r;
scif_set_rtrg(port, 1);
if (r > 0)
diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c
index f5335be344f6..6b0ca65027d0 100644
--- a/drivers/tty/serial/st-asc.c
+++ b/drivers/tty/serial/st-asc.c
@@ -758,6 +758,7 @@ static int asc_init_port(struct asc_port *ascport,
if (IS_ERR(ascport->pinctrl)) {
ret = PTR_ERR(ascport->pinctrl);
dev_err(&pdev->dev, "Failed to get Pinctrl: %d\n", ret);
+ return ret;
}
ascport->states[DEFAULT] =
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 5357d83bbda2..5e056064259c 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1829,6 +1829,9 @@ static const struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x1576, 0x03b1), /* Maretron USB100 */
.driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
},
+ { USB_DEVICE(0xfff0, 0x0100), /* DATECS FP-2000 */
+ .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
+ },
{ USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */
.driver_info = CLEAR_HALT_CONDITIONS,
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index ab1bb3b538ac..7f277b092b5b 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1888,7 +1888,7 @@ void usb_hcd_flush_endpoint(struct usb_device *udev,
/* No more submits can occur */
spin_lock_irq(&hcd_urb_list_lock);
rescan:
- list_for_each_entry (urb, &ep->urb_list, urb_list) {
+ list_for_each_entry_reverse(urb, &ep->urb_list, urb_list) {
int is_in;
if (urb->unlinked)
@@ -2485,6 +2485,8 @@ void usb_hc_died (struct usb_hcd *hcd)
}
if (usb_hcd_is_primary_hcd(hcd) && hcd->shared_hcd) {
hcd = hcd->shared_hcd;
+ clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
+ set_bit(HCD_FLAG_DEAD, &hcd->flags);
if (hcd->rh_registered) {
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 6e6797d145dd..822f8c50e423 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -4725,7 +4725,8 @@ hub_power_remaining(struct usb_hub *hub)
static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
u16 portchange)
{
- int status, i;
+ int status = -ENODEV;
+ int i;
unsigned unit_load;
struct usb_device *hdev = hub->hdev;
struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
@@ -4929,9 +4930,10 @@ loop:
done:
hub_port_disable(hub, port1, 1);
- if (hcd->driver->relinquish_port && !hub->hdev->parent)
- hcd->driver->relinquish_port(hcd, port1);
-
+ if (hcd->driver->relinquish_port && !hub->hdev->parent) {
+ if (status != -ENOTCONN && status != -ENODEV)
+ hcd->driver->relinquish_port(hcd, port1);
+ }
}
/* Handle physical or logical connection change events.
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 3116edfcdc18..574da2b4529c 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -150,6 +150,9 @@ static const struct usb_device_id usb_quirk_list[] = {
/* appletouch */
{ USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Genesys Logic hub, internally used by Moshi USB to Ethernet Adapter */
+ { USB_DEVICE(0x05e3, 0x0616), .driver_info = USB_QUIRK_NO_LPM },
+
/* Avision AV600U */
{ USB_DEVICE(0x0638, 0x0a13), .driver_info =
USB_QUIRK_STRING_FETCH_255 },
@@ -249,6 +252,7 @@ static const struct usb_device_id usb_amd_resume_quirk_list[] = {
{ USB_DEVICE(0x093a, 0x2500), .driver_info = USB_QUIRK_RESET_RESUME },
{ USB_DEVICE(0x093a, 0x2510), .driver_info = USB_QUIRK_RESET_RESUME },
{ USB_DEVICE(0x093a, 0x2521), .driver_info = USB_QUIRK_RESET_RESUME },
+ { USB_DEVICE(0x03f0, 0x2b4a), .driver_info = USB_QUIRK_RESET_RESUME },
/* Logitech Optical Mouse M90/M100 */
{ USB_DEVICE(0x046d, 0xc05a), .driver_info = USB_QUIRK_RESET_RESUME },
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index bc3b3fda5000..c4066cd77e47 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -3573,6 +3573,9 @@ irq_retry:
/* Report disconnection if it is not already done. */
dwc2_hsotg_disconnect(hsotg);
+ /* Reset device address to zero */
+ __bic32(hsotg->regs + DCFG, DCFG_DEVADDR_MASK);
+
if (usb_status & GOTGCTL_BSESVLD && connected)
dwc2_hsotg_core_init_disconnected(hsotg, true);
}
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 326b302fc440..03474d3575ab 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -766,15 +766,15 @@ static int dwc3_core_init(struct dwc3 *dwc)
dwc->maximum_speed = USB_SPEED_HIGH;
}
- ret = dwc3_core_soft_reset(dwc);
+ ret = dwc3_core_get_phy(dwc);
if (ret)
goto err0;
- ret = dwc3_phy_setup(dwc);
+ ret = dwc3_core_soft_reset(dwc);
if (ret)
goto err0;
- ret = dwc3_core_get_phy(dwc);
+ ret = dwc3_phy_setup(dwc);
if (ret)
goto err0;
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 98926504b55b..f5aaa0cf3873 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -512,15 +512,6 @@ static int dwc3_omap_probe(struct platform_device *pdev)
/* check the DMA Status */
reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG);
- irq_set_status_flags(omap->irq, IRQ_NOAUTOEN);
- ret = devm_request_threaded_irq(dev, omap->irq, dwc3_omap_interrupt,
- dwc3_omap_interrupt_thread, IRQF_SHARED,
- "dwc3-omap", omap);
- if (ret) {
- dev_err(dev, "failed to request IRQ #%d --> %d\n",
- omap->irq, ret);
- goto err1;
- }
ret = dwc3_omap_extcon_register(omap);
if (ret < 0)
@@ -532,8 +523,15 @@ static int dwc3_omap_probe(struct platform_device *pdev)
goto err1;
}
+ ret = devm_request_threaded_irq(dev, omap->irq, dwc3_omap_interrupt,
+ dwc3_omap_interrupt_thread, IRQF_SHARED,
+ "dwc3-omap", omap);
+ if (ret) {
+ dev_err(dev, "failed to request IRQ #%d --> %d\n",
+ omap->irq, ret);
+ goto err1;
+ }
dwc3_omap_enable_irqs(omap);
- enable_irq(omap->irq);
return 0;
err1:
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 9e41605a276b..f064f1549333 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -191,14 +191,16 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
req->started = false;
list_del(&req->list);
- req->trb = NULL;
req->remaining = 0;
if (req->request.status == -EINPROGRESS)
req->request.status = status;
- usb_gadget_unmap_request_by_dev(dwc->sysdev,
- &req->request, req->direction);
+ if (req->trb)
+ usb_gadget_unmap_request_by_dev(dwc->sysdev,
+ &req->request, req->direction);
+
+ req->trb = NULL;
trace_dwc3_gadget_giveback(req);
@@ -894,9 +896,40 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb,
if (!node) {
trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
+ /*
+ * USB Specification 2.0 Section 5.9.2 states that: "If
+ * there is only a single transaction in the microframe,
+ * only a DATA0 data packet PID is used. If there are
+ * two transactions per microframe, DATA1 is used for
+ * the first transaction data packet and DATA0 is used
+ * for the second transaction data packet. If there are
+ * three transactions per microframe, DATA2 is used for
+ * the first transaction data packet, DATA1 is used for
+ * the second, and DATA0 is used for the third."
+ *
+ * IOW, we should satisfy the following cases:
+ *
+ * 1) length <= maxpacket
+ * - DATA0
+ *
+ * 2) maxpacket < length <= (2 * maxpacket)
+ * - DATA1, DATA0
+ *
+ * 3) (2 * maxpacket) < length <= (3 * maxpacket)
+ * - DATA2, DATA1, DATA0
+ */
if (speed == USB_SPEED_HIGH) {
struct usb_ep *ep = &dep->endpoint;
- trb->size |= DWC3_TRB_SIZE_PCM1(ep->mult - 1);
+ unsigned int mult = ep->mult - 1;
+ unsigned int maxp = usb_endpoint_maxp(ep->desc);
+
+ if (length <= (2 * maxp))
+ mult--;
+
+ if (length <= maxp)
+ mult--;
+
+ trb->size |= DWC3_TRB_SIZE_PCM1(mult);
}
} else {
trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS;
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
index e80b9c123a9d..f95bddd6513f 100644
--- a/drivers/usb/gadget/function/f_mass_storage.c
+++ b/drivers/usb/gadget/function/f_mass_storage.c
@@ -2490,7 +2490,7 @@ static int fsg_main_thread(void *common_)
int i;
down_write(&common->filesem);
- for (i = 0; i < ARRAY_SIZE(common->luns); --i) {
+ for (i = 0; i < ARRAY_SIZE(common->luns); i++) {
struct fsg_lun *curlun = common->luns[i];
if (!curlun || !fsg_lun_is_open(curlun))
continue;
diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c
index 8656f84e17d9..29efbedc91f9 100644
--- a/drivers/usb/gadget/function/f_uac1.c
+++ b/drivers/usb/gadget/function/f_uac1.c
@@ -92,9 +92,9 @@ static struct uac_input_terminal_descriptor usb_out_it_desc = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = UAC_INPUT_TERMINAL,
.bTerminalID = USB_OUT_IT_ID,
- .wTerminalType = UAC_TERMINAL_STREAMING,
+ .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING),
.bAssocTerminal = 0,
- .wChannelConfig = 0x3,
+ .wChannelConfig = cpu_to_le16(0x3),
};
#define IO_OUT_OT_ID 2
@@ -103,7 +103,7 @@ static struct uac1_output_terminal_descriptor io_out_ot_desc = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = UAC_OUTPUT_TERMINAL,
.bTerminalID = IO_OUT_OT_ID,
- .wTerminalType = UAC_OUTPUT_TERMINAL_SPEAKER,
+ .wTerminalType = cpu_to_le16(UAC_OUTPUT_TERMINAL_SPEAKER),
.bAssocTerminal = 0,
.bSourceID = USB_OUT_IT_ID,
};
@@ -114,9 +114,9 @@ static struct uac_input_terminal_descriptor io_in_it_desc = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = UAC_INPUT_TERMINAL,
.bTerminalID = IO_IN_IT_ID,
- .wTerminalType = UAC_INPUT_TERMINAL_MICROPHONE,
+ .wTerminalType = cpu_to_le16(UAC_INPUT_TERMINAL_MICROPHONE),
.bAssocTerminal = 0,
- .wChannelConfig = 0x3,
+ .wChannelConfig = cpu_to_le16(0x3),
};
#define USB_IN_OT_ID 4
@@ -125,7 +125,7 @@ static struct uac1_output_terminal_descriptor usb_in_ot_desc = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = UAC_OUTPUT_TERMINAL,
.bTerminalID = USB_IN_OT_ID,
- .wTerminalType = UAC_TERMINAL_STREAMING,
+ .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING),
.bAssocTerminal = 0,
.bSourceID = IO_IN_IT_ID,
};
@@ -174,7 +174,7 @@ static struct uac1_as_header_descriptor as_out_header_desc = {
.bDescriptorSubtype = UAC_AS_GENERAL,
.bTerminalLink = USB_OUT_IT_ID,
.bDelay = 1,
- .wFormatTag = UAC_FORMAT_TYPE_I_PCM,
+ .wFormatTag = cpu_to_le16(UAC_FORMAT_TYPE_I_PCM),
};
static struct uac1_as_header_descriptor as_in_header_desc = {
@@ -183,7 +183,7 @@ static struct uac1_as_header_descriptor as_in_header_desc = {
.bDescriptorSubtype = UAC_AS_GENERAL,
.bTerminalLink = USB_IN_OT_ID,
.bDelay = 1,
- .wFormatTag = UAC_FORMAT_TYPE_I_PCM,
+ .wFormatTag = cpu_to_le16(UAC_FORMAT_TYPE_I_PCM),
};
DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1);
@@ -606,8 +606,8 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f)
if (status)
goto fail;
- audio->out_ep_maxpsize = as_out_ep_desc.wMaxPacketSize;
- audio->in_ep_maxpsize = as_in_ep_desc.wMaxPacketSize;
+ audio->out_ep_maxpsize = le16_to_cpu(as_out_ep_desc.wMaxPacketSize);
+ audio->in_ep_maxpsize = le16_to_cpu(as_in_ep_desc.wMaxPacketSize);
audio->params.c_chmask = audio_opts->c_chmask;
audio->params.c_srate = audio_opts->c_srate;
audio->params.c_ssize = audio_opts->c_ssize;
diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c
index 9082ce261e70..f05c3f3e6103 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -168,7 +168,7 @@ static struct uac2_input_terminal_descriptor usb_out_it_desc = {
.bAssocTerminal = 0,
.bCSourceID = USB_OUT_CLK_ID,
.iChannelNames = 0,
- .bmControls = (CONTROL_RDWR << COPY_CTRL),
+ .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL),
};
/* Input Terminal for I/O-In */
@@ -182,7 +182,7 @@ static struct uac2_input_terminal_descriptor io_in_it_desc = {
.bAssocTerminal = 0,
.bCSourceID = USB_IN_CLK_ID,
.iChannelNames = 0,
- .bmControls = (CONTROL_RDWR << COPY_CTRL),
+ .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL),
};
/* Ouput Terminal for USB_IN */
@@ -196,7 +196,7 @@ static struct uac2_output_terminal_descriptor usb_in_ot_desc = {
.bAssocTerminal = 0,
.bSourceID = IO_IN_IT_ID,
.bCSourceID = USB_IN_CLK_ID,
- .bmControls = (CONTROL_RDWR << COPY_CTRL),
+ .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL),
};
/* Ouput Terminal for I/O-Out */
@@ -210,7 +210,7 @@ static struct uac2_output_terminal_descriptor io_out_ot_desc = {
.bAssocTerminal = 0,
.bSourceID = USB_OUT_IT_ID,
.bCSourceID = USB_OUT_CLK_ID,
- .bmControls = (CONTROL_RDWR << COPY_CTRL),
+ .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL),
};
static struct uac2_ac_header_descriptor ac_hdr_desc = {
@@ -220,9 +220,10 @@ static struct uac2_ac_header_descriptor ac_hdr_desc = {
.bDescriptorSubtype = UAC_MS_HEADER,
.bcdADC = cpu_to_le16(0x200),
.bCategory = UAC2_FUNCTION_IO_BOX,
- .wTotalLength = sizeof in_clk_src_desc + sizeof out_clk_src_desc
- + sizeof usb_out_it_desc + sizeof io_in_it_desc
- + sizeof usb_in_ot_desc + sizeof io_out_ot_desc,
+ .wTotalLength = cpu_to_le16(sizeof in_clk_src_desc
+ + sizeof out_clk_src_desc + sizeof usb_out_it_desc
+ + sizeof io_in_it_desc + sizeof usb_in_ot_desc
+ + sizeof io_out_ot_desc),
.bmControls = 0,
};
@@ -569,10 +570,12 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
return ret;
}
- agdev->in_ep_maxpsize = max(fs_epin_desc.wMaxPacketSize,
- hs_epin_desc.wMaxPacketSize);
- agdev->out_ep_maxpsize = max(fs_epout_desc.wMaxPacketSize,
- hs_epout_desc.wMaxPacketSize);
+ agdev->in_ep_maxpsize = max_t(u16,
+ le16_to_cpu(fs_epin_desc.wMaxPacketSize),
+ le16_to_cpu(hs_epin_desc.wMaxPacketSize));
+ agdev->out_ep_maxpsize = max_t(u16,
+ le16_to_cpu(fs_epout_desc.wMaxPacketSize),
+ le16_to_cpu(hs_epout_desc.wMaxPacketSize));
hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress;
hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress;
diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig
index 9ffb11ec9ed9..7cd5c969fcbe 100644
--- a/drivers/usb/gadget/udc/Kconfig
+++ b/drivers/usb/gadget/udc/Kconfig
@@ -192,7 +192,7 @@ config USB_RENESAS_USBHS_UDC
config USB_RENESAS_USB3
tristate 'Renesas USB3.0 Peripheral controller'
depends on ARCH_RENESAS || COMPILE_TEST
- depends on EXTCON
+ depends on EXTCON && HAS_DMA
help
Renesas USB3.0 Peripheral controller is a USB peripheral controller
that supports super, high, and full speed USB 3.0 data transfers.
@@ -257,6 +257,7 @@ config USB_MV_U3D
config USB_SNP_CORE
depends on (USB_AMD5536UDC || USB_SNP_UDC_PLAT)
+ depends on HAS_DMA
tristate
help
This enables core driver support for Synopsys USB 2.0 Device
@@ -271,7 +272,7 @@ config USB_SNP_CORE
config USB_SNP_UDC_PLAT
tristate "Synopsys USB 2.0 Device controller"
- depends on (USB_GADGET && OF)
+ depends on USB_GADGET && OF && HAS_DMA
select USB_GADGET_DUALSPEED
select USB_SNP_CORE
default ARCH_BCM_IPROC
diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c
index d8278322d5ac..e1de8fe599a3 100644
--- a/drivers/usb/gadget/udc/renesas_usb3.c
+++ b/drivers/usb/gadget/udc/renesas_usb3.c
@@ -89,6 +89,9 @@
/* USB_COM_CON */
#define USB_COM_CON_CONF BIT(24)
+#define USB_COM_CON_PN_WDATAIF_NL BIT(23)
+#define USB_COM_CON_PN_RDATAIF_NL BIT(22)
+#define USB_COM_CON_PN_LSTTR_PP BIT(21)
#define USB_COM_CON_SPD_MODE BIT(17)
#define USB_COM_CON_EP0_EN BIT(16)
#define USB_COM_CON_DEV_ADDR_SHIFT 8
@@ -686,6 +689,9 @@ static void renesas_usb3_init_controller(struct renesas_usb3 *usb3)
{
usb3_init_axi_bridge(usb3);
usb3_init_epc_registers(usb3);
+ usb3_set_bit(usb3, USB_COM_CON_PN_WDATAIF_NL |
+ USB_COM_CON_PN_RDATAIF_NL | USB_COM_CON_PN_LSTTR_PP,
+ USB3_USB_COM_CON);
usb3_write(usb3, USB_OTG_IDMON, USB3_USB_OTG_INT_STA);
usb3_write(usb3, USB_OTG_IDMON, USB3_USB_OTG_INT_ENA);
@@ -832,21 +838,32 @@ static struct renesas_usb3_request *usb3_get_request(struct renesas_usb3_ep
return usb3_req;
}
-static void usb3_request_done(struct renesas_usb3_ep *usb3_ep,
- struct renesas_usb3_request *usb3_req, int status)
+static void __usb3_request_done(struct renesas_usb3_ep *usb3_ep,
+ struct renesas_usb3_request *usb3_req,
+ int status)
{
struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep);
- unsigned long flags;
dev_dbg(usb3_to_dev(usb3), "giveback: ep%2d, %u, %u, %d\n",
usb3_ep->num, usb3_req->req.length, usb3_req->req.actual,
status);
usb3_req->req.status = status;
- spin_lock_irqsave(&usb3->lock, flags);
usb3_ep->started = false;
list_del_init(&usb3_req->queue);
- spin_unlock_irqrestore(&usb3->lock, flags);
+ spin_unlock(&usb3->lock);
usb_gadget_giveback_request(&usb3_ep->ep, &usb3_req->req);
+ spin_lock(&usb3->lock);
+}
+
+static void usb3_request_done(struct renesas_usb3_ep *usb3_ep,
+ struct renesas_usb3_request *usb3_req, int status)
+{
+ struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep);
+ unsigned long flags;
+
+ spin_lock_irqsave(&usb3->lock, flags);
+ __usb3_request_done(usb3_ep, usb3_req, status);
+ spin_unlock_irqrestore(&usb3->lock, flags);
}
static void usb3_irq_epc_pipe0_status_end(struct renesas_usb3 *usb3)
@@ -1369,7 +1386,7 @@ static int renesas_usb3_dma_free_prd(struct renesas_usb3 *usb3,
usb3_for_each_dma(usb3, dma, i) {
if (dma->prd) {
- dma_free_coherent(dev, USB3_DMA_MAX_XFER_SIZE,
+ dma_free_coherent(dev, USB3_DMA_PRD_SIZE,
dma->prd, dma->prd_dma);
dma->prd = NULL;
}
@@ -1409,12 +1426,12 @@ static void usb3_start_pipen(struct renesas_usb3_ep *usb3_ep,
int ret = -EAGAIN;
u32 enable_bits = 0;
+ spin_lock_irqsave(&usb3->lock, flags);
if (usb3_ep->halt || usb3_ep->started)
- return;
+ goto out;
if (usb3_req != usb3_req_first)
- return;
+ goto out;
- spin_lock_irqsave(&usb3->lock, flags);
if (usb3_pn_change(usb3, usb3_ep->num) < 0)
goto out;
diff --git a/drivers/usb/gadget/udc/snps_udc_plat.c b/drivers/usb/gadget/udc/snps_udc_plat.c
index 2e11f19e07ae..f7b4d0f159e4 100644
--- a/drivers/usb/gadget/udc/snps_udc_plat.c
+++ b/drivers/usb/gadget/udc/snps_udc_plat.c
@@ -28,7 +28,7 @@
/* description */
#define UDC_MOD_DESCRIPTION "Synopsys UDC platform driver"
-void start_udc(struct udc *udc)
+static void start_udc(struct udc *udc)
{
if (udc->driver) {
dev_info(udc->dev, "Connecting...\n");
@@ -38,7 +38,7 @@ void start_udc(struct udc *udc)
}
}
-void stop_udc(struct udc *udc)
+static void stop_udc(struct udc *udc)
{
int tmp;
u32 reg;
@@ -76,7 +76,7 @@ void stop_udc(struct udc *udc)
dev_info(udc->dev, "Device disconnected\n");
}
-void udc_drd_work(struct work_struct *work)
+static void udc_drd_work(struct work_struct *work)
{
struct udc *udc;
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index a9a1e4c40480..c8f38649f749 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -77,6 +77,16 @@
#define USB_INTEL_USB3_PSSEN 0xD8
#define USB_INTEL_USB3PRM 0xDC
+/* ASMEDIA quirk use */
+#define ASMT_DATA_WRITE0_REG 0xF8
+#define ASMT_DATA_WRITE1_REG 0xFC
+#define ASMT_CONTROL_REG 0xE0
+#define ASMT_CONTROL_WRITE_BIT 0x02
+#define ASMT_WRITEREG_CMD 0x10423
+#define ASMT_FLOWCTL_ADDR 0xFA30
+#define ASMT_FLOWCTL_DATA 0xBA
+#define ASMT_PSEUDO_DATA 0
+
/*
* amd_chipset_gen values represent AMD different chipset generations
*/
@@ -88,6 +98,7 @@ enum amd_chipset_gen {
AMD_CHIPSET_HUDSON2,
AMD_CHIPSET_BOLTON,
AMD_CHIPSET_YANGTZE,
+ AMD_CHIPSET_TAISHAN,
AMD_CHIPSET_UNKNOWN,
};
@@ -131,6 +142,11 @@ static int amd_chipset_sb_type_init(struct amd_chipset_info *pinfo)
pinfo->sb_type.gen = AMD_CHIPSET_SB700;
else if (rev >= 0x40 && rev <= 0x4f)
pinfo->sb_type.gen = AMD_CHIPSET_SB800;
+ }
+ pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
+ 0x145c, NULL);
+ if (pinfo->smbus_dev) {
+ pinfo->sb_type.gen = AMD_CHIPSET_TAISHAN;
} else {
pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, NULL);
@@ -250,11 +266,12 @@ int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev)
{
/* Make sure amd chipset type has already been initialized */
usb_amd_find_chipset_info();
- if (amd_chipset.sb_type.gen != AMD_CHIPSET_YANGTZE)
- return 0;
-
- dev_dbg(&pdev->dev, "QUIRK: Enable AMD remote wakeup fix\n");
- return 1;
+ if (amd_chipset.sb_type.gen == AMD_CHIPSET_YANGTZE ||
+ amd_chipset.sb_type.gen == AMD_CHIPSET_TAISHAN) {
+ dev_dbg(&pdev->dev, "QUIRK: Enable AMD remote wakeup fix\n");
+ return 1;
+ }
+ return 0;
}
EXPORT_SYMBOL_GPL(usb_hcd_amd_remote_wakeup_quirk);
@@ -412,6 +429,50 @@ void usb_amd_quirk_pll_disable(void)
}
EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_disable);
+static int usb_asmedia_wait_write(struct pci_dev *pdev)
+{
+ unsigned long retry_count;
+ unsigned char value;
+
+ for (retry_count = 1000; retry_count > 0; --retry_count) {
+
+ pci_read_config_byte(pdev, ASMT_CONTROL_REG, &value);
+
+ if (value == 0xff) {
+ dev_err(&pdev->dev, "%s: check_ready ERROR", __func__);
+ return -EIO;
+ }
+
+ if ((value & ASMT_CONTROL_WRITE_BIT) == 0)
+ return 0;
+
+ usleep_range(40, 60);
+ }
+
+ dev_warn(&pdev->dev, "%s: check_write_ready timeout", __func__);
+ return -ETIMEDOUT;
+}
+
+void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev)
+{
+ if (usb_asmedia_wait_write(pdev) != 0)
+ return;
+
+ /* send command and address to device */
+ pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_WRITEREG_CMD);
+ pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_FLOWCTL_ADDR);
+ pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT);
+
+ if (usb_asmedia_wait_write(pdev) != 0)
+ return;
+
+ /* send data to device */
+ pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_FLOWCTL_DATA);
+ pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_PSEUDO_DATA);
+ pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT);
+}
+EXPORT_SYMBOL_GPL(usb_asmedia_modifyflowcontrol);
+
void usb_amd_quirk_pll_enable(void)
{
usb_amd_quirk_pll(0);
@@ -1096,3 +1157,23 @@ static void quirk_usb_early_handoff(struct pci_dev *pdev)
}
DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_SERIAL_USB, 8, quirk_usb_early_handoff);
+
+bool usb_xhci_needs_pci_reset(struct pci_dev *pdev)
+{
+ /*
+ * Our dear uPD72020{1,2} friend only partially resets when
+ * asked to via the XHCI interface, and may end up doing DMA
+ * at the wrong addresses, as it keeps the top 32bit of some
+ * addresses from its previous programming under obscure
+ * circumstances.
+ * Give it a good wack at probe time. Unfortunately, this
+ * needs to happen before we've had a chance to discover any
+ * quirk, or the system will be in a rather bad state.
+ */
+ if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
+ (pdev->device == 0x0014 || pdev->device == 0x0015))
+ return true;
+
+ return false;
+}
+EXPORT_SYMBOL_GPL(usb_xhci_needs_pci_reset);
diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h
index 0222195bd5b0..5582cbafecd4 100644
--- a/drivers/usb/host/pci-quirks.h
+++ b/drivers/usb/host/pci-quirks.h
@@ -11,13 +11,16 @@ bool usb_amd_prefetch_quirk(void);
void usb_amd_dev_put(void);
void usb_amd_quirk_pll_disable(void);
void usb_amd_quirk_pll_enable(void);
+void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev);
void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev);
void usb_disable_xhci_ports(struct pci_dev *xhci_pdev);
void sb800_prefetch(struct device *dev, int on);
+bool usb_xhci_needs_pci_reset(struct pci_dev *pdev);
#else
struct pci_dev;
static inline void usb_amd_quirk_pll_disable(void) {}
static inline void usb_amd_quirk_pll_enable(void) {}
+static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {}
static inline void usb_amd_dev_put(void) {}
static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {}
static inline void sb800_prefetch(struct device *dev, int on) {}
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 1adae9eab831..00721e8807ab 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -398,14 +398,21 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
spin_lock_irqsave(&xhci->lock, flags);
for (i = LAST_EP_INDEX; i > 0; i--) {
if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) {
+ struct xhci_ep_ctx *ep_ctx;
struct xhci_command *command;
+
+ ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->out_ctx, i);
+
+ /* Check ep is running, required by AMD SNPS 3.1 xHC */
+ if (GET_EP_CTX_STATE(ep_ctx) != EP_STATE_RUNNING)
+ continue;
+
command = xhci_alloc_command(xhci, false, false,
GFP_NOWAIT);
if (!command) {
spin_unlock_irqrestore(&xhci->lock, flags);
xhci_free_command(xhci, cmd);
return -ENOMEM;
-
}
xhci_queue_stop_endpoint(xhci, command, slot_id, i,
suspend);
@@ -603,12 +610,14 @@ static int xhci_enter_test_mode(struct xhci_hcd *xhci,
/* Disable all Device Slots */
xhci_dbg(xhci, "Disable all slots\n");
+ spin_unlock_irqrestore(&xhci->lock, *flags);
for (i = 1; i <= HCS_MAX_SLOTS(xhci->hcs_params1); i++) {
retval = xhci_disable_slot(xhci, NULL, i);
if (retval)
xhci_err(xhci, "Failed to disable slot %d, %d. Enter test mode anyway\n",
i, retval);
}
+ spin_lock_irqsave(&xhci->lock, *flags);
/* Put all ports to the Disable state by clear PP */
xhci_dbg(xhci, "Disable all port (PP = 0)\n");
/* Power off USB3 ports*/
@@ -897,6 +906,9 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
clear_bit(wIndex, &bus_state->resuming_ports);
set_bit(wIndex, &bus_state->rexit_ports);
+
+ xhci_test_and_clear_bit(xhci, port_array, wIndex,
+ PORT_PLC);
xhci_set_link_state(xhci, port_array, wIndex,
XDEV_U0);
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 53882e2babbb..8071c8fdd15e 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -59,6 +59,8 @@
#define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb
#define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc
+#define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142
+
static const char hcd_name[] = "xhci_hcd";
static struct hc_driver __read_mostly xhci_pci_hc_driver;
@@ -217,6 +219,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
pdev->device == 0x1142)
xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+ if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
+ pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI)
+ xhci->quirks |= XHCI_ASMEDIA_MODIFY_FLOWCONTROL;
+
if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241)
xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7;
@@ -278,6 +284,13 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
driver = (struct hc_driver *)id->driver_data;
+ /* For some HW implementation, a XHCI reset is just not enough... */
+ if (usb_xhci_needs_pci_reset(dev)) {
+ dev_info(&dev->dev, "Resetting\n");
+ if (pci_reset_function_locked(dev))
+ dev_warn(&dev->dev, "Reset failed");
+ }
+
/* Prevent runtime suspending between USB-2 and USB-3 initialization */
pm_runtime_get_noresume(&dev->dev);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index c50c902d009e..cc368ad2b51e 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -864,13 +864,16 @@ static void xhci_kill_endpoint_urbs(struct xhci_hcd *xhci,
(ep->ep_state & EP_GETTING_NO_STREAMS)) {
int stream_id;
- for (stream_id = 0; stream_id < ep->stream_info->num_streams;
+ for (stream_id = 1; stream_id < ep->stream_info->num_streams;
stream_id++) {
+ ring = ep->stream_info->stream_rings[stream_id];
+ if (!ring)
+ continue;
+
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
"Killing URBs for slot ID %u, ep index %u, stream %u",
- slot_id, ep_index, stream_id + 1);
- xhci_kill_ring_urbs(xhci,
- ep->stream_info->stream_rings[stream_id]);
+ slot_id, ep_index, stream_id);
+ xhci_kill_ring_urbs(xhci, ring);
}
} else {
ring = ep->ring;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 56f85df013db..b2ff1ff1a02f 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -198,6 +198,9 @@ int xhci_reset(struct xhci_hcd *xhci)
if (ret)
return ret;
+ if (xhci->quirks & XHCI_ASMEDIA_MODIFY_FLOWCONTROL)
+ usb_asmedia_modifyflowcontrol(to_pci_dev(xhci_to_hcd(xhci)->self.controller));
+
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
"Wait for controller to be ready for doorbell rings");
/*
@@ -622,8 +625,10 @@ int xhci_run(struct usb_hcd *hcd)
if (!command)
return -ENOMEM;
- xhci_queue_vendor_command(xhci, command, 0, 0, 0,
+ ret = xhci_queue_vendor_command(xhci, command, 0, 0, 0,
TRB_TYPE(TRB_NEC_GET_FW));
+ if (ret)
+ xhci_free_command(xhci, command);
}
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
"Finished xhci_run for USB2 roothub");
@@ -1085,6 +1090,9 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !comp_timer_running)
compliance_mode_recovery_timer_init(xhci);
+ if (xhci->quirks & XHCI_ASMEDIA_MODIFY_FLOWCONTROL)
+ usb_asmedia_modifyflowcontrol(to_pci_dev(hcd->self.controller));
+
/* Re-enable port polling. */
xhci_dbg(xhci, "%s: starting port polling.\n", __func__);
set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 3c6da1f93c84..e3e935291ed6 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1820,6 +1820,7 @@ struct xhci_hcd {
#define XHCI_BROKEN_PORT_PED (1 << 25)
#define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26)
#define XHCI_U2_DISABLE_WAKE (1 << 27)
+#define XHCI_ASMEDIA_MODIFY_FLOWCONTROL (1 << 28)
unsigned int num_active_eps;
unsigned int limit_active_eps;
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 76decb8011eb..3344ffd5bb13 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -139,6 +139,7 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
"Could not flush host TX%d fifo: csr: %04x\n",
ep->epnum, csr))
return;
+ mdelay(1);
}
}
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index 8fb86a5f458e..3d0dd2f97415 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -197,6 +197,7 @@ struct msm_otg {
struct regulator *v3p3;
struct regulator *v1p8;
struct regulator *vddcx;
+ struct regulator_bulk_data supplies[3];
struct reset_control *phy_rst;
struct reset_control *link_rst;
@@ -1731,7 +1732,6 @@ static int msm_otg_reboot_notify(struct notifier_block *this,
static int msm_otg_probe(struct platform_device *pdev)
{
- struct regulator_bulk_data regs[3];
int ret = 0;
struct device_node *np = pdev->dev.of_node;
struct msm_otg_platform_data *pdata;
@@ -1817,17 +1817,18 @@ static int msm_otg_probe(struct platform_device *pdev)
return motg->irq;
}
- regs[0].supply = "vddcx";
- regs[1].supply = "v3p3";
- regs[2].supply = "v1p8";
+ motg->supplies[0].supply = "vddcx";
+ motg->supplies[1].supply = "v3p3";
+ motg->supplies[2].supply = "v1p8";
- ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(regs), regs);
+ ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(motg->supplies),
+ motg->supplies);
if (ret)
return ret;
- motg->vddcx = regs[0].consumer;
- motg->v3p3 = regs[1].consumer;
- motg->v1p8 = regs[2].consumer;
+ motg->vddcx = motg->supplies[0].consumer;
+ motg->v3p3 = motg->supplies[1].consumer;
+ motg->v1p8 = motg->supplies[2].consumer;
clk_set_rate(motg->clk, 60000000);
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c
index 623c51300393..f0ce304c5aaf 100644
--- a/drivers/usb/renesas_usbhs/common.c
+++ b/drivers/usb/renesas_usbhs/common.c
@@ -752,8 +752,10 @@ static int usbhsc_resume(struct device *dev)
struct usbhs_priv *priv = dev_get_drvdata(dev);
struct platform_device *pdev = usbhs_priv_to_pdev(priv);
- if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
+ if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) {
usbhsc_power_ctrl(priv, 1);
+ usbhs_mod_autonomy_mode(priv);
+ }
usbhs_platform_call(priv, phy_reset, pdev);
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index 5bc7a6138855..2c8161bcf5b5 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -37,6 +37,7 @@ struct usbhsg_gpriv;
struct usbhsg_uep {
struct usb_ep ep;
struct usbhs_pipe *pipe;
+ spinlock_t lock; /* protect the pipe */
char ep_name[EP_NAME_SIZE];
@@ -636,10 +637,13 @@ usbhsg_ep_enable_end:
static int usbhsg_ep_disable(struct usb_ep *ep)
{
struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
- struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
+ struct usbhs_pipe *pipe;
+ unsigned long flags;
+ spin_lock_irqsave(&uep->lock, flags);
+ pipe = usbhsg_uep_to_pipe(uep);
if (!pipe)
- return -EINVAL;
+ goto out;
usbhsg_pipe_disable(uep);
usbhs_pipe_free(pipe);
@@ -647,6 +651,9 @@ static int usbhsg_ep_disable(struct usb_ep *ep)
uep->pipe->mod_private = NULL;
uep->pipe = NULL;
+out:
+ spin_unlock_irqrestore(&uep->lock, flags);
+
return 0;
}
@@ -696,8 +703,11 @@ static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
{
struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
struct usbhsg_request *ureq = usbhsg_req_to_ureq(req);
- struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
+ struct usbhs_pipe *pipe;
+ unsigned long flags;
+ spin_lock_irqsave(&uep->lock, flags);
+ pipe = usbhsg_uep_to_pipe(uep);
if (pipe)
usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq));
@@ -706,6 +716,7 @@ static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
* even if the pipe is NULL.
*/
usbhsg_queue_pop(uep, ureq, -ECONNRESET);
+ spin_unlock_irqrestore(&uep->lock, flags);
return 0;
}
@@ -852,10 +863,10 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status)
{
struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
struct usbhs_mod *mod = usbhs_mod_get_current(priv);
- struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv);
+ struct usbhsg_uep *uep;
struct device *dev = usbhs_priv_to_dev(priv);
unsigned long flags;
- int ret = 0;
+ int ret = 0, i;
/******************** spin lock ********************/
usbhs_lock(priv, flags);
@@ -887,7 +898,9 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status)
usbhs_sys_set_test_mode(priv, 0);
usbhs_sys_function_ctrl(priv, 0);
- usbhsg_ep_disable(&dcp->ep);
+ /* disable all eps */
+ usbhsg_for_each_uep_with_dcp(uep, gpriv, i)
+ usbhsg_ep_disable(&uep->ep);
dev_dbg(dev, "stop gadget\n");
@@ -1069,6 +1082,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
ret = -ENOMEM;
goto usbhs_mod_gadget_probe_err_gpriv;
}
+ spin_lock_init(&uep->lock);
gpriv->transceiver = usb_get_phy(USB_PHY_TYPE_UNDEFINED);
dev_info(dev, "%stransceiver found\n",
diff --git a/drivers/usb/renesas_usbhs/rcar3.c b/drivers/usb/renesas_usbhs/rcar3.c
index d544b331c9f2..02b67abfc2a1 100644
--- a/drivers/usb/renesas_usbhs/rcar3.c
+++ b/drivers/usb/renesas_usbhs/rcar3.c
@@ -20,9 +20,13 @@
/* Low Power Status register (LPSTS) */
#define LPSTS_SUSPM 0x4000
-/* USB General control register 2 (UGCTRL2), bit[31:6] should be 0 */
+/*
+ * USB General control register 2 (UGCTRL2)
+ * Remarks: bit[31:11] and bit[9:6] should be 0
+ */
#define UGCTRL2_RESERVED_3 0x00000001 /* bit[3:0] should be B'0001 */
#define UGCTRL2_USB0SEL_OTG 0x00000030
+#define UGCTRL2_VBUSSEL 0x00000400
static void usbhs_write32(struct usbhs_priv *priv, u32 reg, u32 data)
{
@@ -34,7 +38,8 @@ static int usbhs_rcar3_power_ctrl(struct platform_device *pdev,
{
struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
- usbhs_write32(priv, UGCTRL2, UGCTRL2_RESERVED_3 | UGCTRL2_USB0SEL_OTG);
+ usbhs_write32(priv, UGCTRL2, UGCTRL2_RESERVED_3 | UGCTRL2_USB0SEL_OTG |
+ UGCTRL2_VBUSSEL);
if (enable) {
usbhs_bset(priv, LPSTS, LPSTS_SUSPM, LPSTS_SUSPM);
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index f64e914a8985..2d945c9f975c 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -142,6 +142,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */
{ USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */
{ USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */
+ { USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index ebe51f11105d..fe123153b1a5 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -2025,6 +2025,8 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) }, /* D-Link DWM-158 */
{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B1 */
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e35, 0xff), /* D-Link DWM-222 */
+ .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index c9ebefd8f35f..a585b477415d 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -52,6 +52,8 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID),
.driver_info = PL2303_QUIRK_ENDPOINT_HACK },
+ { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_UC485),
+ .driver_info = PL2303_QUIRK_ENDPOINT_HACK },
{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID2) },
{ USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) },
{ USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index 09d9be88209e..3b5a15d1dc0d 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -27,6 +27,7 @@
#define ATEN_VENDOR_ID 0x0557
#define ATEN_VENDOR_ID2 0x0547
#define ATEN_PRODUCT_ID 0x2008
+#define ATEN_PRODUCT_UC485 0x2021
#define ATEN_PRODUCT_ID2 0x2118
#define IODATA_VENDOR_ID 0x04bb
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index fba4005dd737..6a7720e66595 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -1529,8 +1529,11 @@ static void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us)
/* Make sure driver was initialized */
- if (us->extra == NULL)
+ if (us->extra == NULL) {
usb_stor_dbg(us, "ERROR Driver not initialized\n");
+ srb->result = DID_ERROR << 16;
+ return;
+ }
scsi_set_resid(srb, 0);
/* scsi_bufflen might change in protocol translation to ata */
diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h
index cbea9f329e71..cde115359793 100644
--- a/drivers/usb/storage/unusual_uas.h
+++ b/drivers/usb/storage/unusual_uas.h
@@ -124,9 +124,9 @@ UNUSUAL_DEV(0x0bc2, 0xab2a, 0x0000, 0x9999,
/* Reported-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> */
UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999,
"Initio Corporation",
- "",
+ "INIC-3069",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
- US_FL_NO_ATA_1X),
+ US_FL_NO_ATA_1X | US_FL_IGNORE_RESIDUE),
/* Reported-by: Tom Arild Naess <tanaess@gmail.com> */
UNUSUAL_DEV(0x152d, 0x0539, 0x0000, 0x9999,
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 06615934fed1..0dceb9fa3a06 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -315,6 +315,7 @@ static int usb_stor_control_thread(void * __us)
{
struct us_data *us = (struct us_data *)__us;
struct Scsi_Host *host = us_to_host(us);
+ struct scsi_cmnd *srb;
for (;;) {
usb_stor_dbg(us, "*** thread sleeping\n");
@@ -330,6 +331,7 @@ static int usb_stor_control_thread(void * __us)
scsi_lock(host);
/* When we are called with no command pending, we're done */
+ srb = us->srb;
if (us->srb == NULL) {
scsi_unlock(host);
mutex_unlock(&us->dev_mutex);
@@ -398,14 +400,11 @@ static int usb_stor_control_thread(void * __us)
/* lock access to the state */
scsi_lock(host);
- /* indicate that the command is done */
- if (us->srb->result != DID_ABORT << 16) {
- usb_stor_dbg(us, "scsi cmd done, result=0x%x\n",
- us->srb->result);
- us->srb->scsi_done(us->srb);
- } else {
+ /* was the command aborted? */
+ if (us->srb->result == DID_ABORT << 16) {
SkipForAbort:
usb_stor_dbg(us, "scsi command aborted\n");
+ srb = NULL; /* Don't call srb->scsi_done() */
}
/*
@@ -429,6 +428,13 @@ SkipForAbort:
/* unlock the device pointers */
mutex_unlock(&us->dev_mutex);
+
+ /* now that the locks are released, notify the SCSI core */
+ if (srb) {
+ usb_stor_dbg(us, "scsi cmd done, result=0x%x\n",
+ srb->result);
+ srb->scsi_done(srb);
+ }
} /* for (;;) */
/* Wait until we are told to stop */
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index 6b0d2f0918c6..8a88f45822e3 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -3,6 +3,7 @@
#define __DRIVER_USB_TYPEC_UCSI_H
#include <linux/bitops.h>
+#include <linux/device.h>
#include <linux/types.h>
/* -------------------------------------------------------------------------- */
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 063c1ce6fa42..f041b1a6cf66 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -226,7 +226,14 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev)
if (ret)
return ret;
- vdev->reset_works = (pci_reset_function(pdev) == 0);
+ /* If reset fails because of the device lock, fail this path entirely */
+ ret = pci_try_reset_function(pdev);
+ if (ret == -EAGAIN) {
+ pci_disable_device(pdev);
+ return ret;
+ }
+
+ vdev->reset_works = !ret;
pci_save_state(pdev);
vdev->pci_saved_state = pci_store_saved_state(pdev);
if (!vdev->pci_saved_state)
diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c
index 330a57024cbc..5628fe114347 100644
--- a/drivers/vfio/pci/vfio_pci_config.c
+++ b/drivers/vfio/pci/vfio_pci_config.c
@@ -839,7 +839,7 @@ static int vfio_exp_config_write(struct vfio_pci_device *vdev, int pos,
/* Permissions for PCI Express capability */
static int __init init_pci_cap_exp_perm(struct perm_bits *perm)
{
- /* Alloc larger of two possible sizes */
+ /* Alloc largest of possible sizes */
if (alloc_perm_bits(perm, PCI_CAP_EXP_ENDPOINT_SIZEOF_V2))
return -ENOMEM;
@@ -1243,11 +1243,16 @@ static int vfio_cap_len(struct vfio_pci_device *vdev, u8 cap, u8 pos)
vdev->extended_caps = (dword != 0);
}
- /* length based on version */
- if ((pcie_caps_reg(pdev) & PCI_EXP_FLAGS_VERS) == 1)
+ /* length based on version and type */
+ if ((pcie_caps_reg(pdev) & PCI_EXP_FLAGS_VERS) == 1) {
+ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END)
+ return 0xc; /* "All Devices" only, no link */
return PCI_CAP_EXP_ENDPOINT_SIZEOF_V1;
- else
+ } else {
+ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END)
+ return 0x2c; /* No link */
return PCI_CAP_EXP_ENDPOINT_SIZEOF_V2;
+ }
case PCI_CAP_ID_HT:
ret = pci_read_config_byte(pdev, pos + 3, &byte);
if (ret)
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index e4613a3c362d..9cb3f722dce1 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -308,7 +308,6 @@ static void vhost_vq_reset(struct vhost_dev *dev,
vq->avail = NULL;
vq->used = NULL;
vq->last_avail_idx = 0;
- vq->last_used_event = 0;
vq->avail_idx = 0;
vq->last_used_idx = 0;
vq->signalled_used = 0;
@@ -1402,7 +1401,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
r = -EINVAL;
break;
}
- vq->last_avail_idx = vq->last_used_event = s.num;
+ vq->last_avail_idx = s.num;
/* Forget the cached index value. */
vq->avail_idx = vq->last_avail_idx;
break;
@@ -2241,6 +2240,10 @@ static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
__u16 old, new;
__virtio16 event;
bool v;
+ /* Flush out used index updates. This is paired
+ * with the barrier that the Guest executes when enabling
+ * interrupts. */
+ smp_mb();
if (vhost_has_feature(vq, VIRTIO_F_NOTIFY_ON_EMPTY) &&
unlikely(vq->avail_idx == vq->last_avail_idx))
@@ -2248,10 +2251,6 @@ static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
if (!vhost_has_feature(vq, VIRTIO_RING_F_EVENT_IDX)) {
__virtio16 flags;
- /* Flush out used index updates. This is paired
- * with the barrier that the Guest executes when enabling
- * interrupts. */
- smp_mb();
if (vhost_get_avail(vq, flags, &vq->avail->flags)) {
vq_err(vq, "Failed to get flags");
return true;
@@ -2266,26 +2265,11 @@ static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
if (unlikely(!v))
return true;
- /* We're sure if the following conditions are met, there's no
- * need to notify guest:
- * 1) cached used event is ahead of new
- * 2) old to new updating does not cross cached used event. */
- if (vring_need_event(vq->last_used_event, new + vq->num, new) &&
- !vring_need_event(vq->last_used_event, new, old))
- return false;
-
- /* Flush out used index updates. This is paired
- * with the barrier that the Guest executes when enabling
- * interrupts. */
- smp_mb();
-
if (vhost_get_avail(vq, event, vhost_used_event(vq))) {
vq_err(vq, "Failed to get used event idx");
return true;
}
- vq->last_used_event = vhost16_to_cpu(vq, event);
-
- return vring_need_event(vq->last_used_event, new, old);
+ return vring_need_event(vhost16_to_cpu(vq, event), new, old);
}
/* This actually signals the guest, using eventfd. */
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index f72095868b93..bb7c29b8b9fc 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -115,9 +115,6 @@ struct vhost_virtqueue {
/* Last index we used. */
u16 last_used_idx;
- /* Last used evet we've seen */
- u16 last_used_event;
-
/* Used flags */
u16 used_flags;
diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index ff01bed7112f..1e784adb89b1 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -17,6 +17,7 @@
#include <asm/efi.h>
static bool request_mem_succeeded = false;
+static bool nowc = false;
static struct fb_var_screeninfo efifb_defined = {
.activate = FB_ACTIVATE_NOW,
@@ -99,6 +100,8 @@ static int efifb_setup(char *options)
screen_info.lfb_height = simple_strtoul(this_opt+7, NULL, 0);
else if (!strncmp(this_opt, "width:", 6))
screen_info.lfb_width = simple_strtoul(this_opt+6, NULL, 0);
+ else if (!strcmp(this_opt, "nowc"))
+ nowc = true;
}
}
@@ -255,7 +258,10 @@ static int efifb_probe(struct platform_device *dev)
info->apertures->ranges[0].base = efifb_fix.smem_start;
info->apertures->ranges[0].size = size_remap;
- info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);
+ if (nowc)
+ info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
+ else
+ info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);
if (!info->screen_base) {
pr_err("efifb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
efifb_fix.smem_len, efifb_fix.smem_start);
diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c
index c166e0725be5..ba82f97fb42b 100644
--- a/drivers/video/fbdev/imxfb.c
+++ b/drivers/video/fbdev/imxfb.c
@@ -1073,20 +1073,16 @@ static int imxfb_remove(struct platform_device *pdev)
imxfb_disable_controller(fbi);
unregister_framebuffer(info);
-
+ fb_dealloc_cmap(&info->cmap);
pdata = dev_get_platdata(&pdev->dev);
if (pdata && pdata->exit)
pdata->exit(fbi->pdev);
-
- fb_dealloc_cmap(&info->cmap);
- kfree(info->pseudo_palette);
- framebuffer_release(info);
-
dma_free_wc(&pdev->dev, fbi->map_size, info->screen_base,
fbi->map_dma);
-
iounmap(fbi->regs);
release_mem_region(res->start, resource_size(res));
+ kfree(info->pseudo_palette);
+ framebuffer_release(info);
return 0;
}
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/core.c b/drivers/video/fbdev/omap2/omapfb/dss/core.c
index eecf695c16f4..09e5bb013d28 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/core.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/core.c
@@ -193,7 +193,6 @@ static struct notifier_block omap_dss_pm_notif_block = {
static int __init omap_dss_probe(struct platform_device *pdev)
{
- struct omap_dss_board_info *pdata = pdev->dev.platform_data;
int r;
core.pdev = pdev;
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
index 156a254705ea..ec78d61bc551 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
@@ -664,7 +664,7 @@ static int hdmi_audio_register(struct device *dev)
{
struct omap_hdmi_audio_pdata pdata = {
.dev = dev,
- .dss_version = omapdss_get_version(),
+ .version = 4,
.audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
.ops = &hdmi_audio_ops,
};
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
index 4da36bcab977..2e2fcc3d6d4f 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c
@@ -695,7 +695,7 @@ static int hdmi_audio_register(struct device *dev)
{
struct omap_hdmi_audio_pdata pdata = {
.dev = dev,
- .dss_version = omapdss_get_version(),
+ .version = 5,
.audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
.ops = &hdmi_audio_ops,
};
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 22caf808bfab..f0b3a0b9d42f 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -104,12 +104,6 @@ static u32 page_to_balloon_pfn(struct page *page)
return pfn * VIRTIO_BALLOON_PAGES_PER_PAGE;
}
-static struct page *balloon_pfn_to_page(u32 pfn)
-{
- BUG_ON(pfn % VIRTIO_BALLOON_PAGES_PER_PAGE);
- return pfn_to_page(pfn / VIRTIO_BALLOON_PAGES_PER_PAGE);
-}
-
static void balloon_ack(struct virtqueue *vq)
{
struct virtio_balloon *vb = vq->vdev->priv;
@@ -138,8 +132,10 @@ static void set_page_pfns(struct virtio_balloon *vb,
{
unsigned int i;
- /* Set balloon pfns pointing at this page.
- * Note that the first pfn points at start of the page. */
+ /*
+ * Set balloon pfns pointing at this page.
+ * Note that the first pfn points at start of the page.
+ */
for (i = 0; i < VIRTIO_BALLOON_PAGES_PER_PAGE; i++)
pfns[i] = cpu_to_virtio32(vb->vdev,
page_to_balloon_pfn(page) + i);
@@ -182,18 +178,16 @@ static unsigned fill_balloon(struct virtio_balloon *vb, size_t num)
return num_allocated_pages;
}
-static void release_pages_balloon(struct virtio_balloon *vb)
+static void release_pages_balloon(struct virtio_balloon *vb,
+ struct list_head *pages)
{
- unsigned int i;
- struct page *page;
+ struct page *page, *next;
- /* Find pfns pointing at start of each page, get pages and free them. */
- for (i = 0; i < vb->num_pfns; i += VIRTIO_BALLOON_PAGES_PER_PAGE) {
- page = balloon_pfn_to_page(virtio32_to_cpu(vb->vdev,
- vb->pfns[i]));
+ list_for_each_entry_safe(page, next, pages, lru) {
if (!virtio_has_feature(vb->vdev,
VIRTIO_BALLOON_F_DEFLATE_ON_OOM))
adjust_managed_page_count(page, 1);
+ list_del(&page->lru);
put_page(page); /* balloon reference */
}
}
@@ -203,6 +197,7 @@ static unsigned leak_balloon(struct virtio_balloon *vb, size_t num)
unsigned num_freed_pages;
struct page *page;
struct balloon_dev_info *vb_dev_info = &vb->vb_dev_info;
+ LIST_HEAD(pages);
/* We can only do one array worth at a time. */
num = min(num, ARRAY_SIZE(vb->pfns));
@@ -216,6 +211,7 @@ static unsigned leak_balloon(struct virtio_balloon *vb, size_t num)
if (!page)
break;
set_page_pfns(vb, vb->pfns + vb->num_pfns, page);
+ list_add(&page->lru, &pages);
vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE;
}
@@ -227,7 +223,7 @@ static unsigned leak_balloon(struct virtio_balloon *vb, size_t num)
*/
if (vb->num_pfns != 0)
tell_host(vb, vb->deflate_vq);
- release_pages_balloon(vb);
+ release_pages_balloon(vb, &pages);
mutex_unlock(&vb->balloon_lock);
return num_freed_pages;
}
diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c
index 3612542b6044..83fc9aab34e8 100644
--- a/drivers/w1/masters/omap_hdq.c
+++ b/drivers/w1/masters/omap_hdq.c
@@ -704,7 +704,8 @@ static int omap_hdq_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
- ret = -ENXIO;
+ dev_dbg(&pdev->dev, "Failed to get IRQ: %d\n", irq);
+ ret = irq;
goto err_irq;
}
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 95ea7e6b1d99..74471e7aa5cc 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -728,6 +728,7 @@ int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
memcpy(&sl->reg_num, rn, sizeof(sl->reg_num));
atomic_set(&sl->refcnt, 1);
atomic_inc(&sl->master->refcnt);
+ dev->slave_count++;
/* slave modules need to be loaded in a context with unlocked mutex */
mutex_unlock(&dev->mutex);
@@ -747,11 +748,11 @@ int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
sl->family = f;
-
err = __w1_attach_slave_device(sl);
if (err < 0) {
dev_err(&dev->dev, "%s: Attaching %s failed.\n", __func__,
sl->name);
+ dev->slave_count--;
w1_family_put(sl->family);
atomic_dec(&sl->master->refcnt);
kfree(sl);
@@ -759,7 +760,6 @@ int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
}
sl->ttl = dev->slave_ttl;
- dev->slave_count++;
memcpy(msg.id.id, rn, sizeof(msg.id));
msg.type = W1_SLAVE_ADD;
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index 50dcb68d8070..ab609255a0f3 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -780,6 +780,9 @@ static int __init balloon_init(void)
}
#endif
+ /* Init the xen-balloon driver. */
+ xen_balloon_init();
+
return 0;
}
subsys_initcall(balloon_init);
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index b241bfa529ce..2d43118077e4 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -343,14 +343,6 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
info->cpu = cpu;
}
-static void xen_evtchn_mask_all(void)
-{
- unsigned int evtchn;
-
- for (evtchn = 0; evtchn < xen_evtchn_nr_channels(); evtchn++)
- mask_evtchn(evtchn);
-}
-
/**
* notify_remote_via_irq - send event to remote end of event channel via irq
* @irq: irq of event channel to send event to
@@ -582,7 +574,7 @@ static void shutdown_pirq(struct irq_data *data)
static void enable_pirq(struct irq_data *data)
{
- startup_pirq(data);
+ enable_dynirq(data);
}
static void disable_pirq(struct irq_data *data)
@@ -1573,7 +1565,6 @@ void xen_irq_resume(void)
struct irq_info *info;
/* New event-channel space is not 'live' yet. */
- xen_evtchn_mask_all();
xen_evtchn_resume();
/* No IRQ <-> event-channel mappings. */
@@ -1681,6 +1672,7 @@ module_param(fifo_events, bool, 0);
void __init xen_init_IRQ(void)
{
int ret = -EINVAL;
+ unsigned int evtchn;
if (fifo_events)
ret = xen_evtchn_fifo_init();
@@ -1692,7 +1684,8 @@ void __init xen_init_IRQ(void)
BUG_ON(!evtchn_to_irq);
/* No event channels are 'live' right now. */
- xen_evtchn_mask_all();
+ for (evtchn = 0; evtchn < xen_evtchn_nr_channels(); evtchn++)
+ mask_evtchn(evtchn);
pirq_needs_eoi = pirq_needs_eoi_flag;
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index d6786b87e13b..2c6a9114d332 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -42,6 +42,7 @@
#include <linux/delay.h>
#include <linux/hardirq.h>
#include <linux/workqueue.h>
+#include <linux/ratelimit.h>
#include <xen/xen.h>
#include <xen/interface/xen.h>
@@ -1072,8 +1073,14 @@ static int gnttab_expand(unsigned int req_entries)
cur = nr_grant_frames;
extra = ((req_entries + (grefs_per_grant_frame-1)) /
grefs_per_grant_frame);
- if (cur + extra > gnttab_max_grant_frames())
+ if (cur + extra > gnttab_max_grant_frames()) {
+ pr_warn_ratelimited("xen/grant-table: max_grant_frames reached"
+ " cur=%u extra=%u limit=%u"
+ " gnttab_free_count=%u req_entries=%u\n",
+ cur, extra, gnttab_max_grant_frames(),
+ gnttab_free_count, req_entries);
return -ENOSPC;
+ }
rc = gnttab_map(cur, cur + extra - 1);
if (rc == 0)
diff --git a/drivers/xen/xen-balloon.c b/drivers/xen/xen-balloon.c
index e7715cb62eef..e89136ab851e 100644
--- a/drivers/xen/xen-balloon.c
+++ b/drivers/xen/xen-balloon.c
@@ -59,6 +59,8 @@ static void watch_target(struct xenbus_watch *watch,
{
unsigned long long new_target;
int err;
+ static bool watch_fired;
+ static long target_diff;
err = xenbus_scanf(XBT_NIL, "memory", "target", "%llu", &new_target);
if (err != 1) {
@@ -69,7 +71,14 @@ static void watch_target(struct xenbus_watch *watch,
/* The given memory/target value is in KiB, so it needs converting to
* pages. PAGE_SHIFT converts bytes to pages, hence PAGE_SHIFT - 10.
*/
- balloon_set_new_target(new_target >> (PAGE_SHIFT - 10));
+ new_target >>= PAGE_SHIFT - 10;
+ if (watch_fired) {
+ balloon_set_new_target(new_target - target_diff);
+ return;
+ }
+
+ watch_fired = true;
+ target_diff = new_target - balloon_stats.target_pages;
}
static struct xenbus_watch target_watch = {
.node = "memory/target",
@@ -94,22 +103,15 @@ static struct notifier_block xenstore_notifier = {
.notifier_call = balloon_init_watcher,
};
-static int __init balloon_init(void)
+void xen_balloon_init(void)
{
- if (!xen_domain())
- return -ENODEV;
-
- pr_info("Initialising balloon driver\n");
-
register_balloon(&balloon_dev);
register_xen_selfballooning(&balloon_dev);
register_xenstore_notifier(&xenstore_notifier);
-
- return 0;
}
-subsys_initcall(balloon_init);
+EXPORT_SYMBOL_GPL(xen_balloon_init);
#define BALLOON_SHOW(name, format, args...) \
static ssize_t show_##name(struct device *dev, \
diff --git a/drivers/xen/xen-selfballoon.c b/drivers/xen/xen-selfballoon.c
index 66620713242a..a67e955cacd1 100644
--- a/drivers/xen/xen-selfballoon.c
+++ b/drivers/xen/xen-selfballoon.c
@@ -151,8 +151,8 @@ static unsigned long frontswap_inertia_counter;
static void frontswap_selfshrink(void)
{
static unsigned long cur_frontswap_pages;
- static unsigned long last_frontswap_pages;
- static unsigned long tgt_frontswap_pages;
+ unsigned long last_frontswap_pages;
+ unsigned long tgt_frontswap_pages;
last_frontswap_pages = cur_frontswap_pages;
cur_frontswap_pages = frontswap_curr_pages();
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c
index e46080214955..3e59590c7254 100644
--- a/drivers/xen/xenbus/xenbus_xs.c
+++ b/drivers/xen/xenbus/xenbus_xs.c
@@ -857,6 +857,8 @@ static int xenwatch_thread(void *unused)
struct list_head *ent;
struct xs_watch_event *event;
+ xenwatch_pid = current->pid;
+
for (;;) {
wait_event_interruptible(watch_events_waitq,
!list_empty(&watch_events));
@@ -925,7 +927,6 @@ int xs_init(void)
task = kthread_run(xenwatch_thread, NULL, "xenwatch");
if (IS_ERR(task))
return PTR_ERR(task);
- xenwatch_pid = task->pid;
/* shutdown watches for kexec boot */
xs_reset_watches();
diff --git a/drivers/xen/xenfs/super.c b/drivers/xen/xenfs/super.c
index 967f069385d0..71ddfb4cf61c 100644
--- a/drivers/xen/xenfs/super.c
+++ b/drivers/xen/xenfs/super.c
@@ -87,7 +87,6 @@ static int __init xenfs_init(void)
if (xen_domain())
return register_filesystem(&xenfs_type);
- pr_info("not registering filesystem on non-xen platform\n");
return 0;
}
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 69ec23daa25e..a1e6860b6f46 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -574,7 +574,7 @@ static int load_flat_file(struct linux_binprm *bprm,
MAX_SHARED_LIBS * sizeof(unsigned long),
FLAT_DATA_ALIGN);
- pr_debug("Allocated data+bss+stack (%ld bytes): %lx\n",
+ pr_debug("Allocated data+bss+stack (%u bytes): %lx\n",
data_len + bss_len + stack_len, datapos);
fpos = ntohl(hdr->data_start);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 375f8c728d91..e3b0b4196d3d 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4825,10 +4825,6 @@ skip_async:
else
flush = BTRFS_RESERVE_NO_FLUSH;
spin_lock(&space_info->lock);
- if (can_overcommit(fs_info, space_info, orig, flush, false)) {
- spin_unlock(&space_info->lock);
- break;
- }
if (list_empty(&space_info->tickets) &&
list_empty(&space_info->priority_tickets)) {
spin_unlock(&space_info->lock);
@@ -7589,6 +7585,10 @@ search:
u64 offset;
int cached;
+ /* If the block group is read-only, we can skip it entirely. */
+ if (unlikely(block_group->ro))
+ continue;
+
btrfs_grab_block_group(block_group, delalloc);
search_start = block_group->key.objectid;
@@ -7624,8 +7624,6 @@ have_block_group:
if (unlikely(block_group->cached == BTRFS_CACHE_ERROR))
goto loop;
- if (unlikely(block_group->ro))
- goto loop;
/*
* Ok we want to try and use the cluster allocator, so
@@ -7839,6 +7837,7 @@ loop:
failed_alloc = false;
BUG_ON(index != get_block_group_index(block_group));
btrfs_release_block_group(block_group, delalloc);
+ cond_resched();
}
up_read(&space_info->groups_sem);
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index f20ef211a73d..3a11ae63676e 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -2153,8 +2153,7 @@ process_leaf:
u32 this_len = sizeof(*di) + name_len + data_len;
char *name;
- ret = verify_dir_item(fs_info, path->nodes[0],
- path->slots[0], di);
+ ret = verify_dir_item(fs_info, path->nodes[0], i, di);
if (ret) {
ret = -EIO;
goto out;
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 5eb7217738ed..e8b9a269fdde 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2702,7 +2702,7 @@ int btrfs_grow_device(struct btrfs_trans_handle *trans,
mutex_lock(&fs_info->chunk_mutex);
old_total = btrfs_super_total_bytes(super_copy);
- diff = new_size - device->total_bytes;
+ diff = round_down(new_size - device->total_bytes, fs_info->sectorsize);
if (new_size <= device->total_bytes ||
device->is_tgtdev_for_dev_replace) {
@@ -4406,7 +4406,7 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)
u64 diff;
new_size = round_down(new_size, fs_info->sectorsize);
- diff = old_size - new_size;
+ diff = round_down(old_size - new_size, fs_info->sectorsize);
if (device->is_tgtdev_for_dev_replace)
return -EINVAL;
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index e071d23f6148..ef7240ace576 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -271,6 +271,11 @@ out:
if (ret < 0)
err = ret;
dput(last);
+ /* last_name no longer match cache index */
+ if (fi->readdir_cache_idx >= 0) {
+ fi->readdir_cache_idx = -1;
+ fi->dir_release_count = 0;
+ }
}
return err;
}
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
index 79dafa71effd..51f0aea70cb4 100644
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -175,11 +175,8 @@ ext2_get_acl(struct inode *inode, int type)
return acl;
}
-/*
- * inode->i_mutex: down
- */
-int
-ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+static int
+__ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
{
int name_index;
void *value = NULL;
@@ -189,13 +186,6 @@ ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
switch(type) {
case ACL_TYPE_ACCESS:
name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
- if (acl) {
- error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
- if (error)
- return error;
- inode->i_ctime = current_time(inode);
- mark_inode_dirty(inode);
- }
break;
case ACL_TYPE_DEFAULT:
@@ -222,6 +212,31 @@ ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
}
/*
+ * inode->i_mutex: down
+ */
+int
+ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+{
+ int error;
+ int update_mode = 0;
+ umode_t mode = inode->i_mode;
+
+ if (type == ACL_TYPE_ACCESS && acl) {
+ error = posix_acl_update_mode(inode, &mode, &acl);
+ if (error)
+ return error;
+ update_mode = 1;
+ }
+ error = __ext2_set_acl(inode, acl, type);
+ if (!error && update_mode) {
+ inode->i_mode = mode;
+ inode->i_ctime = current_time(inode);
+ mark_inode_dirty(inode);
+ }
+ return error;
+}
+
+/*
* Initialize the ACLs of a new inode. Called from ext2_new_inode.
*
* dir->i_mutex: down
@@ -238,12 +253,12 @@ ext2_init_acl(struct inode *inode, struct inode *dir)
return error;
if (default_acl) {
- error = ext2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
+ error = __ext2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
posix_acl_release(default_acl);
}
if (acl) {
if (!error)
- error = ext2_set_acl(inode, acl, ACL_TYPE_ACCESS);
+ error = __ext2_set_acl(inode, acl, ACL_TYPE_ACCESS);
posix_acl_release(acl);
}
return error;
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
index 09441ae07a5b..46ff2229ff5e 100644
--- a/fs/ext4/acl.c
+++ b/fs/ext4/acl.c
@@ -193,13 +193,6 @@ __ext4_set_acl(handle_t *handle, struct inode *inode, int type,
switch (type) {
case ACL_TYPE_ACCESS:
name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
- if (acl) {
- error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
- if (error)
- return error;
- inode->i_ctime = current_time(inode);
- ext4_mark_inode_dirty(handle, inode);
- }
break;
case ACL_TYPE_DEFAULT:
@@ -221,8 +214,9 @@ __ext4_set_acl(handle_t *handle, struct inode *inode, int type,
value, size, xattr_flags);
kfree(value);
- if (!error)
+ if (!error) {
set_cached_acl(inode, type, acl);
+ }
return error;
}
@@ -233,6 +227,8 @@ ext4_set_acl(struct inode *inode, struct posix_acl *acl, int type)
handle_t *handle;
int error, credits, retries = 0;
size_t acl_size = acl ? ext4_acl_size(acl->a_count) : 0;
+ umode_t mode = inode->i_mode;
+ int update_mode = 0;
error = dquot_initialize(inode);
if (error)
@@ -247,7 +243,20 @@ retry:
if (IS_ERR(handle))
return PTR_ERR(handle);
+ if ((type == ACL_TYPE_ACCESS) && acl) {
+ error = posix_acl_update_mode(inode, &mode, &acl);
+ if (error)
+ goto out_stop;
+ update_mode = 1;
+ }
+
error = __ext4_set_acl(handle, inode, type, acl, 0 /* xattr_flags */);
+ if (!error && update_mode) {
+ inode->i_mode = mode;
+ inode->i_ctime = current_time(inode);
+ ext4_mark_inode_dirty(handle, inode);
+ }
+out_stop:
ext4_journal_stop(handle);
if (error == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
goto retry;
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 9ebde0cd632e..a2bb7d2870e4 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -961,7 +961,7 @@ struct ext4_inode_info {
/*
* i_block_group is the number of the block group which contains
* this file's inode. Constant across the lifetime of the inode,
- * it is ued for making block allocation decisions - we try to
+ * it is used for making block allocation decisions - we try to
* place a file's data blocks near its inode block, and new inodes
* near to their parent directory's inode.
*/
@@ -1049,10 +1049,8 @@ struct ext4_inode_info {
ext4_group_t i_last_alloc_group;
/* allocation reservation info for delalloc */
- /* In case of bigalloc, these refer to clusters rather than blocks */
+ /* In case of bigalloc, this refer to clusters rather than blocks */
unsigned int i_reserved_data_blocks;
- unsigned int i_reserved_meta_blocks;
- unsigned int i_allocated_meta_blocks;
ext4_lblk_t i_da_metadata_calc_last_lblock;
int i_da_metadata_calc_len;
@@ -2022,7 +2020,8 @@ static inline __le16 ext4_rec_len_to_disk(unsigned len, unsigned blocksize)
#define is_dx(dir) (ext4_has_feature_dir_index((dir)->i_sb) && \
ext4_test_inode_flag((dir), EXT4_INODE_INDEX))
-#define EXT4_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT4_LINK_MAX)
+#define EXT4_DIR_LINK_MAX(dir) unlikely((dir)->i_nlink >= EXT4_LINK_MAX && \
+ !(ext4_has_feature_dir_nlink((dir)->i_sb) && is_dx(dir)))
#define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
/* Legal values for the dx_root hash_version field: */
@@ -2462,6 +2461,8 @@ extern void ext4_process_freed_data(struct super_block *sb, tid_t commit_tid);
int ext4_inode_is_fast_symlink(struct inode *inode);
struct buffer_head *ext4_getblk(handle_t *, struct inode *, ext4_lblk_t, int);
struct buffer_head *ext4_bread(handle_t *, struct inode *, ext4_lblk_t, int);
+int ext4_bread_batch(struct inode *inode, ext4_lblk_t block, int bh_count,
+ bool wait, struct buffer_head **bhs);
int ext4_get_block_unwritten(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create);
int ext4_get_block(struct inode *inode, sector_t iblock,
@@ -3074,7 +3075,7 @@ extern int ext4_handle_dirty_dirent_node(handle_t *handle,
struct inode *inode,
struct buffer_head *bh);
#define S_SHIFT 12
-static const unsigned char ext4_type_by_mode[S_IFMT >> S_SHIFT] = {
+static const unsigned char ext4_type_by_mode[(S_IFMT >> S_SHIFT) + 1] = {
[S_IFREG >> S_SHIFT] = EXT4_FT_REG_FILE,
[S_IFDIR >> S_SHIFT] = EXT4_FT_DIR,
[S_IFCHR >> S_SHIFT] = EXT4_FT_CHRDEV,
diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
index dabad1bc8617..48143e32411c 100644
--- a/fs/ext4/ext4_jbd2.h
+++ b/fs/ext4/ext4_jbd2.h
@@ -227,6 +227,9 @@ int ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode);
+int ext4_expand_extra_isize(struct inode *inode,
+ unsigned int new_extra_isize,
+ struct ext4_iloc *iloc);
/*
* Wrapper functions with which ext4 calls into JBD.
*/
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index e0a8425ff74d..97f0fd06728d 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4652,7 +4652,7 @@ retry:
static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
ext4_lblk_t len, loff_t new_size,
- int flags, int mode)
+ int flags)
{
struct inode *inode = file_inode(file);
handle_t *handle;
@@ -4815,7 +4815,7 @@ static long ext4_zero_range(struct file *file, loff_t offset,
round_down(offset, 1 << blkbits) >> blkbits,
(round_up((offset + len), 1 << blkbits) -
round_down(offset, 1 << blkbits)) >> blkbits,
- new_size, flags, mode);
+ new_size, flags);
if (ret)
goto out_dio;
@@ -4841,7 +4841,7 @@ static long ext4_zero_range(struct file *file, loff_t offset,
inode->i_mtime = inode->i_ctime = current_time(inode);
ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size,
- flags, mode);
+ flags);
up_write(&EXT4_I(inode)->i_mmap_sem);
if (ret)
goto out_dio;
@@ -4976,8 +4976,7 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
ext4_inode_block_unlocked_dio(inode);
inode_dio_wait(inode);
- ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size,
- flags, mode);
+ ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, flags);
ext4_inode_resume_unlocked_dio(inode);
if (ret)
goto out;
@@ -5837,7 +5836,7 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1,
if (e1_blk > lblk1)
next1 = e1_blk;
if (e2_blk > lblk2)
- next2 = e1_blk;
+ next2 = e2_blk;
/* Do we have something to swap */
if (next1 == EXT_MAX_BLOCKS || next2 == EXT_MAX_BLOCKS)
goto finish;
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 58294c9a7e1d..0d7cf0cc9b87 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -537,6 +537,8 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
lastoff = page_offset(page);
bh = head = page_buffers(page);
do {
+ if (lastoff + bh->b_size <= startoff)
+ goto next;
if (buffer_uptodate(bh) ||
buffer_unwritten(bh)) {
if (whence == SEEK_DATA)
@@ -551,6 +553,7 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
unlock_page(page);
goto out;
}
+next:
lastoff += bh->b_size;
bh = bh->b_this_page;
} while (bh != head);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 3c600f02673f..c774bdc22759 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -892,7 +892,7 @@ static int ext4_dio_get_block_unwritten_async(struct inode *inode,
/*
* Get block function for non-AIO DIO writes when we create unwritten extent if
* blocks are not allocated yet. The extent will be converted to written
- * after IO is complete from ext4_ext_direct_IO() function.
+ * after IO is complete by ext4_direct_IO_write().
*/
static int ext4_dio_get_block_unwritten_sync(struct inode *inode,
sector_t iblock, struct buffer_head *bh_result, int create)
@@ -907,7 +907,7 @@ static int ext4_dio_get_block_unwritten_sync(struct inode *inode,
/*
* Mark inode as having pending DIO writes to unwritten extents.
- * ext4_ext_direct_IO() checks this flag and converts extents to
+ * ext4_direct_IO_write() checks this flag and converts extents to
* written.
*/
if (!ret && buffer_unwritten(bh_result))
@@ -1015,6 +1015,50 @@ struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode,
return ERR_PTR(-EIO);
}
+/* Read a contiguous batch of blocks. */
+int ext4_bread_batch(struct inode *inode, ext4_lblk_t block, int bh_count,
+ bool wait, struct buffer_head **bhs)
+{
+ int i, err;
+
+ for (i = 0; i < bh_count; i++) {
+ bhs[i] = ext4_getblk(NULL, inode, block + i, 0 /* map_flags */);
+ if (IS_ERR(bhs[i])) {
+ err = PTR_ERR(bhs[i]);
+ bh_count = i;
+ goto out_brelse;
+ }
+ }
+
+ for (i = 0; i < bh_count; i++)
+ /* Note that NULL bhs[i] is valid because of holes. */
+ if (bhs[i] && !buffer_uptodate(bhs[i]))
+ ll_rw_block(REQ_OP_READ, REQ_META | REQ_PRIO, 1,
+ &bhs[i]);
+
+ if (!wait)
+ return 0;
+
+ for (i = 0; i < bh_count; i++)
+ if (bhs[i])
+ wait_on_buffer(bhs[i]);
+
+ for (i = 0; i < bh_count; i++) {
+ if (bhs[i] && !buffer_uptodate(bhs[i])) {
+ err = -EIO;
+ goto out_brelse;
+ }
+ }
+ return 0;
+
+out_brelse:
+ for (i = 0; i < bh_count; i++) {
+ brelse(bhs[i]);
+ bhs[i] = NULL;
+ }
+ return err;
+}
+
int ext4_walk_page_buffers(handle_t *handle,
struct buffer_head *head,
unsigned from,
@@ -5658,22 +5702,16 @@ ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
return err;
}
-/*
- * Expand an inode by new_extra_isize bytes.
- * Returns 0 on success or negative error number on failure.
- */
-static int ext4_expand_extra_isize(struct inode *inode,
- unsigned int new_extra_isize,
- struct ext4_iloc iloc,
- handle_t *handle)
+static int __ext4_expand_extra_isize(struct inode *inode,
+ unsigned int new_extra_isize,
+ struct ext4_iloc *iloc,
+ handle_t *handle, int *no_expand)
{
struct ext4_inode *raw_inode;
struct ext4_xattr_ibody_header *header;
+ int error;
- if (EXT4_I(inode)->i_extra_isize >= new_extra_isize)
- return 0;
-
- raw_inode = ext4_raw_inode(&iloc);
+ raw_inode = ext4_raw_inode(iloc);
header = IHDR(inode, raw_inode);
@@ -5688,8 +5726,98 @@ static int ext4_expand_extra_isize(struct inode *inode,
}
/* try to expand with EAs present */
- return ext4_expand_extra_isize_ea(inode, new_extra_isize,
- raw_inode, handle);
+ error = ext4_expand_extra_isize_ea(inode, new_extra_isize,
+ raw_inode, handle);
+ if (error) {
+ /*
+ * Inode size expansion failed; don't try again
+ */
+ *no_expand = 1;
+ }
+
+ return error;
+}
+
+/*
+ * Expand an inode by new_extra_isize bytes.
+ * Returns 0 on success or negative error number on failure.
+ */
+static int ext4_try_to_expand_extra_isize(struct inode *inode,
+ unsigned int new_extra_isize,
+ struct ext4_iloc iloc,
+ handle_t *handle)
+{
+ int no_expand;
+ int error;
+
+ if (ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND))
+ return -EOVERFLOW;
+
+ /*
+ * In nojournal mode, we can immediately attempt to expand
+ * the inode. When journaled, we first need to obtain extra
+ * buffer credits since we may write into the EA block
+ * with this same handle. If journal_extend fails, then it will
+ * only result in a minor loss of functionality for that inode.
+ * If this is felt to be critical, then e2fsck should be run to
+ * force a large enough s_min_extra_isize.
+ */
+ if (ext4_handle_valid(handle) &&
+ jbd2_journal_extend(handle,
+ EXT4_DATA_TRANS_BLOCKS(inode->i_sb)) != 0)
+ return -ENOSPC;
+
+ if (ext4_write_trylock_xattr(inode, &no_expand) == 0)
+ return -EBUSY;
+
+ error = __ext4_expand_extra_isize(inode, new_extra_isize, &iloc,
+ handle, &no_expand);
+ ext4_write_unlock_xattr(inode, &no_expand);
+
+ return error;
+}
+
+int ext4_expand_extra_isize(struct inode *inode,
+ unsigned int new_extra_isize,
+ struct ext4_iloc *iloc)
+{
+ handle_t *handle;
+ int no_expand;
+ int error, rc;
+
+ if (ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) {
+ brelse(iloc->bh);
+ return -EOVERFLOW;
+ }
+
+ handle = ext4_journal_start(inode, EXT4_HT_INODE,
+ EXT4_DATA_TRANS_BLOCKS(inode->i_sb));
+ if (IS_ERR(handle)) {
+ error = PTR_ERR(handle);
+ brelse(iloc->bh);
+ return error;
+ }
+
+ ext4_write_lock_xattr(inode, &no_expand);
+
+ BUFFER_TRACE(iloc.bh, "get_write_access");
+ error = ext4_journal_get_write_access(handle, iloc->bh);
+ if (error) {
+ brelse(iloc->bh);
+ goto out_stop;
+ }
+
+ error = __ext4_expand_extra_isize(inode, new_extra_isize, iloc,
+ handle, &no_expand);
+
+ rc = ext4_mark_iloc_dirty(handle, inode, iloc);
+ if (!error)
+ error = rc;
+
+ ext4_write_unlock_xattr(inode, &no_expand);
+out_stop:
+ ext4_journal_stop(handle);
+ return error;
}
/*
@@ -5709,44 +5837,18 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
{
struct ext4_iloc iloc;
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
- static unsigned int mnt_count;
- int err, ret;
+ int err;
might_sleep();
trace_ext4_mark_inode_dirty(inode, _RET_IP_);
err = ext4_reserve_inode_write(handle, inode, &iloc);
if (err)
return err;
- if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize &&
- !ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) {
- /*
- * In nojournal mode, we can immediately attempt to expand
- * the inode. When journaled, we first need to obtain extra
- * buffer credits since we may write into the EA block
- * with this same handle. If journal_extend fails, then it will
- * only result in a minor loss of functionality for that inode.
- * If this is felt to be critical, then e2fsck should be run to
- * force a large enough s_min_extra_isize.
- */
- if (!ext4_handle_valid(handle) ||
- jbd2_journal_extend(handle,
- EXT4_DATA_TRANS_BLOCKS(inode->i_sb)) == 0) {
- ret = ext4_expand_extra_isize(inode,
- sbi->s_want_extra_isize,
- iloc, handle);
- if (ret) {
- if (mnt_count !=
- le16_to_cpu(sbi->s_es->s_mnt_count)) {
- ext4_warning(inode->i_sb,
- "Unable to expand inode %lu. Delete"
- " some EAs or run e2fsck.",
- inode->i_ino);
- mnt_count =
- le16_to_cpu(sbi->s_es->s_mnt_count);
- }
- }
- }
- }
+
+ if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize)
+ ext4_try_to_expand_extra_isize(inode, sbi->s_want_extra_isize,
+ iloc, handle);
+
return ext4_mark_iloc_dirty(handle, inode, &iloc);
}
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 42b3a73143cf..afb66d4ab5cf 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -64,18 +64,16 @@ static void swap_inode_data(struct inode *inode1, struct inode *inode2)
ei1 = EXT4_I(inode1);
ei2 = EXT4_I(inode2);
- memswap(&inode1->i_flags, &inode2->i_flags, sizeof(inode1->i_flags));
- memswap(&inode1->i_version, &inode2->i_version,
- sizeof(inode1->i_version));
- memswap(&inode1->i_blocks, &inode2->i_blocks,
- sizeof(inode1->i_blocks));
- memswap(&inode1->i_bytes, &inode2->i_bytes, sizeof(inode1->i_bytes));
- memswap(&inode1->i_atime, &inode2->i_atime, sizeof(inode1->i_atime));
- memswap(&inode1->i_mtime, &inode2->i_mtime, sizeof(inode1->i_mtime));
+ swap(inode1->i_flags, inode2->i_flags);
+ swap(inode1->i_version, inode2->i_version);
+ swap(inode1->i_blocks, inode2->i_blocks);
+ swap(inode1->i_bytes, inode2->i_bytes);
+ swap(inode1->i_atime, inode2->i_atime);
+ swap(inode1->i_mtime, inode2->i_mtime);
memswap(ei1->i_data, ei2->i_data, sizeof(ei1->i_data));
- memswap(&ei1->i_flags, &ei2->i_flags, sizeof(ei1->i_flags));
- memswap(&ei1->i_disksize, &ei2->i_disksize, sizeof(ei1->i_disksize));
+ swap(ei1->i_flags, ei2->i_flags);
+ swap(ei1->i_disksize, ei2->i_disksize);
ext4_es_remove_extent(inode1, 0, EXT_MAX_BLOCKS);
ext4_es_remove_extent(inode2, 0, EXT_MAX_BLOCKS);
@@ -351,11 +349,14 @@ static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
raw_inode = ext4_raw_inode(&iloc);
if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) {
- err = -EOVERFLOW;
+ err = ext4_expand_extra_isize(inode,
+ EXT4_SB(sb)->s_want_extra_isize,
+ &iloc);
+ if (err)
+ goto out_unlock;
+ } else {
brelse(iloc.bh);
- goto out_unlock;
}
- brelse(iloc.bh);
dquot_initialize(inode);
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 581e357e8406..5a1052627a81 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2295,9 +2295,12 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v)
int err, buddy_loaded = 0;
struct ext4_buddy e4b;
struct ext4_group_info *grinfo;
+ unsigned char blocksize_bits = min_t(unsigned char,
+ sb->s_blocksize_bits,
+ EXT4_MAX_BLOCK_LOG_SIZE);
struct sg {
struct ext4_group_info info;
- ext4_grpblk_t counters[EXT4_MAX_BLOCK_LOG_SIZE + 2];
+ ext4_grpblk_t counters[blocksize_bits + 2];
} sg;
group--;
@@ -2306,8 +2309,6 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v)
" 2^0 2^1 2^2 2^3 2^4 2^5 2^6 "
" 2^7 2^8 2^9 2^10 2^11 2^12 2^13 ]\n");
- i = (sb->s_blocksize_bits + 2) * sizeof(sg.info.bb_counters[0]) +
- sizeof(struct ext4_group_info);
grinfo = ext4_get_group_info(sb, group);
/* Load the group info in memory only if not already loaded. */
if (unlikely(EXT4_MB_GRP_NEED_INIT(grinfo))) {
@@ -2319,7 +2320,7 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v)
buddy_loaded = 1;
}
- memcpy(&sg, ext4_get_group_info(sb, group), i);
+ memcpy(&sg, ext4_get_group_info(sb, group), sizeof(sg));
if (buddy_loaded)
ext4_mb_unload_buddy(&e4b);
@@ -2327,7 +2328,7 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v)
seq_printf(seq, "#%-5u: %-5u %-5u %-5u [", group, sg.info.bb_free,
sg.info.bb_fragments, sg.info.bb_first_free);
for (i = 0; i <= 13; i++)
- seq_printf(seq, " %-5u", i <= sb->s_blocksize_bits + 1 ?
+ seq_printf(seq, " %-5u", i <= blocksize_bits + 1 ?
sg.info.bb_counters[i] : 0);
seq_printf(seq, " ]\n");
@@ -2892,8 +2893,10 @@ void ext4_process_freed_data(struct super_block *sb, tid_t commit_tid)
break;
}
- if (discard_bio)
+ if (discard_bio) {
submit_bio_wait(discard_bio);
+ bio_put(discard_bio);
+ }
}
list_for_each_entry_safe(entry, tmp, &freed_data_list, efd_list)
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 13f0cadb1238..c1cf020d1889 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1342,13 +1342,12 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
struct super_block *sb;
struct buffer_head *bh_use[NAMEI_RA_SIZE];
struct buffer_head *bh, *ret = NULL;
- ext4_lblk_t start, block, b;
+ ext4_lblk_t start, block;
const u8 *name = d_name->name;
- int ra_max = 0; /* Number of bh's in the readahead
+ size_t ra_max = 0; /* Number of bh's in the readahead
buffer, bh_use[] */
- int ra_ptr = 0; /* Current index into readahead
+ size_t ra_ptr = 0; /* Current index into readahead
buffer */
- int num = 0;
ext4_lblk_t nblocks;
int i, namelen, retval;
struct ext4_filename fname;
@@ -1411,31 +1410,17 @@ restart:
if (ra_ptr >= ra_max) {
/* Refill the readahead buffer */
ra_ptr = 0;
- b = block;
- for (ra_max = 0; ra_max < NAMEI_RA_SIZE; ra_max++) {
- /*
- * Terminate if we reach the end of the
- * directory and must wrap, or if our
- * search has finished at this block.
- */
- if (b >= nblocks || (num && block == start)) {
- bh_use[ra_max] = NULL;
- break;
- }
- num++;
- bh = ext4_getblk(NULL, dir, b++, 0);
- if (IS_ERR(bh)) {
- if (ra_max == 0) {
- ret = bh;
- goto cleanup_and_exit;
- }
- break;
- }
- bh_use[ra_max] = bh;
- if (bh)
- ll_rw_block(REQ_OP_READ,
- REQ_META | REQ_PRIO,
- 1, &bh);
+ if (block < start)
+ ra_max = start - block;
+ else
+ ra_max = nblocks - block;
+ ra_max = min(ra_max, ARRAY_SIZE(bh_use));
+ retval = ext4_bread_batch(dir, block, ra_max,
+ false /* wait */, bh_use);
+ if (retval) {
+ ret = ERR_PTR(retval);
+ ra_max = 0;
+ goto cleanup_and_exit;
}
}
if ((bh = bh_use[ra_ptr++]) == NULL)
@@ -2395,19 +2380,22 @@ out:
}
/*
- * DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
- * since this indicates that nlinks count was previously 1.
+ * Set directory link count to 1 if nlinks > EXT4_LINK_MAX, or if nlinks == 2
+ * since this indicates that nlinks count was previously 1 to avoid overflowing
+ * the 16-bit i_links_count field on disk. Directories with i_nlink == 1 mean
+ * that subdirectory link counts are not being maintained accurately.
+ *
+ * The caller has already checked for i_nlink overflow in case the DIR_LINK
+ * feature is not enabled and returned -EMLINK. The is_dx() check is a proxy
+ * for checking S_ISDIR(inode) (since the INODE_INDEX feature will not be set
+ * on regular files) and to avoid creating huge/slow non-HTREE directories.
*/
static void ext4_inc_count(handle_t *handle, struct inode *inode)
{
inc_nlink(inode);
- if (is_dx(inode) && inode->i_nlink > 1) {
- /* limit is 16-bit i_links_count */
- if (inode->i_nlink >= EXT4_LINK_MAX || inode->i_nlink == 2) {
- set_nlink(inode, 1);
- ext4_set_feature_dir_nlink(inode->i_sb);
- }
- }
+ if (is_dx(inode) &&
+ (inode->i_nlink > EXT4_LINK_MAX || inode->i_nlink == 2))
+ set_nlink(inode, 1);
}
/*
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index c3ed9021b781..035cd3f4785e 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1927,7 +1927,8 @@ retry:
n_desc_blocks = o_desc_blocks +
le16_to_cpu(es->s_reserved_gdt_blocks);
n_group = n_desc_blocks * EXT4_DESC_PER_BLOCK(sb);
- n_blocks_count = n_group * EXT4_BLOCKS_PER_GROUP(sb);
+ n_blocks_count = (ext4_fsblk_t)n_group *
+ EXT4_BLOCKS_PER_GROUP(sb);
n_group--; /* set to last group number */
}
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 0886fe82e9c4..d61a70e2193a 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -978,8 +978,6 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
ei->i_es_shk_nr = 0;
ei->i_es_shrink_lblk = 0;
ei->i_reserved_data_blocks = 0;
- ei->i_reserved_meta_blocks = 0;
- ei->i_allocated_meta_blocks = 0;
ei->i_da_metadata_calc_len = 0;
ei->i_da_metadata_calc_last_lblock = 0;
spin_lock_init(&(ei->i_block_reservation_lock));
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index cff4f41ced61..82a5af9f6668 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -317,28 +317,41 @@ static void ext4_xattr_inode_set_hash(struct inode *ea_inode, u32 hash)
*/
static int ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t size)
{
- unsigned long block = 0;
- struct buffer_head *bh;
- int blocksize = ea_inode->i_sb->s_blocksize;
- size_t csize, copied = 0;
- void *copy_pos = buf;
-
- while (copied < size) {
- csize = (size - copied) > blocksize ? blocksize : size - copied;
- bh = ext4_bread(NULL, ea_inode, block, 0);
- if (IS_ERR(bh))
- return PTR_ERR(bh);
- if (!bh)
- return -EFSCORRUPTED;
+ int blocksize = 1 << ea_inode->i_blkbits;
+ int bh_count = (size + blocksize - 1) >> ea_inode->i_blkbits;
+ int tail_size = (size % blocksize) ?: blocksize;
+ struct buffer_head *bhs_inline[8];
+ struct buffer_head **bhs = bhs_inline;
+ int i, ret;
+
+ if (bh_count > ARRAY_SIZE(bhs_inline)) {
+ bhs = kmalloc_array(bh_count, sizeof(*bhs), GFP_NOFS);
+ if (!bhs)
+ return -ENOMEM;
+ }
- memcpy(copy_pos, bh->b_data, csize);
- brelse(bh);
+ ret = ext4_bread_batch(ea_inode, 0 /* block */, bh_count,
+ true /* wait */, bhs);
+ if (ret)
+ goto free_bhs;
- copy_pos += csize;
- block += 1;
- copied += csize;
+ for (i = 0; i < bh_count; i++) {
+ /* There shouldn't be any holes in ea_inode. */
+ if (!bhs[i]) {
+ ret = -EFSCORRUPTED;
+ goto put_bhs;
+ }
+ memcpy((char *)buf + blocksize * i, bhs[i]->b_data,
+ i < bh_count - 1 ? blocksize : tail_size);
}
- return 0;
+ ret = 0;
+put_bhs:
+ for (i = 0; i < bh_count; i++)
+ brelse(bhs[i]);
+free_bhs:
+ if (bhs != bhs_inline)
+ kfree(bhs);
+ return ret;
}
static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino,
@@ -451,6 +464,7 @@ ext4_xattr_inode_get(struct inode *inode, struct ext4_xattr_entry *entry,
}
/* Do not add ea_inode to the cache. */
ea_inode_cache = NULL;
+ err = 0;
} else if (err)
goto out;
@@ -1815,9 +1829,6 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
ea_bdebug(bs->bh, "modifying in-place");
error = ext4_xattr_set_entry(i, s, handle, inode,
true /* is_block */);
- if (!error)
- ext4_xattr_block_cache_insert(ea_block_cache,
- bs->bh);
ext4_xattr_block_csum_set(inode, bs->bh);
unlock_buffer(bs->bh);
if (error == -EFSCORRUPTED)
@@ -1973,6 +1984,7 @@ inserted:
} else if (bs->bh && s->base == bs->bh->b_data) {
/* We were modifying this block in-place. */
ea_bdebug(bs->bh, "keeping this block");
+ ext4_xattr_block_cache_insert(ea_block_cache, bs->bh);
new_bh = bs->bh;
get_bh(new_bh);
} else {
@@ -2625,23 +2637,21 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
struct ext4_inode *raw_inode, handle_t *handle)
{
struct ext4_xattr_ibody_header *header;
- struct buffer_head *bh = NULL;
+ struct buffer_head *bh;
+ struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+ static unsigned int mnt_count;
size_t min_offs;
size_t ifree, bfree;
int total_ino;
void *base, *end;
int error = 0, tried_min_extra_isize = 0;
- int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize);
+ int s_min_extra_isize = le16_to_cpu(sbi->s_es->s_min_extra_isize);
int isize_diff; /* How much do we need to grow i_extra_isize */
- int no_expand;
-
- if (ext4_write_trylock_xattr(inode, &no_expand) == 0)
- return 0;
retry:
isize_diff = new_extra_isize - EXT4_I(inode)->i_extra_isize;
if (EXT4_I(inode)->i_extra_isize >= new_extra_isize)
- goto out;
+ return 0;
header = IHDR(inode, raw_inode);
@@ -2676,6 +2686,7 @@ retry:
EXT4_ERROR_INODE(inode, "bad block %llu",
EXT4_I(inode)->i_file_acl);
error = -EFSCORRUPTED;
+ brelse(bh);
goto cleanup;
}
base = BHDR(bh);
@@ -2683,11 +2694,11 @@ retry:
min_offs = end - base;
bfree = ext4_xattr_free_space(BFIRST(bh), &min_offs, base,
NULL);
+ brelse(bh);
if (bfree + ifree < isize_diff) {
if (!tried_min_extra_isize && s_min_extra_isize) {
tried_min_extra_isize++;
new_extra_isize = s_min_extra_isize;
- brelse(bh);
goto retry;
}
error = -ENOSPC;
@@ -2705,7 +2716,6 @@ retry:
s_min_extra_isize) {
tried_min_extra_isize++;
new_extra_isize = s_min_extra_isize;
- brelse(bh);
goto retry;
}
goto cleanup;
@@ -2717,18 +2727,13 @@ shift:
EXT4_GOOD_OLD_INODE_SIZE + new_extra_isize,
(void *)header, total_ino);
EXT4_I(inode)->i_extra_isize = new_extra_isize;
- brelse(bh);
-out:
- ext4_write_unlock_xattr(inode, &no_expand);
- return 0;
cleanup:
- brelse(bh);
- /*
- * Inode size expansion failed; don't try again
- */
- no_expand = 1;
- ext4_write_unlock_xattr(inode, &no_expand);
+ if (error && (mnt_count != le16_to_cpu(sbi->s_es->s_mnt_count))) {
+ ext4_warning(inode->i_sb, "Unable to expand inode %lu. Delete some EAs or run e2fsck.",
+ inode->i_ino);
+ mnt_count = le16_to_cpu(sbi->s_es->s_mnt_count);
+ }
return error;
}
diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c
index a140c5e3dc54..b4b8438c42ef 100644
--- a/fs/f2fs/acl.c
+++ b/fs/f2fs/acl.c
@@ -211,7 +211,7 @@ static int __f2fs_set_acl(struct inode *inode, int type,
switch (type) {
case ACL_TYPE_ACCESS:
name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
- if (acl) {
+ if (acl && !ipage) {
error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
if (error)
return error;
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 56bbf592e487..5b876f6d3f6b 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -879,6 +879,7 @@ int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
struct inode *inode;
struct f2fs_inode_info *fi;
bool is_dir = (type == DIR_INODE);
+ unsigned long ino = 0;
trace_f2fs_sync_dirty_inodes_enter(sbi->sb, is_dir,
get_pages(sbi, is_dir ?
@@ -901,8 +902,17 @@ retry:
inode = igrab(&fi->vfs_inode);
spin_unlock(&sbi->inode_lock[type]);
if (inode) {
+ unsigned long cur_ino = inode->i_ino;
+
filemap_fdatawrite(inode->i_mapping);
iput(inode);
+ /* We need to give cpu to another writers. */
+ if (ino == cur_ino) {
+ congestion_wait(BLK_RW_ASYNC, HZ/50);
+ cond_resched();
+ } else {
+ ino = cur_ino;
+ }
} else {
/*
* We should submit bio, since it exists several
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index a0e6d2c65a9e..2706130c261b 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -1538,7 +1538,6 @@ static int f2fs_ioc_setflags(struct file *filp, unsigned long arg)
/* Is it quota file? Do not allow user to mess with it */
if (IS_NOQUOTA(inode)) {
- inode_unlock(inode);
ret = -EPERM;
goto unlock_out;
}
@@ -1549,9 +1548,8 @@ static int f2fs_ioc_setflags(struct file *filp, unsigned long arg)
if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) {
if (!capable(CAP_LINUX_IMMUTABLE)) {
- inode_unlock(inode);
ret = -EPERM;
- goto out;
+ goto unlock_out;
}
}
@@ -1564,7 +1562,6 @@ static int f2fs_ioc_setflags(struct file *filp, unsigned long arg)
f2fs_mark_inode_dirty_sync(inode, false);
unlock_out:
inode_unlock(inode);
-out:
mnt_drop_write_file(filp);
return ret;
}
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 9adc202fcd6f..71191d89917d 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -11,6 +11,7 @@
*/
#include <linux/proc_fs.h>
#include <linux/f2fs_fs.h>
+#include <linux/seq_file.h>
#include "f2fs.h"
#include "segment.h"
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 3ee4fdc3da9e..ab60051be6e5 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -46,7 +46,7 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc)
{
struct fuse_file *ff;
- ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
+ ff = kzalloc(sizeof(struct fuse_file), GFP_KERNEL);
if (unlikely(!ff))
return NULL;
@@ -609,7 +609,7 @@ static void fuse_aio_complete_req(struct fuse_conn *fc, struct fuse_req *req)
struct fuse_io_priv *io = req->io;
ssize_t pos = -1;
- fuse_release_user_pages(req, !io->write);
+ fuse_release_user_pages(req, io->should_dirty);
if (io->write) {
if (req->misc.write.in.size != req->misc.write.out.size)
@@ -1316,7 +1316,6 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
loff_t *ppos, int flags)
{
int write = flags & FUSE_DIO_WRITE;
- bool should_dirty = !write && iter_is_iovec(iter);
int cuse = flags & FUSE_DIO_CUSE;
struct file *file = io->file;
struct inode *inode = file->f_mapping->host;
@@ -1346,6 +1345,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
inode_unlock(inode);
}
+ io->should_dirty = !write && iter_is_iovec(iter);
while (count) {
size_t nres;
fl_owner_t owner = current->files;
@@ -1360,7 +1360,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
nres = fuse_send_read(req, io, pos, nbytes, owner);
if (!io->async)
- fuse_release_user_pages(req, should_dirty);
+ fuse_release_user_pages(req, io->should_dirty);
if (req->out.h.error) {
err = req->out.h.error;
break;
@@ -1669,6 +1669,7 @@ err_nofile:
err_free:
fuse_request_free(req);
err:
+ mapping_set_error(page->mapping, error);
end_page_writeback(page);
return error;
}
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 1bd7ffdad593..bd4d2a3e1ec1 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -249,6 +249,7 @@ struct fuse_io_priv {
size_t size;
__u64 offset;
bool write;
+ bool should_dirty;
int err;
struct kiocb *iocb;
struct file *file;
diff --git a/fs/hfsplus/posix_acl.c b/fs/hfsplus/posix_acl.c
index 9b92058a1240..6bb5d7c42888 100644
--- a/fs/hfsplus/posix_acl.c
+++ b/fs/hfsplus/posix_acl.c
@@ -51,8 +51,8 @@ struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type)
return acl;
}
-int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl,
- int type)
+static int __hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl,
+ int type)
{
int err;
char *xattr_name;
@@ -64,12 +64,6 @@ int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl,
switch (type) {
case ACL_TYPE_ACCESS:
xattr_name = XATTR_NAME_POSIX_ACL_ACCESS;
- if (acl) {
- err = posix_acl_update_mode(inode, &inode->i_mode, &acl);
- if (err)
- return err;
- }
- err = 0;
break;
case ACL_TYPE_DEFAULT:
@@ -105,6 +99,18 @@ end_set_acl:
return err;
}
+int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl, int type)
+{
+ int err;
+
+ if (type == ACL_TYPE_ACCESS && acl) {
+ err = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (err)
+ return err;
+ }
+ return __hfsplus_set_posix_acl(inode, acl, type);
+}
+
int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir)
{
int err = 0;
@@ -122,15 +128,15 @@ int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir)
return err;
if (default_acl) {
- err = hfsplus_set_posix_acl(inode, default_acl,
- ACL_TYPE_DEFAULT);
+ err = __hfsplus_set_posix_acl(inode, default_acl,
+ ACL_TYPE_DEFAULT);
posix_acl_release(default_acl);
}
if (acl) {
if (!err)
- err = hfsplus_set_posix_acl(inode, acl,
- ACL_TYPE_ACCESS);
+ err = __hfsplus_set_posix_acl(inode, acl,
+ ACL_TYPE_ACCESS);
posix_acl_release(acl);
}
return err;
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 8cf898a59730..217a5e7815da 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -410,7 +410,11 @@ static int parse_options(char *options, struct iso9660_options *popt)
if (match_int(&args[0], &option))
return 0;
n = option;
- if (n > 99)
+ /*
+ * Track numbers are supposed to be in range 1-99, the
+ * mount option starts indexing at 0.
+ */
+ if (n >= 99)
return 0;
popt->session = n + 1;
break;
@@ -543,7 +547,7 @@ static unsigned int isofs_get_last_session(struct super_block *sb, s32 session)
vol_desc_start=0;
ms_info.addr_format=CDROM_LBA;
- if(session >= 0 && session <= 99) {
+ if (session > 0) {
struct cdrom_tocentry Te;
Te.cdte_track=session;
Te.cdte_format=CDROM_LBA;
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c
index 7bc186f4ed4d..2e71b6e7e646 100644
--- a/fs/jfs/acl.c
+++ b/fs/jfs/acl.c
@@ -77,13 +77,6 @@ static int __jfs_set_acl(tid_t tid, struct inode *inode, int type,
switch (type) {
case ACL_TYPE_ACCESS:
ea_name = XATTR_NAME_POSIX_ACL_ACCESS;
- if (acl) {
- rc = posix_acl_update_mode(inode, &inode->i_mode, &acl);
- if (rc)
- return rc;
- inode->i_ctime = current_time(inode);
- mark_inode_dirty(inode);
- }
break;
case ACL_TYPE_DEFAULT:
ea_name = XATTR_NAME_POSIX_ACL_DEFAULT;
@@ -115,12 +108,27 @@ int jfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
{
int rc;
tid_t tid;
+ int update_mode = 0;
+ umode_t mode = inode->i_mode;
tid = txBegin(inode->i_sb, 0);
mutex_lock(&JFS_IP(inode)->commit_mutex);
+ if (type == ACL_TYPE_ACCESS && acl) {
+ rc = posix_acl_update_mode(inode, &mode, &acl);
+ if (rc)
+ goto end_tx;
+ update_mode = 1;
+ }
rc = __jfs_set_acl(tid, inode, type, acl);
- if (!rc)
+ if (!rc) {
+ if (update_mode) {
+ inode->i_mode = mode;
+ inode->i_ctime = current_time(inode);
+ mark_inode_dirty(inode);
+ }
rc = txCommit(tid, 1, &inode, 0);
+ }
+end_tx:
txEnd(tid);
mutex_unlock(&JFS_IP(inode)->commit_mutex);
return rc;
diff --git a/fs/jfs/resize.c b/fs/jfs/resize.c
index bd9b641ada2c..7ddcb445a3d9 100644
--- a/fs/jfs/resize.c
+++ b/fs/jfs/resize.c
@@ -98,7 +98,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
goto out;
}
- VolumeSize = sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits;
+ VolumeSize = i_size_read(sb->s_bdev->bd_inode) >> sb->s_blocksize_bits;
if (VolumeSize) {
if (newLVSize > VolumeSize) {
@@ -211,7 +211,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
txQuiesce(sb);
/* Reset size of direct inode */
- sbi->direct_inode->i_size = sb->s_bdev->bd_inode->i_size;
+ sbi->direct_inode->i_size = i_size_read(sb->s_bdev->bd_inode);
if (sbi->mntflag & JFS_INLINELOG) {
/*
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index e8aad7d87b8c..78b41e1d5c67 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -313,7 +313,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
}
case Opt_resize_nosize:
{
- *newLVSize = sb->s_bdev->bd_inode->i_size >>
+ *newLVSize = i_size_read(sb->s_bdev->bd_inode) >>
sb->s_blocksize_bits;
if (*newLVSize == 0)
pr_err("JFS: Cannot determine volume size\n");
@@ -579,7 +579,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
goto out_unload;
}
inode->i_ino = 0;
- inode->i_size = sb->s_bdev->bd_inode->i_size;
+ inode->i_size = i_size_read(sb->s_bdev->bd_inode);
inode->i_mapping->a_ops = &jfs_metapage_aops;
hlist_add_fake(&inode->i_hash);
mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
diff --git a/fs/mount.h b/fs/mount.h
index de45d9e76748..6790767d1883 100644
--- a/fs/mount.h
+++ b/fs/mount.h
@@ -16,7 +16,7 @@ struct mnt_namespace {
u64 event;
unsigned int mounts; /* # of mounts in the namespace */
unsigned int pending_mounts;
-};
+} __randomize_layout;
struct mnt_pcp {
int mnt_count;
@@ -69,7 +69,7 @@ struct mount {
struct hlist_head mnt_pins;
struct fs_pin mnt_umount;
struct dentry *mnt_ex_mountpoint;
-};
+} __randomize_layout;
#define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
diff --git a/fs/namei.c b/fs/namei.c
index 88fd38d1e3e7..ddb6a7c2b3d4 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -524,7 +524,7 @@ struct nameidata {
struct inode *link_inode;
unsigned root_seq;
int dfd;
-};
+} __randomize_layout;
static void set_nameidata(struct nameidata *p, int dfd, struct filename *name)
{
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index 69d02cf8cf37..5f93cfacb3d1 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -121,6 +121,7 @@ config PNFS_FILE_LAYOUT
config PNFS_BLOCK
tristate
depends on NFS_V4_1 && BLK_DEV_DM
+ depends on 64BIT || LBDAF
default NFS_V4
config PNFS_FLEXFILE_LAYOUT
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index ee5ddbd36088..efebe6cf4378 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -820,6 +820,7 @@ void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *sour
target->caps = source->caps;
target->options = source->options;
target->auth_info = source->auth_info;
+ target->port = source->port;
}
EXPORT_SYMBOL_GPL(nfs_server_copy_userdata);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 5ac484fe0dee..3522b1249019 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -2372,16 +2372,40 @@ void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
}
EXPORT_SYMBOL_GPL(nfs_access_add_cache);
+#define NFS_MAY_READ (NFS4_ACCESS_READ)
+#define NFS_MAY_WRITE (NFS4_ACCESS_MODIFY | \
+ NFS4_ACCESS_EXTEND | \
+ NFS4_ACCESS_DELETE)
+#define NFS_FILE_MAY_WRITE (NFS4_ACCESS_MODIFY | \
+ NFS4_ACCESS_EXTEND)
+#define NFS_DIR_MAY_WRITE NFS_MAY_WRITE
+#define NFS_MAY_LOOKUP (NFS4_ACCESS_LOOKUP)
+#define NFS_MAY_EXECUTE (NFS4_ACCESS_EXECUTE)
+static int
+nfs_access_calc_mask(u32 access_result, umode_t umode)
+{
+ int mask = 0;
+
+ if (access_result & NFS_MAY_READ)
+ mask |= MAY_READ;
+ if (S_ISDIR(umode)) {
+ if ((access_result & NFS_DIR_MAY_WRITE) == NFS_DIR_MAY_WRITE)
+ mask |= MAY_WRITE;
+ if ((access_result & NFS_MAY_LOOKUP) == NFS_MAY_LOOKUP)
+ mask |= MAY_EXEC;
+ } else if (S_ISREG(umode)) {
+ if ((access_result & NFS_FILE_MAY_WRITE) == NFS_FILE_MAY_WRITE)
+ mask |= MAY_WRITE;
+ if ((access_result & NFS_MAY_EXECUTE) == NFS_MAY_EXECUTE)
+ mask |= MAY_EXEC;
+ } else if (access_result & NFS_MAY_WRITE)
+ mask |= MAY_WRITE;
+ return mask;
+}
+
void nfs_access_set_mask(struct nfs_access_entry *entry, u32 access_result)
{
- entry->mask = 0;
- if (access_result & NFS4_ACCESS_READ)
- entry->mask |= MAY_READ;
- if (access_result &
- (NFS4_ACCESS_MODIFY | NFS4_ACCESS_EXTEND | NFS4_ACCESS_DELETE))
- entry->mask |= MAY_WRITE;
- if (access_result & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE))
- entry->mask |= MAY_EXEC;
+ entry->mask = access_result;
}
EXPORT_SYMBOL_GPL(nfs_access_set_mask);
@@ -2389,6 +2413,7 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
{
struct nfs_access_entry cache;
bool may_block = (mask & MAY_NOT_BLOCK) == 0;
+ int cache_mask;
int status;
trace_nfs_access_enter(inode);
@@ -2404,7 +2429,8 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
goto out;
/* Be clever: ask server to check for all possible rights */
- cache.mask = MAY_EXEC | MAY_WRITE | MAY_READ;
+ cache.mask = NFS_MAY_LOOKUP | NFS_MAY_EXECUTE
+ | NFS_MAY_WRITE | NFS_MAY_READ;
cache.cred = cred;
cache.jiffies = jiffies;
status = NFS_PROTO(inode)->access(inode, &cache);
@@ -2418,7 +2444,8 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
}
nfs_access_add_cache(inode, &cache);
out_cached:
- if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) != 0)
+ cache_mask = nfs_access_calc_mask(cache.mask, inode->i_mode);
+ if ((mask & ~cache_mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) != 0)
status = -EACCES;
out:
trace_nfs_access_exit(inode, status);
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 5713eb32a45e..af330c31f627 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -617,6 +617,8 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
if (result)
goto out;
}
+ if (iocb->ki_pos > i_size_read(inode))
+ nfs_revalidate_mapping(inode, file->f_mapping);
nfs_start_io_write(inode);
result = generic_write_checks(iocb, from);
@@ -750,7 +752,7 @@ do_setlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
*/
nfs_sync_mapping(filp->f_mapping);
if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
- nfs_zap_mapping(inode, filp->f_mapping);
+ nfs_zap_caches(inode);
out:
return status;
}
diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c
index 080fc6b278bd..44c638b7876c 100644
--- a/fs/nfs/filelayout/filelayout.c
+++ b/fs/nfs/filelayout/filelayout.c
@@ -542,6 +542,10 @@ filelayout_check_deviceid(struct pnfs_layout_hdr *lo,
struct nfs4_file_layout_dsaddr *dsaddr;
int status = -EINVAL;
+ /* Is the deviceid already set? If so, we're good. */
+ if (fl->dsaddr != NULL)
+ return 0;
+
/* find and reference the deviceid */
d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode), &fl->deviceid,
lo->plh_lc_cred, gfp_flags);
@@ -553,8 +557,6 @@ filelayout_check_deviceid(struct pnfs_layout_hdr *lo,
if (filelayout_test_devid_unavailable(&dsaddr->id_node))
goto out_put;
- fl->dsaddr = dsaddr;
-
if (fl->first_stripe_index >= dsaddr->stripe_count) {
dprintk("%s Bad first_stripe_index %u\n",
__func__, fl->first_stripe_index);
@@ -570,6 +572,13 @@ filelayout_check_deviceid(struct pnfs_layout_hdr *lo,
goto out_put;
}
status = 0;
+
+ /*
+ * Atomic compare and xchange to ensure we don't scribble
+ * over a non-NULL pointer.
+ */
+ if (cmpxchg(&fl->dsaddr, NULL, dsaddr) != NULL)
+ goto out_put;
out:
return status;
out_put:
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index 1f2ac3dd0fe5..b0fa83a60754 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -1842,6 +1842,10 @@ static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how)
int vers, ret;
struct nfs_fh *fh;
+ if (!lseg || !(pnfs_is_valid_lseg(lseg) ||
+ test_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags)))
+ goto out_err;
+
idx = calc_ds_index_from_commit(lseg, data->ds_commit_index);
ds = nfs4_ff_layout_prepare_ds(lseg, idx, true);
if (!ds)
diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
index 6df7a0cf5660..f32c58bbe556 100644
--- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c
+++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
@@ -32,6 +32,7 @@ void nfs4_ff_layout_free_deviceid(struct nfs4_ff_layout_ds *mirror_ds)
{
nfs4_print_deviceid(&mirror_ds->id_node.deviceid);
nfs4_pnfs_ds_put(mirror_ds->ds);
+ kfree(mirror_ds->ds_versions);
kfree_rcu(mirror_ds, id_node.rcu);
}
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index 3efe946672be..60bad882c123 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -512,7 +512,7 @@ static const struct rpc_version mnt_version1 = {
.counts = mnt_counts,
};
-static unsigned int mnt3_counts[ARRAY_SIZE(mnt_procedures)];
+static unsigned int mnt3_counts[ARRAY_SIZE(mnt3_procedures)];
static const struct rpc_version mnt_version3 = {
.number = 3,
.nrprocs = ARRAY_SIZE(mnt3_procedures),
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index df4a7d3ab915..d1e87ec0df84 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -220,15 +220,8 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
nfs_refresh_inode(inode, res.fattr);
- if (status == 0) {
- entry->mask = 0;
- if (res.access & NFS3_ACCESS_READ)
- entry->mask |= MAY_READ;
- if (res.access & (NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND | NFS3_ACCESS_DELETE))
- entry->mask |= MAY_WRITE;
- if (res.access & (NFS3_ACCESS_LOOKUP|NFS3_ACCESS_EXECUTE))
- entry->mask |= MAY_EXEC;
- }
+ if (status == 0)
+ nfs_access_set_mask(entry, res.access);
nfs_free_fattr(res.fattr);
out:
dprintk("NFS reply access: %d\n", status);
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 50566acb5469..e9bea90dc017 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -660,9 +660,6 @@ int nfs4_detect_session_trunking(struct nfs_client *clp,
if (!nfs4_check_server_scope(clp->cl_serverscope, res->server_scope))
goto out_err;
- /* Session trunking passed, add the xprt */
- rpc_clnt_xprt_switch_add_xprt(clp->cl_rpcclient, xprt);
-
pr_info("NFS: %s: Session trunking succeeded for %s\n",
clp->cl_hostname,
xprt->address_strings[RPC_DISPLAY_ADDR]);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index a0b4e1091340..d90132642340 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2236,7 +2236,7 @@ static int nfs4_opendata_access(struct rpc_cred *cred,
int openflags)
{
struct nfs_access_entry cache;
- u32 mask;
+ u32 mask, flags;
/* access call failed or for some reason the server doesn't
* support any access modes -- defer access call until later */
@@ -2250,16 +2250,20 @@ static int nfs4_opendata_access(struct rpc_cred *cred,
*/
if (openflags & __FMODE_EXEC) {
/* ONLY check for exec rights */
- mask = MAY_EXEC;
+ if (S_ISDIR(state->inode->i_mode))
+ mask = NFS4_ACCESS_LOOKUP;
+ else
+ mask = NFS4_ACCESS_EXECUTE;
} else if ((fmode & FMODE_READ) && !opendata->file_created)
- mask = MAY_READ;
+ mask = NFS4_ACCESS_READ;
cache.cred = cred;
cache.jiffies = jiffies;
nfs_access_set_mask(&cache, opendata->o_res.access_result);
nfs_access_add_cache(state->inode, &cache);
- if ((mask & ~cache.mask & (MAY_READ | MAY_EXEC)) == 0)
+ flags = NFS4_ACCESS_READ | NFS4_ACCESS_EXECUTE | NFS4_ACCESS_LOOKUP;
+ if ((mask & ~cache.mask & flags) == 0)
return 0;
return -EACCES;
@@ -2549,9 +2553,8 @@ static int nfs41_check_open_stateid(struct nfs4_state *state)
clear_bit(NFS_O_RDWR_STATE, &state->flags);
clear_bit(NFS_OPEN_STATE, &state->flags);
stateid->type = NFS4_INVALID_STATEID_TYPE;
- }
- if (status != NFS_OK)
return status;
+ }
if (nfs_open_stateid_recover_openmode(state))
return -NFS4ERR_OPENMODE;
return NFS_OK;
@@ -6492,7 +6495,7 @@ nfs4_retry_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
set_current_state(TASK_INTERRUPTIBLE);
spin_unlock_irqrestore(&q->lock, flags);
- freezable_schedule_timeout_interruptible(NFS4_LOCK_MAXTIMEOUT);
+ freezable_schedule_timeout(NFS4_LOCK_MAXTIMEOUT);
}
finish_wait(q, &wait);
@@ -7457,7 +7460,7 @@ static void nfs4_exchange_id_done(struct rpc_task *task, void *data)
cdata->res.server_scope = NULL;
}
/* Save the EXCHANGE_ID verifier session trunk tests */
- memcpy(clp->cl_confirm.data, cdata->args.verifier->data,
+ memcpy(clp->cl_confirm.data, cdata->args.verifier.data,
sizeof(clp->cl_confirm.data));
}
out:
@@ -7470,10 +7473,6 @@ static void nfs4_exchange_id_release(void *data)
struct nfs41_exchange_id_data *cdata =
(struct nfs41_exchange_id_data *)data;
- if (cdata->xprt) {
- xprt_put(cdata->xprt);
- rpc_clnt_xprt_switch_put(cdata->args.client->cl_rpcclient);
- }
nfs_put_client(cdata->args.client);
kfree(cdata->res.impl_id);
kfree(cdata->res.server_scope);
@@ -7494,7 +7493,6 @@ static const struct rpc_call_ops nfs4_exchange_id_call_ops = {
static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
u32 sp4_how, struct rpc_xprt *xprt)
{
- nfs4_verifier verifier;
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_EXCHANGE_ID],
.rpc_cred = cred,
@@ -7503,7 +7501,7 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
.rpc_client = clp->cl_rpcclient,
.callback_ops = &nfs4_exchange_id_call_ops,
.rpc_message = &msg,
- .flags = RPC_TASK_ASYNC | RPC_TASK_TIMEOUT,
+ .flags = RPC_TASK_TIMEOUT,
};
struct nfs41_exchange_id_data *calldata;
struct rpc_task *task;
@@ -7518,8 +7516,7 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
return -ENOMEM;
}
- if (!xprt)
- nfs4_init_boot_verifier(clp, &verifier);
+ nfs4_init_boot_verifier(clp, &calldata->args.verifier);
status = nfs4_init_uniform_client_string(clp);
if (status)
@@ -7558,11 +7555,9 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
if (xprt) {
calldata->xprt = xprt;
task_setup_data.rpc_xprt = xprt;
- task_setup_data.flags =
- RPC_TASK_SOFT|RPC_TASK_SOFTCONN|RPC_TASK_ASYNC;
- calldata->args.verifier = &clp->cl_confirm;
- } else {
- calldata->args.verifier = &verifier;
+ task_setup_data.flags |= RPC_TASK_SOFTCONN;
+ memcpy(calldata->args.verifier.data, clp->cl_confirm.data,
+ sizeof(calldata->args.verifier.data));
}
calldata->args.client = clp;
#ifdef CONFIG_NFS_V4_1_MIGRATION
@@ -7581,12 +7576,7 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
if (IS_ERR(task))
return PTR_ERR(task);
- if (!xprt) {
- status = rpc_wait_for_completion_task(task);
- if (!status)
- status = calldata->rpc_status;
- } else /* session trunking test */
- status = calldata->rpc_status;
+ status = calldata->rpc_status;
rpc_put_task(task);
out:
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index fa3eb361d4f8..37c8af003275 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1785,7 +1785,7 @@ static void encode_exchange_id(struct xdr_stream *xdr,
int len = 0;
encode_op_hdr(xdr, OP_EXCHANGE_ID, decode_exchange_id_maxsz, hdr);
- encode_nfs4_verifier(xdr, args->verifier);
+ encode_nfs4_verifier(xdr, &args->verifier);
encode_string(xdr, strlen(args->client->cl_owner_id),
args->client->cl_owner_id);
diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c
index d40755a0984b..25f28fa64c57 100644
--- a/fs/nfs/pnfs_nfs.c
+++ b/fs/nfs/pnfs_nfs.c
@@ -159,13 +159,18 @@ void pnfs_generic_recover_commit_reqs(struct list_head *dst,
{
struct pnfs_commit_bucket *b;
struct pnfs_layout_segment *freeme;
+ int nwritten;
int i;
lockdep_assert_held(&cinfo->inode->i_lock);
restart:
for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) {
- if (pnfs_generic_transfer_commit_list(&b->written, dst,
- cinfo, 0)) {
+ nwritten = pnfs_generic_transfer_commit_list(&b->written,
+ dst, cinfo, 0);
+ if (!nwritten)
+ continue;
+ cinfo->ds->nwritten -= nwritten;
+ if (list_empty(&b->written)) {
freeme = b->wlseg;
b->wlseg = NULL;
spin_unlock(&cinfo->inode->i_lock);
@@ -174,7 +179,6 @@ restart:
goto restart;
}
}
- cinfo->ds->nwritten = 0;
}
EXPORT_SYMBOL_GPL(pnfs_generic_recover_commit_reqs);
@@ -183,6 +187,7 @@ static void pnfs_generic_retry_commit(struct nfs_commit_info *cinfo, int idx)
struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
struct pnfs_commit_bucket *bucket;
struct pnfs_layout_segment *freeme;
+ struct list_head *pos;
LIST_HEAD(pages);
int i;
@@ -193,6 +198,8 @@ static void pnfs_generic_retry_commit(struct nfs_commit_info *cinfo, int idx)
continue;
freeme = bucket->clseg;
bucket->clseg = NULL;
+ list_for_each(pos, &bucket->committing)
+ cinfo->ds->ncommitting--;
list_splice_init(&bucket->committing, &pages);
spin_unlock(&cinfo->inode->i_lock);
nfs_retry_commit(&pages, freeme, cinfo, i);
@@ -217,13 +224,6 @@ pnfs_generic_alloc_ds_commits(struct nfs_commit_info *cinfo,
for (i = 0; i < fl_cinfo->nbuckets; i++, bucket++) {
if (list_empty(&bucket->committing))
continue;
- /*
- * If the layout segment is invalid, then let
- * pnfs_generic_retry_commit() clean up the bucket.
- */
- if (bucket->clseg && !pnfs_is_valid_lseg(bucket->clseg) &&
- !test_bit(NFS_LSEG_LAYOUTRETURN, &bucket->clseg->pls_flags))
- break;
data = nfs_commitdata_alloc(false);
if (!data)
break;
@@ -243,9 +243,12 @@ void pnfs_fetch_commit_bucket_list(struct list_head *pages,
struct nfs_commit_info *cinfo)
{
struct pnfs_commit_bucket *bucket;
+ struct list_head *pos;
bucket = &cinfo->ds->buckets[data->ds_commit_index];
spin_lock(&cinfo->inode->i_lock);
+ list_for_each(pos, &bucket->committing)
+ cinfo->ds->ncommitting--;
list_splice_init(&bucket->committing, pages);
data->lseg = bucket->clseg;
bucket->clseg = NULL;
@@ -330,7 +333,6 @@ pnfs_generic_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
}
}
out:
- cinfo->ds->ncommitting = 0;
return PNFS_ATTEMPTED;
}
EXPORT_SYMBOL_GPL(pnfs_generic_commit_pagelist);
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index b45083c0f9ae..49b0a9e7ff18 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -720,8 +720,8 @@ static const struct rpc_version nfs_cb_version4 = {
.counts = nfs4_cb_counts,
};
-static const struct rpc_version *nfs_cb_version[] = {
- &nfs_cb_version4,
+static const struct rpc_version *nfs_cb_version[2] = {
+ [1] = &nfs_cb_version4,
};
static const struct rpc_program cb_program;
@@ -795,7 +795,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
.saddress = (struct sockaddr *) &conn->cb_saddr,
.timeout = &timeparms,
.program = &cb_program,
- .version = 0,
+ .version = 1,
.flags = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET),
};
struct rpc_clnt *client;
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c
index dc22ba8c710f..e50a387959bf 100644
--- a/fs/ocfs2/acl.c
+++ b/fs/ocfs2/acl.c
@@ -240,18 +240,6 @@ int ocfs2_set_acl(handle_t *handle,
switch (type) {
case ACL_TYPE_ACCESS:
name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
- if (acl) {
- umode_t mode;
-
- ret = posix_acl_update_mode(inode, &mode, &acl);
- if (ret)
- return ret;
-
- ret = ocfs2_acl_set_mode(inode, di_bh,
- handle, mode);
- if (ret)
- return ret;
- }
break;
case ACL_TYPE_DEFAULT:
name_index = OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT;
@@ -289,7 +277,19 @@ int ocfs2_iop_set_acl(struct inode *inode, struct posix_acl *acl, int type)
had_lock = ocfs2_inode_lock_tracker(inode, &bh, 1, &oh);
if (had_lock < 0)
return had_lock;
+ if (type == ACL_TYPE_ACCESS && acl) {
+ umode_t mode;
+
+ status = posix_acl_update_mode(inode, &mode, &acl);
+ if (status)
+ goto unlock;
+
+ status = ocfs2_acl_set_mode(inode, bh, NULL, mode);
+ if (status)
+ goto unlock;
+ }
status = ocfs2_set_acl(NULL, inode, bh, type, acl, NULL, NULL);
+unlock:
ocfs2_inode_unlock_tracker(inode, 1, &oh, had_lock);
brelse(bh);
return status;
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index 641d9ee97f91..48b70e6490f3 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -481,17 +481,30 @@ out_cleanup:
}
static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
- struct cattr *attr, struct dentry *hardlink)
+ struct cattr *attr, struct dentry *hardlink,
+ bool origin)
{
int err;
const struct cred *old_cred;
struct cred *override_cred;
+ struct dentry *parent = dentry->d_parent;
- err = ovl_copy_up(dentry->d_parent);
+ err = ovl_copy_up(parent);
if (err)
return err;
old_cred = ovl_override_creds(dentry->d_sb);
+
+ /*
+ * When linking a file with copy up origin into a new parent, mark the
+ * new parent dir "impure".
+ */
+ if (origin) {
+ err = ovl_set_impure(parent, ovl_dentry_upper(parent));
+ if (err)
+ goto out_revert_creds;
+ }
+
err = -ENOMEM;
override_cred = prepare_creds();
if (override_cred) {
@@ -550,7 +563,7 @@ static int ovl_create_object(struct dentry *dentry, int mode, dev_t rdev,
inode_init_owner(inode, dentry->d_parent->d_inode, mode);
attr.mode = inode->i_mode;
- err = ovl_create_or_link(dentry, inode, &attr, NULL);
+ err = ovl_create_or_link(dentry, inode, &attr, NULL, false);
if (err)
iput(inode);
@@ -609,7 +622,8 @@ static int ovl_link(struct dentry *old, struct inode *newdir,
inode = d_inode(old);
ihold(inode);
- err = ovl_create_or_link(new, inode, NULL, ovl_dentry_upper(old));
+ err = ovl_create_or_link(new, inode, NULL, ovl_dentry_upper(old),
+ ovl_type_origin(old));
if (err)
iput(inode);
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 69f4fc26ee39..5bc71642b226 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -202,37 +202,38 @@ bool ovl_is_private_xattr(const char *name)
sizeof(OVL_XATTR_PREFIX) - 1) == 0;
}
-int ovl_xattr_set(struct dentry *dentry, const char *name, const void *value,
- size_t size, int flags)
+int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name,
+ const void *value, size_t size, int flags)
{
int err;
- struct path realpath;
- enum ovl_path_type type = ovl_path_real(dentry, &realpath);
+ struct dentry *upperdentry = ovl_i_dentry_upper(inode);
+ struct dentry *realdentry = upperdentry ?: ovl_dentry_lower(dentry);
const struct cred *old_cred;
err = ovl_want_write(dentry);
if (err)
goto out;
- if (!value && !OVL_TYPE_UPPER(type)) {
- err = vfs_getxattr(realpath.dentry, name, NULL, 0);
+ if (!value && !upperdentry) {
+ err = vfs_getxattr(realdentry, name, NULL, 0);
if (err < 0)
goto out_drop_write;
}
- err = ovl_copy_up(dentry);
- if (err)
- goto out_drop_write;
+ if (!upperdentry) {
+ err = ovl_copy_up(dentry);
+ if (err)
+ goto out_drop_write;
- if (!OVL_TYPE_UPPER(type))
- ovl_path_upper(dentry, &realpath);
+ realdentry = ovl_dentry_upper(dentry);
+ }
old_cred = ovl_override_creds(dentry->d_sb);
if (value)
- err = vfs_setxattr(realpath.dentry, name, value, size, flags);
+ err = vfs_setxattr(realdentry, name, value, size, flags);
else {
WARN_ON(flags != XATTR_REPLACE);
- err = vfs_removexattr(realpath.dentry, name);
+ err = vfs_removexattr(realdentry, name);
}
revert_creds(old_cred);
@@ -242,12 +243,13 @@ out:
return err;
}
-int ovl_xattr_get(struct dentry *dentry, const char *name,
+int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name,
void *value, size_t size)
{
- struct dentry *realdentry = ovl_dentry_real(dentry);
ssize_t res;
const struct cred *old_cred;
+ struct dentry *realdentry =
+ ovl_i_dentry_upper(inode) ?: ovl_dentry_lower(dentry);
old_cred = ovl_override_creds(dentry->d_sb);
res = vfs_getxattr(realdentry, name, value, size);
diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
index 9bc0e580a5b3..8aef2b304b2d 100644
--- a/fs/overlayfs/namei.c
+++ b/fs/overlayfs/namei.c
@@ -397,8 +397,19 @@ int ovl_verify_index(struct dentry *index, struct path *lowerstack,
if (!d_inode(index))
return 0;
- err = -EISDIR;
- if (d_is_dir(index))
+ /*
+ * Directory index entries are going to be used for looking up
+ * redirected upper dirs by lower dir fh when decoding an overlay
+ * file handle of a merge dir. Whiteout index entries are going to be
+ * used as an indication that an exported overlay file handle should
+ * be treated as stale (i.e. after unlink of the overlay inode).
+ * We don't know the verification rules for directory and whiteout
+ * index entries, because they have not been implemented yet, so return
+ * EROFS if those entries are found to avoid corrupting an index that
+ * was created by a newer kernel.
+ */
+ err = -EROFS;
+ if (d_is_dir(index) || ovl_is_whiteout(index))
goto fail;
err = -EINVAL;
@@ -436,8 +447,8 @@ out:
return err;
fail:
- pr_warn_ratelimited("overlayfs: failed to verify index (%pd2, err=%i)\n",
- index, err);
+ pr_warn_ratelimited("overlayfs: failed to verify index (%pd2, ftype=%x, err=%i)\n",
+ index, d_inode(index)->i_mode & S_IFMT, err);
goto out;
}
@@ -502,6 +513,7 @@ static struct dentry *ovl_lookup_index(struct dentry *dentry,
goto out;
}
+ inode = d_inode(index);
if (d_is_negative(index)) {
if (upper && d_inode(origin)->i_nlink > 1) {
pr_warn_ratelimited("overlayfs: hard link with origin but no index (ino=%lu).\n",
@@ -511,11 +523,22 @@ static struct dentry *ovl_lookup_index(struct dentry *dentry,
dput(index);
index = NULL;
- } else if (upper && d_inode(index) != d_inode(upper)) {
- inode = d_inode(index);
- pr_warn_ratelimited("overlayfs: wrong index found (index ino: %lu, upper ino: %lu).\n",
- d_inode(index)->i_ino,
- d_inode(upper)->i_ino);
+ } else if (upper && d_inode(upper) != inode) {
+ pr_warn_ratelimited("overlayfs: wrong index found (index=%pd2, ino=%lu, upper ino=%lu).\n",
+ index, inode->i_ino, d_inode(upper)->i_ino);
+ goto fail;
+ } else if (ovl_dentry_weird(index) || ovl_is_whiteout(index) ||
+ ((inode->i_mode ^ d_inode(origin)->i_mode) & S_IFMT)) {
+ /*
+ * Index should always be of the same file type as origin
+ * except for the case of a whiteout index. A whiteout
+ * index should only exist if all lower aliases have been
+ * unlinked, which means that finding a lower origin on lookup
+ * whose index is a whiteout should be treated as an error.
+ */
+ pr_warn_ratelimited("overlayfs: bad index found (index=%pd2, ftype=%x, origin ftype=%x).\n",
+ index, d_inode(index)->i_mode & S_IFMT,
+ d_inode(origin)->i_mode & S_IFMT);
goto fail;
}
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 60d26605e039..e927a62c97ae 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -47,7 +47,8 @@ enum ovl_flag {
/* Is the real inode encoded in fid an upper inode? */
#define OVL_FH_FLAG_PATH_UPPER (1 << 2)
-#define OVL_FH_FLAG_ALL (OVL_FH_FLAG_BIG_ENDIAN | OVL_FH_FLAG_ANY_ENDIAN)
+#define OVL_FH_FLAG_ALL (OVL_FH_FLAG_BIG_ENDIAN | OVL_FH_FLAG_ANY_ENDIAN | \
+ OVL_FH_FLAG_PATH_UPPER)
#if defined(__LITTLE_ENDIAN)
#define OVL_FH_FLAG_CPU_ENDIAN 0
@@ -199,6 +200,7 @@ enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path);
struct dentry *ovl_dentry_upper(struct dentry *dentry);
struct dentry *ovl_dentry_lower(struct dentry *dentry);
struct dentry *ovl_dentry_real(struct dentry *dentry);
+struct dentry *ovl_i_dentry_upper(struct inode *inode);
struct inode *ovl_inode_upper(struct inode *inode);
struct inode *ovl_inode_lower(struct inode *inode);
struct inode *ovl_inode_real(struct inode *inode);
@@ -270,9 +272,9 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr);
int ovl_getattr(const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags);
int ovl_permission(struct inode *inode, int mask);
-int ovl_xattr_set(struct dentry *dentry, const char *name, const void *value,
- size_t size, int flags);
-int ovl_xattr_get(struct dentry *dentry, const char *name,
+int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name,
+ const void *value, size_t size, int flags);
+int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name,
void *value, size_t size);
ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
struct posix_acl *ovl_get_acl(struct inode *inode, int type);
diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
index 0298463cf9c3..3d424a51cabb 100644
--- a/fs/overlayfs/readdir.c
+++ b/fs/overlayfs/readdir.c
@@ -703,7 +703,10 @@ int ovl_indexdir_cleanup(struct dentry *dentry, struct vfsmount *mnt,
err = PTR_ERR(index);
break;
}
- if (ovl_verify_index(index, lowerstack, numlower)) {
+ err = ovl_verify_index(index, lowerstack, numlower);
+ if (err) {
+ if (err == -EROFS)
+ break;
err = ovl_cleanup(dir, index);
if (err)
break;
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 44dc2d6ffe0f..d86e89f97201 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -692,7 +692,7 @@ ovl_posix_acl_xattr_get(const struct xattr_handler *handler,
struct dentry *dentry, struct inode *inode,
const char *name, void *buffer, size_t size)
{
- return ovl_xattr_get(dentry, handler->name, buffer, size);
+ return ovl_xattr_get(dentry, inode, handler->name, buffer, size);
}
static int __maybe_unused
@@ -742,7 +742,7 @@ ovl_posix_acl_xattr_set(const struct xattr_handler *handler,
return err;
}
- err = ovl_xattr_set(dentry, handler->name, value, size, flags);
+ err = ovl_xattr_set(dentry, inode, handler->name, value, size, flags);
if (!err)
ovl_copyattr(ovl_inode_real(inode), inode);
@@ -772,7 +772,7 @@ static int ovl_other_xattr_get(const struct xattr_handler *handler,
struct dentry *dentry, struct inode *inode,
const char *name, void *buffer, size_t size)
{
- return ovl_xattr_get(dentry, name, buffer, size);
+ return ovl_xattr_get(dentry, inode, name, buffer, size);
}
static int ovl_other_xattr_set(const struct xattr_handler *handler,
@@ -780,7 +780,7 @@ static int ovl_other_xattr_set(const struct xattr_handler *handler,
const char *name, const void *value,
size_t size, int flags)
{
- return ovl_xattr_set(dentry, name, value, size, flags);
+ return ovl_xattr_set(dentry, inode, name, value, size, flags);
}
static const struct xattr_handler __maybe_unused
@@ -1058,10 +1058,6 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
ufs->indexdir = ovl_workdir_create(sb, ufs, workpath.dentry,
OVL_INDEXDIR_NAME, true);
- err = PTR_ERR(ufs->indexdir);
- if (IS_ERR(ufs->indexdir))
- goto out_put_lower_mnt;
-
if (ufs->indexdir) {
/* Verify upper root is index dir origin */
err = ovl_verify_origin(ufs->indexdir, ufs->upper_mnt,
@@ -1090,6 +1086,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
else
sb->s_d_op = &ovl_dentry_operations;
+ err = -ENOMEM;
ufs->creator_cred = cred = prepare_creds();
if (!cred)
goto out_put_indexdir;
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index c492ba75c659..f46ad75dc96a 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -157,9 +157,14 @@ struct dentry *ovl_dentry_real(struct dentry *dentry)
return ovl_dentry_upper(dentry) ?: ovl_dentry_lower(dentry);
}
+struct dentry *ovl_i_dentry_upper(struct inode *inode)
+{
+ return ovl_upperdentry_dereference(OVL_I(inode));
+}
+
struct inode *ovl_inode_upper(struct inode *inode)
{
- struct dentry *upperdentry = ovl_upperdentry_dereference(OVL_I(inode));
+ struct dentry *upperdentry = ovl_i_dentry_upper(inode);
return upperdentry ? d_inode(upperdentry) : NULL;
}
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 18694598bebf..aa2b89071630 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -51,7 +51,7 @@ struct proc_dir_entry {
spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
u8 namelen;
char name[];
-};
+} __randomize_layout;
union proc_op {
int (*proc_get_link)(struct dentry *, struct path *);
@@ -70,7 +70,7 @@ struct proc_inode {
struct hlist_node sysctl_inodes;
const struct proc_ns_operations *ns_ops;
struct inode vfs_inode;
-};
+} __randomize_layout;
/*
* General functions
@@ -279,7 +279,7 @@ struct proc_maps_private {
#ifdef CONFIG_NUMA
struct mempolicy *task_mempolicy;
#endif
-};
+} __randomize_layout;
struct mm_struct *proc_mem_open(struct inode *inode, unsigned int mode);
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c
index 8a428498d6b2..509a61668d90 100644
--- a/fs/proc/meminfo.c
+++ b/fs/proc/meminfo.c
@@ -106,13 +106,13 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
global_node_page_state(NR_FILE_MAPPED));
show_val_kb(m, "Shmem: ", i.sharedram);
show_val_kb(m, "Slab: ",
- global_page_state(NR_SLAB_RECLAIMABLE) +
- global_page_state(NR_SLAB_UNRECLAIMABLE));
+ global_node_page_state(NR_SLAB_RECLAIMABLE) +
+ global_node_page_state(NR_SLAB_UNRECLAIMABLE));
show_val_kb(m, "SReclaimable: ",
- global_page_state(NR_SLAB_RECLAIMABLE));
+ global_node_page_state(NR_SLAB_RECLAIMABLE));
show_val_kb(m, "SUnreclaim: ",
- global_page_state(NR_SLAB_UNRECLAIMABLE));
+ global_node_page_state(NR_SLAB_UNRECLAIMABLE));
seq_printf(m, "KernelStack: %8lu kB\n",
global_page_state(NR_KERNEL_STACK_KB));
show_val_kb(m, "PageTables: ",
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index b836fd61ed87..fe8f3265e877 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -16,9 +16,10 @@
#include <linux/mmu_notifier.h>
#include <linux/page_idle.h>
#include <linux/shmem_fs.h>
+#include <linux/uaccess.h>
#include <asm/elf.h>
-#include <linux/uaccess.h>
+#include <asm/tlb.h>
#include <asm/tlbflush.h>
#include "internal.h"
@@ -1008,6 +1009,7 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf,
struct mm_struct *mm;
struct vm_area_struct *vma;
enum clear_refs_types type;
+ struct mmu_gather tlb;
int itype;
int rv;
@@ -1054,6 +1056,7 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf,
}
down_read(&mm->mmap_sem);
+ tlb_gather_mmu(&tlb, mm, 0, -1);
if (type == CLEAR_REFS_SOFT_DIRTY) {
for (vma = mm->mmap; vma; vma = vma->vm_next) {
if (!(vma->vm_flags & VM_SOFTDIRTY))
@@ -1075,7 +1078,7 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf,
walk_page_range(0, mm->highest_vm_end, &clear_refs_walk);
if (type == CLEAR_REFS_SOFT_DIRTY)
mmu_notifier_invalidate_range_end(mm, 0, -1);
- flush_tlb_mm(mm);
+ tlb_finish_mmu(&tlb, 0, -1);
up_read(&mm->mmap_sem);
out_mm:
mmput(mm);
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index 3d2256a425ee..54415f0e3d18 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -23,7 +23,8 @@ reiserfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
struct reiserfs_transaction_handle th;
size_t jcreate_blocks;
int size = acl ? posix_acl_xattr_size(acl->a_count) : 0;
-
+ int update_mode = 0;
+ umode_t mode = inode->i_mode;
/*
* Pessimism: We can't assume that anything from the xattr root up
@@ -37,7 +38,16 @@ reiserfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
error = journal_begin(&th, inode->i_sb, jcreate_blocks);
reiserfs_write_unlock(inode->i_sb);
if (error == 0) {
+ if (type == ACL_TYPE_ACCESS && acl) {
+ error = posix_acl_update_mode(inode, &mode, &acl);
+ if (error)
+ goto unlock;
+ update_mode = 1;
+ }
error = __reiserfs_set_acl(&th, inode, type, acl);
+ if (!error && update_mode)
+ inode->i_mode = mode;
+unlock:
reiserfs_write_lock(inode->i_sb);
error2 = journal_end(&th);
reiserfs_write_unlock(inode->i_sb);
@@ -241,11 +251,6 @@ __reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
switch (type) {
case ACL_TYPE_ACCESS:
name = XATTR_NAME_POSIX_ACL_ACCESS;
- if (acl) {
- error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
- if (error)
- return error;
- }
break;
case ACL_TYPE_DEFAULT:
name = XATTR_NAME_POSIX_ACL_DEFAULT;
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
index cadcd12a3d35..b0d5897bc4e6 100644
--- a/fs/userfaultfd.c
+++ b/fs/userfaultfd.c
@@ -854,6 +854,9 @@ wakeup:
__wake_up_locked_key(&ctx->fault_wqh, TASK_NORMAL, &range);
spin_unlock(&ctx->fault_pending_wqh.lock);
+ /* Flush pending events that may still wait on event_wqh */
+ wake_up_all(&ctx->event_wqh);
+
wake_up_poll(&ctx->fd_wqh, POLLHUP);
userfaultfd_ctx_put(ctx);
return 0;
@@ -1597,7 +1600,7 @@ static int userfaultfd_copy(struct userfaultfd_ctx *ctx,
uffdio_copy.len);
mmput(ctx->mm);
} else {
- return -ENOSPC;
+ return -ESRCH;
}
if (unlikely(put_user(ret, &user_uffdio_copy->copy)))
return -EFAULT;
@@ -1643,6 +1646,8 @@ static int userfaultfd_zeropage(struct userfaultfd_ctx *ctx,
ret = mfill_zeropage(ctx->mm, uffdio_zeropage.range.start,
uffdio_zeropage.range.len);
mmput(ctx->mm);
+ } else {
+ return -ESRCH;
}
if (unlikely(put_user(ret, &user_uffdio_zeropage->zeropage)))
return -EFAULT;
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 0a9880777c9c..c09c16b1ad3b 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -5435,6 +5435,7 @@ __xfs_bunmapi(
xfs_fsblock_t sum;
xfs_filblks_t len = *rlen; /* length to unmap in file */
xfs_fileoff_t max_len;
+ xfs_agnumber_t prev_agno = NULLAGNUMBER, agno;
trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_);
@@ -5534,6 +5535,17 @@ __xfs_bunmapi(
*/
del = got;
wasdel = isnullstartblock(del.br_startblock);
+
+ /*
+ * Make sure we don't touch multiple AGF headers out of order
+ * in a single transaction, as that could cause AB-BA deadlocks.
+ */
+ if (!wasdel) {
+ agno = XFS_FSB_TO_AGNO(mp, del.br_startblock);
+ if (prev_agno != NULLAGNUMBER && prev_agno > agno)
+ break;
+ prev_agno = agno;
+ }
if (got.br_startoff < start) {
del.br_startoff = start;
del.br_blockcount -= start - got.br_startoff;
@@ -6499,6 +6511,15 @@ xfs_bmap_finish_one(
xfs_fsblock_t firstfsb;
int error = 0;
+ /*
+ * firstfsb is tied to the transaction lifetime and is used to
+ * ensure correct AG locking order and schedule work item
+ * continuations. XFS_BUI_MAX_FAST_EXTENTS (== 1) restricts us
+ * to only making one bmap call per transaction, so it should
+ * be safe to have it as a local variable here.
+ */
+ firstfsb = NULLFSBLOCK;
+
trace_xfs_bmap_deferred(tp->t_mountp,
XFS_FSB_TO_AGNO(tp->t_mountp, startblock), type,
XFS_FSB_TO_AGBNO(tp->t_mountp, startblock),
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
index 4da85fff69ad..e0bcc4a59efd 100644
--- a/fs/xfs/libxfs/xfs_btree.c
+++ b/fs/xfs/libxfs/xfs_btree.c
@@ -728,7 +728,8 @@ xfs_btree_firstrec(
* Get the block pointer for this level.
*/
block = xfs_btree_get_block(cur, level, &bp);
- xfs_btree_check_block(cur, block, level, bp);
+ if (xfs_btree_check_block(cur, block, level, bp))
+ return 0;
/*
* It's empty, there is no such record.
*/
@@ -757,7 +758,8 @@ xfs_btree_lastrec(
* Get the block pointer for this level.
*/
block = xfs_btree_get_block(cur, level, &bp);
- xfs_btree_check_block(cur, block, level, bp);
+ if (xfs_btree_check_block(cur, block, level, bp))
+ return 0;
/*
* It's empty, there is no such record.
*/
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c
index d478065b9544..8727a43115ef 100644
--- a/fs/xfs/libxfs/xfs_dir2_data.c
+++ b/fs/xfs/libxfs/xfs_dir2_data.c
@@ -136,6 +136,8 @@ __xfs_dir3_data_check(
*/
if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
XFS_WANT_CORRUPTED_RETURN(mp, lastfree == 0);
+ XFS_WANT_CORRUPTED_RETURN(mp, endp >=
+ p + be16_to_cpu(dup->length));
XFS_WANT_CORRUPTED_RETURN(mp,
be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) ==
(char *)dup - (char *)hdr);
@@ -164,6 +166,8 @@ __xfs_dir3_data_check(
XFS_WANT_CORRUPTED_RETURN(mp, dep->namelen != 0);
XFS_WANT_CORRUPTED_RETURN(mp,
!xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)));
+ XFS_WANT_CORRUPTED_RETURN(mp, endp >=
+ p + ops->data_entsize(dep->namelen));
XFS_WANT_CORRUPTED_RETURN(mp,
be16_to_cpu(*ops->data_entry_tag_p(dep)) ==
(char *)dep - (char *)hdr);
diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c
index 900ea231f9a3..45b1c3b4e047 100644
--- a/fs/xfs/libxfs/xfs_refcount.c
+++ b/fs/xfs/libxfs/xfs_refcount.c
@@ -1638,6 +1638,10 @@ xfs_refcount_recover_cow_leftovers(
error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
if (error)
goto out_trans;
+ if (!agbp) {
+ error = -ENOMEM;
+ goto out_trans;
+ }
cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno, NULL);
/* Find all the leftover CoW staging extents. */
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index ceef77c0416a..ff48f0096810 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -874,7 +874,6 @@ xfs_ialloc(
case S_IFREG:
case S_IFDIR:
if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
- uint64_t di_flags2 = 0;
uint di_flags = 0;
if (S_ISDIR(mode)) {
@@ -911,20 +910,23 @@ xfs_ialloc(
di_flags |= XFS_DIFLAG_NODEFRAG;
if (pip->i_d.di_flags & XFS_DIFLAG_FILESTREAM)
di_flags |= XFS_DIFLAG_FILESTREAM;
- if (pip->i_d.di_flags2 & XFS_DIFLAG2_DAX)
- di_flags2 |= XFS_DIFLAG2_DAX;
ip->i_d.di_flags |= di_flags;
- ip->i_d.di_flags2 |= di_flags2;
}
if (pip &&
(pip->i_d.di_flags2 & XFS_DIFLAG2_ANY) &&
pip->i_d.di_version == 3 &&
ip->i_d.di_version == 3) {
+ uint64_t di_flags2 = 0;
+
if (pip->i_d.di_flags2 & XFS_DIFLAG2_COWEXTSIZE) {
- ip->i_d.di_flags2 |= XFS_DIFLAG2_COWEXTSIZE;
+ di_flags2 |= XFS_DIFLAG2_COWEXTSIZE;
ip->i_d.di_cowextsize = pip->i_d.di_cowextsize;
}
+ if (pip->i_d.di_flags2 & XFS_DIFLAG2_DAX)
+ di_flags2 |= XFS_DIFLAG2_DAX;
+
+ ip->i_d.di_flags2 |= di_flags2;
}
/* FALLTHROUGH */
case S_IFLNK:
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
index fbe72b134bef..43aa42a3a5d3 100644
--- a/fs/xfs/xfs_log_cil.c
+++ b/fs/xfs/xfs_log_cil.c
@@ -539,6 +539,7 @@ xlog_discard_endio(
INIT_WORK(&ctx->discard_endio_work, xlog_discard_endio_work);
queue_work(xfs_discard_wq, &ctx->discard_endio_work);
+ bio_put(bio);
}
static void
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 6ce948c436d5..15751dc2a27d 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -111,6 +111,9 @@ restart:
skipped = 0;
break;
}
+ /* we're done if id overflows back to zero */
+ if (!next_index)
+ break;
}
if (skipped) {
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index ab2270a87196..f45fbf0db9bb 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -170,6 +170,8 @@ xfs_reflink_find_shared(
error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
if (error)
return error;
+ if (!agbp)
+ return -ENOMEM;
cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno, NULL);
@@ -329,7 +331,7 @@ xfs_reflink_convert_cow_extent(
xfs_filblks_t count_fsb,
struct xfs_defer_ops *dfops)
{
- xfs_fsblock_t first_block;
+ xfs_fsblock_t first_block = NULLFSBLOCK;
int nimaps = 1;
if (imap->br_state == XFS_EXT_NORM)
diff --git a/include/acpi/acpi_numa.h b/include/acpi/acpi_numa.h
index d4b72944ccda..1e3a74f94131 100644
--- a/include/acpi/acpi_numa.h
+++ b/include/acpi/acpi_numa.h
@@ -3,6 +3,7 @@
#ifdef CONFIG_ACPI_NUMA
#include <linux/kernel.h>
+#include <linux/numa.h>
/* Proximity bitmap length */
#if MAX_NUMNODES > 256
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index 8afa4335e5b2..faddde44de8c 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -112,10 +112,11 @@ struct mmu_gather {
#define HAVE_GENERIC_MMU_GATHER
-void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end);
+void arch_tlb_gather_mmu(struct mmu_gather *tlb,
+ struct mm_struct *mm, unsigned long start, unsigned long end);
void tlb_flush_mmu(struct mmu_gather *tlb);
-void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start,
- unsigned long end);
+void arch_tlb_finish_mmu(struct mmu_gather *tlb,
+ unsigned long start, unsigned long end, bool force);
extern bool __tlb_remove_page_size(struct mmu_gather *tlb, struct page *page,
int page_size);
diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h
new file mode 100644
index 000000000000..9b30fec302c8
--- /dev/null
+++ b/include/drm/bridge/dw_mipi_dsi.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) STMicroelectronics SA 2017
+ *
+ * Authors: Philippe Cornu <philippe.cornu@st.com>
+ * Yannick Fertre <yannick.fertre@st.com>
+ *
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef __DW_MIPI_DSI__
+#define __DW_MIPI_DSI__
+
+struct dw_mipi_dsi_phy_ops {
+ int (*init)(void *priv_data);
+ int (*get_lane_mbps)(void *priv_data, struct drm_display_mode *mode,
+ unsigned long mode_flags, u32 lanes, u32 format,
+ unsigned int *lane_mbps);
+};
+
+struct dw_mipi_dsi_plat_data {
+ void __iomem *base;
+ unsigned int max_data_lanes;
+
+ enum drm_mode_status (*mode_valid)(void *priv_data,
+ const struct drm_display_mode *mode);
+
+ const struct dw_mipi_dsi_phy_ops *phy_ops;
+
+ void *priv_data;
+};
+
+int dw_mipi_dsi_probe(struct platform_device *pdev,
+ const struct dw_mipi_dsi_plat_data *plat_data);
+void dw_mipi_dsi_remove(struct platform_device *pdev);
+int dw_mipi_dsi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
+ const struct dw_mipi_dsi_plat_data *plat_data);
+void dw_mipi_dsi_unbind(struct device *dev);
+
+#endif /* __DW_MIPI_DSI__ */
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 39df16af7a4a..7277783a4ff0 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -82,19 +82,10 @@
#include <drm/drm_sysfs.h>
#include <drm/drm_vblank.h>
#include <drm/drm_irq.h>
-
+#include <drm/drm_device.h>
struct module;
-struct drm_device;
-struct drm_agp_head;
-struct drm_local_map;
-struct drm_device_dma;
-struct drm_gem_object;
-struct drm_master;
-struct drm_vblank_crtc;
-struct drm_vma_offset_manager;
-
struct device_node;
struct videomode;
struct reservation_object;
@@ -306,143 +297,6 @@ struct pci_controller;
/**
- * DRM device structure. This structure represent a complete card that
- * may contain multiple heads.
- */
-struct drm_device {
- struct list_head legacy_dev_list;/**< list of devices per driver for stealth attach cleanup */
- int if_version; /**< Highest interface version set */
-
- /** \name Lifetime Management */
- /*@{ */
- struct kref ref; /**< Object ref-count */
- struct device *dev; /**< Device structure of bus-device */
- struct drm_driver *driver; /**< DRM driver managing the device */
- void *dev_private; /**< DRM driver private data */
- struct drm_minor *control; /**< Control node */
- struct drm_minor *primary; /**< Primary node */
- struct drm_minor *render; /**< Render node */
- bool registered;
-
- /* currently active master for this device. Protected by master_mutex */
- struct drm_master *master;
-
- atomic_t unplugged; /**< Flag whether dev is dead */
- struct inode *anon_inode; /**< inode for private address-space */
- char *unique; /**< unique name of the device */
- /*@} */
-
- /** \name Locks */
- /*@{ */
- struct mutex struct_mutex; /**< For others */
- struct mutex master_mutex; /**< For drm_minor::master and drm_file::is_master */
- /*@} */
-
- /** \name Usage Counters */
- /*@{ */
- int open_count; /**< Outstanding files open, protected by drm_global_mutex. */
- spinlock_t buf_lock; /**< For drm_device::buf_use and a few other things. */
- int buf_use; /**< Buffers in use -- cannot alloc */
- atomic_t buf_alloc; /**< Buffer allocation in progress */
- /*@} */
-
- struct mutex filelist_mutex;
- struct list_head filelist;
-
- /** \name Memory management */
- /*@{ */
- struct list_head maplist; /**< Linked list of regions */
- struct drm_open_hash map_hash; /**< User token hash table for maps */
-
- /** \name Context handle management */
- /*@{ */
- struct list_head ctxlist; /**< Linked list of context handles */
- struct mutex ctxlist_mutex; /**< For ctxlist */
-
- struct idr ctx_idr;
-
- struct list_head vmalist; /**< List of vmas (for debugging) */
-
- /*@} */
-
- /** \name DMA support */
- /*@{ */
- struct drm_device_dma *dma; /**< Optional pointer for DMA support */
- /*@} */
-
- /** \name Context support */
- /*@{ */
-
- __volatile__ long context_flag; /**< Context swapping flag */
- int last_context; /**< Last current context */
- /*@} */
-
- /**
- * @irq_enabled:
- *
- * Indicates that interrupt handling is enabled, specifically vblank
- * handling. Drivers which don't use drm_irq_install() need to set this
- * to true manually.
- */
- bool irq_enabled;
- int irq;
-
- /*
- * If true, vblank interrupt will be disabled immediately when the
- * refcount drops to zero, as opposed to via the vblank disable
- * timer.
- * This can be set to true it the hardware has a working vblank
- * counter and the driver uses drm_vblank_on() and drm_vblank_off()
- * appropriately.
- */
- bool vblank_disable_immediate;
-
- /* array of size num_crtcs */
- struct drm_vblank_crtc *vblank;
-
- spinlock_t vblank_time_lock; /**< Protects vblank count and time updates during vblank enable/disable */
- spinlock_t vbl_lock;
-
- u32 max_vblank_count; /**< size of vblank counter register */
-
- /**
- * List of events
- */
- struct list_head vblank_event_list;
- spinlock_t event_lock;
-
- /*@} */
-
- struct drm_agp_head *agp; /**< AGP data */
-
- struct pci_dev *pdev; /**< PCI device structure */
-#ifdef __alpha__
- struct pci_controller *hose;
-#endif
-
- struct drm_sg_mem *sg; /**< Scatter gather memory */
- unsigned int num_crtcs; /**< Number of CRTCs on this device */
-
- struct {
- int context;
- struct drm_hw_lock *lock;
- } sigdata;
-
- struct drm_local_map *agp_buffer_map;
- unsigned int agp_buffer_token;
-
- struct drm_mode_config mode_config; /**< Current mode config */
-
- /** \name GEM information */
- /*@{ */
- struct mutex object_name_lock;
- struct idr object_name_idr;
- struct drm_vma_offset_manager *vma_offset_manager;
- /*@} */
- int switch_power_state;
-};
-
-/**
* drm_drv_uses_atomic_modeset - check if the driver implements
* atomic_commit()
* @dev: DRM device
@@ -466,19 +320,6 @@ static __inline__ int drm_core_check_feature(struct drm_device *dev,
return ((dev->driver->driver_features & feature) ? 1 : 0);
}
-static inline void drm_device_set_unplugged(struct drm_device *dev)
-{
- smp_wmb();
- atomic_set(&dev->unplugged, 1);
-}
-
-static inline int drm_device_is_unplugged(struct drm_device *dev)
-{
- int ret = atomic_read(&dev->unplugged);
- smp_rmb();
- return ret;
-}
-
/******************************************************************/
/** \name Internal function definitions */
/*@{*/
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 0196f264a418..8a5808eb5628 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -154,6 +154,9 @@ struct __drm_connnectors_state {
struct drm_connector_state *state, *old_state, *new_state;
};
+struct drm_private_obj;
+struct drm_private_state;
+
/**
* struct drm_private_state_funcs - atomic state functions for private objects
*
@@ -166,7 +169,7 @@ struct __drm_connnectors_state {
*/
struct drm_private_state_funcs {
/**
- * @duplicate_state:
+ * @atomic_duplicate_state:
*
* Duplicate the current state of the private object and return it. It
* is an error to call this before obj->state has been initialized.
@@ -176,29 +179,30 @@ struct drm_private_state_funcs {
* Duplicated atomic state or NULL when obj->state is not
* initialized or allocation failed.
*/
- void *(*duplicate_state)(struct drm_atomic_state *state, void *obj);
+ struct drm_private_state *(*atomic_duplicate_state)(struct drm_private_obj *obj);
/**
- * @swap_state:
+ * @atomic_destroy_state:
*
- * This function swaps the existing state of a private object @obj with
- * it's newly created state, the pointer to which is passed as
- * @obj_state_ptr.
+ * Frees the private object state created with @atomic_duplicate_state.
*/
- void (*swap_state)(void *obj, void **obj_state_ptr);
+ void (*atomic_destroy_state)(struct drm_private_obj *obj,
+ struct drm_private_state *state);
+};
- /**
- * @destroy_state:
- *
- * Frees the private object state created with @duplicate_state.
- */
- void (*destroy_state)(void *obj_state);
+struct drm_private_obj {
+ struct drm_private_state *state;
+
+ const struct drm_private_state_funcs *funcs;
+};
+
+struct drm_private_state {
+ struct drm_atomic_state *state;
};
struct __drm_private_objs_state {
- void *obj;
- void *obj_state;
- const struct drm_private_state_funcs *funcs;
+ struct drm_private_obj *ptr;
+ struct drm_private_state *state, *old_state, *new_state;
};
/**
@@ -207,6 +211,7 @@ struct __drm_private_objs_state {
* @dev: parent DRM device
* @allow_modeset: allow full modeset
* @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics
+ * @async_update: hint for asynchronous plane update
* @planes: pointer to array of structures with per-plane data
* @crtcs: pointer to array of CRTC pointers
* @num_connector: size of the @connectors and @connector_states arrays
@@ -221,6 +226,7 @@ struct drm_atomic_state {
struct drm_device *dev;
bool allow_modeset : 1;
bool legacy_cursor_update : 1;
+ bool async_update : 1;
struct __drm_planes_state *planes;
struct __drm_crtcs_state *crtcs;
int num_connector;
@@ -309,20 +315,18 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
struct drm_plane_state * __must_check
drm_atomic_get_plane_state(struct drm_atomic_state *state,
struct drm_plane *plane);
-int drm_atomic_plane_set_property(struct drm_plane *plane,
- struct drm_plane_state *state, struct drm_property *property,
- uint64_t val);
struct drm_connector_state * __must_check
drm_atomic_get_connector_state(struct drm_atomic_state *state,
struct drm_connector *connector);
-int drm_atomic_connector_set_property(struct drm_connector *connector,
- struct drm_connector_state *state, struct drm_property *property,
- uint64_t val);
-void * __must_check
+void drm_atomic_private_obj_init(struct drm_private_obj *obj,
+ struct drm_private_state *state,
+ const struct drm_private_state_funcs *funcs);
+void drm_atomic_private_obj_fini(struct drm_private_obj *obj);
+
+struct drm_private_state * __must_check
drm_atomic_get_private_obj_state(struct drm_atomic_state *state,
- void *obj,
- const struct drm_private_state_funcs *funcs);
+ struct drm_private_obj *obj);
/**
* drm_atomic_get_existing_crtc_state - get crtc state, if it exists
@@ -541,8 +545,6 @@ int __must_check
drm_atomic_add_affected_planes(struct drm_atomic_state *state,
struct drm_crtc *crtc);
-void drm_atomic_legacy_backoff(struct drm_atomic_state *state);
-
void
drm_atomic_clean_old_fb(struct drm_device *dev, unsigned plane_mask, int ret);
@@ -809,43 +811,63 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
for_each_if (plane)
/**
- * __for_each_private_obj - iterate over all private objects
+ * for_each_oldnew_private_obj_in_state - iterate over all private objects in an atomic update
* @__state: &struct drm_atomic_state pointer
- * @obj: private object iteration cursor
- * @obj_state: private object state iteration cursor
+ * @obj: &struct drm_private_obj iteration cursor
+ * @old_obj_state: &struct drm_private_state iteration cursor for the old state
+ * @new_obj_state: &struct drm_private_state iteration cursor for the new state
* @__i: int iteration cursor, for macro-internal use
- * @__funcs: &struct drm_private_state_funcs iteration cursor
*
- * This macro iterates over the array containing private object data in atomic
- * state
+ * This iterates over all private objects in an atomic update, tracking both
+ * old and new state. This is useful in places where the state delta needs
+ * to be considered, for example in atomic check functions.
*/
-#define __for_each_private_obj(__state, obj, obj_state, __i, __funcs) \
- for ((__i) = 0; \
- (__i) < (__state)->num_private_objs && \
- ((obj) = (__state)->private_objs[__i].obj, \
- (__funcs) = (__state)->private_objs[__i].funcs, \
- (obj_state) = (__state)->private_objs[__i].obj_state, \
- 1); \
- (__i)++) \
+#define for_each_oldnew_private_obj_in_state(__state, obj, old_obj_state, new_obj_state, __i) \
+ for ((__i) = 0; \
+ (__i) < (__state)->num_private_objs && \
+ ((obj) = (__state)->private_objs[__i].ptr, \
+ (old_obj_state) = (__state)->private_objs[__i].old_state, \
+ (new_obj_state) = (__state)->private_objs[__i].new_state, 1); \
+ (__i)++) \
+ for_each_if (obj)
/**
- * for_each_private_obj - iterate over a specify type of private object
+ * for_each_old_private_obj_in_state - iterate over all private objects in an atomic update
* @__state: &struct drm_atomic_state pointer
- * @obj_funcs: &struct drm_private_state_funcs function table to filter
- * private objects
- * @obj: private object iteration cursor
- * @obj_state: private object state iteration cursor
+ * @obj: &struct drm_private_obj iteration cursor
+ * @old_obj_state: &struct drm_private_state iteration cursor for the old state
* @__i: int iteration cursor, for macro-internal use
- * @__funcs: &struct drm_private_state_funcs iteration cursor
*
- * This macro iterates over the private objects state array while filtering the
- * objects based on the vfunc table that is passed as @obj_funcs. New macros
- * can be created by passing in the vfunc table associated with a specific
- * private object.
+ * This iterates over all private objects in an atomic update, tracking only
+ * the old state. This is useful in disable functions, where we need the old
+ * state the hardware is still in.
+ */
+#define for_each_old_private_obj_in_state(__state, obj, old_obj_state, __i) \
+ for ((__i) = 0; \
+ (__i) < (__state)->num_private_objs && \
+ ((obj) = (__state)->private_objs[__i].ptr, \
+ (old_obj_state) = (__state)->private_objs[__i].old_state, 1); \
+ (__i)++) \
+ for_each_if (obj)
+
+/**
+ * for_each_new_private_obj_in_state - iterate over all private objects in an atomic update
+ * @__state: &struct drm_atomic_state pointer
+ * @obj: &struct drm_private_obj iteration cursor
+ * @new_obj_state: &struct drm_private_state iteration cursor for the new state
+ * @__i: int iteration cursor, for macro-internal use
+ *
+ * This iterates over all private objects in an atomic update, tracking only
+ * the new state. This is useful in enable functions, where we need the new state the
+ * hardware should be in when the atomic commit operation has completed.
*/
-#define for_each_private_obj(__state, obj_funcs, obj, obj_state, __i, __funcs) \
- __for_each_private_obj(__state, obj, obj_state, __i, __funcs) \
- for_each_if (__funcs == obj_funcs)
+#define for_each_new_private_obj_in_state(__state, obj, new_obj_state, __i) \
+ for ((__i) = 0; \
+ (__i) < (__state)->num_private_objs && \
+ ((obj) = (__state)->private_objs[__i].ptr, \
+ (new_obj_state) = (__state)->private_objs[__i].new_state, 1); \
+ (__i)++) \
+ for_each_if (obj)
/**
* drm_atomic_crtc_needs_modeset - compute combined modeset need
@@ -853,7 +875,7 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
*
* To give drivers flexibility &struct drm_crtc_state has 3 booleans to track
* whether the state CRTC changed enough to need a full modeset cycle:
- * planes_changed, mode_changed and active_changed. This helper simply
+ * mode_changed, active_changed and connectors_changed. This helper simply
* combines these three to compute the overall need for a modeset for @state.
*
* The atomic helper code sets these booleans, but drivers can and should
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index f0a8678ae98e..d2b56cc657e9 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -33,6 +33,8 @@
#include <drm/drm_modeset_helper.h>
struct drm_atomic_state;
+struct drm_private_obj;
+struct drm_private_state;
int drm_atomic_helper_check_modeset(struct drm_device *dev,
struct drm_atomic_state *state);
@@ -41,9 +43,14 @@ int drm_atomic_helper_check_planes(struct drm_device *dev,
int drm_atomic_helper_check(struct drm_device *dev,
struct drm_atomic_state *state);
void drm_atomic_helper_commit_tail(struct drm_atomic_state *state);
+void drm_atomic_helper_commit_tail_rpm(struct drm_atomic_state *state);
int drm_atomic_helper_commit(struct drm_device *dev,
struct drm_atomic_state *state,
bool nonblock);
+int drm_atomic_helper_async_check(struct drm_device *dev,
+ struct drm_atomic_state *state);
+void drm_atomic_helper_async_commit(struct drm_device *dev,
+ struct drm_atomic_state *state);
int drm_atomic_helper_wait_for_fences(struct drm_device *dev,
struct drm_atomic_state *state,
@@ -52,6 +59,9 @@ int drm_atomic_helper_wait_for_fences(struct drm_device *dev,
void drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
struct drm_atomic_state *old_state);
+void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev,
+ struct drm_atomic_state *old_state);
+
void
drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
struct drm_atomic_state *old_state);
@@ -77,8 +87,8 @@ void
drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state,
bool atomic);
-void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
- bool stall);
+int __must_check drm_atomic_helper_swap_state(struct drm_atomic_state *state,
+ bool stall);
/* nonblocking commit helpers */
int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
@@ -114,15 +124,6 @@ int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
int drm_atomic_helper_resume(struct drm_device *dev,
struct drm_atomic_state *state);
-int drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
- struct drm_property *property,
- uint64_t val);
-int drm_atomic_helper_plane_set_property(struct drm_plane *plane,
- struct drm_property *property,
- uint64_t val);
-int drm_atomic_helper_connector_set_property(struct drm_connector *connector,
- struct drm_property *property,
- uint64_t val);
int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
@@ -135,8 +136,6 @@ int drm_atomic_helper_page_flip_target(
uint32_t flags,
uint32_t target,
struct drm_modeset_acquire_ctx *ctx);
-int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
- int mode);
struct drm_encoder *
drm_atomic_helper_best_encoder(struct drm_connector *connector);
@@ -178,6 +177,8 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
u16 *red, u16 *green, u16 *blue,
uint32_t size,
struct drm_modeset_acquire_ctx *ctx);
+void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
+ struct drm_private_state *state);
/**
* drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 1dc94d5392e2..6522d4cbc9d9 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -268,6 +268,9 @@ void drm_bridge_enable(struct drm_bridge *bridge);
struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel,
u32 connector_type);
void drm_panel_bridge_remove(struct drm_bridge *bridge);
+struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev,
+ struct drm_panel *panel,
+ u32 connector_type);
#endif
#endif
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index ae5b7dc316c8..ea8da401c93c 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -135,6 +135,28 @@ struct drm_scdc {
struct drm_hdmi_info {
/** @scdc: sink's scdc support and capabilities */
struct drm_scdc scdc;
+
+ /**
+ * @y420_vdb_modes: bitmap of modes which can support ycbcr420
+ * output only (not normal RGB/YCBCR444/422 outputs). There are total
+ * 107 VICs defined by CEA-861-F spec, so the size is 128 bits to map
+ * upto 128 VICs;
+ */
+ unsigned long y420_vdb_modes[BITS_TO_LONGS(128)];
+
+ /**
+ * @y420_cmdb_modes: bitmap of modes which can support ycbcr420
+ * output also, along with normal HDMI outputs. There are total 107
+ * VICs defined by CEA-861-F spec, so the size is 128 bits to map upto
+ * 128 VICs;
+ */
+ unsigned long y420_cmdb_modes[BITS_TO_LONGS(128)];
+
+ /** @y420_cmdb_map: bitmap of SVD index, to extraxt vcb modes */
+ u64 y420_cmdb_map;
+
+ /** @y420_dc_modes: bitmap of deep color support index */
+ u8 y420_dc_modes;
};
/**
@@ -198,6 +220,7 @@ struct drm_display_info {
#define DRM_COLOR_FORMAT_RGB444 (1<<0)
#define DRM_COLOR_FORMAT_YCRCB444 (1<<1)
#define DRM_COLOR_FORMAT_YCRCB422 (1<<2)
+#define DRM_COLOR_FORMAT_YCRCB420 (1<<3)
/**
* @color_formats: HDMI Color formats, selects between RGB and YCrCb
@@ -359,8 +382,8 @@ struct drm_connector_funcs {
* implement the 4 level DPMS support on the connector any more, but
* instead only have an on/off "ACTIVE" property on the CRTC object.
*
- * Drivers implementing atomic modeset should use
- * drm_atomic_helper_connector_dpms() to implement this hook.
+ * This hook is not used by atomic drivers, remapping of the legacy DPMS
+ * property is entirely handled in the DRM core.
*
* RETURNS:
*
@@ -457,11 +480,9 @@ struct drm_connector_funcs {
* This is the legacy entry point to update a property attached to the
* connector.
*
- * Drivers implementing atomic modeset should use
- * drm_atomic_helper_connector_set_property() to implement this hook.
- *
* This callback is optional if the driver does not support any legacy
- * driver-private properties.
+ * driver-private properties. For atomic drivers it is not used because
+ * property handling is done entirely in the DRM core.
*
* RETURNS:
*
@@ -726,6 +747,15 @@ struct drm_connector {
bool interlace_allowed;
bool doublescan_allowed;
bool stereo_allowed;
+
+ /**
+ * @ycbcr_420_allowed : This bool indicates if this connector is
+ * capable of handling YCBCR 420 output. While parsing the EDID
+ * blocks, its very helpful to know, if the source is capable of
+ * handling YCBCR 420 outputs.
+ */
+ bool ycbcr_420_allowed;
+
/**
* @registered: Is this connector exposed (registered) with userspace?
* Protected by @mutex.
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 629a5fe075b3..1a642020e306 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -358,14 +358,6 @@ struct drm_crtc_funcs {
* drm_crtc_enable_color_mgmt(), which then supports the legacy gamma
* interface through the drm_atomic_helper_legacy_gamma_set()
* compatibility implementation.
- *
- * NOTE:
- *
- * Drivers that support gamma tables and also fbdev emulation through
- * the provided helper library need to take care to fill out the gamma
- * hooks for both. Currently there's a bit an unfortunate duplication
- * going on, which should eventually be unified to just one set of
- * hooks.
*/
int (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
uint32_t size,
@@ -481,11 +473,9 @@ struct drm_crtc_funcs {
* This is the legacy entry point to update a property attached to the
* CRTC.
*
- * Drivers implementing atomic modeset should use
- * drm_atomic_helper_crtc_set_property() to implement this hook.
- *
* This callback is optional if the driver does not support any legacy
- * driver-private properties.
+ * driver-private properties. For atomic drivers it is not used because
+ * property handling is done entirely in the DRM core.
*
* RETURNS:
*
@@ -685,6 +675,9 @@ struct drm_crtc_funcs {
* drm_crtc_vblank_off() and drm_crtc_vblank_on() when disabling or
* enabling a CRTC.
*
+ * See also &drm_device.vblank_disable_immediate and
+ * &drm_device.max_vblank_count.
+ *
* Returns:
*
* Raw vblank counter value.
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
new file mode 100644
index 000000000000..e21af87a2f3c
--- /dev/null
+++ b/include/drm/drm_device.h
@@ -0,0 +1,190 @@
+#ifndef _DRM_DEVICE_H_
+#define _DRM_DEVICE_H_
+
+#include <linux/list.h>
+#include <linux/kref.h>
+#include <linux/mutex.h>
+#include <linux/idr.h>
+
+#include <drm/drm_hashtab.h>
+#include <drm/drm_mode_config.h>
+
+struct drm_driver;
+struct drm_minor;
+struct drm_master;
+struct drm_device_dma;
+struct drm_vblank_crtc;
+struct drm_sg_mem;
+struct drm_local_map;
+struct drm_vma_offset_manager;
+
+struct inode;
+
+struct pci_dev;
+struct pci_controller;
+
+/**
+ * DRM device structure. This structure represent a complete card that
+ * may contain multiple heads.
+ */
+struct drm_device {
+ struct list_head legacy_dev_list;/**< list of devices per driver for stealth attach cleanup */
+ int if_version; /**< Highest interface version set */
+
+ /** \name Lifetime Management */
+ /*@{ */
+ struct kref ref; /**< Object ref-count */
+ struct device *dev; /**< Device structure of bus-device */
+ struct drm_driver *driver; /**< DRM driver managing the device */
+ void *dev_private; /**< DRM driver private data */
+ struct drm_minor *control; /**< Control node */
+ struct drm_minor *primary; /**< Primary node */
+ struct drm_minor *render; /**< Render node */
+ bool registered;
+
+ /* currently active master for this device. Protected by master_mutex */
+ struct drm_master *master;
+
+ atomic_t unplugged; /**< Flag whether dev is dead */
+ struct inode *anon_inode; /**< inode for private address-space */
+ char *unique; /**< unique name of the device */
+ /*@} */
+
+ /** \name Locks */
+ /*@{ */
+ struct mutex struct_mutex; /**< For others */
+ struct mutex master_mutex; /**< For drm_minor::master and drm_file::is_master */
+ /*@} */
+
+ /** \name Usage Counters */
+ /*@{ */
+ int open_count; /**< Outstanding files open, protected by drm_global_mutex. */
+ spinlock_t buf_lock; /**< For drm_device::buf_use and a few other things. */
+ int buf_use; /**< Buffers in use -- cannot alloc */
+ atomic_t buf_alloc; /**< Buffer allocation in progress */
+ /*@} */
+
+ struct mutex filelist_mutex;
+ struct list_head filelist;
+
+ /** \name Memory management */
+ /*@{ */
+ struct list_head maplist; /**< Linked list of regions */
+ struct drm_open_hash map_hash; /**< User token hash table for maps */
+
+ /** \name Context handle management */
+ /*@{ */
+ struct list_head ctxlist; /**< Linked list of context handles */
+ struct mutex ctxlist_mutex; /**< For ctxlist */
+
+ struct idr ctx_idr;
+
+ struct list_head vmalist; /**< List of vmas (for debugging) */
+
+ /*@} */
+
+ /** \name DMA support */
+ /*@{ */
+ struct drm_device_dma *dma; /**< Optional pointer for DMA support */
+ /*@} */
+
+ /** \name Context support */
+ /*@{ */
+
+ __volatile__ long context_flag; /**< Context swapping flag */
+ int last_context; /**< Last current context */
+ /*@} */
+
+ /**
+ * @irq_enabled:
+ *
+ * Indicates that interrupt handling is enabled, specifically vblank
+ * handling. Drivers which don't use drm_irq_install() need to set this
+ * to true manually.
+ */
+ bool irq_enabled;
+ int irq;
+
+ /**
+ * @vblank_disable_immediate:
+ *
+ * If true, vblank interrupt will be disabled immediately when the
+ * refcount drops to zero, as opposed to via the vblank disable
+ * timer.
+ *
+ * This can be set to true it the hardware has a working vblank counter
+ * with high-precision timestamping (otherwise there are races) and the
+ * driver uses drm_crtc_vblank_on() and drm_crtc_vblank_off()
+ * appropriately. See also @max_vblank_count and
+ * &drm_crtc_funcs.get_vblank_counter.
+ */
+ bool vblank_disable_immediate;
+
+ /**
+ * @vblank:
+ *
+ * Array of vblank tracking structures, one per &struct drm_crtc. For
+ * historical reasons (vblank support predates kernel modesetting) this
+ * is free-standing and not part of &struct drm_crtc itself. It must be
+ * initialized explicitly by calling drm_vblank_init().
+ */
+ struct drm_vblank_crtc *vblank;
+
+ spinlock_t vblank_time_lock; /**< Protects vblank count and time updates during vblank enable/disable */
+ spinlock_t vbl_lock;
+
+ /**
+ * @max_vblank_count:
+ *
+ * Maximum value of the vblank registers. This value +1 will result in a
+ * wrap-around of the vblank register. It is used by the vblank core to
+ * handle wrap-arounds.
+ *
+ * If set to zero the vblank core will try to guess the elapsed vblanks
+ * between times when the vblank interrupt is disabled through
+ * high-precision timestamps. That approach is suffering from small
+ * races and imprecision over longer time periods, hence exposing a
+ * hardware vblank counter is always recommended.
+ *
+ * If non-zeor, &drm_crtc_funcs.get_vblank_counter must be set.
+ */
+ u32 max_vblank_count; /**< size of vblank counter register */
+
+ /**
+ * List of events
+ */
+ struct list_head vblank_event_list;
+ spinlock_t event_lock;
+
+ /*@} */
+
+ struct drm_agp_head *agp; /**< AGP data */
+
+ struct pci_dev *pdev; /**< PCI device structure */
+#ifdef __alpha__
+ struct pci_controller *hose;
+#endif
+
+ struct drm_sg_mem *sg; /**< Scatter gather memory */
+ unsigned int num_crtcs; /**< Number of CRTCs on this device */
+
+ struct {
+ int context;
+ struct drm_hw_lock *lock;
+ } sigdata;
+
+ struct drm_local_map *agp_buffer_map;
+ unsigned int agp_buffer_token;
+
+ struct drm_mode_config mode_config; /**< Current mode config */
+
+ /** \name GEM information */
+ /*@{ */
+ struct mutex object_name_lock;
+ struct idr object_name_idr;
+ struct drm_vma_offset_manager *vma_offset_manager;
+ /*@} */
+ int switch_power_state;
+};
+
+#endif
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index 177ab6f86855..d55abb75f29a 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -404,12 +404,17 @@ struct drm_dp_payload {
int vcpi;
};
+#define to_dp_mst_topology_state(x) container_of(x, struct drm_dp_mst_topology_state, base)
+
struct drm_dp_mst_topology_state {
+ struct drm_private_state base;
int avail_slots;
struct drm_atomic_state *state;
struct drm_dp_mst_topology_mgr *mgr;
};
+#define to_dp_mst_topology_mgr(x) container_of(x, struct drm_dp_mst_topology_mgr, base)
+
/**
* struct drm_dp_mst_topology_mgr - DisplayPort MST manager
*
@@ -419,6 +424,11 @@ struct drm_dp_mst_topology_state {
*/
struct drm_dp_mst_topology_mgr {
/**
+ * @base: Base private object for atomic
+ */
+ struct drm_private_obj base;
+
+ /**
* @dev: device pointer for adding i2c devices etc.
*/
struct drm_device *dev;
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index d855f9ae41a8..71bbaaec836d 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -30,7 +30,8 @@
#include <linux/list.h>
#include <linux/irqreturn.h>
-struct drm_device;
+#include <drm/drm_device.h>
+
struct drm_file;
struct drm_gem_object;
struct drm_master;
@@ -173,8 +174,6 @@ struct drm_driver {
*/
void (*release) (struct drm_device *);
- int (*set_busid)(struct drm_device *dev, struct drm_master *master);
-
/**
* @get_vblank_counter:
*
@@ -392,6 +391,11 @@ struct drm_driver {
*/
void (*master_drop)(struct drm_device *dev, struct drm_file *file_priv);
+ /**
+ * @debugfs_init:
+ *
+ * Allows drivers to create driver-specific debugfs files.
+ */
int (*debugfs_init)(struct drm_minor *minor);
/**
@@ -410,7 +414,18 @@ struct drm_driver {
*/
void (*gem_free_object_unlocked) (struct drm_gem_object *obj);
+ /**
+ * @gem_open_object:
+ *
+ * Driver hook called upon gem handle creation
+ */
int (*gem_open_object) (struct drm_gem_object *, struct drm_file *);
+
+ /**
+ * @gem_close_object:
+ *
+ * Driver hook called upon gem handle release
+ */
void (*gem_close_object) (struct drm_gem_object *, struct drm_file *);
/**
@@ -423,19 +438,34 @@ struct drm_driver {
size_t size);
/* prime: */
- /* export handle -> fd (see drm_gem_prime_handle_to_fd() helper) */
+ /**
+ * @prime_handle_to_fd:
+ *
+ * export handle -> fd (see drm_gem_prime_handle_to_fd() helper)
+ */
int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file *file_priv,
uint32_t handle, uint32_t flags, int *prime_fd);
- /* import fd -> handle (see drm_gem_prime_fd_to_handle() helper) */
+ /**
+ * @prime_fd_to_handle:
+ *
+ * import fd -> handle (see drm_gem_prime_fd_to_handle() helper)
+ */
int (*prime_fd_to_handle)(struct drm_device *dev, struct drm_file *file_priv,
int prime_fd, uint32_t *handle);
- /* export GEM -> dmabuf */
+ /**
+ * @gem_prime_export:
+ *
+ * export GEM -> dmabuf
+ */
struct dma_buf * (*gem_prime_export)(struct drm_device *dev,
struct drm_gem_object *obj, int flags);
- /* import dmabuf -> GEM */
+ /**
+ * @gem_prime_import:
+ *
+ * import dmabuf -> GEM
+ */
struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev,
struct dma_buf *dma_buf);
- /* low-level interface used by drm_gem_prime_{import,export} */
int (*gem_prime_pin)(struct drm_gem_object *obj);
void (*gem_prime_unpin)(struct drm_gem_object *obj);
struct reservation_object * (*gem_prime_res_obj)(
@@ -507,19 +537,46 @@ struct drm_driver {
struct drm_device *dev,
uint32_t handle);
- /* Driver private ops for this object */
+ /**
+ * @gem_vm_ops: Driver private ops for this object
+ */
const struct vm_operations_struct *gem_vm_ops;
+ /** @major: driver major number */
int major;
+ /** @minor: driver minor number */
int minor;
+ /** @patchlevel: driver patch level */
int patchlevel;
+ /** @name: driver name */
char *name;
+ /** @desc: driver description */
char *desc;
+ /** @date: driver date */
char *date;
+ /** @driver_features: driver features */
u32 driver_features;
+
+ /**
+ * @ioctls:
+ *
+ * Array of driver-private IOCTL description entries. See the chapter on
+ * :ref:`IOCTL support in the userland interfaces
+ * chapter<drm_driver_ioctl>` for the full details.
+ */
+
const struct drm_ioctl_desc *ioctls;
+ /** @num_ioctls: Number of entries in @ioctls. */
int num_ioctls;
+
+ /**
+ * @fops:
+ *
+ * File operations for the DRM device node. See the discussion in
+ * :ref:`file operations<drm_driver_fops>` for in-depth coverage and
+ * some examples.
+ */
const struct file_operations *fops;
/* Everything below here is for legacy driver, never use! */
@@ -557,7 +614,24 @@ void drm_dev_unregister(struct drm_device *dev);
void drm_dev_ref(struct drm_device *dev);
void drm_dev_unref(struct drm_device *dev);
void drm_put_dev(struct drm_device *dev);
-void drm_unplug_dev(struct drm_device *dev);
+void drm_dev_unplug(struct drm_device *dev);
+
+/**
+ * drm_dev_is_unplugged - is a DRM device unplugged
+ * @dev: DRM device
+ *
+ * This function can be called to check whether a hotpluggable is unplugged.
+ * Unplugging itself is singalled through drm_dev_unplug(). If a device is
+ * unplugged, these two functions guarantee that any store before calling
+ * drm_dev_unplug() is visible to callers of this function after it completes
+ */
+static inline int drm_dev_is_unplugged(struct drm_device *dev)
+{
+ int ret = atomic_read(&dev->unplugged);
+ smp_rmb();
+ return ret;
+}
+
int drm_dev_set_unique(struct drm_device *dev, const char *name);
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 7b9f48b62e07..1e1908a6b1d6 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -213,6 +213,14 @@ struct detailed_timing {
#define DRM_EDID_HDMI_DC_30 (1 << 4)
#define DRM_EDID_HDMI_DC_Y444 (1 << 3)
+/* YCBCR 420 deep color modes */
+#define DRM_EDID_YCBCR420_DC_48 (1 << 6)
+#define DRM_EDID_YCBCR420_DC_36 (1 << 5)
+#define DRM_EDID_YCBCR420_DC_30 (1 << 4)
+#define DRM_EDID_YCBCR420_DC_MASK (DRM_EDID_YCBCR420_DC_48 | \
+ DRM_EDID_YCBCR420_DC_36 | \
+ DRM_EDID_YCBCR420_DC_30)
+
/* ELD Header Block */
#define DRM_ELD_HEADER_BLOCK_SIZE 4
@@ -343,7 +351,8 @@ drm_load_edid_firmware(struct drm_connector *connector)
int
drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
- const struct drm_display_mode *mode);
+ const struct drm_display_mode *mode,
+ bool is_hdmi2_sink);
int
drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
const struct drm_display_mode *mode);
diff --git a/include/drm/drm_fb_cma_helper.h b/include/drm/drm_fb_cma_helper.h
index 199a63f48659..a323781afc3f 100644
--- a/include/drm/drm_fb_cma_helper.h
+++ b/include/drm/drm_fb_cma_helper.h
@@ -24,9 +24,9 @@ void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma);
void drm_fbdev_cma_restore_mode(struct drm_fbdev_cma *fbdev_cma);
void drm_fbdev_cma_hotplug_event(struct drm_fbdev_cma *fbdev_cma);
-void drm_fbdev_cma_set_suspend(struct drm_fbdev_cma *fbdev_cma, int state);
+void drm_fbdev_cma_set_suspend(struct drm_fbdev_cma *fbdev_cma, bool state);
void drm_fbdev_cma_set_suspend_unlocked(struct drm_fbdev_cma *fbdev_cma,
- int state);
+ bool state);
void drm_fb_cma_destroy(struct drm_framebuffer *fb);
int drm_fb_cma_create_handle(struct drm_framebuffer *fb,
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 119e5e4609c7..33fe95927742 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -85,38 +85,6 @@ struct drm_fb_helper_surface_size {
*/
struct drm_fb_helper_funcs {
/**
- * @gamma_set:
- *
- * Set the given gamma LUT register on the given CRTC.
- *
- * This callback is optional.
- *
- * FIXME:
- *
- * This callback is functionally redundant with the core gamma table
- * support and simply exists because the fbdev hasn't yet been
- * refactored to use the core gamma table interfaces.
- */
- void (*gamma_set)(struct drm_crtc *crtc, u16 red, u16 green,
- u16 blue, int regno);
- /**
- * @gamma_get:
- *
- * Read the given gamma LUT register on the given CRTC, used to save the
- * current LUT when force-restoring the fbdev for e.g. kdbg.
- *
- * This callback is optional.
- *
- * FIXME:
- *
- * This callback is functionally redundant with the core gamma table
- * support and simply exists because the fbdev hasn't yet been
- * refactored to use the core gamma table interfaces.
- */
- void (*gamma_get)(struct drm_crtc *crtc, u16 *red, u16 *green,
- u16 *blue, int regno);
-
- /**
* @fb_probe:
*
* Driver callback to allocate and initialize the fbdev info structure.
@@ -169,7 +137,6 @@ struct drm_fb_helper_connector {
* @crtc_info: per-CRTC helper state (mode, x/y offset, etc)
* @connector_count: number of connected connectors
* @connector_info_alloc_count: size of connector_info
- * @connector_info: array of per-connector information
* @funcs: driver callbacks for fb helper
* @fbdev: emulated fbdev device info struct
* @pseudo_palette: fake palette of 16 colors
@@ -191,6 +158,12 @@ struct drm_fb_helper {
struct drm_fb_helper_crtc *crtc_info;
int connector_count;
int connector_info_alloc_count;
+ /**
+ * @connector_info:
+ *
+ * Array of per-connector information. Do not iterate directly, but use
+ * drm_fb_helper_for_each_connector.
+ */
struct drm_fb_helper_connector **connector_info;
const struct drm_fb_helper_funcs *funcs;
struct fb_info *fbdev;
@@ -201,6 +174,18 @@ struct drm_fb_helper {
struct work_struct resume_work;
/**
+ * @lock:
+ *
+ * Top-level FBDEV helper lock. This protects all internal data
+ * structures and lists, such as @connector_info and @crtc_info.
+ *
+ * FIXME: fbdev emulation locking is a mess and long term we want to
+ * protect all helper internal state with this lock as well as reduce
+ * core KMS locking as much as possible.
+ */
+ struct mutex lock;
+
+ /**
* @kernel_fb_list:
*
* Entry on the global kernel_fb_helper_list, used for kgdb entry/exit.
@@ -215,6 +200,29 @@ struct drm_fb_helper {
* needs to be reprobe when fbdev is in control again.
*/
bool delayed_hotplug;
+
+ /**
+ * @deferred_setup:
+ *
+ * If no outputs are connected (disconnected or unknown) the FB helper
+ * code will defer setup until at least one of the outputs shows up.
+ * This field keeps track of the status so that setup can be retried
+ * at every hotplug event until it succeeds eventually.
+ *
+ * Protected by @lock.
+ */
+ bool deferred_setup;
+
+ /**
+ * @preferred_bpp:
+ *
+ * Temporary storage for the driver's preferred BPP setting passed to
+ * FB helper initialization. This needs to be tracked so that deferred
+ * FB helper setup can pass this on.
+ *
+ * See also: @deferred_setup
+ */
+ int preferred_bpp;
};
/**
diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
index 5244f059d23a..b6996ddb19d6 100644
--- a/include/drm/drm_framebuffer.h
+++ b/include/drm/drm_framebuffer.h
@@ -190,6 +190,13 @@ struct drm_framebuffer {
* @filp_head: Placed on &drm_file.fbs, protected by &drm_file.fbs_lock.
*/
struct list_head filp_head;
+ /**
+ * @obj: GEM objects backing the framebuffer, one per plane (optional).
+ *
+ * This is used by the GEM framebuffer helpers, see e.g.
+ * drm_gem_fb_create().
+ */
+ struct drm_gem_object *obj[4];
};
#define obj_to_fb(x) container_of(x, struct drm_framebuffer, base)
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index 663d80358057..9c55c2acaa2b 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -131,21 +131,6 @@ struct drm_gem_object {
uint32_t write_domain;
/**
- * @pending_read_domains:
- *
- * While validating an exec operation, the
- * new read/write domain values are computed here.
- * They will be transferred to the above values
- * at the point that any cache flushing occurs
- */
- uint32_t pending_read_domains;
-
- /**
- * @pending_write_domain: Write domain similar to @pending_read_domains.
- */
- uint32_t pending_write_domain;
-
- /**
* @dma_buf:
*
* dma-buf associated with this GEM object.
@@ -317,6 +302,8 @@ void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages,
bool dirty, bool accessed);
struct drm_gem_object *drm_gem_object_lookup(struct drm_file *filp, u32 handle);
+int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
+ u32 handle, u64 *offset);
int drm_gem_dumb_destroy(struct drm_file *file,
struct drm_device *dev,
uint32_t handle);
diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h
index b42529e0fae0..58a739bf15f1 100644
--- a/include/drm/drm_gem_cma_helper.h
+++ b/include/drm/drm_gem_cma_helper.h
@@ -73,11 +73,6 @@ int drm_gem_cma_dumb_create(struct drm_file *file_priv,
struct drm_device *drm,
struct drm_mode_create_dumb *args);
-/* map memory region for DRM framebuffer to user space */
-int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv,
- struct drm_device *drm, u32 handle,
- u64 *offset);
-
/* set vm_flags and we can change the VM attribute to other one at here */
int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma);
diff --git a/include/drm/drm_gem_framebuffer_helper.h b/include/drm/drm_gem_framebuffer_helper.h
new file mode 100644
index 000000000000..db9cfa07235e
--- /dev/null
+++ b/include/drm/drm_gem_framebuffer_helper.h
@@ -0,0 +1,37 @@
+#ifndef __DRM_GEM_FB_HELPER_H__
+#define __DRM_GEM_FB_HELPER_H__
+
+struct drm_device;
+struct drm_file;
+struct drm_fb_helper_surface_size;
+struct drm_framebuffer;
+struct drm_framebuffer_funcs;
+struct drm_gem_object;
+struct drm_mode_fb_cmd2;
+struct drm_plane;
+struct drm_plane_state;
+
+struct drm_gem_object *drm_gem_fb_get_obj(struct drm_framebuffer *fb,
+ unsigned int plane);
+void drm_gem_fb_destroy(struct drm_framebuffer *fb);
+int drm_gem_fb_create_handle(struct drm_framebuffer *fb, struct drm_file *file,
+ unsigned int *handle);
+
+struct drm_framebuffer *
+drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
+ const struct drm_mode_fb_cmd2 *mode_cmd,
+ const struct drm_framebuffer_funcs *funcs);
+struct drm_framebuffer *
+drm_gem_fb_create(struct drm_device *dev, struct drm_file *file,
+ const struct drm_mode_fb_cmd2 *mode_cmd);
+
+int drm_gem_fb_prepare_fb(struct drm_plane *plane,
+ struct drm_plane_state *state);
+
+struct drm_framebuffer *
+drm_gem_fbdev_fb_create(struct drm_device *dev,
+ struct drm_fb_helper_surface_size *sizes,
+ unsigned int pitch_align, struct drm_gem_object *obj,
+ const struct drm_framebuffer_funcs *funcs);
+
+#endif
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 42981711189b..1b37368416c8 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -757,6 +757,12 @@ struct drm_mode_config {
*/
bool allow_fb_modifiers;
+ /**
+ * @modifiers: Plane property to list support modifier/format
+ * combination.
+ */
+ struct drm_property *modifiers_property;
+
/* cursor size */
uint32_t cursor_width, cursor_height;
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
index 94ac771fe460..9f3421c8efcd 100644
--- a/include/drm/drm_modes.h
+++ b/include/drm/drm_modes.h
@@ -80,6 +80,7 @@ struct videomode;
* @MODE_ONE_SIZE: only one resolution is supported
* @MODE_NO_REDUCED: monitor doesn't accept reduced blanking
* @MODE_NO_STEREO: stereo modes not supported
+ * @MODE_NO_420: ycbcr 420 modes not supported
* @MODE_STALE: mode has become stale
* @MODE_BAD: unspecified reason
* @MODE_ERROR: error condition
@@ -124,6 +125,7 @@ enum drm_mode_status {
MODE_ONE_SIZE,
MODE_NO_REDUCED,
MODE_NO_STEREO,
+ MODE_NO_420,
MODE_STALE = -3,
MODE_BAD = -2,
MODE_ERROR = -1
@@ -450,6 +452,12 @@ int drm_mode_convert_umode(struct drm_display_mode *out,
const struct drm_mode_modeinfo *in);
void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode);
void drm_mode_debug_printmodeline(const struct drm_display_mode *mode);
+bool drm_mode_is_420_only(const struct drm_display_info *display,
+ const struct drm_display_mode *mode);
+bool drm_mode_is_420_also(const struct drm_display_info *display,
+ const struct drm_display_mode *mode);
+bool drm_mode_is_420(const struct drm_display_info *display,
+ const struct drm_display_mode *mode);
struct drm_display_mode *drm_cvt_mode(struct drm_device *dev,
int hdisplay, int vdisplay, int vrefresh,
@@ -496,6 +504,9 @@ bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
enum drm_mode_status drm_mode_validate_basic(const struct drm_display_mode *mode);
enum drm_mode_status drm_mode_validate_size(const struct drm_display_mode *mode,
int maxX, int maxY);
+enum drm_mode_status
+drm_mode_validate_ycbcr420(const struct drm_display_mode *mode,
+ struct drm_connector *connector);
void drm_mode_prune_invalid(struct drm_device *dev,
struct list_head *mode_list, bool verbose);
void drm_mode_sort(struct list_head *mode_list);
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index 85984b208218..c55cf3ff6847 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -71,7 +71,7 @@ struct drm_crtc_helper_funcs {
* This callback is used by the legacy CRTC helpers. Atomic helpers
* also support using this hook for enabling and disabling a CRTC to
* facilitate transitions to atomic, but it is deprecated. Instead
- * @enable and @disable should be used.
+ * @atomic_enable and @atomic_disable should be used.
*/
void (*dpms)(struct drm_crtc *crtc, int mode);
@@ -85,8 +85,8 @@ struct drm_crtc_helper_funcs {
*
* This callback is used by the legacy CRTC helpers. Atomic helpers
* also support using this hook for disabling a CRTC to facilitate
- * transitions to atomic, but it is deprecated. Instead @disable should
- * be used.
+ * transitions to atomic, but it is deprecated. Instead @atomic_disable
+ * should be used.
*/
void (*prepare)(struct drm_crtc *crtc);
@@ -100,8 +100,8 @@ struct drm_crtc_helper_funcs {
*
* This callback is used by the legacy CRTC helpers. Atomic helpers
* also support using this hook for enabling a CRTC to facilitate
- * transitions to atomic, but it is deprecated. Instead @enable should
- * be used.
+ * transitions to atomic, but it is deprecated. Instead @atomic_enable
+ * should be used.
*/
void (*commit)(struct drm_crtc *crtc);
@@ -222,7 +222,7 @@ struct drm_crtc_helper_funcs {
* pipeline is suspended using either DPMS or the new "ACTIVE" property.
* Which means register values set in this callback might get reset when
* the CRTC is suspended, but not restored. Such drivers should instead
- * move all their CRTC setup into the @enable callback.
+ * move all their CRTC setup into the @atomic_enable callback.
*
* This callback is optional.
*/
@@ -267,22 +267,6 @@ struct drm_crtc_helper_funcs {
enum mode_set_atomic);
/**
- * @load_lut:
- *
- * Load a LUT prepared with the &drm_fb_helper_funcs.gamma_set vfunc.
- *
- * This callback is optional and is only used by the fbdev emulation
- * helpers.
- *
- * FIXME:
- *
- * This callback is functionally redundant with the core gamma table
- * support and simply exists because the fbdev hasn't yet been
- * refactored to use the core gamma table interfaces.
- */
- void (*load_lut)(struct drm_crtc *crtc);
-
- /**
* @disable:
*
* This callback should be used to disable the CRTC. With the atomic
@@ -297,7 +281,7 @@ struct drm_crtc_helper_funcs {
* Atomic drivers don't need to implement it if there's no need to
* disable anything at the CRTC level. To ensure that runtime PM
* handling (using either DPMS or the new "ACTIVE" property) works
- * @disable must be the inverse of @enable for atomic drivers.
+ * @disable must be the inverse of @atomic_enable for atomic drivers.
* Atomic drivers should consider to use @atomic_disable instead of
* this one.
*
@@ -316,24 +300,6 @@ struct drm_crtc_helper_funcs {
void (*disable)(struct drm_crtc *crtc);
/**
- * @enable:
- *
- * This callback should be used to enable the CRTC. With the atomic
- * drivers it is called before all encoders connected to this CRTC are
- * enabled through the encoder's own &drm_encoder_helper_funcs.enable
- * hook. If that sequence is too simple drivers can just add their own
- * hooks and call it from this CRTC callback here by looping over all
- * encoders connected to it using for_each_encoder_on_crtc().
- *
- * This hook is used only by atomic helpers, for symmetry with @disable.
- * Atomic drivers don't need to implement it if there's no need to
- * enable anything at the CRTC level. To ensure that runtime PM handling
- * (using either DPMS or the new "ACTIVE" property) works
- * @enable must be the inverse of @disable for atomic drivers.
- */
- void (*enable)(struct drm_crtc *crtc);
-
- /**
* @atomic_check:
*
* Drivers should check plane-update related CRTC constraints in this
@@ -433,6 +399,30 @@ struct drm_crtc_helper_funcs {
struct drm_crtc_state *old_crtc_state);
/**
+ * @atomic_enable:
+ *
+ * This callback should be used to enable the CRTC. With the atomic
+ * drivers it is called before all encoders connected to this CRTC are
+ * enabled through the encoder's own &drm_encoder_helper_funcs.enable
+ * hook. If that sequence is too simple drivers can just add their own
+ * hooks and call it from this CRTC callback here by looping over all
+ * encoders connected to it using for_each_encoder_on_crtc().
+ *
+ * This hook is used only by atomic helpers, for symmetry with
+ * @atomic_disable. Atomic drivers don't need to implement it if there's
+ * no need to enable anything at the CRTC level. To ensure that runtime
+ * PM handling (using either DPMS or the new "ACTIVE" property) works
+ * @atomic_enable must be the inverse of @atomic_disable for atomic
+ * drivers.
+ *
+ * Drivers can use the @old_crtc_state input parameter if the operations
+ * needed to enable the CRTC don't depend solely on the new state but
+ * also on the transition between the old state and the new state.
+ */
+ void (*atomic_enable)(struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state);
+
+ /**
* @atomic_disable:
*
* This callback should be used to disable the CRTC. With the atomic
@@ -1129,6 +1119,56 @@ struct drm_plane_helper_funcs {
*/
void (*atomic_disable)(struct drm_plane *plane,
struct drm_plane_state *old_state);
+
+ /**
+ * @atomic_async_check:
+ *
+ * Drivers should set this function pointer to check if the plane state
+ * can be updated in a async fashion. Here async means "not vblank
+ * synchronized".
+ *
+ * This hook is called by drm_atomic_async_check() to establish if a
+ * given update can be committed asynchronously, that is, if it can
+ * jump ahead of the state currently queued for update.
+ *
+ * RETURNS:
+ *
+ * Return 0 on success and any error returned indicates that the update
+ * can not be applied in asynchronous manner.
+ */
+ int (*atomic_async_check)(struct drm_plane *plane,
+ struct drm_plane_state *state);
+
+ /**
+ * @atomic_async_update:
+ *
+ * Drivers should set this function pointer to perform asynchronous
+ * updates of planes, that is, jump ahead of the currently queued
+ * state and update the plane. Here async means "not vblank
+ * synchronized".
+ *
+ * This hook is called by drm_atomic_helper_async_commit().
+ *
+ * An async update will happen on legacy cursor updates. An async
+ * update won't happen if there is an outstanding commit modifying
+ * the same plane.
+ *
+ * Note that unlike &drm_plane_helper_funcs.atomic_update this hook
+ * takes the new &drm_plane_state as parameter. When doing async_update
+ * drivers shouldn't replace the &drm_plane_state but update the
+ * current one with the new plane configurations in the new
+ * plane_state.
+ *
+ * FIXME:
+ * - It only works for single plane updates
+ * - Async Pageflips are not supported yet
+ * - Some hw might still scan out the old buffer until the next
+ * vblank, however we let go of the fb references as soon as
+ * we run this hook. For now drivers must implement their own workers
+ * for deferring if needed, until a common solution is created.
+ */
+ void (*atomic_async_update)(struct drm_plane *plane,
+ struct drm_plane_state *new_state);
};
/**
@@ -1169,7 +1209,8 @@ struct drm_mode_config_helper_funcs {
* After the atomic update is committed to the hardware this hook needs
* to call drm_atomic_helper_commit_hw_done(). Then wait for the upate
* to be executed by the hardware, for example using
- * drm_atomic_helper_wait_for_vblanks(), and then clean up the old
+ * drm_atomic_helper_wait_for_vblanks() or
+ * drm_atomic_helper_wait_for_flip_done(), and then clean up the old
* framebuffers using drm_atomic_helper_cleanup_planes().
*
* When disabling a CRTC this hook _must_ stall for the commit to
diff --git a/include/drm/drm_pci.h b/include/drm/drm_pci.h
index 4579fac1080c..674599025d7d 100644
--- a/include/drm/drm_pci.h
+++ b/include/drm/drm_pci.h
@@ -43,13 +43,12 @@ struct drm_dma_handle *drm_pci_alloc(struct drm_device *dev, size_t size,
size_t align);
void drm_pci_free(struct drm_device *dev, struct drm_dma_handle * dmah);
-int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver);
-void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver);
+int drm_legacy_pci_init(struct drm_driver *driver, struct pci_driver *pdriver);
+void drm_legacy_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver);
#ifdef CONFIG_PCI
int drm_get_pci_dev(struct pci_dev *pdev,
const struct pci_device_id *ent,
struct drm_driver *driver);
-int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master);
#else
static inline int drm_get_pci_dev(struct pci_dev *pdev,
const struct pci_device_id *ent,
@@ -57,12 +56,6 @@ static inline int drm_get_pci_dev(struct pci_dev *pdev,
{
return -ENOSYS;
}
-
-static inline int drm_pci_set_busid(struct drm_device *dev,
- struct drm_master *master)
-{
- return -ENOSYS;
-}
#endif
#define DRM_PCIE_SPEED_25 1
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 9ab3e7044812..73f90f9d057f 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -233,11 +233,9 @@ struct drm_plane_funcs {
* This is the legacy entry point to update a property attached to the
* plane.
*
- * Drivers implementing atomic modeset should use
- * drm_atomic_helper_plane_set_property() to implement this hook.
- *
* This callback is optional if the driver does not support any legacy
- * driver-private properties.
+ * driver-private properties. For atomic drivers it is not used because
+ * property handling is done entirely in the DRM core.
*
* RETURNS:
*
@@ -392,6 +390,22 @@ struct drm_plane_funcs {
*/
void (*atomic_print_state)(struct drm_printer *p,
const struct drm_plane_state *state);
+
+ /**
+ * @format_mod_supported:
+ *
+ * This optional hook is used for the DRM to determine if the given
+ * format/modifier combination is valid for the plane. This allows the
+ * DRM to generate the correct format bitmask (which formats apply to
+ * which modifier).
+ *
+ * Returns:
+ *
+ * True if the given modifier is valid for that format on the plane.
+ * False otherwise.
+ */
+ bool (*format_mod_supported)(struct drm_plane *plane, uint32_t format,
+ uint64_t modifier);
};
/**
@@ -487,6 +501,9 @@ struct drm_plane {
unsigned int format_count;
bool format_default;
+ uint64_t *modifiers;
+ unsigned int modifier_count;
+
struct drm_crtc *crtc;
struct drm_framebuffer *fb;
@@ -527,13 +544,14 @@ struct drm_plane {
#define obj_to_plane(x) container_of(x, struct drm_plane, base)
-__printf(8, 9)
+__printf(9, 10)
int drm_universal_plane_init(struct drm_device *dev,
struct drm_plane *plane,
uint32_t possible_crtcs,
const struct drm_plane_funcs *funcs,
const uint32_t *formats,
unsigned int format_count,
+ const uint64_t *format_modifiers,
enum drm_plane_type type,
const char *name, ...);
int drm_plane_init(struct drm_device *dev,
diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h
index 619868dc08d8..37355c623e6c 100644
--- a/include/drm/drm_property.h
+++ b/include/drm/drm_property.h
@@ -273,6 +273,8 @@ int drm_property_replace_global_blob(struct drm_device *dev,
const void *data,
struct drm_mode_object *obj_holds_id,
struct drm_property *prop_holds_id);
+bool drm_property_replace_blob(struct drm_property_blob **blob,
+ struct drm_property_blob *new_blob);
struct drm_property_blob *drm_property_blob_get(struct drm_property_blob *blob);
void drm_property_blob_put(struct drm_property_blob *blob);
diff --git a/include/drm/drm_scdc_helper.h b/include/drm/drm_scdc_helper.h
index c25122bb490a..f92eb2094d6b 100644
--- a/include/drm/drm_scdc_helper.h
+++ b/include/drm/drm_scdc_helper.h
@@ -131,31 +131,6 @@ static inline int drm_scdc_writeb(struct i2c_adapter *adapter, u8 offset,
bool drm_scdc_get_scrambling_status(struct i2c_adapter *adapter);
-/**
- * drm_scdc_set_scrambling - enable scrambling
- * @adapter: I2C adapter for DDC channel
- * @enable: bool to indicate if scrambling is to be enabled/disabled
- *
- * Writes the TMDS config register over SCDC channel, and:
- * enables scrambling when enable = 1
- * disables scrambling when enable = 0
- *
- * Returns:
- * True if scrambling is set/reset successfully, false otherwise.
- */
bool drm_scdc_set_scrambling(struct i2c_adapter *adapter, bool enable);
-
-/**
- * drm_scdc_set_high_tmds_clock_ratio - set TMDS clock ratio
- * @adapter: I2C adapter for DDC channel
- * @set: ret or reset the high clock ratio
- *
- * Writes to the TMDS config register over SCDC channel, and:
- * sets TMDS clock ratio to 1/40 when set = 1
- * sets TMDS clock ratio to 1/10 when set = 0
- *
- * Returns:
- * True if write is successful, false otherwise.
- */
bool drm_scdc_set_high_tmds_clock_ratio(struct i2c_adapter *adapter, bool set);
#endif
diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h
index 2d36538e4a17..6d9adbb46293 100644
--- a/include/drm/drm_simple_kms_helper.h
+++ b/include/drm/drm_simple_kms_helper.h
@@ -122,6 +122,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
struct drm_simple_display_pipe *pipe,
const struct drm_simple_display_pipe_funcs *funcs,
const uint32_t *formats, unsigned int format_count,
+ const uint64_t *format_modifiers,
struct drm_connector *connector);
#endif /* __LINUX_DRM_SIMPLE_KMS_HELPER_H */
diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h
index 4cde47332dfa..7fba9efe4951 100644
--- a/include/drm/drm_vblank.h
+++ b/include/drm/drm_vblank.h
@@ -168,8 +168,7 @@ void drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
void drm_crtc_vblank_off(struct drm_crtc *crtc);
void drm_crtc_vblank_reset(struct drm_crtc *crtc);
void drm_crtc_vblank_on(struct drm_crtc *crtc);
-void drm_vblank_cleanup(struct drm_device *dev);
-u32 drm_accurate_vblank_count(struct drm_crtc *crtc);
+u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc);
bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
unsigned int pipe, int *max_error,
diff --git a/include/drm/tinydrm/mipi-dbi.h b/include/drm/tinydrm/mipi-dbi.h
index d137b16ee873..83346ddb9dba 100644
--- a/include/drm/tinydrm/mipi-dbi.h
+++ b/include/drm/tinydrm/mipi-dbi.h
@@ -62,11 +62,7 @@ mipi_dbi_from_tinydrm(struct tinydrm_device *tdev)
}
int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *mipi,
- struct gpio_desc *dc,
- const struct drm_simple_display_pipe_funcs *pipe_funcs,
- struct drm_driver *driver,
- const struct drm_display_mode *mode,
- unsigned int rotation);
+ struct gpio_desc *dc);
int mipi_dbi_init(struct device *dev, struct mipi_dbi *mipi,
const struct drm_simple_display_pipe_funcs *pipe_funcs,
struct drm_driver *driver,
diff --git a/include/drm/tinydrm/tinydrm-helpers.h b/include/drm/tinydrm/tinydrm-helpers.h
index 9b9b6cfe3ba5..d554ded60ee9 100644
--- a/include/drm/tinydrm/tinydrm-helpers.h
+++ b/include/drm/tinydrm/tinydrm-helpers.h
@@ -43,6 +43,8 @@ void tinydrm_swab16(u16 *dst, void *vaddr, struct drm_framebuffer *fb,
void tinydrm_xrgb8888_to_rgb565(u16 *dst, void *vaddr,
struct drm_framebuffer *fb,
struct drm_clip_rect *clip, bool swap);
+void tinydrm_xrgb8888_to_gray8(u8 *dst, void *vaddr, struct drm_framebuffer *fb,
+ struct drm_clip_rect *clip);
struct backlight_device *tinydrm_of_find_backlight(struct device *dev);
int tinydrm_enable_backlight(struct backlight_device *backlight);
diff --git a/include/drm/tinydrm/tinydrm.h b/include/drm/tinydrm/tinydrm.h
index 00b800df4d1b..4774fe3d4273 100644
--- a/include/drm/tinydrm/tinydrm.h
+++ b/include/drm/tinydrm/tinydrm.h
@@ -56,9 +56,7 @@ pipe_to_tinydrm(struct drm_simple_display_pipe *pipe)
.gem_prime_vmap = drm_gem_cma_prime_vmap, \
.gem_prime_vunmap = drm_gem_cma_prime_vunmap, \
.gem_prime_mmap = drm_gem_cma_prime_mmap, \
- .dumb_create = drm_gem_cma_dumb_create, \
- .dumb_map_offset = drm_gem_cma_dumb_map_offset, \
- .dumb_destroy = drm_gem_dumb_destroy
+ .dumb_create = drm_gem_cma_dumb_create
/**
* TINYDRM_MODE - tinydrm display mode
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index 990d529f823c..5f821a9b3a1f 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -229,13 +229,14 @@ struct ttm_mem_type_manager_func {
* struct ttm_mem_type_manager member debug
*
* @man: Pointer to a memory type manager.
- * @prefix: Prefix to be used in printout to identify the caller.
+ * @printer: Prefix to be used in printout to identify the caller.
*
* This function is called to print out the state of the memory
* type manager to aid debugging of out-of-memory conditions.
* It may not be called from within atomic context.
*/
- void (*debug)(struct ttm_mem_type_manager *man, const char *prefix);
+ void (*debug)(struct ttm_mem_type_manager *man,
+ struct drm_printer *printer);
};
/**
@@ -472,6 +473,23 @@ struct ttm_bo_driver {
*/
unsigned long (*io_mem_pfn)(struct ttm_buffer_object *bo,
unsigned long page_offset);
+
+ /**
+ * Read/write memory buffers for ptrace access
+ *
+ * @bo: the BO to access
+ * @offset: the offset from the start of the BO
+ * @buf: pointer to source/destination buffer
+ * @len: number of bytes to copy
+ * @write: whether to read (0) from or write (non-0) to BO
+ *
+ * If successful, this function should return the number of
+ * bytes copied, -EIO otherwise. If the number of bytes
+ * returned is < len, the function may be called again with
+ * the remainder of the buffer to copy.
+ */
+ int (*access_memory)(struct ttm_buffer_object *bo, unsigned long offset,
+ void *buf, int len, int write);
};
/**
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index f6e030617467..f87fe20fcb05 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -48,7 +48,6 @@ void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu);
void kvm_pmu_vcpu_destroy(struct kvm_vcpu *vcpu);
void kvm_pmu_disable_counter(struct kvm_vcpu *vcpu, u64 val);
void kvm_pmu_enable_counter(struct kvm_vcpu *vcpu, u64 val);
-void kvm_pmu_overflow_set(struct kvm_vcpu *vcpu, u64 val);
void kvm_pmu_flush_hwstate(struct kvm_vcpu *vcpu);
void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu);
bool kvm_pmu_should_notify_user(struct kvm_vcpu *vcpu);
@@ -86,7 +85,6 @@ static inline void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu) {}
static inline void kvm_pmu_vcpu_destroy(struct kvm_vcpu *vcpu) {}
static inline void kvm_pmu_disable_counter(struct kvm_vcpu *vcpu, u64 val) {}
static inline void kvm_pmu_enable_counter(struct kvm_vcpu *vcpu, u64 val) {}
-static inline void kvm_pmu_overflow_set(struct kvm_vcpu *vcpu, u64 val) {}
static inline void kvm_pmu_flush_hwstate(struct kvm_vcpu *vcpu) {}
static inline void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu) {}
static inline bool kvm_pmu_should_notify_user(struct kvm_vcpu *vcpu)
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index c749eef1daa1..27b4b6615263 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1209,6 +1209,7 @@ static inline bool acpi_has_watchdog(void) { return false; }
#endif
#ifdef CONFIG_ACPI_SPCR_TABLE
+extern bool qdf2400_e44_present;
int parse_spcr(bool earlycon);
#else
static inline int parse_spcr(bool earlycon) { return 0; }
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 05488da3aee9..3ae9013eeaaa 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -46,7 +46,7 @@ struct linux_binprm {
unsigned interp_flags;
unsigned interp_data;
unsigned long loader, exec;
-};
+} __randomize_layout;
#define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
#define BINPRM_FLAGS_ENFORCE_NONDUMP (1 << BINPRM_FLAGS_ENFORCE_NONDUMP_BIT)
@@ -81,7 +81,7 @@ struct linux_binfmt {
int (*load_shlib)(struct file *);
int (*core_dump)(struct coredump_params *cprm);
unsigned long min_coredump; /* minimal dump size */
-};
+} __randomize_layout;
extern void __register_binfmt(struct linux_binfmt *fmt, int insert);
diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
index 360c082e885c..d41d40ac3efd 100644
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -85,7 +85,7 @@ int __cgroup_bpf_run_filter_sock_ops(struct sock *sk,
int __ret = 0; \
if (cgroup_bpf_enabled && (sock_ops)->sk) { \
typeof(sk) __sk = sk_to_full_sk((sock_ops)->sk); \
- if (sk_fullsock(__sk)) \
+ if (__sk && sk_fullsock(__sk)) \
__ret = __cgroup_bpf_run_filter_sock_ops(__sk, \
sock_ops, \
BPF_CGROUP_SOCK_OPS); \
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 621076f56251..8e5d31f6faef 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -43,6 +43,7 @@ struct bpf_reg_state {
u32 min_align;
u32 aux_off;
u32 aux_off_align;
+ bool value_from_signed;
};
enum bpf_stack_slot_type {
diff --git a/include/linux/cdev.h b/include/linux/cdev.h
index 408bc09ce497..cb28eb21e3ca 100644
--- a/include/linux/cdev.h
+++ b/include/linux/cdev.h
@@ -17,7 +17,7 @@ struct cdev {
struct list_head list;
dev_t dev;
unsigned int count;
-};
+} __randomize_layout;
void cdev_init(struct cdev *, const struct file_operations *);
diff --git a/include/linux/ceph/ceph_features.h b/include/linux/ceph/ceph_features.h
index f0f6c537b64c..040dd105c3e7 100644
--- a/include/linux/ceph/ceph_features.h
+++ b/include/linux/ceph/ceph_features.h
@@ -10,14 +10,14 @@
#define CEPH_FEATURE_INCARNATION_2 (1ull<<57) // CEPH_FEATURE_SERVER_JEWEL
#define DEFINE_CEPH_FEATURE(bit, incarnation, name) \
- const static uint64_t CEPH_FEATURE_##name = (1ULL<<bit); \
- const static uint64_t CEPH_FEATUREMASK_##name = \
+ static const uint64_t CEPH_FEATURE_##name = (1ULL<<bit); \
+ static const uint64_t CEPH_FEATUREMASK_##name = \
(1ULL<<bit | CEPH_FEATURE_INCARNATION_##incarnation);
/* this bit is ignored but still advertised by release *when* */
#define DEFINE_CEPH_FEATURE_DEPRECATED(bit, incarnation, name, when) \
- const static uint64_t DEPRECATED_CEPH_FEATURE_##name = (1ULL<<bit); \
- const static uint64_t DEPRECATED_CEPH_FEATUREMASK_##name = \
+ static const uint64_t DEPRECATED_CEPH_FEATURE_##name = (1ULL<<bit); \
+ static const uint64_t DEPRECATED_CEPH_FEATUREMASK_##name = \
(1ULL<<bit | CEPH_FEATURE_INCARNATION_##incarnation);
/*
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h
index c6d96a5f46fd..adf670ecaf94 100644
--- a/include/linux/ceph/osd_client.h
+++ b/include/linux/ceph/osd_client.h
@@ -148,6 +148,7 @@ struct ceph_osd_request_target {
int size;
int min_size;
bool sort_bitwise;
+ bool recovery_deletes;
unsigned int flags; /* CEPH_OSD_FLAG_* */
bool paused;
diff --git a/include/linux/ceph/osdmap.h b/include/linux/ceph/osdmap.h
index a0996cb9faed..af3444a5bfdd 100644
--- a/include/linux/ceph/osdmap.h
+++ b/include/linux/ceph/osdmap.h
@@ -272,6 +272,8 @@ bool ceph_is_new_interval(const struct ceph_osds *old_acting,
u32 new_pg_num,
bool old_sort_bitwise,
bool new_sort_bitwise,
+ bool old_recovery_deletes,
+ bool new_recovery_deletes,
const struct ceph_pg *pgid);
bool ceph_osds_changed(const struct ceph_osds *old_acting,
const struct ceph_osds *new_acting,
diff --git a/include/linux/ceph/rados.h b/include/linux/ceph/rados.h
index 385db08bb8b2..b8281feda9c7 100644
--- a/include/linux/ceph/rados.h
+++ b/include/linux/ceph/rados.h
@@ -158,6 +158,10 @@ extern const char *ceph_osd_state_name(int s);
#define CEPH_OSDMAP_NOTIERAGENT (1<<13) /* disable tiering agent */
#define CEPH_OSDMAP_NOREBALANCE (1<<14) /* block osd backfill unless pg is degraded */
#define CEPH_OSDMAP_SORTBITWISE (1<<15) /* use bitwise hobject_t sort */
+#define CEPH_OSDMAP_REQUIRE_JEWEL (1<<16) /* require jewel for booting osds */
+#define CEPH_OSDMAP_REQUIRE_KRAKEN (1<<17) /* require kraken for booting osds */
+#define CEPH_OSDMAP_REQUIRE_LUMINOUS (1<<18) /* require l for booting osds */
+#define CEPH_OSDMAP_RECOVERY_DELETES (1<<19) /* deletes performed during recovery instead of peering */
/*
* The error code to return when an OSD can't handle a write
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index cd4bbe8242bd..bdb80c4aef6e 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -235,6 +235,7 @@
#endif /* GCC_VERSION >= 40500 */
#if GCC_VERSION >= 40600
+
/*
* When used with Link Time Optimization, gcc can optimize away C functions or
* variables which are referenced only from assembly code. __visible tells the
@@ -242,7 +243,17 @@
* this.
*/
#define __visible __attribute__((externally_visible))
-#endif
+
+/*
+ * RANDSTRUCT_PLUGIN wants to use an anonymous struct, but it is only
+ * possible since GCC 4.6. To provide as much build testing coverage
+ * as possible, this is used for all GCC 4.6+ builds, and not just on
+ * RANDSTRUCT_PLUGIN builds.
+ */
+#define randomized_struct_fields_start struct {
+#define randomized_struct_fields_end } __randomize_layout;
+
+#endif /* GCC_VERSION >= 40600 */
#if GCC_VERSION >= 40900 && !defined(__CHECKER__)
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 219f82f3ec1a..eca8ad75e28b 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -452,6 +452,11 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
# define __no_randomize_layout
#endif
+#ifndef randomized_struct_fields_start
+# define randomized_struct_fields_start
+# define randomized_struct_fields_end
+#endif
+
/*
* Tell gcc if a function is cold. The compiler will assume any path
* directly leading to the call is unlikely.
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index b56573bf440d..82b30e638430 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -39,8 +39,6 @@ enum cpuhp_state {
CPUHP_PCI_XGENE_DEAD,
CPUHP_IOMMU_INTEL_DEAD,
CPUHP_LUSTRE_CFS_DEAD,
- CPUHP_SCSI_BNX2FC_DEAD,
- CPUHP_SCSI_BNX2I_DEAD,
CPUHP_WORKQUEUE_PREP,
CPUHP_POWER_NUMA_PREPARE,
CPUHP_HRTIMERS_PREPARE,
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 119a3f9604b0..898cfe2eeb42 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -18,6 +18,19 @@
#ifdef CONFIG_CPUSETS
+/*
+ * Static branch rewrites can happen in an arbitrary order for a given
+ * key. In code paths where we need to loop with read_mems_allowed_begin() and
+ * read_mems_allowed_retry() to get a consistent view of mems_allowed, we need
+ * to ensure that begin() always gets rewritten before retry() in the
+ * disabled -> enabled transition. If not, then if local irqs are disabled
+ * around the loop, we can deadlock since retry() would always be
+ * comparing the latest value of the mems_allowed seqcount against 0 as
+ * begin() still would see cpusets_enabled() as false. The enabled -> disabled
+ * transition should happen in reverse order for the same reasons (want to stop
+ * looking at real value of mems_allowed.sequence in retry() first).
+ */
+extern struct static_key_false cpusets_pre_enable_key;
extern struct static_key_false cpusets_enabled_key;
static inline bool cpusets_enabled(void)
{
@@ -32,12 +45,14 @@ static inline int nr_cpusets(void)
static inline void cpuset_inc(void)
{
+ static_branch_inc(&cpusets_pre_enable_key);
static_branch_inc(&cpusets_enabled_key);
}
static inline void cpuset_dec(void)
{
static_branch_dec(&cpusets_enabled_key);
+ static_branch_dec(&cpusets_pre_enable_key);
}
extern int cpuset_init(void);
@@ -115,7 +130,7 @@ extern void cpuset_print_current_mems_allowed(void);
*/
static inline unsigned int read_mems_allowed_begin(void)
{
- if (!cpusets_enabled())
+ if (!static_branch_unlikely(&cpusets_pre_enable_key))
return 0;
return read_seqcount_begin(&current->mems_allowed_seq);
@@ -129,7 +144,7 @@ static inline unsigned int read_mems_allowed_begin(void)
*/
static inline bool read_mems_allowed_retry(unsigned int seq)
{
- if (!cpusets_enabled())
+ if (!static_branch_unlikely(&cpusets_enabled_key))
return false;
return read_seqcount_retry(&current->mems_allowed_seq, seq);
diff --git a/include/linux/cred.h b/include/linux/cred.h
index c728d515e5e2..099058e1178b 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -31,7 +31,7 @@ struct group_info {
atomic_t usage;
int ngroups;
kgid_t gid[0];
-};
+} __randomize_layout;
/**
* get_group_info - Get a reference to a group info structure
@@ -145,7 +145,7 @@ struct cred {
struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */
struct group_info *group_info; /* supplementary groups for euid/fsgid */
struct rcu_head rcu; /* RCU deletion hook */
-};
+} __randomize_layout;
extern void __put_cred(struct cred *);
extern void exit_creds(struct task_struct *);
diff --git a/include/linux/crush/crush.h b/include/linux/crush/crush.h
index 92e165d417a6..07eed95e10c7 100644
--- a/include/linux/crush/crush.h
+++ b/include/linux/crush/crush.h
@@ -193,7 +193,7 @@ struct crush_choose_arg {
struct crush_choose_arg_map {
#ifdef __KERNEL__
struct rb_node node;
- u64 choose_args_index;
+ s64 choose_args_index;
#endif
struct crush_choose_arg *args; /*!< replacement for each bucket
in the crushmap */
diff --git a/include/linux/dax.h b/include/linux/dax.h
index 794811875732..df97b7af7e2c 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -87,6 +87,7 @@ size_t dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr,
void dax_flush(struct dax_device *dax_dev, pgoff_t pgoff, void *addr,
size_t size);
void dax_write_cache(struct dax_device *dax_dev, bool wc);
+bool dax_write_cache_enabled(struct dax_device *dax_dev);
/*
* We use lowest available bit in exceptional entry for locking, one bit for
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 3f3ff4ccdc3f..aae1cdb76851 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -118,7 +118,7 @@ struct dentry {
struct hlist_bl_node d_in_lookup_hash; /* only for in-lookup ones */
struct rcu_head d_rcu;
} d_u;
-};
+} __randomize_layout;
/*
* dentry->d_lock spinlock nesting subclasses:
diff --git a/include/linux/device.h b/include/linux/device.h
index 723cd54b94da..beabdbc08420 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -843,7 +843,7 @@ struct dev_links_info {
* hibernation, system resume and during runtime PM transitions
* along with subsystem-level and driver-level callbacks.
* @pins: For device pin management.
- * See Documentation/pinctrl.txt for details.
+ * See Documentation/driver-api/pinctl.rst for details.
* @msi_list: Hosts MSI descriptors
* @msi_domain: The generic MSI domain this device is using.
* @numa_node: NUMA node this device is close to.
diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
index a5195a7d6f77..171895072435 100644
--- a/include/linux/dma-fence.h
+++ b/include/linux/dma-fence.h
@@ -55,6 +55,7 @@ struct dma_fence_cb;
* of the time.
*
* DMA_FENCE_FLAG_SIGNALED_BIT - fence is already signaled
+ * DMA_FENCE_FLAG_TIMESTAMP_BIT - timestamp recorded for fence signaling
* DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT - enable_signaling might have been called
* DMA_FENCE_FLAG_USER_BITS - start of the unused bits, can be used by the
* implementer of the fence for its own purposes. Can be used in different
@@ -84,6 +85,7 @@ struct dma_fence {
enum dma_fence_flag_bits {
DMA_FENCE_FLAG_SIGNALED_BIT,
+ DMA_FENCE_FLAG_TIMESTAMP_BIT,
DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
DMA_FENCE_FLAG_USER_BITS, /* must always be last member */
};
@@ -336,6 +338,19 @@ dma_fence_is_signaled(struct dma_fence *fence)
}
/**
+ * __dma_fence_is_later - return if f1 is chronologically later than f2
+ * @f1: [in] the first fence's seqno
+ * @f2: [in] the second fence's seqno from the same context
+ *
+ * Returns true if f1 is chronologically later than f2. Both fences must be
+ * from the same context, since a seqno is not common across contexts.
+ */
+static inline bool __dma_fence_is_later(u32 f1, u32 f2)
+{
+ return (int)(f1 - f2) > 0;
+}
+
+/**
* dma_fence_is_later - return if f1 is chronologically later than f2
* @f1: [in] the first fence from the same context
* @f2: [in] the second fence from the same context
@@ -349,7 +364,7 @@ static inline bool dma_fence_is_later(struct dma_fence *f1,
if (WARN_ON(f1->context != f2->context))
return false;
- return (int)(f1->seqno - f2->seqno) > 0;
+ return __dma_fence_is_later(f1->seqno, f2->seqno);
}
/**
@@ -416,8 +431,8 @@ int dma_fence_get_status(struct dma_fence *fence);
static inline void dma_fence_set_error(struct dma_fence *fence,
int error)
{
- BUG_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags));
- BUG_ON(error >= 0 || error < -MAX_ERRNO);
+ WARN_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags));
+ WARN_ON(error >= 0 || error < -MAX_ERRNO);
fence->error = error;
}
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 843ab866e0f4..03c0196a6f24 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -157,16 +157,40 @@ static inline int is_device_dma_capable(struct device *dev)
* These three functions are only for dma allocator.
* Don't use them in device drivers.
*/
-int dma_alloc_from_coherent(struct device *dev, ssize_t size,
+int dma_alloc_from_dev_coherent(struct device *dev, ssize_t size,
dma_addr_t *dma_handle, void **ret);
-int dma_release_from_coherent(struct device *dev, int order, void *vaddr);
+int dma_release_from_dev_coherent(struct device *dev, int order, void *vaddr);
-int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma,
+int dma_mmap_from_dev_coherent(struct device *dev, struct vm_area_struct *vma,
void *cpu_addr, size_t size, int *ret);
+
+void *dma_alloc_from_global_coherent(ssize_t size, dma_addr_t *dma_handle);
+int dma_release_from_global_coherent(int order, void *vaddr);
+int dma_mmap_from_global_coherent(struct vm_area_struct *vma, void *cpu_addr,
+ size_t size, int *ret);
+
#else
-#define dma_alloc_from_coherent(dev, size, handle, ret) (0)
-#define dma_release_from_coherent(dev, order, vaddr) (0)
-#define dma_mmap_from_coherent(dev, vma, vaddr, order, ret) (0)
+#define dma_alloc_from_dev_coherent(dev, size, handle, ret) (0)
+#define dma_release_from_dev_coherent(dev, order, vaddr) (0)
+#define dma_mmap_from_dev_coherent(dev, vma, vaddr, order, ret) (0)
+
+static inline void *dma_alloc_from_global_coherent(ssize_t size,
+ dma_addr_t *dma_handle)
+{
+ return NULL;
+}
+
+static inline int dma_release_from_global_coherent(int order, void *vaddr)
+{
+ return 0;
+}
+
+static inline int dma_mmap_from_global_coherent(struct vm_area_struct *vma,
+ void *cpu_addr, size_t size,
+ int *ret)
+{
+ return 0;
+}
#endif /* CONFIG_HAVE_GENERIC_DMA_COHERENT */
#ifdef CONFIG_HAS_DMA
@@ -481,7 +505,7 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size,
BUG_ON(!ops);
- if (dma_alloc_from_coherent(dev, size, dma_handle, &cpu_addr))
+ if (dma_alloc_from_dev_coherent(dev, size, dma_handle, &cpu_addr))
return cpu_addr;
if (!arch_dma_alloc_attrs(&dev, &flag))
@@ -503,7 +527,7 @@ static inline void dma_free_attrs(struct device *dev, size_t size,
BUG_ON(!ops);
WARN_ON(irqs_disabled());
- if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
+ if (dma_release_from_dev_coherent(dev, get_order(size), cpu_addr))
return;
if (!ops->free || !cpu_addr)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 7b5d6816542b..6e1fd5d21248 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -296,7 +296,7 @@ struct kiocb {
void *private;
int ki_flags;
enum rw_hint ki_hint;
-};
+} __randomize_layout;
static inline bool is_sync_kiocb(struct kiocb *kiocb)
{
@@ -404,7 +404,7 @@ struct address_space {
struct list_head private_list; /* ditto */
void *private_data; /* ditto */
errseq_t wb_err;
-} __attribute__((aligned(sizeof(long))));
+} __attribute__((aligned(sizeof(long)))) __randomize_layout;
/*
* On most architectures that alignment is already the case; but
* must be enforced here for CRIS, to let the least significant bit
@@ -447,7 +447,7 @@ struct block_device {
int bd_fsfreeze_count;
/* Mutex for freeze */
struct mutex bd_fsfreeze_mutex;
-};
+} __randomize_layout;
/*
* Radix-tree tags, for tagging dirty and writeback pages within the pagecache
@@ -666,7 +666,7 @@ struct inode {
#endif
void *i_private; /* fs or device private pointer */
-};
+} __randomize_layout;
static inline unsigned int i_blocksize(const struct inode *node)
{
@@ -883,7 +883,8 @@ struct file {
#endif /* #ifdef CONFIG_EPOLL */
struct address_space *f_mapping;
errseq_t f_wb_err;
-} __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */
+} __randomize_layout
+ __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */
struct file_handle {
__u32 handle_bytes;
@@ -1020,7 +1021,7 @@ struct file_lock {
int state; /* state of grant or error if -ve */
} afs;
} fl_u;
-};
+} __randomize_layout;
struct file_lock_context {
spinlock_t flc_lock;
@@ -1412,7 +1413,7 @@ struct super_block {
spinlock_t s_inode_wblist_lock;
struct list_head s_inodes_wb; /* writeback inodes */
-};
+} __randomize_layout;
/* Helper functions so that in most cases filesystems will
* not need to deal directly with kuid_t and kgid_t and can
@@ -1698,7 +1699,7 @@ struct file_operations {
u64);
ssize_t (*dedupe_file_range)(struct file *, u64, u64, struct file *,
u64);
-};
+} __randomize_layout;
struct inode_operations {
struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h
index 0efc3e62843a..7a026240cbb1 100644
--- a/include/linux/fs_struct.h
+++ b/include/linux/fs_struct.h
@@ -12,7 +12,7 @@ struct fs_struct {
int umask;
int in_exec;
struct path root, pwd;
-};
+} __randomize_layout;
extern struct kmem_cache *fs_cachep;
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 5857390ac35a..6383115e9d2c 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -145,8 +145,8 @@ enum {
#ifdef CONFIG_DYNAMIC_FTRACE
/* The hash used to know what functions callbacks trace */
struct ftrace_ops_hash {
- struct ftrace_hash *notrace_hash;
- struct ftrace_hash *filter_hash;
+ struct ftrace_hash __rcu *notrace_hash;
+ struct ftrace_hash __rcu *filter_hash;
struct mutex regex_lock;
};
@@ -168,7 +168,7 @@ static inline void ftrace_free_init_mem(void) { }
*/
struct ftrace_ops {
ftrace_func_t func;
- struct ftrace_ops *next;
+ struct ftrace_ops __rcu *next;
unsigned long flags;
void *private;
ftrace_func_t saved_func;
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 00ca5b86a753..d501d3956f13 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -689,7 +689,8 @@ i2c_unlock_adapter(struct i2c_adapter *adapter)
#define I2C_CLASS_HWMON (1<<0) /* lm_sensors, ... */
#define I2C_CLASS_DDC (1<<3) /* DDC bus on graphics adapters */
#define I2C_CLASS_SPD (1<<7) /* Memory modules */
-#define I2C_CLASS_DEPRECATED (1<<8) /* Warn users that adapter will stop using classes */
+/* Warn users that the adapter doesn't support classes anymore */
+#define I2C_CLASS_DEPRECATED (1<<8)
/* Internal numbers to terminate lists */
#define I2C_CLIENT_END 0xfffeU
diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h
index 497f2b3a5a62..97f1b465d04f 100644
--- a/include/linux/iio/common/st_sensors.h
+++ b/include/linux/iio/common/st_sensors.h
@@ -105,6 +105,11 @@ struct st_sensor_fullscale {
struct st_sensor_fullscale_avl fs_avl[ST_SENSORS_FULLSCALE_AVL_MAX];
};
+struct st_sensor_sim {
+ u8 addr;
+ u8 value;
+};
+
/**
* struct st_sensor_bdu - ST sensor device block data update
* @addr: address of the register.
@@ -197,6 +202,7 @@ struct st_sensor_transfer_function {
* @bdu: Block data update register.
* @das: Data Alignment Selection register.
* @drdy_irq: Data ready register of the sensor.
+ * @sim: SPI serial interface mode register of the sensor.
* @multi_read_bit: Use or not particular bit for [I2C/SPI] multi-read.
* @bootime: samples to discard when sensor passing from power-down to power-up.
*/
@@ -213,6 +219,7 @@ struct st_sensor_settings {
struct st_sensor_bdu bdu;
struct st_sensor_das das;
struct st_sensor_data_ready_irq drdy_irq;
+ struct st_sensor_sim sim;
bool multi_read_bit;
unsigned int bootime;
};
diff --git a/include/linux/ipc.h b/include/linux/ipc.h
index 5591f055e13f..fadd579d577d 100644
--- a/include/linux/ipc.h
+++ b/include/linux/ipc.h
@@ -23,6 +23,6 @@ struct kern_ipc_perm {
struct rcu_head rcu;
atomic_t refcount;
-} ____cacheline_aligned_in_smp;
+} ____cacheline_aligned_in_smp __randomize_layout;
#endif /* _LINUX_IPC_H */
diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h
index 848e5796400e..65327ee0936b 100644
--- a/include/linux/ipc_namespace.h
+++ b/include/linux/ipc_namespace.h
@@ -61,7 +61,7 @@ struct ipc_namespace {
struct ucounts *ucounts;
struct ns_common ns;
-};
+} __randomize_layout;
extern struct ipc_namespace init_ipc_ns;
extern spinlock_t mq_lock;
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index e1b442996f81..474d6bbc158c 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -128,6 +128,7 @@ struct inet6_skb_parm {
#define IP6SKB_FRAGMENTED 16
#define IP6SKB_HOPBYHOP 32
#define IP6SKB_L3SLAVE 64
+#define IP6SKB_JUMBOGRAM 128
};
#if defined(CONFIG_NET_L3_MASTER_DEV)
@@ -152,6 +153,11 @@ static inline int inet6_iif(const struct sk_buff *skb)
return l3_slave ? skb->skb_iif : IP6CB(skb)->iif;
}
+static inline bool inet6_is_jumbogram(const struct sk_buff *skb)
+{
+ return !!(IP6CB(skb)->flags & IP6SKB_JUMBOGRAM);
+}
+
/* can not be used in TCP layer after tcp_v6_fill_cb */
static inline bool inet6_exact_dif_match(struct net *net, struct sk_buff *skb)
{
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 00db35b61e9e..d2d543794093 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -388,7 +388,12 @@ static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
* @irq_mask_ack: ack and mask an interrupt source
* @irq_unmask: unmask an interrupt source
* @irq_eoi: end of interrupt
- * @irq_set_affinity: set the CPU affinity on SMP machines
+ * @irq_set_affinity: Set the CPU affinity on SMP machines. If the force
+ * argument is true, it tells the driver to
+ * unconditionally apply the affinity setting. Sanity
+ * checks against the supplied affinity mask are not
+ * required. This is used for CPU hotplug where the
+ * target CPU is not yet set in the cpu_online_mask.
* @irq_retrigger: resend an IRQ to the CPU
* @irq_set_type: set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ
* @irq_set_wake: enable/disable power-management wake-on of an IRQ
diff --git a/include/linux/jhash.h b/include/linux/jhash.h
index 348c6f47e4cc..8037850f3104 100644
--- a/include/linux/jhash.h
+++ b/include/linux/jhash.h
@@ -85,19 +85,18 @@ static inline u32 jhash(const void *key, u32 length, u32 initval)
k += 12;
}
/* Last block: affect all 32 bits of (c) */
- /* All the case statements fall through */
switch (length) {
- case 12: c += (u32)k[11]<<24;
- case 11: c += (u32)k[10]<<16;
- case 10: c += (u32)k[9]<<8;
- case 9: c += k[8];
- case 8: b += (u32)k[7]<<24;
- case 7: b += (u32)k[6]<<16;
- case 6: b += (u32)k[5]<<8;
- case 5: b += k[4];
- case 4: a += (u32)k[3]<<24;
- case 3: a += (u32)k[2]<<16;
- case 2: a += (u32)k[1]<<8;
+ case 12: c += (u32)k[11]<<24; /* fall through */
+ case 11: c += (u32)k[10]<<16; /* fall through */
+ case 10: c += (u32)k[9]<<8; /* fall through */
+ case 9: c += k[8]; /* fall through */
+ case 8: b += (u32)k[7]<<24; /* fall through */
+ case 7: b += (u32)k[6]<<16; /* fall through */
+ case 6: b += (u32)k[5]<<8; /* fall through */
+ case 5: b += k[4]; /* fall through */
+ case 4: a += (u32)k[3]<<24; /* fall through */
+ case 3: a += (u32)k[2]<<16; /* fall through */
+ case 2: a += (u32)k[1]<<8; /* fall through */
case 1: a += k[0];
__jhash_final(a, b, c);
case 0: /* Nothing left to add */
@@ -131,10 +130,10 @@ static inline u32 jhash2(const u32 *k, u32 length, u32 initval)
k += 3;
}
- /* Handle the last 3 u32's: all the case statements fall through */
+ /* Handle the last 3 u32's */
switch (length) {
- case 3: c += k[2];
- case 2: b += k[1];
+ case 3: c += k[2]; /* fall through */
+ case 2: b += k[1]; /* fall through */
case 1: a += k[0];
__jhash_final(a, b, c);
case 0: /* Nothing left to add */
diff --git a/include/linux/key-type.h b/include/linux/key-type.h
index 8496cf64575c..9520fc3c3b9a 100644
--- a/include/linux/key-type.h
+++ b/include/linux/key-type.h
@@ -45,7 +45,7 @@ struct key_preparsed_payload {
size_t datalen; /* Raw datalen */
size_t quotalen; /* Quota length for proposed payload */
time_t expiry; /* Expiry time of key */
-};
+} __randomize_layout;
typedef int (*request_key_actor_t)(struct key_construction *key,
const char *op, void *aux);
@@ -158,7 +158,7 @@ struct key_type {
/* internal fields */
struct list_head link; /* link in types list */
struct lock_class_key lock_class; /* key->sem lock class */
-};
+} __randomize_layout;
extern struct key_type key_type_keyring;
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index c4e441e00db5..655082c88fd9 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -64,7 +64,7 @@ struct subprocess_info {
int (*init)(struct subprocess_info *info, struct cred *new);
void (*cleanup)(struct subprocess_info *info);
void *data;
-};
+} __randomize_layout;
extern int
call_usermodehelper(const char *path, char **argv, char **envp, int wait);
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index eeab34b0f589..4d800c79475a 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -172,7 +172,7 @@ struct kset {
spinlock_t list_lock;
struct kobject kobj;
const struct kset_uevent_ops *uevent_ops;
-};
+} __randomize_layout;
extern void kset_init(struct kset *kset);
extern int __must_check kset_register(struct kset *kset);
diff --git a/include/linux/kthread.h b/include/linux/kthread.h
index 4fec8b775895..82e197eeac91 100644
--- a/include/linux/kthread.h
+++ b/include/linux/kthread.h
@@ -15,7 +15,7 @@ struct task_struct *kthread_create_on_node(int (*threadfn)(void *data),
* @threadfn: the function to run in the thread
* @data: data pointer for @threadfn()
* @namefmt: printf-style format string for the thread name
- * @...: arguments for @namefmt.
+ * @arg...: arguments for @namefmt.
*
* This macro will create a kthread on the current node, leaving it in
* the stopped state. This is just a helper for kthread_create_on_node();
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 648b34cabb38..21a6fd6c44af 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -445,6 +445,7 @@ struct kvm {
struct kvm_stat_data **debugfs_stat_data;
struct srcu_struct srcu;
struct srcu_struct irq_srcu;
+ pid_t userspace_pid;
};
#define kvm_err(fmt, ...) \
@@ -476,7 +477,8 @@ struct kvm {
static inline struct kvm_io_bus *kvm_get_bus(struct kvm *kvm, enum kvm_bus idx)
{
return srcu_dereference_check(kvm->buses[idx], &kvm->srcu,
- lockdep_is_held(&kvm->slots_lock));
+ lockdep_is_held(&kvm->slots_lock) ||
+ !refcount_read(&kvm->users_count));
}
static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)
@@ -569,7 +571,8 @@ void kvm_put_kvm(struct kvm *kvm);
static inline struct kvm_memslots *__kvm_memslots(struct kvm *kvm, int as_id)
{
return srcu_dereference_check(kvm->memslots[as_id], &kvm->srcu,
- lockdep_is_held(&kvm->slots_lock));
+ lockdep_is_held(&kvm->slots_lock) ||
+ !refcount_read(&kvm->users_count));
}
static inline struct kvm_memslots *kvm_memslots(struct kvm *kvm)
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 55de3da58b1c..931c32f1f18d 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -435,7 +435,7 @@ enum {
ATA_HORKAGE_NOLPM = (1 << 20), /* don't use LPM */
ATA_HORKAGE_WD_BROKEN_LPM = (1 << 21), /* some WDs have broken LPM */
ATA_HORKAGE_ZERO_AFTER_TRIM = (1 << 22),/* guarantees zero after trim */
- ATA_HORKAGE_NO_NCQ_LOG = (1 << 23), /* don't use NCQ for log read */
+ ATA_HORKAGE_NO_DMA_LOG = (1 << 23), /* don't use DMA for log read */
ATA_HORKAGE_NOTRIM = (1 << 24), /* don't use TRIM */
ATA_HORKAGE_MAX_SEC_1024 = (1 << 25), /* Limit max sects to 1024 */
diff --git a/include/linux/llist.h b/include/linux/llist.h
index d11738110a7a..1957635e6d5f 100644
--- a/include/linux/llist.h
+++ b/include/linux/llist.h
@@ -93,6 +93,23 @@ static inline void init_llist_head(struct llist_head *list)
container_of(ptr, type, member)
/**
+ * member_address_is_nonnull - check whether the member address is not NULL
+ * @ptr: the object pointer (struct type * that contains the llist_node)
+ * @member: the name of the llist_node within the struct.
+ *
+ * This macro is conceptually the same as
+ * &ptr->member != NULL
+ * but it works around the fact that compilers can decide that taking a member
+ * address is never a NULL pointer.
+ *
+ * Real objects that start at a high address and have a member at NULL are
+ * unlikely to exist, but such pointers may be returned e.g. by the
+ * container_of() macro.
+ */
+#define member_address_is_nonnull(ptr, member) \
+ ((uintptr_t)(ptr) + offsetof(typeof(*(ptr)), member) != 0)
+
+/**
* llist_for_each - iterate over some deleted entries of a lock-less list
* @pos: the &struct llist_node to use as a loop cursor
* @node: the first entry of deleted list entries
@@ -145,7 +162,7 @@ static inline void init_llist_head(struct llist_head *list)
*/
#define llist_for_each_entry(pos, node, member) \
for ((pos) = llist_entry((node), typeof(*(pos)), member); \
- &(pos)->member != NULL; \
+ member_address_is_nonnull(pos, member); \
(pos) = llist_entry((pos)->member.next, typeof(*(pos)), member))
/**
@@ -167,7 +184,7 @@ static inline void init_llist_head(struct llist_head *list)
*/
#define llist_for_each_entry_safe(pos, n, node, member) \
for (pos = llist_entry((node), typeof(*pos), member); \
- &pos->member != NULL && \
+ member_address_is_nonnull(pos, member) && \
(n = llist_entry(pos->member.next, typeof(*n), member), true); \
pos = n)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 7a86925ba8f3..3a90febadbe2 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1912,7 +1912,7 @@ struct security_hook_heads {
struct list_head audit_rule_match;
struct list_head audit_rule_free;
#endif /* CONFIG_AUDIT */
-};
+} __randomize_layout;
/*
* Security module hook list structure.
@@ -1923,7 +1923,7 @@ struct security_hook_list {
struct list_head *head;
union security_list_options hook;
char *lsm;
-};
+} __randomize_layout;
/*
* Initializing a security_hook_list structure takes
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index d5bed0875d30..b54517c05e9a 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -620,6 +620,7 @@ struct mlx4_caps {
u32 dmfs_high_rate_qpn_base;
u32 dmfs_high_rate_qpn_range;
u32 vf_caps;
+ bool wol_port[MLX4_MAX_PORTS + 1];
struct mlx4_rate_limit_caps rl_caps;
};
@@ -1068,7 +1069,7 @@ static inline int mlx4_is_eth(struct mlx4_dev *dev, int port)
}
int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct,
- struct mlx4_buf *buf, gfp_t gfp);
+ struct mlx4_buf *buf);
void mlx4_buf_free(struct mlx4_dev *dev, int size, struct mlx4_buf *buf);
static inline void *mlx4_buf_offset(struct mlx4_buf *buf, int offset)
{
@@ -1105,10 +1106,9 @@ int mlx4_mw_enable(struct mlx4_dev *dev, struct mlx4_mw *mw);
int mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
int start_index, int npages, u64 *page_list);
int mlx4_buf_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
- struct mlx4_buf *buf, gfp_t gfp);
+ struct mlx4_buf *buf);
-int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order,
- gfp_t gfp);
+int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order);
void mlx4_db_free(struct mlx4_dev *dev, struct mlx4_db *db);
int mlx4_alloc_hwq_res(struct mlx4_dev *dev, struct mlx4_hwq_resources *wqres,
@@ -1124,8 +1124,7 @@ int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align,
int *base, u8 flags);
void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt);
-int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp,
- gfp_t gfp);
+int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp);
void mlx4_qp_free(struct mlx4_dev *dev, struct mlx4_qp *qp);
int mlx4_srq_alloc(struct mlx4_dev *dev, u32 pdn, u32 cqn, u16 xrcdn,
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index 87869c04849a..3030121b4746 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -7749,8 +7749,10 @@ struct mlx5_ifc_pcam_reg_bits {
};
struct mlx5_ifc_mcam_enhanced_features_bits {
- u8 reserved_at_0[0x7f];
+ u8 reserved_at_0[0x7d];
+ u8 mtpps_enh_out_per_adj[0x1];
+ u8 mtpps_fs[0x1];
u8 pcie_performance_group[0x1];
};
@@ -8159,7 +8161,8 @@ struct mlx5_ifc_mtpps_reg_bits {
u8 reserved_at_78[0x4];
u8 cap_pin_4_mode[0x4];
- u8 reserved_at_80[0x80];
+ u8 field_select[0x20];
+ u8 reserved_at_a0[0x60];
u8 enable[0x1];
u8 reserved_at_101[0xb];
@@ -8174,8 +8177,9 @@ struct mlx5_ifc_mtpps_reg_bits {
u8 out_pulse_duration[0x10];
u8 out_periodic_adjustment[0x10];
+ u8 enhanced_out_periodic_adjustment[0x20];
- u8 reserved_at_1a0[0x60];
+ u8 reserved_at_1c0[0x20];
};
struct mlx5_ifc_mtppse_reg_bits {
diff --git a/include/linux/mlx5/qp.h b/include/linux/mlx5/qp.h
index 6f41270d80c0..f378dc0e7eaf 100644
--- a/include/linux/mlx5/qp.h
+++ b/include/linux/mlx5/qp.h
@@ -212,7 +212,6 @@ struct mlx5_wqe_ctrl_seg {
#define MLX5_WQE_CTRL_OPCODE_MASK 0xff
#define MLX5_WQE_CTRL_WQE_INDEX_MASK 0x00ffff00
#define MLX5_WQE_CTRL_WQE_INDEX_SHIFT 8
-#define MLX5_WQE_AV_EXT 0x80000000
enum {
MLX5_ETH_WQE_L3_INNER_CSUM = 1 << 4,
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 45cdb27791a3..3cadee0a3508 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -342,7 +342,7 @@ struct vm_area_struct {
struct mempolicy *vm_policy; /* NUMA policy for the VMA */
#endif
struct vm_userfaultfd_ctx vm_userfaultfd_ctx;
-};
+} __randomize_layout;
struct core_thread {
struct task_struct *task;
@@ -487,20 +487,22 @@ struct mm_struct {
/* numa_scan_seq prevents two threads setting pte_numa */
int numa_scan_seq;
#endif
-#if defined(CONFIG_NUMA_BALANCING) || defined(CONFIG_COMPACTION)
/*
* An operation with batched TLB flushing is going on. Anything that
* can move process memory needs to flush the TLB when moving a
* PROT_NONE or PROT_NUMA mapped page.
*/
- bool tlb_flush_pending;
+ atomic_t tlb_flush_pending;
+#ifdef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
+ /* See flush_tlb_batched_pending() */
+ bool tlb_flush_batched;
#endif
struct uprobes_state uprobes_state;
#ifdef CONFIG_HUGETLB_PAGE
atomic_long_t hugetlb_usage;
#endif
struct work_struct async_put_work;
-};
+} __randomize_layout;
extern struct mm_struct init_mm;
@@ -518,46 +520,60 @@ static inline cpumask_t *mm_cpumask(struct mm_struct *mm)
return mm->cpu_vm_mask_var;
}
-#if defined(CONFIG_NUMA_BALANCING) || defined(CONFIG_COMPACTION)
+struct mmu_gather;
+extern void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
+ unsigned long start, unsigned long end);
+extern void tlb_finish_mmu(struct mmu_gather *tlb,
+ unsigned long start, unsigned long end);
+
/*
* Memory barriers to keep this state in sync are graciously provided by
* the page table locks, outside of which no page table modifications happen.
- * The barriers below prevent the compiler from re-ordering the instructions
- * around the memory barriers that are already present in the code.
+ * The barriers are used to ensure the order between tlb_flush_pending updates,
+ * which happen while the lock is not taken, and the PTE updates, which happen
+ * while the lock is taken, are serialized.
*/
static inline bool mm_tlb_flush_pending(struct mm_struct *mm)
{
- barrier();
- return mm->tlb_flush_pending;
+ return atomic_read(&mm->tlb_flush_pending) > 0;
+}
+
+/*
+ * Returns true if there are two above TLB batching threads in parallel.
+ */
+static inline bool mm_tlb_flush_nested(struct mm_struct *mm)
+{
+ return atomic_read(&mm->tlb_flush_pending) > 1;
+}
+
+static inline void init_tlb_flush_pending(struct mm_struct *mm)
+{
+ atomic_set(&mm->tlb_flush_pending, 0);
}
-static inline void set_tlb_flush_pending(struct mm_struct *mm)
+
+static inline void inc_tlb_flush_pending(struct mm_struct *mm)
{
- mm->tlb_flush_pending = true;
+ atomic_inc(&mm->tlb_flush_pending);
/*
- * Guarantee that the tlb_flush_pending store does not leak into the
+ * Guarantee that the tlb_flush_pending increase does not leak into the
* critical section updating the page tables
*/
smp_mb__before_spinlock();
}
+
/* Clearing is done after a TLB flush, which also provides a barrier. */
-static inline void clear_tlb_flush_pending(struct mm_struct *mm)
-{
- barrier();
- mm->tlb_flush_pending = false;
-}
-#else
-static inline bool mm_tlb_flush_pending(struct mm_struct *mm)
-{
- return false;
-}
-static inline void set_tlb_flush_pending(struct mm_struct *mm)
-{
-}
-static inline void clear_tlb_flush_pending(struct mm_struct *mm)
+static inline void dec_tlb_flush_pending(struct mm_struct *mm)
{
+ /*
+ * Guarantee that the tlb_flush_pending does not not leak into the
+ * critical section, since we must order the PTE change and changes to
+ * the pending TLB flush indication. We could have relied on TLB flush
+ * as a memory barrier, but this behavior is not clearly documented.
+ */
+ smp_mb__before_atomic();
+ atomic_dec(&mm->tlb_flush_pending);
}
-#endif
struct vm_fault;
diff --git a/include/linux/module.h b/include/linux/module.h
index 8eb9a1e693e5..e7bdd549e527 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -45,7 +45,7 @@ struct module_kobject {
struct kobject *drivers_dir;
struct module_param_attrs *mp;
struct completion *kobj_completion;
-};
+} __randomize_layout;
struct module_attribute {
struct attribute attr;
@@ -475,7 +475,7 @@ struct module {
ctor_fn_t *ctors;
unsigned int num_ctors;
#endif
-} ____cacheline_aligned;
+} ____cacheline_aligned __randomize_layout;
#ifndef MODULE_ARCH_INIT
#define MODULE_ARCH_INIT {}
#endif
diff --git a/include/linux/mount.h b/include/linux/mount.h
index 8e0352af06b7..1ce85e6fd95f 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -67,7 +67,7 @@ struct vfsmount {
struct dentry *mnt_root; /* root of the mounted tree */
struct super_block *mnt_sb; /* pointer to superblock */
int mnt_flags;
-};
+} __randomize_layout;
struct file; /* forward dec */
struct path;
diff --git a/include/linux/msg.h b/include/linux/msg.h
index f3f302f9c197..a001305f5a79 100644
--- a/include/linux/msg.h
+++ b/include/linux/msg.h
@@ -29,7 +29,7 @@ struct msg_queue {
struct list_head q_messages;
struct list_head q_receivers;
struct list_head q_senders;
-};
+} __randomize_layout;
/* Helper routines for sys_msgsnd and sys_msgrcv */
extern long do_msgsnd(int msqid, long mtype, void __user *mtext,
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 892148c448cc..5216d2eb2289 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -681,10 +681,10 @@ struct nand_buffers {
* @tWW_min: WP# transition to WE# low
*/
struct nand_sdr_timings {
- u32 tBERS_max;
+ u64 tBERS_max;
u32 tCCS_min;
- u32 tPROG_max;
- u32 tR_max;
+ u64 tPROG_max;
+ u64 tR_max;
u32 tALH_min;
u32 tADL_min;
u32 tALS_min;
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index a4b97be30b28..22f081065d49 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -61,8 +61,6 @@ typedef unsigned int nf_hookfn(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state);
struct nf_hook_ops {
- struct list_head list;
-
/* User fills in from here down. */
nf_hookfn *hook;
struct net_device *dev;
@@ -160,13 +158,6 @@ int nf_register_net_hooks(struct net *net, const struct nf_hook_ops *reg,
void nf_unregister_net_hooks(struct net *net, const struct nf_hook_ops *reg,
unsigned int n);
-int nf_register_hook(struct nf_hook_ops *reg);
-void nf_unregister_hook(struct nf_hook_ops *reg);
-int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n);
-void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n);
-int _nf_register_hooks(struct nf_hook_ops *reg, unsigned int n);
-void _nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n);
-
/* Functions to register get/setsockopt ranges (non-inclusive). You
need to check permissions yourself! */
int nf_register_sockopt(struct nf_sockopt_ops *reg);
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index e52cc55ac300..5cc91d6381a3 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -51,7 +51,7 @@ struct nfs_access_entry {
struct list_head lru;
unsigned long jiffies;
struct rpc_cred * cred;
- int mask;
+ __u32 mask;
struct rcu_head rcu_head;
};
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index ca3bcc4ed4e5..62cbcb842f99 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1235,7 +1235,7 @@ struct nfs41_state_protection {
struct nfs41_exchange_id_args {
struct nfs_client *client;
- nfs4_verifier *verifier;
+ nfs4_verifier verifier;
u32 flags;
struct nfs41_state_protection state_protect;
};
diff --git a/include/linux/nvme-fc-driver.h b/include/linux/nvme-fc-driver.h
index 6c8c5d8041b7..2591878c1d48 100644
--- a/include/linux/nvme-fc-driver.h
+++ b/include/linux/nvme-fc-driver.h
@@ -346,6 +346,11 @@ struct nvme_fc_remote_port {
* indicating an FC transport Aborted status.
* Entrypoint is Mandatory.
*
+ * @defer_rcv: Called by the transport to signal the LLLD that it has
+ * begun processing of a previously received NVME CMD IU. The LLDD
+ * is now free to re-use the rcv buffer associated with the
+ * nvmefc_tgt_fcp_req.
+ *
* @max_hw_queues: indicates the maximum number of hw queues the LLDD
* supports for cpu affinitization.
* Value is Mandatory. Must be at least 1.
@@ -846,6 +851,8 @@ struct nvmet_fc_target_template {
struct nvmefc_tgt_fcp_req *fcpreq);
void (*fcp_req_release)(struct nvmet_fc_target_port *tgtport,
struct nvmefc_tgt_fcp_req *fcpreq);
+ void (*defer_rcv)(struct nvmet_fc_target_port *tgtport,
+ struct nvmefc_tgt_fcp_req *fcpreq);
u32 max_hw_queues;
u16 max_sgl_segments;
diff --git a/include/linux/nvme-fc.h b/include/linux/nvme-fc.h
index 21c37e39e41a..36cca93a5ff2 100644
--- a/include/linux/nvme-fc.h
+++ b/include/linux/nvme-fc.h
@@ -334,5 +334,24 @@ struct fcnvme_ls_disconnect_acc {
#define NVME_FC_LS_TIMEOUT_SEC 2 /* 2 seconds */
#define NVME_FC_TGTOP_TIMEOUT_SEC 2 /* 2 seconds */
+/*
+ * TRADDR string must be of form "nn-<16hexdigits>:pn-<16hexdigits>"
+ * the string is allowed to be specified with or without a "0x" prefix
+ * infront of the <16hexdigits>. Without is considered the "min" string
+ * and with is considered the "max" string. The hexdigits may be upper
+ * or lower case.
+ */
+#define NVME_FC_TRADDR_NNLEN 3 /* "?n-" */
+#define NVME_FC_TRADDR_OXNNLEN 5 /* "?n-0x" */
+#define NVME_FC_TRADDR_HEXNAMELEN 16
+#define NVME_FC_TRADDR_MINLENGTH \
+ (2 * (NVME_FC_TRADDR_NNLEN + NVME_FC_TRADDR_HEXNAMELEN) + 1)
+#define NVME_FC_TRADDR_MAXLENGTH \
+ (2 * (NVME_FC_TRADDR_OXNNLEN + NVME_FC_TRADDR_HEXNAMELEN) + 1)
+#define NVME_FC_TRADDR_MIN_PN_OFFSET \
+ (NVME_FC_TRADDR_NNLEN + NVME_FC_TRADDR_HEXNAMELEN + 1)
+#define NVME_FC_TRADDR_MAX_PN_OFFSET \
+ (NVME_FC_TRADDR_OXNNLEN + NVME_FC_TRADDR_HEXNAMELEN + 1)
+
#endif /* _NVME_FC_H */
diff --git a/include/linux/nvme.h b/include/linux/nvme.h
index 6b8ee9e628e1..25d8225dbd04 100644
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -963,14 +963,14 @@ struct nvme_dbbuf {
};
struct streams_directive_params {
- __u16 msl;
- __u16 nssa;
- __u16 nsso;
+ __le16 msl;
+ __le16 nssa;
+ __le16 nsso;
__u8 rsvd[10];
- __u32 sws;
- __u16 sgs;
- __u16 nsa;
- __u16 nso;
+ __le32 sws;
+ __le16 sgs;
+ __le16 nsa;
+ __le16 nso;
__u8 rsvd2[6];
};
@@ -1006,7 +1006,7 @@ static inline bool nvme_is_write(struct nvme_command *cmd)
* Why can't we simply have a Fabrics In and Fabrics out command?
*/
if (unlikely(cmd->common.opcode == nvme_fabrics_command))
- return cmd->fabrics.opcode & 1;
+ return cmd->fabrics.fctype & 1;
return cmd->common.opcode & 1;
}
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index baa9344dcd10..79b36f57c3ba 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -163,8 +163,6 @@ void release_pages(struct page **pages, int nr, bool cold);
*/
static inline int page_cache_get_speculative(struct page *page)
{
- VM_BUG_ON(in_interrupt());
-
#ifdef CONFIG_TINY_RCU
# ifdef CONFIG_PREEMPT_COUNT
VM_BUG_ON(!in_atomic() && !irqs_disabled());
diff --git a/include/linux/path.h b/include/linux/path.h
index d1372186f431..cde895cc4af4 100644
--- a/include/linux/path.h
+++ b/include/linux/path.h
@@ -7,7 +7,7 @@ struct vfsmount;
struct path {
struct vfsmount *mnt;
struct dentry *dentry;
-};
+} __randomize_layout;
extern void path_get(const struct path *);
extern void path_put(const struct path *);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 4869e66dd659..a75c13673852 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1067,6 +1067,7 @@ void pcie_flr(struct pci_dev *dev);
int __pci_reset_function(struct pci_dev *dev);
int __pci_reset_function_locked(struct pci_dev *dev);
int pci_reset_function(struct pci_dev *dev);
+int pci_reset_function_locked(struct pci_dev *dev);
int pci_try_reset_function(struct pci_dev *dev);
int pci_probe_reset_slot(struct pci_slot *slot);
int pci_reset_slot(struct pci_slot *slot);
diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
index 1360dd6d5e61..af0f44effd44 100644
--- a/include/linux/perf/arm_pmu.h
+++ b/include/linux/perf/arm_pmu.h
@@ -24,10 +24,14 @@
* interrupt and passed the address of the low level handler,
* and can be used to implement any platform specific handling
* before or after calling it.
+ *
+ * @irq_flags: if non-zero, these flags will be passed to request_irq
+ * when requesting interrupts for this PMU device.
*/
struct arm_pmu_platdata {
irqreturn_t (*handle_irq)(int irq, void *dev,
irq_handler_t pmu_handler);
+ unsigned long irq_flags;
};
#ifdef CONFIG_ARM_PMU
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 2a9567bb8186..0bb5b212ab42 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -830,7 +830,7 @@ static inline int phy_read_status(struct phy_device *phydev)
dev_err(&_phydev->mdio.dev, format, ##args)
#define phydev_dbg(_phydev, format, args...) \
- dev_dbg(&_phydev->mdio.dev, format, ##args);
+ dev_dbg(&_phydev->mdio.dev, format, ##args)
static inline const char *phydev_name(const struct phy_device *phydev)
{
diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h
index c2a989dee876..b09136f88cf4 100644
--- a/include/linux/pid_namespace.h
+++ b/include/linux/pid_namespace.h
@@ -52,7 +52,7 @@ struct pid_namespace {
int hide_pid;
int reboot; /* group exit code if this pidns was rebooted */
struct ns_common ns;
-};
+} __randomize_layout;
extern struct pid_namespace init_pid_ns;
diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h
index 231d3075815a..e91d1b6a260d 100644
--- a/include/linux/pinctrl/pinconf-generic.h
+++ b/include/linux/pinctrl/pinconf-generic.h
@@ -81,8 +81,8 @@
* it.
* @PIN_CONFIG_OUTPUT: this will configure the pin as an output and drive a
* value on the line. Use argument 1 to indicate high level, argument 0 to
- * indicate low level. (Please see Documentation/pinctrl.txt, section
- * "GPIO mode pitfalls" for a discussion around this parameter.)
+ * indicate low level. (Please see Documentation/driver-api/pinctl.rst,
+ * section "GPIO mode pitfalls" for a discussion around this parameter.)
* @PIN_CONFIG_POWER_SOURCE: if the pin can select between different power
* supplies, the argument to this parameter (on a custom format) tells
* the driver which alternative power source to use.
diff --git a/include/linux/platform_data/hsmmc-omap.h b/include/linux/platform_data/hsmmc-omap.h
index 8e981be2e2c2..0ff1e0dba720 100644
--- a/include/linux/platform_data/hsmmc-omap.h
+++ b/include/linux/platform_data/hsmmc-omap.h
@@ -55,9 +55,6 @@ struct omap_hsmmc_platform_data {
u32 caps; /* Used for the MMC driver on 2430 and later */
u32 pm_caps; /* PM capabilities of the mmc */
- /* use the internal clock */
- unsigned internal_clock:1;
-
/* nonremovable e.g. eMMC */
unsigned nonremovable:1;
@@ -73,13 +70,6 @@ struct omap_hsmmc_platform_data {
int gpio_cd; /* gpio (card detect) */
int gpio_cod; /* gpio (cover detect) */
int gpio_wp; /* gpio (write protect) */
-
- int (*set_power)(struct device *dev, int power_on, int vdd);
- void (*remux)(struct device *dev, int power_on);
- /* Call back before enabling / disabling regulators */
- void (*before_set_reg)(struct device *dev, int power_on, int vdd);
- /* Call back after enabling / disabling regulators */
- void (*after_set_reg)(struct device *dev, int power_on, int vdd);
/* if we have special card, init it using this callback */
void (*init_card)(struct mmc_card *card);
diff --git a/include/linux/platform_data/omap_drm.h b/include/linux/platform_data/omap_drm.h
deleted file mode 100644
index f4e4a237ebd2..000000000000
--- a/include/linux/platform_data/omap_drm.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * DRM/KMS platform data for TI OMAP platforms
- *
- * Copyright (C) 2012 Texas Instruments
- * Author: Rob Clark <rob.clark@linaro.org>
- *
- * 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.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __PLATFORM_DATA_OMAP_DRM_H__
-#define __PLATFORM_DATA_OMAP_DRM_H__
-
-/*
- * Optional platform data to configure the default configuration of which
- * pipes/overlays/CRTCs are used.. if this is not provided, then instead the
- * first CONFIG_DRM_OMAP_NUM_CRTCS are used, and they are each connected to
- * one manager, with priority given to managers that are connected to
- * detected devices. Remaining overlays are used as video planes. This
- * should be a good default behavior for most cases, but yet there still
- * might be times when you wish to do something different.
- */
-struct omap_kms_platform_data {
- /* overlays to use as CRTCs: */
- int ovl_cnt;
- const int *ovl_ids;
-
- /* overlays to use as video planes: */
- int pln_cnt;
- const int *pln_ids;
-
- int mgr_cnt;
- const int *mgr_ids;
-
- int dev_cnt;
- const char **dev_names;
-};
-
-struct omap_drm_platform_data {
- uint32_t omaprev;
- struct omap_kms_platform_data *kms_pdata;
-};
-
-#endif /* __PLATFORM_DATA_OMAP_DRM_H__ */
diff --git a/include/linux/platform_data/st_sensors_pdata.h b/include/linux/platform_data/st_sensors_pdata.h
index 79b0e4cdb814..f8274b0c6888 100644
--- a/include/linux/platform_data/st_sensors_pdata.h
+++ b/include/linux/platform_data/st_sensors_pdata.h
@@ -17,10 +17,12 @@
* Available only for accelerometer and pressure sensors.
* Accelerometer DRDY on LSM330 available only on pin 1 (see datasheet).
* @open_drain: set the interrupt line to be open drain if possible.
+ * @spi_3wire: enable spi-3wire mode.
*/
struct st_sensors_platform_data {
u8 drdy_int_pin;
bool open_drain;
+ bool spi_3wire;
};
#endif /* ST_SENSORS_PDATA_H */
diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h
index 58ab28d81fc2..06844b54dfc1 100644
--- a/include/linux/proc_ns.h
+++ b/include/linux/proc_ns.h
@@ -21,7 +21,7 @@ struct proc_ns_operations {
int (*install)(struct nsproxy *nsproxy, struct ns_common *ns);
struct user_namespace *(*owner)(struct ns_common *ns);
struct ns_common *(*get_parent)(struct ns_common *ns);
-};
+} __randomize_layout;
extern const struct proc_ns_operations netns_operations;
extern const struct proc_ns_operations utsns_operations;
diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h
index a026bfd089db..51349d124ee5 100644
--- a/include/linux/ptp_clock_kernel.h
+++ b/include/linux/ptp_clock_kernel.h
@@ -99,6 +99,11 @@ struct system_device_crosststamp;
* parameter func: the desired function to use.
* parameter chan: the function channel index to use.
*
+ * @do_work: Request driver to perform auxiliary (periodic) operations
+ * Driver should return delay of the next auxiliary work scheduling
+ * time (>=0) or negative value in case further scheduling
+ * is not required.
+ *
* Drivers should embed their ptp_clock_info within a private
* structure, obtaining a reference to it using container_of().
*
@@ -126,6 +131,7 @@ struct ptp_clock_info {
struct ptp_clock_request *request, int on);
int (*verify)(struct ptp_clock_info *ptp, unsigned int pin,
enum ptp_pin_function func, unsigned int chan);
+ long (*do_aux_work)(struct ptp_clock_info *ptp);
};
struct ptp_clock;
@@ -211,6 +217,16 @@ extern int ptp_clock_index(struct ptp_clock *ptp);
int ptp_find_pin(struct ptp_clock *ptp,
enum ptp_pin_function func, unsigned int chan);
+/**
+ * ptp_schedule_worker() - schedule ptp auxiliary work
+ *
+ * @ptp: The clock obtained from ptp_clock_register().
+ * @delay: number of jiffies to wait before queuing
+ * See kthread_queue_delayed_work() for more info.
+ */
+
+int ptp_schedule_worker(struct ptp_clock *ptp, unsigned long delay);
+
#else
static inline struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
struct device *parent)
@@ -225,6 +241,10 @@ static inline int ptp_clock_index(struct ptp_clock *ptp)
static inline int ptp_find_pin(struct ptp_clock *ptp,
enum ptp_pin_function func, unsigned int chan)
{ return -1; }
+static inline int ptp_schedule_worker(struct ptp_clock *ptp,
+ unsigned long delay)
+{ return -EOPNOTSUPP; }
+
#endif
#endif
diff --git a/include/linux/reservation.h b/include/linux/reservation.h
index 156cfd330b66..21fc84d82d41 100644
--- a/include/linux/reservation.h
+++ b/include/linux/reservation.h
@@ -254,6 +254,9 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj,
unsigned *pshared_count,
struct dma_fence ***pshared);
+int reservation_object_copy_fences(struct reservation_object *dst,
+ struct reservation_object *src);
+
long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
bool wait_all, bool intr,
unsigned long timeout);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 2ba9ec93423f..8337e2db0bb2 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -426,7 +426,7 @@ struct sched_rt_entity {
/* rq "owned" by this entity/group: */
struct rt_rq *my_q;
#endif
-};
+} __randomize_layout;
struct sched_dl_entity {
struct rb_node rb_node;
@@ -526,6 +526,13 @@ struct task_struct {
#endif
/* -1 unrunnable, 0 runnable, >0 stopped: */
volatile long state;
+
+ /*
+ * This begins the randomizable portion of task_struct. Only
+ * scheduling-critical items should be added above here.
+ */
+ randomized_struct_fields_start
+
void *stack;
atomic_t usage;
/* Per task flags (PF_*), defined further below: */
@@ -1079,6 +1086,13 @@ struct task_struct {
/* Used by LSM modules for access restriction: */
void *security;
#endif
+
+ /*
+ * New fields for task_struct should be added above here, so that
+ * they are included in the randomized portion of task_struct.
+ */
+ randomized_struct_fields_end
+
/* CPU-specific state of this task: */
struct thread_struct thread;
diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h
index c06d63b3a583..2a0dd40b15db 100644
--- a/include/linux/sched/signal.h
+++ b/include/linux/sched/signal.h
@@ -222,7 +222,7 @@ struct signal_struct {
struct mutex cred_guard_mutex; /* guard against foreign influences on
* credential calculations
* (notably. ptrace) */
-};
+} __randomize_layout;
/*
* Bits in flags field of signal_struct.
diff --git a/include/linux/sem.h b/include/linux/sem.h
index be5cf2ea14ad..de2deb8676bd 100644
--- a/include/linux/sem.h
+++ b/include/linux/sem.h
@@ -41,7 +41,7 @@ struct sem_array {
unsigned int use_global_lock;/* >0: global lock required */
struct sem sems[];
-};
+} __randomize_layout;
#ifdef CONFIG_SYSVIPC
diff --git a/include/linux/shm.h b/include/linux/shm.h
index 04e881829625..0fb7061ec54c 100644
--- a/include/linux/shm.h
+++ b/include/linux/shm.h
@@ -22,7 +22,7 @@ struct shmid_kernel /* private to the kernel */
/* The task created the shm object. NULL if the task is dead. */
struct task_struct *shm_creator;
struct list_head shm_clist; /* list by creator */
-};
+} __randomize_layout;
/* shm_mode upper byte flags */
#define SHM_DEST 01000 /* segment will be destroyed on last detach */
diff --git a/include/linux/sync_file.h b/include/linux/sync_file.h
index 5726107963b2..0ad87c434ae6 100644
--- a/include/linux/sync_file.h
+++ b/include/linux/sync_file.h
@@ -43,12 +43,13 @@ struct sync_file {
#endif
wait_queue_head_t wq;
+ unsigned long flags;
struct dma_fence *fence;
struct dma_fence_cb cb;
};
-#define POLL_ENABLED DMA_FENCE_FLAG_USER_BITS
+#define POLL_ENABLED 0
struct sync_file *sync_file_create(struct dma_fence *fence);
struct dma_fence *sync_file_get_fence(int fd);
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 3a89b9ff4cdc..1d4dba490fb6 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -120,7 +120,7 @@ struct ctl_table
struct ctl_table_poll *poll;
void *extra1;
void *extra2;
-};
+} __randomize_layout;
struct ctl_node {
struct rb_node node;
diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index f73cedfa2e0b..536c80ff7ad9 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -338,7 +338,7 @@ enum {
struct trace_event_file {
struct list_head list;
struct trace_event_call *event_call;
- struct event_filter *filter;
+ struct event_filter __rcu *filter;
struct dentry *dir;
struct trace_array *tr;
struct trace_subsystem_dir *system;
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 69464c0d8068..79c30daf46a9 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -332,7 +332,7 @@ struct tty_struct {
/* If the tty has a pending do_SAK, queue it here - akpm */
struct work_struct SAK_work;
struct tty_port *port;
-};
+} __randomize_layout;
/* Each of a tty's open files has private_data pointing to tty_file_private */
struct tty_file_private {
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index b742b5e47cc2..00b2213f6a35 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -291,7 +291,7 @@ struct tty_operations {
void (*poll_put_char)(struct tty_driver *driver, int line, char ch);
#endif
const struct file_operations *proc_fops;
-};
+} __randomize_layout;
struct tty_driver {
int magic; /* magic number for this structure */
@@ -325,7 +325,7 @@ struct tty_driver {
const struct tty_operations *ops;
struct list_head tty_drivers;
-};
+} __randomize_layout;
extern struct list_head tty_drivers;
diff --git a/include/linux/usb/audio-v2.h b/include/linux/usb/audio-v2.h
index c5f2158ab00e..fd73bc0e9027 100644
--- a/include/linux/usb/audio-v2.h
+++ b/include/linux/usb/audio-v2.h
@@ -115,13 +115,13 @@ struct uac2_input_terminal_descriptor {
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bTerminalID;
- __u16 wTerminalType;
+ __le16 wTerminalType;
__u8 bAssocTerminal;
__u8 bCSourceID;
__u8 bNrChannels;
- __u32 bmChannelConfig;
+ __le32 bmChannelConfig;
__u8 iChannelNames;
- __u16 bmControls;
+ __le16 bmControls;
__u8 iTerminal;
} __attribute__((packed));
@@ -132,11 +132,11 @@ struct uac2_output_terminal_descriptor {
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bTerminalID;
- __u16 wTerminalType;
+ __le16 wTerminalType;
__u8 bAssocTerminal;
__u8 bSourceID;
__u8 bCSourceID;
- __u16 bmControls;
+ __le16 bmControls;
__u8 iTerminal;
} __attribute__((packed));
@@ -164,9 +164,9 @@ struct uac2_as_header_descriptor {
__u8 bTerminalLink;
__u8 bmControls;
__u8 bFormatType;
- __u32 bmFormats;
+ __le32 bmFormats;
__u8 bNrChannels;
- __u32 bmChannelConfig;
+ __le32 bmChannelConfig;
__u8 iChannelNames;
} __attribute__((packed));
diff --git a/include/linux/usb/cdc_ncm.h b/include/linux/usb/cdc_ncm.h
index 021f7a88f52c..1a59699cf82a 100644
--- a/include/linux/usb/cdc_ncm.h
+++ b/include/linux/usb/cdc_ncm.h
@@ -83,6 +83,7 @@
/* Driver flags */
#define CDC_NCM_FLAG_NDP_TO_END 0x02 /* NDP is placed at end of frame */
#define CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE 0x04 /* Avoid altsetting toggle during init */
+#define CDC_NCM_FLAG_RESET_NTB16 0x08 /* set NDP16 one more time after altsetting switch */
#define cdc_ncm_comm_intf_is_mbim(x) ((x)->desc.bInterfaceSubClass == USB_CDC_SUBCLASS_MBIM && \
(x)->desc.bInterfaceProtocol == USB_CDC_PROTO_NONE)
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index 32354b4b4b2b..b3575ce29148 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -66,7 +66,7 @@ struct user_namespace {
#endif
struct ucounts *ucounts;
int ucount_max[UCOUNT_COUNTS];
-};
+} __randomize_layout;
struct ucounts {
struct hlist_node node;
diff --git a/include/linux/utsname.h b/include/linux/utsname.h
index 60f0bb83b313..da826ed059cf 100644
--- a/include/linux/utsname.h
+++ b/include/linux/utsname.h
@@ -26,7 +26,7 @@ struct uts_namespace {
struct user_namespace *user_ns;
struct ucounts *ucounts;
struct ns_common ns;
-};
+} __randomize_layout;
extern struct uts_namespace init_uts_ns;
#ifdef CONFIG_UTS_NS
diff --git a/include/linux/uuid.h b/include/linux/uuid.h
index 2251e1925ea4..33b0bdbb613c 100644
--- a/include/linux/uuid.h
+++ b/include/linux/uuid.h
@@ -84,26 +84,12 @@ int guid_parse(const char *uuid, guid_t *u);
int uuid_parse(const char *uuid, uuid_t *u);
/* backwards compatibility, don't use in new code */
-typedef uuid_t uuid_be;
-#define UUID_BE(a, _b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
- UUID_INIT(a, _b, c, d0, d1, d2, d3, d4, d5, d6, d7)
-#define NULL_UUID_BE \
- UUID_BE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00)
-
#define uuid_le_gen(u) guid_gen(u)
-#define uuid_be_gen(u) uuid_gen(u)
#define uuid_le_to_bin(guid, u) guid_parse(guid, u)
-#define uuid_be_to_bin(uuid, u) uuid_parse(uuid, u)
static inline int uuid_le_cmp(const guid_t u1, const guid_t u2)
{
return memcmp(&u1, &u2, sizeof(guid_t));
}
-static inline int uuid_be_cmp(const uuid_t u1, const uuid_t u2)
-{
- return memcmp(&u1, &u2, sizeof(uuid_t));
-}
-
#endif
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index 586809abb273..a47b985341d1 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -152,7 +152,7 @@ extern int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr,
size_t *data_size);
struct pci_dev;
-#ifdef CONFIG_EEH
+#if IS_ENABLED(CONFIG_VFIO_SPAPR_EEH)
extern void vfio_spapr_pci_eeh_open(struct pci_dev *pdev);
extern void vfio_spapr_pci_eeh_release(struct pci_dev *pdev);
extern long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,
@@ -173,7 +173,7 @@ static inline long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,
{
return -ENOTTY;
}
-#endif /* CONFIG_EEH */
+#endif /* CONFIG_VFIO_SPAPR_EEH */
/*
* IRQfd - generic
diff --git a/include/linux/wait.h b/include/linux/wait.h
index b289c96151ee..5b74e36c0ca8 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -529,13 +529,13 @@ do { \
/**
* wait_event_interruptible_hrtimeout - sleep until a condition gets true or a timeout elapses
- * @wq_head: the waitqueue to wait on
+ * @wq: the waitqueue to wait on
* @condition: a C expression for the event to wait for
* @timeout: timeout, as a ktime_t
*
* The process is put to sleep (TASK_INTERRUPTIBLE) until the
* @condition evaluates to true or a signal is received.
- * The @condition is checked each time the waitqueue @wq_head is woken up.
+ * The @condition is checked each time the waitqueue @wq is woken up.
*
* wake_up() has to be called after changing any variable that could
* change the result of the wait condition.
@@ -735,12 +735,12 @@ extern int do_wait_intr_irq(wait_queue_head_t *, wait_queue_entry_t *);
/**
* wait_event_killable - sleep until a condition gets true
- * @wq: the waitqueue to wait on
+ * @wq_head: the waitqueue to wait on
* @condition: a C expression for the event to wait for
*
* The process is put to sleep (TASK_KILLABLE) until the
* @condition evaluates to true or a signal is received.
- * The @condition is checked each time the waitqueue @wq is woken up.
+ * The @condition is checked each time the waitqueue @wq_head is woken up.
*
* wake_up() has to be called after changing any variable that could
* change the result of the wait condition.
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index c102ef65cb64..db6dc9dc0482 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -323,6 +323,7 @@ enum {
__WQ_DRAINING = 1 << 16, /* internal: workqueue is draining */
__WQ_ORDERED = 1 << 17, /* internal: workqueue is ordered */
+ __WQ_ORDERED_EXPLICIT = 1 << 18, /* internal: alloc_ordered_workqueue() */
__WQ_LEGACY = 1 << 18, /* internal: create*_workqueue() */
WQ_MAX_ACTIVE = 512, /* I like 512, better ideas? */
@@ -422,7 +423,8 @@ __alloc_workqueue_key(const char *fmt, unsigned int flags, int max_active,
* Pointer to the allocated workqueue on success, %NULL on failure.
*/
#define alloc_ordered_workqueue(fmt, flags, args...) \
- alloc_workqueue(fmt, WQ_UNBOUND | __WQ_ORDERED | (flags), 1, ##args)
+ alloc_workqueue(fmt, WQ_UNBOUND | __WQ_ORDERED | \
+ __WQ_ORDERED_EXPLICIT | (flags), 1, ##args)
#define create_workqueue(name) \
alloc_workqueue("%s", __WQ_LEGACY | WQ_MEM_RECLAIM, 1, (name))
diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h
index 298f996969df..a4f7429c4ae5 100644
--- a/include/media/cec-notifier.h
+++ b/include/media/cec-notifier.h
@@ -57,6 +57,7 @@ void cec_notifier_put(struct cec_notifier *n);
* @pa: the CEC physical address
*
* Set a new CEC physical address.
+ * Does nothing if @n == NULL.
*/
void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa);
@@ -66,6 +67,7 @@ void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa);
* @edid: the struct edid pointer
*
* Parses the EDID to obtain the new CEC physical address and set it.
+ * Does nothing if @n == NULL.
*/
void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n,
const struct edid *edid);
@@ -118,4 +120,17 @@ static inline void cec_notifier_unregister(struct cec_notifier *n)
#endif
+/**
+ * cec_notifier_phys_addr_invalidate() - set the physical address to INVALID
+ *
+ * @n: the CEC notifier
+ *
+ * This is a simple helper function to invalidate the physical
+ * address. Does nothing if @n == NULL.
+ */
+static inline void cec_notifier_phys_addr_invalidate(struct cec_notifier *n)
+{
+ cec_notifier_set_phys_addr(n, CEC_PHYS_ADDR_INVALID);
+}
+
#endif
diff --git a/include/media/davinci/dm644x_ccdc.h b/include/media/davinci/dm644x_ccdc.h
index 7c909da29d43..6ea2ce241851 100644
--- a/include/media/davinci/dm644x_ccdc.h
+++ b/include/media/davinci/dm644x_ccdc.h
@@ -103,16 +103,6 @@ struct ccdc_black_compensation {
char gb;
};
-/* structure for fault pixel correction */
-struct ccdc_fault_pixel {
- /* Enable or Disable fault pixel correction */
- unsigned char enable;
- /* Number of fault pixel */
- unsigned short fp_num;
- /* Address of fault pixel table */
- unsigned long fpc_table_addr;
-};
-
/* Structure for CCDC configuration parameters for raw capture mode passed
* by application
*/
@@ -125,8 +115,6 @@ struct ccdc_config_params_raw {
struct ccdc_black_clamp blk_clamp;
/* Structure for Black Compensation */
struct ccdc_black_compensation blk_comp;
- /* Structure for Fault Pixel Module Configuration */
- struct ccdc_fault_pixel fault_pxl;
};
diff --git a/include/media/davinci/vpfe_capture.h b/include/media/davinci/vpfe_capture.h
index 8e1a4d88daa0..f003533602d0 100644
--- a/include/media/davinci/vpfe_capture.h
+++ b/include/media/davinci/vpfe_capture.h
@@ -183,14 +183,4 @@ struct vpfe_config_params {
};
#endif /* End of __KERNEL__ */
-/**
- * VPFE_CMD_S_CCDC_RAW_PARAMS - EXPERIMENTAL IOCTL to set raw capture params
- * This can be used to configure modules such as defect pixel correction,
- * color space conversion, culling etc. This is an experimental ioctl that
- * will change in future kernels. So use this ioctl with care !
- * TODO: This is to be split into multiple ioctls and also explore the
- * possibility of extending the v4l2 api to include this
- **/
-#define VPFE_CMD_S_CCDC_RAW_PARAMS _IOW('V', BASE_VIDIOC_PRIVATE + 1, \
- void *)
#endif /* _DAVINCI_VPFE_H */
diff --git a/include/media/vsp1.h b/include/media/vsp1.h
index c837383b2013..68a8abe4fac5 100644
--- a/include/media/vsp1.h
+++ b/include/media/vsp1.h
@@ -34,11 +34,12 @@ struct vsp1_du_lif_config {
unsigned int width;
unsigned int height;
- void (*callback)(void *);
+ void (*callback)(void *, bool);
void *callback_data;
};
-int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg);
+int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index,
+ const struct vsp1_du_lif_config *cfg);
struct vsp1_du_atomic_config {
u32 pixelformat;
@@ -50,10 +51,11 @@ struct vsp1_du_atomic_config {
unsigned int zpos;
};
-void vsp1_du_atomic_begin(struct device *dev);
-int vsp1_du_atomic_update(struct device *dev, unsigned int rpf,
+void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index);
+int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
+ unsigned int rpf,
const struct vsp1_du_atomic_config *cfg);
-void vsp1_du_atomic_flush(struct device *dev);
+void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index);
int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt);
void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt);
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 678e4d6fa317..53b1a2cca421 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -37,7 +37,7 @@ struct unix_skb_parms {
u32 secid; /* Security ID */
#endif
u32 consumed;
-};
+} __randomize_layout;
#define UNIXCB(skb) (*(struct unix_skb_parms *)&((skb)->cb))
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index afc39e3a3f7c..9816df225af3 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -156,7 +156,7 @@ struct neighbour {
struct rcu_head rcu;
struct net_device *dev;
u8 primary_key[0];
-};
+} __randomize_layout;
struct neigh_ops {
int family;
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 31a2b51bef2c..1c401bd4c2e0 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -148,7 +148,7 @@ struct net {
#endif
struct sock *diag_nlsk;
atomic_t fnhe_genid;
-};
+} __randomize_layout;
#include <linux/seq_file_net.h>
diff --git a/include/net/netlink.h b/include/net/netlink.h
index 01709172b3d3..ef8e6c3a80a6 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -98,8 +98,8 @@
* nla_put_u8(skb, type, value) add u8 attribute to skb
* nla_put_u16(skb, type, value) add u16 attribute to skb
* nla_put_u32(skb, type, value) add u32 attribute to skb
- * nla_put_u64_64bits(skb, type,
- * value, padattr) add u64 attribute to skb
+ * nla_put_u64_64bit(skb, type,
+ * value, padattr) add u64 attribute to skb
* nla_put_s8(skb, type, value) add s8 attribute to skb
* nla_put_s16(skb, type, value) add s16 attribute to skb
* nla_put_s32(skb, type, value) add s32 attribute to skb
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index a9519a06a23b..45fd4c6056b5 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -469,6 +469,8 @@ _sctp_walk_params((pos), (chunk), ntohs((chunk)->chunk_hdr.length), member)
#define _sctp_walk_params(pos, chunk, end, member)\
for (pos.v = chunk->member;\
+ (pos.v + offsetof(struct sctp_paramhdr, length) + sizeof(pos.p->length) <=\
+ (void *)chunk + end) &&\
pos.v <= (void *)chunk + end - ntohs(pos.p->length) &&\
ntohs(pos.p->length) >= sizeof(struct sctp_paramhdr);\
pos.v += SCTP_PAD4(ntohs(pos.p->length)))
@@ -479,6 +481,8 @@ _sctp_walk_errors((err), (chunk_hdr), ntohs((chunk_hdr)->length))
#define _sctp_walk_errors(err, chunk_hdr, end)\
for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \
sizeof(struct sctp_chunkhdr));\
+ ((void *)err + offsetof(sctp_errhdr_t, length) + sizeof(err->length) <=\
+ (void *)chunk_hdr + end) &&\
(void *)err <= (void *)chunk_hdr + end - ntohs(err->length) &&\
ntohs(err->length) >= sizeof(sctp_errhdr_t); \
err = (sctp_errhdr_t *)((void *)err + SCTP_PAD4(ntohs(err->length))))
diff --git a/include/net/sock.h b/include/net/sock.h
index f69c8c2782df..7c0632c7e870 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1128,7 +1128,7 @@ struct proto {
atomic_t socks;
#endif
int (*diag_destroy)(struct sock *sk, int err);
-};
+} __randomize_layout;
int proto_register(struct proto *prot, int alloc_slab);
void proto_unregister(struct proto *prot);
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 70483296157f..ada65e767b28 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1916,6 +1916,16 @@ extern void tcp_rack_advance(struct tcp_sock *tp, u8 sacked, u32 end_seq,
u64 xmit_time);
extern void tcp_rack_reo_timeout(struct sock *sk);
+/* At how many usecs into the future should the RTO fire? */
+static inline s64 tcp_rto_delta_us(const struct sock *sk)
+{
+ const struct sk_buff *skb = tcp_write_queue_head(sk);
+ u32 rto = inet_csk(sk)->icsk_rto;
+ u64 rto_time_stamp_us = skb->skb_mstamp + jiffies_to_usecs(rto);
+
+ return rto_time_stamp_us - tcp_sk(sk)->tcp_mstamp;
+}
+
/*
* Save and compile IPv4 options, return a pointer to it
*/
diff --git a/include/net/udp.h b/include/net/udp.h
index 972ce4baab6b..cc8036987dcb 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -260,6 +260,7 @@ static inline struct sk_buff *skb_recv_udp(struct sock *sk, unsigned int flags,
}
void udp_v4_early_demux(struct sk_buff *skb);
+void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst);
int udp_get_port(struct sock *sk, unsigned short snum,
int (*saddr_cmp)(const struct sock *,
const struct sock *));
@@ -305,33 +306,44 @@ struct sock *udp6_lib_lookup_skb(struct sk_buff *skb,
/* UDP uses skb->dev_scratch to cache as much information as possible and avoid
* possibly multiple cache miss on dequeue()
*/
-#if BITS_PER_LONG == 64
-
-/* truesize, len and the bit needed to compute skb_csum_unnecessary will be on
- * cold cache lines at recvmsg time.
- * skb->len can be stored on 16 bits since the udp header has been already
- * validated and pulled.
- */
struct udp_dev_scratch {
- u32 truesize;
+ /* skb->truesize and the stateless bit are embedded in a single field;
+ * do not use a bitfield since the compiler emits better/smaller code
+ * this way
+ */
+ u32 _tsize_state;
+
+#if BITS_PER_LONG == 64
+ /* len and the bit needed to compute skb_csum_unnecessary
+ * will be on cold cache lines at recvmsg time.
+ * skb->len can be stored on 16 bits since the udp header has been
+ * already validated and pulled.
+ */
u16 len;
bool is_linear;
bool csum_unnecessary;
+#endif
};
+static inline struct udp_dev_scratch *udp_skb_scratch(struct sk_buff *skb)
+{
+ return (struct udp_dev_scratch *)&skb->dev_scratch;
+}
+
+#if BITS_PER_LONG == 64
static inline unsigned int udp_skb_len(struct sk_buff *skb)
{
- return ((struct udp_dev_scratch *)&skb->dev_scratch)->len;
+ return udp_skb_scratch(skb)->len;
}
static inline bool udp_skb_csum_unnecessary(struct sk_buff *skb)
{
- return ((struct udp_dev_scratch *)&skb->dev_scratch)->csum_unnecessary;
+ return udp_skb_scratch(skb)->csum_unnecessary;
}
static inline bool udp_skb_is_linear(struct sk_buff *skb)
{
- return ((struct udp_dev_scratch *)&skb->dev_scratch)->is_linear;
+ return udp_skb_scratch(skb)->is_linear;
}
#else
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
index 4b34c51f859e..b73a14edc85e 100644
--- a/include/rdma/ib_addr.h
+++ b/include/rdma/ib_addr.h
@@ -205,11 +205,13 @@ static inline void iboe_addr_get_sgid(struct rdma_dev_addr *dev_addr,
dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if);
if (dev) {
ip4 = in_dev_get(dev);
- if (ip4 && ip4->ifa_list && ip4->ifa_list->ifa_address) {
+ if (ip4 && ip4->ifa_list && ip4->ifa_list->ifa_address)
ipv6_addr_set_v4mapped(ip4->ifa_list->ifa_address,
(struct in6_addr *)gid);
+
+ if (ip4)
in_dev_put(ip4);
- }
+
dev_put(dev);
}
}
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 356953d3dbd1..b5732432bb29 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1056,7 +1056,7 @@ enum ib_qp_create_flags {
IB_QP_CREATE_MANAGED_RECV = 1 << 4,
IB_QP_CREATE_NETIF_QP = 1 << 5,
IB_QP_CREATE_SIGNATURE_EN = 1 << 6,
- IB_QP_CREATE_USE_GFP_NOIO = 1 << 7,
+ /* FREE = 1 << 7, */
IB_QP_CREATE_SCATTER_FCS = 1 << 8,
IB_QP_CREATE_CVLAN_STRIPPING = 1 << 9,
/* reserve bits 26-31 for low level drivers' internal use */
@@ -2948,6 +2948,22 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
struct ib_qp_init_attr *qp_init_attr);
/**
+ * ib_modify_qp_with_udata - Modifies the attributes for the specified QP.
+ * @qp: The QP to modify.
+ * @attr: On input, specifies the QP attributes to modify. On output,
+ * the current values of selected QP attributes are returned.
+ * @attr_mask: A bit-mask used to specify which attributes of the QP
+ * are being modified.
+ * @udata: pointer to user's input output buffer information
+ * are being modified.
+ * It returns 0 on success and returns appropriate error code on error.
+ */
+int ib_modify_qp_with_udata(struct ib_qp *qp,
+ struct ib_qp_attr *attr,
+ int attr_mask,
+ struct ib_udata *udata);
+
+/**
* ib_modify_qp - Modifies the attributes for the specified QP and then
* transitions the QP to the given state.
* @qp: The QP to modify.
diff --git a/include/rdma/rdma_vt.h b/include/rdma/rdma_vt.h
index 4878aaf7bdff..55af69271053 100644
--- a/include/rdma/rdma_vt.h
+++ b/include/rdma/rdma_vt.h
@@ -229,8 +229,7 @@ struct rvt_driver_provided {
* ERR_PTR(err). The driver is free to return NULL or a valid
* pointer.
*/
- void * (*qp_priv_alloc)(struct rvt_dev_info *rdi, struct rvt_qp *qp,
- gfp_t gfp);
+ void * (*qp_priv_alloc)(struct rvt_dev_info *rdi, struct rvt_qp *qp);
/*
* Free the driver's private qp structure.
@@ -319,7 +318,7 @@ struct rvt_driver_provided {
/* Let the driver pick the next queue pair number*/
int (*alloc_qpn)(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
- enum ib_qp_type type, u8 port_num, gfp_t gfp);
+ enum ib_qp_type type, u8 port_num);
/* Determine if its safe or allowed to modify the qp */
int (*check_modify_qp)(struct rvt_qp *qp, struct ib_qp_attr *attr,
diff --git a/include/rdma/rdmavt_qp.h b/include/rdma/rdmavt_qp.h
index be6472e5b06b..d664d2e76280 100644
--- a/include/rdma/rdmavt_qp.h
+++ b/include/rdma/rdmavt_qp.h
@@ -647,6 +647,20 @@ static inline u32 rvt_div_mtu(struct rvt_qp *qp, u32 len)
return len >> qp->log_pmtu;
}
+/**
+ * rvt_timeout_to_jiffies - Convert a ULP timeout input into jiffies
+ * @timeout - timeout input(0 - 31).
+ *
+ * Return a timeout value in jiffies.
+ */
+static inline unsigned long rvt_timeout_to_jiffies(u8 timeout)
+{
+ if (timeout > 31)
+ timeout = 31;
+
+ return usecs_to_jiffies(1U << timeout) * 4096UL / 1000UL;
+}
+
extern const int ib_rvt_state_ops[];
struct rvt_dev_info;
diff --git a/include/sound/omap-hdmi-audio.h b/include/sound/omap-hdmi-audio.h
index 1df2ff61a4dd..0e495ed8872e 100644
--- a/include/sound/omap-hdmi-audio.h
+++ b/include/sound/omap-hdmi-audio.h
@@ -39,7 +39,7 @@ struct omap_hdmi_audio_ops {
/* HDMI audio initalization data */
struct omap_hdmi_audio_pdata {
struct device *dev;
- enum omapdss_version dss_version;
+ unsigned int version;
phys_addr_t audio_dma_addr;
const struct omap_hdmi_audio_ops *ops;
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 9c94b97c17f8..c4a8b1947566 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -795,10 +795,6 @@ struct snd_soc_component_driver {
int (*suspend)(struct snd_soc_component *);
int (*resume)(struct snd_soc_component *);
- /* pcm creation and destruction */
- int (*pcm_new)(struct snd_soc_pcm_runtime *);
- void (*pcm_free)(struct snd_pcm *);
-
/* DT */
int (*of_xlate_dai_name)(struct snd_soc_component *component,
struct of_phandle_args *args,
@@ -874,8 +870,6 @@ struct snd_soc_component {
void (*remove)(struct snd_soc_component *);
int (*suspend)(struct snd_soc_component *);
int (*resume)(struct snd_soc_component *);
- int (*pcm_new)(struct snd_soc_pcm_runtime *);
- void (*pcm_free)(struct snd_pcm *);
/* machine specific init */
int (*init)(struct snd_soc_component *component);
diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h
index 0ca1fb08805b..fb87d32f5e51 100644
--- a/include/target/iscsi/iscsi_target_core.h
+++ b/include/target/iscsi/iscsi_target_core.h
@@ -786,6 +786,7 @@ struct iscsi_np {
int np_sock_type;
enum np_thread_state_table np_thread_state;
bool enabled;
+ atomic_t np_reset_count;
enum iscsi_timer_flags_table np_login_timer_flags;
u32 np_exports;
enum np_flags_table np_flags;
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index dfae175ddebc..9c3bc3883d2f 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -937,21 +937,19 @@ TRACE_EVENT(ext4_alloc_da_blocks,
TP_STRUCT__entry(
__field( dev_t, dev )
__field( ino_t, ino )
- __field( unsigned int, data_blocks )
- __field( unsigned int, meta_blocks )
+ __field( unsigned int, data_blocks )
),
TP_fast_assign(
__entry->dev = inode->i_sb->s_dev;
__entry->ino = inode->i_ino;
__entry->data_blocks = EXT4_I(inode)->i_reserved_data_blocks;
- __entry->meta_blocks = EXT4_I(inode)->i_reserved_meta_blocks;
),
- TP_printk("dev %d,%d ino %lu data_blocks %u meta_blocks %u",
+ TP_printk("dev %d,%d ino %lu reserved_data_blocks %u",
MAJOR(__entry->dev), MINOR(__entry->dev),
(unsigned long) __entry->ino,
- __entry->data_blocks, __entry->meta_blocks)
+ __entry->data_blocks)
);
TRACE_EVENT(ext4_mballoc_alloc,
@@ -1153,8 +1151,6 @@ TRACE_EVENT(ext4_da_update_reserve_space,
__field( __u64, i_blocks )
__field( int, used_blocks )
__field( int, reserved_data_blocks )
- __field( int, reserved_meta_blocks )
- __field( int, allocated_meta_blocks )
__field( int, quota_claim )
__field( __u16, mode )
),
@@ -1166,22 +1162,16 @@ TRACE_EVENT(ext4_da_update_reserve_space,
__entry->used_blocks = used_blocks;
__entry->reserved_data_blocks =
EXT4_I(inode)->i_reserved_data_blocks;
- __entry->reserved_meta_blocks =
- EXT4_I(inode)->i_reserved_meta_blocks;
- __entry->allocated_meta_blocks =
- EXT4_I(inode)->i_allocated_meta_blocks;
__entry->quota_claim = quota_claim;
__entry->mode = inode->i_mode;
),
TP_printk("dev %d,%d ino %lu mode 0%o i_blocks %llu used_blocks %d "
- "reserved_data_blocks %d reserved_meta_blocks %d "
- "allocated_meta_blocks %d quota_claim %d",
+ "reserved_data_blocks %d quota_claim %d",
MAJOR(__entry->dev), MINOR(__entry->dev),
(unsigned long) __entry->ino,
__entry->mode, __entry->i_blocks,
__entry->used_blocks, __entry->reserved_data_blocks,
- __entry->reserved_meta_blocks, __entry->allocated_meta_blocks,
__entry->quota_claim)
);
@@ -1195,7 +1185,6 @@ TRACE_EVENT(ext4_da_reserve_space,
__field( ino_t, ino )
__field( __u64, i_blocks )
__field( int, reserved_data_blocks )
- __field( int, reserved_meta_blocks )
__field( __u16, mode )
),
@@ -1204,17 +1193,15 @@ TRACE_EVENT(ext4_da_reserve_space,
__entry->ino = inode->i_ino;
__entry->i_blocks = inode->i_blocks;
__entry->reserved_data_blocks = EXT4_I(inode)->i_reserved_data_blocks;
- __entry->reserved_meta_blocks = EXT4_I(inode)->i_reserved_meta_blocks;
__entry->mode = inode->i_mode;
),
TP_printk("dev %d,%d ino %lu mode 0%o i_blocks %llu "
- "reserved_data_blocks %d reserved_meta_blocks %d",
+ "reserved_data_blocks %d",
MAJOR(__entry->dev), MINOR(__entry->dev),
(unsigned long) __entry->ino,
__entry->mode, __entry->i_blocks,
- __entry->reserved_data_blocks,
- __entry->reserved_meta_blocks)
+ __entry->reserved_data_blocks)
);
TRACE_EVENT(ext4_da_release_space,
@@ -1228,8 +1215,6 @@ TRACE_EVENT(ext4_da_release_space,
__field( __u64, i_blocks )
__field( int, freed_blocks )
__field( int, reserved_data_blocks )
- __field( int, reserved_meta_blocks )
- __field( int, allocated_meta_blocks )
__field( __u16, mode )
),
@@ -1239,19 +1224,15 @@ TRACE_EVENT(ext4_da_release_space,
__entry->i_blocks = inode->i_blocks;
__entry->freed_blocks = freed_blocks;
__entry->reserved_data_blocks = EXT4_I(inode)->i_reserved_data_blocks;
- __entry->reserved_meta_blocks = EXT4_I(inode)->i_reserved_meta_blocks;
- __entry->allocated_meta_blocks = EXT4_I(inode)->i_allocated_meta_blocks;
__entry->mode = inode->i_mode;
),
TP_printk("dev %d,%d ino %lu mode 0%o i_blocks %llu freed_blocks %d "
- "reserved_data_blocks %d reserved_meta_blocks %d "
- "allocated_meta_blocks %d",
+ "reserved_data_blocks %d",
MAJOR(__entry->dev), MINOR(__entry->dev),
(unsigned long) __entry->ino,
__entry->mode, __entry->i_blocks,
- __entry->freed_blocks, __entry->reserved_data_blocks,
- __entry->reserved_meta_blocks, __entry->allocated_meta_blocks)
+ __entry->freed_blocks, __entry->reserved_data_blocks)
);
DECLARE_EVENT_CLASS(ext4__bitmap_load,
diff --git a/include/uapi/asm-generic/ioctls.h b/include/uapi/asm-generic/ioctls.h
index 06d5f7ddf84e..14baf9f23a14 100644
--- a/include/uapi/asm-generic/ioctls.h
+++ b/include/uapi/asm-generic/ioctls.h
@@ -77,7 +77,7 @@
#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */
#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */
#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */
-#define TIOCGPTPEER _IOR('T', 0x41, int) /* Safely open the slave */
+#define TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */
#define FIONCLEX 0x5450
#define FIOCLEX 0x5451
diff --git a/include/uapi/drm/armada_drm.h b/include/uapi/drm/armada_drm.h
index 72e326f9c7de..0cb932416cfe 100644
--- a/include/uapi/drm/armada_drm.h
+++ b/include/uapi/drm/armada_drm.h
@@ -23,27 +23,27 @@ extern "C" {
DRM_##dir(DRM_COMMAND_BASE + DRM_ARMADA_##name, struct drm_armada_##str)
struct drm_armada_gem_create {
- uint32_t handle;
- uint32_t size;
+ __u32 handle;
+ __u32 size;
};
#define DRM_IOCTL_ARMADA_GEM_CREATE \
ARMADA_IOCTL(IOWR, GEM_CREATE, gem_create)
struct drm_armada_gem_mmap {
- uint32_t handle;
- uint32_t pad;
- uint64_t offset;
- uint64_t size;
- uint64_t addr;
+ __u32 handle;
+ __u32 pad;
+ __u64 offset;
+ __u64 size;
+ __u64 addr;
};
#define DRM_IOCTL_ARMADA_GEM_MMAP \
ARMADA_IOCTL(IOWR, GEM_MMAP, gem_mmap)
struct drm_armada_gem_pwrite {
- uint64_t ptr;
- uint32_t handle;
- uint32_t offset;
- uint32_t size;
+ __u64 ptr;
+ __u32 handle;
+ __u32 offset;
+ __u32 size;
};
#define DRM_IOCTL_ARMADA_GEM_PWRITE \
ARMADA_IOCTL(IOW, GEM_PWRITE, gem_pwrite)
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 7586c46f68bf..3ad838d3f93f 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -185,6 +185,8 @@ extern "C" {
#define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07
/* add more to the end as needed */
+#define DRM_FORMAT_RESERVED ((1ULL << 56) - 1)
+
#define fourcc_mod_code(vendor, val) \
((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL))
@@ -197,6 +199,15 @@ extern "C" {
*/
/*
+ * Invalid Modifier
+ *
+ * This modifier can be used as a sentinel to terminate the format modifiers
+ * list, or to initialize a variable with an invalid modifier. It might also be
+ * used to report an error back to userspace for certain APIs.
+ */
+#define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED)
+
+/*
* Linear Layout
*
* Just plain linear layout. Note that this is different from no specifying any
@@ -253,6 +264,26 @@ extern "C" {
#define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3)
/*
+ * Intel color control surface (CCS) for render compression
+ *
+ * The framebuffer format must be one of the 8:8:8:8 RGB formats.
+ * The main surface will be plane index 0 and must be Y/Yf-tiled,
+ * the CCS will be plane index 1.
+ *
+ * Each CCS tile matches a 1024x512 pixel area of the main surface.
+ * To match certain aspects of the 3D hardware the CCS is
+ * considered to be made up of normal 128Bx32 Y tiles, Thus
+ * the CCS pitch must be specified in multiples of 128 bytes.
+ *
+ * In reality the CCS tile appears to be a 64Bx64 Y tile, composed
+ * of QWORD (8 bytes) chunks instead of OWORD (16 bytes) chunks.
+ * But that fact is not relevant unless the memory is accessed
+ * directly.
+ */
+#define I915_FORMAT_MOD_Y_TILED_CCS fourcc_mod_code(INTEL, 4)
+#define I915_FORMAT_MOD_Yf_TILED_CCS fourcc_mod_code(INTEL, 5)
+
+/*
* Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks
*
* Macroblocks are laid in a Z-shape, and each pixel data is following the
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 403339f98a92..a2bb7161f020 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -712,6 +712,56 @@ struct drm_mode_atomic {
__u64 user_data;
};
+struct drm_format_modifier_blob {
+#define FORMAT_BLOB_CURRENT 1
+ /* Version of this blob format */
+ u32 version;
+
+ /* Flags */
+ u32 flags;
+
+ /* Number of fourcc formats supported */
+ u32 count_formats;
+
+ /* Where in this blob the formats exist (in bytes) */
+ u32 formats_offset;
+
+ /* Number of drm_format_modifiers */
+ u32 count_modifiers;
+
+ /* Where in this blob the modifiers exist (in bytes) */
+ u32 modifiers_offset;
+
+ /* u32 formats[] */
+ /* struct drm_format_modifier modifiers[] */
+};
+
+struct drm_format_modifier {
+ /* Bitmask of formats in get_plane format list this info applies to. The
+ * offset allows a sliding window of which 64 formats (bits).
+ *
+ * Some examples:
+ * In today's world with < 65 formats, and formats 0, and 2 are
+ * supported
+ * 0x0000000000000005
+ * ^-offset = 0, formats = 5
+ *
+ * If the number formats grew to 128, and formats 98-102 are
+ * supported with the modifier:
+ *
+ * 0x0000003c00000000 0000000000000000
+ * ^
+ * |__offset = 64, formats = 0x3c00000000
+ *
+ */
+ __u64 formats;
+ __u32 offset;
+ __u32 pad;
+
+ /* The modifier that applies to the >get_plane format list bitmask. */
+ __u64 modifier;
+};
+
/**
* Create a new 'blob' data property, copying length bytes from data pointer,
* and returning new blob ID.
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 7ccbd6a2bbe0..6598fb76d2c2 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -260,6 +260,8 @@ typedef struct _drm_i915_sarea {
#define DRM_I915_GEM_CONTEXT_GETPARAM 0x34
#define DRM_I915_GEM_CONTEXT_SETPARAM 0x35
#define DRM_I915_PERF_OPEN 0x36
+#define DRM_I915_PERF_ADD_CONFIG 0x37
+#define DRM_I915_PERF_REMOVE_CONFIG 0x38
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -315,6 +317,8 @@ typedef struct _drm_i915_sarea {
#define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param)
#define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param)
#define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param)
+#define DRM_IOCTL_I915_PERF_ADD_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config)
+#define DRM_IOCTL_I915_PERF_REMOVE_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64)
/* Allow drivers to submit batchbuffers directly to hardware, relying
* on the security mechanisms provided by hardware.
@@ -431,6 +435,11 @@ typedef struct drm_i915_irq_wait {
*/
#define I915_PARAM_HAS_EXEC_BATCH_FIRST 48
+/* Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying an array of
+ * drm_i915_gem_exec_fence structures. See I915_EXEC_FENCE_ARRAY.
+ */
+#define I915_PARAM_HAS_EXEC_FENCE_ARRAY 49
+
typedef struct drm_i915_getparam {
__s32 param;
/*
@@ -812,6 +821,17 @@ struct drm_i915_gem_exec_object2 {
__u64 rsvd2;
};
+struct drm_i915_gem_exec_fence {
+ /**
+ * User's handle for a drm_syncobj to wait on or signal.
+ */
+ __u32 handle;
+
+#define I915_EXEC_FENCE_WAIT (1<<0)
+#define I915_EXEC_FENCE_SIGNAL (1<<1)
+ __u32 flags;
+};
+
struct drm_i915_gem_execbuffer2 {
/**
* List of gem_exec_object2 structs
@@ -826,7 +846,11 @@ struct drm_i915_gem_execbuffer2 {
__u32 DR1;
__u32 DR4;
__u32 num_cliprects;
- /** This is a struct drm_clip_rect *cliprects */
+ /**
+ * This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY
+ * is not set. If I915_EXEC_FENCE_ARRAY is set, then this is a
+ * struct drm_i915_gem_exec_fence *fences.
+ */
__u64 cliprects_ptr;
#define I915_EXEC_RING_MASK (7<<0)
#define I915_EXEC_DEFAULT (0<<0)
@@ -927,7 +951,14 @@ struct drm_i915_gem_execbuffer2 {
* element).
*/
#define I915_EXEC_BATCH_FIRST (1<<18)
-#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_BATCH_FIRST<<1))
+
+/* Setting I915_FENCE_ARRAY implies that num_cliprects and cliprects_ptr
+ * define an array of i915_gem_exec_fence structures which specify a set of
+ * dma fences to wait upon or signal.
+ */
+#define I915_EXEC_FENCE_ARRAY (1<<19)
+
+#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_ARRAY<<1))
#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
#define i915_execbuffer2_set_context_id(eb2, context) \
@@ -1467,6 +1498,22 @@ enum drm_i915_perf_record_type {
DRM_I915_PERF_RECORD_MAX /* non-ABI */
};
+/**
+ * Structure to upload perf dynamic configuration into the kernel.
+ */
+struct drm_i915_perf_oa_config {
+ /** String formatted like "%08x-%04x-%04x-%04x-%012x" */
+ char uuid[36];
+
+ __u32 n_mux_regs;
+ __u32 n_boolean_regs;
+ __u32 n_flex_regs;
+
+ __u64 __user mux_regs_ptr;
+ __u64 __user boolean_regs_ptr;
+ __u64 __user flex_regs_ptr;
+};
+
#if defined(__cplusplus)
}
#endif
diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h
index 26c54f6d595d..ad4eb2863e70 100644
--- a/include/uapi/drm/msm_drm.h
+++ b/include/uapi/drm/msm_drm.h
@@ -171,7 +171,7 @@ struct drm_msm_gem_submit_cmd {
__u32 size; /* in, cmdstream size */
__u32 pad;
__u32 nr_relocs; /* in, number of submit_reloc's */
- __u64 __user relocs; /* in, ptr to array of submit_reloc's */
+ __u64 relocs; /* in, ptr to array of submit_reloc's */
};
/* Each buffer referenced elsewhere in the cmdstream submit (ie. the
@@ -215,8 +215,8 @@ struct drm_msm_gem_submit {
__u32 fence; /* out */
__u32 nr_bos; /* in, number of submit_bo's */
__u32 nr_cmds; /* in, number of submit_cmd's */
- __u64 __user bos; /* in, ptr to array of submit_bo's */
- __u64 __user cmds; /* in, ptr to array of submit_cmd's */
+ __u64 bos; /* in, ptr to array of submit_bo's */
+ __u64 cmds; /* in, ptr to array of submit_cmd's */
__s32 fence_fd; /* in/out fence fd (see MSM_SUBMIT_FENCE_FD_IN/OUT) */
};
diff --git a/include/uapi/drm/qxl_drm.h b/include/uapi/drm/qxl_drm.h
index 7eef42213051..880999d2d863 100644
--- a/include/uapi/drm/qxl_drm.h
+++ b/include/uapi/drm/qxl_drm.h
@@ -80,8 +80,8 @@ struct drm_qxl_reloc {
};
struct drm_qxl_command {
- __u64 __user command; /* void* */
- __u64 __user relocs; /* struct drm_qxl_reloc* */
+ __u64 command; /* void* */
+ __u64 relocs; /* struct drm_qxl_reloc* */
__u32 type;
__u32 command_size;
__u32 relocs_num;
@@ -91,7 +91,7 @@ struct drm_qxl_command {
struct drm_qxl_execbuffer {
__u32 flags; /* for future use */
__u32 commands_num;
- __u64 __user commands; /* struct drm_qxl_command* */
+ __u64 commands; /* struct drm_qxl_command* */
};
struct drm_qxl_update_area {
diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h
index 6ac4c5c014cb..afae87004963 100644
--- a/include/uapi/drm/vc4_drm.h
+++ b/include/uapi/drm/vc4_drm.h
@@ -40,6 +40,7 @@ extern "C" {
#define DRM_VC4_GET_PARAM 0x07
#define DRM_VC4_SET_TILING 0x08
#define DRM_VC4_GET_TILING 0x09
+#define DRM_VC4_LABEL_BO 0x0a
#define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl)
#define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno)
@@ -51,6 +52,7 @@ extern "C" {
#define DRM_IOCTL_VC4_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_PARAM, struct drm_vc4_get_param)
#define DRM_IOCTL_VC4_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SET_TILING, struct drm_vc4_set_tiling)
#define DRM_IOCTL_VC4_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_TILING, struct drm_vc4_get_tiling)
+#define DRM_IOCTL_VC4_LABEL_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_LABEL_BO, struct drm_vc4_label_bo)
struct drm_vc4_submit_rcl_surface {
__u32 hindex; /* Handle index, or ~0 if not present. */
@@ -153,6 +155,16 @@ struct drm_vc4_submit_cl {
__u32 pad:24;
#define VC4_SUBMIT_CL_USE_CLEAR_COLOR (1 << 0)
+/* By default, the kernel gets to choose the order that the tiles are
+ * rendered in. If this is set, then the tiles will be rendered in a
+ * raster order, with the right-to-left vs left-to-right and
+ * top-to-bottom vs bottom-to-top dictated by
+ * VC4_SUBMIT_CL_RCL_ORDER_INCREASING_*. This allows overlapping
+ * blits to be implemented using the 3D engine.
+ */
+#define VC4_SUBMIT_CL_FIXED_RCL_ORDER (1 << 1)
+#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X (1 << 2)
+#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y (1 << 3)
__u32 flags;
/* Returned value of the seqno of this render job (for the
@@ -292,6 +304,7 @@ struct drm_vc4_get_hang_state {
#define DRM_VC4_PARAM_SUPPORTS_BRANCHES 3
#define DRM_VC4_PARAM_SUPPORTS_ETC1 4
#define DRM_VC4_PARAM_SUPPORTS_THREADED_FS 5
+#define DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER 6
struct drm_vc4_get_param {
__u32 param;
@@ -311,6 +324,15 @@ struct drm_vc4_set_tiling {
__u64 modifier;
};
+/**
+ * struct drm_vc4_label_bo - Attach a name to a BO for debug purposes.
+ */
+struct drm_vc4_label_bo {
+ __u32 handle;
+ __u32 len;
+ __u64 name;
+};
+
#if defined(__cplusplus)
}
#endif
diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h
index d6833426fdef..7b4567bacfc2 100644
--- a/include/uapi/linux/kfd_ioctl.h
+++ b/include/uapi/linux/kfd_ioctl.h
@@ -232,6 +232,35 @@ struct kfd_ioctl_wait_events_args {
uint32_t wait_result; /* from KFD */
};
+struct kfd_ioctl_set_scratch_backing_va_args {
+ uint64_t va_addr; /* to KFD */
+ uint32_t gpu_id; /* to KFD */
+ uint32_t pad;
+};
+
+struct kfd_ioctl_get_tile_config_args {
+ /* to KFD: pointer to tile array */
+ uint64_t tile_config_ptr;
+ /* to KFD: pointer to macro tile array */
+ uint64_t macro_tile_config_ptr;
+ /* to KFD: array size allocated by user mode
+ * from KFD: array size filled by kernel
+ */
+ uint32_t num_tile_configs;
+ /* to KFD: array size allocated by user mode
+ * from KFD: array size filled by kernel
+ */
+ uint32_t num_macro_tile_configs;
+
+ uint32_t gpu_id; /* to KFD */
+ uint32_t gb_addr_config; /* from KFD */
+ uint32_t num_banks; /* from KFD */
+ uint32_t num_ranks; /* from KFD */
+ /* struct size can be extended later if needed
+ * without breaking ABI compatibility
+ */
+};
+
#define AMDKFD_IOCTL_BASE 'K'
#define AMDKFD_IO(nr) _IO(AMDKFD_IOCTL_BASE, nr)
#define AMDKFD_IOR(nr, type) _IOR(AMDKFD_IOCTL_BASE, nr, type)
@@ -286,7 +315,13 @@ struct kfd_ioctl_wait_events_args {
#define AMDKFD_IOC_DBG_WAVE_CONTROL \
AMDKFD_IOW(0x10, struct kfd_ioctl_dbg_wave_control_args)
+#define AMDKFD_IOC_SET_SCRATCH_BACKING_VA \
+ AMDKFD_IOWR(0x11, struct kfd_ioctl_set_scratch_backing_va_args)
+
+#define AMDKFD_IOC_GET_TILE_CONFIG \
+ AMDKFD_IOWR(0x12, struct kfd_ioctl_get_tile_config_args)
+
#define AMDKFD_COMMAND_START 0x01
-#define AMDKFD_COMMAND_END 0x11
+#define AMDKFD_COMMAND_END 0x13
#endif
diff --git a/include/uapi/linux/usb/audio.h b/include/uapi/linux/usb/audio.h
index d2314be4f0c0..a4680a5bf5dd 100644
--- a/include/uapi/linux/usb/audio.h
+++ b/include/uapi/linux/usb/audio.h
@@ -333,7 +333,7 @@ struct uac_processing_unit_descriptor {
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bUnitID;
- __u16 wProcessType;
+ __le16 wProcessType;
__u8 bNrInPins;
__u8 baSourceID[];
} __attribute__ ((packed));
@@ -491,8 +491,8 @@ struct uac_format_type_ii_ext_descriptor {
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bFormatType;
- __u16 wMaxBitRate;
- __u16 wSamplesPerFrame;
+ __le16 wMaxBitRate;
+ __le16 wSamplesPerFrame;
__u8 bHeaderLength;
__u8 bSideBandProtocol;
} __attribute__((packed));
diff --git a/include/xen/balloon.h b/include/xen/balloon.h
index d1767dfb0d95..8906361bb50c 100644
--- a/include/xen/balloon.h
+++ b/include/xen/balloon.h
@@ -35,3 +35,11 @@ static inline int register_xen_selfballooning(struct device *dev)
return -ENOSYS;
}
#endif
+
+#ifdef CONFIG_XEN_BALLOON
+void xen_balloon_init(void);
+#else
+static inline void xen_balloon_init(void)
+{
+}
+#endif
diff --git a/ipc/msg.c b/ipc/msg.c
index 5b25e0755656..2c38f10d1483 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -1034,7 +1034,8 @@ void msg_exit_ns(struct ipc_namespace *ns)
static int sysvipc_msg_proc_show(struct seq_file *s, void *it)
{
struct user_namespace *user_ns = seq_user_ns(s);
- struct msg_queue *msq = it;
+ struct kern_ipc_perm *ipcp = it;
+ struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm);
seq_printf(s,
"%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n",
diff --git a/ipc/sem.c b/ipc/sem.c
index 9e70cd7a17da..38371e93bfa5 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -2179,7 +2179,8 @@ void exit_sem(struct task_struct *tsk)
static int sysvipc_sem_proc_show(struct seq_file *s, void *it)
{
struct user_namespace *user_ns = seq_user_ns(s);
- struct sem_array *sma = it;
+ struct kern_ipc_perm *ipcp = it;
+ struct sem_array *sma = container_of(ipcp, struct sem_array, sem_perm);
time_t sem_otime;
/*
diff --git a/ipc/shm.c b/ipc/shm.c
index 28a444861a8f..8828b4c3a190 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -1380,9 +1380,11 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr)
static int sysvipc_shm_proc_show(struct seq_file *s, void *it)
{
struct user_namespace *user_ns = seq_user_ns(s);
- struct shmid_kernel *shp = it;
+ struct kern_ipc_perm *ipcp = it;
+ struct shmid_kernel *shp;
unsigned long rss = 0, swp = 0;
+ shp = container_of(ipcp, struct shmid_kernel, shm_perm);
shm_add_rss_swap(shp, &rss, &swp);
#if BITS_PER_LONG <= 32
diff --git a/kernel/audit.c b/kernel/audit.c
index 833267bbd80b..6dd556931739 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -641,6 +641,7 @@ static int auditd_send_unicast_skb(struct sk_buff *skb)
ac = rcu_dereference(auditd_conn);
if (!ac) {
rcu_read_unlock();
+ kfree_skb(skb);
rc = -ECONNREFUSED;
goto err;
}
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 045646da97cc..6c772adabad2 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1289,7 +1289,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
info_len = min_t(u32, sizeof(info), info_len);
if (copy_from_user(&info, uinfo, info_len))
- return err;
+ return -EFAULT;
info.type = prog->type;
info.id = prog->aux->id;
@@ -1312,7 +1312,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
}
ulen = info.xlated_prog_len;
- info.xlated_prog_len = bpf_prog_size(prog->len);
+ info.xlated_prog_len = bpf_prog_insn_size(prog);
if (info.xlated_prog_len && ulen) {
uinsns = u64_to_user_ptr(info.xlated_prog_insns);
ulen = min_t(u32, info.xlated_prog_len, ulen);
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 6a86723c5b64..664d93972373 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -504,6 +504,7 @@ static void reset_reg_range_values(struct bpf_reg_state *regs, u32 regno)
{
regs[regno].min_value = BPF_REGISTER_MIN_RANGE;
regs[regno].max_value = BPF_REGISTER_MAX_RANGE;
+ regs[regno].value_from_signed = false;
regs[regno].min_align = 0;
}
@@ -777,12 +778,13 @@ static int check_ctx_access(struct bpf_verifier_env *env, int insn_idx, int off,
return -EACCES;
}
-static bool is_pointer_value(struct bpf_verifier_env *env, int regno)
+static bool __is_pointer_value(bool allow_ptr_leaks,
+ const struct bpf_reg_state *reg)
{
- if (env->allow_ptr_leaks)
+ if (allow_ptr_leaks)
return false;
- switch (env->cur_state.regs[regno].type) {
+ switch (reg->type) {
case UNKNOWN_VALUE:
case CONST_IMM:
return false;
@@ -791,6 +793,11 @@ static bool is_pointer_value(struct bpf_verifier_env *env, int regno)
}
}
+static bool is_pointer_value(struct bpf_verifier_env *env, int regno)
+{
+ return __is_pointer_value(env->allow_ptr_leaks, &env->cur_state.regs[regno]);
+}
+
static int check_pkt_ptr_alignment(const struct bpf_reg_state *reg,
int off, int size, bool strict)
{
@@ -1832,10 +1839,24 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env,
dst_align = dst_reg->min_align;
/* We don't know anything about what was done to this register, mark it
- * as unknown.
+ * as unknown. Also, if both derived bounds came from signed/unsigned
+ * mixed compares and one side is unbounded, we cannot really do anything
+ * with them as boundaries cannot be trusted. Thus, arithmetic of two
+ * regs of such kind will get invalidated bounds on the dst side.
*/
- if (min_val == BPF_REGISTER_MIN_RANGE &&
- max_val == BPF_REGISTER_MAX_RANGE) {
+ if ((min_val == BPF_REGISTER_MIN_RANGE &&
+ max_val == BPF_REGISTER_MAX_RANGE) ||
+ (BPF_SRC(insn->code) == BPF_X &&
+ ((min_val != BPF_REGISTER_MIN_RANGE &&
+ max_val == BPF_REGISTER_MAX_RANGE) ||
+ (min_val == BPF_REGISTER_MIN_RANGE &&
+ max_val != BPF_REGISTER_MAX_RANGE) ||
+ (dst_reg->min_value != BPF_REGISTER_MIN_RANGE &&
+ dst_reg->max_value == BPF_REGISTER_MAX_RANGE) ||
+ (dst_reg->min_value == BPF_REGISTER_MIN_RANGE &&
+ dst_reg->max_value != BPF_REGISTER_MAX_RANGE)) &&
+ regs[insn->dst_reg].value_from_signed !=
+ regs[insn->src_reg].value_from_signed)) {
reset_reg_range_values(regs, insn->dst_reg);
return;
}
@@ -1844,10 +1865,12 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env,
* do our normal operations to the register, we need to set the values
* to the min/max since they are undefined.
*/
- if (min_val == BPF_REGISTER_MIN_RANGE)
- dst_reg->min_value = BPF_REGISTER_MIN_RANGE;
- if (max_val == BPF_REGISTER_MAX_RANGE)
- dst_reg->max_value = BPF_REGISTER_MAX_RANGE;
+ if (opcode != BPF_SUB) {
+ if (min_val == BPF_REGISTER_MIN_RANGE)
+ dst_reg->min_value = BPF_REGISTER_MIN_RANGE;
+ if (max_val == BPF_REGISTER_MAX_RANGE)
+ dst_reg->max_value = BPF_REGISTER_MAX_RANGE;
+ }
switch (opcode) {
case BPF_ADD:
@@ -1858,10 +1881,17 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env,
dst_reg->min_align = min(src_align, dst_align);
break;
case BPF_SUB:
+ /* If one of our values was at the end of our ranges, then the
+ * _opposite_ value in the dst_reg goes to the end of our range.
+ */
+ if (min_val == BPF_REGISTER_MIN_RANGE)
+ dst_reg->max_value = BPF_REGISTER_MAX_RANGE;
+ if (max_val == BPF_REGISTER_MAX_RANGE)
+ dst_reg->min_value = BPF_REGISTER_MIN_RANGE;
if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE)
- dst_reg->min_value -= min_val;
+ dst_reg->min_value -= max_val;
if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE)
- dst_reg->max_value -= max_val;
+ dst_reg->max_value -= min_val;
dst_reg->min_align = min(src_align, dst_align);
break;
case BPF_MUL:
@@ -2023,6 +2053,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
regs[insn->dst_reg].max_value = insn->imm;
regs[insn->dst_reg].min_value = insn->imm;
regs[insn->dst_reg].min_align = calc_align(insn->imm);
+ regs[insn->dst_reg].value_from_signed = false;
}
} else if (opcode > BPF_END) {
@@ -2198,40 +2229,63 @@ static void reg_set_min_max(struct bpf_reg_state *true_reg,
struct bpf_reg_state *false_reg, u64 val,
u8 opcode)
{
+ bool value_from_signed = true;
+ bool is_range = true;
+
switch (opcode) {
case BPF_JEQ:
/* If this is false then we know nothing Jon Snow, but if it is
* true then we know for sure.
*/
true_reg->max_value = true_reg->min_value = val;
+ is_range = false;
break;
case BPF_JNE:
/* If this is true we know nothing Jon Snow, but if it is false
* we know the value for sure;
*/
false_reg->max_value = false_reg->min_value = val;
+ is_range = false;
break;
case BPF_JGT:
- /* Unsigned comparison, the minimum value is 0. */
- false_reg->min_value = 0;
+ value_from_signed = false;
/* fallthrough */
case BPF_JSGT:
+ if (true_reg->value_from_signed != value_from_signed)
+ reset_reg_range_values(true_reg, 0);
+ if (false_reg->value_from_signed != value_from_signed)
+ reset_reg_range_values(false_reg, 0);
+ if (opcode == BPF_JGT) {
+ /* Unsigned comparison, the minimum value is 0. */
+ false_reg->min_value = 0;
+ }
/* If this is false then we know the maximum val is val,
* otherwise we know the min val is val+1.
*/
false_reg->max_value = val;
+ false_reg->value_from_signed = value_from_signed;
true_reg->min_value = val + 1;
+ true_reg->value_from_signed = value_from_signed;
break;
case BPF_JGE:
- /* Unsigned comparison, the minimum value is 0. */
- false_reg->min_value = 0;
+ value_from_signed = false;
/* fallthrough */
case BPF_JSGE:
+ if (true_reg->value_from_signed != value_from_signed)
+ reset_reg_range_values(true_reg, 0);
+ if (false_reg->value_from_signed != value_from_signed)
+ reset_reg_range_values(false_reg, 0);
+ if (opcode == BPF_JGE) {
+ /* Unsigned comparison, the minimum value is 0. */
+ false_reg->min_value = 0;
+ }
/* If this is false then we know the maximum value is val - 1,
* otherwise we know the mimimum value is val.
*/
false_reg->max_value = val - 1;
+ false_reg->value_from_signed = value_from_signed;
true_reg->min_value = val;
+ true_reg->value_from_signed = value_from_signed;
break;
default:
break;
@@ -2239,6 +2293,12 @@ static void reg_set_min_max(struct bpf_reg_state *true_reg,
check_reg_overflow(false_reg);
check_reg_overflow(true_reg);
+ if (is_range) {
+ if (__is_pointer_value(false, false_reg))
+ reset_reg_range_values(false_reg, 0);
+ if (__is_pointer_value(false, true_reg))
+ reset_reg_range_values(true_reg, 0);
+ }
}
/* Same as above, but for the case that dst_reg is a CONST_IMM reg and src_reg
@@ -2248,41 +2308,64 @@ static void reg_set_min_max_inv(struct bpf_reg_state *true_reg,
struct bpf_reg_state *false_reg, u64 val,
u8 opcode)
{
+ bool value_from_signed = true;
+ bool is_range = true;
+
switch (opcode) {
case BPF_JEQ:
/* If this is false then we know nothing Jon Snow, but if it is
* true then we know for sure.
*/
true_reg->max_value = true_reg->min_value = val;
+ is_range = false;
break;
case BPF_JNE:
/* If this is true we know nothing Jon Snow, but if it is false
* we know the value for sure;
*/
false_reg->max_value = false_reg->min_value = val;
+ is_range = false;
break;
case BPF_JGT:
- /* Unsigned comparison, the minimum value is 0. */
- true_reg->min_value = 0;
+ value_from_signed = false;
/* fallthrough */
case BPF_JSGT:
+ if (true_reg->value_from_signed != value_from_signed)
+ reset_reg_range_values(true_reg, 0);
+ if (false_reg->value_from_signed != value_from_signed)
+ reset_reg_range_values(false_reg, 0);
+ if (opcode == BPF_JGT) {
+ /* Unsigned comparison, the minimum value is 0. */
+ true_reg->min_value = 0;
+ }
/*
* If this is false, then the val is <= the register, if it is
* true the register <= to the val.
*/
false_reg->min_value = val;
+ false_reg->value_from_signed = value_from_signed;
true_reg->max_value = val - 1;
+ true_reg->value_from_signed = value_from_signed;
break;
case BPF_JGE:
- /* Unsigned comparison, the minimum value is 0. */
- true_reg->min_value = 0;
+ value_from_signed = false;
/* fallthrough */
case BPF_JSGE:
+ if (true_reg->value_from_signed != value_from_signed)
+ reset_reg_range_values(true_reg, 0);
+ if (false_reg->value_from_signed != value_from_signed)
+ reset_reg_range_values(false_reg, 0);
+ if (opcode == BPF_JGE) {
+ /* Unsigned comparison, the minimum value is 0. */
+ true_reg->min_value = 0;
+ }
/* If this is false then constant < register, if it is true then
* the register < constant.
*/
false_reg->min_value = val + 1;
+ false_reg->value_from_signed = value_from_signed;
true_reg->max_value = val;
+ true_reg->value_from_signed = value_from_signed;
break;
default:
break;
@@ -2290,6 +2373,12 @@ static void reg_set_min_max_inv(struct bpf_reg_state *true_reg,
check_reg_overflow(false_reg);
check_reg_overflow(true_reg);
+ if (is_range) {
+ if (__is_pointer_value(false, false_reg))
+ reset_reg_range_values(false_reg, 0);
+ if (__is_pointer_value(false, true_reg))
+ reset_reg_range_values(true_reg, 0);
+ }
}
static void mark_map_reg(struct bpf_reg_state *regs, u32 regno, u32 id,
diff --git a/kernel/cgroup/cgroup-internal.h b/kernel/cgroup/cgroup-internal.h
index 793565c05742..8b4c3c2f2509 100644
--- a/kernel/cgroup/cgroup-internal.h
+++ b/kernel/cgroup/cgroup-internal.h
@@ -33,6 +33,9 @@ struct cgroup_taskset {
struct list_head src_csets;
struct list_head dst_csets;
+ /* the number of tasks in the set */
+ int nr_tasks;
+
/* the subsys currently being processed */
int ssid;
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index 620794a20a33..df2e0f14a95d 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -2006,6 +2006,8 @@ static void cgroup_migrate_add_task(struct task_struct *task,
if (!cset->mg_src_cgrp)
return;
+ mgctx->tset.nr_tasks++;
+
list_move_tail(&task->cg_list, &cset->mg_tasks);
if (list_empty(&cset->mg_node))
list_add_tail(&cset->mg_node,
@@ -2094,21 +2096,19 @@ static int cgroup_migrate_execute(struct cgroup_mgctx *mgctx)
struct css_set *cset, *tmp_cset;
int ssid, failed_ssid, ret;
- /* methods shouldn't be called if no task is actually migrating */
- if (list_empty(&tset->src_csets))
- return 0;
-
/* check that we can legitimately attach to the cgroup */
- do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
- if (ss->can_attach) {
- tset->ssid = ssid;
- ret = ss->can_attach(tset);
- if (ret) {
- failed_ssid = ssid;
- goto out_cancel_attach;
+ if (tset->nr_tasks) {
+ do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
+ if (ss->can_attach) {
+ tset->ssid = ssid;
+ ret = ss->can_attach(tset);
+ if (ret) {
+ failed_ssid = ssid;
+ goto out_cancel_attach;
+ }
}
- }
- } while_each_subsys_mask();
+ } while_each_subsys_mask();
+ }
/*
* Now that we're guaranteed success, proceed to move all tasks to
@@ -2137,25 +2137,29 @@ static int cgroup_migrate_execute(struct cgroup_mgctx *mgctx)
*/
tset->csets = &tset->dst_csets;
- do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
- if (ss->attach) {
- tset->ssid = ssid;
- ss->attach(tset);
- }
- } while_each_subsys_mask();
+ if (tset->nr_tasks) {
+ do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
+ if (ss->attach) {
+ tset->ssid = ssid;
+ ss->attach(tset);
+ }
+ } while_each_subsys_mask();
+ }
ret = 0;
goto out_release_tset;
out_cancel_attach:
- do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
- if (ssid == failed_ssid)
- break;
- if (ss->cancel_attach) {
- tset->ssid = ssid;
- ss->cancel_attach(tset);
- }
- } while_each_subsys_mask();
+ if (tset->nr_tasks) {
+ do_each_subsys_mask(ss, ssid, mgctx->ss_mask) {
+ if (ssid == failed_ssid)
+ break;
+ if (ss->cancel_attach) {
+ tset->ssid = ssid;
+ ss->cancel_attach(tset);
+ }
+ } while_each_subsys_mask();
+ }
out_release_tset:
spin_lock_irq(&css_set_lock);
list_splice_init(&tset->dst_csets, &tset->src_csets);
@@ -2997,11 +3001,11 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of,
cgrp->subtree_control &= ~disable;
ret = cgroup_apply_control(cgrp);
-
cgroup_finalize_control(cgrp, ret);
+ if (ret)
+ goto out_unlock;
kernfs_activate(cgrp->kn);
- ret = 0;
out_unlock:
cgroup_kn_unlock(of->kn);
return ret ?: nbytes;
@@ -4669,6 +4673,10 @@ int __init cgroup_init(void)
if (ss->bind)
ss->bind(init_css_set.subsys[ssid]);
+
+ mutex_lock(&cgroup_mutex);
+ css_populate_dir(init_css_set.subsys[ssid]);
+ mutex_unlock(&cgroup_mutex);
}
/* init_css_set.subsys[] has been updated, re-hash */
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index ca8376e5008c..8d5151688504 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -63,6 +63,7 @@
#include <linux/cgroup.h>
#include <linux/wait.h>
+DEFINE_STATIC_KEY_FALSE(cpusets_pre_enable_key);
DEFINE_STATIC_KEY_FALSE(cpusets_enabled_key);
/* See "Frequency meter" comments, below. */
diff --git a/kernel/cpu.c b/kernel/cpu.c
index ab860453841d..eee033134262 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -279,7 +279,8 @@ static int bringup_wait_for_ap(unsigned int cpu)
/* Wait for the CPU to reach CPUHP_AP_ONLINE_IDLE */
wait_for_completion(&st->done);
- BUG_ON(!cpu_online(cpu));
+ if (WARN_ON_ONCE((!cpu_online(cpu))))
+ return -ECANCELED;
/* Unpark the stopper thread and the hotplug thread of the target cpu */
stop_machine_unpark(cpu);
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 1538df9b2b65..426c2ffba16d 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -1452,6 +1452,13 @@ static enum event_type_t get_event_type(struct perf_event *event)
lockdep_assert_held(&ctx->lock);
+ /*
+ * It's 'group type', really, because if our group leader is
+ * pinned, so are we.
+ */
+ if (event->group_leader != event)
+ event = event->group_leader;
+
event_type = event->attr.pinned ? EVENT_PINNED : EVENT_FLEXIBLE;
if (!ctx->task)
event_type |= EVENT_CPU;
@@ -4378,7 +4385,9 @@ EXPORT_SYMBOL_GPL(perf_event_read_value);
static int __perf_read_group_add(struct perf_event *leader,
u64 read_format, u64 *values)
{
+ struct perf_event_context *ctx = leader->ctx;
struct perf_event *sub;
+ unsigned long flags;
int n = 1; /* skip @nr */
int ret;
@@ -4408,12 +4417,15 @@ static int __perf_read_group_add(struct perf_event *leader,
if (read_format & PERF_FORMAT_ID)
values[n++] = primary_event_id(leader);
+ raw_spin_lock_irqsave(&ctx->lock, flags);
+
list_for_each_entry(sub, &leader->sibling_list, group_entry) {
values[n++] += perf_event_count(sub);
if (read_format & PERF_FORMAT_ID)
values[n++] = primary_event_id(sub);
}
+ raw_spin_unlock_irqrestore(&ctx->lock, flags);
return 0;
}
@@ -7321,21 +7333,6 @@ int perf_event_account_interrupt(struct perf_event *event)
return __perf_event_account_interrupt(event, 1);
}
-static bool sample_is_allowed(struct perf_event *event, struct pt_regs *regs)
-{
- /*
- * Due to interrupt latency (AKA "skid"), we may enter the
- * kernel before taking an overflow, even if the PMU is only
- * counting user events.
- * To avoid leaking information to userspace, we must always
- * reject kernel samples when exclude_kernel is set.
- */
- if (event->attr.exclude_kernel && !user_mode(regs))
- return false;
-
- return true;
-}
-
/*
* Generic event overflow handling, sampling.
*/
@@ -7357,12 +7354,6 @@ static int __perf_event_overflow(struct perf_event *event,
ret = __perf_event_account_interrupt(event, throttle);
/*
- * For security, drop the skid kernel samples if necessary.
- */
- if (!sample_is_allowed(event, regs))
- return ret;
-
- /*
* XXX event_limit might not quite work as expected on inherited
* events
*/
diff --git a/kernel/fork.c b/kernel/fork.c
index 17921b0390b4..e075b7780421 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -807,7 +807,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
mm_init_aio(mm);
mm_init_owner(mm, p);
mmu_notifier_mm_init(mm);
- clear_tlb_flush_pending(mm);
+ init_tlb_flush_pending(mm);
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS
mm->pmd_huge_pte = NULL;
#endif
diff --git a/kernel/futex.c b/kernel/futex.c
index c934689043b2..f50b434756c1 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -212,7 +212,7 @@ struct futex_pi_state {
atomic_t refcount;
union futex_key key;
-};
+} __randomize_layout;
/**
* struct futex_q - The hashed futex queue entry, one per waiting task
@@ -246,7 +246,7 @@ struct futex_q {
struct rt_mutex_waiter *rt_waiter;
union futex_key *requeue_pi_key;
u32 bitset;
-};
+} __randomize_layout;
static const struct futex_q futex_q_init = {
/* list gets initialized in queue_me()*/
@@ -670,13 +670,14 @@ again:
* this reference was taken by ihold under the page lock
* pinning the inode in place so i_lock was unnecessary. The
* only way for this check to fail is if the inode was
- * truncated in parallel so warn for now if this happens.
+ * truncated in parallel which is almost certainly an
+ * application bug. In such a case, just retry.
*
* We are not calling into get_futex_key_refs() in file-backed
* cases, therefore a successful atomic_inc return below will
* guarantee that get_futex_key() will still imply smp_mb(); (B).
*/
- if (WARN_ON_ONCE(!atomic_inc_not_zero(&inode->i_count))) {
+ if (!atomic_inc_not_zero(&inode->i_count)) {
rcu_read_unlock();
put_page(page);
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index d171bc57e1e0..a3cc37c0c85e 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -170,21 +170,11 @@ static void irq_state_clr_disabled(struct irq_desc *desc)
irqd_clear(&desc->irq_data, IRQD_IRQ_DISABLED);
}
-static void irq_state_set_disabled(struct irq_desc *desc)
-{
- irqd_set(&desc->irq_data, IRQD_IRQ_DISABLED);
-}
-
static void irq_state_clr_masked(struct irq_desc *desc)
{
irqd_clear(&desc->irq_data, IRQD_IRQ_MASKED);
}
-static void irq_state_set_masked(struct irq_desc *desc)
-{
- irqd_set(&desc->irq_data, IRQD_IRQ_MASKED);
-}
-
static void irq_state_clr_started(struct irq_desc *desc)
{
irqd_clear(&desc->irq_data, IRQD_IRQ_STARTED);
diff --git a/kernel/irq/cpuhotplug.c b/kernel/irq/cpuhotplug.c
index aee8f7ec40af..638eb9c83d9f 100644
--- a/kernel/irq/cpuhotplug.c
+++ b/kernel/irq/cpuhotplug.c
@@ -95,8 +95,13 @@ static bool migrate_one_irq(struct irq_desc *desc)
affinity = cpu_online_mask;
brokeaff = true;
}
-
- err = irq_do_set_affinity(d, affinity, true);
+ /*
+ * Do not set the force argument of irq_do_set_affinity() as this
+ * disables the masking of offline CPUs from the supplied affinity
+ * mask and therefore might keep/reassign the irq to the outgoing
+ * CPU.
+ */
+ err = irq_do_set_affinity(d, affinity, false);
if (err) {
pr_warn_ratelimited("IRQ%u: set affinity failed(%d).\n",
d->irq, err);
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index dbfba9933ed2..a2c48058354c 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -227,6 +227,16 @@ static inline bool irqd_has_set(struct irq_data *d, unsigned int mask)
return __irqd_to_state(d) & mask;
}
+static inline void irq_state_set_disabled(struct irq_desc *desc)
+{
+ irqd_set(&desc->irq_data, IRQD_IRQ_DISABLED);
+}
+
+static inline void irq_state_set_masked(struct irq_desc *desc)
+{
+ irqd_set(&desc->irq_data, IRQD_IRQ_MASKED);
+}
+
#undef __irqd_to_state
static inline void kstat_incr_irqs_this_cpu(struct irq_desc *desc)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 5624b2dd6b58..1d1a5b945ab4 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1090,6 +1090,16 @@ setup_irq_thread(struct irqaction *new, unsigned int irq, bool secondary)
/*
* Internal function to register an irqaction - typically used to
* allocate special interrupts that are part of the architecture.
+ *
+ * Locking rules:
+ *
+ * desc->request_mutex Provides serialization against a concurrent free_irq()
+ * chip_bus_lock Provides serialization for slow bus operations
+ * desc->lock Provides serialization against hard interrupts
+ *
+ * chip_bus_lock and desc->lock are sufficient for all other management and
+ * interrupt related functions. desc->request_mutex solely serializes
+ * request/free_irq().
*/
static int
__setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
@@ -1167,20 +1177,35 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
if (desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE)
new->flags &= ~IRQF_ONESHOT;
+ /*
+ * Protects against a concurrent __free_irq() call which might wait
+ * for synchronize_irq() to complete without holding the optional
+ * chip bus lock and desc->lock.
+ */
mutex_lock(&desc->request_mutex);
+
+ /*
+ * Acquire bus lock as the irq_request_resources() callback below
+ * might rely on the serialization or the magic power management
+ * functions which are abusing the irq_bus_lock() callback,
+ */
+ chip_bus_lock(desc);
+
+ /* First installed action requests resources. */
if (!desc->action) {
ret = irq_request_resources(desc);
if (ret) {
pr_err("Failed to request resources for %s (irq %d) on irqchip %s\n",
new->name, irq, desc->irq_data.chip->name);
- goto out_mutex;
+ goto out_bus_unlock;
}
}
- chip_bus_lock(desc);
-
/*
* The following block of code has to be executed atomically
+ * protected against a concurrent interrupt and any of the other
+ * management calls which are not serialized via
+ * desc->request_mutex or the optional bus lock.
*/
raw_spin_lock_irqsave(&desc->lock, flags);
old_ptr = &desc->action;
@@ -1286,10 +1311,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
ret = __irq_set_trigger(desc,
new->flags & IRQF_TRIGGER_MASK);
- if (ret) {
- irq_release_resources(desc);
+ if (ret)
goto out_unlock;
- }
}
desc->istate &= ~(IRQS_AUTODETECT | IRQS_SPURIOUS_DISABLED | \
@@ -1385,12 +1408,10 @@ mismatch:
out_unlock:
raw_spin_unlock_irqrestore(&desc->lock, flags);
- chip_bus_sync_unlock(desc);
-
if (!desc->action)
irq_release_resources(desc);
-
-out_mutex:
+out_bus_unlock:
+ chip_bus_sync_unlock(desc);
mutex_unlock(&desc->request_mutex);
out_thread:
@@ -1472,6 +1493,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
WARN(1, "Trying to free already-free IRQ %d\n", irq);
raw_spin_unlock_irqrestore(&desc->lock, flags);
chip_bus_sync_unlock(desc);
+ mutex_unlock(&desc->request_mutex);
return NULL;
}
@@ -1498,6 +1520,20 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
#endif
raw_spin_unlock_irqrestore(&desc->lock, flags);
+ /*
+ * Drop bus_lock here so the changes which were done in the chip
+ * callbacks above are synced out to the irq chips which hang
+ * behind a slow bus (I2C, SPI) before calling synchronize_irq().
+ *
+ * Aside of that the bus_lock can also be taken from the threaded
+ * handler in irq_finalize_oneshot() which results in a deadlock
+ * because synchronize_irq() would wait forever for the thread to
+ * complete, which is blocked on the bus lock.
+ *
+ * The still held desc->request_mutex() protects against a
+ * concurrent request_irq() of this irq so the release of resources
+ * and timing data is properly serialized.
+ */
chip_bus_sync_unlock(desc);
unregister_handler_proc(irq, action);
@@ -1530,8 +1566,15 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
}
}
+ /* Last action releases resources */
if (!desc->action) {
+ /*
+ * Reaquire bus lock as irq_release_resources() might
+ * require it to deallocate resources over the slow bus.
+ */
+ chip_bus_lock(desc);
irq_release_resources(desc);
+ chip_bus_sync_unlock(desc);
irq_remove_timings(desc);
}
diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c
index cea1de0161f1..6bd9b58429cc 100644
--- a/kernel/irq/pm.c
+++ b/kernel/irq/pm.c
@@ -149,6 +149,8 @@ static void resume_irq(struct irq_desc *desc)
/* Pretend that it got disabled ! */
desc->depth++;
+ irq_state_set_disabled(desc);
+ irq_state_set_masked(desc);
resume:
desc->istate &= ~IRQS_SUSPENDED;
__enable_irq(desc);
diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
index 78069895032a..649dc9d3951a 100644
--- a/kernel/locking/rtmutex.c
+++ b/kernel/locking/rtmutex.c
@@ -963,7 +963,6 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock,
return -EDEADLK;
raw_spin_lock(&task->pi_lock);
- rt_mutex_adjust_prio(task);
waiter->task = task;
waiter->lock = lock;
waiter->prio = task->prio;
diff --git a/kernel/pid.c b/kernel/pid.c
index 731c4e528f4e..c69c30d827e5 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -575,13 +575,10 @@ struct pid *find_ge_pid(int nr, struct pid_namespace *ns)
*/
void __init pidhash_init(void)
{
- unsigned int pidhash_size;
-
pid_hash = alloc_large_system_hash("PID", sizeof(*pid_hash), 0, 18,
HASH_EARLY | HASH_SMALL | HASH_ZERO,
&pidhash_shift, NULL,
0, 4096);
- pidhash_size = 1U << pidhash_shift;
}
void __init pidmap_init(void)
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 222317721c5a..0972a8e09d08 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -1650,7 +1650,7 @@ static unsigned long minimum_image_size(unsigned long saveable)
{
unsigned long size;
- size = global_page_state(NR_SLAB_RECLAIMABLE)
+ size = global_node_page_state(NR_SLAB_RECLAIMABLE)
+ global_node_page_state(NR_ACTIVE_ANON)
+ global_node_page_state(NR_INACTIVE_ANON)
+ global_node_page_state(NR_ACTIVE_FILE)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 17c667b427b4..0869b20fba81 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2069,7 +2069,7 @@ out:
/**
* try_to_wake_up_local - try to wake up a local task with rq lock held
* @p: the thread to be awakened
- * @cookie: context's cookie for pinning
+ * @rf: request-queue flags for pinning
*
* Put @p on the run-queue if it's not already there. The caller must
* ensure that this_rq() is locked, @p is bound to this_rq() and not
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index 6e3ea4ac1bda..14d2dbf97c53 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -683,7 +683,7 @@ static u64 vtime_delta(struct vtime *vtime)
{
unsigned long long clock;
- clock = sched_clock_cpu(smp_processor_id());
+ clock = sched_clock();
if (clock < vtime->starttime)
return 0;
@@ -814,7 +814,7 @@ void arch_vtime_task_switch(struct task_struct *prev)
write_seqcount_begin(&vtime->seqcount);
vtime->state = VTIME_SYS;
- vtime->starttime = sched_clock_cpu(smp_processor_id());
+ vtime->starttime = sched_clock();
write_seqcount_end(&vtime->seqcount);
}
@@ -826,7 +826,7 @@ void vtime_init_idle(struct task_struct *t, int cpu)
local_irq_save(flags);
write_seqcount_begin(&vtime->seqcount);
vtime->state = VTIME_SYS;
- vtime->starttime = sched_clock_cpu(cpu);
+ vtime->starttime = sched_clock();
write_seqcount_end(&vtime->seqcount);
local_irq_restore(flags);
}
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index a84299f44b5d..755bd3f1a1a9 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -1392,17 +1392,19 @@ static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags)
struct sched_dl_entity *pi_se = &p->dl;
/*
- * Use the scheduling parameters of the top pi-waiter
- * task if we have one and its (absolute) deadline is
- * smaller than our one... OTW we keep our runtime and
- * deadline.
+ * Use the scheduling parameters of the top pi-waiter task if:
+ * - we have a top pi-waiter which is a SCHED_DEADLINE task AND
+ * - our dl_boosted is set (i.e. the pi-waiter's (absolute) deadline is
+ * smaller than our deadline OR we are a !SCHED_DEADLINE task getting
+ * boosted due to a SCHED_DEADLINE pi-waiter).
+ * Otherwise we keep our runtime and deadline.
*/
- if (pi_task && p->dl.dl_boosted && dl_prio(pi_task->normal_prio)) {
+ if (pi_task && dl_prio(pi_task->normal_prio) && p->dl.dl_boosted) {
pi_se = &pi_task->dl;
} else if (!dl_prio(p->normal_prio)) {
/*
* Special case in which we have a !SCHED_DEADLINE task
- * that is going to be deboosted, but exceedes its
+ * that is going to be deboosted, but exceeds its
* runtime while doing so. No point in replenishing
* it, as it's going to return back to its original
* scheduling class after this.
diff --git a/kernel/signal.c b/kernel/signal.c
index caed9133ae52..7e33f8c583e6 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -3303,12 +3303,15 @@ SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set)
#ifdef CONFIG_COMPAT
COMPAT_SYSCALL_DEFINE1(sigpending, compat_old_sigset_t __user *, set32)
{
+#ifdef __BIG_ENDIAN
sigset_t set;
- int err = do_sigpending(&set, sizeof(old_sigset_t));
- if (err == 0)
- if (copy_to_user(set32, &set, sizeof(old_sigset_t)))
- err = -EFAULT;
+ int err = do_sigpending(&set, sizeof(set.sig[0]));
+ if (!err)
+ err = put_user(set.sig[0], set32);
return err;
+#else
+ return sys_rt_sigpending((sigset_t __user *)set32, sizeof(*set32));
+#endif
}
#endif
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 71ce3f4eead3..8f5d1bf18854 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1495,7 +1495,7 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem)
base->is_idle = false;
} else {
if (!is_max_delta)
- expires = basem + (nextevt - basej) * TICK_NSEC;
+ expires = basem + (u64)(nextevt - basej) * TICK_NSEC;
/*
* If we expect to sleep more than a tick, mark the base idle:
*/
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 53f6b6401cf0..02004ae91860 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -113,7 +113,7 @@ static int ftrace_disabled __read_mostly;
static DEFINE_MUTEX(ftrace_lock);
-static struct ftrace_ops *ftrace_ops_list __read_mostly = &ftrace_list_end;
+static struct ftrace_ops __rcu *ftrace_ops_list __read_mostly = &ftrace_list_end;
ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub;
static struct ftrace_ops global_ops;
@@ -169,8 +169,11 @@ int ftrace_nr_registered_ops(void)
mutex_lock(&ftrace_lock);
- for (ops = ftrace_ops_list;
- ops != &ftrace_list_end; ops = ops->next)
+ for (ops = rcu_dereference_protected(ftrace_ops_list,
+ lockdep_is_held(&ftrace_lock));
+ ops != &ftrace_list_end;
+ ops = rcu_dereference_protected(ops->next,
+ lockdep_is_held(&ftrace_lock)))
cnt++;
mutex_unlock(&ftrace_lock);
@@ -275,10 +278,11 @@ static void update_ftrace_function(void)
* If there's only one ftrace_ops registered, the ftrace_ops_list
* will point to the ops we want.
*/
- set_function_trace_op = ftrace_ops_list;
+ set_function_trace_op = rcu_dereference_protected(ftrace_ops_list,
+ lockdep_is_held(&ftrace_lock));
/* If there's no ftrace_ops registered, just call the stub function */
- if (ftrace_ops_list == &ftrace_list_end) {
+ if (set_function_trace_op == &ftrace_list_end) {
func = ftrace_stub;
/*
@@ -286,7 +290,8 @@ static void update_ftrace_function(void)
* recursion safe and not dynamic and the arch supports passing ops,
* then have the mcount trampoline call the function directly.
*/
- } else if (ftrace_ops_list->next == &ftrace_list_end) {
+ } else if (rcu_dereference_protected(ftrace_ops_list->next,
+ lockdep_is_held(&ftrace_lock)) == &ftrace_list_end) {
func = ftrace_ops_get_list_func(ftrace_ops_list);
} else {
@@ -348,9 +353,11 @@ int using_ftrace_ops_list_func(void)
return ftrace_trace_function == ftrace_ops_list_func;
}
-static void add_ftrace_ops(struct ftrace_ops **list, struct ftrace_ops *ops)
+static void add_ftrace_ops(struct ftrace_ops __rcu **list,
+ struct ftrace_ops *ops)
{
- ops->next = *list;
+ rcu_assign_pointer(ops->next, *list);
+
/*
* We are entering ops into the list but another
* CPU might be walking that list. We need to make sure
@@ -360,7 +367,8 @@ static void add_ftrace_ops(struct ftrace_ops **list, struct ftrace_ops *ops)
rcu_assign_pointer(*list, ops);
}
-static int remove_ftrace_ops(struct ftrace_ops **list, struct ftrace_ops *ops)
+static int remove_ftrace_ops(struct ftrace_ops __rcu **list,
+ struct ftrace_ops *ops)
{
struct ftrace_ops **p;
@@ -368,7 +376,10 @@ static int remove_ftrace_ops(struct ftrace_ops **list, struct ftrace_ops *ops)
* If we are removing the last function, then simply point
* to the ftrace_stub.
*/
- if (*list == ops && ops->next == &ftrace_list_end) {
+ if (rcu_dereference_protected(*list,
+ lockdep_is_held(&ftrace_lock)) == ops &&
+ rcu_dereference_protected(ops->next,
+ lockdep_is_held(&ftrace_lock)) == &ftrace_list_end) {
*list = &ftrace_list_end;
return 0;
}
@@ -1569,8 +1580,8 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip, void *regs)
return 0;
#endif
- hash.filter_hash = rcu_dereference_raw_notrace(ops->func_hash->filter_hash);
- hash.notrace_hash = rcu_dereference_raw_notrace(ops->func_hash->notrace_hash);
+ rcu_assign_pointer(hash.filter_hash, ops->func_hash->filter_hash);
+ rcu_assign_pointer(hash.notrace_hash, ops->func_hash->notrace_hash);
if (hash_contains_ip(ip, &hash))
ret = 1;
@@ -2840,7 +2851,8 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command)
* If there's no more ops registered with ftrace, run a
* sanity check to make sure all rec flags are cleared.
*/
- if (ftrace_ops_list == &ftrace_list_end) {
+ if (rcu_dereference_protected(ftrace_ops_list,
+ lockdep_is_held(&ftrace_lock)) == &ftrace_list_end) {
struct ftrace_page *pg;
struct dyn_ftrace *rec;
@@ -6453,7 +6465,8 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
if (ftrace_enabled) {
/* we are starting ftrace again */
- if (ftrace_ops_list != &ftrace_list_end)
+ if (rcu_dereference_protected(ftrace_ops_list,
+ lockdep_is_held(&ftrace_lock)) != &ftrace_list_end)
update_ftrace_function();
ftrace_startup_sysctl();
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 4ae268e687fe..529cc50d7243 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -1136,12 +1136,12 @@ static int __rb_allocate_pages(long nr_pages, struct list_head *pages, int cpu)
for (i = 0; i < nr_pages; i++) {
struct page *page;
/*
- * __GFP_NORETRY flag makes sure that the allocation fails
- * gracefully without invoking oom-killer and the system is
- * not destabilized.
+ * __GFP_RETRY_MAYFAIL flag makes sure that the allocation fails
+ * gracefully without invoking oom-killer and the system is not
+ * destabilized.
*/
bpage = kzalloc_node(ALIGN(sizeof(*bpage), cache_line_size()),
- GFP_KERNEL | __GFP_NORETRY,
+ GFP_KERNEL | __GFP_RETRY_MAYFAIL,
cpu_to_node(cpu));
if (!bpage)
goto free_pages;
@@ -1149,7 +1149,7 @@ static int __rb_allocate_pages(long nr_pages, struct list_head *pages, int cpu)
list_add(&bpage->list, pages);
page = alloc_pages_node(cpu_to_node(cpu),
- GFP_KERNEL | __GFP_NORETRY, 0);
+ GFP_KERNEL | __GFP_RETRY_MAYFAIL, 0);
if (!page)
goto free_pages;
bpage->page = page_address(page);
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 2d0ffcc49dba..42b9355033d4 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -7774,6 +7774,7 @@ static int instance_rmdir(const char *name)
}
kfree(tr->topts);
+ free_cpumask_var(tr->tracing_cpumask);
kfree(tr->name);
kfree(tr);
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 6ade1c55cc3a..490ba229931d 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1210,9 +1210,9 @@ struct ftrace_event_field {
struct event_filter {
int n_preds; /* Number assigned */
int a_preds; /* allocated */
- struct filter_pred *preds;
- struct filter_pred *root;
- char *filter_string;
+ struct filter_pred __rcu *preds;
+ struct filter_pred __rcu *root;
+ char *filter_string;
};
struct event_subsystem {
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index a86688fabc55..ca937b0c3a96 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -3577,6 +3577,13 @@ static bool wq_calc_node_cpumask(const struct workqueue_attrs *attrs, int node,
/* yeap, return possible CPUs in @node that @attrs wants */
cpumask_and(cpumask, attrs->cpumask, wq_numa_possible_cpumask[node]);
+
+ if (cpumask_empty(cpumask)) {
+ pr_warn_once("WARNING: workqueue cpumask: online intersect > "
+ "possible intersect\n");
+ return false;
+ }
+
return !cpumask_equal(cpumask, attrs->cpumask);
use_dfl:
@@ -3744,8 +3751,12 @@ static int apply_workqueue_attrs_locked(struct workqueue_struct *wq,
return -EINVAL;
/* creating multiple pwqs breaks ordering guarantee */
- if (WARN_ON((wq->flags & __WQ_ORDERED) && !list_empty(&wq->pwqs)))
- return -EINVAL;
+ if (!list_empty(&wq->pwqs)) {
+ if (WARN_ON(wq->flags & __WQ_ORDERED_EXPLICIT))
+ return -EINVAL;
+
+ wq->flags &= ~__WQ_ORDERED;
+ }
ctx = apply_wqattrs_prepare(wq, attrs);
if (!ctx)
@@ -3929,6 +3940,16 @@ struct workqueue_struct *__alloc_workqueue_key(const char *fmt,
struct workqueue_struct *wq;
struct pool_workqueue *pwq;
+ /*
+ * Unbound && max_active == 1 used to imply ordered, which is no
+ * longer the case on NUMA machines due to per-node pools. While
+ * alloc_ordered_workqueue() is the right way to create an ordered
+ * workqueue, keep the previous behavior to avoid subtle breakages
+ * on NUMA.
+ */
+ if ((flags & WQ_UNBOUND) && max_active == 1)
+ flags |= __WQ_ORDERED;
+
/* see the comment above the definition of WQ_POWER_EFFICIENT */
if ((flags & WQ_POWER_EFFICIENT) && wq_power_efficient)
flags |= WQ_UNBOUND;
@@ -4119,13 +4140,14 @@ void workqueue_set_max_active(struct workqueue_struct *wq, int max_active)
struct pool_workqueue *pwq;
/* disallow meddling with max_active for ordered workqueues */
- if (WARN_ON(wq->flags & __WQ_ORDERED))
+ if (WARN_ON(wq->flags & __WQ_ORDERED_EXPLICIT))
return;
max_active = wq_clamp_max_active(max_active, wq->flags, wq->name);
mutex_lock(&wq->mutex);
+ wq->flags &= ~__WQ_ORDERED;
wq->saved_max_active = max_active;
for_each_pwq(pwq, wq)
@@ -5253,7 +5275,7 @@ int workqueue_sysfs_register(struct workqueue_struct *wq)
* attributes breaks ordering guarantee. Disallow exposing ordered
* workqueues.
*/
- if (WARN_ON(wq->flags & __WQ_ORDERED))
+ if (WARN_ON(wq->flags & __WQ_ORDERED_EXPLICIT))
return -EINVAL;
wq->wq_dev = wq_dev = kzalloc(sizeof(*wq_dev), GFP_KERNEL);
diff --git a/lib/fault-inject.c b/lib/fault-inject.c
index 7d315fdb9f13..cf7b129b0b2b 100644
--- a/lib/fault-inject.c
+++ b/lib/fault-inject.c
@@ -110,10 +110,12 @@ bool should_fail(struct fault_attr *attr, ssize_t size)
if (in_task()) {
unsigned int fail_nth = READ_ONCE(current->fail_nth);
- if (fail_nth && !WRITE_ONCE(current->fail_nth, fail_nth - 1))
- goto fail;
+ if (fail_nth) {
+ if (!WRITE_ONCE(current->fail_nth, fail_nth - 1))
+ goto fail;
- return false;
+ return false;
+ }
}
/* No need to check any other properties if the probability is 0 */
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 898e87998417..3527eb364964 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -2022,6 +2022,7 @@ void radix_tree_iter_delete(struct radix_tree_root *root,
if (__radix_tree_delete(root, iter->node, slot))
iter->index = iter->next_index;
}
+EXPORT_SYMBOL(radix_tree_iter_delete);
/**
* radix_tree_delete_item - delete an item from a radix tree
diff --git a/lib/test_kmod.c b/lib/test_kmod.c
index 6c1d678bcf8b..ff9148969b92 100644
--- a/lib/test_kmod.c
+++ b/lib/test_kmod.c
@@ -485,7 +485,7 @@ static ssize_t config_show(struct device *dev,
config->test_driver);
else
len += snprintf(buf+len, PAGE_SIZE - len,
- "driver:\tEMTPY\n");
+ "driver:\tEMPTY\n");
if (config->test_fs)
len += snprintf(buf+len, PAGE_SIZE - len,
@@ -493,7 +493,7 @@ static ssize_t config_show(struct device *dev,
config->test_fs);
else
len += snprintf(buf+len, PAGE_SIZE - len,
- "fs:\tEMTPY\n");
+ "fs:\tEMPTY\n");
mutex_unlock(&test_dev->config_mutex);
@@ -746,11 +746,11 @@ static int trigger_config_run_type(struct kmod_test_device *test_dev,
strlen(test_str));
break;
case TEST_KMOD_FS_TYPE:
- break;
kfree_const(config->test_fs);
config->test_driver = NULL;
copied = config_copy_test_fs(config, test_str,
strlen(test_str));
+ break;
default:
mutex_unlock(&test_dev->config_mutex);
return -EINVAL;
@@ -880,10 +880,10 @@ static int test_dev_config_update_uint_sync(struct kmod_test_device *test_dev,
int (*test_sync)(struct kmod_test_device *test_dev))
{
int ret;
- long new;
+ unsigned long new;
unsigned int old_val;
- ret = kstrtol(buf, 10, &new);
+ ret = kstrtoul(buf, 10, &new);
if (ret)
return ret;
@@ -918,9 +918,9 @@ static int test_dev_config_update_uint_range(struct kmod_test_device *test_dev,
unsigned int max)
{
int ret;
- long new;
+ unsigned long new;
- ret = kstrtol(buf, 10, &new);
+ ret = kstrtoul(buf, 10, &new);
if (ret)
return ret;
@@ -1146,7 +1146,7 @@ static struct kmod_test_device *register_test_dev_kmod(void)
struct kmod_test_device *test_dev = NULL;
int ret;
- mutex_unlock(&reg_dev_mutex);
+ mutex_lock(&reg_dev_mutex);
/* int should suffice for number of devices, test for wrap */
if (unlikely(num_test_devs + 1) < 0) {
diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c
index 64e899b63337..0ffca990a833 100644
--- a/lib/test_rhashtable.c
+++ b/lib/test_rhashtable.c
@@ -56,8 +56,13 @@ static bool enomem_retry = false;
module_param(enomem_retry, bool, 0);
MODULE_PARM_DESC(enomem_retry, "Retry insert even if -ENOMEM was returned (default: off)");
+struct test_obj_val {
+ int id;
+ int tid;
+};
+
struct test_obj {
- int value;
+ struct test_obj_val value;
struct rhash_head node;
};
@@ -72,7 +77,7 @@ static struct test_obj array[MAX_ENTRIES];
static struct rhashtable_params test_rht_params = {
.head_offset = offsetof(struct test_obj, node),
.key_offset = offsetof(struct test_obj, value),
- .key_len = sizeof(int),
+ .key_len = sizeof(struct test_obj_val),
.hashfn = jhash,
.nulls_base = (3U << RHT_BASE_SHIFT),
};
@@ -109,24 +114,26 @@ static int __init test_rht_lookup(struct rhashtable *ht)
for (i = 0; i < entries * 2; i++) {
struct test_obj *obj;
bool expected = !(i % 2);
- u32 key = i;
+ struct test_obj_val key = {
+ .id = i,
+ };
- if (array[i / 2].value == TEST_INSERT_FAIL)
+ if (array[i / 2].value.id == TEST_INSERT_FAIL)
expected = false;
obj = rhashtable_lookup_fast(ht, &key, test_rht_params);
if (expected && !obj) {
- pr_warn("Test failed: Could not find key %u\n", key);
+ pr_warn("Test failed: Could not find key %u\n", key.id);
return -ENOENT;
} else if (!expected && obj) {
pr_warn("Test failed: Unexpected entry found for key %u\n",
- key);
+ key.id);
return -EEXIST;
} else if (expected && obj) {
- if (obj->value != i) {
+ if (obj->value.id != i) {
pr_warn("Test failed: Lookup value mismatch %u!=%u\n",
- obj->value, i);
+ obj->value.id, i);
return -EINVAL;
}
}
@@ -195,7 +202,7 @@ static s64 __init test_rhashtable(struct rhashtable *ht)
for (i = 0; i < entries; i++) {
struct test_obj *obj = &array[i];
- obj->value = i * 2;
+ obj->value.id = i * 2;
err = insert_retry(ht, &obj->node, test_rht_params);
if (err > 0)
insert_retries += err;
@@ -216,9 +223,11 @@ static s64 __init test_rhashtable(struct rhashtable *ht)
pr_info(" Deleting %d keys\n", entries);
for (i = 0; i < entries; i++) {
- u32 key = i * 2;
+ struct test_obj_val key = {
+ .id = i * 2,
+ };
- if (array[i].value != TEST_INSERT_FAIL) {
+ if (array[i].value.id != TEST_INSERT_FAIL) {
obj = rhashtable_lookup_fast(ht, &key, test_rht_params);
BUG_ON(!obj);
@@ -242,18 +251,21 @@ static int thread_lookup_test(struct thread_data *tdata)
for (i = 0; i < entries; i++) {
struct test_obj *obj;
- int key = (tdata->id << 16) | i;
+ struct test_obj_val key = {
+ .id = i,
+ .tid = tdata->id,
+ };
obj = rhashtable_lookup_fast(&ht, &key, test_rht_params);
- if (obj && (tdata->objs[i].value == TEST_INSERT_FAIL)) {
- pr_err(" found unexpected object %d\n", key);
+ if (obj && (tdata->objs[i].value.id == TEST_INSERT_FAIL)) {
+ pr_err(" found unexpected object %d-%d\n", key.tid, key.id);
err++;
- } else if (!obj && (tdata->objs[i].value != TEST_INSERT_FAIL)) {
- pr_err(" object %d not found!\n", key);
+ } else if (!obj && (tdata->objs[i].value.id != TEST_INSERT_FAIL)) {
+ pr_err(" object %d-%d not found!\n", key.tid, key.id);
err++;
- } else if (obj && (obj->value != key)) {
- pr_err(" wrong object returned (got %d, expected %d)\n",
- obj->value, key);
+ } else if (obj && memcmp(&obj->value, &key, sizeof(key))) {
+ pr_err(" wrong object returned (got %d-%d, expected %d-%d)\n",
+ obj->value.tid, obj->value.id, key.tid, key.id);
err++;
}
@@ -272,7 +284,8 @@ static int threadfunc(void *data)
pr_err(" thread[%d]: down_interruptible failed\n", tdata->id);
for (i = 0; i < entries; i++) {
- tdata->objs[i].value = (tdata->id << 16) | i;
+ tdata->objs[i].value.id = i;
+ tdata->objs[i].value.tid = tdata->id;
err = insert_retry(&ht, &tdata->objs[i].node, test_rht_params);
if (err > 0) {
insert_retries += err;
@@ -295,7 +308,7 @@ static int threadfunc(void *data)
for (step = 10; step > 0; step--) {
for (i = 0; i < entries; i += step) {
- if (tdata->objs[i].value == TEST_INSERT_FAIL)
+ if (tdata->objs[i].value.id == TEST_INSERT_FAIL)
continue;
err = rhashtable_remove_fast(&ht, &tdata->objs[i].node,
test_rht_params);
@@ -304,7 +317,7 @@ static int threadfunc(void *data)
tdata->id);
goto out;
}
- tdata->objs[i].value = TEST_INSERT_FAIL;
+ tdata->objs[i].value.id = TEST_INSERT_FAIL;
cond_resched();
}
diff --git a/lib/test_uuid.c b/lib/test_uuid.c
index 478c049630b5..cd819c397dc7 100644
--- a/lib/test_uuid.c
+++ b/lib/test_uuid.c
@@ -82,7 +82,7 @@ static void __init test_uuid_test(const struct test_uuid_data *data)
test_uuid_failed("conversion", false, true, data->uuid, NULL);
total_tests++;
- if (uuid_equal(&data->be, &be)) {
+ if (!uuid_equal(&data->be, &be)) {
sprintf(buf, "%pUb", &be);
test_uuid_failed("cmp", false, true, data->uuid, buf);
}
diff --git a/mm/balloon_compaction.c b/mm/balloon_compaction.c
index 9075aa54e955..b06d9fe23a28 100644
--- a/mm/balloon_compaction.c
+++ b/mm/balloon_compaction.c
@@ -24,7 +24,7 @@ struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info)
{
unsigned long flags;
struct page *page = alloc_page(balloon_mapping_gfp_mask() |
- __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_ZERO);
+ __GFP_NOMEMALLOC | __GFP_NORETRY);
if (!page)
return NULL;
diff --git a/mm/debug.c b/mm/debug.c
index db1cd26d8752..5715448ab0b5 100644
--- a/mm/debug.c
+++ b/mm/debug.c
@@ -124,9 +124,7 @@ void dump_mm(const struct mm_struct *mm)
#ifdef CONFIG_NUMA_BALANCING
"numa_next_scan %lu numa_scan_offset %lu numa_scan_seq %d\n"
#endif
-#if defined(CONFIG_NUMA_BALANCING) || defined(CONFIG_COMPACTION)
"tlb_flush_pending %d\n"
-#endif
"def_flags: %#lx(%pGv)\n",
mm, mm->mmap, mm->vmacache_seqnum, mm->task_size,
@@ -158,9 +156,7 @@ void dump_mm(const struct mm_struct *mm)
#ifdef CONFIG_NUMA_BALANCING
mm->numa_next_scan, mm->numa_scan_offset, mm->numa_scan_seq,
#endif
-#if defined(CONFIG_NUMA_BALANCING) || defined(CONFIG_COMPACTION)
- mm->tlb_flush_pending,
-#endif
+ atomic_read(&mm->tlb_flush_pending),
mm->def_flags, &mm->def_flags
);
}
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 86975dec0ba1..216114f6ef0b 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1496,6 +1496,13 @@ int do_huge_pmd_numa_page(struct vm_fault *vmf, pmd_t pmd)
}
/*
+ * The page_table_lock above provides a memory barrier
+ * with change_protection_range.
+ */
+ if (mm_tlb_flush_pending(vma->vm_mm))
+ flush_tlb_range(vma, haddr, haddr + HPAGE_PMD_SIZE);
+
+ /*
* Migrate the THP to the requested node, returns with page unlocked
* and access rights restored.
*/
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index bc48ee783dd9..31e207cb399b 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -4062,9 +4062,9 @@ out:
return ret;
out_release_unlock:
spin_unlock(ptl);
-out_release_nounlock:
if (vm_shared)
unlock_page(page);
+out_release_nounlock:
put_page(page);
goto out;
}
@@ -4078,6 +4078,7 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long vaddr = *position;
unsigned long remainder = *nr_pages;
struct hstate *h = hstate_vma(vma);
+ int err = -EFAULT;
while (vaddr < vma->vm_end && remainder) {
pte_t *pte;
@@ -4154,11 +4155,7 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
}
ret = hugetlb_fault(mm, vma, vaddr, fault_flags);
if (ret & VM_FAULT_ERROR) {
- int err = vm_fault_to_errno(ret, flags);
-
- if (err)
- return err;
-
+ err = vm_fault_to_errno(ret, flags);
remainder = 0;
break;
}
@@ -4213,7 +4210,7 @@ same_page:
*/
*position = vaddr;
- return i ? i : -EFAULT;
+ return i ? i : err;
}
#ifndef __HAVE_ARCH_FLUSH_HUGETLB_TLB_RANGE
diff --git a/mm/internal.h b/mm/internal.h
index 24d88f084705..4ef49fc55e58 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -498,6 +498,7 @@ extern struct workqueue_struct *mm_percpu_wq;
#ifdef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
void try_to_unmap_flush(void);
void try_to_unmap_flush_dirty(void);
+void flush_tlb_batched_pending(struct mm_struct *mm);
#else
static inline void try_to_unmap_flush(void)
{
@@ -505,7 +506,9 @@ static inline void try_to_unmap_flush(void)
static inline void try_to_unmap_flush_dirty(void)
{
}
-
+static inline void flush_tlb_batched_pending(struct mm_struct *mm)
+{
+}
#endif /* CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH */
extern const struct trace_print_flags pageflag_names[];
diff --git a/mm/kasan/report.c b/mm/kasan/report.c
index 04bb1d3eb9ec..6bcfb01ba038 100644
--- a/mm/kasan/report.c
+++ b/mm/kasan/report.c
@@ -401,6 +401,7 @@ void kasan_report(unsigned long addr, size_t size,
disable_trace_on_warning();
info.access_addr = (void *)addr;
+ info.first_bad_addr = (void *)addr;
info.access_size = size;
info.is_write = is_write;
info.ip = ip;
diff --git a/mm/ksm.c b/mm/ksm.c
index 4dc92f138786..db20f8436bc3 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1038,7 +1038,8 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page,
goto out_unlock;
if (pte_write(*pvmw.pte) || pte_dirty(*pvmw.pte) ||
- (pte_protnone(*pvmw.pte) && pte_savedwrite(*pvmw.pte))) {
+ (pte_protnone(*pvmw.pte) && pte_savedwrite(*pvmw.pte)) ||
+ mm_tlb_flush_pending(mm)) {
pte_t entry;
swapped = PageSwapCache(page);
diff --git a/mm/madvise.c b/mm/madvise.c
index 9976852f1e1c..47d8d8a25eae 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -320,6 +320,7 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
tlb_remove_check_page_size_change(tlb, PAGE_SIZE);
orig_pte = pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+ flush_tlb_batched_pending(mm);
arch_enter_lazy_mmu_mode();
for (; addr != end; pte++, addr += PAGE_SIZE) {
ptent = *pte;
diff --git a/mm/memory.c b/mm/memory.c
index 0e517be91a89..e158f7ac6730 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -215,12 +215,8 @@ static bool tlb_next_batch(struct mmu_gather *tlb)
return true;
}
-/* tlb_gather_mmu
- * Called to initialize an (on-stack) mmu_gather structure for page-table
- * tear-down from @mm. The @fullmm argument is used when @mm is without
- * users and we're going to destroy the full address space (exit/execve).
- */
-void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
+void arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
+ unsigned long start, unsigned long end)
{
tlb->mm = mm;
@@ -275,10 +271,14 @@ void tlb_flush_mmu(struct mmu_gather *tlb)
* Called at the end of the shootdown operation to free up any resources
* that were required.
*/
-void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
+void arch_tlb_finish_mmu(struct mmu_gather *tlb,
+ unsigned long start, unsigned long end, bool force)
{
struct mmu_gather_batch *batch, *next;
+ if (force)
+ __tlb_adjust_range(tlb, start, end - start);
+
tlb_flush_mmu(tlb);
/* keep the page table cache within bounds */
@@ -398,6 +398,34 @@ void tlb_remove_table(struct mmu_gather *tlb, void *table)
#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
+/* tlb_gather_mmu
+ * Called to initialize an (on-stack) mmu_gather structure for page-table
+ * tear-down from @mm. The @fullmm argument is used when @mm is without
+ * users and we're going to destroy the full address space (exit/execve).
+ */
+void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
+ unsigned long start, unsigned long end)
+{
+ arch_tlb_gather_mmu(tlb, mm, start, end);
+ inc_tlb_flush_pending(tlb->mm);
+}
+
+void tlb_finish_mmu(struct mmu_gather *tlb,
+ unsigned long start, unsigned long end)
+{
+ /*
+ * If there are parallel threads are doing PTE changes on same range
+ * under non-exclusive lock(e.g., mmap_sem read-side) but defer TLB
+ * flush by batching, a thread has stable TLB entry can fail to flush
+ * the TLB by observing pte_none|!pte_dirty, for example so flush TLB
+ * forcefully if we detect parallel PTE batching threads.
+ */
+ bool force = mm_tlb_flush_nested(tlb->mm);
+
+ arch_tlb_finish_mmu(tlb, start, end, force);
+ dec_tlb_flush_pending(tlb->mm);
+}
+
/*
* Note: this doesn't free the actual pages themselves. That
* has been handled earlier when unmapping all the memory regions.
@@ -1197,6 +1225,7 @@ again:
init_rss_vec(rss);
start_pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
pte = start_pte;
+ flush_tlb_batched_pending(mm);
arch_enter_lazy_mmu_mode();
do {
pte_t ptent = *pte;
diff --git a/mm/migrate.c b/mm/migrate.c
index 627671551873..d68a41da6abb 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1937,12 +1937,6 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,
put_page(new_page);
goto out_fail;
}
- /*
- * We are not sure a pending tlb flush here is for a huge page
- * mapping or not. Hence use the tlb range variant
- */
- if (mm_tlb_flush_pending(mm))
- flush_tlb_range(vma, mmun_start, mmun_end);
/* Prepare a page as a migration target */
__SetPageLocked(new_page);
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 1a8c9ca83e48..bd0f409922cb 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -64,6 +64,7 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
atomic_read(&vma->vm_mm->mm_users) == 1)
target_node = numa_node_id();
+ flush_tlb_batched_pending(vma->vm_mm);
arch_enter_lazy_mmu_mode();
do {
oldpte = *pte;
@@ -243,7 +244,7 @@ static unsigned long change_protection_range(struct vm_area_struct *vma,
BUG_ON(addr >= end);
pgd = pgd_offset(mm, addr);
flush_cache_range(vma, addr, end);
- set_tlb_flush_pending(mm);
+ inc_tlb_flush_pending(mm);
do {
next = pgd_addr_end(addr, end);
if (pgd_none_or_clear_bad(pgd))
@@ -255,7 +256,7 @@ static unsigned long change_protection_range(struct vm_area_struct *vma,
/* Only flush the TLB if we actually modified any entries: */
if (pages)
flush_tlb_range(vma, start, end);
- clear_tlb_flush_pending(mm);
+ dec_tlb_flush_pending(mm);
return pages;
}
diff --git a/mm/mremap.c b/mm/mremap.c
index cd8a1b199ef9..3f23715d3c69 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -152,6 +152,7 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
new_ptl = pte_lockptr(mm, new_pmd);
if (new_ptl != old_ptl)
spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
+ flush_tlb_batched_pending(vma->vm_mm);
arch_enter_lazy_mmu_mode();
for (; old_addr < old_end; old_pte++, old_addr += PAGE_SIZE,
@@ -428,6 +429,7 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr,
static unsigned long mremap_to(unsigned long addr, unsigned long old_len,
unsigned long new_addr, unsigned long new_len, bool *locked,
struct vm_userfaultfd_ctx *uf,
+ struct list_head *uf_unmap_early,
struct list_head *uf_unmap)
{
struct mm_struct *mm = current->mm;
@@ -446,7 +448,7 @@ static unsigned long mremap_to(unsigned long addr, unsigned long old_len,
if (addr + old_len > new_addr && new_addr + new_len > addr)
goto out;
- ret = do_munmap(mm, new_addr, new_len, NULL);
+ ret = do_munmap(mm, new_addr, new_len, uf_unmap_early);
if (ret)
goto out;
@@ -514,6 +516,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
unsigned long charged = 0;
bool locked = false;
struct vm_userfaultfd_ctx uf = NULL_VM_UFFD_CTX;
+ LIST_HEAD(uf_unmap_early);
LIST_HEAD(uf_unmap);
if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
@@ -541,7 +544,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
if (flags & MREMAP_FIXED) {
ret = mremap_to(addr, old_len, new_addr, new_len,
- &locked, &uf, &uf_unmap);
+ &locked, &uf, &uf_unmap_early, &uf_unmap);
goto out;
}
@@ -621,6 +624,7 @@ out:
up_write(&current->mm->mmap_sem);
if (locked && new_len > old_len)
mm_populate(new_addr + old_len, new_len - old_len);
+ userfaultfd_unmap_complete(mm, &uf_unmap_early);
mremap_userfaultfd_complete(&uf, addr, new_addr, old_len);
userfaultfd_unmap_complete(mm, &uf_unmap);
return ret;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 6d30e914afb6..6d00f746c2fd 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -4458,8 +4458,9 @@ long si_mem_available(void)
* Part of the reclaimable slab consists of items that are in use,
* and cannot be freed. Cap this estimate at the low watermark.
*/
- available += global_page_state(NR_SLAB_RECLAIMABLE) -
- min(global_page_state(NR_SLAB_RECLAIMABLE) / 2, wmark_low);
+ available += global_node_page_state(NR_SLAB_RECLAIMABLE) -
+ min(global_node_page_state(NR_SLAB_RECLAIMABLE) / 2,
+ wmark_low);
if (available < 0)
available = 0;
@@ -4602,8 +4603,8 @@ void show_free_areas(unsigned int filter, nodemask_t *nodemask)
global_node_page_state(NR_FILE_DIRTY),
global_node_page_state(NR_WRITEBACK),
global_node_page_state(NR_UNSTABLE_NFS),
- global_page_state(NR_SLAB_RECLAIMABLE),
- global_page_state(NR_SLAB_UNRECLAIMABLE),
+ global_node_page_state(NR_SLAB_RECLAIMABLE),
+ global_node_page_state(NR_SLAB_UNRECLAIMABLE),
global_node_page_state(NR_FILE_MAPPED),
global_node_page_state(NR_SHMEM),
global_page_state(NR_PAGETABLE),
@@ -4891,9 +4892,11 @@ int numa_zonelist_order_handler(struct ctl_table *table, int write,
NUMA_ZONELIST_ORDER_LEN);
user_zonelist_order = oldval;
} else if (oldval != user_zonelist_order) {
+ mem_hotplug_begin();
mutex_lock(&zonelists_mutex);
build_all_zonelists(NULL, NULL);
mutex_unlock(&zonelists_mutex);
+ mem_hotplug_done();
}
}
out:
@@ -7666,7 +7669,7 @@ int alloc_contig_range(unsigned long start, unsigned long end,
/* Make sure the range is really isolated. */
if (test_pages_isolated(outer_start, end, false)) {
- pr_info("%s: [%lx, %lx) PFNs busy\n",
+ pr_info_ratelimited("%s: [%lx, %lx) PFNs busy\n",
__func__, outer_start, end);
ret = -EBUSY;
goto done;
diff --git a/mm/page_io.c b/mm/page_io.c
index b6c4ac388209..5f61b54ee1f3 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -22,6 +22,7 @@
#include <linux/frontswap.h>
#include <linux/blkdev.h>
#include <linux/uio.h>
+#include <linux/sched/task.h>
#include <asm/pgtable.h>
static struct bio *get_swap_bio(gfp_t gfp_flags,
@@ -136,6 +137,7 @@ out:
WRITE_ONCE(bio->bi_private, NULL);
bio_put(bio);
wake_up_process(waiter);
+ put_task_struct(waiter);
}
int generic_swapfile_activate(struct swap_info_struct *sis,
@@ -378,6 +380,11 @@ int swap_readpage(struct page *page, bool do_poll)
goto out;
}
bdev = bio->bi_bdev;
+ /*
+ * Keep this task valid during swap readpage because the oom killer may
+ * attempt to access it in the page fault retry time check.
+ */
+ get_task_struct(current);
bio->bi_private = current;
bio_set_op_attrs(bio, REQ_OP_READ, 0);
count_vm_event(PSWPIN);
diff --git a/mm/rmap.c b/mm/rmap.c
index ced14f1af6dc..c1286d47aa1f 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -605,6 +605,13 @@ static void set_tlb_ubc_flush_pending(struct mm_struct *mm, bool writable)
tlb_ubc->flush_required = true;
/*
+ * Ensure compiler does not re-order the setting of tlb_flush_batched
+ * before the PTE is cleared.
+ */
+ barrier();
+ mm->tlb_flush_batched = true;
+
+ /*
* If the PTE was dirty then it's best to assume it's writable. The
* caller must use try_to_unmap_flush_dirty() or try_to_unmap_flush()
* before the page is queued for IO.
@@ -631,6 +638,35 @@ static bool should_defer_flush(struct mm_struct *mm, enum ttu_flags flags)
return should_defer;
}
+
+/*
+ * Reclaim unmaps pages under the PTL but do not flush the TLB prior to
+ * releasing the PTL if TLB flushes are batched. It's possible for a parallel
+ * operation such as mprotect or munmap to race between reclaim unmapping
+ * the page and flushing the page. If this race occurs, it potentially allows
+ * access to data via a stale TLB entry. Tracking all mm's that have TLB
+ * batching in flight would be expensive during reclaim so instead track
+ * whether TLB batching occurred in the past and if so then do a flush here
+ * if required. This will cost one additional flush per reclaim cycle paid
+ * by the first operation at risk such as mprotect and mumap.
+ *
+ * This must be called under the PTL so that an access to tlb_flush_batched
+ * that is potentially a "reclaim vs mprotect/munmap/etc" race will synchronise
+ * via the PTL.
+ */
+void flush_tlb_batched_pending(struct mm_struct *mm)
+{
+ if (mm->tlb_flush_batched) {
+ flush_tlb_mm(mm);
+
+ /*
+ * Do not allow the compiler to re-order the clearing of
+ * tlb_flush_batched before the tlb is flushed.
+ */
+ barrier();
+ mm->tlb_flush_batched = false;
+ }
+}
#else
static void set_tlb_ubc_flush_pending(struct mm_struct *mm, bool writable)
{
@@ -852,10 +888,10 @@ static bool page_mkclean_one(struct page *page, struct vm_area_struct *vma,
.flags = PVMW_SYNC,
};
int *cleaned = arg;
+ bool invalidation_needed = false;
while (page_vma_mapped_walk(&pvmw)) {
int ret = 0;
- address = pvmw.address;
if (pvmw.pte) {
pte_t entry;
pte_t *pte = pvmw.pte;
@@ -863,11 +899,11 @@ static bool page_mkclean_one(struct page *page, struct vm_area_struct *vma,
if (!pte_dirty(*pte) && !pte_write(*pte))
continue;
- flush_cache_page(vma, address, pte_pfn(*pte));
- entry = ptep_clear_flush(vma, address, pte);
+ flush_cache_page(vma, pvmw.address, pte_pfn(*pte));
+ entry = ptep_clear_flush(vma, pvmw.address, pte);
entry = pte_wrprotect(entry);
entry = pte_mkclean(entry);
- set_pte_at(vma->vm_mm, address, pte, entry);
+ set_pte_at(vma->vm_mm, pvmw.address, pte, entry);
ret = 1;
} else {
#ifdef CONFIG_TRANSPARENT_HUGE_PAGECACHE
@@ -877,11 +913,11 @@ static bool page_mkclean_one(struct page *page, struct vm_area_struct *vma,
if (!pmd_dirty(*pmd) && !pmd_write(*pmd))
continue;
- flush_cache_page(vma, address, page_to_pfn(page));
- entry = pmdp_huge_clear_flush(vma, address, pmd);
+ flush_cache_page(vma, pvmw.address, page_to_pfn(page));
+ entry = pmdp_huge_clear_flush(vma, pvmw.address, pmd);
entry = pmd_wrprotect(entry);
entry = pmd_mkclean(entry);
- set_pmd_at(vma->vm_mm, address, pmd, entry);
+ set_pmd_at(vma->vm_mm, pvmw.address, pmd, entry);
ret = 1;
#else
/* unexpected pmd-mapped page? */
@@ -890,11 +926,16 @@ static bool page_mkclean_one(struct page *page, struct vm_area_struct *vma,
}
if (ret) {
- mmu_notifier_invalidate_page(vma->vm_mm, address);
(*cleaned)++;
+ invalidation_needed = true;
}
}
+ if (invalidation_needed) {
+ mmu_notifier_invalidate_range(vma->vm_mm, address,
+ address + (1UL << compound_order(page)));
+ }
+
return true;
}
@@ -1287,7 +1328,7 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
};
pte_t pteval;
struct page *subpage;
- bool ret = true;
+ bool ret = true, invalidation_needed = false;
enum ttu_flags flags = (enum ttu_flags)arg;
/* munlock has nothing to gain from examining un-locked vmas */
@@ -1327,11 +1368,9 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
VM_BUG_ON_PAGE(!pvmw.pte, page);
subpage = page - page_to_pfn(page) + pte_pfn(*pvmw.pte);
- address = pvmw.address;
-
if (!(flags & TTU_IGNORE_ACCESS)) {
- if (ptep_clear_flush_young_notify(vma, address,
+ if (ptep_clear_flush_young_notify(vma, pvmw.address,
pvmw.pte)) {
ret = false;
page_vma_mapped_walk_done(&pvmw);
@@ -1340,7 +1379,7 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
}
/* Nuke the page table entry. */
- flush_cache_page(vma, address, pte_pfn(*pvmw.pte));
+ flush_cache_page(vma, pvmw.address, pte_pfn(*pvmw.pte));
if (should_defer_flush(mm, flags)) {
/*
* We clear the PTE but do not flush so potentially
@@ -1350,11 +1389,12 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
* transition on a cached TLB entry is written through
* and traps if the PTE is unmapped.
*/
- pteval = ptep_get_and_clear(mm, address, pvmw.pte);
+ pteval = ptep_get_and_clear(mm, pvmw.address,
+ pvmw.pte);
set_tlb_ubc_flush_pending(mm, pte_dirty(pteval));
} else {
- pteval = ptep_clear_flush(vma, address, pvmw.pte);
+ pteval = ptep_clear_flush(vma, pvmw.address, pvmw.pte);
}
/* Move the dirty bit to the page. Now the pte is gone. */
@@ -1369,12 +1409,12 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
if (PageHuge(page)) {
int nr = 1 << compound_order(page);
hugetlb_count_sub(nr, mm);
- set_huge_swap_pte_at(mm, address,
+ set_huge_swap_pte_at(mm, pvmw.address,
pvmw.pte, pteval,
vma_mmu_pagesize(vma));
} else {
dec_mm_counter(mm, mm_counter(page));
- set_pte_at(mm, address, pvmw.pte, pteval);
+ set_pte_at(mm, pvmw.address, pvmw.pte, pteval);
}
} else if (pte_unused(pteval)) {
@@ -1398,7 +1438,7 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
swp_pte = swp_entry_to_pte(entry);
if (pte_soft_dirty(pteval))
swp_pte = pte_swp_mksoft_dirty(swp_pte);
- set_pte_at(mm, address, pvmw.pte, swp_pte);
+ set_pte_at(mm, pvmw.address, pvmw.pte, swp_pte);
} else if (PageAnon(page)) {
swp_entry_t entry = { .val = page_private(subpage) };
pte_t swp_pte;
@@ -1424,7 +1464,7 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
* If the page was redirtied, it cannot be
* discarded. Remap the page to page table.
*/
- set_pte_at(mm, address, pvmw.pte, pteval);
+ set_pte_at(mm, pvmw.address, pvmw.pte, pteval);
SetPageSwapBacked(page);
ret = false;
page_vma_mapped_walk_done(&pvmw);
@@ -1432,7 +1472,7 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
}
if (swap_duplicate(entry) < 0) {
- set_pte_at(mm, address, pvmw.pte, pteval);
+ set_pte_at(mm, pvmw.address, pvmw.pte, pteval);
ret = false;
page_vma_mapped_walk_done(&pvmw);
break;
@@ -1448,14 +1488,18 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
swp_pte = swp_entry_to_pte(entry);
if (pte_soft_dirty(pteval))
swp_pte = pte_swp_mksoft_dirty(swp_pte);
- set_pte_at(mm, address, pvmw.pte, swp_pte);
+ set_pte_at(mm, pvmw.address, pvmw.pte, swp_pte);
} else
dec_mm_counter(mm, mm_counter_file(page));
discard:
page_remove_rmap(subpage, PageHuge(page));
put_page(page);
- mmu_notifier_invalidate_page(mm, address);
+ invalidation_needed = true;
}
+
+ if (invalidation_needed)
+ mmu_notifier_invalidate_range(mm, address,
+ address + (1UL << compound_order(page)));
return ret;
}
diff --git a/mm/shmem.c b/mm/shmem.c
index b0aa6075d164..6540e5982444 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1022,7 +1022,11 @@ static int shmem_setattr(struct dentry *dentry, struct iattr *attr)
*/
if (IS_ENABLED(CONFIG_TRANSPARENT_HUGE_PAGECACHE)) {
spin_lock(&sbinfo->shrinklist_lock);
- if (list_empty(&info->shrinklist)) {
+ /*
+ * _careful to defend against unlocked access to
+ * ->shrink_list in shmem_unused_huge_shrink()
+ */
+ if (list_empty_careful(&info->shrinklist)) {
list_add_tail(&info->shrinklist,
&sbinfo->shrinklist);
sbinfo->shrinklist_len++;
@@ -1817,7 +1821,11 @@ alloc_nohuge: page = shmem_alloc_and_acct_page(gfp, info, sbinfo,
* to shrink under memory pressure.
*/
spin_lock(&sbinfo->shrinklist_lock);
- if (list_empty(&info->shrinklist)) {
+ /*
+ * _careful to defend against unlocked access to
+ * ->shrink_list in shmem_unused_huge_shrink()
+ */
+ if (list_empty_careful(&info->shrinklist)) {
list_add_tail(&info->shrinklist,
&sbinfo->shrinklist);
sbinfo->shrinklist_len++;
diff --git a/mm/util.c b/mm/util.c
index 7b07ec852e01..9ecddf568fe3 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -633,7 +633,7 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
* which are reclaimable, under pressure. The dentry
* cache and most inode caches should fall into this
*/
- free += global_page_state(NR_SLAB_RECLAIMABLE);
+ free += global_node_page_state(NR_SLAB_RECLAIMABLE);
/*
* Leave reserved pages. The pages are not for anonymous pages.
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 013eea76685e..308acb9d814b 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -2453,7 +2453,6 @@ void zs_destroy_pool(struct zs_pool *pool)
}
destroy_cache(pool);
- kfree(pool->size_class);
kfree(pool->name);
kfree(pool);
}
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index e1133bc634b5..8a3ce79b1307 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1549,9 +1549,41 @@ batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
return found;
}
+/**
+ * batadv_tt_global_sync_flags - update TT sync flags
+ * @tt_global: the TT global entry to update sync flags in
+ *
+ * Updates the sync flag bits in the tt_global flag attribute with a logical
+ * OR of all sync flags from any of its TT orig entries.
+ */
+static void
+batadv_tt_global_sync_flags(struct batadv_tt_global_entry *tt_global)
+{
+ struct batadv_tt_orig_list_entry *orig_entry;
+ const struct hlist_head *head;
+ u16 flags = BATADV_NO_FLAGS;
+
+ rcu_read_lock();
+ head = &tt_global->orig_list;
+ hlist_for_each_entry_rcu(orig_entry, head, list)
+ flags |= orig_entry->flags;
+ rcu_read_unlock();
+
+ flags |= tt_global->common.flags & (~BATADV_TT_SYNC_MASK);
+ tt_global->common.flags = flags;
+}
+
+/**
+ * batadv_tt_global_orig_entry_add - add or update a TT orig entry
+ * @tt_global: the TT global entry to add an orig entry in
+ * @orig_node: the originator to add an orig entry for
+ * @ttvn: translation table version number of this changeset
+ * @flags: TT sync flags
+ */
static void
batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
- struct batadv_orig_node *orig_node, int ttvn)
+ struct batadv_orig_node *orig_node, int ttvn,
+ u8 flags)
{
struct batadv_tt_orig_list_entry *orig_entry;
@@ -1561,7 +1593,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
* was added during a "temporary client detection"
*/
orig_entry->ttvn = ttvn;
- goto out;
+ orig_entry->flags = flags;
+ goto sync_flags;
}
orig_entry = kmem_cache_zalloc(batadv_tt_orig_cache, GFP_ATOMIC);
@@ -1573,6 +1606,7 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
batadv_tt_global_size_inc(orig_node, tt_global->common.vid);
orig_entry->orig_node = orig_node;
orig_entry->ttvn = ttvn;
+ orig_entry->flags = flags;
kref_init(&orig_entry->refcount);
spin_lock_bh(&tt_global->list_lock);
@@ -1582,6 +1616,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
spin_unlock_bh(&tt_global->list_lock);
atomic_inc(&tt_global->orig_list_count);
+sync_flags:
+ batadv_tt_global_sync_flags(tt_global);
out:
if (orig_entry)
batadv_tt_orig_list_entry_put(orig_entry);
@@ -1703,10 +1739,10 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
}
/* the change can carry possible "attribute" flags like the
- * TT_CLIENT_WIFI, therefore they have to be copied in the
+ * TT_CLIENT_TEMP, therefore they have to be copied in the
* client entry
*/
- common->flags |= flags;
+ common->flags |= flags & (~BATADV_TT_SYNC_MASK);
/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
* one originator left in the list and we previously received a
@@ -1723,7 +1759,8 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
}
add_orig_entry:
/* add the new orig_entry (if needed) or update it */
- batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn);
+ batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn,
+ flags & BATADV_TT_SYNC_MASK);
batadv_dbg(BATADV_DBG_TT, bat_priv,
"Creating new global tt entry: %pM (vid: %d, via %pM)\n",
@@ -1946,6 +1983,7 @@ batadv_tt_global_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq,
struct batadv_tt_orig_list_entry *orig,
bool best)
{
+ u16 flags = (common->flags & (~BATADV_TT_SYNC_MASK)) | orig->flags;
void *hdr;
struct batadv_orig_node_vlan *vlan;
u8 last_ttvn;
@@ -1975,7 +2013,7 @@ batadv_tt_global_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq,
nla_put_u8(msg, BATADV_ATTR_TT_LAST_TTVN, last_ttvn) ||
nla_put_u32(msg, BATADV_ATTR_TT_CRC32, crc) ||
nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) ||
- nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, common->flags))
+ nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, flags))
goto nla_put_failure;
if (best && nla_put_flag(msg, BATADV_ATTR_FLAG_BEST))
@@ -2589,6 +2627,7 @@ static u32 batadv_tt_global_crc(struct batadv_priv *bat_priv,
unsigned short vid)
{
struct batadv_hashtable *hash = bat_priv->tt.global_hash;
+ struct batadv_tt_orig_list_entry *tt_orig;
struct batadv_tt_common_entry *tt_common;
struct batadv_tt_global_entry *tt_global;
struct hlist_head *head;
@@ -2627,8 +2666,9 @@ static u32 batadv_tt_global_crc(struct batadv_priv *bat_priv,
/* find out if this global entry is announced by this
* originator
*/
- if (!batadv_tt_global_entry_has_orig(tt_global,
- orig_node))
+ tt_orig = batadv_tt_global_orig_entry_find(tt_global,
+ orig_node);
+ if (!tt_orig)
continue;
/* use network order to read the VID: this ensures that
@@ -2640,10 +2680,12 @@ static u32 batadv_tt_global_crc(struct batadv_priv *bat_priv,
/* compute the CRC on flags that have to be kept in sync
* among nodes
*/
- flags = tt_common->flags & BATADV_TT_SYNC_MASK;
+ flags = tt_orig->flags;
crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags));
crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
+
+ batadv_tt_orig_list_entry_put(tt_orig);
}
rcu_read_unlock();
}
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index ea43a6449247..a62795868794 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1260,6 +1260,7 @@ struct batadv_tt_global_entry {
* struct batadv_tt_orig_list_entry - orig node announcing a non-mesh client
* @orig_node: pointer to orig node announcing this non-mesh client
* @ttvn: translation table version number which added the non-mesh client
+ * @flags: per orig entry TT sync flags
* @list: list node for batadv_tt_global_entry::orig_list
* @refcount: number of contexts the object is used
* @rcu: struct used for freeing in an RCU-safe manner
@@ -1267,6 +1268,7 @@ struct batadv_tt_global_entry {
struct batadv_tt_orig_list_entry {
struct batadv_orig_node *orig_node;
u8 ttvn;
+ u8 flags;
struct hlist_node list;
struct kref refcount;
struct rcu_head rcu;
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index f0f3447e8aa4..861ae2a165f4 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -34,11 +34,11 @@ static struct lock_class_key bridge_netdev_addr_lock_key;
netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct net_bridge *br = netdev_priv(dev);
- const unsigned char *dest = skb->data;
struct net_bridge_fdb_entry *dst;
struct net_bridge_mdb_entry *mdst;
struct pcpu_sw_netstats *brstats = this_cpu_ptr(br->stats);
const struct nf_br_ops *nf_ops;
+ const unsigned char *dest;
u16 vid = 0;
rcu_read_lock();
@@ -61,6 +61,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
if (!br_allowed_ingress(br, br_vlan_group_rcu(br), skb, &vid))
goto out;
+ dest = eth_hdr(skb)->h_dest;
if (is_broadcast_ether_addr(dest)) {
br_flood(br, skb, BR_PKT_BROADCAST, false, true);
} else if (is_multicast_ether_addr(dest)) {
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 013f2290bfa5..7637f58c1226 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -131,11 +131,11 @@ static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br,
int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct net_bridge_port *p = br_port_get_rcu(skb->dev);
- const unsigned char *dest = eth_hdr(skb)->h_dest;
enum br_pkt_type pkt_type = BR_PKT_UNICAST;
struct net_bridge_fdb_entry *dst = NULL;
struct net_bridge_mdb_entry *mdst;
bool local_rcv, mcast_hit = false;
+ const unsigned char *dest;
struct net_bridge *br;
u16 vid = 0;
@@ -153,6 +153,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
br_fdb_update(br, p, eth_hdr(skb)->h_source, vid, false);
local_rcv = !!(br->dev->flags & IFF_PROMISC);
+ dest = eth_hdr(skb)->h_dest;
if (is_multicast_ether_addr(dest)) {
/* by definition the broadcast is also a multicast address */
if (is_broadcast_ether_addr(dest)) {
diff --git a/net/ceph/crush/mapper.c b/net/ceph/crush/mapper.c
index 746b145bfd11..417df675c71b 100644
--- a/net/ceph/crush/mapper.c
+++ b/net/ceph/crush/mapper.c
@@ -306,7 +306,7 @@ static __u32 *get_choose_arg_weights(const struct crush_bucket_straw2 *bucket,
const struct crush_choose_arg *arg,
int position)
{
- if (!arg || !arg->weight_set || arg->weight_set_size == 0)
+ if (!arg || !arg->weight_set)
return bucket->item_weights;
if (position >= arg->weight_set_size)
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 0c31035bbfee..a67298c7e0cd 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -1287,10 +1287,10 @@ static void prepare_write_message(struct ceph_connection *con)
if (m->needs_out_seq) {
m->hdr.seq = cpu_to_le64(++con->out_seq);
m->needs_out_seq = false;
- }
- if (con->ops->reencode_message)
- con->ops->reencode_message(m);
+ if (con->ops->reencode_message)
+ con->ops->reencode_message(m);
+ }
dout("prepare_write_message %p seq %lld type %d len %d+%d+%zd\n",
m, con->out_seq, le16_to_cpu(m->hdr.type),
@@ -3203,8 +3203,10 @@ static struct ceph_msg_data *ceph_msg_data_create(enum ceph_msg_data_type type)
return NULL;
data = kmem_cache_zalloc(ceph_msg_data_cache, GFP_NOFS);
- if (data)
- data->type = type;
+ if (!data)
+ return NULL;
+
+ data->type = type;
INIT_LIST_HEAD(&data->links);
return data;
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 86a9737d8e3f..dcfbdd74dfd1 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -1337,6 +1337,8 @@ static enum calc_target_result calc_target(struct ceph_osd_client *osdc,
bool legacy_change;
bool split = false;
bool sort_bitwise = ceph_osdmap_flag(osdc, CEPH_OSDMAP_SORTBITWISE);
+ bool recovery_deletes = ceph_osdmap_flag(osdc,
+ CEPH_OSDMAP_RECOVERY_DELETES);
enum calc_target_result ct_res;
int ret;
@@ -1399,6 +1401,8 @@ static enum calc_target_result calc_target(struct ceph_osd_client *osdc,
pi->pg_num,
t->sort_bitwise,
sort_bitwise,
+ t->recovery_deletes,
+ recovery_deletes,
&last_pgid))
force_resend = true;
@@ -1421,6 +1425,7 @@ static enum calc_target_result calc_target(struct ceph_osd_client *osdc,
t->pg_num = pi->pg_num;
t->pg_num_mask = pi->pg_num_mask;
t->sort_bitwise = sort_bitwise;
+ t->recovery_deletes = recovery_deletes;
t->osd = acting.primary;
}
@@ -1918,10 +1923,12 @@ static void encode_request_partial(struct ceph_osd_request *req,
}
ceph_encode_32(&p, req->r_attempts); /* retry_attempt */
- BUG_ON(p != end - 8); /* space for features */
+ BUG_ON(p > end - 8); /* space for features */
msg->hdr.version = cpu_to_le16(8); /* MOSDOp v8 */
/* front_len is finalized in encode_request_finish() */
+ msg->front.iov_len = p - msg->front.iov_base;
+ msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
msg->hdr.data_len = cpu_to_le32(data_len);
/*
* The header "data_off" is a hint to the receiver allowing it
@@ -1937,11 +1944,12 @@ static void encode_request_partial(struct ceph_osd_request *req,
static void encode_request_finish(struct ceph_msg *msg)
{
void *p = msg->front.iov_base;
+ void *const partial_end = p + msg->front.iov_len;
void *const end = p + msg->front_alloc_len;
if (CEPH_HAVE_FEATURE(msg->con->peer_features, RESEND_ON_SPLIT)) {
/* luminous OSD -- encode features and be done */
- p = end - 8;
+ p = partial_end;
ceph_encode_64(&p, msg->con->peer_features);
} else {
struct {
@@ -1984,7 +1992,7 @@ static void encode_request_finish(struct ceph_msg *msg)
oid_len = p - oid;
tail = p;
- tail_len = (end - p) - 8;
+ tail_len = partial_end - p;
p = msg->front.iov_base;
ceph_encode_copy(&p, &head.client_inc, sizeof(head.client_inc));
@@ -5310,7 +5318,10 @@ static int invalidate_authorizer(struct ceph_connection *con)
static void osd_reencode_message(struct ceph_msg *msg)
{
- encode_request_finish(msg);
+ int type = le16_to_cpu(msg->hdr.type);
+
+ if (type == CEPH_MSG_OSD_OP)
+ encode_request_finish(msg);
}
static int osd_sign_message(struct ceph_msg *msg)
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
index 864789c5974e..f358d0bfa76b 100644
--- a/net/ceph/osdmap.c
+++ b/net/ceph/osdmap.c
@@ -295,6 +295,10 @@ static int decode_choose_args(void **p, void *end, struct crush_map *c)
ret = decode_choose_arg(p, end, arg);
if (ret)
goto fail;
+
+ if (arg->ids_size &&
+ arg->ids_size != c->buckets[bucket_index]->size)
+ goto e_inval;
}
insert_choose_arg_map(&c->choose_args, arg_map);
@@ -338,7 +342,7 @@ static void crush_finalize(struct crush_map *c)
static struct crush_map *crush_decode(void *pbyval, void *end)
{
struct crush_map *c;
- int err = -EINVAL;
+ int err;
int i, j;
void **p = &pbyval;
void *start = pbyval;
@@ -407,7 +411,6 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
size = sizeof(struct crush_bucket_straw2);
break;
default:
- err = -EINVAL;
goto bad;
}
BUG_ON(size == 0);
@@ -439,31 +442,31 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
err = crush_decode_uniform_bucket(p, end,
(struct crush_bucket_uniform *)b);
if (err < 0)
- goto bad;
+ goto fail;
break;
case CRUSH_BUCKET_LIST:
err = crush_decode_list_bucket(p, end,
(struct crush_bucket_list *)b);
if (err < 0)
- goto bad;
+ goto fail;
break;
case CRUSH_BUCKET_TREE:
err = crush_decode_tree_bucket(p, end,
(struct crush_bucket_tree *)b);
if (err < 0)
- goto bad;
+ goto fail;
break;
case CRUSH_BUCKET_STRAW:
err = crush_decode_straw_bucket(p, end,
(struct crush_bucket_straw *)b);
if (err < 0)
- goto bad;
+ goto fail;
break;
case CRUSH_BUCKET_STRAW2:
err = crush_decode_straw2_bucket(p, end,
(struct crush_bucket_straw2 *)b);
if (err < 0)
- goto bad;
+ goto fail;
break;
}
}
@@ -474,7 +477,6 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
u32 yes;
struct crush_rule *r;
- err = -EINVAL;
ceph_decode_32_safe(p, end, yes, bad);
if (!yes) {
dout("crush_decode NO rule %d off %x %p to %p\n",
@@ -489,7 +491,6 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
/* len */
ceph_decode_32_safe(p, end, yes, bad);
#if BITS_PER_LONG == 32
- err = -EINVAL;
if (yes > (ULONG_MAX - sizeof(*r))
/ sizeof(struct crush_rule_step))
goto bad;
@@ -557,7 +558,7 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
if (*p != end) {
err = decode_choose_args(p, end, c);
if (err)
- goto bad;
+ goto fail;
}
done:
@@ -567,10 +568,14 @@ done:
badmem:
err = -ENOMEM;
-bad:
+fail:
dout("crush_decode fail %d\n", err);
crush_destroy(c);
return ERR_PTR(err);
+
+bad:
+ err = -EINVAL;
+ goto fail;
}
int ceph_pg_compare(const struct ceph_pg *lhs, const struct ceph_pg *rhs)
@@ -1399,7 +1404,7 @@ static struct ceph_pg_mapping *__decode_pg_upmap_items(void **p, void *end,
return ERR_PTR(-EINVAL);
ceph_decode_need(p, end, 2 * len * sizeof(u32), e_inval);
- pg = kzalloc(sizeof(*pg) + 2 * len * sizeof(u32), GFP_NOIO);
+ pg = alloc_pg_mapping(2 * len * sizeof(u32));
if (!pg)
return ERR_PTR(-ENOMEM);
@@ -1544,7 +1549,7 @@ static int osdmap_decode(void **p, void *end, struct ceph_osdmap *map)
if (struct_v >= 3) {
/* erasure_code_profiles */
ceph_decode_skip_map_of_map(p, end, string, string, string,
- bad);
+ e_inval);
}
if (struct_v >= 4) {
@@ -1825,9 +1830,9 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
if (struct_v >= 3) {
/* new_erasure_code_profiles */
ceph_decode_skip_map_of_map(p, end, string, string, string,
- bad);
+ e_inval);
/* old_erasure_code_profiles */
- ceph_decode_skip_set(p, end, string, bad);
+ ceph_decode_skip_set(p, end, string, e_inval);
}
if (struct_v >= 4) {
@@ -2077,6 +2082,8 @@ bool ceph_is_new_interval(const struct ceph_osds *old_acting,
u32 new_pg_num,
bool old_sort_bitwise,
bool new_sort_bitwise,
+ bool old_recovery_deletes,
+ bool new_recovery_deletes,
const struct ceph_pg *pgid)
{
return !osds_equal(old_acting, new_acting) ||
@@ -2084,7 +2091,8 @@ bool ceph_is_new_interval(const struct ceph_osds *old_acting,
old_size != new_size ||
old_min_size != new_min_size ||
ceph_pg_is_split(pgid, old_pg_num, new_pg_num) ||
- old_sort_bitwise != new_sort_bitwise;
+ old_sort_bitwise != new_sort_bitwise ||
+ old_recovery_deletes != new_recovery_deletes;
}
static int calc_pg_rank(int osd, const struct ceph_osds *acting)
@@ -2300,10 +2308,17 @@ static u32 raw_pg_to_pps(struct ceph_pg_pool_info *pi,
}
}
+/*
+ * Magic value used for a "default" fallback choose_args, used if the
+ * crush_choose_arg_map passed to do_crush() does not exist. If this
+ * also doesn't exist, fall back to canonical weights.
+ */
+#define CEPH_DEFAULT_CHOOSE_ARGS -1
+
static int do_crush(struct ceph_osdmap *map, int ruleno, int x,
int *result, int result_max,
const __u32 *weight, int weight_max,
- u64 choose_args_index)
+ s64 choose_args_index)
{
struct crush_choose_arg_map *arg_map;
int r;
@@ -2312,6 +2327,9 @@ static int do_crush(struct ceph_osdmap *map, int ruleno, int x,
arg_map = lookup_choose_arg_map(&map->crush->choose_args,
choose_args_index);
+ if (!arg_map)
+ arg_map = lookup_choose_arg_map(&map->crush->choose_args,
+ CEPH_DEFAULT_CHOOSE_ARGS);
mutex_lock(&map->crush_workspace_mutex);
r = crush_do_rule(map->crush, ruleno, x, result, result_max,
@@ -2422,40 +2440,23 @@ static void apply_upmap(struct ceph_osdmap *osdmap,
for (i = 0; i < pg->pg_upmap.len; i++)
raw->osds[i] = pg->pg_upmap.osds[i];
raw->size = pg->pg_upmap.len;
- return;
+ /* check and apply pg_upmap_items, if any */
}
pg = lookup_pg_mapping(&osdmap->pg_upmap_items, pgid);
if (pg) {
- /*
- * Note: this approach does not allow a bidirectional swap,
- * e.g., [[1,2],[2,1]] applied to [0,1,2] -> [0,2,1].
- */
- for (i = 0; i < pg->pg_upmap_items.len; i++) {
- int from = pg->pg_upmap_items.from_to[i][0];
- int to = pg->pg_upmap_items.from_to[i][1];
- int pos = -1;
- bool exists = false;
-
- /* make sure replacement doesn't already appear */
- for (j = 0; j < raw->size; j++) {
- int osd = raw->osds[j];
-
- if (osd == to) {
- exists = true;
+ for (i = 0; i < raw->size; i++) {
+ for (j = 0; j < pg->pg_upmap_items.len; j++) {
+ int from = pg->pg_upmap_items.from_to[j][0];
+ int to = pg->pg_upmap_items.from_to[j][1];
+
+ if (from == raw->osds[i]) {
+ if (!(to != CRUSH_ITEM_NONE &&
+ to < osdmap->max_osd &&
+ osdmap->osd_weight[to] == 0))
+ raw->osds[i] = to;
break;
}
- /* ignore mapping if target is marked out */
- if (osd == from && pos < 0 &&
- !(to != CRUSH_ITEM_NONE &&
- to < osdmap->max_osd &&
- osdmap->osd_weight[to] == 0)) {
- pos = j;
- }
- }
- if (!exists && pos >= 0) {
- raw->osds[pos] = to;
- return;
}
}
}
diff --git a/net/core/dev.c b/net/core/dev.c
index 8515f8fe0460..ce15a06d5558 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2739,7 +2739,7 @@ static inline bool skb_needs_check(struct sk_buff *skb, bool tx_path)
{
if (tx_path)
return skb->ip_summed != CHECKSUM_PARTIAL &&
- skb->ip_summed != CHECKSUM_NONE;
+ skb->ip_summed != CHECKSUM_UNNECESSARY;
return skb->ip_summed == CHECKSUM_NONE;
}
diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c
index 82fd4c9c4a1b..709a4e6fb447 100644
--- a/net/core/dev_ioctl.c
+++ b/net/core/dev_ioctl.c
@@ -28,6 +28,7 @@ static int dev_ifname(struct net *net, struct ifreq __user *arg)
if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
return -EFAULT;
+ ifr.ifr_name[IFNAMSIZ-1] = 0;
error = netdev_get_name(net, ifr.ifr_name, ifr.ifr_ifindex);
if (error)
@@ -262,6 +263,8 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
return dev_set_mtu(dev, ifr->ifr_mtu);
case SIOCSIFHWADDR:
+ if (dev->addr_len > sizeof(struct sockaddr))
+ return -EINVAL;
return dev_set_mac_address(dev, &ifr->ifr_hwaddr);
case SIOCSIFHWBROADCAST:
@@ -424,6 +427,8 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
if (copy_from_user(&iwr, arg, sizeof(iwr)))
return -EFAULT;
+ iwr.ifr_name[sizeof(iwr.ifr_name) - 1] = 0;
+
return wext_handle_ioctl(net, &iwr, cmd, arg);
}
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index a0093e1b0235..fdcb1bcd2afa 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -400,6 +400,7 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh,
err = -ENOMEM;
goto errout;
}
+ refcount_set(&rule->refcnt, 1);
rule->fr_net = net;
rule->pref = tb[FRA_PRIORITY] ? nla_get_u32(tb[FRA_PRIORITY])
@@ -517,8 +518,6 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh,
last = r;
}
- refcount_set(&rule->refcnt, 1);
-
if (last)
list_add_rcu(&rule->list, &last->list);
else
diff --git a/net/core/filter.c b/net/core/filter.c
index c7f737058d89..f44fc22fd45a 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -2248,7 +2248,7 @@ static int bpf_skb_adjust_net(struct sk_buff *skb, s32 len_diff)
bpf_skb_net_grow(skb, len_diff_abs);
bpf_compute_data_end(skb);
- return 0;
+ return ret;
}
BPF_CALL_4(bpf_skb_adjust_room, struct sk_buff *, skb, s32, len_diff,
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index d3408a693166..912731bed7b7 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -277,7 +277,7 @@ static void zap_completion_queue(void)
struct sk_buff *skb = clist;
clist = clist->next;
if (!skb_irq_freeable(skb)) {
- refcount_inc(&skb->users);
+ refcount_set(&skb->users, 1);
dev_kfree_skb_any(skb); /* put this one back */
} else {
__kfree_skb(skb);
@@ -666,7 +666,7 @@ int netpoll_setup(struct netpoll *np)
int err;
rtnl_lock();
- if (np->dev_name) {
+ if (np->dev_name[0]) {
struct net *net = current->nsproxy->net_ns;
ndev = __dev_get_by_name(net, np->dev_name);
}
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index d1ba90980be1..9201e3621351 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2031,7 +2031,8 @@ static int do_setlink(const struct sk_buff *skb,
struct sockaddr *sa;
int len;
- len = sizeof(sa_family_t) + dev->addr_len;
+ len = sizeof(sa_family_t) + max_t(size_t, dev->addr_len,
+ sizeof(*sa));
sa = kmalloc(len, GFP_KERNEL);
if (!sa) {
err = -ENOMEM;
@@ -4241,6 +4242,7 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi
switch (event) {
case NETDEV_REBOOT:
+ case NETDEV_CHANGEADDR:
case NETDEV_CHANGENAME:
case NETDEV_FEAT_CHANGE:
case NETDEV_BONDING_FAILOVER:
diff --git a/net/dccp/feat.c b/net/dccp/feat.c
index 1704948e6a12..f227f002c73d 100644
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -1471,9 +1471,12 @@ int dccp_feat_init(struct sock *sk)
* singleton values (which always leads to failure).
* These settings can still (later) be overridden via sockopts.
*/
- if (ccid_get_builtin_ccids(&tx.val, &tx.len) ||
- ccid_get_builtin_ccids(&rx.val, &rx.len))
+ if (ccid_get_builtin_ccids(&tx.val, &tx.len))
return -ENOBUFS;
+ if (ccid_get_builtin_ccids(&rx.val, &rx.len)) {
+ kfree(tx.val);
+ return -ENOBUFS;
+ }
if (!dccp_feat_prefer(sysctl_dccp_tx_ccid, tx.val, tx.len) ||
!dccp_feat_prefer(sysctl_dccp_rx_ccid, rx.val, rx.len))
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 4a05d7876850..fa6be9750bb4 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -126,7 +126,7 @@ static int dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb)
static u16 dccp_reset_code_convert(const u8 code)
{
- const u16 error_code[] = {
+ static const u16 error_code[] = {
[DCCP_RESET_CODE_CLOSED] = 0, /* normal termination */
[DCCP_RESET_CODE_UNSPECIFIED] = 0, /* nothing known */
[DCCP_RESET_CODE_ABORTED] = ECONNRESET,
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index f85d901f4e3f..1b202f16531f 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -631,6 +631,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
goto drop_and_free;
inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
+ reqsk_put(req);
return 0;
drop_and_free:
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index c376af5bfdfb..1b58eac8aad3 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -380,6 +380,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
goto drop_and_free;
inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
+ reqsk_put(req);
return 0;
drop_and_free:
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 56e46090526b..c442051d5a55 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -509,21 +509,22 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index,
dst->cpu_dp->netdev = ethernet_dev;
}
+ /* Initialize cpu_port_mask now for drv->setup()
+ * to have access to a correct value, just like what
+ * net/dsa/dsa.c::dsa_switch_setup_one does.
+ */
+ ds->cpu_port_mask |= BIT(index);
+
tag_protocol = ds->ops->get_tag_protocol(ds);
dst->tag_ops = dsa_resolve_tag_protocol(tag_protocol);
if (IS_ERR(dst->tag_ops)) {
dev_warn(ds->dev, "No tagger for this switch\n");
+ ds->cpu_port_mask &= ~BIT(index);
return PTR_ERR(dst->tag_ops);
}
dst->rcv = dst->tag_ops->rcv;
- /* Initialize cpu_port_mask now for drv->setup()
- * to have access to a correct value, just like what
- * net/dsa/dsa.c::dsa_switch_setup_one does.
- */
- ds->cpu_port_mask |= BIT(index);
-
return 0;
}
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 76c2077c3f5b..2e548eca3489 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1731,6 +1731,13 @@ static __net_init int inet_init_net(struct net *net)
net->ipv4.sysctl_ip_prot_sock = PROT_SOCK;
#endif
+ /* Some igmp sysctl, whose values are always used */
+ net->ipv4.sysctl_igmp_max_memberships = 20;
+ net->ipv4.sysctl_igmp_max_msf = 10;
+ /* IGMP reports for link-local multicast groups are enabled by default */
+ net->ipv4.sysctl_igmp_llm_reports = 1;
+ net->ipv4.sysctl_igmp_qrv = 2;
+
return 0;
}
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index c4c6e1969ed0..2ae8f54cb321 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -1523,9 +1523,17 @@ unsigned char *cipso_v4_optptr(const struct sk_buff *skb)
int taglen;
for (optlen = iph->ihl*4 - sizeof(struct iphdr); optlen > 0; ) {
- if (optptr[0] == IPOPT_CIPSO)
+ switch (optptr[0]) {
+ case IPOPT_CIPSO:
return optptr;
- taglen = optptr[1];
+ case IPOPT_END:
+ return NULL;
+ case IPOPT_NOOP:
+ taglen = 1;
+ break;
+ default:
+ taglen = optptr[1];
+ }
optlen -= taglen;
optptr += taglen;
}
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 4e678fa892dd..044d2a159a3c 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -1334,13 +1334,14 @@ static struct pernet_operations fib_net_ops = {
void __init ip_fib_init(void)
{
- rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL, NULL);
- rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL, NULL);
- rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib, NULL);
+ fib_trie_init();
register_pernet_subsys(&fib_net_ops);
+
register_netdevice_notifier(&fib_netdev_notifier);
register_inetaddr_notifier(&fib_inetaddr_notifier);
- fib_trie_init();
+ rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL, NULL);
+ rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL, NULL);
+ rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib, NULL);
}
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 222100103808..b8d18171cca3 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -1452,7 +1452,7 @@ static int call_fib_nh_notifiers(struct fib_nh *fib_nh,
return call_fib_notifiers(dev_net(fib_nh->nh_dev), event_type,
&info.info);
case FIB_EVENT_NH_DEL:
- if ((IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev) &&
+ if ((in_dev && IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev) &&
fib_nh->nh_flags & RTNH_F_LINKDOWN) ||
(fib_nh->nh_flags & RTNH_F_DEAD))
return call_fib_notifiers(dev_net(fib_nh->nh_dev),
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
index 8e0257d01200..1540db65241a 100644
--- a/net/ipv4/fou.c
+++ b/net/ipv4/fou.c
@@ -450,6 +450,7 @@ out_unlock:
out:
NAPI_GRO_CB(skb)->flush |= flush;
skb_gro_remcsum_cleanup(skb, &grc);
+ skb->remcsum_offload = 0;
return pp;
}
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 28f14afd0dd3..498706b072fb 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -2974,12 +2974,6 @@ static int __net_init igmp_net_init(struct net *net)
goto out_sock;
}
- /* Sysctl initialization */
- net->ipv4.sysctl_igmp_max_memberships = 20;
- net->ipv4.sysctl_igmp_max_msf = 10;
- /* IGMP reports for link-local multicast groups are enabled by default */
- net->ipv4.sysctl_igmp_llm_reports = 1;
- net->ipv4.sysctl_igmp_qrv = 2;
return 0;
out_sock:
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 7eb252dcecee..e153c40c2436 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -599,6 +599,7 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
hlen = iph->ihl * 4;
mtu = mtu - hlen; /* Size of data space */
IPCB(skb)->flags |= IPSKB_FRAG_COMPLETE;
+ ll_rs = LL_RESERVED_SPACE(rt->dst.dev);
/* When frag_list is given, use it. First, check its validity:
* some transformers could create wrong frag_list or break existing
@@ -614,14 +615,15 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
if (first_len - hlen > mtu ||
((first_len - hlen) & 7) ||
ip_is_fragment(iph) ||
- skb_cloned(skb))
+ skb_cloned(skb) ||
+ skb_headroom(skb) < ll_rs)
goto slow_path;
skb_walk_frags(skb, frag) {
/* Correct geometry. */
if (frag->len > mtu ||
((frag->len & 7) && frag->next) ||
- skb_headroom(frag) < hlen)
+ skb_headroom(frag) < hlen + ll_rs)
goto slow_path_clean;
/* Partially cloned skb? */
@@ -711,8 +713,6 @@ slow_path:
left = skb->len - hlen; /* Space per frame */
ptr = hlen; /* Where to start from */
- ll_rs = LL_RESERVED_SPACE(rt->dst.dev);
-
/*
* Fragment the datagram.
*/
@@ -965,11 +965,12 @@ static int __ip_append_data(struct sock *sk,
csummode = CHECKSUM_PARTIAL;
cork->length += length;
- if ((((length + (skb ? skb->len : fragheaderlen)) > mtu) ||
- (skb && skb_is_gso(skb))) &&
+ if ((skb && skb_is_gso(skb)) ||
+ (((length + (skb ? skb->len : fragheaderlen)) > mtu) &&
+ (skb_queue_len(queue) <= 1) &&
(sk->sk_protocol == IPPROTO_UDP) &&
(rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) &&
- (sk->sk_type == SOCK_DGRAM) && !sk->sk_no_check_tx) {
+ (sk->sk_type == SOCK_DGRAM) && !sk->sk_no_check_tx)) {
err = ip_ufo_append_data(sk, queue, getfrag, from, length,
hh_len, fragheaderlen, transhdrlen,
maxfraglen, flags);
@@ -1288,6 +1289,7 @@ ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
return -EINVAL;
if ((size + skb->len > mtu) &&
+ (skb_queue_len(&sk->sk_write_queue) == 1) &&
(sk->sk_protocol == IPPROTO_UDP) &&
(rt->dst.dev->features & NETIF_F_UFO)) {
if (skb->ip_summed != CHECKSUM_PARTIAL)
diff --git a/net/ipv4/netfilter/nf_tables_arp.c b/net/ipv4/netfilter/nf_tables_arp.c
index 805c8ddfe860..4bbc273b45e8 100644
--- a/net/ipv4/netfilter/nf_tables_arp.c
+++ b/net/ipv4/netfilter/nf_tables_arp.c
@@ -72,8 +72,7 @@ static const struct nf_chain_type filter_arp = {
.family = NFPROTO_ARP,
.owner = THIS_MODULE,
.hook_mask = (1 << NF_ARP_IN) |
- (1 << NF_ARP_OUT) |
- (1 << NF_ARP_FORWARD),
+ (1 << NF_ARP_OUT),
};
static int __init nf_tables_arp_init(void)
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 0905cf04c2a4..03ad8778c395 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -335,6 +335,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
treq->rcv_isn = ntohl(th->seq) - 1;
treq->snt_isn = cookie;
treq->ts_off = 0;
+ treq->txhash = net_tx_rndhash();
req->mss = mss;
ireq->ir_num = ntohs(th->dest);
ireq->ir_rmt_port = th->source;
diff --git a/net/ipv4/tcp_bbr.c b/net/ipv4/tcp_bbr.c
index dbcc9352a48f..69ee877574d0 100644
--- a/net/ipv4/tcp_bbr.c
+++ b/net/ipv4/tcp_bbr.c
@@ -112,7 +112,8 @@ struct bbr {
cwnd_gain:10, /* current gain for setting cwnd */
full_bw_cnt:3, /* number of rounds without large bw gains */
cycle_idx:3, /* current index in pacing_gain cycle array */
- unused_b:6;
+ has_seen_rtt:1, /* have we seen an RTT sample yet? */
+ unused_b:5;
u32 prior_cwnd; /* prior cwnd upon entering loss recovery */
u32 full_bw; /* recent bw, to estimate if pipe is full */
};
@@ -211,6 +212,35 @@ static u64 bbr_rate_bytes_per_sec(struct sock *sk, u64 rate, int gain)
return rate >> BW_SCALE;
}
+/* Convert a BBR bw and gain factor to a pacing rate in bytes per second. */
+static u32 bbr_bw_to_pacing_rate(struct sock *sk, u32 bw, int gain)
+{
+ u64 rate = bw;
+
+ rate = bbr_rate_bytes_per_sec(sk, rate, gain);
+ rate = min_t(u64, rate, sk->sk_max_pacing_rate);
+ return rate;
+}
+
+/* Initialize pacing rate to: high_gain * init_cwnd / RTT. */
+static void bbr_init_pacing_rate_from_rtt(struct sock *sk)
+{
+ struct tcp_sock *tp = tcp_sk(sk);
+ struct bbr *bbr = inet_csk_ca(sk);
+ u64 bw;
+ u32 rtt_us;
+
+ if (tp->srtt_us) { /* any RTT sample yet? */
+ rtt_us = max(tp->srtt_us >> 3, 1U);
+ bbr->has_seen_rtt = 1;
+ } else { /* no RTT sample yet */
+ rtt_us = USEC_PER_MSEC; /* use nominal default RTT */
+ }
+ bw = (u64)tp->snd_cwnd * BW_UNIT;
+ do_div(bw, rtt_us);
+ sk->sk_pacing_rate = bbr_bw_to_pacing_rate(sk, bw, bbr_high_gain);
+}
+
/* Pace using current bw estimate and a gain factor. In order to help drive the
* network toward lower queues while maintaining high utilization and low
* latency, the average pacing rate aims to be slightly (~1%) lower than the
@@ -220,12 +250,13 @@ static u64 bbr_rate_bytes_per_sec(struct sock *sk, u64 rate, int gain)
*/
static void bbr_set_pacing_rate(struct sock *sk, u32 bw, int gain)
{
+ struct tcp_sock *tp = tcp_sk(sk);
struct bbr *bbr = inet_csk_ca(sk);
- u64 rate = bw;
+ u32 rate = bbr_bw_to_pacing_rate(sk, bw, gain);
- rate = bbr_rate_bytes_per_sec(sk, rate, gain);
- rate = min_t(u64, rate, sk->sk_max_pacing_rate);
- if (bbr->mode != BBR_STARTUP || rate > sk->sk_pacing_rate)
+ if (unlikely(!bbr->has_seen_rtt && tp->srtt_us))
+ bbr_init_pacing_rate_from_rtt(sk);
+ if (bbr_full_bw_reached(sk) || rate > sk->sk_pacing_rate)
sk->sk_pacing_rate = rate;
}
@@ -798,7 +829,6 @@ static void bbr_init(struct sock *sk)
{
struct tcp_sock *tp = tcp_sk(sk);
struct bbr *bbr = inet_csk_ca(sk);
- u64 bw;
bbr->prior_cwnd = 0;
bbr->tso_segs_goal = 0; /* default segs per skb until first ACK */
@@ -814,11 +844,8 @@ static void bbr_init(struct sock *sk)
minmax_reset(&bbr->bw, bbr->rtt_cnt, 0); /* init max bw to 0 */
- /* Initialize pacing rate to: high_gain * init_cwnd / RTT. */
- bw = (u64)tp->snd_cwnd * BW_UNIT;
- do_div(bw, (tp->srtt_us >> 3) ? : USEC_PER_MSEC);
- sk->sk_pacing_rate = 0; /* force an update of sk_pacing_rate */
- bbr_set_pacing_rate(sk, bw, bbr_high_gain);
+ bbr->has_seen_rtt = 0;
+ bbr_init_pacing_rate_from_rtt(sk);
bbr->restore_cwnd = 0;
bbr->round_start = 0;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 2920e0cb09f8..53de1424c13c 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -107,6 +107,7 @@ int sysctl_tcp_invalid_ratelimit __read_mostly = HZ/2;
#define FLAG_ORIG_SACK_ACKED 0x200 /* Never retransmitted data are (s)acked */
#define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */
#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */
+#define FLAG_SET_XMIT_TIMER 0x1000 /* Set TLP or RTO timer */
#define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */
#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */
#define FLAG_NO_CHALLENGE_ACK 0x8000 /* do not call tcp_send_challenge_ack() */
@@ -2520,8 +2521,8 @@ static inline void tcp_end_cwnd_reduction(struct sock *sk)
return;
/* Reset cwnd to ssthresh in CWR or Recovery (unless it's undone) */
- if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR ||
- (tp->undo_marker && tp->snd_ssthresh < TCP_INFINITE_SSTHRESH)) {
+ if (tp->snd_ssthresh < TCP_INFINITE_SSTHRESH &&
+ (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR || tp->undo_marker)) {
tp->snd_cwnd = tp->snd_ssthresh;
tp->snd_cwnd_stamp = tcp_jiffies32;
}
@@ -3004,10 +3005,7 @@ void tcp_rearm_rto(struct sock *sk)
/* Offset the time elapsed after installing regular RTO */
if (icsk->icsk_pending == ICSK_TIME_REO_TIMEOUT ||
icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) {
- struct sk_buff *skb = tcp_write_queue_head(sk);
- u64 rto_time_stamp = skb->skb_mstamp +
- jiffies_to_usecs(rto);
- s64 delta_us = rto_time_stamp - tp->tcp_mstamp;
+ s64 delta_us = tcp_rto_delta_us(sk);
/* delta_us may not be positive if the socket is locked
* when the retrans timer fires and is rescheduled.
*/
@@ -3019,6 +3017,13 @@ void tcp_rearm_rto(struct sock *sk)
}
}
+/* Try to schedule a loss probe; if that doesn't work, then schedule an RTO. */
+static void tcp_set_xmit_timer(struct sock *sk)
+{
+ if (!tcp_schedule_loss_probe(sk))
+ tcp_rearm_rto(sk);
+}
+
/* If we get here, the whole TSO packet has not been acked. */
static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb)
{
@@ -3180,7 +3185,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
ca_rtt_us, sack->rate);
if (flag & FLAG_ACKED) {
- tcp_rearm_rto(sk);
+ flag |= FLAG_SET_XMIT_TIMER; /* set TLP or RTO timer */
if (unlikely(icsk->icsk_mtup.probe_size &&
!after(tp->mtu_probe.probe_seq_end, tp->snd_una))) {
tcp_mtup_probe_success(sk);
@@ -3208,7 +3213,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
* after when the head was last (re)transmitted. Otherwise the
* timeout may continue to extend in loss recovery.
*/
- tcp_rearm_rto(sk);
+ flag |= FLAG_SET_XMIT_TIMER; /* set TLP or RTO timer */
}
if (icsk->icsk_ca_ops->pkts_acked) {
@@ -3580,9 +3585,6 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
if (after(ack, tp->snd_nxt))
goto invalid_ack;
- if (icsk->icsk_pending == ICSK_TIME_LOSS_PROBE)
- tcp_rearm_rto(sk);
-
if (after(ack, prior_snd_una)) {
flag |= FLAG_SND_UNA_ADVANCED;
icsk->icsk_retransmits = 0;
@@ -3647,18 +3649,20 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una, &acked,
&sack_state);
+ if (tp->tlp_high_seq)
+ tcp_process_tlp_ack(sk, ack, flag);
+ /* If needed, reset TLP/RTO timer; RACK may later override this. */
+ if (flag & FLAG_SET_XMIT_TIMER)
+ tcp_set_xmit_timer(sk);
+
if (tcp_ack_is_dubious(sk, flag)) {
is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP));
tcp_fastretrans_alert(sk, acked, is_dupack, &flag, &rexmit);
}
- if (tp->tlp_high_seq)
- tcp_process_tlp_ack(sk, ack, flag);
if ((flag & FLAG_FORWARD_PROGRESS) || !(flag & FLAG_NOT_DUP))
sk_dst_confirm(sk);
- if (icsk->icsk_pending == ICSK_TIME_RETRANS)
- tcp_schedule_loss_probe(sk);
delivered = tp->delivered - delivered; /* freshly ACKed or SACKed */
lost = tp->lost - lost; /* freshly marked lost */
tcp_rate_gen(sk, delivered, lost, sack_state.rate);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 4e985dea1dd2..b7661a68d498 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2202,9 +2202,10 @@ static bool tcp_small_queue_check(struct sock *sk, const struct sk_buff *skb,
static void tcp_chrono_set(struct tcp_sock *tp, const enum tcp_chrono new)
{
const u32 now = tcp_jiffies32;
+ enum tcp_chrono old = tp->chrono_type;
- if (tp->chrono_type > TCP_CHRONO_UNSPEC)
- tp->chrono_stat[tp->chrono_type - 1] += now - tp->chrono_start;
+ if (old > TCP_CHRONO_UNSPEC)
+ tp->chrono_stat[old - 1] += now - tp->chrono_start;
tp->chrono_start = now;
tp->chrono_type = new;
}
@@ -2376,24 +2377,15 @@ bool tcp_schedule_loss_probe(struct sock *sk)
{
struct inet_connection_sock *icsk = inet_csk(sk);
struct tcp_sock *tp = tcp_sk(sk);
- u32 timeout, tlp_time_stamp, rto_time_stamp;
u32 rtt = usecs_to_jiffies(tp->srtt_us >> 3);
+ u32 timeout, rto_delta_us;
- /* No consecutive loss probes. */
- if (WARN_ON(icsk->icsk_pending == ICSK_TIME_LOSS_PROBE)) {
- tcp_rearm_rto(sk);
- return false;
- }
/* Don't do any loss probe on a Fast Open connection before 3WHS
* finishes.
*/
if (tp->fastopen_rsk)
return false;
- /* TLP is only scheduled when next timer event is RTO. */
- if (icsk->icsk_pending != ICSK_TIME_RETRANS)
- return false;
-
/* Schedule a loss probe in 2*RTT for SACK capable connections
* in Open state, that are either limited by cwnd or application.
*/
@@ -2416,14 +2408,10 @@ bool tcp_schedule_loss_probe(struct sock *sk)
(rtt + (rtt >> 1) + TCP_DELACK_MAX));
timeout = max_t(u32, timeout, msecs_to_jiffies(10));
- /* If RTO is shorter, just schedule TLP in its place. */
- tlp_time_stamp = tcp_jiffies32 + timeout;
- rto_time_stamp = (u32)inet_csk(sk)->icsk_timeout;
- if ((s32)(tlp_time_stamp - rto_time_stamp) > 0) {
- s32 delta = rto_time_stamp - tcp_jiffies32;
- if (delta > 0)
- timeout = delta;
- }
+ /* If the RTO formula yields an earlier time, then use that time. */
+ rto_delta_us = tcp_rto_delta_us(sk); /* How far in future is RTO? */
+ if (rto_delta_us > 0)
+ timeout = min_t(u32, timeout, usecs_to_jiffies(rto_delta_us));
inet_csk_reset_xmit_timer(sk, ICSK_TIME_LOSS_PROBE, timeout,
TCP_RTO_MAX);
@@ -3448,6 +3436,10 @@ int tcp_connect(struct sock *sk)
int err;
tcp_call_bpf(sk, BPF_SOCK_OPS_TCP_CONNECT_CB);
+
+ if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk))
+ return -EHOSTUNREACH; /* Routing failure or similar. */
+
tcp_connect_init(sk);
if (unlikely(tp->repair)) {
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index c0feeeef962a..e906014890b6 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -652,7 +652,8 @@ static void tcp_keepalive_timer (unsigned long data)
goto death;
}
- if (!sock_flag(sk, SOCK_KEEPOPEN) || sk->sk_state == TCP_CLOSE)
+ if (!sock_flag(sk, SOCK_KEEPOPEN) ||
+ ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_SYN_SENT)))
goto out;
elapsed = keepalive_time_when(tp);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 25294d43e147..a7c804f73990 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -802,7 +802,7 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4)
if (is_udplite) /* UDP-Lite */
csum = udplite_csum(skb);
- else if (sk->sk_no_check_tx) { /* UDP csum disabled */
+ else if (sk->sk_no_check_tx && !skb_is_gso(skb)) { /* UDP csum off */
skb->ip_summed = CHECKSUM_NONE;
goto send;
@@ -1163,34 +1163,32 @@ out:
return ret;
}
-#if BITS_PER_LONG == 64
+#define UDP_SKB_IS_STATELESS 0x80000000
+
static void udp_set_dev_scratch(struct sk_buff *skb)
{
- struct udp_dev_scratch *scratch;
+ struct udp_dev_scratch *scratch = udp_skb_scratch(skb);
BUILD_BUG_ON(sizeof(struct udp_dev_scratch) > sizeof(long));
- scratch = (struct udp_dev_scratch *)&skb->dev_scratch;
- scratch->truesize = skb->truesize;
+ scratch->_tsize_state = skb->truesize;
+#if BITS_PER_LONG == 64
scratch->len = skb->len;
scratch->csum_unnecessary = !!skb_csum_unnecessary(skb);
scratch->is_linear = !skb_is_nonlinear(skb);
+#endif
+ if (likely(!skb->_skb_refdst))
+ scratch->_tsize_state |= UDP_SKB_IS_STATELESS;
}
static int udp_skb_truesize(struct sk_buff *skb)
{
- return ((struct udp_dev_scratch *)&skb->dev_scratch)->truesize;
-}
-#else
-static void udp_set_dev_scratch(struct sk_buff *skb)
-{
- skb->dev_scratch = skb->truesize;
+ return udp_skb_scratch(skb)->_tsize_state & ~UDP_SKB_IS_STATELESS;
}
-static int udp_skb_truesize(struct sk_buff *skb)
+static bool udp_skb_has_head_state(struct sk_buff *skb)
{
- return skb->dev_scratch;
+ return !(udp_skb_scratch(skb)->_tsize_state & UDP_SKB_IS_STATELESS);
}
-#endif
/* fully reclaim rmem/fwd memory allocated for skb */
static void udp_rmem_release(struct sock *sk, int size, int partial,
@@ -1388,6 +1386,11 @@ void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len)
unlock_sock_fast(sk, slow);
}
+ /* In the more common cases we cleared the head states previously,
+ * see __udp_queue_rcv_skb().
+ */
+ if (unlikely(udp_skb_has_head_state(skb)))
+ skb_release_head_state(skb);
consume_stateless_skb(skb);
}
EXPORT_SYMBOL_GPL(skb_consume_udp);
@@ -1779,8 +1782,12 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
sk_mark_napi_id_once(sk, skb);
}
- /* clear all pending head states while they are hot in the cache */
- skb_release_head_state(skb);
+ /* At recvmsg() time we may access skb->dst or skb->sp depending on
+ * the IP options and the cmsg flags, elsewhere can we clear all
+ * pending head states while they are hot in the cache
+ */
+ if (likely(IPCB(skb)->opt.optlen == 0 && !skb_sec_path(skb)))
+ skb_release_head_state(skb);
rc = __udp_enqueue_schedule_skb(sk, skb);
if (rc < 0) {
@@ -1921,7 +1928,7 @@ drop:
/* For TCP sockets, sk_rx_dst is protected by socket lock
* For UDP, we use xchg() to guard against concurrent changes.
*/
-static void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
+void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
{
struct dst_entry *old;
@@ -1930,6 +1937,7 @@ static void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst)
dst_release(old);
}
}
+EXPORT_SYMBOL(udp_sk_rx_dst_set);
/*
* Multicasts and broadcasts go to each listener.
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index 781250151d40..0932c85b42af 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -235,7 +235,7 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
if (uh->check == 0)
uh->check = CSUM_MANGLED_0;
- skb->ip_summed = CHECKSUM_NONE;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
/* If there is no outer header we can fake a checksum offload
* due to the fact that we have already done the checksum in
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 4996d734f1d2..3cec529c6113 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -756,6 +756,7 @@ static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr)))
goto drop;
+ IP6CB(skb)->flags |= IP6SKB_JUMBOGRAM;
return true;
drop:
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 1422d6c08377..2dfe50d8d609 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -673,8 +673,6 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
*prevhdr = NEXTHDR_FRAGMENT;
tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC);
if (!tmp_hdr) {
- IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
- IPSTATS_MIB_FRAGFAILS);
err = -ENOMEM;
goto fail;
}
@@ -789,8 +787,6 @@ slow_path:
frag = alloc_skb(len + hlen + sizeof(struct frag_hdr) +
hroom + troom, GFP_ATOMIC);
if (!frag) {
- IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
- IPSTATS_MIB_FRAGFAILS);
err = -ENOMEM;
goto fail;
}
@@ -1385,11 +1381,12 @@ emsgsize:
*/
cork->length += length;
- if ((((length + (skb ? skb->len : headersize)) > mtu) ||
- (skb && skb_is_gso(skb))) &&
+ if ((skb && skb_is_gso(skb)) ||
+ (((length + (skb ? skb->len : headersize)) > mtu) &&
+ (skb_queue_len(queue) <= 1) &&
(sk->sk_protocol == IPPROTO_UDP) &&
(rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) &&
- (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk)) {
+ (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk))) {
err = ip6_ufo_append_data(sk, queue, getfrag, from, length,
hh_len, fragheaderlen, exthdrlen,
transhdrlen, mtu, flags, fl6);
diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c
index e9065b8d3af8..abb2c307fbe8 100644
--- a/net/ipv6/output_core.c
+++ b/net/ipv6/output_core.c
@@ -78,7 +78,7 @@ EXPORT_SYMBOL(ipv6_select_ident);
int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
{
- u16 offset = sizeof(struct ipv6hdr);
+ unsigned int offset = sizeof(struct ipv6hdr);
unsigned int packet_len = skb_tail_pointer(skb) -
skb_network_header(skb);
int found_rhdr = 0;
@@ -86,6 +86,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
while (offset <= packet_len) {
struct ipv6_opt_hdr *exthdr;
+ unsigned int len;
switch (**nexthdr) {
@@ -111,7 +112,10 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
offset);
- offset += ipv6_optlen(exthdr);
+ len = ipv6_optlen(exthdr);
+ if (len + offset >= IPV6_MAXPLEN)
+ return -EINVAL;
+ offset += len;
*nexthdr = &exthdr->nexthdr;
}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 4d30c96a819d..a640fbcba15d 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2351,6 +2351,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
if (on_link)
nrt->rt6i_flags &= ~RTF_GATEWAY;
+ nrt->rt6i_protocol = RTPROT_REDIRECT;
nrt->rt6i_gateway = *(struct in6_addr *)neigh->primary_key;
if (ip6_ins_rt(nrt))
@@ -2461,6 +2462,7 @@ static struct rt6_info *rt6_add_route_info(struct net *net,
.fc_dst_len = prefixlen,
.fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO |
RTF_UP | RTF_PREF(pref),
+ .fc_protocol = RTPROT_RA,
.fc_nlinfo.portid = 0,
.fc_nlinfo.nlh = NULL,
.fc_nlinfo.nl_net = net,
@@ -2513,6 +2515,7 @@ struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr,
.fc_ifindex = dev->ifindex,
.fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT |
RTF_UP | RTF_EXPIRES | RTF_PREF(pref),
+ .fc_protocol = RTPROT_RA,
.fc_nlinfo.portid = 0,
.fc_nlinfo.nlh = NULL,
.fc_nlinfo.nl_net = dev_net(dev),
@@ -3424,14 +3427,6 @@ static int rt6_fill_node(struct net *net,
rtm->rtm_flags = 0;
rtm->rtm_scope = RT_SCOPE_UNIVERSE;
rtm->rtm_protocol = rt->rt6i_protocol;
- if (rt->rt6i_flags & RTF_DYNAMIC)
- rtm->rtm_protocol = RTPROT_REDIRECT;
- else if (rt->rt6i_flags & RTF_ADDRCONF) {
- if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ROUTEINFO))
- rtm->rtm_protocol = RTPROT_RA;
- else
- rtm->rtm_protocol = RTPROT_KERNEL;
- }
if (rt->rt6i_flags & RTF_CACHE)
rtm->rtm_flags |= RTM_F_CLONED;
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 7b75b0620730..4e7817abc0b9 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -216,6 +216,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
treq->rcv_isn = ntohl(th->seq) - 1;
treq->snt_isn = cookie;
treq->ts_off = 0;
+ treq->txhash = net_tx_rndhash();
/*
* We need to lookup the dst_entry to get the correct window size.
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 4a3e65626e8b..578142b7ca3e 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -291,11 +291,7 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb,
struct udp_table *udptable)
{
const struct ipv6hdr *iph = ipv6_hdr(skb);
- struct sock *sk;
- sk = skb_steal_sock(skb);
- if (unlikely(sk))
- return sk;
return __udp6_lib_lookup(dev_net(skb->dev), &iph->saddr, sport,
&iph->daddr, dport, inet6_iif(skb),
udptable, skb);
@@ -332,6 +328,15 @@ struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be
EXPORT_SYMBOL_GPL(udp6_lib_lookup);
#endif
+/* do not use the scratch area len for jumbogram: their length execeeds the
+ * scratch area space; note that the IP6CB flags is still in the first
+ * cacheline, so checking for jumbograms is cheap
+ */
+static int udp6_skb_len(struct sk_buff *skb)
+{
+ return unlikely(inet6_is_jumbogram(skb)) ? skb->len : udp_skb_len(skb);
+}
+
/*
* This should be easy, if there is something there we
* return it, otherwise we block.
@@ -362,7 +367,7 @@ try_again:
if (!skb)
return err;
- ulen = udp_skb_len(skb);
+ ulen = udp6_skb_len(skb);
copied = len;
if (copied > ulen - off)
copied = ulen - off;
@@ -804,6 +809,24 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
if (udp6_csum_init(skb, uh, proto))
goto csum_error;
+ /* Check if the socket is already available, e.g. due to early demux */
+ sk = skb_steal_sock(skb);
+ if (sk) {
+ struct dst_entry *dst = skb_dst(skb);
+ int ret;
+
+ if (unlikely(sk->sk_rx_dst != dst))
+ udp_sk_rx_dst_set(sk, dst);
+
+ ret = udpv6_queue_rcv_skb(sk, skb);
+ sock_put(sk);
+
+ /* a return value > 0 means to resubmit the input */
+ if (ret > 0)
+ return ret;
+ return 0;
+ }
+
/*
* Multicast receive code
*/
@@ -812,11 +835,6 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
saddr, daddr, udptable, proto);
/* Unicast */
-
- /*
- * check socket cache ... must talk to Alan about his plans
- * for sock caches... i'll skip this for now.
- */
sk = __udp6_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
if (sk) {
int ret;
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index a2267f80febb..e7d378c032cb 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -72,7 +72,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
if (uh->check == 0)
uh->check = CSUM_MANGLED_0;
- skb->ip_summed = CHECKSUM_NONE;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
/* If there is no outer header we can fake a checksum offload
* due to the fact that we have already done the checksum in
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 552d606e57ca..974cf2a3795a 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -227,114 +227,6 @@ void nf_unregister_net_hooks(struct net *net, const struct nf_hook_ops *reg,
}
EXPORT_SYMBOL(nf_unregister_net_hooks);
-static LIST_HEAD(nf_hook_list);
-
-static int _nf_register_hook(struct nf_hook_ops *reg)
-{
- struct net *net, *last;
- int ret;
-
- for_each_net(net) {
- ret = nf_register_net_hook(net, reg);
- if (ret && ret != -ENOENT)
- goto rollback;
- }
- list_add_tail(&reg->list, &nf_hook_list);
-
- return 0;
-rollback:
- last = net;
- for_each_net(net) {
- if (net == last)
- break;
- nf_unregister_net_hook(net, reg);
- }
- return ret;
-}
-
-int nf_register_hook(struct nf_hook_ops *reg)
-{
- int ret;
-
- rtnl_lock();
- ret = _nf_register_hook(reg);
- rtnl_unlock();
-
- return ret;
-}
-EXPORT_SYMBOL(nf_register_hook);
-
-static void _nf_unregister_hook(struct nf_hook_ops *reg)
-{
- struct net *net;
-
- list_del(&reg->list);
- for_each_net(net)
- nf_unregister_net_hook(net, reg);
-}
-
-void nf_unregister_hook(struct nf_hook_ops *reg)
-{
- rtnl_lock();
- _nf_unregister_hook(reg);
- rtnl_unlock();
-}
-EXPORT_SYMBOL(nf_unregister_hook);
-
-int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n)
-{
- unsigned int i;
- int err = 0;
-
- for (i = 0; i < n; i++) {
- err = nf_register_hook(&reg[i]);
- if (err)
- goto err;
- }
- return err;
-
-err:
- if (i > 0)
- nf_unregister_hooks(reg, i);
- return err;
-}
-EXPORT_SYMBOL(nf_register_hooks);
-
-/* Caller MUST take rtnl_lock() */
-int _nf_register_hooks(struct nf_hook_ops *reg, unsigned int n)
-{
- unsigned int i;
- int err = 0;
-
- for (i = 0; i < n; i++) {
- err = _nf_register_hook(&reg[i]);
- if (err)
- goto err;
- }
- return err;
-
-err:
- if (i > 0)
- _nf_unregister_hooks(reg, i);
- return err;
-}
-EXPORT_SYMBOL(_nf_register_hooks);
-
-void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n)
-{
- while (n-- > 0)
- nf_unregister_hook(&reg[n]);
-}
-EXPORT_SYMBOL(nf_unregister_hooks);
-
-/* Caller MUST take rtnl_lock */
-void _nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n)
-{
- while (n-- > 0)
- _nf_unregister_hook(&reg[n]);
-}
-EXPORT_SYMBOL(_nf_unregister_hooks);
-
/* Returns 1 if okfn() needs to be executed by the caller,
* -EPERM for NF_DROP, 0 otherwise. Caller must hold rcu_read_lock. */
int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state,
@@ -450,40 +342,9 @@ void (*nf_nat_decode_session_hook)(struct sk_buff *, struct flowi *);
EXPORT_SYMBOL(nf_nat_decode_session_hook);
#endif
-static int nf_register_hook_list(struct net *net)
-{
- struct nf_hook_ops *elem;
- int ret;
-
- rtnl_lock();
- list_for_each_entry(elem, &nf_hook_list, list) {
- ret = nf_register_net_hook(net, elem);
- if (ret && ret != -ENOENT)
- goto out_undo;
- }
- rtnl_unlock();
- return 0;
-
-out_undo:
- list_for_each_entry_continue_reverse(elem, &nf_hook_list, list)
- nf_unregister_net_hook(net, elem);
- rtnl_unlock();
- return ret;
-}
-
-static void nf_unregister_hook_list(struct net *net)
-{
- struct nf_hook_ops *elem;
-
- rtnl_lock();
- list_for_each_entry(elem, &nf_hook_list, list)
- nf_unregister_net_hook(net, elem);
- rtnl_unlock();
-}
-
static int __net_init netfilter_net_init(struct net *net)
{
- int i, h, ret;
+ int i, h;
for (i = 0; i < ARRAY_SIZE(net->nf.hooks); i++) {
for (h = 0; h < NF_MAX_HOOKS; h++)
@@ -500,16 +361,12 @@ static int __net_init netfilter_net_init(struct net *net)
return -ENOMEM;
}
#endif
- ret = nf_register_hook_list(net);
- if (ret)
- remove_proc_entry("netfilter", net->proc_net);
- return ret;
+ return 0;
}
static void __net_exit netfilter_net_exit(struct net *net)
{
- nf_unregister_hook_list(net);
remove_proc_entry("netfilter", net->proc_net);
}
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index e03d16ed550d..899c2c36da13 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -422,7 +422,7 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
h = nf_ct_expect_dst_hash(net, &expect->tuple);
hlist_for_each_entry_safe(i, next, &nf_ct_expect_hash[h], hnode) {
if (expect_matches(i, expect)) {
- if (nf_ct_remove_expect(expect))
+ if (nf_ct_remove_expect(i))
break;
} else if (expect_clash(i, expect)) {
ret = -EBUSY;
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index 832c5a08d9a5..eb541786ccb7 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -222,20 +222,21 @@ find_appropriate_src(struct net *net,
.tuple = tuple,
.zone = zone
};
- struct rhlist_head *hl;
+ struct rhlist_head *hl, *h;
hl = rhltable_lookup(&nf_nat_bysource_table, &key,
nf_nat_bysource_params);
- if (!hl)
- return 0;
- ct = container_of(hl, typeof(*ct), nat_bysource);
+ rhl_for_each_entry_rcu(ct, h, hl, nat_bysource) {
+ nf_ct_invert_tuplepr(result,
+ &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+ result->dst = tuple->dst;
- nf_ct_invert_tuplepr(result,
- &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
- result->dst = tuple->dst;
+ if (in_range(l3proto, l4proto, result, range))
+ return 1;
+ }
- return in_range(l3proto, l4proto, result, range);
+ return 0;
}
/* For [FUTURE] fragmentation handling, we want the least-used
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 92b05e188fd1..733d3e4a30d8 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -472,8 +472,7 @@ static void nfnetlink_rcv_skb_batch(struct sk_buff *skb, struct nlmsghdr *nlh)
if (msglen > skb->len)
msglen = skb->len;
- if (nlh->nlmsg_len < NLMSG_HDRLEN ||
- skb->len < NLMSG_HDRLEN + sizeof(struct nfgenmsg))
+ if (skb->len < NLMSG_HDRLEN + sizeof(struct nfgenmsg))
return;
err = nla_parse(cda, NFNL_BATCH_MAX, attr, attrlen, nfnl_batch_policy,
@@ -500,7 +499,8 @@ static void nfnetlink_rcv(struct sk_buff *skb)
{
struct nlmsghdr *nlh = nlmsg_hdr(skb);
- if (nlh->nlmsg_len < NLMSG_HDRLEN ||
+ if (skb->len < NLMSG_HDRLEN ||
+ nlh->nlmsg_len < NLMSG_HDRLEN ||
skb->len < nlh->nlmsg_len)
return;
diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
index 08679ebb3068..03859e386b47 100644
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -629,6 +629,34 @@ ovs_ct_find_existing(struct net *net, const struct nf_conntrack_zone *zone,
return ct;
}
+static
+struct nf_conn *ovs_ct_executed(struct net *net,
+ const struct sw_flow_key *key,
+ const struct ovs_conntrack_info *info,
+ struct sk_buff *skb,
+ bool *ct_executed)
+{
+ struct nf_conn *ct = NULL;
+
+ /* If no ct, check if we have evidence that an existing conntrack entry
+ * might be found for this skb. This happens when we lose a skb->_nfct
+ * due to an upcall, or if the direction is being forced. If the
+ * connection was not confirmed, it is not cached and needs to be run
+ * through conntrack again.
+ */
+ *ct_executed = (key->ct_state & OVS_CS_F_TRACKED) &&
+ !(key->ct_state & OVS_CS_F_INVALID) &&
+ (key->ct_zone == info->zone.id);
+
+ if (*ct_executed || (!key->ct_state && info->force)) {
+ ct = ovs_ct_find_existing(net, &info->zone, info->family, skb,
+ !!(key->ct_state &
+ OVS_CS_F_NAT_MASK));
+ }
+
+ return ct;
+}
+
/* Determine whether skb->_nfct is equal to the result of conntrack lookup. */
static bool skb_nfct_cached(struct net *net,
const struct sw_flow_key *key,
@@ -637,24 +665,17 @@ static bool skb_nfct_cached(struct net *net,
{
enum ip_conntrack_info ctinfo;
struct nf_conn *ct;
+ bool ct_executed = true;
ct = nf_ct_get(skb, &ctinfo);
- /* If no ct, check if we have evidence that an existing conntrack entry
- * might be found for this skb. This happens when we lose a skb->_nfct
- * due to an upcall. If the connection was not confirmed, it is not
- * cached and needs to be run through conntrack again.
- */
- if (!ct && key->ct_state & OVS_CS_F_TRACKED &&
- !(key->ct_state & OVS_CS_F_INVALID) &&
- key->ct_zone == info->zone.id) {
- ct = ovs_ct_find_existing(net, &info->zone, info->family, skb,
- !!(key->ct_state
- & OVS_CS_F_NAT_MASK));
- if (ct)
- nf_ct_get(skb, &ctinfo);
- }
if (!ct)
+ ct = ovs_ct_executed(net, key, info, skb, &ct_executed);
+
+ if (ct)
+ nf_ct_get(skb, &ctinfo);
+ else
return false;
+
if (!net_eq(net, read_pnet(&ct->ct_net)))
return false;
if (!nf_ct_zone_equal_any(info->ct, nf_ct_zone(ct)))
@@ -679,7 +700,7 @@ static bool skb_nfct_cached(struct net *net,
return false;
}
- return true;
+ return ct_executed;
}
#ifdef CONFIG_NF_NAT_NEEDED
@@ -1289,8 +1310,8 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info,
nla_for_each_nested(a, attr, rem) {
int type = nla_type(a);
- int maxlen = ovs_ct_attr_lens[type].maxlen;
- int minlen = ovs_ct_attr_lens[type].minlen;
+ int maxlen;
+ int minlen;
if (type > OVS_CT_ATTR_MAX) {
OVS_NLERR(log,
@@ -1298,6 +1319,9 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info,
type, OVS_CT_ATTR_MAX);
return -EINVAL;
}
+
+ maxlen = ovs_ct_attr_lens[type].maxlen;
+ minlen = ovs_ct_attr_lens[type].minlen;
if (nla_len(a) < minlen || nla_len(a) > maxlen) {
OVS_NLERR(log,
"Conntrack attr type has unexpected length (type=%d, length=%d, expected=%d)",
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index e3beb28203eb..008a45ca3112 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -214,6 +214,7 @@ static void prb_clear_rxhash(struct tpacket_kbdq_core *,
static void prb_fill_vlan_info(struct tpacket_kbdq_core *,
struct tpacket3_hdr *);
static void packet_flush_mclist(struct sock *sk);
+static void packet_pick_tx_queue(struct net_device *dev, struct sk_buff *skb);
struct packet_skb_cb {
union {
@@ -260,6 +261,7 @@ static int packet_direct_xmit(struct sk_buff *skb)
if (skb != orig_skb)
goto drop;
+ packet_pick_tx_queue(dev, skb);
txq = skb_get_tx_queue(dev, skb);
local_bh_disable();
@@ -2747,8 +2749,6 @@ tpacket_error:
goto tpacket_error;
}
- packet_pick_tx_queue(dev, skb);
-
skb->destructor = tpacket_destruct_skb;
__packet_set_status(po, ph, TP_STATUS_SENDING);
packet_inc_pending(&po->tx_ring);
@@ -2931,8 +2931,6 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
skb->priority = sk->sk_priority;
skb->mark = sockc.mark;
- packet_pick_tx_queue(dev, skb);
-
if (po->has_vnet_hdr) {
err = virtio_net_hdr_to_skb(skb, &vnet_hdr, vio_le());
if (err)
@@ -3702,14 +3700,19 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
if (optlen != sizeof(val))
return -EINVAL;
- if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
- return -EBUSY;
if (copy_from_user(&val, optval, sizeof(val)))
return -EFAULT;
if (val > INT_MAX)
return -EINVAL;
- po->tp_reserve = val;
- return 0;
+ lock_sock(sk);
+ if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
+ ret = -EBUSY;
+ } else {
+ po->tp_reserve = val;
+ ret = 0;
+ }
+ release_sock(sk);
+ return ret;
}
case PACKET_LOSS:
{
@@ -4331,7 +4334,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
register_prot_hook(sk);
}
spin_unlock(&po->bind_lock);
- if (closing && (po->tp_version > TPACKET_V2)) {
+ if (pg_vec && (po->tp_version > TPACKET_V2)) {
/* Because we don't support block-based V3 on tx-ring */
if (!tx_ring)
prb_shutdown_retire_blk_timer(po, rb_queue);
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
index e10624aa6959..9722bf839d9d 100644
--- a/net/rds/ib_recv.c
+++ b/net/rds/ib_recv.c
@@ -1015,8 +1015,10 @@ void rds_ib_recv_cqe_handler(struct rds_ib_connection *ic,
if (rds_ib_ring_empty(&ic->i_recv_ring))
rds_ib_stats_inc(s_ib_rx_ring_empty);
- if (rds_ib_ring_low(&ic->i_recv_ring))
+ if (rds_ib_ring_low(&ic->i_recv_ring)) {
rds_ib_recv_refill(conn, 0, GFP_NOWAIT);
+ rds_ib_stats_inc(s_ib_rx_refill_from_cq);
+ }
}
int rds_ib_recv_path(struct rds_conn_path *cp)
@@ -1029,6 +1031,7 @@ int rds_ib_recv_path(struct rds_conn_path *cp)
if (rds_conn_up(conn)) {
rds_ib_attempt_ack(ic);
rds_ib_recv_refill(conn, 0, GFP_KERNEL);
+ rds_ib_stats_inc(s_ib_rx_refill_from_thread);
}
return ret;
diff --git a/net/rds/send.c b/net/rds/send.c
index e81aa176f4e2..41b9f0f5bb9c 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -170,8 +170,8 @@ restart:
* The acquire_in_xmit() check above ensures that only one
* caller can increment c_send_gen at any time.
*/
- cp->cp_send_gen++;
- send_gen = cp->cp_send_gen;
+ send_gen = READ_ONCE(cp->cp_send_gen) + 1;
+ WRITE_ONCE(cp->cp_send_gen, send_gen);
/*
* rds_conn_shutdown() sets the conn state and then tests RDS_IN_XMIT,
@@ -431,7 +431,7 @@ over_batch:
smp_mb();
if ((test_bit(0, &conn->c_map_queued) ||
!list_empty(&cp->cp_send_queue)) &&
- send_gen == cp->cp_send_gen) {
+ send_gen == READ_ONCE(cp->cp_send_gen)) {
rds_stats_inc(s_send_lock_queue_raced);
if (batch_count < send_batch_count)
goto restart;
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index aed6cf2e9fd8..f2e9ed34a963 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -835,7 +835,7 @@ out_nlmsg_trim:
}
static int
-act_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
+tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
struct list_head *actions, int event)
{
struct sk_buff *skb;
@@ -1018,7 +1018,7 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
}
if (event == RTM_GETACTION)
- ret = act_get_notify(net, portid, n, &actions, event);
+ ret = tcf_get_notify(net, portid, n, &actions, event);
else { /* delete */
ret = tcf_del_notify(net, n, &actions, portid);
if (ret)
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index 36f0ced9e60c..d516ba8178b8 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -36,8 +36,8 @@ static struct tc_action_ops act_ipt_ops;
static unsigned int xt_net_id;
static struct tc_action_ops act_xt_ops;
-static int ipt_init_target(struct xt_entry_target *t, char *table,
- unsigned int hook)
+static int ipt_init_target(struct net *net, struct xt_entry_target *t,
+ char *table, unsigned int hook)
{
struct xt_tgchk_param par;
struct xt_target *target;
@@ -49,8 +49,9 @@ static int ipt_init_target(struct xt_entry_target *t, char *table,
return PTR_ERR(target);
t->u.kernel.target = target;
+ memset(&par, 0, sizeof(par));
+ par.net = net;
par.table = table;
- par.entryinfo = NULL;
par.target = target;
par.targinfo = t->data;
par.hook_mask = hook;
@@ -91,10 +92,11 @@ static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = {
[TCA_IPT_TARG] = { .len = sizeof(struct xt_entry_target) },
};
-static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
+static int __tcf_ipt_init(struct net *net, unsigned int id, struct nlattr *nla,
struct nlattr *est, struct tc_action **a,
const struct tc_action_ops *ops, int ovr, int bind)
{
+ struct tc_action_net *tn = net_generic(net, id);
struct nlattr *tb[TCA_IPT_MAX + 1];
struct tcf_ipt *ipt;
struct xt_entry_target *td, *t;
@@ -159,7 +161,7 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
if (unlikely(!t))
goto err2;
- err = ipt_init_target(t, tname, hook);
+ err = ipt_init_target(net, t, tname, hook);
if (err < 0)
goto err3;
@@ -193,18 +195,16 @@ static int tcf_ipt_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a, int ovr,
int bind)
{
- struct tc_action_net *tn = net_generic(net, ipt_net_id);
-
- return __tcf_ipt_init(tn, nla, est, a, &act_ipt_ops, ovr, bind);
+ return __tcf_ipt_init(net, ipt_net_id, nla, est, a, &act_ipt_ops, ovr,
+ bind);
}
static int tcf_xt_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a, int ovr,
int bind)
{
- struct tc_action_net *tn = net_generic(net, xt_net_id);
-
- return __tcf_ipt_init(tn, nla, est, a, &act_xt_ops, ovr, bind);
+ return __tcf_ipt_init(net, xt_net_id, nla, est, a, &act_xt_ops, ovr,
+ bind);
}
static int tcf_ipt(struct sk_buff *skb, const struct tc_action *a,
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 4e16b02ed832..6110447fe51d 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -228,7 +228,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
sctp_adaptation_ind_param_t aiparam;
sctp_supported_ext_param_t ext_param;
int num_ext = 0;
- __u8 extensions[3];
+ __u8 extensions[4];
struct sctp_paramhdr *auth_chunks = NULL,
*auth_hmacs = NULL;
@@ -396,7 +396,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
sctp_adaptation_ind_param_t aiparam;
sctp_supported_ext_param_t ext_param;
int num_ext = 0;
- __u8 extensions[3];
+ __u8 extensions[4];
struct sctp_paramhdr *auth_chunks = NULL,
*auth_hmacs = NULL,
*auth_random = NULL;
diff --git a/net/socket.c b/net/socket.c
index bf2122691fba..ad22df1ffbd1 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1916,7 +1916,7 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
if (copy_from_user(&msg, umsg, sizeof(*umsg)))
return -EFAULT;
- kmsg->msg_control = msg.msg_control;
+ kmsg->msg_control = (void __force *)msg.msg_control;
kmsg->msg_controllen = msg.msg_controllen;
kmsg->msg_flags = msg.msg_flags;
@@ -1935,7 +1935,8 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
if (msg.msg_name && kmsg->msg_namelen) {
if (!save_addr) {
- err = move_addr_to_kernel(msg.msg_name, kmsg->msg_namelen,
+ err = move_addr_to_kernel(msg.msg_name,
+ kmsg->msg_namelen,
kmsg->msg_name);
if (err < 0)
return err;
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index d5b54c020dec..4f154d388748 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1624,6 +1624,8 @@ static void xs_tcp_state_change(struct sock *sk)
if (test_and_clear_bit(XPRT_SOCK_CONNECTING,
&transport->sock_state))
xprt_clear_connecting(xprt);
+ if (sk->sk_err)
+ xprt_wake_pending_tasks(xprt, -sk->sk_err);
xs_sock_mark_closed(xprt);
}
out:
diff --git a/net/tipc/node.c b/net/tipc/node.c
index aeef8011ac7d..9b4dcb6a16b5 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -1455,10 +1455,8 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb,
/* Initiate synch mode if applicable */
if ((usr == TUNNEL_PROTOCOL) && (mtyp == SYNCH_MSG) && (oseqno == 1)) {
syncpt = iseqno + exp_pkts - 1;
- if (!tipc_link_is_up(l)) {
- tipc_link_fsm_evt(l, LINK_ESTABLISH_EVT);
+ if (!tipc_link_is_up(l))
__tipc_node_link_up(n, bearer_id, xmitq);
- }
if (n->state == SELF_UP_PEER_UP) {
n->sync_point = syncpt;
tipc_link_fsm_evt(l, LINK_SYNCH_BEGIN_EVT);
diff --git a/samples/bpf/tcbpf2_kern.c b/samples/bpf/tcbpf2_kern.c
index 9c823a609e75..270edcc149a1 100644
--- a/samples/bpf/tcbpf2_kern.c
+++ b/samples/bpf/tcbpf2_kern.c
@@ -147,9 +147,9 @@ int _geneve_set_tunnel(struct __sk_buff *skb)
__builtin_memset(&gopt, 0x0, sizeof(gopt));
gopt.opt_class = 0x102; /* Open Virtual Networking (OVN) */
gopt.type = 0x08;
- gopt.r1 = 1;
+ gopt.r1 = 0;
gopt.r2 = 0;
- gopt.r3 = 1;
+ gopt.r3 = 0;
gopt.length = 2; /* 4-byte multiple */
*(int *) &gopt.opt_data = 0xdeadbeef;
diff --git a/samples/bpf/test_tunnel_bpf.sh b/samples/bpf/test_tunnel_bpf.sh
index 1ff634f187b7..a70d2ea90313 100755
--- a/samples/bpf/test_tunnel_bpf.sh
+++ b/samples/bpf/test_tunnel_bpf.sh
@@ -149,6 +149,7 @@ function cleanup {
ip link del veth1
ip link del ipip11
ip link del gretap11
+ ip link del vxlan11
ip link del geneve11
pkill tcpdump
pkill cat
diff --git a/scripts/dtc/dtx_diff b/scripts/dtc/dtx_diff
index fb86f3899e16..f9a3d8d23c64 100755
--- a/scripts/dtc/dtx_diff
+++ b/scripts/dtc/dtx_diff
@@ -321,7 +321,7 @@ fi
cpp_flags="\
-nostdinc \
-I${srctree}/arch/${ARCH}/boot/dts \
- -I${srctree}/arch/${ARCH}/boot/dts/include \
+ -I${srctree}/scripts/dtc/include-prefixes \
-I${srctree}/drivers/of/testcase-data \
-undef -D__DTS__"
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index 3bd5f4f30235..bc443201d3ef 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -18,6 +18,7 @@ my $V = '0.26';
use Getopt::Long qw(:config no_auto_abbrev);
use Cwd;
+use File::Find;
my $cur_path = fastgetcwd() . '/';
my $lk_path = "./";
@@ -58,6 +59,7 @@ my $from_filename = 0;
my $pattern_depth = 0;
my $version = 0;
my $help = 0;
+my $find_maintainer_files = 0;
my $vcs_used = 0;
@@ -249,6 +251,7 @@ if (!GetOptions(
'sections!' => \$sections,
'fe|file-emails!' => \$file_emails,
'f|file' => \$from_filename,
+ 'find-maintainer-files' => \$find_maintainer_files,
'v|version' => \$version,
'h|help|usage' => \$help,
)) {
@@ -307,36 +310,74 @@ if (!top_of_kernel_tree($lk_path)) {
my @typevalue = ();
my %keyword_hash;
+my @mfiles = ();
-open (my $maint, '<', "${lk_path}MAINTAINERS")
- or die "$P: Can't open MAINTAINERS: $!\n";
-while (<$maint>) {
- my $line = $_;
-
- if ($line =~ m/^([A-Z]):\s*(.*)/) {
- my $type = $1;
- my $value = $2;
-
- ##Filename pattern matching
- if ($type eq "F" || $type eq "X") {
- $value =~ s@\.@\\\.@g; ##Convert . to \.
- $value =~ s/\*/\.\*/g; ##Convert * to .*
- $value =~ s/\?/\./g; ##Convert ? to .
- ##if pattern is a directory and it lacks a trailing slash, add one
- if ((-d $value)) {
- $value =~ s@([^/])$@$1/@;
+sub read_maintainer_file {
+ my ($file) = @_;
+
+ open (my $maint, '<', "$file")
+ or die "$P: Can't open MAINTAINERS file '$file': $!\n";
+ while (<$maint>) {
+ my $line = $_;
+
+ if ($line =~ m/^([A-Z]):\s*(.*)/) {
+ my $type = $1;
+ my $value = $2;
+
+ ##Filename pattern matching
+ if ($type eq "F" || $type eq "X") {
+ $value =~ s@\.@\\\.@g; ##Convert . to \.
+ $value =~ s/\*/\.\*/g; ##Convert * to .*
+ $value =~ s/\?/\./g; ##Convert ? to .
+ ##if pattern is a directory and it lacks a trailing slash, add one
+ if ((-d $value)) {
+ $value =~ s@([^/])$@$1/@;
+ }
+ } elsif ($type eq "K") {
+ $keyword_hash{@typevalue} = $value;
}
- } elsif ($type eq "K") {
- $keyword_hash{@typevalue} = $value;
+ push(@typevalue, "$type:$value");
+ } elsif (!(/^\s*$/ || /^\s*\#/)) {
+ $line =~ s/\n$//g;
+ push(@typevalue, $line);
}
- push(@typevalue, "$type:$value");
- } elsif (!/^(\s)*$/) {
- $line =~ s/\n$//g;
- push(@typevalue, $line);
}
+ close($maint);
+}
+
+sub find_is_maintainer_file {
+ my ($file) = $_;
+ return if ($file !~ m@/MAINTAINERS$@);
+ $file = $File::Find::name;
+ return if (! -f $file);
+ push(@mfiles, $file);
}
-close($maint);
+sub find_ignore_git {
+ return grep { $_ !~ /^\.git$/; } @_;
+}
+
+if (-d "${lk_path}MAINTAINERS") {
+ opendir(DIR, "${lk_path}MAINTAINERS") or die $!;
+ my @files = readdir(DIR);
+ closedir(DIR);
+ foreach my $file (@files) {
+ push(@mfiles, "${lk_path}MAINTAINERS/$file") if ($file !~ /^\./);
+ }
+}
+
+if ($find_maintainer_files) {
+ find( { wanted => \&find_is_maintainer_file,
+ preprocess => \&find_ignore_git,
+ no_chdir => 1,
+ }, "${lk_path}");
+} else {
+ push(@mfiles, "${lk_path}MAINTAINERS") if -f "${lk_path}MAINTAINERS";
+}
+
+foreach my $file (@mfiles) {
+ read_maintainer_file("$file");
+}
#
# Read mail address map
@@ -873,7 +914,7 @@ sub top_of_kernel_tree {
if ( (-f "${lk_path}COPYING")
&& (-f "${lk_path}CREDITS")
&& (-f "${lk_path}Kbuild")
- && (-f "${lk_path}MAINTAINERS")
+ && (-e "${lk_path}MAINTAINERS")
&& (-f "${lk_path}Makefile")
&& (-f "${lk_path}README")
&& (-d "${lk_path}Documentation")
diff --git a/scripts/parse-maintainers.pl b/scripts/parse-maintainers.pl
new file mode 100644
index 000000000000..e40b53db7f9f
--- /dev/null
+++ b/scripts/parse-maintainers.pl
@@ -0,0 +1,128 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+my $P = $0;
+
+# sort comparison functions
+sub by_category($$) {
+ my ($a, $b) = @_;
+
+ $a = uc $a;
+ $b = uc $b;
+
+ # This always sorts last
+ $a =~ s/THE REST/ZZZZZZ/g;
+ $b =~ s/THE REST/ZZZZZZ/g;
+
+ return $a cmp $b;
+}
+
+sub by_pattern($$) {
+ my ($a, $b) = @_;
+ my $preferred_order = 'MRPLSWTQBCFXNK';
+
+ my $a1 = uc(substr($a, 0, 1));
+ my $b1 = uc(substr($b, 0, 1));
+
+ my $a_index = index($preferred_order, $a1);
+ my $b_index = index($preferred_order, $b1);
+
+ $a_index = 1000 if ($a_index == -1);
+ $b_index = 1000 if ($b_index == -1);
+
+ if (($a1 =~ /^F$/ && $b1 =~ /^F$/) ||
+ ($a1 =~ /^X$/ && $b1 =~ /^X$/)) {
+ return $a cmp $b;
+ }
+
+ if ($a_index < $b_index) {
+ return -1;
+ } elsif ($a_index == $b_index) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+sub trim {
+ my $s = shift;
+ $s =~ s/\s+$//;
+ $s =~ s/^\s+//;
+ return $s;
+}
+
+sub alpha_output {
+ my ($hashref, $filename) = (@_);
+
+ open(my $file, '>', "$filename") or die "$P: $filename: open failed - $!\n";
+ foreach my $key (sort by_category keys %$hashref) {
+ if ($key eq " ") {
+ chomp $$hashref{$key};
+ print $file $$hashref{$key};
+ } else {
+ print $file "\n" . $key . "\n";
+ foreach my $pattern (sort by_pattern split('\n', %$hashref{$key})) {
+ print $file ($pattern . "\n");
+ }
+ }
+ }
+ close($file);
+}
+
+sub file_input {
+ my ($hashref, $filename) = (@_);
+
+ my $lastline = "";
+ my $case = " ";
+ $$hashref{$case} = "";
+
+ open(my $file, '<', "$filename") or die "$P: $filename: open failed - $!\n";
+
+ while (<$file>) {
+ my $line = $_;
+
+ # Pattern line?
+ if ($line =~ m/^([A-Z]):\s*(.*)/) {
+ $line = $1 . ":\t" . trim($2) . "\n";
+ if ($lastline eq "") {
+ $$hashref{$case} = $$hashref{$case} . $line;
+ next;
+ }
+ $case = trim($lastline);
+ exists $$hashref{$case} and die "Header '$case' already exists";
+ $$hashref{$case} = $line;
+ $lastline = "";
+ next;
+ }
+
+ if ($case eq " ") {
+ $$hashref{$case} = $$hashref{$case} . $lastline;
+ $lastline = $line;
+ next;
+ }
+ trim($lastline) eq "" or die ("Odd non-pattern line '$lastline' for '$case'");
+ $lastline = $line;
+ }
+ $$hashref{$case} = $$hashref{$case} . $lastline;
+ close($file);
+}
+
+my %hash;
+my %new_hash;
+
+file_input(\%hash, "MAINTAINERS");
+
+foreach my $type (@ARGV) {
+ foreach my $key (keys %hash) {
+ if ($key =~ /$type/ || $hash{$key} =~ /$type/) {
+ $new_hash{$key} = $hash{$key};
+ delete $hash{$key};
+ }
+ }
+}
+
+alpha_output(\%hash, "MAINTAINERS.new");
+alpha_output(\%new_hash, "SECTION.new");
+
+exit(0);
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 91bc6214ae57..1c02c6547038 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -198,7 +198,7 @@ struct request_key_auth {
void *callout_info;
size_t callout_len;
pid_t pid;
-};
+} __randomize_layout;
extern struct key_type key_type_request_key_auth;
extern struct key *request_key_auth_new(struct key *target,
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 2e402ece4c86..8e6b04b39dcc 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -1235,8 +1235,6 @@ static int snd_fm801_create(struct snd_card *card,
}
}
- snd_fm801_chip_init(chip);
-
if ((chip->tea575x_tuner & TUNER_ONLY) == 0) {
if (devm_request_irq(&pci->dev, pci->irq, snd_fm801_interrupt,
IRQF_SHARED, KBUILD_MODNAME, chip)) {
@@ -1248,6 +1246,8 @@ static int snd_fm801_create(struct snd_card *card,
pci_set_master(pci);
}
+ snd_fm801_chip_init(chip);
+
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
snd_fm801_free(chip);
return err;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 63bc894ddf5e..8c1289963c80 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -933,6 +933,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE),
SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC),
SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO),
+ SND_PCI_QUIRK(0x103c, 0x822e, "HP ProBook 440 G4", CXT_FIXUP_MUTE_LED_GPIO),
SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO),
SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index d549f35f39d3..53f9311370de 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -3733,11 +3733,15 @@ HDA_CODEC_ENTRY(0x1002aa01, "R6xx HDMI", patch_atihdmi),
HDA_CODEC_ENTRY(0x10951390, "SiI1390 HDMI", patch_generic_hdmi),
HDA_CODEC_ENTRY(0x10951392, "SiI1392 HDMI", patch_generic_hdmi),
HDA_CODEC_ENTRY(0x17e80047, "Chrontel HDMI", patch_generic_hdmi),
+HDA_CODEC_ENTRY(0x10de0001, "MCP73 HDMI", patch_nvhdmi_2ch),
HDA_CODEC_ENTRY(0x10de0002, "MCP77/78 HDMI", patch_nvhdmi_8ch_7x),
HDA_CODEC_ENTRY(0x10de0003, "MCP77/78 HDMI", patch_nvhdmi_8ch_7x),
+HDA_CODEC_ENTRY(0x10de0004, "GPU 04 HDMI", patch_nvhdmi_8ch_7x),
HDA_CODEC_ENTRY(0x10de0005, "MCP77/78 HDMI", patch_nvhdmi_8ch_7x),
HDA_CODEC_ENTRY(0x10de0006, "MCP77/78 HDMI", patch_nvhdmi_8ch_7x),
HDA_CODEC_ENTRY(0x10de0007, "MCP79/7A HDMI", patch_nvhdmi_8ch_7x),
+HDA_CODEC_ENTRY(0x10de0008, "GPU 08 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0009, "GPU 09 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de000a, "GPU 0a HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de000b, "GPU 0b HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de000c, "MCP89 HDMI", patch_nvhdmi),
@@ -3764,17 +3768,40 @@ HDA_CODEC_ENTRY(0x10de0041, "GPU 41 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0042, "GPU 42 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0043, "GPU 43 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0044, "GPU 44 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0045, "GPU 45 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0050, "GPU 50 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0051, "GPU 51 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0052, "GPU 52 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0060, "GPU 60 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0061, "GPU 61 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0062, "GPU 62 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0067, "MCP67 HDMI", patch_nvhdmi_2ch),
HDA_CODEC_ENTRY(0x10de0070, "GPU 70 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0071, "GPU 71 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0072, "GPU 72 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0073, "GPU 73 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0074, "GPU 74 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0076, "GPU 76 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de007b, "GPU 7b HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de007c, "GPU 7c HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de007d, "GPU 7d HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de007e, "GPU 7e HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0080, "GPU 80 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0081, "GPU 81 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0082, "GPU 82 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de0083, "GPU 83 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0084, "GPU 84 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0090, "GPU 90 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0091, "GPU 91 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0092, "GPU 92 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0093, "GPU 93 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0094, "GPU 94 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0095, "GPU 95 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0097, "GPU 97 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0098, "GPU 98 HDMI/DP", patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0099, "GPU 99 HDMI/DP", patch_nvhdmi),
HDA_CODEC_ENTRY(0x10de8001, "MCP73 HDMI", patch_nvhdmi_2ch),
+HDA_CODEC_ENTRY(0x10de8067, "MCP67/68 HDMI", patch_nvhdmi_2ch),
HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP", patch_via_hdmi),
HDA_CODEC_ENTRY(0x11069f81, "VX900 HDMI/DP", patch_via_hdmi),
HDA_CODEC_ENTRY(0x11069f84, "VX11 HDMI/DP", patch_generic_hdmi),
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 45d58fc1df39..a91a9ef00c40 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -2296,6 +2296,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
+ SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
@@ -3838,6 +3839,17 @@ static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
}
}
+static struct coef_fw alc225_pre_hsmode[] = {
+ UPDATE_COEF(0x4a, 1<<8, 0),
+ UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
+ UPDATE_COEF(0x63, 3<<14, 3<<14),
+ UPDATE_COEF(0x4a, 3<<4, 2<<4),
+ UPDATE_COEF(0x4a, 3<<10, 3<<10),
+ UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
+ UPDATE_COEF(0x4a, 3<<10, 0),
+ {}
+};
+
static void alc_headset_mode_unplugged(struct hda_codec *codec)
{
static struct coef_fw coef0255[] = {
@@ -3873,6 +3885,10 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
UPDATE_COEF(0x67, 0x2000, 0),
{}
};
+ static struct coef_fw coef0298[] = {
+ UPDATE_COEF(0x19, 0x1300, 0x0300),
+ {}
+ };
static struct coef_fw coef0292[] = {
WRITE_COEF(0x76, 0x000e),
WRITE_COEF(0x6c, 0x2400),
@@ -3895,13 +3911,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
{}
};
static struct coef_fw coef0225[] = {
- UPDATE_COEF(0x4a, 1<<8, 0),
- UPDATE_COEFEX(0x57, 0x05, 1<<14, 0),
- UPDATE_COEF(0x63, 3<<14, 3<<14),
- UPDATE_COEF(0x4a, 3<<4, 2<<4),
- UPDATE_COEF(0x4a, 3<<10, 3<<10),
- UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
- UPDATE_COEF(0x4a, 3<<10, 0),
+ UPDATE_COEF(0x63, 3<<14, 0),
{}
};
static struct coef_fw coef0274[] = {
@@ -3935,7 +3945,10 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
break;
case 0x10ec0286:
case 0x10ec0288:
+ alc_process_coef_fw(codec, coef0288);
+ break;
case 0x10ec0298:
+ alc_process_coef_fw(codec, coef0298);
alc_process_coef_fw(codec, coef0288);
break;
case 0x10ec0292:
@@ -3976,6 +3989,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
{}
};
static struct coef_fw coef0288[] = {
+ UPDATE_COEF(0x4f, 0x00c0, 0),
UPDATE_COEF(0x50, 0x2000, 0),
UPDATE_COEF(0x56, 0x0006, 0),
UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
@@ -4039,7 +4053,6 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
case 0x10ec0286:
case 0x10ec0288:
case 0x10ec0298:
- alc_update_coef_idx(codec, 0x4f, 0x000c, 0);
snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
alc_process_coef_fw(codec, coef0288);
snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
@@ -4072,6 +4085,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
case 0x10ec0225:
case 0x10ec0295:
case 0x10ec0299:
+ alc_process_coef_fw(codec, alc225_pre_hsmode);
alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
alc_process_coef_fw(codec, coef0225);
@@ -4084,7 +4098,12 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
static void alc_headset_mode_default(struct hda_codec *codec)
{
static struct coef_fw coef0225[] = {
- UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
+ UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10),
+ UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10),
+ UPDATE_COEF(0x49, 3<<8, 0<<8),
+ UPDATE_COEF(0x4a, 3<<4, 3<<4),
+ UPDATE_COEF(0x63, 3<<14, 0),
+ UPDATE_COEF(0x67, 0xf000, 0x3000),
{}
};
static struct coef_fw coef0255[] = {
@@ -4138,6 +4157,7 @@ static void alc_headset_mode_default(struct hda_codec *codec)
case 0x10ec0225:
case 0x10ec0295:
case 0x10ec0299:
+ alc_process_coef_fw(codec, alc225_pre_hsmode);
alc_process_coef_fw(codec, coef0225);
break;
case 0x10ec0255:
@@ -4177,6 +4197,8 @@ static void alc_headset_mode_default(struct hda_codec *codec)
/* Iphone type */
static void alc_headset_mode_ctia(struct hda_codec *codec)
{
+ int val;
+
static struct coef_fw coef0255[] = {
WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
WRITE_COEF(0x1b, 0x0c2b),
@@ -4219,11 +4241,14 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
WRITE_COEF(0xc3, 0x0000),
{}
};
- static struct coef_fw coef0225[] = {
+ static struct coef_fw coef0225_1[] = {
UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
- UPDATE_COEF(0x49, 1<<8, 1<<8),
- UPDATE_COEF(0x4a, 7<<6, 7<<6),
- UPDATE_COEF(0x4a, 3<<4, 3<<4),
+ UPDATE_COEF(0x63, 3<<14, 2<<14),
+ {}
+ };
+ static struct coef_fw coef0225_2[] = {
+ UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10),
+ UPDATE_COEF(0x63, 3<<14, 1<<14),
{}
};
@@ -4244,8 +4269,17 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
alc_process_coef_fw(codec, coef0233);
break;
case 0x10ec0298:
- alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);/* Headset output enable */
- /* ALC298 jack type setting is the same with ALC286/ALC288 */
+ val = alc_read_coef_idx(codec, 0x50);
+ if (val & (1 << 12)) {
+ alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
+ alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
+ msleep(300);
+ } else {
+ alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
+ alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
+ msleep(300);
+ }
+ break;
case 0x10ec0286:
case 0x10ec0288:
alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
@@ -4264,7 +4298,11 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
case 0x10ec0225:
case 0x10ec0295:
case 0x10ec0299:
- alc_process_coef_fw(codec, coef0225);
+ val = alc_read_coef_idx(codec, 0x45);
+ if (val & (1 << 9))
+ alc_process_coef_fw(codec, coef0225_2);
+ else
+ alc_process_coef_fw(codec, coef0225_1);
break;
case 0x10ec0867:
alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
@@ -4320,9 +4358,7 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
};
static struct coef_fw coef0225[] = {
UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10),
- UPDATE_COEF(0x49, 1<<8, 1<<8),
- UPDATE_COEF(0x4a, 7<<6, 7<<6),
- UPDATE_COEF(0x4a, 3<<4, 3<<4),
+ UPDATE_COEF(0x63, 3<<14, 2<<14),
{}
};
@@ -4344,7 +4380,9 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
break;
case 0x10ec0298:
alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
- /* ALC298 jack type setting is the same with ALC286/ALC288 */
+ alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
+ msleep(300);
+ break;
case 0x10ec0286:
case 0x10ec0288:
alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
@@ -4384,6 +4422,14 @@ static void alc_determine_headset_type(struct hda_codec *codec)
UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
{}
};
+ static struct coef_fw coef0298[] = {
+ UPDATE_COEF(0x50, 0x2000, 0x2000),
+ UPDATE_COEF(0x56, 0x0006, 0x0006),
+ UPDATE_COEF(0x66, 0x0008, 0),
+ UPDATE_COEF(0x67, 0x2000, 0),
+ UPDATE_COEF(0x19, 0x1300, 0x1300),
+ {}
+ };
static struct coef_fw coef0293[] = {
UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
@@ -4396,11 +4442,6 @@ static void alc_determine_headset_type(struct hda_codec *codec)
WRITE_COEF(0xc3, 0x0c00),
{}
};
- static struct coef_fw coef0225[] = {
- UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
- UPDATE_COEF(0x49, 1<<8, 1<<8),
- {}
- };
static struct coef_fw coef0274[] = {
UPDATE_COEF(0x4a, 0x0010, 0),
UPDATE_COEF(0x4a, 0x8000, 0),
@@ -4433,8 +4474,34 @@ static void alc_determine_headset_type(struct hda_codec *codec)
is_ctia = (val & 0x0070) == 0x0070;
break;
case 0x10ec0298:
- alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020); /* Headset output enable */
- /* ALC298 check jack type is the same with ALC286/ALC288 */
+ snd_hda_codec_write(codec, 0x21, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
+ msleep(100);
+ snd_hda_codec_write(codec, 0x21, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
+ msleep(200);
+
+ val = alc_read_coef_idx(codec, 0x50);
+ if (val & (1 << 12)) {
+ alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);
+ alc_process_coef_fw(codec, coef0288);
+ msleep(350);
+ val = alc_read_coef_idx(codec, 0x50);
+ is_ctia = (val & 0x0070) == 0x0070;
+ } else {
+ alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);
+ alc_process_coef_fw(codec, coef0288);
+ msleep(350);
+ val = alc_read_coef_idx(codec, 0x50);
+ is_ctia = (val & 0x0070) == 0x0070;
+ }
+ alc_process_coef_fw(codec, coef0298);
+ snd_hda_codec_write(codec, 0x21, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
+ msleep(75);
+ snd_hda_codec_write(codec, 0x21, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+ break;
case 0x10ec0286:
case 0x10ec0288:
alc_process_coef_fw(codec, coef0288);
@@ -4463,10 +4530,25 @@ static void alc_determine_headset_type(struct hda_codec *codec)
case 0x10ec0225:
case 0x10ec0295:
case 0x10ec0299:
- alc_process_coef_fw(codec, coef0225);
- msleep(800);
- val = alc_read_coef_idx(codec, 0x46);
- is_ctia = (val & 0x00f0) == 0x00f0;
+ alc_process_coef_fw(codec, alc225_pre_hsmode);
+ alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000);
+ val = alc_read_coef_idx(codec, 0x45);
+ if (val & (1 << 9)) {
+ alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
+ alc_update_coef_idx(codec, 0x49, 3<<8, 2<<8);
+ msleep(800);
+ val = alc_read_coef_idx(codec, 0x46);
+ is_ctia = (val & 0x00f0) == 0x00f0;
+ } else {
+ alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x34<<10);
+ alc_update_coef_idx(codec, 0x49, 3<<8, 1<<8);
+ msleep(800);
+ val = alc_read_coef_idx(codec, 0x46);
+ is_ctia = (val & 0x00f0) == 0x00f0;
+ }
+ alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6);
+ alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4);
+ alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
break;
case 0x10ec0867:
is_ctia = true;
@@ -6724,6 +6806,7 @@ static int patch_alc269(struct hda_codec *codec)
case 0x10ec0225:
case 0x10ec0295:
spec->codec_variant = ALC269_TYPE_ALC225;
+ spec->gen.mixer_nid = 0; /* no loopback on ALC225 ALC295 */
break;
case 0x10ec0299:
spec->codec_variant = ALC269_TYPE_ALC225;
diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c
index a78802920c3c..5710fd440bcd 100644
--- a/sound/soc/codecs/msm8916-wcd-analog.c
+++ b/sound/soc/codecs/msm8916-wcd-analog.c
@@ -36,7 +36,7 @@
#define CDC_D_CDC_DIG_CLK_CTL (0xf04A)
#define DIG_CLK_CTL_RXD1_CLK_EN BIT(0)
#define DIG_CLK_CTL_RXD2_CLK_EN BIT(1)
-#define DIG_CLK_CTL_RXD3_CLK_EN BIT(3)
+#define DIG_CLK_CTL_RXD3_CLK_EN BIT(2)
#define DIG_CLK_CTL_TXD_CLK_EN BIT(4)
#define DIG_CLK_CTL_NCP_CLK_EN_MASK BIT(6)
#define DIG_CLK_CTL_NCP_CLK_EN BIT(6)
diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c
index a33202affeb1..fa550e3c1332 100644
--- a/sound/soc/codecs/rt5663.c
+++ b/sound/soc/codecs/rt5663.c
@@ -466,7 +466,7 @@ static const struct reg_default rt5663_reg[] = {
{ 0x0006, 0x1000 },
{ 0x000a, 0x0000 },
{ 0x0010, 0x000f },
- { 0x0015, 0x42c1 },
+ { 0x0015, 0x42f1 },
{ 0x0016, 0x0000 },
{ 0x0018, 0x000b },
{ 0x0019, 0xafaf },
@@ -509,7 +509,7 @@ static const struct reg_default rt5663_reg[] = {
{ 0x008a, 0x0000 },
{ 0x008b, 0x0000 },
{ 0x008c, 0x0003 },
- { 0x008e, 0x0004 },
+ { 0x008e, 0x0008 },
{ 0x008f, 0x1000 },
{ 0x0090, 0x0646 },
{ 0x0091, 0x0e3e },
@@ -520,7 +520,7 @@ static const struct reg_default rt5663_reg[] = {
{ 0x0098, 0x0000 },
{ 0x009a, 0x0000 },
{ 0x009f, 0x0000 },
- { 0x00ae, 0x2000 },
+ { 0x00ae, 0x6000 },
{ 0x00af, 0x0000 },
{ 0x00b6, 0x0000 },
{ 0x00b7, 0x0000 },
@@ -538,7 +538,7 @@ static const struct reg_default rt5663_reg[] = {
{ 0x00d9, 0x08f9 },
{ 0x00db, 0x0008 },
{ 0x00dc, 0x00c0 },
- { 0x00dd, 0x6724 },
+ { 0x00dd, 0x6729 },
{ 0x00de, 0x3131 },
{ 0x00df, 0x0008 },
{ 0x00e0, 0x4000 },
@@ -578,7 +578,7 @@ static const struct reg_default rt5663_reg[] = {
{ 0x0116, 0x0000 },
{ 0x0117, 0x0f00 },
{ 0x0118, 0x0006 },
- { 0x0125, 0x2224 },
+ { 0x0125, 0x2424 },
{ 0x0126, 0x5550 },
{ 0x0127, 0x0400 },
{ 0x0128, 0x7711 },
@@ -596,8 +596,8 @@ static const struct reg_default rt5663_reg[] = {
{ 0x0145, 0x0002 },
{ 0x0146, 0x0000 },
{ 0x0160, 0x0e80 },
- { 0x0161, 0x0020 },
- { 0x0162, 0x0080 },
+ { 0x0161, 0x0080 },
+ { 0x0162, 0x0200 },
{ 0x0163, 0x0800 },
{ 0x0164, 0x0000 },
{ 0x0165, 0x0000 },
@@ -676,8 +676,8 @@ static const struct reg_default rt5663_reg[] = {
{ 0x0251, 0x0000 },
{ 0x0252, 0x028a },
{ 0x02fa, 0x0000 },
- { 0x02fb, 0x0000 },
- { 0x02fc, 0x0000 },
+ { 0x02fb, 0x00a4 },
+ { 0x02fc, 0x0300 },
{ 0x0300, 0x0000 },
{ 0x03d0, 0x0000 },
{ 0x03d1, 0x0000 },
diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c
index 370ed54d1e15..e597c893536d 100644
--- a/sound/soc/codecs/rt5665.c
+++ b/sound/soc/codecs/rt5665.c
@@ -4368,12 +4368,12 @@ static int rt5665_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
switch (dai->id) {
case RT5665_AIF2_1:
case RT5665_AIF2_2:
- snd_soc_update_bits(codec, RT5665_ADDA_CLK_1,
+ snd_soc_update_bits(codec, RT5665_ADDA_CLK_2,
RT5665_I2S_BCLK_MS2_MASK,
RT5665_I2S_BCLK_MS2_64);
break;
case RT5665_AIF3:
- snd_soc_update_bits(codec, RT5665_ADDA_CLK_1,
+ snd_soc_update_bits(codec, RT5665_ADDA_CLK_2,
RT5665_I2S_BCLK_MS3_MASK,
RT5665_I2S_BCLK_MS3_64);
break;
diff --git a/sound/soc/codecs/rt5665.h b/sound/soc/codecs/rt5665.h
index 1db5c6a62a8e..d95249c4c47b 100644
--- a/sound/soc/codecs/rt5665.h
+++ b/sound/soc/codecs/rt5665.h
@@ -1692,8 +1692,8 @@
#define RT5665_GP6_PIN_MASK (0x3 << 5)
#define RT5665_GP6_PIN_SFT 5
#define RT5665_GP6_PIN_GPIO6 (0x0 << 5)
-#define RT5665_GP6_PIN_BCLK3 (0x0 << 5)
-#define RT5665_GP6_PIN_PDM_SCL (0x1 << 5)
+#define RT5665_GP6_PIN_BCLK3 (0x1 << 5)
+#define RT5665_GP6_PIN_PDM_SCL (0x2 << 5)
#define RT5665_GP7_PIN_MASK (0x3 << 3)
#define RT5665_GP7_PIN_SFT 3
#define RT5665_GP7_PIN_GPIO7 (0x0 << 3)
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 8f6814c1eb6b..80f6d1da7095 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -409,7 +409,7 @@ static int dac_put_volsw(struct snd_kcontrol *kcontrol,
static int avc_get_threshold(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
int db, i;
u16 reg = snd_soc_read(codec, SGTL5000_DAP_AVC_THRESHOLD);
@@ -442,7 +442,7 @@ static int avc_get_threshold(struct snd_kcontrol *kcontrol,
static int avc_put_threshold(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
int db;
u16 reg;
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index b95132e2f9dc..06790615e04e 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -527,6 +527,10 @@ static int imx_ssi_probe(struct platform_device *pdev)
}
ssi->irq = platform_get_irq(pdev, 0);
+ if (ssi->irq < 0) {
+ dev_err(&pdev->dev, "Failed to get IRQ: %d\n", ssi->irq);
+ return ssi->irq;
+ }
ssi->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(ssi->clk)) {
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
index 105ec3a6e30d..de2550c7a96b 100644
--- a/sound/soc/generic/audio-graph-card.c
+++ b/sound/soc/generic/audio-graph-card.c
@@ -224,9 +224,11 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
of_for_each_phandle(&it, rc, node, "dais", NULL, 0) {
ret = asoc_graph_card_dai_link_of(it.node, priv, idx++);
- of_node_put(it.node);
- if (ret < 0)
+ if (ret < 0) {
+ of_node_put(it.node);
+
return ret;
+ }
}
return asoc_simple_card_parse_card_name(card, NULL);
@@ -239,10 +241,8 @@ static int asoc_graph_get_dais_count(struct device *dev)
int count = 0;
int rc;
- of_for_each_phandle(&it, rc, node, "dais", NULL, 0) {
+ of_for_each_phandle(&it, rc, node, "dais", NULL, 0)
count++;
- of_node_put(it.node);
- }
return count;
}
diff --git a/sound/soc/generic/audio-graph-scu-card.c b/sound/soc/generic/audio-graph-scu-card.c
index dcd2df37bc3b..758ac06f3a99 100644
--- a/sound/soc/generic/audio-graph-scu-card.c
+++ b/sound/soc/generic/audio-graph-scu-card.c
@@ -215,7 +215,6 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
codec_ep = of_graph_get_remote_endpoint(cpu_ep);
rcpu_ep = of_graph_get_remote_endpoint(codec_ep);
- of_node_put(cpu_port);
of_node_put(cpu_ep);
of_node_put(codec_ep);
of_node_put(rcpu_ep);
@@ -232,8 +231,10 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep,
NULL, &daifmt);
- if (ret < 0)
+ if (ret < 0) {
+ of_node_put(cpu_port);
goto parse_of_err;
+ }
}
dai_idx = 0;
@@ -250,7 +251,6 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
codec_ep = of_graph_get_remote_endpoint(cpu_ep);
codec_port = of_graph_get_port_parent(codec_ep);
- of_node_put(cpu_port);
of_node_put(cpu_ep);
of_node_put(codec_ep);
of_node_put(codec_port);
@@ -266,13 +266,17 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
/* Back-End (= Codec) */
ret = asoc_graph_card_dai_link_of(codec_ep, priv, daifmt, dai_idx++, 0);
- if (ret < 0)
+ if (ret < 0) {
+ of_node_put(cpu_port);
goto parse_of_err;
+ }
} else {
/* Front-End (= CPU) */
ret = asoc_graph_card_dai_link_of(cpu_ep, priv, daifmt, dai_idx++, 1);
- if (ret < 0)
+ if (ret < 0) {
+ of_node_put(cpu_port);
goto parse_of_err;
+ }
}
}
}
@@ -306,7 +310,6 @@ static int asoc_graph_get_dais_count(struct device *dev)
codec_ep = of_graph_get_remote_endpoint(cpu_ep);
codec_port = of_graph_get_port_parent(codec_ep);
- of_node_put(cpu_port);
of_node_put(cpu_ep);
of_node_put(codec_ep);
of_node_put(codec_port);
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 26d64fa40c9c..7d7ab4aee42e 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -263,6 +263,9 @@ static int asoc_simple_card_get_dai_id(struct device_node *ep)
id = i;
i++;
}
+
+ of_node_put(node);
+
if (id < 0)
return -ENODEV;
@@ -282,11 +285,6 @@ int asoc_simple_card_parse_graph_dai(struct device_node *ep,
if (!dai_name)
return 0;
- /*
- * of_graph_get_port_parent() will call
- * of_node_put(). So, call of_node_get() here
- */
- of_node_get(ep);
node = of_graph_get_port_parent(ep);
/* Get dai->name */
diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
index 3fe4a0807095..cfd89ca6a18d 100644
--- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
@@ -319,7 +319,9 @@ static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream,
int ret;
/* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */
- rt5663_sel_asrc_clk_src(codec_dai->codec, RT5663_DA_STEREO_FILTER, 1);
+ rt5663_sel_asrc_clk_src(codec_dai->codec,
+ RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
+ RT5663_CLK_SEL_I2S1_ASRC);
ret = snd_soc_dai_set_sysclk(codec_dai,
RT5663_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN);
@@ -349,19 +351,10 @@ static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream,
return ret;
}
- ret = snd_soc_dai_set_pll(codec_dai, 0,
- RT5514_PLL1_S_BCLK, RT5514_AIF1_BCLK_FREQ,
- RT5514_AIF1_SYSCLK_FREQ);
- if (ret < 0) {
- dev_err(rtd->dev, "set bclk err: %d\n", ret);
- return ret;
- }
-
ret = snd_soc_dai_set_sysclk(codec_dai,
- RT5514_SCLK_S_PLL1, RT5514_AIF1_SYSCLK_FREQ,
- SND_SOC_CLOCK_IN);
+ RT5514_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN);
if (ret < 0) {
- dev_err(rtd->dev, "set sclk err: %d\n", ret);
+ dev_err(rtd->dev, "set sysclk err: %d\n", ret);
return ret;
}
}
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index eca85827dbd2..fb2f1f603f3c 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -540,6 +540,14 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
cpr_mconfig->gtw_cfg.dma_buffer_size =
mconfig->dma_buffer_size * dma_io_buf;
+ /* fallback to 2ms default value */
+ if (!cpr_mconfig->gtw_cfg.dma_buffer_size) {
+ if (mconfig->hw_conn_type == SKL_CONN_SOURCE)
+ cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * mconfig->obs;
+ else
+ cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * mconfig->ibs;
+ }
+
cpr_mconfig->cpr_feature_mask = 0;
cpr_mconfig->gtw_cfg.config_length = 0;
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index 334917ee41cf..9e3f8c04dd32 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -941,6 +941,7 @@ static struct sst_acpi_mach sst_bxtp_devdata[] = {
.machine_quirk = sst_acpi_codec_list,
.quirk_data = &bxt_codecs,
},
+ {}
};
static struct sst_acpi_mach sst_kbl_devdata[] = {
@@ -991,6 +992,7 @@ static struct sst_acpi_mach sst_glk_devdata[] = {
.drv_name = "glk_alc298s_i2s",
.fw_filename = "intel/dsp_fw_glk.bin",
},
+ {}
};
/* PCI IDs */
diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c
index 888133f9e65d..3e9cc4842a1d 100644
--- a/sound/soc/omap/omap-hdmi-audio.c
+++ b/sound/soc/omap/omap-hdmi-audio.c
@@ -337,14 +337,11 @@ static int omap_hdmi_audio_probe(struct platform_device *pdev)
ad->dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
mutex_init(&ad->current_stream_lock);
- switch (ha->dss_version) {
- case OMAPDSS_VER_OMAP4430_ES1:
- case OMAPDSS_VER_OMAP4430_ES2:
- case OMAPDSS_VER_OMAP4:
+ switch (ha->version) {
+ case 4:
dai_drv = &omap4_hdmi_dai;
break;
- case OMAPDSS_VER_OMAP5:
- case OMAPDSS_VER_DRA7xx:
+ case 5:
dai_drv = &omap5_hdmi_dai;
break;
default:
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 960744e46edc..484ab3c2ad67 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -1,6 +1,7 @@
config SND_PXA2XX_SOC
tristate "SoC Audio for the Intel PXA2xx chip"
depends on ARCH_PXA || COMPILE_TEST
+ depends on HAS_DMA
select SND_PXA2XX_LIB
help
Say Y or M if you want to add support for codecs attached to
diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c
index 0c0b00e40646..0834319ead42 100644
--- a/sound/soc/samsung/odroid.c
+++ b/sound/soc/samsung/odroid.c
@@ -42,17 +42,17 @@ static int odroid_card_hw_params(struct snd_pcm_substream *substream,
switch (params_rate(params)) {
case 32000:
case 64000:
- pll_freq = 131072000U;
+ pll_freq = 131072006U;
break;
case 44100:
case 88200:
case 176400:
- pll_freq = 180633600U;
+ pll_freq = 180633609U;
break;
case 48000:
case 96000:
case 192000:
- pll_freq = 196608000U;
+ pll_freq = 196608001U;
break;
default:
return -EINVAL;
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c
index 84c51037a7d0..624aaf569fef 100644
--- a/sound/soc/sh/hac.c
+++ b/sound/soc/sh/hac.c
@@ -315,6 +315,8 @@ static const struct snd_soc_component_driver sh4_hac_component = {
static int hac_soc_platform_probe(struct platform_device *pdev)
{
+ int ret;
+
ret = snd_soc_set_ac97_ops(&hac_ac97_ops);
if (ret != 0)
return ret;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 921622a01944..13c875e2392a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3171,8 +3171,6 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
component->remove = component->driver->remove;
component->suspend = component->driver->suspend;
component->resume = component->driver->resume;
- component->pcm_new = component->driver->pcm_new;
- component->pcm_free = component->driver->pcm_free;
dapm = &component->dapm;
dapm->dev = dev;
@@ -3360,25 +3358,6 @@ static void snd_soc_platform_drv_remove(struct snd_soc_component *component)
platform->driver->remove(platform);
}
-static int snd_soc_platform_drv_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_platform *platform = rtd->platform;
-
- if (platform->driver->pcm_new)
- return platform->driver->pcm_new(rtd);
- else
- return 0;
-}
-
-static void snd_soc_platform_drv_pcm_free(struct snd_pcm *pcm)
-{
- struct snd_soc_pcm_runtime *rtd = pcm->private_data;
- struct snd_soc_platform *platform = rtd->platform;
-
- if (platform->driver->pcm_free)
- platform->driver->pcm_free(pcm);
-}
-
/**
* snd_soc_add_platform - Add a platform to the ASoC core
* @dev: The parent device for the platform
@@ -3402,10 +3381,6 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
platform->component.probe = snd_soc_platform_drv_probe;
if (platform_drv->remove)
platform->component.remove = snd_soc_platform_drv_remove;
- if (platform_drv->pcm_new)
- platform->component.pcm_new = snd_soc_platform_drv_pcm_new;
- if (platform_drv->pcm_free)
- platform->component.pcm_free = snd_soc_platform_drv_pcm_free;
#ifdef CONFIG_DEBUG_FS
platform->component.debugfs_prefix = "platform";
@@ -4113,6 +4088,8 @@ int snd_soc_get_dai_id(struct device_node *ep)
}
mutex_unlock(&client_mutex);
+ of_node_put(node);
+
return ret;
}
EXPORT_SYMBOL_GPL(snd_soc_get_dai_id);
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index dcc5ece08668..7d3859e1a7b9 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -181,6 +181,10 @@ int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
dev_dbg(be->dev, "ASoC: BE %s event %d dir %d\n",
be->dai_link->name, event, dir);
+ if ((event == SND_SOC_DAPM_STREAM_STOP) &&
+ (be->dpcm[dir].users >= 1))
+ continue;
+
snd_soc_dapm_stream_event(be, dir, event);
}
@@ -2628,25 +2632,12 @@ static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream)
return ret;
}
-static void soc_pcm_free(struct snd_pcm *pcm)
-{
- struct snd_soc_pcm_runtime *rtd = pcm->private_data;
- struct snd_soc_component *component;
-
- list_for_each_entry(component, &rtd->card->component_dev_list,
- card_list) {
- if (component->pcm_free)
- component->pcm_free(pcm);
- }
-}
-
/* create a new pcm */
int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
{
struct snd_soc_platform *platform = rtd->platform;
struct snd_soc_dai *codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_component *component;
struct snd_pcm *pcm;
char new_name[64];
int ret = 0, playback = 0, capture = 0;
@@ -2756,18 +2747,17 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
if (capture)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops);
- list_for_each_entry(component, &rtd->card->component_dev_list, card_list) {
- if (component->pcm_new) {
- ret = component->pcm_new(rtd);
- if (ret < 0) {
- dev_err(component->dev,
- "ASoC: pcm constructor failed: %d\n",
- ret);
- return ret;
- }
+ if (platform->driver->pcm_new) {
+ ret = platform->driver->pcm_new(rtd);
+ if (ret < 0) {
+ dev_err(platform->dev,
+ "ASoC: pcm constructor failed: %d\n",
+ ret);
+ return ret;
}
}
- pcm->private_free = soc_pcm_free;
+
+ pcm->private_free = platform->driver->pcm_free;
out:
dev_info(rtd->card->dev, "%s <-> %s mapping ok\n",
(rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name,
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
index b50f68a439ce..ba9fc099cf67 100644
--- a/sound/soc/ux500/mop500.c
+++ b/sound/soc/ux500/mop500.c
@@ -33,6 +33,7 @@ static struct snd_soc_dai_link mop500_dai_links[] = {
.stream_name = "ab8500_0",
.cpu_dai_name = "ux500-msp-i2s.1",
.codec_dai_name = "ab8500-codec-dai.0",
+ .platform_name = "ux500-msp-i2s.1",
.codec_name = "ab8500-codec.0",
.init = mop500_ab8500_machine_init,
.ops = mop500_ab8500_ops,
@@ -42,6 +43,7 @@ static struct snd_soc_dai_link mop500_dai_links[] = {
.stream_name = "ab8500_1",
.cpu_dai_name = "ux500-msp-i2s.3",
.codec_dai_name = "ab8500-codec-dai.1",
+ .platform_name = "ux500-msp-i2s.3",
.codec_name = "ab8500-codec.0",
.init = NULL,
.ops = mop500_ab8500_ops,
@@ -85,6 +87,8 @@ static int mop500_of_probe(struct platform_device *pdev,
for (i = 0; i < 2; i++) {
mop500_dai_links[i].cpu_of_node = msp_np[i];
mop500_dai_links[i].cpu_dai_name = NULL;
+ mop500_dai_links[i].platform_of_node = msp_np[i];
+ mop500_dai_links[i].platform_name = NULL;
mop500_dai_links[i].codec_of_node = codec_np;
mop500_dai_links[i].codec_name = NULL;
}
diff --git a/tools/build/feature/test-bpf.c b/tools/build/feature/test-bpf.c
index 7598361ef1f1..da2172ff9662 100644
--- a/tools/build/feature/test-bpf.c
+++ b/tools/build/feature/test-bpf.c
@@ -11,6 +11,8 @@
# define __NR_bpf 280
# elif defined(__sparc__)
# define __NR_bpf 349
+# elif defined(__s390__)
+# define __NR_bpf 351
# else
# error __NR_bpf not defined. libbpf does not support your arch.
# endif
diff --git a/tools/kvm/kvm_stat/kvm_stat b/tools/kvm/kvm_stat/kvm_stat
index dd8f00cfb8b4..32283d88701a 100755
--- a/tools/kvm/kvm_stat/kvm_stat
+++ b/tools/kvm/kvm_stat/kvm_stat
@@ -474,7 +474,7 @@ class Provider(object):
@staticmethod
def is_field_wanted(fields_filter, field):
"""Indicate whether field is valid according to fields_filter."""
- if not fields_filter:
+ if not fields_filter or fields_filter == "help":
return True
return re.match(fields_filter, field) is not None
@@ -1413,8 +1413,8 @@ performance.
Requirements:
- Access to:
- /sys/kernel/debug/kvm
- /sys/kernel/debug/trace/events/*
+ %s
+ %s/events/*
/proc/pid/task
- /proc/sys/kernel/perf_event_paranoid < 1 if user has no
CAP_SYS_ADMIN and perf events are used.
@@ -1434,7 +1434,7 @@ Interactive Commands:
s set update interval
x toggle reporting of stats for individual child trace events
Press any other key to refresh statistics immediately.
-"""
+""" % (PATH_DEBUGFS_KVM, PATH_DEBUGFS_TRACING)
class PlainHelpFormatter(optparse.IndentedHelpFormatter):
def format_description(self, description):
@@ -1496,7 +1496,8 @@ Press any other key to refresh statistics immediately.
action='store',
default=DEFAULT_REGEX,
dest='fields',
- help='fields to display (regex)',
+ help='''fields to display (regex)
+ "-f help" for a list of available events''',
)
optparser.add_option('-p', '--pid',
action='store',
@@ -1559,6 +1560,17 @@ def main():
stats = Stats(options)
+ if options.fields == "help":
+ event_list = "\n"
+ s = stats.get()
+ for key in s.keys():
+ if key.find('(') != -1:
+ key = key[0:key.find('(')]
+ if event_list.find('\n' + key + '\n') == -1:
+ event_list += key + '\n'
+ sys.stdout.write(event_list)
+ return ""
+
if options.log:
log(stats)
elif not options.once:
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 7e0405e1651d..e5bbb090bf88 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -39,6 +39,8 @@
# define __NR_bpf 280
# elif defined(__sparc__)
# define __NR_bpf 349
+# elif defined(__s390__)
+# define __NR_bpf 351
# else
# error __NR_bpf not defined. libbpf does not support your arch.
# endif
@@ -120,7 +122,7 @@ int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
int bpf_verify_program(enum bpf_prog_type type, const struct bpf_insn *insns,
size_t insns_cnt, int strict_alignment,
const char *license, __u32 kern_version,
- char *log_buf, size_t log_buf_sz)
+ char *log_buf, size_t log_buf_sz, int log_level)
{
union bpf_attr attr;
@@ -131,7 +133,7 @@ int bpf_verify_program(enum bpf_prog_type type, const struct bpf_insn *insns,
attr.license = ptr_to_u64(license);
attr.log_buf = ptr_to_u64(log_buf);
attr.log_size = log_buf_sz;
- attr.log_level = 2;
+ attr.log_level = log_level;
log_buf[0] = 0;
attr.kern_version = kern_version;
attr.prog_flags = strict_alignment ? BPF_F_STRICT_ALIGNMENT : 0;
@@ -314,7 +316,6 @@ int bpf_obj_get_info_by_fd(int prog_fd, void *info, __u32 *info_len)
int err;
bzero(&attr, sizeof(attr));
- bzero(info, *info_len);
attr.info.bpf_fd = prog_fd;
attr.info.info_len = *info_len;
attr.info.info = ptr_to_u64(info);
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 16de44a14b48..418c86e69bcb 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -38,7 +38,7 @@ int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
int bpf_verify_program(enum bpf_prog_type type, const struct bpf_insn *insns,
size_t insns_cnt, int strict_alignment,
const char *license, __u32 kern_version,
- char *log_buf, size_t log_buf_sz);
+ char *log_buf, size_t log_buf_sz, int log_level);
int bpf_map_update_elem(int fd, const void *key, const void *value,
__u64 flags);
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index a4d3762cd825..83874b0e266c 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -704,7 +704,7 @@ static void __ui_browser__line_arrow_down(struct ui_browser *browser,
ui_browser__gotorc(browser, row, column + 1);
SLsmg_draw_hline(2);
- if (row++ == 0)
+ if (++row == 0)
goto out;
} else
row = 0;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 87b431886670..413f74df08de 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -273,7 +273,7 @@ struct perf_evsel *perf_evsel__new_cycles(void)
struct perf_event_attr attr = {
.type = PERF_TYPE_HARDWARE,
.config = PERF_COUNT_HW_CPU_CYCLES,
- .exclude_kernel = 1,
+ .exclude_kernel = geteuid() != 0,
};
struct perf_evsel *evsel;
@@ -298,8 +298,10 @@ struct perf_evsel *perf_evsel__new_cycles(void)
goto out;
/* use asprintf() because free(evsel) assumes name is allocated */
- if (asprintf(&evsel->name, "cycles%.*s",
- attr.precise_ip ? attr.precise_ip + 1 : 0, ":ppp") < 0)
+ if (asprintf(&evsel->name, "cycles%s%s%.*s",
+ (attr.precise_ip || attr.exclude_kernel) ? ":" : "",
+ attr.exclude_kernel ? "u" : "",
+ attr.precise_ip ? attr.precise_ip + 1 : 0, "ppp") < 0)
goto error_free;
out:
return evsel;
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 5de2b86b9880..2e9eb6aa3ce2 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -2209,7 +2209,7 @@ int machine__get_kernel_start(struct machine *machine)
machine->kernel_start = 1ULL << 63;
if (map) {
err = map__load(map);
- if (map->start)
+ if (!err)
machine->kernel_start = map->start;
}
return err;
diff --git a/tools/testing/selftests/bpf/test_align.c b/tools/testing/selftests/bpf/test_align.c
index bccebd935907..29793694cbc7 100644
--- a/tools/testing/selftests/bpf/test_align.c
+++ b/tools/testing/selftests/bpf/test_align.c
@@ -380,7 +380,7 @@ static int do_test_single(struct bpf_align_test *test)
prog_len = probe_filter_length(prog);
fd_prog = bpf_verify_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
prog, prog_len, 1, "GPL", 0,
- bpf_vlog, sizeof(bpf_vlog));
+ bpf_vlog, sizeof(bpf_vlog), 2);
if (fd_prog < 0) {
printf("Failed to load program.\n");
printf("%s", bpf_vlog);
diff --git a/tools/testing/selftests/bpf/test_pkt_md_access.c b/tools/testing/selftests/bpf/test_pkt_md_access.c
index 71729d47eb85..7956302ecdf2 100644
--- a/tools/testing/selftests/bpf/test_pkt_md_access.c
+++ b/tools/testing/selftests/bpf/test_pkt_md_access.c
@@ -12,12 +12,23 @@
int _version SEC("version") = 1;
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define TEST_FIELD(TYPE, FIELD, MASK) \
{ \
TYPE tmp = *(volatile TYPE *)&skb->FIELD; \
if (tmp != ((*(volatile __u32 *)&skb->FIELD) & MASK)) \
return TC_ACT_SHOT; \
}
+#else
+#define TEST_FIELD_OFFSET(a, b) ((sizeof(a) - sizeof(b)) / sizeof(b))
+#define TEST_FIELD(TYPE, FIELD, MASK) \
+ { \
+ TYPE tmp = *((volatile TYPE *)&skb->FIELD + \
+ TEST_FIELD_OFFSET(skb->FIELD, TYPE)); \
+ if (tmp != ((*(volatile __u32 *)&skb->FIELD) & MASK)) \
+ return TC_ACT_SHOT; \
+ }
+#endif
SEC("test1")
int process(struct __sk_buff *skb)
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
index 5855cd3d3d45..1f7dd35551b9 100644
--- a/tools/testing/selftests/bpf/test_progs.c
+++ b/tools/testing/selftests/bpf/test_progs.c
@@ -340,6 +340,7 @@ static void test_bpf_obj_id(void)
/* Check getting prog info */
info_len = sizeof(struct bpf_prog_info) * 2;
+ bzero(&prog_infos[i], info_len);
prog_infos[i].jited_prog_insns = ptr_to_u64(jited_insns);
prog_infos[i].jited_prog_len = sizeof(jited_insns);
prog_infos[i].xlated_prog_insns = ptr_to_u64(xlated_insns);
@@ -369,6 +370,7 @@ static void test_bpf_obj_id(void)
/* Check getting map info */
info_len = sizeof(struct bpf_map_info) * 2;
+ bzero(&map_infos[i], info_len);
err = bpf_obj_get_info_by_fd(map_fds[i], &map_infos[i],
&info_len);
if (CHECK(err ||
@@ -394,7 +396,7 @@ static void test_bpf_obj_id(void)
nr_id_found = 0;
next_id = 0;
while (!bpf_prog_get_next_id(next_id, &next_id)) {
- struct bpf_prog_info prog_info;
+ struct bpf_prog_info prog_info = {};
int prog_fd;
info_len = sizeof(prog_info);
@@ -418,6 +420,8 @@ static void test_bpf_obj_id(void)
nr_id_found++;
err = bpf_obj_get_info_by_fd(prog_fd, &prog_info, &info_len);
+ prog_infos[i].jited_prog_insns = 0;
+ prog_infos[i].xlated_prog_insns = 0;
CHECK(err || info_len != sizeof(struct bpf_prog_info) ||
memcmp(&prog_info, &prog_infos[i], info_len),
"get-prog-info(next_id->fd)",
@@ -436,7 +440,7 @@ static void test_bpf_obj_id(void)
nr_id_found = 0;
next_id = 0;
while (!bpf_map_get_next_id(next_id, &next_id)) {
- struct bpf_map_info map_info;
+ struct bpf_map_info map_info = {};
int map_fd;
info_len = sizeof(map_info);
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index 404aec520812..d3ed7324105e 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -8,6 +8,7 @@
* License as published by the Free Software Foundation.
*/
+#include <endian.h>
#include <asm/types.h>
#include <linux/types.h>
#include <stdint.h>
@@ -1098,7 +1099,7 @@ static struct bpf_test tests[] = {
"check skb->hash byte load permitted",
.insns = {
BPF_MOV64_IMM(BPF_REG_0, 0),
-#ifdef __LITTLE_ENDIAN
+#if __BYTE_ORDER == __LITTLE_ENDIAN
BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
offsetof(struct __sk_buff, hash)),
#else
@@ -1135,7 +1136,7 @@ static struct bpf_test tests[] = {
"check skb->hash byte load not permitted 3",
.insns = {
BPF_MOV64_IMM(BPF_REG_0, 0),
-#ifdef __LITTLE_ENDIAN
+#if __BYTE_ORDER == __LITTLE_ENDIAN
BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
offsetof(struct __sk_buff, hash) + 3),
#else
@@ -1244,7 +1245,7 @@ static struct bpf_test tests[] = {
"check skb->hash half load permitted",
.insns = {
BPF_MOV64_IMM(BPF_REG_0, 0),
-#ifdef __LITTLE_ENDIAN
+#if __BYTE_ORDER == __LITTLE_ENDIAN
BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
offsetof(struct __sk_buff, hash)),
#else
@@ -1259,7 +1260,7 @@ static struct bpf_test tests[] = {
"check skb->hash half load not permitted",
.insns = {
BPF_MOV64_IMM(BPF_REG_0, 0),
-#ifdef __LITTLE_ENDIAN
+#if __BYTE_ORDER == __LITTLE_ENDIAN
BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
offsetof(struct __sk_buff, hash) + 2),
#else
@@ -4969,7 +4970,7 @@ static struct bpf_test tests[] = {
BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
sizeof(struct test_val), 4),
BPF_MOV64_IMM(BPF_REG_4, 0),
- BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
+ BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
BPF_MOV64_IMM(BPF_REG_3, 0),
BPF_EMIT_CALL(BPF_FUNC_probe_read),
BPF_MOV64_IMM(BPF_REG_0, 0),
@@ -4995,7 +4996,7 @@ static struct bpf_test tests[] = {
BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
sizeof(struct test_val) + 1, 4),
BPF_MOV64_IMM(BPF_REG_4, 0),
- BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
+ BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
BPF_MOV64_IMM(BPF_REG_3, 0),
BPF_EMIT_CALL(BPF_FUNC_probe_read),
BPF_MOV64_IMM(BPF_REG_0, 0),
@@ -5023,7 +5024,7 @@ static struct bpf_test tests[] = {
BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
sizeof(struct test_val) - 20, 4),
BPF_MOV64_IMM(BPF_REG_4, 0),
- BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
+ BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
BPF_MOV64_IMM(BPF_REG_3, 0),
BPF_EMIT_CALL(BPF_FUNC_probe_read),
BPF_MOV64_IMM(BPF_REG_0, 0),
@@ -5050,7 +5051,7 @@ static struct bpf_test tests[] = {
BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
sizeof(struct test_val) - 19, 4),
BPF_MOV64_IMM(BPF_REG_4, 0),
- BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
+ BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
BPF_MOV64_IMM(BPF_REG_3, 0),
BPF_EMIT_CALL(BPF_FUNC_probe_read),
BPF_MOV64_IMM(BPF_REG_0, 0),
@@ -5422,7 +5423,7 @@ static struct bpf_test tests[] = {
"check bpf_perf_event_data->sample_period byte load permitted",
.insns = {
BPF_MOV64_IMM(BPF_REG_0, 0),
-#ifdef __LITTLE_ENDIAN
+#if __BYTE_ORDER == __LITTLE_ENDIAN
BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
offsetof(struct bpf_perf_event_data, sample_period)),
#else
@@ -5438,7 +5439,7 @@ static struct bpf_test tests[] = {
"check bpf_perf_event_data->sample_period half load permitted",
.insns = {
BPF_MOV64_IMM(BPF_REG_0, 0),
-#ifdef __LITTLE_ENDIAN
+#if __BYTE_ORDER == __LITTLE_ENDIAN
BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
offsetof(struct bpf_perf_event_data, sample_period)),
#else
@@ -5454,7 +5455,7 @@ static struct bpf_test tests[] = {
"check bpf_perf_event_data->sample_period word load permitted",
.insns = {
BPF_MOV64_IMM(BPF_REG_0, 0),
-#ifdef __LITTLE_ENDIAN
+#if __BYTE_ORDER == __LITTLE_ENDIAN
BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
offsetof(struct bpf_perf_event_data, sample_period)),
#else
@@ -5481,7 +5482,7 @@ static struct bpf_test tests[] = {
"check skb->data half load not permitted",
.insns = {
BPF_MOV64_IMM(BPF_REG_0, 0),
-#ifdef __LITTLE_ENDIAN
+#if __BYTE_ORDER == __LITTLE_ENDIAN
BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
offsetof(struct __sk_buff, data)),
#else
@@ -5497,7 +5498,7 @@ static struct bpf_test tests[] = {
"check skb->tc_classid half load not permitted for lwt prog",
.insns = {
BPF_MOV64_IMM(BPF_REG_0, 0),
-#ifdef __LITTLE_ENDIAN
+#if __BYTE_ORDER == __LITTLE_ENDIAN
BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
offsetof(struct __sk_buff, tc_classid)),
#else
@@ -5510,6 +5511,504 @@ static struct bpf_test tests[] = {
.errstr = "invalid bpf_context access",
.prog_type = BPF_PROG_TYPE_LWT_IN,
},
+ {
+ "bounds checks mixing signed and unsigned, positive bounds",
+ .insns = {
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
+ BPF_MOV64_IMM(BPF_REG_2, 2),
+ BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 3),
+ BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 4, 2),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+ BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 3 },
+ .errstr_unpriv = "R0 pointer arithmetic prohibited",
+ .errstr = "R0 min value is negative",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
+ {
+ "bounds checks mixing signed and unsigned",
+ .insns = {
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
+ BPF_MOV64_IMM(BPF_REG_2, -1),
+ BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
+ BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+ BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 3 },
+ .errstr_unpriv = "R0 pointer arithmetic prohibited",
+ .errstr = "R0 min value is negative",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
+ {
+ "bounds checks mixing signed and unsigned, variant 2",
+ .insns = {
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
+ BPF_MOV64_IMM(BPF_REG_2, -1),
+ BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
+ BPF_MOV64_IMM(BPF_REG_8, 0),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_1),
+ BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
+ BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 3 },
+ .errstr_unpriv = "R0 pointer arithmetic prohibited",
+ .errstr = "R8 invalid mem access 'inv'",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
+ {
+ "bounds checks mixing signed and unsigned, variant 3",
+ .insns = {
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
+ BPF_MOV64_IMM(BPF_REG_2, -1),
+ BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 4),
+ BPF_MOV64_REG(BPF_REG_8, BPF_REG_1),
+ BPF_JMP_IMM(BPF_JSGT, BPF_REG_8, 1, 2),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
+ BPF_ST_MEM(BPF_B, BPF_REG_8, 0, 0),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 3 },
+ .errstr_unpriv = "R0 pointer arithmetic prohibited",
+ .errstr = "R8 invalid mem access 'inv'",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
+ {
+ "bounds checks mixing signed and unsigned, variant 4",
+ .insns = {
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
+ BPF_MOV64_IMM(BPF_REG_2, 1),
+ BPF_ALU64_REG(BPF_AND, BPF_REG_1, BPF_REG_2),
+ BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+ BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 3 },
+ .errstr_unpriv = "R0 pointer arithmetic prohibited",
+ .errstr = "R0 min value is negative",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
+ {
+ "bounds checks mixing signed and unsigned, variant 5",
+ .insns = {
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
+ BPF_MOV64_IMM(BPF_REG_2, -1),
+ BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 5),
+ BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 4),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 4),
+ BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
+ BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 3 },
+ .errstr_unpriv = "R0 pointer arithmetic prohibited",
+ .errstr = "R0 invalid mem access",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
+ {
+ "bounds checks mixing signed and unsigned, variant 6",
+ .insns = {
+ BPF_MOV64_IMM(BPF_REG_2, 0),
+ BPF_MOV64_REG(BPF_REG_3, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, -512),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -16),
+ BPF_MOV64_IMM(BPF_REG_6, -1),
+ BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_6, 5),
+ BPF_JMP_IMM(BPF_JSGT, BPF_REG_4, 1, 4),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 1),
+ BPF_MOV64_IMM(BPF_REG_5, 0),
+ BPF_ST_MEM(BPF_H, BPF_REG_10, -512, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_skb_load_bytes),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .errstr_unpriv = "R4 min value is negative, either use unsigned",
+ .errstr = "R4 min value is negative, either use unsigned",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
+ {
+ "bounds checks mixing signed and unsigned, variant 7",
+ .insns = {
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
+ BPF_MOV64_IMM(BPF_REG_2, 1024 * 1024 * 1024),
+ BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
+ BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+ BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 3 },
+ .errstr_unpriv = "R0 pointer arithmetic prohibited",
+ .errstr = "R0 min value is negative",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
+ {
+ "bounds checks mixing signed and unsigned, variant 8",
+ .insns = {
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
+ BPF_MOV64_IMM(BPF_REG_2, 1024 * 1024 * 1024 + 1),
+ BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 3),
+ BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+ BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 3 },
+ .errstr_unpriv = "R0 pointer arithmetic prohibited",
+ .errstr = "R0 min value is negative",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
+ {
+ "bounds checks mixing signed and unsigned, variant 9",
+ .insns = {
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
+ BPF_MOV64_IMM(BPF_REG_2, -1),
+ BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+ BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 3 },
+ .errstr_unpriv = "R0 pointer arithmetic prohibited",
+ .errstr = "R0 min value is negative",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
+ {
+ "bounds checks mixing signed and unsigned, variant 10",
+ .insns = {
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
+ BPF_LD_IMM64(BPF_REG_2, -9223372036854775808ULL),
+ BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+ BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 3 },
+ .errstr_unpriv = "R0 pointer arithmetic prohibited",
+ .errstr = "R0 min value is negative",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
+ {
+ "bounds checks mixing signed and unsigned, variant 11",
+ .insns = {
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
+ BPF_MOV64_IMM(BPF_REG_2, 0),
+ BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 2),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+ BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 3 },
+ .errstr_unpriv = "R0 pointer arithmetic prohibited",
+ .errstr = "R0 min value is negative",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
+ {
+ "bounds checks mixing signed and unsigned, variant 12",
+ .insns = {
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
+ BPF_MOV64_IMM(BPF_REG_2, -1),
+ BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
+ /* Dead branch. */
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+ BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 3 },
+ .errstr_unpriv = "R0 pointer arithmetic prohibited",
+ .errstr = "R0 min value is negative",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
+ {
+ "bounds checks mixing signed and unsigned, variant 13",
+ .insns = {
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
+ BPF_MOV64_IMM(BPF_REG_2, -6),
+ BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+ BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 3 },
+ .errstr_unpriv = "R0 pointer arithmetic prohibited",
+ .errstr = "R0 min value is negative",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
+ {
+ "bounds checks mixing signed and unsigned, variant 14",
+ .insns = {
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
+ BPF_MOV64_IMM(BPF_REG_2, 2),
+ BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
+ BPF_MOV64_IMM(BPF_REG_7, 1),
+ BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 0, 2),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_1),
+ BPF_JMP_IMM(BPF_JSGT, BPF_REG_7, 4, 2),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_7),
+ BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 3 },
+ .errstr_unpriv = "R0 pointer arithmetic prohibited",
+ .errstr = "R0 min value is negative",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
+ {
+ "bounds checks mixing signed and unsigned, variant 15",
+ .insns = {
+ BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_1,
+ offsetof(struct __sk_buff, mark)),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
+ BPF_MOV64_IMM(BPF_REG_2, -1),
+ BPF_MOV64_IMM(BPF_REG_8, 2),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_9, 42, 6),
+ BPF_JMP_REG(BPF_JSGT, BPF_REG_8, BPF_REG_1, 3),
+ BPF_JMP_IMM(BPF_JSGT, BPF_REG_1, 1, 2),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+ BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, -3),
+ BPF_JMP_IMM(BPF_JA, 0, 0, -7),
+ },
+ .fixup_map1 = { 4 },
+ .errstr_unpriv = "R0 pointer arithmetic prohibited",
+ .errstr = "R0 min value is negative",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
+ {
+ "bounds checks mixing signed and unsigned, variant 16",
+ .insns = {
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
+ BPF_MOV64_IMM(BPF_REG_2, -6),
+ BPF_JMP_REG(BPF_JGE, BPF_REG_2, BPF_REG_1, 2),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+ BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 1, 2),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ BPF_ST_MEM(BPF_B, BPF_REG_0, 0, 0),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 3 },
+ .errstr_unpriv = "R0 pointer arithmetic prohibited",
+ .errstr = "R0 min value is negative",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
+ {
+ "subtraction bounds (map value)",
+ .insns = {
+ BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+ BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+ BPF_LD_MAP_FD(BPF_REG_1, 0),
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+ BPF_FUNC_map_lookup_elem),
+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
+ BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
+ BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 7),
+ BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
+ BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 5),
+ BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
+ BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 56),
+ BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+ BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+ .fixup_map1 = { 3 },
+ .errstr_unpriv = "R0 pointer arithmetic prohibited",
+ .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
+ .result = REJECT,
+ .result_unpriv = REJECT,
+ },
};
static int probe_filter_length(const struct bpf_insn *fp)
@@ -5633,7 +6132,7 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
fd_prog = bpf_verify_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
prog, prog_len, test->flags & F_LOAD_WITH_STRICT_ALIGNMENT,
- "GPL", 0, bpf_vlog, sizeof(bpf_vlog));
+ "GPL", 0, bpf_vlog, sizeof(bpf_vlog), 1);
expected_ret = unpriv && test->result_unpriv != UNDEF ?
test->result_unpriv : test->result;
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index 0e1fc75f3585..2ea21dac0b44 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -1718,12 +1718,16 @@ static int kvm_test_age_hva_handler(struct kvm *kvm, gpa_t gpa, u64 size, void *
int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end)
{
+ if (!kvm->arch.pgd)
+ return 0;
trace_kvm_age_hva(start, end);
return handle_hva_to_gpa(kvm, start, end, kvm_age_hva_handler, NULL);
}
int kvm_test_age_hva(struct kvm *kvm, unsigned long hva)
{
+ if (!kvm->arch.pgd)
+ return 0;
trace_kvm_test_age_hva(hva);
return handle_hva_to_gpa(kvm, hva, hva, kvm_test_age_hva_handler, NULL);
}
diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c
index fc8a723ff387..8a9c42366db7 100644
--- a/virt/kvm/arm/pmu.c
+++ b/virt/kvm/arm/pmu.c
@@ -203,11 +203,15 @@ static u64 kvm_pmu_overflow_status(struct kvm_vcpu *vcpu)
return reg;
}
-static void kvm_pmu_check_overflow(struct kvm_vcpu *vcpu)
+static void kvm_pmu_update_state(struct kvm_vcpu *vcpu)
{
struct kvm_pmu *pmu = &vcpu->arch.pmu;
- bool overflow = !!kvm_pmu_overflow_status(vcpu);
+ bool overflow;
+
+ if (!kvm_arm_pmu_v3_ready(vcpu))
+ return;
+ overflow = !!kvm_pmu_overflow_status(vcpu);
if (pmu->irq_level == overflow)
return;
@@ -215,33 +219,11 @@ static void kvm_pmu_check_overflow(struct kvm_vcpu *vcpu)
if (likely(irqchip_in_kernel(vcpu->kvm))) {
int ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id,
- pmu->irq_num, overflow,
- &vcpu->arch.pmu);
+ pmu->irq_num, overflow, pmu);
WARN_ON(ret);
}
}
-/**
- * kvm_pmu_overflow_set - set PMU overflow interrupt
- * @vcpu: The vcpu pointer
- * @val: the value guest writes to PMOVSSET register
- */
-void kvm_pmu_overflow_set(struct kvm_vcpu *vcpu, u64 val)
-{
- if (val == 0)
- return;
-
- vcpu_sys_reg(vcpu, PMOVSSET_EL0) |= val;
- kvm_pmu_check_overflow(vcpu);
-}
-
-static void kvm_pmu_update_state(struct kvm_vcpu *vcpu)
-{
- if (!kvm_arm_pmu_v3_ready(vcpu))
- return;
- kvm_pmu_check_overflow(vcpu);
-}
-
bool kvm_pmu_should_notify_user(struct kvm_vcpu *vcpu)
{
struct kvm_pmu *pmu = &vcpu->arch.pmu;
@@ -303,7 +285,7 @@ static inline struct kvm_vcpu *kvm_pmc_to_vcpu(struct kvm_pmc *pmc)
}
/**
- * When perf event overflows, call kvm_pmu_overflow_set to set overflow status.
+ * When the perf event overflows, set the overflow status and inform the vcpu.
*/
static void kvm_pmu_perf_overflow(struct perf_event *perf_event,
struct perf_sample_data *data,
@@ -313,7 +295,12 @@ static void kvm_pmu_perf_overflow(struct perf_event *perf_event,
struct kvm_vcpu *vcpu = kvm_pmc_to_vcpu(pmc);
int idx = pmc->idx;
- kvm_pmu_overflow_set(vcpu, BIT(idx));
+ vcpu_sys_reg(vcpu, PMOVSSET_EL0) |= BIT(idx);
+
+ if (kvm_pmu_overflow_status(vcpu)) {
+ kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu);
+ kvm_vcpu_kick(vcpu);
+ }
}
/**
@@ -341,7 +328,7 @@ void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 val)
reg = lower_32_bits(reg);
vcpu_sys_reg(vcpu, PMEVCNTR0_EL0 + i) = reg;
if (!reg)
- kvm_pmu_overflow_set(vcpu, BIT(i));
+ vcpu_sys_reg(vcpu, PMOVSSET_EL0) |= BIT(i);
}
}
}
diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
index 3a0b8999f011..5801261f3add 100644
--- a/virt/kvm/arm/vgic/vgic-init.c
+++ b/virt/kvm/arm/vgic/vgic-init.c
@@ -285,9 +285,6 @@ int vgic_init(struct kvm *kvm)
if (ret)
goto out;
- if (vgic_has_its(kvm))
- dist->msis_require_devid = true;
-
kvm_for_each_vcpu(i, vcpu, kvm)
kvm_vgic_vcpu_enable(vcpu);
diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
index 2dff288b3a66..aa6b68db80b4 100644
--- a/virt/kvm/arm/vgic/vgic-its.c
+++ b/virt/kvm/arm/vgic/vgic-its.c
@@ -1598,6 +1598,7 @@ static int vgic_its_create(struct kvm_device *dev, u32 type)
INIT_LIST_HEAD(&its->device_list);
INIT_LIST_HEAD(&its->collection_list);
+ dev->kvm->arch.vgic.msis_require_devid = true;
dev->kvm->arch.vgic.has_its = true;
its->enabled = false;
its->dev = dev;
diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
index 714fa3933546..408ef06638fc 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
@@ -369,7 +369,7 @@ static void vgic_mmio_write_propbase(struct kvm_vcpu *vcpu,
return;
do {
- old_propbaser = dist->propbaser;
+ old_propbaser = READ_ONCE(dist->propbaser);
propbaser = old_propbaser;
propbaser = update_64bit_reg(propbaser, addr & 4, len, val);
propbaser = vgic_sanitise_propbaser(propbaser);
@@ -397,7 +397,7 @@ static void vgic_mmio_write_pendbase(struct kvm_vcpu *vcpu,
return;
do {
- old_pendbaser = vgic_cpu->pendbaser;
+ old_pendbaser = READ_ONCE(vgic_cpu->pendbaser);
pendbaser = old_pendbaser;
pendbaser = update_64bit_reg(pendbaser, addr & 4, len, val);
pendbaser = vgic_sanitise_pendbaser(pendbaser);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 82987d457b8b..15252d723b54 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -717,10 +717,9 @@ out_err_no_srcu:
hardware_disable_all();
out_err_no_disable:
for (i = 0; i < KVM_NR_BUSES; i++)
- kfree(rcu_access_pointer(kvm->buses[i]));
+ kfree(kvm_get_bus(kvm, i));
for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++)
- kvm_free_memslots(kvm,
- rcu_dereference_protected(kvm->memslots[i], 1));
+ kvm_free_memslots(kvm, __kvm_memslots(kvm, i));
kvm_arch_free_vm(kvm);
mmdrop(current->mm);
return ERR_PTR(r);
@@ -754,9 +753,8 @@ static void kvm_destroy_vm(struct kvm *kvm)
spin_unlock(&kvm_lock);
kvm_free_irq_routing(kvm);
for (i = 0; i < KVM_NR_BUSES; i++) {
- struct kvm_io_bus *bus;
+ struct kvm_io_bus *bus = kvm_get_bus(kvm, i);
- bus = rcu_dereference_protected(kvm->buses[i], 1);
if (bus)
kvm_io_bus_destroy(bus);
kvm->buses[i] = NULL;
@@ -770,8 +768,7 @@ static void kvm_destroy_vm(struct kvm *kvm)
kvm_arch_destroy_vm(kvm);
kvm_destroy_devices(kvm);
for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++)
- kvm_free_memslots(kvm,
- rcu_dereference_protected(kvm->memslots[i], 1));
+ kvm_free_memslots(kvm, __kvm_memslots(kvm, i));
cleanup_srcu_struct(&kvm->irq_srcu);
cleanup_srcu_struct(&kvm->srcu);
kvm_arch_free_vm(kvm);
@@ -3883,7 +3880,6 @@ static const struct file_operations *stat_fops[] = {
static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm)
{
struct kobj_uevent_env *env;
- char *tmp, *pathbuf = NULL;
unsigned long long created, active;
if (!kvm_dev.this_device || !kvm)
@@ -3907,38 +3903,28 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm)
add_uevent_var(env, "CREATED=%llu", created);
add_uevent_var(env, "COUNT=%llu", active);
- if (type == KVM_EVENT_CREATE_VM)
+ if (type == KVM_EVENT_CREATE_VM) {
add_uevent_var(env, "EVENT=create");
- else if (type == KVM_EVENT_DESTROY_VM)
+ kvm->userspace_pid = task_pid_nr(current);
+ } else if (type == KVM_EVENT_DESTROY_VM) {
add_uevent_var(env, "EVENT=destroy");
+ }
+ add_uevent_var(env, "PID=%d", kvm->userspace_pid);
if (kvm->debugfs_dentry) {
- char p[ITOA_MAX_LEN];
-
- snprintf(p, sizeof(p), "%s", kvm->debugfs_dentry->d_name.name);
- tmp = strchrnul(p + 1, '-');
- *tmp = '\0';
- add_uevent_var(env, "PID=%s", p);
- pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
- if (pathbuf) {
- /* sizeof counts the final '\0' */
- int len = sizeof("STATS_PATH=") - 1;
- const char *pvar = "STATS_PATH=";
-
- tmp = dentry_path_raw(kvm->debugfs_dentry,
- pathbuf + len,
- PATH_MAX - len);
- if (!IS_ERR(tmp)) {
- memcpy(tmp - len, pvar, len);
- env->envp[env->envp_idx++] = tmp - len;
- }
+ char *tmp, *p = kmalloc(PATH_MAX, GFP_KERNEL);
+
+ if (p) {
+ tmp = dentry_path_raw(kvm->debugfs_dentry, p, PATH_MAX);
+ if (!IS_ERR(tmp))
+ add_uevent_var(env, "STATS_PATH=%s", tmp);
+ kfree(p);
}
}
/* no need for checks, since we are adding at most only 5 keys */
env->envp[env->envp_idx++] = NULL;
kobject_uevent_env(&kvm_dev.this_device->kobj, KOBJ_CHANGE, env->envp);
kfree(env);
- kfree(pathbuf);
}
static int kvm_init_debug(void)